From: Christian Brauner <brauner@kernel.org>
To: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Jann Horn <jannh@google.com>, Jan Kara <jack@suse.cz>,
Amir Goldstein <amir73il@gmail.com>,
linux-fsdevel@vger.kernel.org,
Alexander Viro <viro@zeniv.linux.org.uk>,
"Christian Brauner (Amutable)" <brauner@kernel.org>
Subject: [PATCH RFC v2 4/8] namespace: drop the file's reference first in dissolve_on_fput()
Date: Fri, 25 Sep 2026 00:35:44 +0200 [thread overview]
Message-ID: <20260925-work-mount-knullfs-v2-4-c4aebaa186e9@kernel.org> (raw)
In-Reply-To: <20260925-work-mount-knullfs-v2-0-c4aebaa186e9@kernel.org>
A detached mount tree is held alive by a file. dissolve_on_fput()
unmounts the detached tree attached to that file.
Currently dissolve_on_fput() leaves the file's reference to the root of
the tree to the caller. So either __fput(), open_detached_copy(), or
fsmount() drop the mount.
That's backwards. The reference keeps the tree around and is dropped
when the tree is already gone. Instead, let dissolve_on_fput() the mount
and drop it after umount_tree() with namespace_sem still held. After
umount_tree() the mntput() is never the last reference and so the root
gets unmounted before its children.
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
---
fs/file_table.c | 3 ++-
fs/namespace.c | 9 ++++++---
2 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/fs/file_table.c b/fs/file_table.c
index c68b8c0a4097..e2665eaa6f8c 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -520,7 +520,8 @@ static void __fput(struct file *file)
dput(dentry);
if (unlikely(mode & FMODE_NEED_UNMOUNT))
dissolve_on_fput(mnt);
- mntput(mnt);
+ else
+ mntput(mnt);
out:
file_free(file);
}
diff --git a/fs/namespace.c b/fs/namespace.c
index 580877e46b1a..4ff3cebe6c31 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -2294,9 +2294,11 @@ void drop_collected_paths(const struct path *paths, const struct path *prealloc)
static struct mnt_namespace *alloc_mnt_ns(struct user_namespace *, bool);
+/* Consumes the caller's reference to @mnt. */
void dissolve_on_fput(struct vfsmount *mnt)
{
- struct mount *m = real_mount(mnt);
+ struct vfsmount *p __free(mntput) = mnt;
+ struct mount *m = real_mount(p);
/*
* m used to be the root of anon namespace; if it still is one,
@@ -2321,6 +2323,7 @@ void dissolve_on_fput(struct vfsmount *mnt)
lock_mount_hash();
umount_tree(m, UMOUNT_CONNECTED);
unlock_mount_hash();
+ mntput(no_free_ptr(p));
}
}
@@ -3088,7 +3091,7 @@ static struct file *open_detached_copy(struct path *path, unsigned int flags)
path->mnt = mntget(&ns->root->mnt);
file = dentry_open(path, O_PATH, current_cred());
if (IS_ERR(file))
- dissolve_on_fput(path->mnt);
+ dissolve_on_fput(no_free_ptr(path->mnt));
else
file->f_mode |= FMODE_NEED_UNMOUNT;
return file;
@@ -4545,7 +4548,7 @@ SYSCALL_DEFINE3(fsmount, int, fs_fd, unsigned int, flags,
FD_PREPARE(fdf, (flags & FSMOUNT_CLOEXEC) ? O_CLOEXEC : 0,
dentry_open(&new_path, O_PATH, fc->cred));
if (fdf.err) {
- dissolve_on_fput(new_path.mnt);
+ dissolve_on_fput(no_free_ptr(new_path.mnt));
return fdf.err;
}
--
2.53.0
next prev parent reply other threads:[~2026-09-24 22:35 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-24 22:35 [PATCH RFC v2 0/8] namespace: prevent UMOUNT_CONNECTED reference count cycles Christian Brauner
2026-09-24 22:35 ` [PATCH RFC v2 1/8] fs: refuse fspick() on internal superblocks Christian Brauner
2026-09-24 22:35 ` [PATCH RFC v2 2/8] fsnotify: record the superblock a connector is accounted on Christian Brauner
2026-09-24 22:35 ` [PATCH RFC v2 3/8] fs: put the old fs_struct before the old namespaces in unshare() Christian Brauner
2026-09-24 22:35 ` Christian Brauner [this message]
2026-09-24 22:35 ` [PATCH RFC v2 5/8] namespace: prevent UMOUNT_CONNECTED reference count cycles Christian Brauner
2026-09-24 22:35 ` [PATCH RFC v2 6/8] selftests/filesystems: check that a loop mount below a dead mount is released Christian Brauner
2026-09-24 22:35 ` [PATCH RFC v2 7/8] selftests/filesystems: check the two-step cycle over crossed loop images Christian Brauner
2026-09-24 22:35 ` [PATCH RFC v2 8/8] selftests/filesystems: check that the holders let go of a dead mount Christian Brauner
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260925-work-mount-knullfs-v2-4-c4aebaa186e9@kernel.org \
--to=brauner@kernel.org \
--cc=amir73il@gmail.com \
--cc=jack@suse.cz \
--cc=jannh@google.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=torvalds@linux-foundation.org \
--cc=viro@zeniv.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.