[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>
This commit is contained in:
Al Viro 2005-11-07 17:15:04 -05:00 committed by Linus Torvalds
parent 7b7b1ace2d
commit ccd48bc7fa

View file

@ -661,29 +661,32 @@ static int do_loopback(struct nameidata *nd, char *old_name, int recurse)
down_write(&current->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(&current->namespace->sem);
path_release(&old_nd);
return err;