Skip to content

Commit 390c684

Browse files
Ram PaiLinus Torvalds
authored andcommitted
[PATCH] making namespace_sem global
This removes the per-namespace semaphore in favor of a global semaphore. This can have an effect on namespace scalability. Signed-off-by: Miklos Szeredi <miklos@szeredi.hu> Signed-off-by: Ram Pai <linuxram@us.ibm.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
1 parent 36341f6 commit 390c684

File tree

2 files changed

+23
-24
lines changed

2 files changed

+23
-24
lines changed

fs/namespace.c

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ static int event;
4646
static struct list_head *mount_hashtable;
4747
static int hash_mask __read_mostly, hash_bits __read_mostly;
4848
static kmem_cache_t *mnt_cache;
49+
static struct rw_semaphore namespace_sem;
4950

5051
static inline unsigned long hash(struct vfsmount *mnt, struct dentry *dentry)
5152
{
@@ -250,7 +251,7 @@ static void *m_start(struct seq_file *m, loff_t *pos)
250251
struct list_head *p;
251252
loff_t l = *pos;
252253

253-
down_read(&n->sem);
254+
down_read(&namespace_sem);
254255
list_for_each(p, &n->list)
255256
if (!l--)
256257
return list_entry(p, struct vfsmount, mnt_list);
@@ -267,8 +268,7 @@ static void *m_next(struct seq_file *m, void *v, loff_t *pos)
267268

268269
static void m_stop(struct seq_file *m, void *v)
269270
{
270-
struct namespace *n = m->private;
271-
up_read(&n->sem);
271+
up_read(&namespace_sem);
272272
}
273273

274274
static inline void mangle(struct seq_file *m, const char *s)
@@ -487,7 +487,7 @@ static int do_umount(struct vfsmount *mnt, int flags)
487487
return retval;
488488
}
489489

490-
down_write(&current->namespace->sem);
490+
down_write(&namespace_sem);
491491
spin_lock(&vfsmount_lock);
492492
event++;
493493

@@ -500,7 +500,7 @@ static int do_umount(struct vfsmount *mnt, int flags)
500500
spin_unlock(&vfsmount_lock);
501501
if (retval)
502502
security_sb_umount_busy(mnt);
503-
up_write(&current->namespace->sem);
503+
up_write(&namespace_sem);
504504
release_mounts(&umount_list);
505505
return retval;
506506
}
@@ -678,7 +678,7 @@ static int do_loopback(struct nameidata *nd, char *old_name, int recurse)
678678
if (err)
679679
return err;
680680

681-
down_write(&current->namespace->sem);
681+
down_write(&namespace_sem);
682682
err = -EINVAL;
683683
if (!check_mnt(nd->mnt) || !check_mnt(old_nd.mnt))
684684
goto out;
@@ -702,7 +702,7 @@ static int do_loopback(struct nameidata *nd, char *old_name, int recurse)
702702
}
703703

704704
out:
705-
up_write(&current->namespace->sem);
705+
up_write(&namespace_sem);
706706
path_release(&old_nd);
707707
return err;
708708
}
@@ -750,7 +750,7 @@ static int do_move_mount(struct nameidata *nd, char *old_name)
750750
if (err)
751751
return err;
752752

