[LTP] [PATCH] syscalls/ioctl_loop0[23]: TCONF when LOOP_CHANGE_FD is not supported

Avinesh Kumar avinesh.kumar@suse.com
Wed Nov 4 23:14:50 CET 2026


From: Avinesh Kumar <avinesh.kumar@suse.com>

LOOP_CHANGE_FD was removed by d4fabede1da0 ("loop: remove support for
swapping loop fds") n v7.4-rc1 and it fails with EOPNOTSUPP.

ioctl_loop02.c:85: TFAIL: LOOP_CHANGE_FD failed: EOPNOTSUPP (95)
ioctl_loop02.c:97: TFAIL: LOOP_CHANGE_FD failed expected EINVAL got: EOPNOTSUPP (95)

ioctl_loop03.c:34: TFAIL: LOOP_CHANGE_FD failed expected EINVAL got: EOPNOTSUPP (95)

Report TCONF for these checks.

Signed-off-by: Avinesh Kumar <avinesh.kumar@suse.com>
---
 .../kernel/syscalls/ioctl/ioctl_loop02.c      | 49 ++++++++++++-------
 .../kernel/syscalls/ioctl/ioctl_loop03.c      |  6 +++
 2 files changed, 37 insertions(+), 18 deletions(-)

diff --git a/testcases/kernel/syscalls/ioctl/ioctl_loop02.c b/testcases/kernel/syscalls/ioctl/ioctl_loop02.c
index 27f8e6cf968a..d0302efc301f 100644
--- a/testcases/kernel/syscalls/ioctl/ioctl_loop02.c
+++ b/testcases/kernel/syscalls/ioctl/ioctl_loop02.c
@@ -11,7 +11,9 @@
  *
  * 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.
+ * old backing store. The ioctl was removed in Linux v7.4-rc1 by commit
+ * d4fabede1da0 ("loop: remove support for swapping loop fds") and fails with
+ * EOPNOTSUPP since then. The LOOP_CHANGE_FD checks are skipped on such kernels.
  *
  * When using LOOP_CONFIGURE :manpage:`ioctl(2)`, it can set LO_FLAGS_READ_ONLY
  * flag even though backing file with write mode.
@@ -28,7 +30,7 @@ static int file_fd, file_change_fd, file_fd_invalid;
 static char backing_path[1024];
 static char *backing_file_path;
 static char *backing_file_change_path;
-static int attach_flag, dev_fd, loop_configure_sup = 1;
+static int attach_flag, dev_fd, loop_configure_sup = 1, loop_change_fd_sup = 1;
 static char loop_ro_path[1024], dev_path[1024];
 static struct loop_config loopconfig;
 
@@ -80,23 +82,27 @@ 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));
-	if (TST_RET) {
-		tst_res(TFAIL | TTERRNO, "LOOP_CHANGE_FD failed");
+	if (!loop_change_fd_sup) {
+		tst_res(TCONF, "LOOP_CHANGE_FD ioctl not supported");
 	} 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");
+		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);
@@ -134,6 +140,13 @@ static void setup(void)
 		tst_res(TINFO | TERRNO, "LOOP_CONFIGURE is not supported");
 		loop_configure_sup = 0;
 	}
+
+	ret = ioctl(dev_fd, LOOP_CHANGE_FD, -1);
+	if (ret && errno == EOPNOTSUPP) {
+		tst_res(TINFO | TERRNO, "LOOP_CHANGE_FD is not supported");
+		loop_change_fd_sup = 0;
+	}
+
 	loopconfig.info.lo_flags = LO_FLAGS_READ_ONLY;
 }
 
diff --git a/testcases/kernel/syscalls/ioctl/ioctl_loop03.c b/testcases/kernel/syscalls/ioctl/ioctl_loop03.c
index 47f69e800fee..09b5ab3cce9e 100644
--- a/testcases/kernel/syscalls/ioctl/ioctl_loop03.c
+++ b/testcases/kernel/syscalls/ioctl/ioctl_loop03.c
@@ -10,6 +10,10 @@
  *
  * Tests whether LOOP_CHANGE_FD can not succeed (get EINVAL error)
  * when loop_dev is not read only.
+ *
+ * The ioctl was removed in Linux v7.4-rc1 by commit d4fabede1da0 ("loop:
+ * remove support for swapping loop fds") and fails with EOPNOTSUPP since then.
+ * The test reports TCONF on such kernels.
  */
 
 #include <stdio.h>
@@ -28,6 +32,8 @@ static void verify_ioctl_loop(void)
 		tst_res(TFAIL, "LOOP_CHANGE_FD succeeded unexpectedly");
 		return;
 	}
+	if (TST_ERR == EOPNOTSUPP)
+		tst_brk(TCONF | TTERRNO, "LOOP_CHANGE_FD is not supported");
 	if (TST_ERR == EINVAL)
 		tst_res(TPASS | TTERRNO, "LOOP_CHANGE_FD failed as expected");
 	else
-- 
2.56.0



More information about the ltp mailing list