]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
selftests/statmount: add statmount_alloc() helper
authorChristian Brauner <brauner@kernel.org>
Thu, 22 Jan 2026 10:48:50 +0000 (11:48 +0100)
committerChristian Brauner <brauner@kernel.org>
Thu, 12 Mar 2026 12:33:54 +0000 (13:33 +0100)
Add a helper to allocate a statmount buffer and call statmount(). This
helper will be shared by multiple test suites that need to query mount
information via statmount().

Link: https://patch.msgid.link/20260122-work-fsmount-namespace-v1-5-5ef0a886e646@kernel.org
Signed-off-by: Christian Brauner <brauner@kernel.org>
tools/testing/selftests/filesystems/open_tree_ns/open_tree_ns_test.c
tools/testing/selftests/filesystems/statmount/statmount.h
tools/testing/selftests/filesystems/statmount/statmount_test.c

index 9711556280aed4010868bb827b6989f9ac4076b7..86d5d7a831c1e3915fdadab809fe46ce73a414b4 100644 (file)
@@ -115,7 +115,7 @@ static void dump_mounts(struct __test_metadata *_metadata, uint64_t mnt_ns_id)
                                     STATMOUNT_MNT_BASIC |
                                     STATMOUNT_FS_TYPE |
                                     STATMOUNT_MNT_ROOT |
-                                    STATMOUNT_MNT_POINT);
+                                    STATMOUNT_MNT_POINT, 0);
                if (!sm) {
                        TH_LOG("  [%zd] mnt_id %llu: statmount failed: %s",
                               i, (unsigned long long)list[i], strerror(errno));
@@ -746,7 +746,7 @@ TEST_F(open_tree_ns_userns, umount_fails_einval)
                        const char *mnt_point;
 
                        sm = statmount_alloc(list[i], new_ns_id,
-                                            STATMOUNT_MNT_POINT);
+                                            STATMOUNT_MNT_POINT, 0);
                        if (!sm)
                                _exit(11);
 
@@ -863,7 +863,7 @@ TEST_F(open_tree_ns_userns, umount_succeeds)
                        const char *mnt_point;
 
                        sm = statmount_alloc(list[i], new_ns_id,
-                                            STATMOUNT_MNT_POINT);
+                                            STATMOUNT_MNT_POINT, 0);
                        if (!sm)
                                _exit(11);
 
@@ -1003,7 +1003,7 @@ TEST_F(open_tree_ns_unbindable, recursive_skips_on_unbindable)
                struct statmount *sm;
                const char *mnt_point;
 
