mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2026-05-09 21:42:09 +02:00
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>
This commit is contained in:
@@ -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]);
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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));
|
||||
|
||||
Reference in New Issue
Block a user