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 | |
| 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 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; |
