summaryrefslogtreecommitdiff
path: root/fs/namespace.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2023-02-24 19:20:07 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2023-02-24 19:20:07 -0800
commit3df88c6a175d883b58fc3c31e36c94eb5e2ad180 (patch)
treeedf5dbd6d199ec94d3617945be0b8dbfbc578798 /fs/namespace.c
parent10cc5d483ebc00e82d9a38d3419b2edc8b79b64d (diff)
parentda27f796a832122ee533c7685438dad1c4e338dd (diff)
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.c18
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]);