Commit ccd48bc7 authored by Al Viro's avatar Al Viro Committed by Linus Torvalds

[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: default avatarAl Viro <viro@zeniv.linux.org.uk>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 7b7b1ace
......@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment