summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorManuel Bentele2020-09-11 12:32:49 +0200
committerManuel Bentele2020-09-16 07:37:56 +0200
commita4e8885458c4921ad0f6a16ead10dbb557af35f6 (patch)
treeca89c564febb4dd6c507f9d3b1df8f47222e9e98
parentAdded testcases from the Linux testing project (LTP) (diff)
downloadxloop-a4e8885458c4921ad0f6a16ead10dbb557af35f6.tar.gz
xloop-a4e8885458c4921ad0f6a16ead10dbb557af35f6.tar.xz
xloop-a4e8885458c4921ad0f6a16ead10dbb557af35f6.zip
Renamed loop to xloop in all LTP kernel tests
-rw-r--r--kernel/tests/CMakeLists.txt1
-rw-r--r--kernel/tests/include/lapi/xloop.h (renamed from kernel/tests/include/lapi/loop.h)6
-rw-r--r--kernel/tests/include/tst_device.h20
-rw-r--r--kernel/tests/lib/tst_device.c66
-rw-r--r--kernel/tests/testcases/kernel/syscalls/ioctl/CMakeLists.txt16
-rw-r--r--kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_loop01.c155
-rw-r--r--kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_loop05.c155
-rw-r--r--kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_loop07.c95
-rw-r--r--kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_xloop01.c156
-rw-r--r--kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_xloop02.c (renamed from kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_loop02.c)89
-rw-r--r--kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_xloop03.c (renamed from kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_loop03.c)37
-rw-r--r--kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_xloop04.c (renamed from kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_loop04.c)45
-rw-r--r--kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_xloop05.c156
-rw-r--r--kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_xloop06.c (renamed from kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_loop06.c)77
-rw-r--r--kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_xloop07.c96
15 files changed, 589 insertions, 581 deletions
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/xloop.h
index 87a9023..8e57b31 100644
--- a/kernel/tests/include/lapi/loop.h
+++ b/kernel/tests/include/lapi/xloop.h
@@ -8,7 +8,7 @@
#include "config.h"
#include <linux/types.h>
-#include <linux/loop.h>
+#include <linux/xloop.h>
#ifndef LO_FLAGS_PARTSCAN
# define LO_FLAGS_PARTSCAN 8
@@ -44,10 +44,10 @@
* 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 {
+struct xloop_config {
__u32 fd;
__u32 block_size;
- struct loop_info64 info;
+ struct xloop_info64 info;
__u64 __reserved[8];
};
#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 <errno.h>
#include <unistd.h>
#include <stdlib.h>
-#include <linux/loop.h>
+#include <linux/xloop.h>
#include <stdint.h>
#include <inttypes.h>
#include <sys/sysmacros.h>
@@ -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 <xuyang2018.jy@cn.jujitsu.com>
- *
- * 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 <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#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_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 <xuyang2018.jy@cn.jujitsu.com>
- *
- * 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 <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdlib.h>
-#include <sys/mount.h>
-#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_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 <xuyang2018.jy@cn.jujitsu.com>
- *
- * 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 <stdio.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <stdlib.h>
-#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 <xuyang2018.jy@cn.jujitsu.com>
+ *
+ * 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 <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#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_loop02.c b/kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_xloop02.c
index ac61842..895f7f2 100644
--- a/kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_loop02.c
+++ b/kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_xloop02.c
@@ -3,16 +3,16 @@
* Copyright (c) 2020 FUJITSU LIMITED. All rights reserved.
* Author: Yang Xu <xuyang2018.jy@cn.jujitsu.com>
*
- * This is a basic ioctl test about loopdevice.
+ * This is a basic ioctl test about xloopdevice.
*
- * It is designed to test LO_FLAGS_READ_ONLY (similar as losetup -r)
- * and LOOP_CHANGE_FD.
+ * It is designed to test XLO_FLAGS_READ_ONLY (similar as xlosetup -r)
+ * and XLOOP_CHANGE_FD.
*
- * For LOOP_CHANGE_FD, this operation is possible only if the loop device
+ * 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 LOOP_CONFIGURE ioctl, we can set LO_FLAGS_READ_ONLY
+ * If using XLOOP_CONFIGURE ioctl, we can set XLO_FLAGS_READ_ONLY
* flag even though backing file with write mode.
*/
@@ -20,56 +20,56 @@
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
-#include "lapi/loop.h"
+#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, loop_configure_sup = 1;
-static char loop_ro_path[1024], dev_path[1024];
-static struct loop_config loopconfig;
+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, LOOP_SET_FD, "Using LOOP_SET_FD to setup loopdevice"},
- {O_RDWR, LOOP_CONFIGURE, "Using LOOP_CONFIGURE with read_only flag"},
+ {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_loop(unsigned int n)
+static void verify_ioctl_xloop(unsigned int n)
{
struct tcase *tc = &tcases[n];
- struct loop_info loopinfoget;
+ struct xloop_info xloopinfoget;
- if (tc->ioctl == LOOP_CONFIGURE && !loop_configure_sup) {
- tst_res(TCONF, "LOOP_CONFIGURE ioctl not supported");
+ 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 == LOOP_SET_FD) {
- SAFE_IOCTL(dev_fd, LOOP_SET_FD, file_fd);
+ if (tc->ioctl == XLOOP_SET_FD) {
+ SAFE_IOCTL(dev_fd, XLOOP_SET_FD, file_fd);
} else {
- loopconfig.fd = file_fd;
- SAFE_IOCTL(dev_fd, LOOP_CONFIGURE, &loopconfig);
+ xloopconfig.fd = file_fd;
+ SAFE_IOCTL(dev_fd, XLOOP_CONFIGURE, &xloopconfig);
}
attach_flag = 1;
- TST_ASSERT_INT(loop_ro_path, 1);
+ TST_ASSERT_INT(xloop_ro_path, 1);
TST_ASSERT_STR(backing_path, backing_file_path);
- memset(&loopinfoget, 0, sizeof(loopinfoget));
+ memset(&xloopinfoget, 0, sizeof(xloopinfoget));
- SAFE_IOCTL(dev_fd, LOOP_GET_STATUS, &loopinfoget);
+ SAFE_IOCTL(dev_fd, XLOOP_GET_STATUS, &xloopinfoget);
- if (loopinfoget.lo_flags & ~LO_FLAGS_READ_ONLY)
- tst_res(TFAIL, "lo_flags has unexpected %d flag", loopinfoget.lo_flags);
+ if (xloopinfoget.xlo_flags & ~XLO_FLAGS_READ_ONLY)
+ tst_res(TFAIL, "xlo_flags has unexpected %d flag", xloopinfoget.xlo_flags);
else
- tst_res(TPASS, "lo_flags only has default LO_FLAGS_READ_ONLY flag");
+ tst_res(TPASS, "xlo_flags only has default XLO_FLAGS_READ_ONLY flag");
TEST(write(dev_fd, "xx", 2));
if (TST_RET != -1)
@@ -77,23 +77,23 @@ static void verify_ioctl_loop(unsigned int n)
else
tst_res(TPASS | TTERRNO, "Can not write data in RO mode");
- TEST(ioctl(dev_fd, LOOP_CHANGE_FD, file_change_fd));
+ TEST(ioctl(dev_fd, XLOOP_CHANGE_FD, file_change_fd));
if (TST_RET) {
- tst_res(TFAIL | TTERRNO, "LOOP_CHANGE_FD failed");
+ tst_res(TFAIL | TTERRNO, "XLOOP_CHANGE_FD failed");
} else {
- tst_res(TPASS, "LOOP_CHANGE_FD succeeded");
- TST_ASSERT_INT(loop_ro_path, 1);
+ 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, LOOP_CHANGE_FD, file_fd_invalid));
+ TEST(ioctl(dev_fd, XLOOP_CHANGE_FD, file_fd_invalid));
if (TST_RET) {
if (TST_ERR == EINVAL)
- tst_res(TPASS | TTERRNO, "LOOP_CHANGE_FD failed as expected");
+ tst_res(TPASS | TTERRNO, "XLOOP_CHANGE_FD failed as expected");
else
- tst_res(TFAIL | TTERRNO, "LOOP_CHANGE_FD failed expected EINVAL got");
+ tst_res(TFAIL | TTERRNO, "XLOOP_CHANGE_FD failed expected EINVAL got");
} else {
- tst_res(TFAIL, "LOOP_CHANGE_FD succeeded");
+ tst_res(TFAIL, "XLOOP_CHANGE_FD succeeded");
}
SAFE_CLOSE(file_fd);
@@ -107,18 +107,18 @@ static void setup(void)
int ret;
char *tmpdir = tst_get_tmpdir();
- dev_num = tst_find_free_loopdev(dev_path, sizeof(dev_path));
+ dev_num = tst_find_free_xloopdev(dev_path, sizeof(dev_path));
if (dev_num < 0)
- tst_brk(TBROK, "Failed to find free loop device");
+ 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/loop%d/loop/backing_file", dev_num);
+ 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(loop_ro_path, "/sys/block/loop%d/ro", dev_num);
+ sprintf(xloop_ro_path, "/sys/block/xloop%d/ro", dev_num);
free(tmpdir);
@@ -126,14 +126,14 @@ static void setup(void)
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);
+ xloopconfig.fd = -1;
+ ret = ioctl(dev_fd, XLOOP_CONFIGURE, &xloopconfig);
if (ret && errno != EBADF) {
- tst_res(TINFO | TERRNO, "LOOP_CONFIGURE is not supported");
- loop_configure_sup = 0;
+ tst_res(TINFO | TERRNO, "XLOOP_CONFIGURE is not supported");
+ xloop_configure_sup = 0;
}
- loopconfig.info.lo_flags = LO_FLAGS_READ_ONLY;
+ xloopconfig.info.xlo_flags = XLO_FLAGS_READ_ONLY;
}
static void cleanup(void)
@@ -154,11 +154,12 @@ static struct tst_test test = {
.setup = setup,
.cleanup = cleanup,
.tcnt = ARRAY_SIZE(tcases),
- .test = verify_ioctl_loop,
+ .test = verify_ioctl_xloop,
.needs_root = 1,
.needs_tmpdir = 1,
.needs_drivers = (const char *const []) {
- "loop",
+ "xloop",
+ "xloop_file_fmt_raw",
NULL
}
};
diff --git a/kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_loop03.c b/kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_xloop03.c
index 9cf5a41..9447cbc 100644
--- a/kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_loop03.c
+++ b/kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_xloop03.c
@@ -3,42 +3,42 @@
* Copyright (c) 2020 FUJITSU LIMITED. All rights reserved.
* Author: Yang Xu <xuyang2018.jy@cn.jujitsu.com>
*
- * This is a basic ioctl test about loopdevice.
+ * This is a basic ioctl test about xloopdevice.
*
- * It is designed to test LOOP_CHANGE_FD can not succeed (get EINVAL error)
- * when loop_dev is not read only.
+ * It is designed to test XLOOP_CHANGE_FD can not succeed (get EINVAL error)
+ * when xloop_dev is not read only.
*/
#include <stdio.h>
#include <unistd.h>
#include <string.h>
-#include "lapi/loop.h"
+#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_loop(void)
+static void verify_ioctl_xloop(void)
{
- TEST(ioctl(dev_fd, LOOP_CHANGE_FD, file_fd));
+ TEST(ioctl(dev_fd, XLOOP_CHANGE_FD, file_fd));
if (TST_RET == 0) {
- tst_res(TFAIL, "LOOP_CHANGE_FD succeeded unexpectedly");
+ tst_res(TFAIL, "XLOOP_CHANGE_FD succeeded unexpectedly");
return;
}
if (TST_ERR == EINVAL)
- tst_res(TPASS | TTERRNO, "LOOP_CHANGE_FD failed as expected");
+ tst_res(TPASS | TTERRNO, "XLOOP_CHANGE_FD failed as expected");
else
- tst_res(TFAIL | TTERRNO, "LOOP_CHANGE_FD failed expected EINVAL got");
+ tst_res(TFAIL | TTERRNO, "XLOOP_CHANGE_FD failed expected EINVAL got");
}
static void setup(void)
{
- struct loop_info loopinfoget;
+ struct xloop_info xloopinfoget;
- memset(&loopinfoget, 0, sizeof(loopinfoget));
- dev_num = tst_find_free_loopdev(dev_path, sizeof(dev_path));
+ 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 loop device");
+ tst_brk(TBROK, "Failed to find free xloop device");
tst_fill_file("test.img", 0, 1024, 10);
tst_attach_device(dev_path, "test.img");
@@ -46,10 +46,10 @@ static void setup(void)
dev_fd = SAFE_OPEN(dev_path, O_RDWR);
file_fd = SAFE_OPEN("test.img", O_RDWR);
- SAFE_IOCTL(dev_fd, LOOP_GET_STATUS, &loopinfoget);
+ SAFE_IOCTL(dev_fd, XLOOP_GET_STATUS, &xloopinfoget);
- if (loopinfoget.lo_flags & LO_FLAGS_READ_ONLY)
- tst_brk(TCONF, "Current environment has unexpected LO_FLAGS_READ_ONLY flag");
+ if (xloopinfoget.xlo_flags & XLO_FLAGS_READ_ONLY)
+ tst_brk(TCONF, "Current environment has unexpected XLO_FLAGS_READ_ONLY flag");
}
static void cleanup(void)
@@ -65,11 +65,12 @@ static void cleanup(void)
static struct tst_test test = {
.setup = setup,
.cleanup = cleanup,
- .test_all = verify_ioctl_loop,
+ .test_all = verify_ioctl_xloop,
.needs_root = 1,
.needs_tmpdir = 1,
.needs_drivers = (const char *const []) {
- "loop",
+ "xloop",
+ "xloop_file_fmt_raw",
NULL
}
};
diff --git a/kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_loop04.c b/kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_xloop04.c
index b4ab44a..adf5cdf 100644
--- a/kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_loop04.c
+++ b/kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_xloop04.c
@@ -3,57 +3,57 @@
* Copyright (c) 2020 FUJITSU LIMITED. All rights reserved.
* Author: Yang Xu <xuyang2018.jy@cn.jujitsu.com>
*
- * This is a basic ioctl test about loopdevice.
+ * This is a basic ioctl test about xloopdevice.
*
- * It is designed to test LOOP_SET_CAPACITY can update a live
- * loop device size when we change the size of the underlying
+ * 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 <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
-#include "lapi/loop.h"
+#include "lapi/xloop.h"
#include "tst_test.h"
#define OLD_SIZE 10240
#define NEW_SIZE 5120
-static char dev_path[1024], sys_loop_sizepath[1024];
+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_loop(void)
+static void verify_ioctl_xloop(void)
{
- struct loop_info loopinfoget;
+ struct xloop_info xloopinfoget;
- memset(&loopinfoget, 0, sizeof(loopinfoget));
+ 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_loop_sizepath, OLD_SIZE/512);
+ TST_ASSERT_INT(sys_xloop_sizepath, OLD_SIZE/512);
file_fd = SAFE_OPEN("test.img", O_RDWR);
- SAFE_IOCTL(dev_fd, LOOP_GET_STATUS, &loopinfoget);
+ SAFE_IOCTL(dev_fd, XLOOP_GET_STATUS, &xloopinfoget);
- if (loopinfoget.lo_flags & LO_FLAGS_READ_ONLY)
- tst_brk(TCONF, "Current environment has unexpected LO_FLAGS_READ_ONLY flag");
+ 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, LOOP_SET_CAPACITY);
+ SAFE_IOCTL(dev_fd, XLOOP_SET_CAPACITY);
SAFE_LSEEK(dev_fd, 0, SEEK_SET);
- /*check that we can't write data beyond 5K into loop device*/
+ /*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, "LOOP_SET_CAPACITY set loop size to %d", NEW_SIZE);
+ tst_res(TPASS, "XLOOP_SET_CAPACITY set xloop size to %d", NEW_SIZE);
} else {
- tst_res(TFAIL, "LOOP_SET_CAPACITY didn't set loop size to %d, its size is %ld",
+ 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_loop_sizepath, NEW_SIZE/512);
+ TST_ASSERT_INT(sys_xloop_sizepath, NEW_SIZE/512);
SAFE_CLOSE(file_fd);
tst_detach_device_by_fd(dev_path, dev_fd);
@@ -63,13 +63,13 @@ static void verify_ioctl_loop(void)
static void setup(void)
{
- dev_num = tst_find_free_loopdev(dev_path, sizeof(dev_path));
+ dev_num = tst_find_free_xloopdev(dev_path, sizeof(dev_path));
if (dev_num < 0)
- tst_brk(TBROK, "Failed to find free loop device");
+ tst_brk(TBROK, "Failed to find free xloop device");
wrbuf = SAFE_MALLOC(OLD_SIZE);
memset(wrbuf, 'x', OLD_SIZE);
- sprintf(sys_loop_sizepath, "/sys/block/loop%d/size", dev_num);
+ sprintf(sys_xloop_sizepath, "/sys/block/xloop%d/size", dev_num);
dev_fd = SAFE_OPEN(dev_path, O_RDWR);
}
@@ -88,11 +88,12 @@ static void cleanup(void)
static struct tst_test test = {
.setup = setup,
.cleanup = cleanup,
- .test_all = verify_ioctl_loop,
+ .test_all = verify_ioctl_xloop,
.needs_root = 1,
.needs_tmpdir = 1,
.needs_drivers = (const char *const []) {
- "loop",
+ "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 <xuyang2018.jy@cn.jujitsu.com>
+ *
+ * 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 <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/mount.h>
+#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_loop06.c b/kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_xloop06.c
index bd0d289..4bfa63e 100644
--- a/kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_loop06.c
+++ b/kernel/tests/testcases/kernel/syscalls/ioctl/ioctl_xloop06.c
@@ -3,56 +3,56 @@
* Copyright (c) 2020 FUJITSU LIMITED. All rights reserved.
* Author: Yang Xu <xuyang2018.jy@cn.jujitsu.com>
*
- * This is a basic error test about the invalid block size of loopdevice
- * by using LOOP_SET_BLOCK_SIZE or LOOP_CONFIGURE ioctl.
+ * This is a basic error test about the invalid block size of xloopdevice
+ * by using XLOOP_SET_BLOCK_SIZE or XLOOP_CONFIGURE ioctl.
*/
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
-#include "lapi/loop.h"
+#include "lapi/xloop.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 int dev_num, dev_fd, file_fd, attach_flag, xloop_configure_sup = 1;
static unsigned int invalid_value, half_value, unalign_value;
-static struct loop_config loopconfig;
+static struct xloop_config xloopconfig;
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"},
+ {&half_value, XLOOP_SET_BLOCK_SIZE,
+ "Using XLOOP_SET_BLOCK_SIZE with arg < 512"},
- {&invalid_value, LOOP_SET_BLOCK_SIZE,
- "Using LOOP_SET_BLOCK_SIZE with arg > PAGE_SIZE"},
+ {&invalid_value, XLOOP_SET_BLOCK_SIZE,
+ "Using XLOOP_SET_BLOCK_SIZE with arg > PAGE_SIZE"},
- {&unalign_value, LOOP_SET_BLOCK_SIZE,
- "Using LOOP_SET_BLOCK_SIZE with arg != power_of_2"},
+ {&unalign_value, XLOOP_SET_BLOCK_SIZE,
+ "Using XLOOP_SET_BLOCK_SIZE with arg != power_of_2"},
- {&half_value, LOOP_CONFIGURE,
- "Using LOOP_CONFIGURE with block_size < 512"},
+ {&half_value, XLOOP_CONFIGURE,
+ "Using XLOOP_CONFIGURE with block_size < 512"},
- {&invalid_value, LOOP_CONFIGURE,
- "Using LOOP_CONFIGURE with block_size > PAGE_SIZE"},
+ {&invalid_value, XLOOP_CONFIGURE,
+ "Using XLOOP_CONFIGURE with block_size > PAGE_SIZE"},
- {&unalign_value, LOOP_CONFIGURE,
- "Using LOOP_CONFIGURE with block_size != power_of_2"},
+ {&unalign_value, XLOOP_CONFIGURE,
+ "Using XLOOP_CONFIGURE with block_size != power_of_2"},
};
-static void verify_ioctl_loop(unsigned int n)
+static void verify_ioctl_xloop(unsigned int n)
{
- if (tcases[n].ioctl_flag == LOOP_CONFIGURE)
- TEST(ioctl(dev_fd, LOOP_CONFIGURE, &loopconfig));
+ if (tcases[n].ioctl_flag == XLOOP_CONFIGURE)
+ TEST(ioctl(dev_fd, XLOOP_CONFIGURE, &xloopconfig));
else
- TEST(ioctl(dev_fd, LOOP_SET_BLOCK_SIZE, *(tcases[n].setvalue)));
+ 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 == LOOP_CONFIGURE)
+ if (tcases[n].ioctl_flag == XLOOP_CONFIGURE)
tst_detach_device_by_fd(dev_path, dev_fd);
return;
}
@@ -67,25 +67,25 @@ 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 (tc->ioctl_flag == XLOOP_SET_BLOCK_SIZE) {
if (!attach_flag) {
tst_attach_device(dev_path, "test.img");
attach_flag = 1;
}
- verify_ioctl_loop(n);
+ verify_ioctl_xloop(n);
return;
}
- if (tc->ioctl_flag == LOOP_CONFIGURE && !loop_configure_sup) {
- tst_res(TCONF, "LOOP_CONFIGURE ioctl not supported");
+ 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;
}
- loopconfig.block_size = *(tc->setvalue);
- verify_ioctl_loop(n);
+ xloopconfig.block_size = *(tc->setvalue);
+ verify_ioctl_xloop(n);
}
static void setup(void)
@@ -93,9 +93,9 @@ static void setup(void)
unsigned int pg_size;
int ret;
- dev_num = tst_find_free_loopdev(dev_path, sizeof(dev_path));
+ dev_num = tst_find_free_xloopdev(dev_path, sizeof(dev_path));
if (dev_num < 0)
- tst_brk(TBROK, "Failed to find free loop device");
+ tst_brk(TBROK, "Failed to find free xloop device");
tst_fill_file("test.img", 0, 1024, 1024);
half_value = 256;
@@ -105,18 +105,18 @@ static void setup(void)
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");
+ 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);
- loopconfig.fd = -1;
- ret = ioctl(dev_fd, LOOP_CONFIGURE, &loopconfig);
+ xloopconfig.fd = -1;
+ ret = ioctl(dev_fd, XLOOP_CONFIGURE, &xloopconfig);
if (ret && errno != EBADF) {
- tst_res(TINFO | TERRNO, "LOOP_CONFIGURE is not supported");
- loop_configure_sup = 0;
+ tst_res(TINFO | TERRNO, "XLOOP_CONFIGURE is not supported");
+ xloop_configure_sup = 0;
return;
}
- loopconfig.fd = file_fd;
+ xloopconfig.fd = file_fd;
}
static void cleanup(void)
@@ -137,7 +137,8 @@ static struct tst_test test = {
.needs_root = 1,
.needs_tmpdir = 1,
.needs_drivers = (const char *const []) {
- "loop",
+ "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 <xuyang2018.jy@cn.jujitsu.com>
+ *
+ * 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 <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <stdlib.h>
+#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
+ }
+};