tools/testing/selftests/mount_setattr/mount_setattr_test.c
Source file repositories/reference/linux-study-clean/tools/testing/selftests/mount_setattr/mount_setattr_test.c
File Facts
- System
- Linux kernel
- Corpus path
tools/testing/selftests/mount_setattr/mount_setattr_test.c- Extension
.c- Size
- 61139 bytes
- Lines
- 2141
- Domain
- Support Tooling And Documentation
- Bucket
- tools
- Inferred role
- Support Tooling And Documentation: implementation source
- Status
- source implementation candidate
Why This File Exists
Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.
- Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
sched.hstdio.herrno.hpthread.hstring.hsys/stat.hsys/types.hsys/mount.hsys/wait.hsys/vfs.hsys/statvfs.hsys/sysinfo.hstdlib.hunistd.hfcntl.hgrp.hstdbool.hstdarg.hlinux/mount.h../filesystems/wrappers.hkselftest_harness.h
Detected Declarations
struct mount_attr_largefunction sys_mount_setattrfunction sys_open_tree_attrfunction write_nointrfunction write_filefunction create_and_enter_usernsfunction prepare_unpriv_mountnsfunction read_mnt_flagsfunction null_endofwordfunction is_shared_mountfunction mount_setattr_supportedfunction ASSERT_NEfunction ASSERT_NEfunction map_idsfunction do_clonefunction get_userns_fd_cbfunction wait_for_pidfunction get_userns_fdfunction expected_uid_gid
Annotated Snippet
struct mount_attr_large {
struct mount_attr attr1;
struct mount_attr attr2;
struct mount_attr attr3;
} large_attr = {};
if (!mount_setattr_supported())
SKIP(return, "mount_setattr syscall not supported");
old_flags = read_mnt_flags("/mnt/A");
ASSERT_GT(old_flags, 0);
ASSERT_NE(sys_mount_setattr(-1, "/mnt/A", AT_RECURSIVE, NULL,
sizeof(invalid_attr)), 0);
ASSERT_EQ(errno, EFAULT);
ASSERT_NE(sys_mount_setattr(-1, "/mnt/A", AT_RECURSIVE, (void *)s,
sizeof(invalid_attr)), 0);
ASSERT_EQ(errno, EINVAL);
ASSERT_NE(sys_mount_setattr(-1, "/mnt/A", AT_RECURSIVE, &invalid_attr, 0), 0);
ASSERT_EQ(errno, EINVAL);
ASSERT_NE(sys_mount_setattr(-1, "/mnt/A", AT_RECURSIVE, &invalid_attr,
sizeof(invalid_attr) / 2), 0);
ASSERT_EQ(errno, EINVAL);
ASSERT_NE(sys_mount_setattr(-1, "/mnt/A", AT_RECURSIVE, &invalid_attr,
sizeof(invalid_attr) / 2), 0);
ASSERT_EQ(errno, EINVAL);
ASSERT_EQ(sys_mount_setattr(-1, "/mnt/A", AT_RECURSIVE,
(void *)&large_attr, sizeof(large_attr)), 0);
large_attr.attr3.attr_set = MOUNT_ATTR_RDONLY;
ASSERT_NE(sys_mount_setattr(-1, "/mnt/A", AT_RECURSIVE,
(void *)&large_attr, sizeof(large_attr)), 0);
large_attr.attr3.attr_set = 0;
large_attr.attr1.attr_set = MOUNT_ATTR_RDONLY;
ASSERT_EQ(sys_mount_setattr(-1, "/mnt/A", AT_RECURSIVE,
(void *)&large_attr, sizeof(large_attr)), 0);
expected_flags = old_flags;
expected_flags |= MS_RDONLY;
new_flags = read_mnt_flags("/mnt/A");
ASSERT_EQ(new_flags, expected_flags);
new_flags = read_mnt_flags("/mnt/A/AA");
ASSERT_EQ(new_flags, expected_flags);
new_flags = read_mnt_flags("/mnt/A/AA/B");
ASSERT_EQ(new_flags, expected_flags);
new_flags = read_mnt_flags("/mnt/A/AA/B/BB");
ASSERT_EQ(new_flags, expected_flags);
}
TEST_F(mount_setattr, basic)
{
unsigned int old_flags = 0, new_flags = 0, expected_flags = 0;
struct mount_attr attr = {
.attr_set = MOUNT_ATTR_RDONLY | MOUNT_ATTR_NOEXEC | MOUNT_ATTR_RELATIME,
.attr_clr = MOUNT_ATTR__ATIME,
};
if (!mount_setattr_supported())
SKIP(return, "mount_setattr syscall not supported");
old_flags = read_mnt_flags("/mnt/A");
ASSERT_GT(old_flags, 0);
ASSERT_EQ(sys_mount_setattr(-1, "/mnt/A", 0, &attr, sizeof(attr)), 0);
expected_flags = old_flags;
expected_flags |= MS_RDONLY;
expected_flags |= MS_NOEXEC;
expected_flags &= ~MS_NOATIME;
expected_flags |= MS_RELATIME;
new_flags = read_mnt_flags("/mnt/A");
ASSERT_EQ(new_flags, expected_flags);
new_flags = read_mnt_flags("/mnt/A/AA");
ASSERT_EQ(new_flags, old_flags);
new_flags = read_mnt_flags("/mnt/A/AA/B");
ASSERT_EQ(new_flags, old_flags);
Annotation
- Immediate include surface: `sched.h`, `stdio.h`, `errno.h`, `pthread.h`, `string.h`, `sys/stat.h`, `sys/types.h`, `sys/mount.h`.
- Detected declarations: `struct mount_attr_large`, `function sys_mount_setattr`, `function sys_open_tree_attr`, `function write_nointr`, `function write_file`, `function create_and_enter_userns`, `function prepare_unpriv_mountns`, `function read_mnt_flags`, `function null_endofword`, `function is_shared_mount`.
- Atlas domain: Support Tooling And Documentation / tools.
- Implementation status: source implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.