aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRam Pai <linuxram@us.ibm.com>2005-11-07 17:17:51 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2005-11-07 21:18:10 -0500
commit390c684367de37e1c2f9005cf92f7a746c69fdd3 (patch)
tree23cf8783db5fdec3717c79f989c6872955679036
parent36341f64569b0c4572478237ec5ed318f0762510 (diff)
[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>
-rw-r--r--fs/namespace.c46
-rw-r--r--include/linux/namespace.h1
2 files changed, 23 insertions, 24 deletions
diff --git a/fs/namespace.c b/fs/namespace.c
index 65f9c0ecc21c..4abee9ab009f 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -46,6 +46,7 @@ static int event;
46static struct list_head *mount_hashtable; 46static struct list_head *mount_hashtable;
47static int hash_mask __read_mostly, hash_bits __read_mostly; 47static int hash_mask __read_mostly, hash_bits __read_mostly;
48static kmem_cache_t *mnt_cache; 48static kmem_cache_t *mnt_cache;
49static struct rw_semaphore namespace_sem;
49 50
50static inline unsigned long hash(struct vfsmount *mnt, struct dentry *dentry) 51static inline unsigned long hash(struct vfsmount *mnt, struct dentry *dentry)
51{ 52{
@@ -250,7 +251,7 @@ static void *m_start(struct seq_file *m, loff_t *pos)
250 struct list_head *p; 251 struct list_head *p;
251 loff_t l = *pos; 252 loff_t l = *pos;
252 253
253 down_read(&n->sem); 254 down_read(&namespace_sem);
254 list_for_each(p, &n->list) 255 list_for_each(p, &n->list)
255 if (!l--) 256 if (!l--)
256 return list_entry(p, struct vfsmount, mnt_list); 257 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)
267 268
268static void m_stop(struct seq_file *m, void *v) 269static void m_stop(struct seq_file *m, void *v)
269{ 270{
270 struct namespace *n = m->private; 271 up_read(&namespace_sem);
271 up_read(&n->sem);
272} 272}
273 273
274static inline void mangle(struct seq_file *m, const char *s) 274static inline void mangle(struct seq_file *m, const char *s)
@@ -487,7 +487,7 @@ static int do_umount(struct vfsmount *mnt, int flags)
487 return retval; 487 return retval;
488 } 488 }
489 489
490 down_write(&current->namespace->sem); 490 down_write(&namespace_sem);
491 spin_lock(&vfsmount_lock); 491 spin_lock(&vfsmount_lock);
492 event++; 492 event++;
493 493
@@ -500,7 +500,7 @@ static int do_umount(struct vfsmount *mnt, int flags)
500 spin_unlock(&vfsmount_lock); 500 spin_unlock(&vfsmount_lock);
501 if (retval) 501 if (retval)
502 security_sb_umount_busy(mnt); 502 security_sb_umount_busy(mnt);
503 up_write(&current->namespace->sem); 503 up_write(&namespace_sem);
504 release_mounts(&umount_list); 504 release_mounts(&umount_list);
505 return retval; 505 return retval;
506} 506}
@@ -678,7 +678,7 @@ static int do_loopback(struct nameidata *nd, char *old_name, int recurse)
678 if (err) 678 if (err)
679 return err; 679 return err;
680 680
681 down_write(&current->namespace->sem); 681 down_write(&namespace_sem);
682 err = -EINVAL; 682 err = -EINVAL;
683 if (!check_mnt(nd->mnt) || !check_mnt(old_nd.mnt)) 683 if (!check_mnt(nd->mnt) || !check_mnt(old_nd.mnt))
684 goto out; 684 goto out;
@@ -702,7 +702,7 @@ static int do_loopback(struct nameidata *nd, char *old_name, int recurse)
702 } 702 }
703 703
704out: 704out:
705 up_write(&current->namespace->sem); 705 up_write(&namespace_sem);
706 path_release(&old_nd); 706 path_release(&old_nd);
707 return err; 707 return err;
708} 708}
@@ -750,7 +750,7 @@ static int do_move_mount(struct nameidata *nd, char *old_name)
750 if (err) 750 if (err)
751 return err; 751 return err;
752 752
753 down_write(&current->namespace->sem); 753 down_write(&namespace_sem);
754 while (d_mountpoint(nd->dentry) && follow_down(&nd->mnt, &nd->dentry)) 754 while (d_mountpoint(nd->dentry) && follow_down(&nd->mnt, &nd->dentry))
755 ; 755 ;
756 err = -EINVAL; 756 err = -EINVAL;
@@ -795,7 +795,7 @@ out2:
795out1: 795out1:
796 up(&nd->dentry->d_inode->i_sem); 796 up(&nd->dentry->d_inode->i_sem);
797out: 797out:
798 up_write(&current->namespace->sem); 798 up_write(&namespace_sem);
799 if (!err) 799 if (!err)
800 path_release(&parent_nd); 800 path_release(&parent_nd);
801 path_release(&old_nd); 801 path_release(&old_nd);
@@ -834,7 +834,7 @@ int do_add_mount(struct vfsmount *newmnt, struct nameidata *nd,
834{ 834{
835 int err; 835 int err;
836 836
837 down_write(&current->namespace->sem); 837 down_write(&namespace_sem);
838 /* Something was mounted here while we slept */ 838 /* Something was mounted here while we slept */
839 while (d_mountpoint(nd->dentry) && follow_down(&nd->mnt, &nd->dentry)) 839 while (d_mountpoint(nd->dentry) && follow_down(&nd->mnt, &nd->dentry))
840 ; 840 ;
@@ -862,11 +862,11 @@ int do_add_mount(struct vfsmount *newmnt, struct nameidata *nd,
862 list_add_tail(&newmnt->mnt_expire, fslist); 862 list_add_tail(&newmnt->mnt_expire, fslist);
863 spin_unlock(&vfsmount_lock); 863 spin_unlock(&vfsmount_lock);
864 } 864 }
865 up_write(&current->namespace->sem); 865 up_write(&namespace_sem);
866 return 0; 866 return 0;
867 867
868unlock: 868unlock:
869 up_write(&current->namespace->sem); 869 up_write(&namespace_sem);
870 mntput(newmnt); 870 mntput(newmnt);
871 return err; 871 return err;
872} 872}
@@ -958,9 +958,9 @@ void mark_mounts_for_expiry(struct list_head *mounts)
958 get_namespace(namespace); 958 get_namespace(namespace);
959 959
960 spin_unlock(&vfsmount_lock); 960 spin_unlock(&vfsmount_lock);
961 down_write(&namespace->sem); 961 down_write(&namespace_sem);
962 expire_mount(mnt, mounts, &umounts); 962 expire_mount(mnt, mounts, &umounts);
963 up_write(&namespace->sem); 963 up_write(&namespace_sem);
964 release_mounts(&umounts); 964 release_mounts(&umounts);
965 mntput(mnt); 965 mntput(mnt);
966 put_namespace(namespace); 966 put_namespace(namespace);
@@ -1127,17 +1127,16 @@ int copy_namespace(int flags, struct task_struct *tsk)
1127 goto out; 1127 goto out;
1128 1128
1129 atomic_set(&new_ns->count, 1); 1129 atomic_set(&new_ns->count, 1);
1130 init_rwsem(&new_ns->sem);
1131 INIT_LIST_HEAD(&new_ns->list); 1130 INIT_LIST_HEAD(&new_ns->list);
1132 init_waitqueue_head(&new_ns->poll); 1131 init_waitqueue_head(&new_ns->poll);
1133 new_ns->event = 0; 1132 new_ns->event = 0;
1134 1133
1135 down_write(&tsk->namespace->sem); 1134 down_write(&namespace_sem);
1136 /* First pass: copy the tree topology */ 1135 /* First pass: copy the tree topology */
1137 new_ns->root = copy_tree(namespace->root, namespace->root->mnt_root, 1136 new_ns->root = copy_tree(namespace->root, namespace->root->mnt_root,
1138 CL_EXPIRE); 1137 CL_EXPIRE);
1139 if (!new_ns->root) { 1138 if (!new_ns->root) {
1140 up_write(&tsk->namespace->sem); 1139 up_write(&namespace_sem);
1141 kfree(new_ns); 1140 kfree(new_ns);
1142 goto out; 1141 goto out;
1143 } 1142 }
@@ -1171,7 +1170,7 @@ int copy_namespace(int flags, struct task_struct *tsk)
1171 p = next_mnt(p, namespace->root); 1170 p = next_mnt(p, namespace->root);
1172 q = next_mnt(q, new_ns->root); 1171 q = next_mnt(q, new_ns->root);
1173 } 1172 }
1174 up_write(&tsk->namespace->sem); 1173 up_write(&namespace_sem);
1175 1174
1176 tsk->namespace = new_ns; 1175 tsk->namespace = new_ns;
1177 1176
@@ -1356,7 +1355,7 @@ asmlinkage long sys_pivot_root(const char __user * new_root,
1356 user_nd.mnt = mntget(current->fs->rootmnt); 1355 user_nd.mnt = mntget(current->fs->rootmnt);
1357 user_nd.dentry = dget(current->fs->root); 1356 user_nd.dentry = dget(current->fs->root);
1358 read_unlock(&current->fs->lock); 1357 read_unlock(&current->fs->lock);
1359 down_write(&current->namespace->sem); 1358 down_write(&namespace_sem);
1360 down(&old_nd.dentry->d_inode->i_sem); 1359 down(&old_nd.dentry->d_inode->i_sem);
1361 error = -EINVAL; 1360 error = -EINVAL;
1362 if (!check_mnt(user_nd.mnt)) 1361 if (!check_mnt(user_nd.mnt))
@@ -1407,7 +1406,7 @@ asmlinkage long sys_pivot_root(const char __user * new_root,
1407 path_release(&parent_nd); 1406 path_release(&parent_nd);
1408out2: 1407out2:
1409 up(&old_nd.dentry->d_inode->i_sem); 1408 up(&old_nd.dentry->d_inode->i_sem);
1410 up_write(&current->namespace->sem); 1409 up_write(&namespace_sem);
1411 path_release(&user_nd); 1410 path_release(&user_nd);
1412 path_release(&old_nd); 1411 path_release(&old_nd);
1413out1: 1412out1:
@@ -1434,7 +1433,6 @@ static void __init init_mount_tree(void)
1434 panic("Can't allocate initial namespace"); 1433 panic("Can't allocate initial namespace");
1435 atomic_set(&namespace->count, 1); 1434 atomic_set(&namespace->count, 1);
1436 INIT_LIST_HEAD(&namespace->list); 1435 INIT_LIST_HEAD(&namespace->list);
1437 init_rwsem(&namespace->sem);
1438 init_waitqueue_head(&namespace->poll); 1436 init_waitqueue_head(&namespace->poll);
1439 namespace->event = 0; 1437 namespace->event = 0;
1440 list_add(&mnt->mnt_list, &namespace->list); 1438 list_add(&mnt->mnt_list, &namespace->list);
@@ -1459,6 +1457,8 @@ void __init mnt_init(unsigned long mempages)
1459 unsigned int nr_hash; 1457 unsigned int nr_hash;
1460 int i; 1458 int i;
1461 1459
1460 init_rwsem(&namespace_sem);
1461
1462 mnt_cache = kmem_cache_create("mnt_cache", sizeof(struct vfsmount), 1462 mnt_cache = kmem_cache_create("mnt_cache", sizeof(struct vfsmount),
1463 0, SLAB_HWCACHE_ALIGN | SLAB_PANIC, NULL, NULL); 1463 0, SLAB_HWCACHE_ALIGN | SLAB_PANIC, NULL, NULL);
1464 1464
@@ -1507,11 +1507,11 @@ void __put_namespace(struct namespace *namespace)
1507 LIST_HEAD(umount_list); 1507 LIST_HEAD(umount_list);
1508 namespace->root = NULL; 1508 namespace->root = NULL;
1509 spin_unlock(&vfsmount_lock); 1509 spin_unlock(&vfsmount_lock);
1510 down_write(&namespace->sem); 1510 down_write(&namespace_sem);
1511 spin_lock(&vfsmount_lock); 1511 spin_lock(&vfsmount_lock);
1512 umount_tree(root, &umount_list); 1512 umount_tree(root, &umount_list);
1513 spin_unlock(&vfsmount_lock); 1513 spin_unlock(&vfsmount_lock);
1514 up_write(&namespace->sem); 1514 up_write(&namespace_sem);
1515 release_mounts(&umount_list); 1515 release_mounts(&umount_list);
1516 kfree(namespace); 1516 kfree(namespace);
1517} 1517}
diff --git a/include/linux/namespace.h b/include/linux/namespace.h
index 6f0f25d64c38..6731977c4c13 100644
--- a/include/linux/namespace.h
+++ b/include/linux/namespace.h
@@ -9,7 +9,6 @@ struct namespace {
9 atomic_t count; 9 atomic_t count;
10 struct vfsmount * root; 10 struct vfsmount * root;
11 struct list_head list; 11 struct list_head list;
12 struct rw_semaphore sem;
13 wait_queue_head_t poll; 12 wait_queue_head_t poll;
14 int event; 13 int event;
15}; 14};