diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2023-02-25 04:20:07 +0100 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2023-02-25 04:20:07 +0100 |
commit | 3df88c6a175d883b58fc3c31e36c94eb5e2ad180 (patch) | |
tree | edf5dbd6d199ec94d3617945be0b8dbfbc578798 /fs/namespace.c | |
parent | Merge branch 'work.alpha' of git://git.kernel.org/pub/scm/linux/kernel/git/vi... (diff) | |
parent | ipc,namespace: batch free ipc_namespace structures (diff) | |
download | linux-3df88c6a175d883b58fc3c31e36c94eb5e2ad180.tar.xz linux-3df88c6a175d883b58fc3c31e36c94eb5e2ad180.zip |
Merge branch 'work.namespace' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull ipc namespace update from Al Viro:
"Rik's patches reducing the amount of synchronize_rcu() triggered by
ipc namespace destruction.
I've some pending stuff reducing that on the normal umount side, but
it's nowhere near ready and Rik's stuff shouldn't be held back due to
conflicts - I'll just redo the parts of my series that stray into
ipc/*"
* 'work.namespace' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
ipc,namespace: batch free ipc_namespace structures
ipc,namespace: make ipc namespace allocation wait for pending free
Diffstat (limited to 'fs/namespace.c')
-rw-r--r-- | fs/namespace.c | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/fs/namespace.c b/fs/namespace.c index 5927d90e24a0..bc0f15257b49 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -1283,6 +1283,17 @@ struct vfsmount *mntget(struct vfsmount *mnt) } EXPORT_SYMBOL(mntget); +/* + * Make a mount point inaccessible to new lookups. + * Because there may still be current users, the caller MUST WAIT + * for an RCU grace period before destroying the mount point. + */ +void mnt_make_shortterm(struct vfsmount *mnt) +{ + if (mnt) + real_mount(mnt)->mnt_ns = NULL; +} + /** * path_is_mountpoint() - Check if path is a mount in the current namespace. * @path: path to check @@ -4459,8 +4470,8 @@ EXPORT_SYMBOL_GPL(kern_mount); void kern_unmount(struct vfsmount *mnt) { /* release long term mount so mount point can be released */ - if (!IS_ERR_OR_NULL(mnt)) { - real_mount(mnt)->mnt_ns = NULL; + if (!IS_ERR(mnt)) { + mnt_make_shortterm(mnt); synchronize_rcu(); /* yecchhh... */ mntput(mnt); } @@ -4472,8 +4483,7 @@ void kern_unmount_array(struct vfsmount *mnt[], unsigned int num) unsigned int i; for (i = 0; i < num; i++) - if (mnt[i]) - real_mount(mnt[i])->mnt_ns = NULL; + mnt_make_shortterm(mnt[i]); synchronize_rcu_expedited(); for (i = 0; i < num; i++) mntput(mnt[i]); |