Commit Graph

179 Commits

Author SHA1 Message Date
Christian Brauner
eadfe727dd
selftests/filesystems: test that a mntns file can't take over a lock
Add a case to the locked mount test:

- a bind of the mount namespace file of a grandchild moved beneath a
  locked cover must fail with EINVAL
- a bind of an ordinary file beneath it takes the lock over, the old
  cover can go and the new one can't
- the file is still covered after unshare(CLONE_NEWNS)

Link: https://patch.msgid.link/20261014-work-namei-locked-mnt_ns_file-v1-2-24035bd5d8e9@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-10-14 22:08:06 +02:00
Christian Brauner
3e78bf8433
selftests/filesystems: test covered mounts
Test that mount cycles are resolved and test that mount covers behave as
expected.

Link: https://patch.msgid.link/20261002-work-mount-cover-v1-3-232a8f52b43c@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-10-07 00:45:50 +02:00
Christian Brauner
098bf3be6c selftests/filesystems: check that reading the root of an empty mount namespace stalls nobody
A readdir of the root of an empty mount namespace stuck in the page
fault of its buffer must stall neither a create nor a lookup in that
directory. The test needs userfaultfd and skips without it.

Link: https://patch.msgid.link/20261002-work-mount-fixes-4-v1-21-dd44b89d44ce@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-10-04 12:36:15 +02:00
Christian Brauner
fa15a241f0 selftests/filesystems: add a helper that holds a readdir in a page fault
A getdents64() whose buffer is a page registered with userfaultfd sits
in handle_userfault() with whatever iterate_dir() took before it copied
the entries. Add readdir_hold.h for tests that want to know what that
blocks: it opens the userfaultfd before the test enters a user
namespace, the fault happens in the kernel and needs CAP_SYS_PTRACE in
the initial one, starts the readdir in a thread, waits until that
thread is stuck, queues a create behind it and waits for it to settle,
then probes a lookup with a watchdog and says whether it came back.
The page is released afterwards so that everything drains on a kernel
that still holds the lock across the copy.

The two users follow.

Link: https://patch.msgid.link/20261002-work-mount-fixes-4-v1-20-dd44b89d44ce@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-10-04 12:36:14 +02:00
Christian Brauner
39796254f4
selftests/filesystems: check that an automount below an overlay layer is refused
Make sure that we don't automount on top of internal things.

Link: https://patch.msgid.link/20261002-work-mount-fixes-4-v1-12-dd44b89d44ce@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-10-04 12:31:40 +02:00
Christian Brauner
2244ca5662
selftests/filesystems: check the atime of the empty mount namespace root
No access time updates for immutable nullfs.

Link: https://patch.msgid.link/20261002-work-mount-fixes-4-v1-11-dd44b89d44ce@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-10-04 12:31:40 +02:00
Christian Brauner
921c14fd00
selftests/filesystems: check that a lock lands on the right mount and stays
Check MNT_LOCKED:

- A child in a user namespace of its own triggers the tracefs automount
  through a directory descriptor on the host's debugfs mount. The copy
  in the child's namespace has to be locked and the host's mount unlocked.

- A child moves a bind of that automount beneath a locked covering mount,
  unmounts the covering mount and asks for the umount of an unlocked
  ancestor. This must not expire the mount which holds the lock now.

- The host mounts and unmounts on a directory that a locked mount covers
  in a user namespace further down the propagation chain. That cover has
  to be locked afterwards as it was before.

Link: https://patch.msgid.link/20261002-work-mount-fixes-4-v1-10-dd44b89d44ce@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-10-04 12:31:39 +02:00
Christian Brauner
66cda7ec9a
selftests/filesystems: check that an immutable inode takes no write hint
Check that an immutable inode takes no write hint.

Link: https://patch.msgid.link/20261002-work-mount-fixes-4-v1-4-dd44b89d44ce@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-10-04 12:31:39 +02:00
Christian Brauner
5e83e3a38b
selftests/filesystems: check that the nullfs root can't be reconfigured
Add a test for the root of an empty mount namespace:

- fspick() of the root fails with EINVAL
- mount(MS_REMOUNT) of the root fails with EINVAL
- umount() of the root fails and doesn't remount it read-only

Link: https://patch.msgid.link/20260930-work-mount-fixes-3-v1-12-be34c83956ae@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-10-01 14:20:07 +02:00
Christian Brauner
c518a195f6
selftests/filesystems: check that a mount namespace file on top doesn't bury a mount
Add a test for moving a mount with a mount namespace file on top of it:

- S, a bind mount of a file, with a newer mount namespace's file on top
- A shared with a slave B that has Q on B/file
- S moved onto A/file, its copy lands on B/file below Q

B/file keeps reading Q and once Q is unmounted it reads the copy.

Link: https://patch.msgid.link/20260930-work-mount-fixes-3-v1-9-be34c83956ae@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-10-01 14:20:06 +02:00
Christian Brauner
fe187cbb48
selftests/filesystems: check that OPEN_TREE_NAMESPACE keeps mounts covered
Add a test for open_tree(OPEN_TREE_NAMESPACE) from a user namespace that
doesn't own the mount namespace it copies from:

- a file covered by a private or an unbindable tmpfs mount
- the non-recursive copy of the parent mount fails with EINVAL
- the recursive copy keeps the file covered in the new mount namespace
- the owner of the mount namespace keeps the bind mount semantics

Link: https://patch.msgid.link/20260930-work-mount-fixes-3-v1-7-be34c83956ae@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-10-01 14:20:05 +02:00
Christian Brauner
7c07b18300
selftests/filesystems: check that a recursive bind mount can't pin the caller's mount namespace
Add a test for a recursive bind mount of a namespace file in another mount
namespace:

- a bind mount of the network namespace file, held through a descriptor
- the caller's own mount namespace file stacked on top of it there
- the recursive bind mount through the descriptor fails with EINVAL
- a plain bind mount of the file still works

The copy would pin the namespace it is put in otherwise.

Link: https://patch.msgid.link/20260930-work-mount-fixes-3-v1-5-be34c83956ae@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-10-01 14:20:05 +02:00
Christian Brauner
520b5a15fc
selftests/filesystems: check that a busy submount survives a synchronous umount
Add a test for the shrinkable submounts of a synchronous umount:

- P shared, P1 a slave that is shared in turn, P2 its peer
- B on P/options with copies on P1 and P2, R on top of the copy in P2
- P with B moved below P1, R is the working directory
- umount(P1) slides R to where the copy of B is looked up

The umount fails with EBUSY and R stays mounted. Needs the tracefs
automount below debugfs for the shrinkable mounts.

Link: https://patch.msgid.link/20260930-work-mount-fixes-3-v1-3-be34c83956ae@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-10-01 14:20:04 +02:00
Christian Brauner
7fbcc793f7
selftests/filesystems: check that a dead mount's overmount isn't followed
Add overmount_reparent_test:

- a mount that a file descriptor keeps alive after propagate_umount()
  reparented its overmount and unmounted it must not be walked into the
  freed overmount by move_mount(MOVE_MOUNT_BENEATH)

