From mboxrd@z Thu Jan 1 00:00:00 1970 From: Mike Waychison Subject: Re: [RFC][PATCH 1/8] namespace: use global namespace semaphore Date: Mon, 30 May 2005 23:23:35 -0400 Message-ID: <429BD8B7.7070906@waychison.com> References: Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Cc: Miklos Szeredi , linux-fsdevel@vger.kernel.org, jamie@shareable.org, viro@parcelfarce.linux.theplanet.co.uk Return-path: Received: from dsl081-242-086.sfo1.dsl.speakeasy.net ([64.81.242.86]:19691 "EHLO lapdance.christiehouse.net") by vger.kernel.org with ESMTP id S261708AbVEaD0P (ORCPT ); Mon, 30 May 2005 23:26:15 -0400 To: Ian Kent In-Reply-To: Sender: linux-fsdevel-owner@vger.kernel.org List-Id: linux-fsdevel.vger.kernel.org -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Ian Kent wrote: > On Mon, 30 May 2005, Miklos Szeredi wrote: > > >>This patch removes the per-namespace semaphore in favor of a global >>semaphore. This can have an effect on scalability, however it is >>necessary for the following patches. >> >>A similar scheme can be added later if needed. > > > Which, together with patch 3, effectively removes the ability for code in > a module to safely find out about vfsmounts in its namespace. > > Given the assumption in link_path_walk, that a vfsmount will not be > followed prior to a call to follow_link this stops me from doing > autofs direct mount via this method. > > Any ideas on how I might cope with this? No, the removal of struct namespace shouldn't keep you from walking vfsmounts from modules. In fact, in Miklos' 1/8 patch, he moved namespace->sem to a global semaphore, which isn't needed by the end of the patch set. namespace->sem only ever protected the namespace->list field. If you which to walk a mounttree, you still only ever require grabbing vfsmount_lock and use mntget/mntput. Overall, this means autofs4 stuff will need to be updated to reflect these changes, but they are minimal at best. > > >>Signed-off-by: Miklos Szeredi >> >>Index: linux/include/linux/namespace.h >>=================================================================== >>--- linux.orig/include/linux/namespace.h 2005-05-29 13:34:30.000000000 +0200 >>+++ linux/include/linux/namespace.h 2005-05-29 13:46:23.000000000 +0200 >>@@ -9,7 +9,6 @@ struct namespace { >> atomic_t count; >> struct vfsmount * root; >> struct list_head list; >>- struct rw_semaphore sem; >> }; >> >> extern int copy_namespace(int, struct task_struct *); >>Index: linux/fs/namespace.c >>=================================================================== >>--- linux.orig/fs/namespace.c 2005-05-29 13:42:33.000000000 +0200 >>+++ linux/fs/namespace.c 2005-05-29 14:06:50.000000000 +0200 >>@@ -42,6 +42,7 @@ static inline int sysfs_init(void) >> static struct list_head *mount_hashtable; >> static int hash_mask, hash_bits; >> static kmem_cache_t *mnt_cache; >>+static struct rw_semaphore namespace_sem; >> >> static inline unsigned long hash(struct vfsmount *mnt, struct dentry *dentry) >> { >>@@ -189,7 +190,7 @@ static void *m_start(struct seq_file *m, >> struct list_head *p; >> loff_t l = *pos; >> >>- down_read(&n->sem); >>+ down_read(&namespace_sem); >> list_for_each(p, &n->list) >> if (!l--) >> return list_entry(p, struct vfsmount, mnt_list); >>@@ -206,8 +207,7 @@ static void *m_next(struct seq_file *m, >> >> static void m_stop(struct seq_file *m, void *v) >> { >>- struct namespace *n = m->private; >>- up_read(&n->sem); >>+ up_read(&namespace_sem); >> } >> >> static inline void mangle(struct seq_file *m, const char *s) >>@@ -432,7 +432,7 @@ static int do_umount(struct vfsmount *mn >> return retval; >> } >> >>- down_write(¤t->namespace->sem); >>+ down_write(&namespace_sem); >> spin_lock(&vfsmount_lock); >> >> if (atomic_read(&sb->s_active) == 1) { >>@@ -454,7 +454,7 @@ static int do_umount(struct vfsmount *mn >> spin_unlock(&vfsmount_lock); >> if (retval) >> security_sb_umount_busy(mnt); >>- up_write(¤t->namespace->sem); >>+ up_write(&namespace_sem); >> return retval; >> } >> >>@@ -632,7 +632,7 @@ static int do_loopback(struct nameidata >> if (err) >> return err; >> >>- down_write(¤t->namespace->sem); >>+ down_write(&namespace_sem); >> err = -EINVAL; >> if (check_mnt(nd->mnt) && (!recurse || check_mnt(old_nd.mnt))) { >> err = -ENOMEM; >>@@ -657,7 +657,7 @@ static int do_loopback(struct nameidata >> mntput(mnt); >> } >> >>- up_write(¤t->namespace->sem); >>+ up_write(&namespace_sem); >> path_release(&old_nd); >> return err; >> } >>@@ -706,7 +706,7 @@ static int do_move_mount(struct nameidat >> if (err) >> return err; >> >>- down_write(¤t->namespace->sem); >>+ down_write(&namespace_sem); >> while(d_mountpoint(nd->dentry) && follow_down(&nd->mnt, &nd->dentry)) >> ; >> err = -EINVAL; >>@@ -750,7 +750,7 @@ out2: >> out1: >> up(&nd->dentry->d_inode->i_sem); >> out: >>- up_write(¤t->namespace->sem); >>+ up_write(&namespace_sem); >> if (!err) >> path_release(&parent_nd); >> path_release(&old_nd); >>@@ -789,7 +789,7 @@ int do_add_mount(struct vfsmount *newmnt >> { >> int err; >> >>- down_write(¤t->namespace->sem); >>+ down_write(&namespace_sem); >> /* Something was mounted here while we slept */ >> while(d_mountpoint(nd->dentry) && follow_down(&nd->mnt, &nd->dentry)) >> ; >>@@ -819,7 +819,7 @@ int do_add_mount(struct vfsmount *newmnt >> } >> >> unlock: >>- up_write(¤t->namespace->sem); >>+ up_write(&namespace_sem); >> mntput(newmnt); >> return err; >> } >>@@ -875,7 +875,6 @@ static void expire_mount(struct vfsmount >> */ >> void mark_mounts_for_expiry(struct list_head *mounts) >> { >>- struct namespace *namespace; >> struct vfsmount *mnt, *next; >> LIST_HEAD(graveyard); >> >>@@ -909,20 +908,12 @@ void mark_mounts_for_expiry(struct list_ >> mnt = list_entry(graveyard.next, struct vfsmount, mnt_expire); >> list_del_init(&mnt->mnt_expire); >> >>- /* don't do anything if the namespace is dead - all the >>- * vfsmounts from it are going away anyway */ >>- namespace = mnt->mnt_namespace; >>- if (!namespace || !namespace->root) >>- continue; >>- get_namespace(namespace); >>- >> spin_unlock(&vfsmount_lock); >>- down_write(&namespace->sem); >>+ down_write(&namespace_sem); >> expire_mount(mnt, mounts); >>- up_write(&namespace->sem); >>+ up_write(&namespace_sem); >> >> mntput(mnt); >>- put_namespace(namespace); >> >> spin_lock(&vfsmount_lock); >> } >>@@ -1087,14 +1078,13 @@ int copy_namespace(int flags, struct tas >> goto out; >> >> atomic_set(&new_ns->count, 1); >>- init_rwsem(&new_ns->sem); >> INIT_LIST_HEAD(&new_ns->list); >> >>- down_write(&tsk->namespace->sem); >>+ down_write(&namespace_sem); >> /* First pass: copy the tree topology */ >> new_ns->root = copy_tree(namespace->root, namespace->root->mnt_root); >> if (!new_ns->root) { >>- up_write(&tsk->namespace->sem); >>+ up_write(&namespace_sem); >> kfree(new_ns); >> goto out; >> } >>@@ -1128,7 +1118,7 @@ int copy_namespace(int flags, struct tas >> p = next_mnt(p, namespace->root); >> q = next_mnt(q, new_ns->root); >> } >>- up_write(&tsk->namespace->sem); >>+ up_write(&namespace_sem); >> >> tsk->namespace = new_ns; >> >>@@ -1310,7 +1300,7 @@ asmlinkage long sys_pivot_root(const cha >> user_nd.mnt = mntget(current->fs->rootmnt); >> user_nd.dentry = dget(current->fs->root); >> read_unlock(¤t->fs->lock); >>- down_write(¤t->namespace->sem); >>+ down_write(&namespace_sem); >> down(&old_nd.dentry->d_inode->i_sem); >> error = -EINVAL; >> if (!check_mnt(user_nd.mnt)) >>@@ -1356,7 +1346,7 @@ asmlinkage long sys_pivot_root(const cha >> path_release(&parent_nd); >> out2: >> up(&old_nd.dentry->d_inode->i_sem); >>- up_write(¤t->namespace->sem); >>+ up_write(&namespace_sem); >> path_release(&user_nd); >> path_release(&old_nd); >> out1: >>@@ -1383,7 +1373,6 @@ static void __init init_mount_tree(void) >> panic("Can't allocate initial namespace"); >> atomic_set(&namespace->count, 1); >> INIT_LIST_HEAD(&namespace->list); >>- init_rwsem(&namespace->sem); >> list_add(&mnt->mnt_list, &namespace->list); >> namespace->root = mnt; >> mnt->mnt_namespace = namespace; >>@@ -1406,6 +1395,8 @@ void __init mnt_init(unsigned long mempa >> unsigned int nr_hash; >> int i; >> >>+ init_rwsem(&namespace_sem); >>+ >> mnt_cache = kmem_cache_create("mnt_cache", sizeof(struct vfsmount), >> 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL); >> >>@@ -1454,10 +1445,10 @@ void __put_namespace(struct namespace *n >> struct vfsmount *root = namespace->root; >> namespace->root = NULL; >> spin_unlock(&vfsmount_lock); >>- down_write(&namespace->sem); >>+ down_write(&namespace_sem); >> spin_lock(&vfsmount_lock); >> umount_tree(root); >> spin_unlock(&vfsmount_lock); >>- up_write(&namespace->sem); >>+ up_write(&namespace_sem); >> kfree(namespace); >> } >>- >>To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in >>the body of a message to majordomo@vger.kernel.org >>More majordomo info at http://vger.kernel.org/majordomo-info.html >> > > -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.0 (GNU/Linux) Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org iD8DBQFCm9i3dQs4kOxk3/MRAlESAJ9rItxr1YbOfOJCWvArhlSmlNUM0QCfezPN GyXzPaNSzLAUx/sInVOhRkU= =v1Ix -----END PGP SIGNATURE-----