753-
down_write(&current->namespace->sem);
753+
down_write(&namespace_sem);
754754
while (d_mountpoint(nd->dentry) && follow_down(&nd->mnt, &nd->dentry))
755755
;
756756
err = -EINVAL;
@@ -795,7 +795,7 @@ static int do_move_mount(struct nameidata *nd, char *old_name)
795795
out1:
796796
up(&nd->dentry->d_inode->i_sem);
797797
out:
798-
up_write(&current->namespace->sem);
798+
up_write(&namespace_sem);
799799
if (!err)
800800
path_release(&parent_nd);
801801
path_release(&old_nd);
@@ -834,7 +834,7 @@ int do_add_mount(struct vfsmount *newmnt, struct nameidata *nd,
834834
{
835835
int err;
836836

837-
down_write(&current->namespace->sem);
837+
down_write(&namespace_sem);
838838
/* Something was mounted here while we slept */
839839
while (d_mountpoint(nd->dentry) && follow_down(&nd->mnt, &nd->dentry))
840840
;
@@ -862,11 +862,11 @@ int do_add_mount(struct vfsmount *newmnt, struct nameidata *nd,
862862
list_add_tail(&newmnt->mnt_expire, fslist);
863863
spin_unlock(&vfsmount_lock);
864864
}
865-
up_write(&current->namespace->sem);
865+
up_write(&namespace_sem);
866866
return 0;
867867

868868
unlock:
869-
up_write(&current->namespace->sem);
869+
up_write(&namespace_sem);
870870
mntput(newmnt);
871871
return err;
872872
}
@@ -958,9 +958,9 @@ void mark_mounts_for_expiry(struct list_head *mounts)
958958
get_namespace(namespace);
959959

960960
spin_unlock(&vfsmount_lock);
961-
down_write(&namespace->sem);
961+
down_write(&namespace_sem);
962962
expire_mount(mnt, mounts, &umounts);
963-
up_write(&namespace->sem);
963+
up_write(&namespace_sem);
964964
release_mounts(&umounts);
965965
mntput(mnt);
966966
put_namespace(namespace);
@@ -1127,17 +1127,16 @@ int copy_namespace(int flags, struct task_struct *tsk)
11271127
goto out;
11281128

11291129
atomic_set(&new_ns->count, 1);
1130-
init_rwsem(&new_ns->sem);
11311130
INIT_LIST_HEAD(&new_ns->list);
11321131
init_waitqueue_head(&new_ns->poll);
11331132
new_ns->event = 0;
11341133

1135-
down_write(&tsk->namespace->sem);
1134+
down_write(&namespace_sem);
11361135
/* First pass: copy the tree topology */
11371136
new_ns->root = copy_tree(namespace->root, namespace->root->mnt_root,
11381137
CL_EXPIRE);
11391138
if (!new_ns->root) {
1140-
up_write(&tsk->namespace->sem);
1139+
up_write(&namespace_sem);
11411140
kfree(new_ns);
11421141
goto out;
11431142
}
@@ -1171,7 +1170,7 @@ int copy_namespace(int flags, struct task_struct *tsk)
11711170
p = next_mnt(p, namespace->root);
11721171
q = next_mnt(q, new_ns->root);
11731172
}
1174-
up_write(&tsk->namespace->sem);
1173+
up_write(&namespace_sem);
11751174

11761175
tsk->namespace = new_ns;
11771176

@@ -1356,7 +1355,7 @@ asmlinkage long sys_pivot_root(const char __user * new_root,
13561355
user_nd.mnt = mntget(current->fs->rootmnt);
13571356
user_nd.dentry = dget(current->fs->root);
13581357
read_unlock(&current->fs->lock);
1359-
down_write(&current->namespace->sem);
1358+
down_write(&namespace_sem);
13601359
down(&old_nd.dentry->d_inode->i_sem);
13611360
error = -EINVAL;
13621361
if (!check_mnt(user_nd.mnt))
@@ -1407,7 +1406,7 @@ asmlinkage long sys_pivot_root(const char __user * new_root,
14071406
path_release(&parent_nd);
14081407
out2:
14091408
up(&old_nd.dentry->d_inode->i_sem);
1410-
up_write(&current->namespace->sem);
1409+
up_write(&namespace_sem);
14111410
path_release(&user_nd);
14121411
path_release(&old_nd);
14131412
out1:
@@ -1434,7 +1433,6 @@ static void __init init_mount_tree(void)
14341433
panic("Can't allocate initial namespace");
14351434
atomic_set(&namespace->count, 1);
14361435
INIT_LIST_HEAD(&namespace->list);
1437-
init_rwsem(&namespace->sem);
14381436
init_waitqueue_head(&namespace->poll);
14391437
namespace->event = 0;
14401438
list_add(&mnt->mnt_list, &namespace->list);
@@ -1459,6 +1457,8 @@ void __init mnt_init(unsigned long mempages)
14591457
unsigned int nr_hash;
14601458
int i;
14611459

1460+
init_rwsem(&namespace_sem);
1461+
14621462
mnt_cache = kmem_cache_create("mnt_cache", sizeof(struct vfsmount),
14631463
0, SLAB_HWCACHE_ALIGN | SLAB_PANIC, NULL, NULL);
14641464

@@ -1507,11 +1507,11 @@ void __put_namespace(struct namespace *namespace)
15071507
LIST_HEAD(umount_list);
15081508
namespace->root = NULL;
15091509
spin_unlock(&vfsmount_lock);
1510-
down_write(&namespace->sem);
1510+
down_write(&namespace_sem);
15111511
spin_lock(&vfsmount_lock);
15121512
umount_tree(root, &umount_list);
15131513
spin_unlock(&vfsmount_lock);
1514-
up_write(&namespace->sem);
1514+
up_write(&namespace_sem);
15151515
release_mounts(&umount_list);
15161516
kfree(namespace);
15171517
}

include/linux/namespace.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ struct namespace {
99
atomic_t count;
1010
struct vfsmount * root;
1111
struct list_head list;
12-
struct rw_semaphore sem;
1312
wait_queue_head_t poll;
1413
int event;
1514
};

0 commit comments

Comments
 (0)