]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
test-btrfs: skip info test when GET_SUBVOL_INFO ioctl is unsupported
authorDaan De Meyer <daan@amutable.com>
Wed, 20 May 2026 20:46:40 +0000 (20:46 +0000)
committerLuca Boccassi <luca.boccassi@gmail.com>
Thu, 21 May 2026 11:06:21 +0000 (12:06 +0100)
On 32-bit userspace running against a 64-bit kernel
BTRFS_IOC_GET_SUBVOL_INFO returns -ENOTTY: struct
btrfs_ioctl_get_subvol_info_args embeds four btrfs_ioctl_timespec
values, and that timespec struct (__u64 sec; __u32 nsec) packs to 12
bytes on i386 but 16 on x86_64 due to differing __u64 alignment.
sizeof(struct) is part of the ioctl cmd number via _IOR(), so the cmd
emitted by 32-bit userspace doesn't match the case label compiled by
the 64-bit kernel and the switch falls through to -ENOTTY.

btrfs already handles this exact class of bug for
BTRFS_IOC_SET_RECEIVED_SUBVOL via a btrfs_ioctl_timespec_32 struct
plus a _32 cmd alias in fs/btrfs/ioctl.c, but GET_SUBVOL_INFO (added
in 2018, four years after that fix) didn't get the same treatment.
Until a kernel patch lands the test can't exercise the ioctl on
32-bit, so convert TEST(info) to TEST_RET(info) and return
EXIT_TEST_SKIP with a clear message when -ENOTTY comes back. The
other tests in the file use ioctls that already have working compat
paths and remain unaffected.

src/test/test-btrfs.c

index 66cb10a4c2534356f730b78b9bcf500d5024f9d6..fe3cfbfd8f88622859a2b6463fa20c267c1388a4 100644 (file)
@@ -52,14 +52,18 @@ static int open_test_subvol(char **ret_path) {
         return fd;
 }
 
-TEST(info) {
+TEST_RET(info) {
         _cleanup_(rm_rf_subvolume_and_freep) char *dir = NULL;
         _cleanup_close_ int dir_fd = ASSERT_OK(open_test_subvol(&dir));
         BtrfsSubvolInfo info;
         BtrfsQuotaInfo quota;
         int r;
 
-        ASSERT_OK(btrfs_subvol_get_info_fd(dir_fd, 0, &info));
+        r = btrfs_subvol_get_info_fd(dir_fd, 0, &info);
+        if (r == -ENOTTY)
+                return log_tests_skipped("BTRFS_IOC_GET_SUBVOL_INFO not supported "
+                                         "(missing 32-bit compat handler in kernel?)");
+        ASSERT_OK(r);
         log_info("otime: %s", FORMAT_TIMESTAMP(info.otime));
         log_info("read-only (search): %s", yes_no(info.read_only));
 
@@ -75,6 +79,8 @@ TEST(info) {
 
         r = ASSERT_OK(btrfs_subvol_get_read_only_fd(dir_fd));
         log_info("read-only (ioctl): %s", yes_no(r));
+
+        return EXIT_SUCCESS;
 }
 
 TEST(subvol) {