summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Brauner <brauner@kernel.org>2026-01-22 11:48:50 +0100
committerChristian Brauner <brauner@kernel.org>2026-03-12 13:33:54 +0100
commitbe1ca3ee8f97067fee87fda73ea5959d5ab75bbf (patch)
tree6b8b878ac3e45c3e1672c386c69bad24ade8705f
parentfc1a05de0058bc1dbbc202f6f6cdb25ee0bae16d (diff)
selftests/statmount: add statmount_alloc() helper
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>
-rw-r--r--tools/testing/selftests/filesystems/open_tree_ns/open_tree_ns_test.c8
-rw-r--r--tools/testing/selftests/filesystems/statmount/statmount.h51
-rw-r--r--tools/testing/selftests/filesystems/statmount/statmount_test.c45
3 files changed, 58 insertions, 46 deletions
diff --git a/tools/testing/selftests/filesystems/open_tree_ns/open_tree_ns_test.c b/tools/testing/selftests/filesystems/open_tree_ns/open_tree_ns_test.c
index 9711556280ae..86d5d7a831c1 100644
--- a/tools/testing/selftests/filesystems/open_tree_ns/open_tree_ns_test.c
+++ b/tools/testing/selftests/filesystems/open_tree_ns/open_tree_ns_test.c
@@ -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]);
diff --git a/tools/testing/selftests/filesystems/statmount/statmount.h b/tools/testing/selftests/filesystems/statmount/statmount.h
index e1cba4bfd8d9..675f7cc00076 100644
--- a/tools/testing/selftests/filesystems/statmount/statmount.h
+++ b/tools/testing/selftests/filesystems/statmount/statmount.h
@@ -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 */
diff --git a/tools/testing/selftests/filesystems/statmount/statmount_test.c b/tools/testing/selftests/filesystems/statmount/statmount_test.c
index a04bcaace126..8dc018d47a93 100644
--- a/tools/testing/selftests/filesystems/statmount/statmount_test.c
+++ b/tools/testing/selftests/filesystems/statmount/statmount_test.c
@@ -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));