diff options
| author | Al Viro <viro@zeniv.linux.org.uk> | 2005-11-07 17:15:04 -0500 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-11-07 18:18:09 -0800 | 
| commit | ccd48bc7fac284caf704dcdcafd223a24f70bccf (patch) | |
| tree | 83b0b6643cb7ea302391e99ec57e07503a292646 | |
| parent | 7b7b1ace2d9d06d76bce7481a045c22ed75e35dd (diff) | |
[PATCH] cleanups and bug fix in do_loopback()
 - check_mnt() on the source of binding should've been unconditional
   from the very beginning.  My fault - as far I could've trace it,
   that's an old thinko made back in 2001.  Kudos to Miklos for spotting
   it...
   Fixed.
 - code cleaned up.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
| -rw-r--r-- | fs/namespace.c | 41 | 
1 files changed, 22 insertions, 19 deletions
| diff --git a/fs/namespace.c b/fs/namespace.c index 1d83302f30c..611f777bbd6 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -661,29 +661,32 @@ static int do_loopback(struct nameidata *nd, char *old_name, int recurse)  	down_write(¤t->namespace->sem);  	err = -EINVAL; -	if (check_mnt(nd->mnt) && (!recurse || check_mnt(old_nd.mnt))) { -		err = -ENOMEM; -		if (recurse) -			mnt = copy_tree(old_nd.mnt, old_nd.dentry); -		else -			mnt = clone_mnt(old_nd.mnt, old_nd.dentry); -	} +	if (!check_mnt(nd->mnt) || !check_mnt(old_nd.mnt)) +		goto out; -	if (mnt) { -		/* stop bind mounts from expiring */ +	err = -ENOMEM; +	if (recurse) +		mnt = copy_tree(old_nd.mnt, old_nd.dentry); +	else +		mnt = clone_mnt(old_nd.mnt, old_nd.dentry); + +	if (!mnt) +		goto out; + +	/* stop bind mounts from expiring */ +	spin_lock(&vfsmount_lock); +	list_del_init(&mnt->mnt_expire); +	spin_unlock(&vfsmount_lock); + +	err = graft_tree(mnt, nd); +	if (err) {  		spin_lock(&vfsmount_lock); -		list_del_init(&mnt->mnt_expire); +		umount_tree(mnt);  		spin_unlock(&vfsmount_lock); +	} else +		mntput(mnt); -		err = graft_tree(mnt, nd); -		if (err) { -			spin_lock(&vfsmount_lock); -			umount_tree(mnt); -			spin_unlock(&vfsmount_lock); -		} else -			mntput(mnt); -	} - +out:  	up_write(¤t->namespace->sem);  	path_release(&old_nd);  	return err; | 