Link: https://patch.msgid.link/20260926-work-mount-fixes-2-v1-10-f357abf3d17b@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-09-26 15:47:42 +02:00
Christian Brauner
07617913d0
selftests/filesystems: check that an unmounted mount tree isn't walked
Add unmounted_tree_test:

- a detached nsfs or pidfs bind mount that a file descriptor keeps
  alive can't be copied recursively, a copy of the mount itself and
  a copy of a mounted one still work
- a detached tree with a child that was vacated behind it can't be
  copied recursively either
- a copy of a detached bind mount is an ordinary mount: unlinking its
  mountpoint from another mount namespace unmounts it
- mount_setattr() refuses to change the propagation of a detached
  tree and still allows it for the root of an anonymous mount
  namespace

Every case runs in a user and mount namespace of its own.

Link: https://patch.msgid.link/20260926-work-mount-fixes-2-v1-9-f357abf3d17b@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-09-26 15:47:41 +02:00
Christian Brauner
bba9960c07
selftests/filesystems: check that a busy propagated copy blocks a synchronous umount
A slave namespace moves an open_tree() copy of the shared tree beneath
the propagated copy of the victim and keeps the descriptor. Check that:

- umount(2) of the victim fails with EBUSY while the descriptor is open

- the moved tree is still attached in the slave namespace afterwards

- the umount succeeds once the descriptor is closed

The test needs CAP_SYS_ADMIN and skips otherwise.

Link: https://patch.msgid.link/20260923-work-mount-fixes-v1-6-f424cf8d3242@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-09-25 17:20:33 +02:00
Christian Brauner
0bab6b6d77
selftests/filesystems: check that a copied mount namespace keeps unbindable
Make a tmpfs unbindable, copy the mount namespace and check from the
copy that:

- a bind of the mount fails with EINVAL

- a recursive bind fails as well

- open_tree(OPEN_TREE_CLONE) of it fails

- mountinfo still shows it as unbindable

- a copy of the copy refuses the bind too

The first case runs in the original namespace so the fixture stays
honest about what it set up.

Link: https://patch.msgid.link/20260923-work-mount-fixes-v1-2-f424cf8d3242@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-09-25 17:20:32 +02:00
Christian Brauner
76ebb69da6 Revert "selftests/filesystems: add mntns cleanup test"
This reverts commit 3452eecbcc.

The test checks that the mounts of a destroyed mount namespace stay
connected. The commit that made them stay connected is reverted next
because it leaks superblocks and loop devices, so drop the test with it.

Link: https://patch.msgid.link/20260917-work-put_mnt_ns-revert-v1-1-34d9b8679e68@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-09-23 09:03:18 +02:00
Linus Torvalds
9cebfe6504 fuse update for 7.3
-----BEGIN PGP SIGNATURE-----
 
 iHUEABYKAB0WIQSQHSd0lITzzeNWNm3h3BK/laaZPAUCao1RzQAKCRDh3BK/laaZ
 PJ2EAP9dfslni4sFYqtXv/43Wk2iVwwdGRRSy5Tfoq8nCeNXpQEAygIv9BuJYpl6
 DL861AOn/NfDBXpeU0vX4WQpTgtFIgc=
 =Av0t
 -----END PGP SIGNATURE-----

Merge tag 'fuse-update-7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse

Pull fuse updates from Miklos Szeredi:

 - Improve performance of the io-uring transport by introducing buffer
   pools and zero-copy (Joanne)

 - Fix lots of bugs (Baokun Li)

 - Fix io-uring initialization issues (Joanne, Bernd)

 - More prep work for large folios (Joanne)

 - Don't limit buffered read to 128k (Jim Harris)

 - Fix zeroing of page end (dirtied with mmap) on file size extension
   (Jimmy Zuber)

 - Improve performance in certain cases with wake_up_sync() when queuing
   request (Xuewen Yan)

 - Misc fixes and cleanups (Xuewen Yan)

* tag 'fuse-update-7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse: (35 commits)
  fuse: zero the partial EOF page when extending a file
  io_uring: Add missing include for ITER_SOURCE and ITER_DEST
  fuse: Fix the condition to enable over-io-uring
  fuse: invalidate the correct range after O_APPEND direct write
  selftests/fuse: test post-EOF page zeroing when a file is extended
  fuse: wake one waiter per freed slot when raising max_background
  fuse: use min_not_zero() in fuse_init_server_timeout()
  fuse: copy request headers via a stack buffer for io-uring
  fuse: give wakeup hints to the scheduler for synchronous requests
  fuse: check for NULL root inode in fuse_fill_super_submount
  fuse: reject a duplicate fd= mount option
  cuse: wait for pending RCU callbacks on module exit
  fuse: fix invalidate lock leak on open O_TRUNC DAX failure
  fuse: fix invalidate lock leak on setattr writeback failure
  fuse: wait for FR_FINISHED on abort_on_kill to prevent use-after-free
  fuse: make dentry_tree_work static
  docs: fuse: document io-uring buffer pool and zero-copy uapi
  fuse: add zero-copy over io-uring
  fuse: support registered buffer pools in io-uring
  fuse: add io-uring buffer pools
  ...
2026-08-25 07:59:44 -07:00
Jimmy Zuber
60dbcce156 selftests/fuse: test post-EOF page zeroing when a file is extended
Add a regression test for the bug where extending a file left the tail of
the old partial EOF page exposing stale mmap-dirtied data instead of zeros.

The test is a self-contained raw /dev/fuse server (no libfuse dependency)
that runs without writeback_cache and returns FOPEN_KEEP_CACHE, the
configuration in which the bug is visible.  Its backing data is always zero
in the hole, so any non-zero byte a read sees is stale page-cache data.
All offsets are relative to the runtime page size.  Four cases:

  - write_extend: pollute the post-EOF tail, extend past it by writing into
    a later page, and verify the tail reads back as zero;
  - ftruncate_extend: same, but extend via ftruncate();
  - fallocate_extend: same, but extend via fallocate() at the old EOF;
  - extend_into_eof_page_preserves_data: an extending write landing inside
    the old EOF page must not be clobbered by the zeroing.

Each case fails without the fix and passes with it.

Signed-off-by: Jimmy Zuber <jamz@amazon.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
2026-08-24 12:18:02 +02:00
Linus Torvalds
1781f0b3d7 vfs-7.3-rc1.super
Please consider pulling these changes from the signed vfs-7.3-rc1.super tag.
 
 Thanks!
 Christian
 -----BEGIN PGP SIGNATURE-----
 
 iHUEABYKAB0WIQRAhzRXHqcMeLMyaSiRxhvAZXjcogUCan7RJQAKCRCRxhvAZXjc
 oroBAP40BufiChnC6I9Ev79QWF+Pfri1r/3AR4xXRG4HkXQaYQD/YE+Ria3+Bt35
 +tWU66cYlQ/+9LfU8DJ3KXm7jPUBiQA=
 =hXLH
 -----END PGP SIGNATURE-----

Merge tag 'vfs-7.3-rc1.super' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs

