test-btrfs: skip info test when GET_SUBVOL_INFO ioctl is unsupported

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.
This commit is contained in:
Daan De Meyer
2026-05-21 12:06:21 +01:00
committed by Luca Boccassi
parent d46dae085f
commit 05a4f7755a
+8 -2
View 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) {