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 21:18:09 -0500 |
commit | ccd48bc7fac284caf704dcdcafd223a24f70bccf (patch) | |
tree | 83b0b6643cb7ea302391e99ec57e07503a292646 /fs/namespace.c | |
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>
Diffstat (limited to 'fs/namespace.c')
-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 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(¤t->namespace->sem); | 662 | down_write(¤t->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); | 689 | out: |
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(¤t->namespace->sem); | 690 | up_write(¤t->namespace->sem); |
688 | path_release(&old_nd); | 691 | path_release(&old_nd); |
689 | return err; | 692 | return err; |