Pull vfs superblock updates from Christian Brauner:

 - Make it possible to share a block device between multiple
   filesystems.

   erofs can mount read-only blob devices shared between many
   superblocks, but because we only tracked a single superblock a
   freeze, thaw, removal or sync on such a device was never propagated
   to all the superblocks using it, and there was no way to find them.

   Add an efficient table to lookup all superblocks using a given block
   device.

 - A bunch of pre-existing fixes fell out of this work:

   A block-device freeze racing a btrfs device change could leave the
   whole filesystem stuck frozen. A bdev_freeze() issued by "dmsetup
   suspend" or an LVM snapshot resolves that holder to freeze the
   filesystem. and bdev_thaw() resolves it again to thaw. A freeze
   landing while btrfs is adding, removing or replacing a device freezes
   the filesystem. The membership change then drops that link. So the
   matching thaw could no longer find the superblock.

   Forbid freezing a device for the duration of a membership change,
   modelled on deny_write_access()/allow_write_access().

* tag 'vfs-7.3-rc1.super' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: (24 commits)
  super: fix dying superblock warning messages
  block: reject block device inodes with i_rdev == 0 in lookup_bdev()
  selftests/filesystems: add ustat() coverage
  fs: look up the superblock via the device table in user_get_super()
  super: make fs_holder_ops private
  f2fs: open via dedicated fs bdev helpers
  erofs: open via dedicated fs bdev helpers
  fs: tolerate per-superblock freeze errors on shared devices
  fs: look up superblocks via the device table in fs_holder_ops
  ext4: open via dedicated fs bdev helpers
  btrfs: open via dedicated fs bdev helpers
  xfs: port to fs_bdev_file_open_by_path()
  fs: add dedicated block device open helpers for filesystems
  fs: maintain a global device-to-superblock table
  ocfs2: don't reset s_dev on dismount
  ext4: use anonymous devices for KUnit test superblocks
  fs, block: move blk_mode_t and fop_flags_t into <linux/types.h>
  super: take lock after last reference count
  super: convert s_count to refcount_t s_passive
  btrfs: deny freezing devices undergoing a replace
  ...
2026-08-17 13:57:04 -07:00
Linus Torvalds
aaed66fadb vfs-7.3-rc1.ovl
Please consider pulling these changes from the signed vfs-7.3-rc1.ovl tag.
 
 Thanks!
 Christian
 -----BEGIN PGP SIGNATURE-----
 
 iHUEABYKAB0WIQRAhzRXHqcMeLMyaSiRxhvAZXjcogUCan7RJQAKCRCRxhvAZXjc
 ok/9AQDpiRYIoLwnUa7URD92AQXBRQeSYFqicAqDqP3NpCUMwQD+IcmA1EtkfmaG
 ROdhiUJWe8TV5Ci1qNPXzoy1XRVhNQU=
 =xOj4
 -----END PGP SIGNATURE-----

Merge tag 'vfs-7.3-rc1.ovl' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs

Pull overlayfs updates from Christian Brauner:
 "This lets the merged overlayfs mount itself be idmapped through
  mount_setattr(MOUNT_ATTR_IDMAP), in addition to the already supported
  idmapped lower and upper layers. The same overlay tree can then be
  exposed under a different ownership view.

  Overlayfs already normalizes every underlying id through the relevant
  layer idmap when ovl_copyattr() copies attributes into the overlay
  inode. So the overlay inode's i_uid and i_gid are overlay-final ids.

  The overlay mount idmap composes on top of that and is applied at the
  overlay-inode boundary only while the underlying layers keep being
  accessed with the mounter's credentials through their own (possibly
  idmapped) mounts.

  So this only changes how the caller sees the overlay inode and never
  widens the mounter's access to the layers. The second,
  mounter-credential check in ovl_permission() against the real inode
  stays on the layer idmap.

  Most paths need no change because the VFS applies the mount idmap to
  the overlay inode before overlayfs runs or after it returns at the
  syscall boundary. Overlayfs only has to change where it bypasses the
  generic path.

  This also included is a fix for a double end_creating() on the
  overlayfs casefold-mismatch path"

* tag 'vfs-7.3-rc1.ovl' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs:
  ovl: fix double end_creating() on the casefold-mismatch path
  ovl: document security.capability idmapping on the xattr forward paths
  selftests/filesystems/overlayfs: test idmapped overlay mounts
  selftests/filesystems/overlayfs: fix set_layers_via_fds link error
  docs: document idmapped overlay mounts
  ovl: allow idmapping overlay mounts
  ovl: handle idmapped mounts in ovl_set_acl()
  ovl: handle idmapped mounts in ovl_getattr()
  ovl: handle idmapped mounts in ovl_setattr()
  ovl: handle idmapped mounts in ovl_permission()
  ovl: handle idmapped mounts in ovl_create_object() and ovl_tmpfile()
2026-08-17 13:38:36 -07:00
Linus Torvalds
1c3e8cef79 vfs-7.3-rc1.misc
Please consider pulling these changes from the signed vfs-7.3-rc1.misc tag.
 
 Thanks!
 Christian
 -----BEGIN PGP SIGNATURE-----
 
 iHUEABYKAB0WIQRAhzRXHqcMeLMyaSiRxhvAZXjcogUCan7RJQAKCRCRxhvAZXjc
 otI6AQCIwshv02UI9fmbTC9pFr8b+v/9IWQwdVULaH61HXgICQD7BE/CktL8nfRs
 zCzGS6kBdWgiOA6bdVpgGGLqiMRnQgo=
 =Kc+G
 -----END PGP SIGNATURE-----

Merge tag 'vfs-7.3-rc1.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs

Pull misc vfs updates from Christian Brauner:
 "Bigger cleanups:

   - The lockref dead-count handling is tidied up.

     The open-coded check for a count below zero as the dead marker
     relies on information the caller should not have.

   - make put_mnt_ns() leave mounts connected. Destroying a mount
     namespace disconnected its mounts from their mount points. So a
     file descriptor still open on the parent of a mount point could be
     used to peek under it.

     Locked mounts were already kept connected to prevent exactly that.
     But a mount is only locked when its tree is copied across a user
     namespace boundary. So a mount namespace set up by a privileged
     component had no locked mounts and its mounts were disconnected.
     Passing UMOUNT_CONNECTED keeps every mount connected and prevents
     that bug.

   - vfs_prepare_mode() passes S_IFDIR for directories. I meant to fix
     that ago but didn't get to it. So now someone finally did it.

     This kills the exception where the mode could be 0 when a directory
     was created whereas every other creation operation passed it
     explicitly already.

   - move long delayed work for ufs, jffs2, hfsplus, hfs and affs from
     the per-cpu system_long_wq to the new unbound system_dfl_long_wq.

     None of that work relies on per-cpu state and the work item is
     enqueued with queue_delayed_work() whose timer is global anyway. So
     it may as well benefit from scheduler task placement.

  Smaller fixes and cleanups:

   - unlock_buffer() and journal_end_buffer_io_sync() use
     clear_and_wake_up_bit()

   - the pipe page pools are unified into a single per-pipe pool and the
     extra wake_up(rd_wait) is limited to EPOLLET consumers

   - eventpoll now computes its timer slack lazily in ep_poll()

   - shrink_dcache_for_umount() keeps making progress on busy roots

   - excess xarray nodes are freed in clear_inode()

   - romfs detects hard link cycles

   - the user path of nested backing files is fixed

   - pidfd holds exec_update_lock around the namespace ioctl

   - non-memcg-aware nr_cached_objects is skipped during memcg slab
     shrink

   - iomap_write_iter() always returns status

   - mangle_path() is renamed to seq_mangle_path()

   - inode timestamp accessors are annotated

   - new regression test for pipe->poll_usage.

   - a few documentation, kernel-doc and selftest fixes"

