From 5d132cfafb6a86740e65177c79fd5d7b02613383 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 5 Jul 2025 00:38:09 -0400 Subject: [PATCH] setup_mnt(): primitive for connecting a mount to filesystem Take the identical logics in vfs_create_mount() and clone_mnt() into a new helper that takes an empty struct mount and attaches it to given dentry (sub)tree. Should be called once in the lifetime of every mount, prior to making it visible in any data structures. After that point ->mnt_root and ->mnt_sb never change; ->mnt_root is a counting reference to dentry and ->mnt_sb - an active reference to superblock. Mount remains associated with that dentry tree all the way until the call of cleanup_mnt(), when the refcount eventually drops to zero. Reviewed-by: Christian Brauner Signed-off-by: Al Viro --- fs/namespace.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/fs/namespace.c b/fs/namespace.c index c628a323281b3..4e9ed4edd8542 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -1196,6 +1196,21 @@ static void commit_tree(struct mount *mnt) touch_mnt_namespace(n); } +static void setup_mnt(struct mount *m, struct dentry *root) +{ + struct super_block *s = root->d_sb; + + atomic_inc(&s->s_active); + m->mnt.mnt_sb = s; + m->mnt.mnt_root = dget(root); + m->mnt_mountpoint = m->mnt.mnt_root; + m->mnt_parent = m; + + lock_mount_hash(); + list_add_tail(&m->mnt_instance, &s->s_mounts); + unlock_mount_hash(); +} + /** * vfs_create_mount - Create a mount for a configured superblock * @fc: The configuration context with the superblock attached @@ -1219,15 +1234,8 @@ struct vfsmount *vfs_create_mount(struct fs_context *fc) if (fc->sb_flags & SB_KERNMOUNT) mnt->mnt.mnt_flags = MNT_INTERNAL; - atomic_inc(&fc->root->d_sb->s_active); - mnt->mnt.mnt_sb = fc->root->d_sb; - mnt->mnt.mnt_root = dget(fc->root); - mnt->mnt_mountpoint = mnt->mnt.mnt_root; - mnt->mnt_parent = mnt; + setup_mnt(mnt, fc->root); - lock_mount_hash(); - list_add_tail(&mnt->mnt_instance, &mnt->mnt.mnt_sb->s_mounts); - unlock_mount_hash(); return &mnt->mnt; } EXPORT_SYMBOL(vfs_create_mount); @@ -1285,7 +1293,6 @@ EXPORT_SYMBOL_GPL(vfs_kern_mount); static struct mount *clone_mnt(struct mount *old, struct dentry *root, int flag) { - struct super_block *sb = old->mnt.mnt_sb; struct mount *mnt; int err; @@ -1310,16 +1317,9 @@ static struct mount *clone_mnt(struct mount *old, struct dentry *root, if (mnt->mnt_group_id) set_mnt_shared(mnt); - atomic_inc(&sb->s_active); mnt->mnt.mnt_idmap = mnt_idmap_get(mnt_idmap(&old->mnt)); - mnt->mnt.mnt_sb = sb; - mnt->mnt.mnt_root = dget(root); - mnt->mnt_mountpoint = mnt->mnt.mnt_root; - mnt->mnt_parent = mnt; - lock_mount_hash(); - list_add_tail(&mnt->mnt_instance, &sb->s_mounts); - unlock_mount_hash(); + setup_mnt(mnt, root); if (flag & CL_PRIVATE) // we are done with it return mnt; -- 2.47.3