mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 0/3] dcache: fixes for mountpoints racing d_invalidate() and umount
@ 2026-10-30 12:38 Christian Brauner
  2026-10-30 12:38 ` [PATCH 1/3] dcache: let d_invalidate() wait for a d_set_mounted() in flight Christian Brauner
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Christian Brauner @ 2026-10-30 12:38 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Alexander Viro, Jan Kara, linux-kernel, Karl Mehltretter,
	Chris Mason, Josef Bacik, Christian Brauner (Amutable),
	stable

d_set_mounted() hasn't bumped the seqcount of rename_lock since v6.17
and the lockless walk in d_invalidate() neither waits for nor retries
against a concurrent mount anymore.

So a mount below a directory that is being invalidated can end up below
the unhashed directory. Nobody can reach it anymore and it pins the
subtree until the mount namespace goes away. Giving d_set_mounted() a
seqlock of its own that d_invalidate() waits on after its unhash closes
that without going back to bumping the seqcount.

The second one is from v7.3 and was backported to 7.2.6. do_one_tree()
now takes every secondary root off ->s_roots before its dput(). If
another thread is evicting the root at the same time umount loses the
eviction to it and doesn't wait for it. That ends in busy inodes after
unmount and an iput() on a dead superblock.

The third one is old. With CAP_DAC_READ_SEARCH a disconnected dentry
can be mounted on via open_by_handle_at() and move_mount(). When that
mount goes away while the filesystem of the dentry is unmounted, umount
never sees the dentry. Same result as the second one. The fix makes such
a dentry a secondary root until it's evicted. So it needs the second
patch and it only goes back to v7.2.

I reproduced all three in a VM. With a FUSE directory 3000 levels deep
151 of 200 bind mounts racing FUSE_NOTIFY_INVAL_ENTRY ended up below the
invalidated directory and none did with the fix. The other two need
delays in the right places to trigger. With them both reliably end in
busy inodes and a GPF in iput() and with the fixes they don't.

This goes into vfs.fixes.

Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
---
Christian Brauner (1):
      dcache: let d_invalidate() wait for a d_set_mounted() in flight

Josef Bacik (2):
      dcache: wait for a racing eviction of a secondary root
      dcache: let umount find a disconnected ex-mountpoint

 fs/dcache.c                    | 44 ++++++++++++++++++++++++++++++++++--------
 include/linux/fs/super_types.h |  2 +-
 2 files changed, 37 insertions(+), 9 deletions(-)
---
base-commit: 172658cf600904ff6121e240f69a0ccb36e65d6b
change-id: 20261029-work-dcache-ai-6e7ad5e247ce


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-10-30 12:38 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-30 12:38 [PATCH 0/3] dcache: fixes for mountpoints racing d_invalidate() and umount Christian Brauner
2026-10-30 12:38 ` [PATCH 1/3] dcache: let d_invalidate() wait for a d_set_mounted() in flight Christian Brauner
2026-10-30 12:38 ` [PATCH 2/3] dcache: wait for a racing eviction of a secondary root Christian Brauner
2026-10-30 12:38 ` [PATCH 3/3] dcache: let umount find a disconnected ex-mountpoint Christian Brauner

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®