* tag 'vfs-7.3-rc1.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: (67 commits)
  selftests/namespaces: Fix racy pipe handshake in timens and pidns_separate
  selftests/epoll: add a regression test for pipe->poll_usage
  pipe: only enable the extra wake_up(rd_wait) for EPOLLET consumers
  pidfd: hold exec_update_lock around namespace ioctl
  fs: fix user path of nested backing files
  fs: remove stale inode_insert5() kernel-doc parameter
  fs: fix switch/case indentation in sysfs() syscall
  fs: document semantics of kstat::{uid,gid} fields
  dcache: keep shrink_dcache_for_umount() making progress on busy roots
  seq_file: rename mangle_path to seq_mangle_path
  nstree: add/fix struct ns_id_req kernel-doc member fields
  dcache: use lockref routines for dead count checks
  lockref: tidy up dead count handling
  initramfs: fix typo in reserve_initrd_mem comment
  fs/pipe: unify the page pools into a single per-pipe pool
  fs: annotate inode timestamp accessors
  eventpoll: compute timer slack lazily in ep_poll()
  selftests/filesystems: add mntns cleanup test
  put_mnt_ns(): leave mounts connected
  affs: Move long delayed work on system_dfl_long_wq
  ...
2026-08-17 12:56:12 -07:00
Linus Torvalds
cd051cfe1e vfs-7.3-rc1.failfs
Please consider pulling these changes from the signed vfs-7.3-rc1.failfs tag.
 
 Thanks!
 Christian
 -----BEGIN PGP SIGNATURE-----
 
 iHUEABYKAB0WIQRAhzRXHqcMeLMyaSiRxhvAZXjcogUCan7RJAAKCRCRxhvAZXjc
 ouz+AQCXKHb1Ay9ra1RG+dGu8mCpVZLebMt/+VO0/beMCqiqWAD8ChgvsFqObmr5
 8vLKOnzsSMeglRYGPL81h3xnaILRIQk=
 =0qwg
 -----END PGP SIGNATURE-----

Merge tag 'vfs-7.3-rc1.failfs' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs

Pull failfs filesystem from Christian Brauner:
 "Add failfs and expose a FD_FAILFS_ROOT sentinel.

  This allows userspace to shed their filesystem state completely. A
  process with its root or working directory in failfs must anchor every
  path lookup at an explicit file descriptor. Absolute paths, absolute
  symlinks and AT_FDCWD-relative lookups simply fail.

  Failfs is the counterpart to nullfs. nullfs says adds a permanently
  empty, immutable directory whose lookups fail with ENOENT but which
  can be opened, read, stat'd and mounted upon. Failfs on the other hand
  fails every operation. The root cannot be opened at all. A single
  instance is mounted during early boot via kern_mount(), which makes it
  logically distinct from every mount namespace.

  This is accompanied by a new fchroot() system call which makes
  chrooting via a file descriptor a first class concept. It's possible
  to chroot into failfs as an unprivileged user provided the task has no
  new privileges set"

* tag 'vfs-7.3-rc1.failfs' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs:
  Documentation: add failfs documentation
  selftests/filesystems: add failfs selftests
  arch: hookup fchroot() system call
  fs: support FD_FAILFS_ROOT in fchroot()
  fs: add fchroot()
  fs: support FD_FAILFS_ROOT in fchdir()
  fs: add failfs
2026-08-17 09:15:52 -07:00
Oleg Nesterov
ab018b7733
selftests/epoll: add a regression test for pipe->poll_usage
pipe->poll_usage was added to ensure that edge-triggered epoll consumers
get a wakeup on every write, even if the pipe was already non-empty.
However, none of the existing epoll_wakeup_test cases cover this; the
test suite passes even with WRITE_ONCE(pipe->poll_usage, true) removed.

Add a test that writes twice to a pipe and verifies that epoll_wait with
EPOLLET reports data each time. This covers the pipe-specific per-write
wakeup behavior that edge-triggered consumers depend on.

Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Link: https://patch.msgid.link/amnlGZesXu-SUK2H@redhat.com
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-08-13 12:19:27 +02:00
Christian Brauner
d64ba78b74
selftests/filesystems: test completing a context from another user namespace
fsopen() records the caller's user namespace in fc->user_ns and hands
back an ordinary file descriptor, so the task that issues
FSCONFIG_CMD_CREATE need not be the one that created the context.
mount_capable() authorizes that for a caller holding CAP_SYS_ADMIN in an
ancestor of fc->user_ns, which any unprivileged user has over a user
namespace it just created.

binfmt_misc and overlayfs used to WARN_ON() the mismatch. Add a test for
both. Also cover the handover within one user namespace. That is a
supported thing to do and has to keep working.

Link: https://patch.msgid.link/20260802-work-fill_super-warn-v1-3-4e987911a39a@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-08-10 09:35:54 +02:00
Noah Orlando
3452eecbcc
selftests/filesystems: add mntns cleanup test
Verify that destroying a mount namespace keeps its mounts connected.

Signed-off-by: Noah Orlando <Noah.Orlando@deshaw.com>
Link: https://patch.msgid.link/20260706182559.2496448-4-Noah.Orlando@deshaw.com
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-07-31 10:09:09 +02:00
Malaya Kumar Rout
8c8fe5c77b
selftests/statmount: Fix file descriptor leak in setup_namespace
In setup_namespace(), f_mountinfo is opened with fopen() at line 115
but is never closed. Multiple ksft_exit_fail_msg() calls exit the
program without closing this file descriptor, and the cleanup_namespace()
function registered with atexit() also doesn't close it.

Add fclose(f_mountinfo) in cleanup_namespace() to ensure the file
descriptor is properly closed on both normal and error exit paths,
since cleanup_namespace() is already registered as an atexit handler.

Signed-off-by: Malaya Kumar Rout <malayarout91@gmail.com>
Link: https://patch.msgid.link/20260704120437.99851-1-malayarout91@gmail.com
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-07-31 10:09:06 +02:00
Wang Yan
50bb761eb9
selftests/filesystems: fix spelling error in statmount test comment
Fix typo "didnt't" -> "didn't" in statmount_test.c comment.

