aboutsummaryrefslogtreecommitdiffstats
path: root/fs/namespace.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/namespace.c')
-rw-r--r--fs/namespace.c41
1 files changed, 22 insertions, 19 deletions
diff --git a/fs/namespace.c b/fs/namespace.c
index 1d83302f30c3..611f777bbd61 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)
661 661
662 down_write(&current->namespace->sem); 662 down_write(&current->namespace->sem);
663 err = -EINVAL; 663 err = -EINVAL;
664 if (check_mnt(nd->mnt) && (!recurse || check_mnt(old_nd.mnt))) { 664 if (!check_mnt(nd->mnt) || !check_mnt(old_nd.mnt))
665 err = -ENOMEM; 665 goto out;
666 if (recurse)
667 mnt = copy_tree(old_nd.mnt, old_nd.dentry);
668 else
669 mnt = clone_mnt(old_nd.mnt, old_nd.dentry);
670 }
671 666
672 if (mnt) { 667 err = -ENOMEM;
673 /* stop bind mounts from expiring */ 668 if (recurse)
669 mnt = copy_tree(old_nd.mnt, old_nd.dentry);
670 else
671 mnt = clone_mnt(old_nd.mnt, old_nd.dentry);
672
673 if (!mnt)
674 goto out;
675
676 /* stop bind mounts from expiring */
677 spin_lock(&vfsmount_lock);
678 list_del_init(&mnt->mnt_expire);
679 spin_unlock(&vfsmount_lock);
680
681 err = graft_tree(mnt, nd);
682 if (err) {
674 spin_lock(&vfsmount_lock); 683 spin_lock(&vfsmount_lock);
675 list_del_init(&mnt->mnt_expire); 684 umount_tree(mnt);
676 spin_unlock(&vfsmount_lock); 685 spin_unlock(&vfsmount_lock);
686 } else
687 mntput(mnt);
677 688
678 err = graft_tree(mnt, nd); 689out:
679 if (err) {
680 spin_lock(&vfsmount_lock);
681 umount_tree(mnt);
682 spin_unlock(&vfsmount_lock);
683 } else
684 mntput(mnt);
685 }
686
687 up_write(&current->namespace->sem); 690 up_write(&current->namespace->sem);
688 path_release(&old_nd); 691 path_release(&old_nd);
689 return err; 692 return err;