From a4e8885458c4921ad0f6a16ead10dbb557af35f6 Mon Sep 17 00:00:00 2001 From: Manuel Bentele Date: Fri, 11 Sep 2020 12:32:49 +0200 Subject: Renamed loop to xloop in all LTP kernel tests --- kernel/tests/CMakeLists.txt | 1 + kernel/tests/include/lapi/loop.h | 55 ------- kernel/tests/include/lapi/xloop.h | 55 +++++++ kernel/tests/include/tst_device.h | 20 +-- kernel/tests/lib/tst_device.c | 66 ++++----- .../testcases/kernel/syscalls/ioctl/CMakeLists.txt | 16 +- .../testcases/kernel/syscalls/ioctl/ioctl_loop01.c | 155 ------------------- .../testcases/kernel/syscalls/ioctl/ioctl_loop02.c | 164 -------------------- .../testcases/kernel/syscalls/ioctl/ioctl_loop03.c | 75 ---------- .../testcases/kernel/syscalls/ioctl/ioctl_loop04.c | 98 ------------ .../testcases/kernel/syscalls/ioctl/ioctl_loop05.c | 155 ------------------- .../testcases/kernel/syscalls/ioctl/ioctl_loop06.c | 143 ------------------ .../testcases/kernel/syscalls/ioctl/ioctl_loop07.c | 95 ------------ .../kernel/syscalls/ioctl/ioctl_xloop01.c | 156 +++++++++++++++++++ .../kernel/syscalls/ioctl/ioctl_xloop02.c | 165 +++++++++++++++++++++ .../kernel/syscalls/ioctl/ioctl_xloop03.c | 76 ++++++++++ .../kernel/syscalls/ioctl/ioctl_xloop04.c | 99 +++++++++++++ .../kernel/syscalls/ioctl/ioctl_xloop05.c | 156 +++++++++++++++++++ .../kernel/syscalls/ioctl/ioctl_xloop06.c | 144 ++++++++++++++++++ .../kernel/syscalls/ioctl/ioctl_xloop07.c | 96 ++++++++++++ 20 files changed, 999 insertions(+), 991 deletions(-) delete mode 100644 kernel/tests/include/lapi/loop.h create mode 100644 kernel/tests/include/lapi/xloop.h delete mode 100644 kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_loop01.c delete mode 100644 kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_loop02.c delete mode 100644 kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_loop03.c delete mode 100644 kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_loop04.c delete mode 100644 kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_loop05.c delete mode 100644 kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_loop06.c delete mode 100644 kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_loop07.c create mode 100644 kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_xloop01.c create mode 100644 kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_xloop02.c create mode 100644 kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_xloop03.c create mode 100644 kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_xloop04.c create mode 100644 kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_xloop05.c create mode 100644 kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_xloop06.c create mode 100644 kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_xloop07.c diff --git a/kernel/tests/CMakeLists.txt b/kernel/tests/CMakeLists.txt index 551a2fe..7bbd7a0 100644 --- a/kernel/tests/CMakeLists.txt +++ b/kernel/tests/CMakeLists.txt @@ -4,6 +4,7 @@ project(xloop-kernel-test) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include/old) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../uapi) # configure configuration config.h and add it to the include directories configure_file(${CMAKE_CURRENT_SOURCE_DIR}/include/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h) diff --git a/kernel/tests/include/lapi/loop.h b/kernel/tests/include/lapi/loop.h deleted file mode 100644 index 87a9023..0000000 --- a/kernel/tests/include/lapi/loop.h +++ /dev/null @@ -1,55 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (c) 2020 FUJITSU LIMITED. All rights reserved. - * Author: Yang Xu - */ -#ifndef LAPI_LOOP_H -#define LAPI_LOOP_H - -#include "config.h" -#include -#include - -#ifndef LO_FLAGS_PARTSCAN -# define LO_FLAGS_PARTSCAN 8 -#endif - -#ifndef LO_FLAGS_DIRECT_IO -# define LO_FLAGS_DIRECT_IO 16 -#endif - -#ifndef LOOP_SET_CAPACITY -# define LOOP_SET_CAPACITY 0x4C07 -#endif - -#ifndef LOOP_SET_DIRECT_IO -# define LOOP_SET_DIRECT_IO 0x4C08 -#endif - -#ifndef LOOP_SET_BLOCK_SIZE -# define LOOP_SET_BLOCK_SIZE 0x4C09 -#endif - -#ifndef LOOP_CONFIGURE -# define LOOP_CONFIGURE 0x4C0A -#endif - -#ifndef HAVE_STRUCT_LOOP_CONFIG -/* - * struct loop_config - Complete configuration for a loop device. - * @fd: fd of the file to be used as a backing file for the loop device. - * @block_size: block size to use; ignored if 0. - * @info: struct loop_info64 to configure the loop device with. - * - * This structure is used with the LOOP_CONFIGURE ioctl, and can be used to - * atomically setup and configure all loop device parameters at once. - */ -struct loop_config { - __u32 fd; - __u32 block_size; - struct loop_info64 info; - __u64 __reserved[8]; -}; -#endif - -#endif diff --git a/kernel/tests/include/lapi/xloop.h b/kernel/tests/include/lapi/xloop.h new file mode 100644 index 0000000..8e57b31 --- /dev/null +++ b/kernel/tests/include/lapi/xloop.h @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2020 FUJITSU LIMITED. All rights reserved. + * Author: Yang Xu + */ +#ifndef LAPI_LOOP_H +#define LAPI_LOOP_H + +#include "config.h" +#include +#include + +#ifndef LO_FLAGS_PARTSCAN +# define LO_FLAGS_PARTSCAN 8 +#endif + +#ifndef LO_FLAGS_DIRECT_IO +# define LO_FLAGS_DIRECT_IO 16 +#endif + +#ifndef LOOP_SET_CAPACITY +# define LOOP_SET_CAPACITY 0x4C07 +#endif + +#ifndef LOOP_SET_DIRECT_IO +# define LOOP_SET_DIRECT_IO 0x4C08 +#endif + +#ifndef LOOP_SET_BLOCK_SIZE +# define LOOP_SET_BLOCK_SIZE 0x4C09 +#endif + +#ifndef LOOP_CONFIGURE +# define LOOP_CONFIGURE 0x4C0A +#endif + +#ifndef HAVE_STRUCT_LOOP_CONFIG +/* + * struct loop_config - Complete configuration for a loop device. + * @fd: fd of the file to be used as a backing file for the loop device. + * @block_size: block size to use; ignored if 0. + * @info: struct loop_info64 to configure the loop device with. + * + * This structure is used with the LOOP_CONFIGURE ioctl, and can be used to + * atomically setup and configure all loop device parameters at once. + */ +struct xloop_config { + __u32 fd; + __u32 block_size; + struct xloop_info64 info; + __u64 __reserved[8]; +}; +#endif + +#endif diff --git a/kernel/tests/include/tst_device.h b/kernel/tests/include/tst_device.h index 1d1246e..00687a2 100644 --- a/kernel/tests/include/tst_device.h +++ b/kernel/tests/include/tst_device.h @@ -42,34 +42,34 @@ int tst_is_mounted_at_tmpdir(const char *path); int tst_clear_device(const char *dev); /* - * Finds a free loop device for use and returns the free loopdev minor(-1 for no - * free loopdev). If path is non-NULL, it will be filled with free loopdev path. + * Finds a free xloop device for use and returns the free xloopdev minor(-1 for no + * free xloopdev). If path is non-NULL, it will be filled with free xloopdev path. * */ -int tst_find_free_loopdev(const char *path, size_t path_len); +int tst_find_free_xloopdev(const char *path, size_t path_len); /* - * Attaches a file to a loop device. + * Attaches a file to a xloop device. * - * @dev_path Path to the loop device e.g. /dev/loop0 + * @dev_path Path to the xloop device e.g. /dev/xloop0 * @file_path Path to a file e.g. disk.img * @return Zero on success, non-zero otherwise. */ int tst_attach_device(const char *dev_path, const char *file_path); /* - * Detaches a file from a loop device fd. + * Detaches a file from a xloop device fd. * - * @dev_path Path to the loop device e.g. /dev/loop0 - * @dev_fd a open fd for the loop device + * @dev_path Path to the xloop device e.g. /dev/xloop0 + * @dev_fd a open fd for the xloop device * @return Zero on succes, non-zero otherwise. */ int tst_detach_device_by_fd(const char *dev_path, int dev_fd); /* - * Detaches a file from a loop device. + * Detaches a file from a xloop device. * - * @dev_path Path to the loop device e.g. /dev/loop0 + * @dev_path Path to the xloop device e.g. /dev/xloop0 * @return Zero on succes, non-zero otherwise. * * Internally this function opens the device and calls diff --git a/kernel/tests/lib/tst_device.c b/kernel/tests/lib/tst_device.c index 0e98a72..24f34a3 100644 --- a/kernel/tests/lib/tst_device.c +++ b/kernel/tests/lib/tst_device.c @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include #include @@ -36,11 +36,11 @@ #include "test.h" #include "safe_macros.h" -#ifndef LOOP_CTL_GET_FREE -# define LOOP_CTL_GET_FREE 0x4C82 +#ifndef XLOOP_CTL_GET_FREE +# define XLOOP_CTL_GET_FREE 0x4C82 #endif -#define LOOP_CONTROL_FILE "/dev/loop-control" +#define XLOOP_CONTROL_FILE "/dev/xloop-control" #define DEV_FILE "test_dev.img" #define DEV_SIZE_MB 256u @@ -50,9 +50,9 @@ static int device_acquired; static unsigned long prev_dev_sec_write; static const char *dev_variants[] = { - "/dev/loop%i", - "/dev/loop/%i", - "/dev/block/loop%i" + "/dev/xloop%i", + "/dev/xloop/%i", + "/dev/block/xloop%i" }; static int set_dev_path(int dev, char *path, size_t path_len) @@ -70,17 +70,17 @@ static int set_dev_path(int dev, char *path, size_t path_len) return 0; } -int tst_find_free_loopdev(char *path, size_t path_len) +int tst_find_free_xloopdev(char *path, size_t path_len) { int ctl_fd, dev_fd, rc, i; - struct loop_info loopinfo; + struct xloop_info xloopinfo; char buf[1024]; /* since Linux 3.1 */ - ctl_fd = open(LOOP_CONTROL_FILE, O_RDWR); + ctl_fd = open(XLOOP_CONTROL_FILE, O_RDWR); if (ctl_fd > 0) { - rc = ioctl(ctl_fd, LOOP_CTL_GET_FREE); + rc = ioctl(ctl_fd, XLOOP_CTL_GET_FREE); close(ctl_fd); if (rc >= 0) { if (path) @@ -89,7 +89,7 @@ int tst_find_free_loopdev(char *path, size_t path_len) rc, path ?: ""); return rc; } - tst_resm(TINFO, "Couldn't find free loop device"); + tst_resm(TINFO, "Couldn't find free xloop device"); return -1; } @@ -98,16 +98,16 @@ int tst_find_free_loopdev(char *path, size_t path_len) break; case EACCES: tst_resm(TINFO | TERRNO, - "Not allowed to open " LOOP_CONTROL_FILE ". " + "Not allowed to open " XLOOP_CONTROL_FILE ". " "Are you root?"); break; default: - tst_resm(TBROK | TERRNO, "Failed to open " LOOP_CONTROL_FILE); + tst_resm(TBROK | TERRNO, "Failed to open " XLOOP_CONTROL_FILE); } /* - * Older way is to iterate over /dev/loop%i and /dev/loop/%i and try - * LOOP_GET_STATUS ioctl() which fails for free loop devices. + * Older way is to iterate over /dev/xloop%i and /dev/xloop/%i and try + * XLOOP_GET_STATUS ioctl() which fails for free xloop devices. */ for (i = 0; i < 256; i++) { @@ -119,7 +119,7 @@ int tst_find_free_loopdev(char *path, size_t path_len) if (dev_fd < 0) continue; - if (ioctl(dev_fd, LOOP_GET_STATUS, &loopinfo) == 0) { + if (ioctl(dev_fd, XLOOP_GET_STATUS, &xloopinfo) == 0) { tst_resm(TINFO, "Device '%s' in use", buf); } else { if (errno != ENXIO) @@ -144,7 +144,7 @@ int tst_find_free_loopdev(char *path, size_t path_len) int tst_attach_device(const char *dev, const char *file) { int dev_fd, file_fd; - struct loop_info loopinfo; + struct xloop_info xloopinfo; dev_fd = open(dev, O_RDWR); if (dev_fd < 0) { @@ -159,26 +159,26 @@ int tst_attach_device(const char *dev, const char *file) return 1; } - if (ioctl(dev_fd, LOOP_SET_FD, file_fd) < 0) { + if (ioctl(dev_fd, XLOOP_SET_FD, file_fd) < 0) { close(dev_fd); close(file_fd); - tst_resm(TWARN | TERRNO, "ioctl(%s, LOOP_SET_FD, %s) failed", + tst_resm(TWARN | TERRNO, "ioctl(%s, XLOOP_SET_FD, %s) failed", dev, file); return 1; } - /* Old mkfs.btrfs use LOOP_GET_STATUS instead of backing_file to get + /* Old mkfs.btrfs use XLOOP_GET_STATUS instead of backing_file to get * associated filename, so we need to set up the device by calling - * LOOP_SET_FD and LOOP_SET_STATUS. + * XLOOP_SET_FD and XLOOP_SET_STATUS. */ - memset(&loopinfo, 0, sizeof(loopinfo)); - strcpy(loopinfo.lo_name, file); + memset(&xloopinfo, 0, sizeof(xloopinfo)); + strcpy(xloopinfo.xlo_name, file); - if (ioctl(dev_fd, LOOP_SET_STATUS, &loopinfo)) { + if (ioctl(dev_fd, XLOOP_SET_STATUS, &xloopinfo)) { close(dev_fd); close(file_fd); tst_resm(TWARN | TERRNO, - "ioctl(%s, LOOP_SET_STATUS, %s) failed", dev, file); + "ioctl(%s, XLOOP_SET_STATUS, %s) failed", dev, file); return 1; } @@ -191,17 +191,17 @@ int tst_detach_device_by_fd(const char *dev, int dev_fd) { int ret, i; - /* keep trying to clear LOOPDEV until we get ENXIO, a quick succession + /* keep trying to clear XLOOPDEV until we get ENXIO, a quick succession * of attach/detach might not give udev enough time to complete */ for (i = 0; i < 40; i++) { - ret = ioctl(dev_fd, LOOP_CLR_FD, 0); + ret = ioctl(dev_fd, XLOOP_CLR_FD, 0); if (ret && (errno == ENXIO)) return 0; if (ret && (errno != EBUSY)) { tst_resm(TWARN, - "ioctl(%s, LOOP_CLR_FD, 0) unexpectedly failed with: %s", + "ioctl(%s, XLOOP_CLR_FD, 0) unexpectedly failed with: %s", dev, tst_strerrno(errno)); return 1; } @@ -210,7 +210,7 @@ int tst_detach_device_by_fd(const char *dev, int dev_fd) } tst_resm(TWARN, - "ioctl(%s, LOOP_CLR_FD, 0) no ENXIO for too long", dev); + "ioctl(%s, XLOOP_CLR_FD, 0) no ENXIO for too long", dev); return 1; } @@ -234,7 +234,7 @@ int tst_dev_sync(int fd) return syscall(__NR_syncfs, fd); } -const char *tst_acquire_loop_device(unsigned int size, const char *filename) +const char *tst_acquire_xloop_device(unsigned int size, const char *filename) { unsigned int acq_dev_size = MAX(size, DEV_SIZE_MB); @@ -243,7 +243,7 @@ const char *tst_acquire_loop_device(unsigned int size, const char *filename) return NULL; } - if (tst_find_free_loopdev(dev_path, sizeof(dev_path)) == -1) + if (tst_find_free_xloopdev(dev_path, sizeof(dev_path)) == -1) return NULL; if (tst_attach_device(dev_path, filename)) @@ -306,7 +306,7 @@ const char *tst_acquire_device__(unsigned int size) ltp_dev_size, acq_dev_size); } - dev = tst_acquire_loop_device(acq_dev_size, DEV_FILE); + dev = tst_acquire_xloop_device(acq_dev_size, DEV_FILE); if (dev) device_acquired = 1; diff --git a/kernel/tests/testcases/kernel/syscalls/ioctl/CMakeLists.txt b/kernel/tests/testcases/kernel/syscalls/ioctl/CMakeLists.txt index e0687ec..674b787 100644 --- a/kernel/tests/testcases/kernel/syscalls/ioctl/CMakeLists.txt +++ b/kernel/tests/testcases/kernel/syscalls/ioctl/CMakeLists.txt @@ -1,32 +1,32 @@ cmake_minimum_required(VERSION 3.12) -project(xloop-kernel-test-ioctl-xloop) +project(xloop-kernel-test-ioctl_xloop) # test ioctl_xloop01 -add_executable(tst_ioctl_xloop01 ${CMAKE_CURRENT_SOURCE_DIR}/ioctl_loop01.c) +add_executable(tst_ioctl_xloop01 ${CMAKE_CURRENT_SOURCE_DIR}/ioctl_xloop01.c) target_link_libraries(tst_ioctl_xloop01 LINK_PUBLIC libltp) install(TARGETS tst_ioctl_xloop01 DESTINATION bin) # test ioctl_xloop02 -add_executable(tst_ioctl_xloop02 ${CMAKE_CURRENT_SOURCE_DIR}/ioctl_loop02.c) +add_executable(tst_ioctl_xloop02 ${CMAKE_CURRENT_SOURCE_DIR}/ioctl_xloop02.c) target_link_libraries(tst_ioctl_xloop02 LINK_PUBLIC libltp) # test ioctl_xloop03 -add_executable(tst_ioctl_xloop03 ${CMAKE_CURRENT_SOURCE_DIR}/ioctl_loop03.c) +add_executable(tst_ioctl_xloop03 ${CMAKE_CURRENT_SOURCE_DIR}/ioctl_xloop03.c) target_link_libraries(tst_ioctl_xloop03 LINK_PUBLIC libltp) # test ioctl_xloop04 -add_executable(tst_ioctl_xloop04 ${CMAKE_CURRENT_SOURCE_DIR}/ioctl_loop04.c) +add_executable(tst_ioctl_xloop04 ${CMAKE_CURRENT_SOURCE_DIR}/ioctl_xloop04.c) target_link_libraries(tst_ioctl_xloop04 LINK_PUBLIC libltp) # test ioctl_xloop05 -add_executable(tst_ioctl_xloop05 ${CMAKE_CURRENT_SOURCE_DIR}/ioctl_loop05.c) +add_executable(tst_ioctl_xloop05 ${CMAKE_CURRENT_SOURCE_DIR}/ioctl_xloop05.c) target_link_libraries(tst_ioctl_xloop05 LINK_PUBLIC libltp) # test ioctl_xloop06 -add_executable(tst_ioctl_xloop06 ${CMAKE_CURRENT_SOURCE_DIR}/ioctl_loop06.c) +add_executable(tst_ioctl_xloop06 ${CMAKE_CURRENT_SOURCE_DIR}/ioctl_xloop06.c) target_link_libraries(tst_ioctl_xloop06 LINK_PUBLIC libltp) # test ioctl_xloop07 -add_executable(tst_ioctl_xloop07 ${CMAKE_CURRENT_SOURCE_DIR}/ioctl_loop07.c) +add_executable(tst_ioctl_xloop07 ${CMAKE_CURRENT_SOURCE_DIR}/ioctl_xloop07.c) target_link_libraries(tst_ioctl_xloop07 LINK_PUBLIC libltp) \ No newline at end of file diff --git a/kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_loop01.c b/kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_loop01.c deleted file mode 100644 index cf71184..0000000 --- a/kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_loop01.c +++ /dev/null @@ -1,155 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (c) 2020 FUJITSU LIMITED. All rights reserved. - * Author: Yang Xu - * - * This is a basic ioctl test about loopdevice. - * It is designed to test LO_FLAGS_AUTOCLEAR and LO_FLAGS_PARTSCAN flag. - * - * For LO_FLAGS_AUTOCLEAR flag, we only check autoclear field value in sys - * directory and also get lo_flags by using LOOP_GET_STATUS. - * - * For LO_FLAGS_PARTSCAN flag, it is the same as LO_FLAGS_AUTOCLEAR flag. - * But we also check whether we can scan partition table correctly ie check - * whether /dev/loopnp1 and /sys/bloclk/loop0/loop0p1 existed. - * - * For LO_FLAGS_AUTOCLEAR flag, it can be clear. For LO_FLAGS_PARTSCAN flag, - * it cannot be clear. We also check this. - * - * It is also a regression test for kernel - * commit 10c70d95c0f2 ("block: remove the bd_openers checks in blk_drop_partitions") - * commit 6ac92fb5cdff ("loop: Fix wrong masking of status flags"). - */ - -#include -#include -#include -#include "lapi/loop.h" -#include "tst_test.h" - -static char dev_path[1024], backing_path[1024], backing_file_path[1024]; -static int dev_num, attach_flag, dev_fd, parted_sup; - -/* - * In drivers/block/loop.c code, set status function doesn't handle - * LO_FLAGS_READ_ONLY flag and ingore it. Only loop_set_fd with read only mode - * file_fd, lo_flags will include LO_FLAGS_READ_ONLY and it's the same for - * LO_FLAGS_DIRECT_IO. - */ -#define SET_FLAGS (LO_FLAGS_AUTOCLEAR | LO_FLAGS_PARTSCAN | LO_FLAGS_READ_ONLY | LO_FLAGS_DIRECT_IO) -#define GET_FLAGS (LO_FLAGS_AUTOCLEAR | LO_FLAGS_PARTSCAN) - -static char partscan_path[1024], autoclear_path[1024]; -static char loop_partpath[1026], sys_loop_partpath[1026]; - -static void check_loop_value(int set_flag, int get_flag, int autoclear_field) -{ - struct loop_info loopinfo = {0}, loopinfoget = {0}; - int ret; - - loopinfo.lo_flags = set_flag; - SAFE_IOCTL(dev_fd, LOOP_SET_STATUS, &loopinfo); - SAFE_IOCTL(dev_fd, LOOP_GET_STATUS, &loopinfoget); - - if (loopinfoget.lo_flags & ~get_flag) - tst_res(TFAIL, "expect %d but got %d", get_flag, loopinfoget.lo_flags); - else - tst_res(TPASS, "get expected lo_flag %d", loopinfoget.lo_flags); - - TST_ASSERT_INT(partscan_path, 1); - TST_ASSERT_INT(autoclear_path, autoclear_field); - - if (!parted_sup) { - tst_res(TINFO, "Current environment doesn't have parted disk, skip it"); - return; - } - - ret = TST_RETRY_FN_EXP_BACKOFF(access(loop_partpath, F_OK), TST_RETVAL_EQ0, 30); - if (ret == 0) - tst_res(TPASS, "access %s succeeds", loop_partpath); - else - tst_res(TFAIL, "access %s fails", loop_partpath); - - ret = TST_RETRY_FN_EXP_BACKOFF(access(sys_loop_partpath, F_OK), TST_RETVAL_EQ0, 30); - if (ret == 0) - tst_res(TPASS, "access %s succeeds", sys_loop_partpath); - else - tst_res(TFAIL, "access %s fails", sys_loop_partpath); -} - -static void verify_ioctl_loop(void) -{ - tst_attach_device(dev_path, "test.img"); - attach_flag = 1; - - TST_ASSERT_INT(partscan_path, 0); - TST_ASSERT_INT(autoclear_path, 0); - TST_ASSERT_STR(backing_path, backing_file_path); - - check_loop_value(SET_FLAGS, GET_FLAGS, 1); - - tst_res(TINFO, "Test flag can be clear"); - check_loop_value(0, LO_FLAGS_PARTSCAN, 0); - - tst_detach_device_by_fd(dev_path, dev_fd); - attach_flag = 0; -} - -static void setup(void) -{ - int ret; - const char *const cmd_parted[] = {"parted", "-s", "test.img", "mklabel", "msdos", "mkpart", - "primary", "ext4", "1M", "10M", NULL}; - - dev_num = tst_find_free_loopdev(dev_path, sizeof(dev_path)); - if (dev_num < 0) - tst_brk(TBROK, "Failed to find free loop device"); - - tst_fill_file("test.img", 0, 1024 * 1024, 10); - - ret = tst_cmd(cmd_parted, NULL, NULL, TST_CMD_PASS_RETVAL); - switch (ret) { - case 0: - parted_sup = 1; - break; - case 255: - tst_res(TCONF, "parted binary not installed or failed"); - break; - default: - tst_res(TCONF, "parted exited with %i", ret); - break; - } - - sprintf(partscan_path, "/sys/block/loop%d/loop/partscan", dev_num); - sprintf(autoclear_path, "/sys/block/loop%d/loop/autoclear", dev_num); - sprintf(backing_path, "/sys/block/loop%d/loop/backing_file", dev_num); - sprintf(sys_loop_partpath, "/sys/block/loop%d/loop%dp1", dev_num, dev_num); - sprintf(backing_file_path, "%s/test.img", tst_get_tmpdir()); - sprintf(loop_partpath, "%sp1", dev_path); - dev_fd = SAFE_OPEN(dev_path, O_RDWR); -} - -static void cleanup(void) -{ - if (dev_fd > 0) - SAFE_CLOSE(dev_fd); - if (attach_flag) - tst_detach_device(dev_path); -} - -static struct tst_test test = { - .setup = setup, - .cleanup = cleanup, - .test_all = verify_ioctl_loop, - .needs_root = 1, - .needs_drivers = (const char *const []) { - "loop", - NULL - }, - .tags = (const struct tst_tag[]) { - {"linux-git", "10c70d95c0f2"}, - {"linux-git", "6ac92fb5cdff"}, - {} - }, - .needs_tmpdir = 1, -}; diff --git a/kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_loop02.c b/kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_loop02.c deleted file mode 100644 index ac61842..0000000 --- a/kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_loop02.c +++ /dev/null @@ -1,164 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (c) 2020 FUJITSU LIMITED. All rights reserved. - * Author: Yang Xu - * - * This is a basic ioctl test about loopdevice. - * - * It is designed to test LO_FLAGS_READ_ONLY (similar as losetup -r) - * and LOOP_CHANGE_FD. - * - * For LOOP_CHANGE_FD, this operation is possible only if the loop device - * is read-only and the new backing store is the same size and type as the - * old backing store. - * - * If using LOOP_CONFIGURE ioctl, we can set LO_FLAGS_READ_ONLY - * flag even though backing file with write mode. - */ - -#include -#include -#include -#include -#include "lapi/loop.h" -#include "tst_test.h" - -static int file_fd, file_change_fd, file_fd_invalid; -static char backing_path[1024], backing_file_path[1024], backing_file_change_path[1024]; -static int attach_flag, dev_fd, loop_configure_sup = 1; -static char loop_ro_path[1024], dev_path[1024]; -static struct loop_config loopconfig; - -static struct tcase { - int mode; - int ioctl; - char *message; -} tcases[] = { - {O_RDONLY, LOOP_SET_FD, "Using LOOP_SET_FD to setup loopdevice"}, - {O_RDWR, LOOP_CONFIGURE, "Using LOOP_CONFIGURE with read_only flag"}, -}; - -static void verify_ioctl_loop(unsigned int n) -{ - struct tcase *tc = &tcases[n]; - struct loop_info loopinfoget; - - if (tc->ioctl == LOOP_CONFIGURE && !loop_configure_sup) { - tst_res(TCONF, "LOOP_CONFIGURE ioctl not supported"); - return; - } - - tst_res(TINFO, "%s", tc->message); - file_fd = SAFE_OPEN("test.img", tc->mode); - - if (tc->ioctl == LOOP_SET_FD) { - SAFE_IOCTL(dev_fd, LOOP_SET_FD, file_fd); - } else { - loopconfig.fd = file_fd; - SAFE_IOCTL(dev_fd, LOOP_CONFIGURE, &loopconfig); - } - attach_flag = 1; - - TST_ASSERT_INT(loop_ro_path, 1); - TST_ASSERT_STR(backing_path, backing_file_path); - - memset(&loopinfoget, 0, sizeof(loopinfoget)); - - SAFE_IOCTL(dev_fd, LOOP_GET_STATUS, &loopinfoget); - - if (loopinfoget.lo_flags & ~LO_FLAGS_READ_ONLY) - tst_res(TFAIL, "lo_flags has unexpected %d flag", loopinfoget.lo_flags); - else - tst_res(TPASS, "lo_flags only has default LO_FLAGS_READ_ONLY flag"); - - TEST(write(dev_fd, "xx", 2)); - if (TST_RET != -1) - tst_res(TFAIL, "write succeed unexpectedly"); - else - tst_res(TPASS | TTERRNO, "Can not write data in RO mode"); - - TEST(ioctl(dev_fd, LOOP_CHANGE_FD, file_change_fd)); - if (TST_RET) { - tst_res(TFAIL | TTERRNO, "LOOP_CHANGE_FD failed"); - } else { - tst_res(TPASS, "LOOP_CHANGE_FD succeeded"); - TST_ASSERT_INT(loop_ro_path, 1); - TST_ASSERT_STR(backing_path, backing_file_change_path); - } - - TEST(ioctl(dev_fd, LOOP_CHANGE_FD, file_fd_invalid)); - if (TST_RET) { - if (TST_ERR == EINVAL) - tst_res(TPASS | TTERRNO, "LOOP_CHANGE_FD failed as expected"); - else - tst_res(TFAIL | TTERRNO, "LOOP_CHANGE_FD failed expected EINVAL got"); - } else { - tst_res(TFAIL, "LOOP_CHANGE_FD succeeded"); - } - - SAFE_CLOSE(file_fd); - tst_detach_device_by_fd(dev_path, dev_fd); - attach_flag = 0; -} - -static void setup(void) -{ - int dev_num; - int ret; - - char *tmpdir = tst_get_tmpdir(); - dev_num = tst_find_free_loopdev(dev_path, sizeof(dev_path)); - if (dev_num < 0) - tst_brk(TBROK, "Failed to find free loop device"); - - tst_fill_file("test.img", 0, 1024, 10); - tst_fill_file("test1.img", 0, 1024, 10); - tst_fill_file("test2.img", 0, 2048, 20); - - sprintf(backing_path, "/sys/block/loop%d/loop/backing_file", dev_num); - sprintf(backing_file_path, "%s/test.img", tmpdir); - sprintf(backing_file_change_path, "%s/test1.img", tmpdir); - sprintf(loop_ro_path, "/sys/block/loop%d/ro", dev_num); - - free(tmpdir); - - file_change_fd = SAFE_OPEN("test1.img", O_RDWR); - file_fd_invalid = SAFE_OPEN("test2.img", O_RDWR); - - dev_fd = SAFE_OPEN(dev_path, O_RDWR); - loopconfig.fd = -1; - ret = ioctl(dev_fd, LOOP_CONFIGURE, &loopconfig); - - if (ret && errno != EBADF) { - tst_res(TINFO | TERRNO, "LOOP_CONFIGURE is not supported"); - loop_configure_sup = 0; - } - loopconfig.info.lo_flags = LO_FLAGS_READ_ONLY; -} - -static void cleanup(void) -{ - if (dev_fd > 0) - SAFE_CLOSE(dev_fd); - if (file_fd > 0) - SAFE_CLOSE(file_fd); - if (file_change_fd > 0) - SAFE_CLOSE(file_change_fd); - if (file_fd_invalid > 0) - SAFE_CLOSE(file_fd_invalid); - if (attach_flag) - tst_detach_device(dev_path); -} - -static struct tst_test test = { - .setup = setup, - .cleanup = cleanup, - .tcnt = ARRAY_SIZE(tcases), - .test = verify_ioctl_loop, - .needs_root = 1, - .needs_tmpdir = 1, - .needs_drivers = (const char *const []) { - "loop", - NULL - } -}; diff --git a/kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_loop03.c b/kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_loop03.c deleted file mode 100644 index 9cf5a41..0000000 --- a/kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_loop03.c +++ /dev/null @@ -1,75 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (c) 2020 FUJITSU LIMITED. All rights reserved. - * Author: Yang Xu - * - * This is a basic ioctl test about loopdevice. - * - * It is designed to test LOOP_CHANGE_FD can not succeed (get EINVAL error) - * when loop_dev is not read only. - */ - -#include -#include -#include -#include "lapi/loop.h" -#include "tst_test.h" - -static char dev_path[1024]; -static int dev_num, dev_fd, file_fd, attach_flag; - -static void verify_ioctl_loop(void) -{ - TEST(ioctl(dev_fd, LOOP_CHANGE_FD, file_fd)); - if (TST_RET == 0) { - tst_res(TFAIL, "LOOP_CHANGE_FD succeeded unexpectedly"); - return; - } - if (TST_ERR == EINVAL) - tst_res(TPASS | TTERRNO, "LOOP_CHANGE_FD failed as expected"); - else - tst_res(TFAIL | TTERRNO, "LOOP_CHANGE_FD failed expected EINVAL got"); -} - -static void setup(void) -{ - struct loop_info loopinfoget; - - memset(&loopinfoget, 0, sizeof(loopinfoget)); - dev_num = tst_find_free_loopdev(dev_path, sizeof(dev_path)); - if (dev_num < 0) - tst_brk(TBROK, "Failed to find free loop device"); - - tst_fill_file("test.img", 0, 1024, 10); - tst_attach_device(dev_path, "test.img"); - attach_flag = 1; - - dev_fd = SAFE_OPEN(dev_path, O_RDWR); - file_fd = SAFE_OPEN("test.img", O_RDWR); - SAFE_IOCTL(dev_fd, LOOP_GET_STATUS, &loopinfoget); - - if (loopinfoget.lo_flags & LO_FLAGS_READ_ONLY) - tst_brk(TCONF, "Current environment has unexpected LO_FLAGS_READ_ONLY flag"); -} - -static void cleanup(void) -{ - if (dev_fd > 0) - SAFE_CLOSE(dev_fd); - if (file_fd > 0) - SAFE_CLOSE(file_fd); - if (attach_flag) - tst_detach_device(dev_path); -} - -static struct tst_test test = { - .setup = setup, - .cleanup = cleanup, - .test_all = verify_ioctl_loop, - .needs_root = 1, - .needs_tmpdir = 1, - .needs_drivers = (const char *const []) { - "loop", - NULL - } -}; diff --git a/kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_loop04.c b/kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_loop04.c deleted file mode 100644 index b4ab44a..0000000 --- a/kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_loop04.c +++ /dev/null @@ -1,98 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (c) 2020 FUJITSU LIMITED. All rights reserved. - * Author: Yang Xu - * - * This is a basic ioctl test about loopdevice. - * - * It is designed to test LOOP_SET_CAPACITY can update a live - * loop device size when we change the size of the underlying - * backing file. Also check sys value. - */ -#include -#include -#include -#include -#include "lapi/loop.h" -#include "tst_test.h" - -#define OLD_SIZE 10240 -#define NEW_SIZE 5120 - -static char dev_path[1024], sys_loop_sizepath[1024]; -static char *wrbuf; -static int dev_num, dev_fd, file_fd, attach_flag; - -static void verify_ioctl_loop(void) -{ - struct loop_info loopinfoget; - - memset(&loopinfoget, 0, sizeof(loopinfoget)); - tst_fill_file("test.img", 0, 1024, OLD_SIZE/1024); - tst_attach_device(dev_path, "test.img"); - attach_flag = 1; - - TST_ASSERT_INT(sys_loop_sizepath, OLD_SIZE/512); - file_fd = SAFE_OPEN("test.img", O_RDWR); - SAFE_IOCTL(dev_fd, LOOP_GET_STATUS, &loopinfoget); - - if (loopinfoget.lo_flags & LO_FLAGS_READ_ONLY) - tst_brk(TCONF, "Current environment has unexpected LO_FLAGS_READ_ONLY flag"); - - SAFE_TRUNCATE("test.img", NEW_SIZE); - SAFE_IOCTL(dev_fd, LOOP_SET_CAPACITY); - - SAFE_LSEEK(dev_fd, 0, SEEK_SET); - - /*check that we can't write data beyond 5K into loop device*/ - TEST(write(dev_fd, wrbuf, OLD_SIZE)); - if (TST_RET == NEW_SIZE) { - tst_res(TPASS, "LOOP_SET_CAPACITY set loop size to %d", NEW_SIZE); - } else { - tst_res(TFAIL, "LOOP_SET_CAPACITY didn't set loop size to %d, its size is %ld", - NEW_SIZE, TST_RET); - } - - TST_ASSERT_INT(sys_loop_sizepath, NEW_SIZE/512); - - SAFE_CLOSE(file_fd); - tst_detach_device_by_fd(dev_path, dev_fd); - unlink("test.img"); - attach_flag = 0; -} - -static void setup(void) -{ - dev_num = tst_find_free_loopdev(dev_path, sizeof(dev_path)); - if (dev_num < 0) - tst_brk(TBROK, "Failed to find free loop device"); - - wrbuf = SAFE_MALLOC(OLD_SIZE); - memset(wrbuf, 'x', OLD_SIZE); - sprintf(sys_loop_sizepath, "/sys/block/loop%d/size", dev_num); - dev_fd = SAFE_OPEN(dev_path, O_RDWR); -} - -static void cleanup(void) -{ - if (dev_fd > 0) - SAFE_CLOSE(dev_fd); - if (file_fd > 0) - SAFE_CLOSE(file_fd); - if (wrbuf) - free(wrbuf); - if (attach_flag) - tst_detach_device(dev_path); -} - -static struct tst_test test = { - .setup = setup, - .cleanup = cleanup, - .test_all = verify_ioctl_loop, - .needs_root = 1, - .needs_tmpdir = 1, - .needs_drivers = (const char *const []) { - "loop", - NULL - } -}; diff --git a/kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_loop05.c b/kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_loop05.c deleted file mode 100644 index e3c14fa..0000000 --- a/kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_loop05.c +++ /dev/null @@ -1,155 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (c) 2020 FUJITSU LIMITED. All rights reserved. - * Author: Yang Xu - * - * This is a basic ioctl test about loopdevice. - * - * It is designed to test LOOP_SET_DIRECT_IO can update a live - * loop device dio mode. It needs the backing file also supports - * dio mode and the lo_offset is aligned with the logical block size. - * - * The direct I/O error handling is a bit messy on Linux, some filesystems - * return error when it coudln't be enabled, some silently fall back to regular - * buffered I/O. - * - * The LOOP_SET_DIRECT_IO ioctl() may ignore all checks if it cannot get the - * logical block size which is the case if the block device pointer in the - * backing file inode is not set. In this case the direct I/O appears to be - * enabled but falls back to buffered I/O later on. This is the case at least - * for Btrfs. Because of that the test passes both with failure as well as - * success with non-zero offset. - */ - -#include -#include -#include -#include -#include -#include "lapi/loop.h" -#include "tst_test.h" - -#define DIO_MESSAGE "In dio mode" -#define NON_DIO_MESSAGE "In non dio mode" - -static char dev_path[1024], sys_loop_diopath[1024], backing_file_path[1024];; -static int dev_num, dev_fd, block_devfd, attach_flag, logical_block_size; - -static void check_dio_value(int flag) -{ - struct loop_info loopinfoget; - - memset(&loopinfoget, 0, sizeof(loopinfoget)); - - SAFE_IOCTL(dev_fd, LOOP_GET_STATUS, &loopinfoget); - tst_res(TINFO, "%s", flag ? DIO_MESSAGE : NON_DIO_MESSAGE); - - if (loopinfoget.lo_flags & LO_FLAGS_DIRECT_IO) - tst_res(flag ? TPASS : TFAIL, "lo_flags has LO_FLAGS_DIRECT_IO flag"); - else - tst_res(flag ? TFAIL : TPASS, "lo_flags doesn't have LO_FLAGS_DIRECT_IO flag"); - - TST_ASSERT_INT(sys_loop_diopath, flag); -} - -static void verify_ioctl_loop(void) -{ - struct loop_info loopinfo; - - memset(&loopinfo, 0, sizeof(loopinfo)); - TST_RETRY_FUNC(ioctl(dev_fd, LOOP_SET_STATUS, &loopinfo), TST_RETVAL_EQ0); - - tst_res(TINFO, "Without setting lo_offset or sizelimit"); - SAFE_IOCTL(dev_fd, LOOP_SET_DIRECT_IO, 1); - check_dio_value(1); - - SAFE_IOCTL(dev_fd, LOOP_SET_DIRECT_IO, 0); - check_dio_value(0); - - tst_res(TINFO, "With offset equal to logical_block_size"); - loopinfo.lo_offset = logical_block_size; - TST_RETRY_FUNC(ioctl(dev_fd, LOOP_SET_STATUS, &loopinfo), TST_RETVAL_EQ0); - TEST(ioctl(dev_fd, LOOP_SET_DIRECT_IO, 1)); - if (TST_RET == 0) { - tst_res(TPASS, "LOOP_SET_DIRECT_IO succeeded"); - check_dio_value(1); - SAFE_IOCTL(dev_fd, LOOP_SET_DIRECT_IO, 0); - } else { - tst_res(TFAIL | TTERRNO, "LOOP_SET_DIRECT_IO failed"); - } - - tst_res(TINFO, "With nonzero offset less than logical_block_size"); - loopinfo.lo_offset = logical_block_size / 2; - TST_RETRY_FUNC(ioctl(dev_fd, LOOP_SET_STATUS, &loopinfo), TST_RETVAL_EQ0); - - TEST(ioctl(dev_fd, LOOP_SET_DIRECT_IO, 1)); - if (TST_RET == 0) { - tst_res(TPASS, "LOOP_SET_DIRECT_IO succeeded, offset is ignored"); - SAFE_IOCTL(dev_fd, LOOP_SET_DIRECT_IO, 0); - return; - } - if (TST_ERR == EINVAL) - tst_res(TPASS | TTERRNO, "LOOP_SET_DIRECT_IO failed as expected"); - else - tst_res(TFAIL | TTERRNO, "LOOP_SET_DIRECT_IO failed expected EINVAL got"); -} - -static void setup(void) -{ - char bd_path[100]; - - if (tst_fs_type(".") == TST_TMPFS_MAGIC) - tst_brk(TCONF, "tmpfd doesn't support O_DIRECT flag"); - - dev_num = tst_find_free_loopdev(dev_path, sizeof(dev_path)); - if (dev_num < 0) - tst_brk(TBROK, "Failed to find free loop device"); - - sprintf(sys_loop_diopath, "/sys/block/loop%d/loop/dio", dev_num); - tst_fill_file("test.img", 0, 1024, 1024); - - tst_attach_device(dev_path, "test.img"); - attach_flag = 1; - dev_fd = SAFE_OPEN(dev_path, O_RDWR); - - if (ioctl(dev_fd, LOOP_SET_DIRECT_IO, 0) && errno == EINVAL) - tst_brk(TCONF, "LOOP_SET_DIRECT_IO is not supported"); - - /* - * from __loop_update_dio(): - * We support direct I/O only if lo_offset is aligned with the - * logical I/O size of backing device, and the logical block - * size of loop is bigger than the backing device's and the loop - * needn't transform transfer. - */ - sprintf(backing_file_path, "%s/test.img", tst_get_tmpdir()); - tst_find_backing_dev(backing_file_path, bd_path); - block_devfd = SAFE_OPEN(bd_path, O_RDWR); - SAFE_IOCTL(block_devfd, BLKSSZGET, &logical_block_size); - tst_res(TINFO, "backing dev(%s) logical_block_size is %d", bd_path, logical_block_size); - SAFE_CLOSE(block_devfd); - if (logical_block_size > 512) - TST_RETRY_FUNC(ioctl(dev_fd, LOOP_SET_BLOCK_SIZE, logical_block_size), TST_RETVAL_EQ0); -} - -static void cleanup(void) -{ - if (dev_fd > 0) - SAFE_CLOSE(dev_fd); - if (block_devfd > 0) - SAFE_CLOSE(block_devfd); - if (attach_flag) - tst_detach_device(dev_path); -} - -static struct tst_test test = { - .setup = setup, - .cleanup = cleanup, - .test_all = verify_ioctl_loop, - .needs_root = 1, - .needs_tmpdir = 1, - .needs_drivers = (const char *const []) { - "loop", - NULL - } -}; diff --git a/kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_loop06.c b/kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_loop06.c deleted file mode 100644 index bd0d289..0000000 --- a/kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_loop06.c +++ /dev/null @@ -1,143 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (c) 2020 FUJITSU LIMITED. All rights reserved. - * Author: Yang Xu - * - * This is a basic error test about the invalid block size of loopdevice - * by using LOOP_SET_BLOCK_SIZE or LOOP_CONFIGURE ioctl. - */ - -#include -#include -#include -#include -#include "lapi/loop.h" -#include "tst_test.h" - -static char dev_path[1024]; -static int dev_num, dev_fd, file_fd, attach_flag, loop_configure_sup = 1; -static unsigned int invalid_value, half_value, unalign_value; -static struct loop_config loopconfig; - -static struct tcase { - unsigned int *setvalue; - int ioctl_flag; - char *message; -} tcases[] = { - {&half_value, LOOP_SET_BLOCK_SIZE, - "Using LOOP_SET_BLOCK_SIZE with arg < 512"}, - - {&invalid_value, LOOP_SET_BLOCK_SIZE, - "Using LOOP_SET_BLOCK_SIZE with arg > PAGE_SIZE"}, - - {&unalign_value, LOOP_SET_BLOCK_SIZE, - "Using LOOP_SET_BLOCK_SIZE with arg != power_of_2"}, - - {&half_value, LOOP_CONFIGURE, - "Using LOOP_CONFIGURE with block_size < 512"}, - - {&invalid_value, LOOP_CONFIGURE, - "Using LOOP_CONFIGURE with block_size > PAGE_SIZE"}, - - {&unalign_value, LOOP_CONFIGURE, - "Using LOOP_CONFIGURE with block_size != power_of_2"}, -}; - -static void verify_ioctl_loop(unsigned int n) -{ - if (tcases[n].ioctl_flag == LOOP_CONFIGURE) - TEST(ioctl(dev_fd, LOOP_CONFIGURE, &loopconfig)); - else - TEST(ioctl(dev_fd, LOOP_SET_BLOCK_SIZE, *(tcases[n].setvalue))); - - if (TST_RET == 0) { - tst_res(TFAIL, "Set block size succeed unexpectedly"); - if (tcases[n].ioctl_flag == LOOP_CONFIGURE) - tst_detach_device_by_fd(dev_path, dev_fd); - return; - } - if (TST_ERR == EINVAL) - tst_res(TPASS | TTERRNO, "Set block size failed as expected"); - else - tst_res(TFAIL | TTERRNO, "Set block size failed expected EINVAL got"); -} - -static void run(unsigned int n) -{ - struct tcase *tc = &tcases[n]; - - tst_res(TINFO, "%s", tc->message); - if (tc->ioctl_flag == LOOP_SET_BLOCK_SIZE) { - if (!attach_flag) { - tst_attach_device(dev_path, "test.img"); - attach_flag = 1; - } - verify_ioctl_loop(n); - return; - } - - if (tc->ioctl_flag == LOOP_CONFIGURE && !loop_configure_sup) { - tst_res(TCONF, "LOOP_CONFIGURE ioctl not supported"); - return; - } - if (attach_flag) { - tst_detach_device_by_fd(dev_path, dev_fd); - attach_flag = 0; - } - loopconfig.block_size = *(tc->setvalue); - verify_ioctl_loop(n); -} - -static void setup(void) -{ - unsigned int pg_size; - int ret; - - dev_num = tst_find_free_loopdev(dev_path, sizeof(dev_path)); - if (dev_num < 0) - tst_brk(TBROK, "Failed to find free loop device"); - - tst_fill_file("test.img", 0, 1024, 1024); - half_value = 256; - pg_size = getpagesize(); - invalid_value = pg_size * 2 ; - unalign_value = pg_size - 1; - - dev_fd = SAFE_OPEN(dev_path, O_RDWR); - - if (ioctl(dev_fd, LOOP_SET_BLOCK_SIZE, 512) && errno == EINVAL) - tst_brk(TCONF, "LOOP_SET_BLOCK_SIZE is not supported"); - - file_fd = SAFE_OPEN("test.img", O_RDWR); - loopconfig.fd = -1; - ret = ioctl(dev_fd, LOOP_CONFIGURE, &loopconfig); - if (ret && errno != EBADF) { - tst_res(TINFO | TERRNO, "LOOP_CONFIGURE is not supported"); - loop_configure_sup = 0; - return; - } - loopconfig.fd = file_fd; -} - -static void cleanup(void) -{ - if (dev_fd > 0) - SAFE_CLOSE(dev_fd); - if (file_fd > 0) - SAFE_CLOSE(file_fd); - if (attach_flag) - tst_detach_device(dev_path); -} - -static struct tst_test test = { - .setup = setup, - .cleanup = cleanup, - .test = run, - .tcnt = ARRAY_SIZE(tcases), - .needs_root = 1, - .needs_tmpdir = 1, - .needs_drivers = (const char *const []) { - "loop", - NULL - } -}; diff --git a/kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_loop07.c b/kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_loop07.c deleted file mode 100644 index ce4b476..0000000 --- a/kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_loop07.c +++ /dev/null @@ -1,95 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (c) 2020 FUJITSU LIMITED. All rights reserved. - * Author: Yang Xu - * - * This is a basic ioctl test about loopdevice LOOP_SET_STATUS64 - * and LOOP_GET_STATUS64. - * Test its lo_sizelimit field. If lo_sizelimit is 0,it means max - * available. If sizelimit is less than loop_size, loopsize will - * be truncated. - */ - -#include -#include -#include -#include -#include "lapi/loop.h" -#include "tst_test.h" - -static char dev_path[1024], sys_loop_sizepath[1024], sys_loop_sizelimitpath[1024]; -static int dev_num, dev_fd, file_fd, attach_flag; - -static struct tcase { - unsigned int set_sizelimit; - unsigned int exp_loopsize; - char *message; -} tcases[] = { - {1024 * 4096, 2048, "When sizelimit is greater than loopsize "}, - {1024 * 512, 1024, "When sizelimit is less than loopsize"}, -}; - -static void verify_ioctl_loop(unsigned int n) -{ - struct tcase *tc = &tcases[n]; - struct loop_info64 loopinfo, loopinfoget; - - tst_res(TINFO, "%s", tc->message); - memset(&loopinfo, 0, sizeof(loopinfo)); - memset(&loopinfoget, 0, sizeof(loopinfoget)); - - loopinfo.lo_sizelimit = tc->set_sizelimit; - TST_RETRY_FUNC(ioctl(dev_fd, LOOP_SET_STATUS64, &loopinfo), TST_RETVAL_EQ0); - - TST_ASSERT_INT(sys_loop_sizepath, tc->exp_loopsize); - TST_ASSERT_INT(sys_loop_sizelimitpath, tc->set_sizelimit); - SAFE_IOCTL(dev_fd, LOOP_GET_STATUS64, &loopinfoget); - if (loopinfoget.lo_sizelimit == tc->set_sizelimit) - tst_res(TPASS, "LOOP_GET_STATUS64 gets correct lo_sizelimit(%d)", tc->set_sizelimit); - else - tst_res(TFAIL, "LOOP_GET_STATUS64 gets wrong lo_sizelimit(%llu), expect %d", - loopinfoget.lo_sizelimit, tc->set_sizelimit); - /*Reset*/ - loopinfo.lo_sizelimit = 0; - TST_RETRY_FUNC(ioctl(dev_fd, LOOP_SET_STATUS, &loopinfo), TST_RETVAL_EQ0); -} - -static void setup(void) -{ - dev_num = tst_find_free_loopdev(dev_path, sizeof(dev_path)); - if (dev_num < 0) - tst_brk(TBROK, "Failed to find free loop device"); - - tst_fill_file("test.img", 0, 1024 * 1024, 1); - tst_attach_device(dev_path, "test.img"); - attach_flag = 1; - - sprintf(sys_loop_sizepath, "/sys/block/loop%d/size", dev_num); - sprintf(sys_loop_sizelimitpath, "/sys/block/loop%d/loop/sizelimit", dev_num); - - dev_fd = SAFE_OPEN(dev_path, O_RDWR); - tst_res(TINFO, "original loop size 2048 sectors"); -} - -static void cleanup(void) -{ - if (dev_fd > 0) - SAFE_CLOSE(dev_fd); - if (file_fd > 0) - SAFE_CLOSE(file_fd); - if (attach_flag) - tst_detach_device(dev_path); -} - -static struct tst_test test = { - .setup = setup, - .cleanup = cleanup, - .test = verify_ioctl_loop, - .tcnt = ARRAY_SIZE(tcases), - .needs_root = 1, - .needs_tmpdir = 1, - .needs_drivers = (const char *const []) { - "loop", - NULL - } -}; diff --git a/kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_xloop01.c b/kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_xloop01.c new file mode 100644 index 0000000..58bb692 --- /dev/null +++ b/kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_xloop01.c @@ -0,0 +1,156 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2020 FUJITSU LIMITED. All rights reserved. + * Author: Yang Xu + * + * This is a basic ioctl test about xloopdevice. + * It is designed to test XLO_FLAGS_AUTOCLEAR and XLO_FLAGS_PARTSCAN flag. + * + * For XLO_FLAGS_AUTOCLEAR flag, we only check autoclear field value in sys + * directory and also get xlo_flags by using XLOOP_GET_STATUS. + * + * For XLO_FLAGS_PARTSCAN flag, it is the same as XLO_FLAGS_AUTOCLEAR flag. + * But we also check whether we can scan partition table correctly ie check + * whether /dev/xloopnp1 and /sys/bloclk/xloop0/xloop0p1 existed. + * + * For XLO_FLAGS_AUTOCLEAR flag, it can be clear. For XLO_FLAGS_PARTSCAN flag, + * it cannot be clear. We also check this. + * + * It is also a regression test for kernel + * commit 10c70d95c0f2 ("block: remove the bd_openers checks in blk_drop_partitions") + * commit 6ac92fb5cdff ("xloop: Fix wrong masking of status flags"). + */ + +#include +#include +#include +#include "lapi/xloop.h" +#include "tst_test.h" + +static char dev_path[1024], backing_path[1024], backing_file_path[1024]; +static int dev_num, attach_flag, dev_fd, parted_sup; + +/* + * In drivers/block/xloop.c code, set status function doesn't handle + * XLO_FLAGS_READ_ONLY flag and ingore it. Only xloop_set_fd with read only mode + * file_fd, xlo_flags will include XLO_FLAGS_READ_ONLY and it's the same for + * XLO_FLAGS_DIRECT_IO. + */ +#define SET_FLAGS (XLO_FLAGS_AUTOCLEAR | XLO_FLAGS_PARTSCAN | XLO_FLAGS_READ_ONLY | XLO_FLAGS_DIRECT_IO) +#define GET_FLAGS (XLO_FLAGS_AUTOCLEAR | XLO_FLAGS_PARTSCAN) + +static char partscan_path[1024], autoclear_path[1024]; +static char xloop_partpath[1026], sys_xloop_partpath[1026]; + +static void check_xloop_value(int set_flag, int get_flag, int autoclear_field) +{ + struct xloop_info xloopinfo = {0}, xloopinfoget = {0}; + int ret; + + xloopinfo.xlo_flags = set_flag; + SAFE_IOCTL(dev_fd, XLOOP_SET_STATUS, &xloopinfo); + SAFE_IOCTL(dev_fd, XLOOP_GET_STATUS, &xloopinfoget); + + if (xloopinfoget.xlo_flags & ~get_flag) + tst_res(TFAIL, "expect %d but got %d", get_flag, xloopinfoget.xlo_flags); + else + tst_res(TPASS, "get expected xlo_flag %d", xloopinfoget.xlo_flags); + + TST_ASSERT_INT(partscan_path, 1); + TST_ASSERT_INT(autoclear_path, autoclear_field); + + if (!parted_sup) { + tst_res(TINFO, "Current environment doesn't have parted disk, skip it"); + return; + } + + ret = TST_RETRY_FN_EXP_BACKOFF(access(xloop_partpath, F_OK), TST_RETVAL_EQ0, 30); + if (ret == 0) + tst_res(TPASS, "access %s succeeds", xloop_partpath); + else + tst_res(TFAIL, "access %s fails", xloop_partpath); + + ret = TST_RETRY_FN_EXP_BACKOFF(access(sys_xloop_partpath, F_OK), TST_RETVAL_EQ0, 30); + if (ret == 0) + tst_res(TPASS, "access %s succeeds", sys_xloop_partpath); + else + tst_res(TFAIL, "access %s fails", sys_xloop_partpath); +} + +static void verify_ioctl_xloop(void) +{ + tst_attach_device(dev_path, "test.img"); + attach_flag = 1; + + TST_ASSERT_INT(partscan_path, 0); + TST_ASSERT_INT(autoclear_path, 0); + TST_ASSERT_STR(backing_path, backing_file_path); + + check_xloop_value(SET_FLAGS, GET_FLAGS, 1); + + tst_res(TINFO, "Test flag can be clear"); + check_xloop_value(0, XLO_FLAGS_PARTSCAN, 0); + + tst_detach_device_by_fd(dev_path, dev_fd); + attach_flag = 0; +} + +static void setup(void) +{ + int ret; + const char *const cmd_parted[] = {"parted", "-s", "test.img", "mklabel", "msdos", "mkpart", + "primary", "ext4", "1M", "10M", NULL}; + + dev_num = tst_find_free_xloopdev(dev_path, sizeof(dev_path)); + if (dev_num < 0) + tst_brk(TBROK, "Failed to find free xloop device"); + + tst_fill_file("test.img", 0, 1024 * 1024, 10); + + ret = tst_cmd(cmd_parted, NULL, NULL, TST_CMD_PASS_RETVAL); + switch (ret) { + case 0: + parted_sup = 1; + break; + case 255: + tst_res(TCONF, "parted binary not installed or failed"); + break; + default: + tst_res(TCONF, "parted exited with %i", ret); + break; + } + + sprintf(partscan_path, "/sys/block/xloop%d/xloop/partscan", dev_num); + sprintf(autoclear_path, "/sys/block/xloop%d/xloop/autoclear", dev_num); + sprintf(backing_path, "/sys/block/xloop%d/xloop/backing_file", dev_num); + sprintf(sys_xloop_partpath, "/sys/block/xloop%d/xloop%dp1", dev_num, dev_num); + sprintf(backing_file_path, "%s/test.img", tst_get_tmpdir()); + sprintf(xloop_partpath, "%sp1", dev_path); + dev_fd = SAFE_OPEN(dev_path, O_RDWR); +} + +static void cleanup(void) +{ + if (dev_fd > 0) + SAFE_CLOSE(dev_fd); + if (attach_flag) + tst_detach_device(dev_path); +} + +static struct tst_test test = { + .setup = setup, + .cleanup = cleanup, + .test_all = verify_ioctl_xloop, + .needs_root = 1, + .needs_drivers = (const char *const []) { + "xloop", + "xloop_file_fmt_raw", + NULL + }, + .tags = (const struct tst_tag[]) { + {"linux-git", "10c70d95c0f2"}, + {"linux-git", "6ac92fb5cdff"}, + {} + }, + .needs_tmpdir = 1, +}; diff --git a/kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_xloop02.c b/kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_xloop02.c new file mode 100644 index 0000000..895f7f2 --- /dev/null +++ b/kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_xloop02.c @@ -0,0 +1,165 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2020 FUJITSU LIMITED. All rights reserved. + * Author: Yang Xu + * + * This is a basic ioctl test about xloopdevice. + * + * It is designed to test XLO_FLAGS_READ_ONLY (similar as xlosetup -r) + * and XLOOP_CHANGE_FD. + * + * For XLOOP_CHANGE_FD, this operation is possible only if the xloop device + * is read-only and the new backing store is the same size and type as the + * old backing store. + * + * If using XLOOP_CONFIGURE ioctl, we can set XLO_FLAGS_READ_ONLY + * flag even though backing file with write mode. + */ + +#include +#include +#include +#include +#include "lapi/xloop.h" +#include "tst_test.h" + +static int file_fd, file_change_fd, file_fd_invalid; +static char backing_path[1024], backing_file_path[1024], backing_file_change_path[1024]; +static int attach_flag, dev_fd, xloop_configure_sup = 1; +static char xloop_ro_path[1024], dev_path[1024]; +static struct xloop_config xloopconfig; + +static struct tcase { + int mode; + int ioctl; + char *message; +} tcases[] = { + {O_RDONLY, XLOOP_SET_FD, "Using XLOOP_SET_FD to setup xloopdevice"}, + {O_RDWR, XLOOP_CONFIGURE, "Using XLOOP_CONFIGURE with read_only flag"}, +}; + +static void verify_ioctl_xloop(unsigned int n) +{ + struct tcase *tc = &tcases[n]; + struct xloop_info xloopinfoget; + + if (tc->ioctl == XLOOP_CONFIGURE && !xloop_configure_sup) { + tst_res(TCONF, "XLOOP_CONFIGURE ioctl not supported"); + return; + } + + tst_res(TINFO, "%s", tc->message); + file_fd = SAFE_OPEN("test.img", tc->mode); + + if (tc->ioctl == XLOOP_SET_FD) { + SAFE_IOCTL(dev_fd, XLOOP_SET_FD, file_fd); + } else { + xloopconfig.fd = file_fd; + SAFE_IOCTL(dev_fd, XLOOP_CONFIGURE, &xloopconfig); + } + attach_flag = 1; + + TST_ASSERT_INT(xloop_ro_path, 1); + TST_ASSERT_STR(backing_path, backing_file_path); + + memset(&xloopinfoget, 0, sizeof(xloopinfoget)); + + SAFE_IOCTL(dev_fd, XLOOP_GET_STATUS, &xloopinfoget); + + if (xloopinfoget.xlo_flags & ~XLO_FLAGS_READ_ONLY) + tst_res(TFAIL, "xlo_flags has unexpected %d flag", xloopinfoget.xlo_flags); + else + tst_res(TPASS, "xlo_flags only has default XLO_FLAGS_READ_ONLY flag"); + + TEST(write(dev_fd, "xx", 2)); + if (TST_RET != -1) + tst_res(TFAIL, "write succeed unexpectedly"); + else + tst_res(TPASS | TTERRNO, "Can not write data in RO mode"); + + TEST(ioctl(dev_fd, XLOOP_CHANGE_FD, file_change_fd)); + if (TST_RET) { + tst_res(TFAIL | TTERRNO, "XLOOP_CHANGE_FD failed"); + } else { + tst_res(TPASS, "XLOOP_CHANGE_FD succeeded"); + TST_ASSERT_INT(xloop_ro_path, 1); + TST_ASSERT_STR(backing_path, backing_file_change_path); + } + + TEST(ioctl(dev_fd, XLOOP_CHANGE_FD, file_fd_invalid)); + if (TST_RET) { + if (TST_ERR == EINVAL) + tst_res(TPASS | TTERRNO, "XLOOP_CHANGE_FD failed as expected"); + else + tst_res(TFAIL | TTERRNO, "XLOOP_CHANGE_FD failed expected EINVAL got"); + } else { + tst_res(TFAIL, "XLOOP_CHANGE_FD succeeded"); + } + + SAFE_CLOSE(file_fd); + tst_detach_device_by_fd(dev_path, dev_fd); + attach_flag = 0; +} + +static void setup(void) +{ + int dev_num; + int ret; + + char *tmpdir = tst_get_tmpdir(); + dev_num = tst_find_free_xloopdev(dev_path, sizeof(dev_path)); + if (dev_num < 0) + tst_brk(TBROK, "Failed to find free xloop device"); + + tst_fill_file("test.img", 0, 1024, 10); + tst_fill_file("test1.img", 0, 1024, 10); + tst_fill_file("test2.img", 0, 2048, 20); + + sprintf(backing_path, "/sys/block/xloop%d/xloop/backing_file", dev_num); + sprintf(backing_file_path, "%s/test.img", tmpdir); + sprintf(backing_file_change_path, "%s/test1.img", tmpdir); + sprintf(xloop_ro_path, "/sys/block/xloop%d/ro", dev_num); + + free(tmpdir); + + file_change_fd = SAFE_OPEN("test1.img", O_RDWR); + file_fd_invalid = SAFE_OPEN("test2.img", O_RDWR); + + dev_fd = SAFE_OPEN(dev_path, O_RDWR); + xloopconfig.fd = -1; + ret = ioctl(dev_fd, XLOOP_CONFIGURE, &xloopconfig); + + if (ret && errno != EBADF) { + tst_res(TINFO | TERRNO, "XLOOP_CONFIGURE is not supported"); + xloop_configure_sup = 0; + } + xloopconfig.info.xlo_flags = XLO_FLAGS_READ_ONLY; +} + +static void cleanup(void) +{ + if (dev_fd > 0) + SAFE_CLOSE(dev_fd); + if (file_fd > 0) + SAFE_CLOSE(file_fd); + if (file_change_fd > 0) + SAFE_CLOSE(file_change_fd); + if (file_fd_invalid > 0) + SAFE_CLOSE(file_fd_invalid); + if (attach_flag) + tst_detach_device(dev_path); +} + +static struct tst_test test = { + .setup = setup, + .cleanup = cleanup, + .tcnt = ARRAY_SIZE(tcases), + .test = verify_ioctl_xloop, + .needs_root = 1, + .needs_tmpdir = 1, + .needs_drivers = (const char *const []) { + "xloop", + "xloop_file_fmt_raw", + NULL + } +}; diff --git a/kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_xloop03.c b/kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_xloop03.c new file mode 100644 index 0000000..9447cbc --- /dev/null +++ b/kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_xloop03.c @@ -0,0 +1,76 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2020 FUJITSU LIMITED. All rights reserved. + * Author: Yang Xu + * + * This is a basic ioctl test about xloopdevice. + * + * It is designed to test XLOOP_CHANGE_FD can not succeed (get EINVAL error) + * when xloop_dev is not read only. + */ + +#include +#include +#include +#include "lapi/xloop.h" +#include "tst_test.h" + +static char dev_path[1024]; +static int dev_num, dev_fd, file_fd, attach_flag; + +static void verify_ioctl_xloop(void) +{ + TEST(ioctl(dev_fd, XLOOP_CHANGE_FD, file_fd)); + if (TST_RET == 0) { + tst_res(TFAIL, "XLOOP_CHANGE_FD succeeded unexpectedly"); + return; + } + if (TST_ERR == EINVAL) + tst_res(TPASS | TTERRNO, "XLOOP_CHANGE_FD failed as expected"); + else + tst_res(TFAIL | TTERRNO, "XLOOP_CHANGE_FD failed expected EINVAL got"); +} + +static void setup(void) +{ + struct xloop_info xloopinfoget; + + memset(&xloopinfoget, 0, sizeof(xloopinfoget)); + dev_num = tst_find_free_xloopdev(dev_path, sizeof(dev_path)); + if (dev_num < 0) + tst_brk(TBROK, "Failed to find free xloop device"); + + tst_fill_file("test.img", 0, 1024, 10); + tst_attach_device(dev_path, "test.img"); + attach_flag = 1; + + dev_fd = SAFE_OPEN(dev_path, O_RDWR); + file_fd = SAFE_OPEN("test.img", O_RDWR); + SAFE_IOCTL(dev_fd, XLOOP_GET_STATUS, &xloopinfoget); + + if (xloopinfoget.xlo_flags & XLO_FLAGS_READ_ONLY) + tst_brk(TCONF, "Current environment has unexpected XLO_FLAGS_READ_ONLY flag"); +} + +static void cleanup(void) +{ + if (dev_fd > 0) + SAFE_CLOSE(dev_fd); + if (file_fd > 0) + SAFE_CLOSE(file_fd); + if (attach_flag) + tst_detach_device(dev_path); +} + +static struct tst_test test = { + .setup = setup, + .cleanup = cleanup, + .test_all = verify_ioctl_xloop, + .needs_root = 1, + .needs_tmpdir = 1, + .needs_drivers = (const char *const []) { + "xloop", + "xloop_file_fmt_raw", + NULL + } +}; diff --git a/kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_xloop04.c b/kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_xloop04.c new file mode 100644 index 0000000..adf5cdf --- /dev/null +++ b/kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_xloop04.c @@ -0,0 +1,99 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2020 FUJITSU LIMITED. All rights reserved. + * Author: Yang Xu + * + * This is a basic ioctl test about xloopdevice. + * + * It is designed to test XLOOP_SET_CAPACITY can update a live + * xloop device size when we change the size of the underlying + * backing file. Also check sys value. + */ +#include +#include +#include +#include +#include "lapi/xloop.h" +#include "tst_test.h" + +#define OLD_SIZE 10240 +#define NEW_SIZE 5120 + +static char dev_path[1024], sys_xloop_sizepath[1024]; +static char *wrbuf; +static int dev_num, dev_fd, file_fd, attach_flag; + +static void verify_ioctl_xloop(void) +{ + struct xloop_info xloopinfoget; + + memset(&xloopinfoget, 0, sizeof(xloopinfoget)); + tst_fill_file("test.img", 0, 1024, OLD_SIZE/1024); + tst_attach_device(dev_path, "test.img"); + attach_flag = 1; + + TST_ASSERT_INT(sys_xloop_sizepath, OLD_SIZE/512); + file_fd = SAFE_OPEN("test.img", O_RDWR); + SAFE_IOCTL(dev_fd, XLOOP_GET_STATUS, &xloopinfoget); + + if (xloopinfoget.xlo_flags & XLO_FLAGS_READ_ONLY) + tst_brk(TCONF, "Current environment has unexpected XLO_FLAGS_READ_ONLY flag"); + + SAFE_TRUNCATE("test.img", NEW_SIZE); + SAFE_IOCTL(dev_fd, XLOOP_SET_CAPACITY); + + SAFE_LSEEK(dev_fd, 0, SEEK_SET); + + /*check that we can't write data beyond 5K into xloop device*/ + TEST(write(dev_fd, wrbuf, OLD_SIZE)); + if (TST_RET == NEW_SIZE) { + tst_res(TPASS, "XLOOP_SET_CAPACITY set xloop size to %d", NEW_SIZE); + } else { + tst_res(TFAIL, "XLOOP_SET_CAPACITY didn't set xloop size to %d, its size is %ld", + NEW_SIZE, TST_RET); + } + + TST_ASSERT_INT(sys_xloop_sizepath, NEW_SIZE/512); + + SAFE_CLOSE(file_fd); + tst_detach_device_by_fd(dev_path, dev_fd); + unlink("test.img"); + attach_flag = 0; +} + +static void setup(void) +{ + dev_num = tst_find_free_xloopdev(dev_path, sizeof(dev_path)); + if (dev_num < 0) + tst_brk(TBROK, "Failed to find free xloop device"); + + wrbuf = SAFE_MALLOC(OLD_SIZE); + memset(wrbuf, 'x', OLD_SIZE); + sprintf(sys_xloop_sizepath, "/sys/block/xloop%d/size", dev_num); + dev_fd = SAFE_OPEN(dev_path, O_RDWR); +} + +static void cleanup(void) +{ + if (dev_fd > 0) + SAFE_CLOSE(dev_fd); + if (file_fd > 0) + SAFE_CLOSE(file_fd); + if (wrbuf) + free(wrbuf); + if (attach_flag) + tst_detach_device(dev_path); +} + +static struct tst_test test = { + .setup = setup, + .cleanup = cleanup, + .test_all = verify_ioctl_xloop, + .needs_root = 1, + .needs_tmpdir = 1, + .needs_drivers = (const char *const []) { + "xloop", + "xloop_file_fmt_raw", + NULL + } +}; diff --git a/kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_xloop05.c b/kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_xloop05.c new file mode 100644 index 0000000..62ee0c8 --- /dev/null +++ b/kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_xloop05.c @@ -0,0 +1,156 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2020 FUJITSU LIMITED. All rights reserved. + * Author: Yang Xu + * + * This is a basic ioctl test about xloopdevice. + * + * It is designed to test XLOOP_SET_DIRECT_IO can update a live + * xloop device dio mode. It needs the backing file also supports + * dio mode and the xlo_offset is aligned with the logical block size. + * + * The direct I/O error handling is a bit messy on Linux, some filesystems + * return error when it coudln't be enabled, some silently fall back to regular + * buffered I/O. + * + * The XLOOP_SET_DIRECT_IO ioctl() may ignore all checks if it cannot get the + * logical block size which is the case if the block device pointer in the + * backing file inode is not set. In this case the direct I/O appears to be + * enabled but falls back to buffered I/O later on. This is the case at least + * for Btrfs. Because of that the test passes both with failure as well as + * success with non-zero offset. + */ + +#include +#include +#include +#include +#include +#include "lapi/xloop.h" +#include "tst_test.h" + +#define DIO_MESSAGE "In dio mode" +#define NON_DIO_MESSAGE "In non dio mode" + +static char dev_path[1024], sys_xloop_diopath[1024], backing_file_path[1024];; +static int dev_num, dev_fd, block_devfd, attach_flag, logical_block_size; + +static void check_dio_value(int flag) +{ + struct xloop_info xloopinfoget; + + memset(&xloopinfoget, 0, sizeof(xloopinfoget)); + + SAFE_IOCTL(dev_fd, XLOOP_GET_STATUS, &xloopinfoget); + tst_res(TINFO, "%s", flag ? DIO_MESSAGE : NON_DIO_MESSAGE); + + if (xloopinfoget.xlo_flags & XLO_FLAGS_DIRECT_IO) + tst_res(flag ? TPASS : TFAIL, "xlo_flags has XLO_FLAGS_DIRECT_IO flag"); + else + tst_res(flag ? TFAIL : TPASS, "xlo_flags doesn't have XLO_FLAGS_DIRECT_IO flag"); + + TST_ASSERT_INT(sys_xloop_diopath, flag); +} + +static void verify_ioctl_xloop(void) +{ + struct xloop_info xloopinfo; + + memset(&xloopinfo, 0, sizeof(xloopinfo)); + TST_RETRY_FUNC(ioctl(dev_fd, XLOOP_SET_STATUS, &xloopinfo), TST_RETVAL_EQ0); + + tst_res(TINFO, "Without setting xlo_offset or sizelimit"); + SAFE_IOCTL(dev_fd, XLOOP_SET_DIRECT_IO, 1); + check_dio_value(1); + + SAFE_IOCTL(dev_fd, XLOOP_SET_DIRECT_IO, 0); + check_dio_value(0); + + tst_res(TINFO, "With offset equal to logical_block_size"); + xloopinfo.xlo_offset = logical_block_size; + TST_RETRY_FUNC(ioctl(dev_fd, XLOOP_SET_STATUS, &xloopinfo), TST_RETVAL_EQ0); + TEST(ioctl(dev_fd, XLOOP_SET_DIRECT_IO, 1)); + if (TST_RET == 0) { + tst_res(TPASS, "XLOOP_SET_DIRECT_IO succeeded"); + check_dio_value(1); + SAFE_IOCTL(dev_fd, XLOOP_SET_DIRECT_IO, 0); + } else { + tst_res(TFAIL | TTERRNO, "XLOOP_SET_DIRECT_IO failed"); + } + + tst_res(TINFO, "With nonzero offset less than logical_block_size"); + xloopinfo.xlo_offset = logical_block_size / 2; + TST_RETRY_FUNC(ioctl(dev_fd, XLOOP_SET_STATUS, &xloopinfo), TST_RETVAL_EQ0); + + TEST(ioctl(dev_fd, XLOOP_SET_DIRECT_IO, 1)); + if (TST_RET == 0) { + tst_res(TPASS, "XLOOP_SET_DIRECT_IO succeeded, offset is ignored"); + SAFE_IOCTL(dev_fd, XLOOP_SET_DIRECT_IO, 0); + return; + } + if (TST_ERR == EINVAL) + tst_res(TPASS | TTERRNO, "XLOOP_SET_DIRECT_IO failed as expected"); + else + tst_res(TFAIL | TTERRNO, "XLOOP_SET_DIRECT_IO failed expected EINVAL got"); +} + +static void setup(void) +{ + char bd_path[100]; + + if (tst_fs_type(".") == TST_TMPFS_MAGIC) + tst_brk(TCONF, "tmpfd doesn't support O_DIRECT flag"); + + dev_num = tst_find_free_xloopdev(dev_path, sizeof(dev_path)); + if (dev_num < 0) + tst_brk(TBROK, "Failed to find free xloop device"); + + sprintf(sys_xloop_diopath, "/sys/block/xloop%d/xloop/dio", dev_num); + tst_fill_file("test.img", 0, 1024, 1024); + + tst_attach_device(dev_path, "test.img"); + attach_flag = 1; + dev_fd = SAFE_OPEN(dev_path, O_RDWR); + + if (ioctl(dev_fd, XLOOP_SET_DIRECT_IO, 0) && errno == EINVAL) + tst_brk(TCONF, "XLOOP_SET_DIRECT_IO is not supported"); + + /* + * from __xloop_update_dio(): + * We support direct I/O only if xlo_offset is aligned with the + * logical I/O size of backing device, and the logical block + * size of xloop is bigger than the backing device's and the xloop + * needn't transform transfer. + */ + sprintf(backing_file_path, "%s/test.img", tst_get_tmpdir()); + tst_find_backing_dev(backing_file_path, bd_path); + block_devfd = SAFE_OPEN(bd_path, O_RDWR); + SAFE_IOCTL(block_devfd, BLKSSZGET, &logical_block_size); + tst_res(TINFO, "backing dev(%s) logical_block_size is %d", bd_path, logical_block_size); + SAFE_CLOSE(block_devfd); + if (logical_block_size > 512) + TST_RETRY_FUNC(ioctl(dev_fd, XLOOP_SET_BLOCK_SIZE, logical_block_size), TST_RETVAL_EQ0); +} + +static void cleanup(void) +{ + if (dev_fd > 0) + SAFE_CLOSE(dev_fd); + if (block_devfd > 0) + SAFE_CLOSE(block_devfd); + if (attach_flag) + tst_detach_device(dev_path); +} + +static struct tst_test test = { + .setup = setup, + .cleanup = cleanup, + .test_all = verify_ioctl_xloop, + .needs_root = 1, + .needs_tmpdir = 1, + .needs_drivers = (const char *const []) { + "xloop", + "xloop_file_fmt_raw", + NULL + } +}; diff --git a/kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_xloop06.c b/kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_xloop06.c new file mode 100644 index 0000000..4bfa63e --- /dev/null +++ b/kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_xloop06.c @@ -0,0 +1,144 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2020 FUJITSU LIMITED. All rights reserved. + * Author: Yang Xu + * + * This is a basic error test about the invalid block size of xloopdevice + * by using XLOOP_SET_BLOCK_SIZE or XLOOP_CONFIGURE ioctl. + */ + +#include +#include +#include +#include +#include "lapi/xloop.h" +#include "tst_test.h" + +static char dev_path[1024]; +static int dev_num, dev_fd, file_fd, attach_flag, xloop_configure_sup = 1; +static unsigned int invalid_value, half_value, unalign_value; +static struct xloop_config xloopconfig; + +static struct tcase { + unsigned int *setvalue; + int ioctl_flag; + char *message; +} tcases[] = { + {&half_value, XLOOP_SET_BLOCK_SIZE, + "Using XLOOP_SET_BLOCK_SIZE with arg < 512"}, + + {&invalid_value, XLOOP_SET_BLOCK_SIZE, + "Using XLOOP_SET_BLOCK_SIZE with arg > PAGE_SIZE"}, + + {&unalign_value, XLOOP_SET_BLOCK_SIZE, + "Using XLOOP_SET_BLOCK_SIZE with arg != power_of_2"}, + + {&half_value, XLOOP_CONFIGURE, + "Using XLOOP_CONFIGURE with block_size < 512"}, + + {&invalid_value, XLOOP_CONFIGURE, + "Using XLOOP_CONFIGURE with block_size > PAGE_SIZE"}, + + {&unalign_value, XLOOP_CONFIGURE, + "Using XLOOP_CONFIGURE with block_size != power_of_2"}, +}; + +static void verify_ioctl_xloop(unsigned int n) +{ + if (tcases[n].ioctl_flag == XLOOP_CONFIGURE) + TEST(ioctl(dev_fd, XLOOP_CONFIGURE, &xloopconfig)); + else + TEST(ioctl(dev_fd, XLOOP_SET_BLOCK_SIZE, *(tcases[n].setvalue))); + + if (TST_RET == 0) { + tst_res(TFAIL, "Set block size succeed unexpectedly"); + if (tcases[n].ioctl_flag == XLOOP_CONFIGURE) + tst_detach_device_by_fd(dev_path, dev_fd); + return; + } + if (TST_ERR == EINVAL) + tst_res(TPASS | TTERRNO, "Set block size failed as expected"); + else + tst_res(TFAIL | TTERRNO, "Set block size failed expected EINVAL got"); +} + +static void run(unsigned int n) +{ + struct tcase *tc = &tcases[n]; + + tst_res(TINFO, "%s", tc->message); + if (tc->ioctl_flag == XLOOP_SET_BLOCK_SIZE) { + if (!attach_flag) { + tst_attach_device(dev_path, "test.img"); + attach_flag = 1; + } + verify_ioctl_xloop(n); + return; + } + + if (tc->ioctl_flag == XLOOP_CONFIGURE && !xloop_configure_sup) { + tst_res(TCONF, "XLOOP_CONFIGURE ioctl not supported"); + return; + } + if (attach_flag) { + tst_detach_device_by_fd(dev_path, dev_fd); + attach_flag = 0; + } + xloopconfig.block_size = *(tc->setvalue); + verify_ioctl_xloop(n); +} + +static void setup(void) +{ + unsigned int pg_size; + int ret; + + dev_num = tst_find_free_xloopdev(dev_path, sizeof(dev_path)); + if (dev_num < 0) + tst_brk(TBROK, "Failed to find free xloop device"); + + tst_fill_file("test.img", 0, 1024, 1024); + half_value = 256; + pg_size = getpagesize(); + invalid_value = pg_size * 2 ; + unalign_value = pg_size - 1; + + dev_fd = SAFE_OPEN(dev_path, O_RDWR); + + if (ioctl(dev_fd, XLOOP_SET_BLOCK_SIZE, 512) && errno == EINVAL) + tst_brk(TCONF, "XLOOP_SET_BLOCK_SIZE is not supported"); + + file_fd = SAFE_OPEN("test.img", O_RDWR); + xloopconfig.fd = -1; + ret = ioctl(dev_fd, XLOOP_CONFIGURE, &xloopconfig); + if (ret && errno != EBADF) { + tst_res(TINFO | TERRNO, "XLOOP_CONFIGURE is not supported"); + xloop_configure_sup = 0; + return; + } + xloopconfig.fd = file_fd; +} + +static void cleanup(void) +{ + if (dev_fd > 0) + SAFE_CLOSE(dev_fd); + if (file_fd > 0) + SAFE_CLOSE(file_fd); + if (attach_flag) + tst_detach_device(dev_path); +} + +static struct tst_test test = { + .setup = setup, + .cleanup = cleanup, + .test = run, + .tcnt = ARRAY_SIZE(tcases), + .needs_root = 1, + .needs_tmpdir = 1, + .needs_drivers = (const char *const []) { + "xloop", + "xloop_file_fmt_raw", + NULL + } +}; diff --git a/kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_xloop07.c b/kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_xloop07.c new file mode 100644 index 0000000..b51a970 --- /dev/null +++ b/kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_xloop07.c @@ -0,0 +1,96 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2020 FUJITSU LIMITED. All rights reserved. + * Author: Yang Xu + * + * This is a basic ioctl test about xloopdevice XLOOP_SET_STATUS64 + * and XLOOP_GET_STATUS64. + * Test its xlo_sizelimit field. If xlo_sizelimit is 0,it means max + * available. If sizelimit is less than xloop_size, xloopsize will + * be truncated. + */ + +#include +#include +#include +#include +#include "lapi/xloop.h" +#include "tst_test.h" + +static char dev_path[1024], sys_xloop_sizepath[1024], sys_xloop_sizelimitpath[1024]; +static int dev_num, dev_fd, file_fd, attach_flag; + +static struct tcase { + unsigned int set_sizelimit; + unsigned int exp_xloopsize; + char *message; +} tcases[] = { + {1024 * 4096, 2048, "When sizelimit is greater than xloopsize "}, + {1024 * 512, 1024, "When sizelimit is less than xloopsize"}, +}; + +static void verify_ioctl_xloop(unsigned int n) +{ + struct tcase *tc = &tcases[n]; + struct xloop_info64 xloopinfo, xloopinfoget; + + tst_res(TINFO, "%s", tc->message); + memset(&xloopinfo, 0, sizeof(xloopinfo)); + memset(&xloopinfoget, 0, sizeof(xloopinfoget)); + + xloopinfo.xlo_sizelimit = tc->set_sizelimit; + TST_RETRY_FUNC(ioctl(dev_fd, XLOOP_SET_STATUS64, &xloopinfo), TST_RETVAL_EQ0); + + TST_ASSERT_INT(sys_xloop_sizepath, tc->exp_xloopsize); + TST_ASSERT_INT(sys_xloop_sizelimitpath, tc->set_sizelimit); + SAFE_IOCTL(dev_fd, XLOOP_GET_STATUS64, &xloopinfoget); + if (xloopinfoget.xlo_sizelimit == tc->set_sizelimit) + tst_res(TPASS, "XLOOP_GET_STATUS64 gets correct xlo_sizelimit(%d)", tc->set_sizelimit); + else + tst_res(TFAIL, "XLOOP_GET_STATUS64 gets wrong xlo_sizelimit(%llu), expect %d", + xloopinfoget.xlo_sizelimit, tc->set_sizelimit); + /*Reset*/ + xloopinfo.xlo_sizelimit = 0; + TST_RETRY_FUNC(ioctl(dev_fd, XLOOP_SET_STATUS, &xloopinfo), TST_RETVAL_EQ0); +} + +static void setup(void) +{ + dev_num = tst_find_free_xloopdev(dev_path, sizeof(dev_path)); + if (dev_num < 0) + tst_brk(TBROK, "Failed to find free xloop device"); + + tst_fill_file("test.img", 0, 1024 * 1024, 1); + tst_attach_device(dev_path, "test.img"); + attach_flag = 1; + + sprintf(sys_xloop_sizepath, "/sys/block/xloop%d/size", dev_num); + sprintf(sys_xloop_sizelimitpath, "/sys/block/xloop%d/xloop/sizelimit", dev_num); + + dev_fd = SAFE_OPEN(dev_path, O_RDWR); + tst_res(TINFO, "original xloop size 2048 sectors"); +} + +static void cleanup(void) +{ + if (dev_fd > 0) + SAFE_CLOSE(dev_fd); + if (file_fd > 0) + SAFE_CLOSE(file_fd); + if (attach_flag) + tst_detach_device(dev_path); +} + +static struct tst_test test = { + .setup = setup, + .cleanup = cleanup, + .test = verify_ioctl_xloop, + .tcnt = ARRAY_SIZE(tcases), + .needs_root = 1, + .needs_tmpdir = 1, + .needs_drivers = (const char *const []) { + "xloop", + "xloop_file_fmt_raw", + NULL + } +}; -- cgit v1.2.3-55-g7522