Signed-off-by: Wang Yan <wangyan01@kylinos.cn>
Link: https://patch.msgid.link/20260702015428.363642-1-wangyan01@kylinos.cn
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-07-31 10:09:06 +02:00
Linus Torvalds
62cc902415 13 hotfixes. All are cc:stable. 11 are for MM. All are singletons -
please see the changelogs for details.
 -----BEGIN PGP SIGNATURE-----
 
 iHUEABYKAB0WIQTTMBEPP41GrTpTJgfdBJ7gKXxAjgUCamfLHAAKCRDdBJ7gKXxA
 jrrMAQDQHf+VGi/lZaxtgfLv0OThODhzzckRI2dcTGG66YX/DQD/V4aTndWFUUpM
 j1aSODTTWeKi3Ija4E3dA7SIaZkqSAI=
 =s/6H
 -----END PGP SIGNATURE-----

Merge tag 'mm-hotfixes-stable-2026-07-27-14-18' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm

Pull misc fixes from Andrew Morton:
 "13 hotfixes. All are cc:stable. 11 are for MM. All are singletons -
  please see the changelogs for details"

* tag 'mm-hotfixes-stable-2026-07-27-14-18' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm:
  fs/proc/task_mmu: fix PAGEMAP_SCAN written state for PMD holes
  mm/hugetlb: fix list corruption in allocate_file_region_entries()
  mm: mglru: fix stale batch updates after memcg reparenting
  selftest: fix headers in fclog.c
  ocfs2: fix boundary check in ocfs2_check_dir_entry() to use buffer offset
  mm/percpu-km: fix bitmap overflow and accounting in pcpu_create_chunk()
  mm/util: don't read __page_2 for order-1 folios in snapshot_page()
  mm/hugetlb: fix swap entry corruption when clearing uffd-wp at fork()
  mm: migrate_device: fix pte_pfn/pte_dirty called on non-present PTE
  fs/proc/task_mmu: fix PAGEMAP_SCAN written state for unpopulated ptes
  userfaultfd: wait on source PMD during UFFDIO_MOVE
  lib: test_hmm: use device devt for coherent device range selection
  mm/vmstat: fold stranded per-cpu node stats when a node comes online
2026-07-27 14:36:26 -07:00
Christian Brauner
df4b2889ea
selftests/filesystems: add failfs selftests
Test the failfs semantics and both new entry points:

- fchdir(FD_FAILFS_ROOT):

  * working directory lookups and getcwd() fail
  * other sentinels are rejected
  * the state is recoverable while the root is untouched

- fchroot() with regular fds:
  * chroot parity
  * CAP_SYS_CHROOT required
  * ENOTDIR/EBADF/EINVAL checks

- fchroot(FD_FAILFS_ROOT):

  * absolute lookups, stat, statfs and opens of the root including O_PATH fail with EOPNOTSUPP
  * dirfd-anchored I/O keeps working
  * ".." walks clamp at the top of the mount tree
  * /proc magic links resolve but can't be stat through
  * absolute symlinks fail while relative symlinks keep resolving

- Unprivileged entry requires no_new_privs and is rejected for
  chrooted callers and for a shared fs_struct

- entering makes the task count as chrooted so user namespace creation
  fails

- Nothing can be mounted on top of failfs and OPEN_TREE_CLONE is
  rejected; the overmount test runs in a private mount namespace so a
  regression cannot touch the host root

- setns() to a kept mount namespace fd restores root and working
  directory

- The failfs root is inherited across fork() and absolute exec fails

- Exec by fd of a dynamically linked binary fails on opening its
  absolute PT_INTERP interpreter

The exec tests run the exec in a child so a wrongly successful exec
cannot replace the test image and masquerade as a pass.

Link: https://patch.msgid.link/20260724-work-failfs-v2-6-485dabbae185@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-07-27 17:18:00 +02:00
Amir Goldstein
9acb102522 selftests/fuse: add ACL_DONT_CACHE regression test
Add a test that reproduces the stale ACL bug fixed by:
  "fs: preserve ACL_DONT_CACHE state in forget_cached_acl()"

A FUSE mount that does not negotiate FUSE_POSIX_ACL initialises inodes
with i_acl = ACL_DONT_CACHE.  Before the fix, calling
forget_all_cached_acls() (e.g. from fuse_update_get_attr() on a
statx(AT_STATX_FORCE_SYNC)) would silently replace ACL_DONT_CACHE with
ACL_NOT_CACHED, enabling the kernel ACL cache.  A subsequent getxattr
would populate the cache, and because fuse_set_acl() skips
forget_all_cached_acls() for !fc->posix_acl, later ACL changes were
not visible to callers — getxattr returned stale data.

The test mounts a minimal libfuse3 lowlevel filesystem (no
FUSE_POSIX_ACL negotiated) and:
  1. Issues two getxattrs — both must reach the daemon, proving
     ACL_DONT_CACHE suppresses caching before any trigger.
  2. Calls statx(AT_STATX_FORCE_SYNC) to trigger forget_all_cached_acls().
  3. Issues another getxattr (populates the cache on a buggy kernel).
  4. Switches the daemon to a different-sized ACL (ACL_B).
  5. Issues a final getxattr — expects ACL_B (44 bytes) and daemon
     call count 4; a buggy kernel returns stale ACL_A (28 bytes).

fuse_acl_cache_test is only built when libfuse3 is detected via
pkg-config.

Christian Brauner <brauner@kernel.org> says:
Changed do_force_statx() to call the statx() libc wrapper instead of
syscall(SYS_statx, ...) as requested by Amir after review feedback from
Luis Henriques, and dropped the now unused <sys/syscall.h> include.

Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Link: https://patch.msgid.link/20260713220932.413004-3-amir73il@gmail.com
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-07-21 22:04:02 +02:00
Jori Koolstra
e3a0127eee selftest: fix headers in fclog.c
fclog.c does not compile because it is missing fcntl.h, needed for
O_RDONLY etc.

There are also some redundant includes that are also in
kselftest_harness.h.

Link: https://lore.kernel.org/20260710171741.837308-1-jkoolstra@xs4all.nl
Signed-off-by: Jori Koolstra <jkoolstra@xs4all.nl>
Cc: Aleksa Sarai <cyphar@cyphar.com>
Cc: Shuah Khan <shuah@kernel.org>
Cc: Wei Yang <richard.weiyang@gmail.com>
Cc: Christian Brauner <brauner@kernel.org>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
2026-07-20 17:41:28 -07:00
Christian Brauner
d943e68edc
selftests/filesystems: test O_TMPFILE creation on idmapped mounts
Add a regression test for the fsuidgid_has_mapping() check in
vfs_tmpfile().  It idmaps a detached tmpfs mount so that the
caller-visible id range [0, 10000) maps onto the on-disk range
[10000, 20000) and checks that:

  - a caller whose fsuid/fsgid fall outside that range cannot create an
    O_TMPFILE through the mount and gets -EOVERFLOW instead of an inode
    owned by (uid_t)-1;

  - a mapped caller can create an O_TMPFILE, link it into the namespace,
    and the ownership round-trips through the mount idmap: it is reported
    as 0 through the mount and stored as 10000 on the underlying tmpfs.

The test runs entirely as root and uses setfsuid()/setfsgid() to become
the unmapped caller, so it needs no helper user.  The layer directory is
world-writable so that an unmapped caller still clears the directory
permission check and reaches the fsuidgid_has_mapping() test.