-               sm = statmount_alloc(list[i], new_ns_id, STATMOUNT_MNT_POINT);
+               sm = statmount_alloc(list[i], new_ns_id, STATMOUNT_MNT_POINT, 0);
                ASSERT_NE(sm, NULL) {
                        TH_LOG("statmount_alloc failed for mnt_id %llu",
                               (unsigned long long)list[i]);
index e1cba4bfd8d91529ccf0a2d6e2027a09aba54f30..675f7cc000766f0fea2bb82253350354d0da3963 100644 (file)
@@ -3,10 +3,14 @@
 #ifndef __STATMOUNT_H
 #define __STATMOUNT_H
 
+#include <errno.h>
 #include <stdint.h>
+#include <stdlib.h>
 #include <linux/mount.h>
 #include <asm/unistd.h>
 
+#define STATMOUNT_BUFSIZE (1 << 15)
+
 #ifndef __NR_statmount
        #if defined __alpha__
                #define __NR_statmount 567
@@ -84,4 +88,51 @@ static inline ssize_t listmount(uint64_t mnt_id, uint64_t mnt_ns_id,
        return syscall(__NR_listmount, &req, list, num, flags);
 }
 
+static inline struct statmount *statmount_alloc(uint64_t mnt_id, uint64_t mnt_ns_id,
+                                                uint64_t mask, unsigned int flags)
+{
+       struct statmount *buf;
+       size_t bufsize = STATMOUNT_BUFSIZE;
+       int ret;
+
+       for (;;) {
+               buf = malloc(bufsize);
+               if (!buf)
+                       return NULL;
+
+               ret = statmount(mnt_id, mnt_ns_id, 0, mask, buf, bufsize, flags);
+               if (ret == 0)
+                       return buf;
+
+               free(buf);
+               if (errno != EOVERFLOW)
+                       return NULL;
+
+               bufsize <<= 1;
+       }
+}
+
+static inline struct statmount *statmount_alloc_by_fd(int fd, uint64_t mask)
+{
+       struct statmount *buf;
+       size_t bufsize = STATMOUNT_BUFSIZE;
+       int ret;
+
+       for (;;) {
+               buf = malloc(bufsize);
+               if (!buf)
+                       return NULL;
+
+               ret = statmount(0, 0, fd, mask, buf, bufsize, STATMOUNT_BY_FD);
+               if (ret == 0)
+                       return buf;
+
+               free(buf);
+               if (errno != EOVERFLOW)
+                       return NULL;
+
+               bufsize <<= 1;
+       }
+}
+
 #endif /* __STATMOUNT_H */
index a04bcaace126162fed4dec6a8786199b5b130e69..8dc018d47a93535c08b433a09a4983f5bfc70de6 100644 (file)
@@ -33,45 +33,6 @@ static const char *const known_fs[] = {
        "sysv", "tmpfs", "tracefs", "ubifs", "udf", "ufs", "v7", "vboxsf",
        "vfat", "virtiofs", "vxfs", "xenfs", "xfs", "zonefs", NULL };
 
-static struct statmount *statmount_alloc(uint64_t mnt_id, int fd, uint64_t mask, unsigned int flags)
-{
-       size_t bufsize = 1 << 15;
-       struct statmount *buf = NULL, *tmp = NULL;
-       int tofree = 0;
-       int ret;
-
-       if (flags & STATMOUNT_BY_FD && fd < 0)
-               return NULL;
-
-       tmp = alloca(bufsize);
-
-       for (;;) {
-               if (flags & STATMOUNT_BY_FD)
-                       ret = statmount(0, 0, (uint32_t) fd, mask, tmp, bufsize, flags);
-               else
-                       ret = statmount(mnt_id, 0, 0, mask, tmp, bufsize, flags);
-
-               if (ret != -1)
-                       break;
-               if (tofree)
-                       free(tmp);
-               if (errno != EOVERFLOW)
-                       return NULL;
-               bufsize <<= 1;
-               tofree = 1;
-               tmp = malloc(bufsize);
-               if (!tmp)
-                       return NULL;
-       }
-       buf = malloc(tmp->size);
-       if (buf)
-               memcpy(buf, tmp, tmp->size);
-       if (tofree)
-               free(tmp);
-
-       return buf;
-}
-
 static void write_file(const char *path, const char *val)
 {
        int fd = open(path, O_WRONLY);
@@ -715,7 +676,7 @@ static void test_statmount_by_fd(void)
                goto err_fd;
        }
 
-       sm = statmount_alloc(0, fd, STATMOUNT_MNT_ROOT | STATMOUNT_MNT_POINT, STATMOUNT_BY_FD);
+       sm = statmount_alloc_by_fd(fd, STATMOUNT_MNT_ROOT | STATMOUNT_MNT_POINT);
        if (!sm) {
                ksft_test_result_fail("statmount by fd failed: %s\n", strerror(errno));
                goto err_chroot;
@@ -750,7 +711,7 @@ static void test_statmount_by_fd(void)
        }
 
        free(sm);
-       sm = statmount_alloc(0, fd, STATMOUNT_MNT_ROOT | STATMOUNT_MNT_POINT, STATMOUNT_BY_FD);
+       sm = statmount_alloc_by_fd(fd, STATMOUNT_MNT_ROOT | STATMOUNT_MNT_POINT);
        if (!sm) {
                ksft_test_result_fail("statmount by fd failed: %s\n", strerror(errno));
                goto err_fd;
@@ -844,7 +805,7 @@ static void test_statmount_by_fd_unmounted(void)
                goto err_fd;
        }
 
-       sm = statmount_alloc(0, fd, STATMOUNT_MNT_POINT | STATMOUNT_MNT_ROOT, STATMOUNT_BY_FD);
+       sm = statmount_alloc_by_fd(fd, STATMOUNT_MNT_POINT | STATMOUNT_MNT_ROOT);
        if (!sm) {
                ksft_test_result_fail("statmount by fd unmounted: %s\n",
                                      strerror(errno));