Link: https://patch.msgid.link/20260615-work-idmapped-tmpfile-v1-2-754a94d81f83@kernel.org
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-07-01 15:26:18 +02:00
Christian Brauner
1ec284f38b
selftests/filesystems/overlayfs: test idmapped overlay mounts
Add a selftest for idmapping the merged overlay mount itself.  It
applies an idmapping to a freshly created (still detached) overlay
mount with mount_setattr(MOUNT_ATTR_IDMAP) and checks that:

  - getattr reports ownership mapped through the mount idmap;
  - a file created through the idmapped mount is stored on the upper
    layer with the corresponding overlay-final id;
  - chown through the idmapped mount round-trips;
  - an nfs_export overlay can be idmapped and decodable file handles
    round-trip through it with correctly mapped ownership.

The layers live on a private tmpfs and are owned by the host id so that
they map to id 0 through the test idmapping, allowing the root caller
to operate on them.

Link: https://patch.msgid.link/20260615-work-idmapped-overlayfs-v1-9-7381632aa402@kernel.org
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-06-29 10:32:32 +02:00
Christian Brauner
e5804b1024
selftests/filesystems/overlayfs: fix set_layers_via_fds link error
set_layers_via_fds.c calls open_tree() directly, but that wrapper is
not provided by all C libraries, so the test fails to link with
"undefined reference to open_tree" on toolchains without it.

Use sys_open_tree() from ../wrappers.h, the syscall wrapper already
used for move_mount(), fsmount() and friends here.  This is also a
prerequisite for building the new idmapped_mounts test added to this
directory.

Link: https://patch.msgid.link/20260615-work-idmapped-overlayfs-v1-8-7381632aa402@kernel.org
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-06-29 10:32:32 +02:00
Christian Brauner
a21db4dcaf
selftests/filesystems: add ustat() coverage
user_get_super() is now backed by the global device-to-superblock table
instead of a walk of the super_blocks list. ustat(2) is its most direct
user-visible consumer but nothing in the tree exercises it.

Add a small regression test: the device number of a mounted tmpfs (an
anonymous device, registered in the table by sget_fc()) must resolve,
it must stop resolving after the unmount (the entry is dropped again in
kill_super_notify()), and bogus device numbers keep reporting EINVAL.

The test passes on kernels before the conversion: it pins down the
semantics the table-backed lookup must preserve.

Link: https://patch.msgid.link/20260616-work-super-bdev_holder_global-v2-18-7df6b864028e@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-06-29 10:31:54 +02:00
Linus Torvalds
5b7c3f0fe3 vfs-7.2-rc1.eventpoll
Please consider pulling these changes from the signed vfs-7.2-rc1.eventpoll tag.
 
 Thanks!
 Christian
 -----BEGIN PGP SIGNATURE-----
 
 iHUEABYKAB0WIQRAhzRXHqcMeLMyaSiRxhvAZXjcogUCaiwLKgAKCRCRxhvAZXjc
 ouUiAP9oTjqqJEcc50zs79WLZANmgn5+/RONL2c65VHaOh2cHAEA/SWT56OnQ+Rf
 debIkResImn7LiEdbOJCp6PId60hIgE=
 =Z6mX
 -----END PGP SIGNATURE-----

Merge tag 'vfs-7.2-rc1.eventpoll' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs

Pull eventpoll updates from Christian Brauner:

 - eventpoll clarity refactor

   The recent eventpoll UAF fixes (a6dc643c69 and follow-ups) depended
   on invariants in fs/eventpoll.c that were nowhere documented and had
   to be reverse-engineered from the code: the lifetime relationships
   between struct eventpoll, struct epitem, and struct file, the three
   removal paths coordinating via epi_fget() pins and ep->mtx, the
   ovflist sentinel-encoded scan state machine, the POLLFREE
   release/acquire handshake, and the loop / path check globals
   serialized by epnested_mutex. The fixes were correct but the next
   person to touch this code would hit the same learning curve.

   This series codifies those invariants in source and tightens the
   surrounding structure. No functional changes intended:

     - Documentation: a top-of-file overview with field-protection
       tables for struct eventpoll and struct epitem, a section
       gathering the loop-check / path-check globals next to their
       declarations, labelled comments on the two sides of the POLLFREE
       handshake, refreshed comments on epi_fget() and ep_remove_file(),
       and a docblock on ep_clear_and_put() that names its two-pass
       structure as load-bearing.

     - Mechanical renames: ep_refcount_dec_and_test() -> ep_put() to
       pair with ep_get(), attach_epitem() -> ep_attach_file() for
       ep_remove_file() symmetry, the unused depth argument dropped from
       epoll_mutex_lock(), and the CONFIG_KCMP block relocated next to
       CONFIG_COMPAT so the hot-path code is contiguous.

     - Helper extraction: ep_insert() splits into ep_alloc_epitem() and
       ep_register_epitem(), ep_clear_and_put()'s two passes become
       ep_drain_pollwaits() and ep_drain_tree() so the ordering
       invariant is enforced by the call sequence rather than
       convention, the per-event delivery loop body becomes
       ep_deliver_event(), and the ep->mtx + epnested_mutex acquisition
       dance lifts out of do_epoll_ctl() into ep_ctl_lock() /
       ep_ctl_unlock().

     - Sentinel and predicate cleanup: the EP_UNACTIVE_PTR overload is
       hidden behind named helpers (ep_is_scanning, epi_on_ovflist,
       ...), epi->next is renamed to epi->ovflist_next, and the boolean
       predicates return bool.

     - The per-CTL_ADD scratch state (tfile_check_list, path_count[],
       inserting_into) moves from file-scope globals into a
       stack-allocated struct ep_ctl_ctx plumbed through the loop / path
       check chain.

   Two follow-up fixes are included: missing kernel-doc for the new @ctx
   parameters, and restoring the EP_UNACTIVE_PTR sentinel for
   ctx->tfile_check_list - replacing it with NULL termination broke
   ep_remove_file()'s "never listed" check for the list tail, causing a
   syzbot-reported use-after-free.

 - io_uring related epoll cleanups

   One of the nastier things about epoll is how it allows nesting
   contexts inside each other, leading to the necessity of loop
   detection and the issues that have come with that. There is no reason
   to support nesting on the io_uring side, so contain the damage and
   disallow nested contexts from there: eventpoll gains a file based
   control interface and struct epoll_filefd is renamed to epoll_key.
   The io_uring side proper goes on top of this through the block tree.

 - Fix epoll_wait() reporting false negatives

   ep_events_available() checks ep->rdllist and ep_is_scanning() without
   a lock and can race with a concurrent scan such that neither check
   sees the events, causing epoll_wait() with a zero timeout to wrongly
   report no events even though events are available. A sequence lock
   closes the race and a reproducer is added to the eventpoll selftests.

* tag 'vfs-7.2-rc1.eventpoll' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: (25 commits)
  eventpoll: restore EP_UNACTIVE_PTR sentinel for ctx->tfile_check_list
  eventpoll: Fix epoll_wait() report false negative
  selftests/eventpoll: Add test for multiple waiters
  eventpoll: add missing kernel-doc for @ctx function parameters
  eventpoll: rename struct epoll_filefd to epoll_key
  eventpoll: add file based control interface
  eventpoll: export is_file_epoll()
  eventpoll: pass struct epoll_filefd through ep_find() and ep_insert()
  eventpoll: hoist CTL_ADD scratch state into struct ep_ctl_ctx
  eventpoll: use bool for predicate helpers
  eventpoll: rename epi->next and txlist for clarity
  eventpoll: wrap EP_UNACTIVE_PTR in typed sentinel helpers
  eventpoll: extract lock dance from do_epoll_ctl() into ep_ctl_lock()
  eventpoll: extract ep_deliver_event() from ep_send_events()
  eventpoll: split ep_clear_and_put() into drain helpers
  eventpoll: split ep_insert() into alloc + register stages
  eventpoll: relocate KCMP helpers near compat syscalls
  eventpoll: rename attach_epitem() to ep_attach_file()
  eventpoll: drop unused depth argument from epoll_mutex_lock()
  eventpoll: rename ep_refcount_dec_and_test() to ep_put()
  ...
2026-06-15 03:40:54 +05:30
Nam Cao
827382c088
selftests/eventpoll: Add test for multiple waiters
Add a test whichs creates 64 threads who all epoll_wait() on the same
eventpoll. The source eventfd is written but never read, therefore all the
threads should always see an EPOLLIN event.

This test fails because of a kernel bug, which will be fixed by a follow-up
commit.

Signed-off-by: Nam Cao <namcao@linutronix.de>
Link: https://patch.msgid.link/b11947013563875c046c0b0959c29fd95eeebd34.1780422138.git.namcao@linutronix.de
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-06-04 10:25:10 +02:00
Christian Brauner
8c47b5e9b9
selftests: openat2: port emptypath_test to kselftest harness
Convert the emptypath selftests to the
FIXTURE_SETUP()/FIXTURE_TEARDOWN() and the two checks become TEST_F()s.
No change in coverage.

Link: https://patch.msgid.link/20260521-wettstreit-meinen-46271dede480@brauner
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-05-21 15:33:48 +02:00
Dorjoy Chowdhury
6045a75399
kselftest/openat2: test for OPENAT2_REGULAR flag
Just a happy path test.

Christian Brauner <brauner@kernel.org> says:

Update OPENAT2_REGULAR fallback define to match upper-32-bit UAPI value.
Port the test to the kselftest_harness TEST*/FIXTURE framework to match
the migrated openat2_test.c, and add a regression test ensuring
open()/openat() keep ignoring the internal __O_REGULAR carrier bit.

Signed-off-by: Dorjoy Chowdhury <dorjoychy111@gmail.com>
Link: https://patch.msgid.link/20260328172314.45807-3-dorjoychy111@gmail.com
Reviewed-by: Aleksa Sarai <aleksa@amutable.com>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-05-21 15:33:48 +02:00
Jori Koolstra
c0329020da
selftest: add tests for O_EMPTYPATH
Add tests for the new O_EMPTYPATH flag of openat(2)/openat2(2).

Also, the current openat2 tests include a helper header file that
defines the necessary structs and constants to use openat2(2), such as
struct open_how. This may result in conflicting definitions when the
system header openat2.h is present as well.

So add openat2.h generated by 'make headers' to the uapi header
files in ./tools/include and remove the helper file definitions of
the current openat2 selftests.

Signed-off-by: Jori Koolstra <jkoolstra@xs4all.nl>
Link: https://patch.msgid.link/20260424114611.1678641-3-jkoolstra@xs4all.nl
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-05-21 10:53:37 +02:00
Aleksa Sarai
215be76e02
selftests: openat2: migrate to kselftest harness
These tests were written in the early days of selftests' TAP support,
the more modern kselftest harness is much easier to follow and maintain.
The actual contents of the tests are unchanged by this change. Most of
the diff involves switching from the E_* syscall wrappers we previously
used to ASSERT_EQ(fn(...), 0) in tests and helper functions.

The first pass of the migration was done using Claude, followed by a
manual rework and review.

Assisted-by: Claude:claude-4.6-opus
Signed-off-by: Aleksa Sarai <aleksa@amutable.com>
Link: https://patch.msgid.link/20260401-openat2-selftests-kunit-v2-4-ad153a07da0c@amutable.com
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-05-21 10:53:29 +02:00
Aleksa Sarai
582c904573
selftests: openat2: switch from custom ARRAY_LEN to ARRAY_SIZE
For whatever reason, the original version of the tests used a custom
version of ARRAY_SIZE, but ARRAY_SIZE works just as well.

Signed-off-by: Aleksa Sarai <aleksa@amutable.com>
Link: https://patch.msgid.link/20260401-openat2-selftests-kunit-v2-3-ad153a07da0c@amutable.com
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-05-21 10:53:25 +02:00
Aleksa Sarai
d2fcf57ffc
selftests: openat2: move helpers to header
This is a bit ugly, but in the next patch we will move to using
kselftest_harness.h -- which doesn't play well with being included in
multiple compilation units due to duplicate function definitions.

Not including kselftest_harness.h would let us avoid this patch, but the
helpers will need include kselftest_harness.h in order to switch to
TH_LOG.

Signed-off-by: Aleksa Sarai <aleksa@amutable.com>
Link: https://patch.msgid.link/20260401-openat2-selftests-kunit-v2-2-ad153a07da0c@amutable.com
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-05-21 10:53:22 +02:00
Aleksa Sarai
fe08792704
selftests: move openat2 tests to selftests/filesystems/
These tests really should've always belonged there, doubly so now that
they include a lot of other generic filesystem-related tests.

Suggested-by: Christian Brauner <brauner@kernel.org>
Signed-off-by: Aleksa Sarai <aleksa@amutable.com>
Link: https://patch.msgid.link/20260401-openat2-selftests-kunit-v2-1-ad153a07da0c@amutable.com
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-05-21 10:53:09 +02:00
Linus Torvalds
7c8a4671dc vfs-7.1-rc1.mount.v2
Please consider pulling these changes from the signed vfs-7.1-rc1.mount.v2 tag.
 
 Thanks!
 Christian
 -----BEGIN PGP SIGNATURE-----
 
 iHUEABYKAB0WIQRAhzRXHqcMeLMyaSiRxhvAZXjcogUCad3vFgAKCRCRxhvAZXjc
 onXwAQDwEGvpMUUiuI/JWFqCA5vY5LXXr/36wdcs0iUL1uy9IgEAyOdnYhYkcaX1
 3lm87f6OmYkhlq6enJbco7uT4CUzlQA=
 =1Ls8
 -----END PGP SIGNATURE-----

Merge tag 'vfs-7.1-rc1.mount.v2' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs

Pull vfs mount updates from Christian Brauner:

 - Add FSMOUNT_NAMESPACE flag to fsmount() that creates a new mount
   namespace with the newly created filesystem attached to a copy of the
   real rootfs. This returns a namespace file descriptor instead of an
   O_PATH mount fd, similar to how OPEN_TREE_NAMESPACE works for
   open_tree().

   This allows creating a new filesystem and immediately placing it in a
   new mount namespace in a single operation, which is useful for
   container runtimes and other namespace-based isolation mechanisms.

   This accompanies OPEN_TREE_NAMESPACE and avoids a needless detour via
   OPEN_TREE_NAMESPACE to get the same effect. Will be especially useful
   when you mount an actual filesystem to be used as the container
   rootfs.

 - Currently, creating a new mount namespace always copies the entire
   mount tree from the caller's namespace. For containers and sandboxes
   that intend to build their mount table from scratch this is wasteful:
   they inherit a potentially large mount tree only to immediately tear
   it down.

   This series adds support for creating a mount namespace that contains
   only a clone of the root mount, with none of the child mounts. Two
   new flags are introduced:

     - CLONE_EMPTY_MNTNS (0x400000000) for clone3(), using the 64-bit flag space
     - UNSHARE_EMPTY_MNTNS (0x00100000) for unshare()

   Both flags imply CLONE_NEWNS. The resulting namespace contains a
   single nullfs root mount with an immutable empty directory. The
   intended workflow is to then mount a real filesystem (e.g., tmpfs)
   over the root and build the mount table from there.

 - Allow MOVE_MOUNT_BENEATH to target the caller's rootfs, allowing to
   switch out the rootfs without pivot_root(2).

   The traditional approach to switching the rootfs involves
   pivot_root(2) or a chroot_fs_refs()-based mechanism that atomically
   updates fs->root for all tasks sharing the same fs_struct. This has
   consequences for fork(), unshare(CLONE_FS), and setns().

   This series instead decomposes root-switching into individually
   atomic, locally-scoped steps:

	fd_tree = open_tree(-EBADF, "/newroot", OPEN_TREE_CLONE | OPEN_TREE_CLOEXEC);
	fchdir(fd_tree);
	move_mount(fd_tree, "", AT_FDCWD, "/", MOVE_MOUNT_BENEATH | MOVE_MOUNT_F_EMPTY_PATH);
	chroot(".");
	umount2(".", MNT_DETACH);

   Since each step only modifies the caller's own state, the
   fork/unshare/setns races are eliminated by design.

   A key step to making this possible is to remove the locked mount
   restriction. Originally MOVE_MOUNT_BENEATH doesn't support mounting
   beneath a mount that is locked. The locked mount protects the
   underlying mount from being revealed. This is a core mechanism of
   unshare(CLONE_NEWUSER | CLONE_NEWNS). The mounts in the new mount
   namespace become locked. That effectively makes the new mount table
   useless as the caller cannot ever get rid of any of the mounts no
   matter how useless they are.

   We can lift this restriction though. We simply transfer the locked
   property from the top mount to the mount beneath. This works because
   what we care about is to protect the underlying mount aka the parent.
   The mount mounted between the parent and the top mount takes over the
   job of protecting the parent mount from the top mount mount. This
   leaves us free to remove the locked property from the top mount which
   can consequently be unmounted:

	unshare(CLONE_NEWUSER | CLONE_NEWNS)

   and we inherit a clone of procfs on /proc then currently we cannot
   unmount it as:

	umount -l /proc

   will fail with EINVAL because the procfs mount is locked.

   After this series we can now do:

	mount --beneath -t tmpfs tmpfs /proc
	umount -l /proc

   after which a tmpfs mount has been placed beneath the procfs mount.
   The tmpfs mount has become locked and the procfs mount has become
   unlocked.

   This means you can safely modify an inherited mount table after
   unprivileged namespace creation.

   Afterwards we simply make it possible to move a mount beneath the
   rootfs allowing to upgrade the rootfs.

   Removing the locked restriction makes this very useful for containers
   created with unshare(CLONE_NEWUSER | CLONE_NEWNS) to reshuffle an
   inherited mount table safely and MOVE_MOUNT_BENEATH makes it possible
   to switch out the rootfs instead of using the costly pivot_root(2).

* tag 'vfs-7.1-rc1.mount.v2' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs:
  selftests/namespaces: remove unused utils.h include from listns_efault_test
  selftests/fsmount_ns: add missing TARGETS and fix cap test
  selftests/empty_mntns: fix wrong CLONE_EMPTY_MNTNS hex value in comment
  selftests/empty_mntns: fix statmount_alloc() signature mismatch
  selftests/statmount: remove duplicate wait_for_pid()
  mount: always duplicate mount
  selftests/filesystems: add MOVE_MOUNT_BENEATH rootfs tests
  move_mount: allow MOVE_MOUNT_BENEATH on the rootfs
  move_mount: transfer MNT_LOCKED
  selftests/filesystems: add clone3 tests for empty mount namespaces
  selftests/filesystems: add tests for empty mount namespaces
  namespace: allow creating empty mount namespaces
  selftests: add FSMOUNT_NAMESPACE tests
  selftests/statmount: add statmount_alloc() helper
  tools: update mount.h header
  mount: add FSMOUNT_NAMESPACE
  mount: simplify __do_loopback()
  mount: start iterating from start of rbtree
2026-04-14 19:59:25 -07:00
Christian Brauner
660c09404c
selftests/fsmount_ns: add missing TARGETS and fix cap test
Add missing top-level kselftest TARGETS entries for empty_mntns and
fsmount_ns so that 'make kselftest' discovers and runs these tests.

Fix requires_cap_sys_admin test which always SKIPped because fsopen()
was called after enter_userns(), where CAP_SYS_ADMIN in the mount
namespace's user_ns is unavailable. Move fsopen/fsconfig before fork so
the configured fs_fd is inherited by the child, which then only needs to
call fsmount() after dropping privileges.

Fixes: 3ac7ea91f3 ("selftests: add FSMOUNT_NAMESPACE tests")
Signed-off-by: Christian Brauner <brauner@kernel.org>
2026-04-14 09:31:07 +02:00
Christian Brauner
d38aa6cdee
selftests/empty_mntns: fix wrong CLONE_EMPTY_MNTNS hex value in comment
CLONE_EMPTY_MNTNS is (1ULL << 37) = 0x2000000000ULL, not 0x400000000ULL.

Fixes: 5b8ffd63fb ("selftests/filesystems: add clone3 tests for empty mount namespaces")
Signed-off-by: Christian Brauner <brauner@kernel.org>
2026-04-14 09:30:57 +02:00
Christian Brauner
1a398a2378
selftests/empty_mntns: fix statmount_alloc() signature mismatch
empty_mntns.h includes ../statmount/statmount.h which provides a
4-argument statmount_alloc(mnt_id, mnt_ns_id, mask, flags), but then
redefines its own 3-argument version without the flags parameter. This
causes a build failure due to conflicting types.

Remove the duplicate definition from empty_mntns.h and update all
callers to pass 0 for the flags argument.

Fixes: 32f54f2bbc ("selftests/filesystems: add tests for empty mount namespaces")
Signed-off-by: Christian Brauner <brauner@kernel.org>
2026-04-14 09:30:48 +02:00