mnt: Update detach_mounts to leave mounts connected
authorEric W. Biederman <ebiederm@xmission.com>
Wed, 1 Apr 2015 23:30:06 +0000 (18:30 -0500)
committerEric W. Biederman <ebiederm@xmission.com>
Thu, 9 Apr 2015 16:39:57 +0000 (11:39 -0500)
Now that it is possible to lazily unmount an entire mount tree and
leave the individual mounts connected to each other add a new flag
UMOUNT_CONNECTED to umount_tree to force this behavior and use
this flag in detach_mounts.

This closes a bug where the deletion of a file or directory could
trigger an unmount and reveal data under a mount point.

Cc: stable@vger.kernel.org
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
fs/namespace.c

index e8f7f8c58c3c64cacb39629db55262c922797a16..1f4f9dac6e5af8017e41ab497b92e0515e5ed71c 100644 (file)
@@ -1348,6 +1348,7 @@ static inline void namespace_lock(void)
 enum umount_tree_flags {
        UMOUNT_SYNC = 1,
        UMOUNT_PROPAGATE = 2,
+       UMOUNT_CONNECTED = 4,
 };
 /*
  * mount_lock must be held
@@ -1386,7 +1387,10 @@ static void umount_tree(struct mount *mnt, enum umount_tree_flags how)
                if (how & UMOUNT_SYNC)
                        p->mnt.mnt_flags |= MNT_SYNC_UMOUNT;
 
-               disconnect = !IS_MNT_LOCKED_AND_LAZY(p);
+               disconnect = !(((how & UMOUNT_CONNECTED) &&
+                               mnt_has_parent(p) &&
+                               (p->mnt_parent->mnt.mnt_flags & MNT_UMOUNT)) ||
+                              IS_MNT_LOCKED_AND_LAZY(p));
 
                pin_insert_group(&p->mnt_umount, &p->mnt_parent->mnt,
                                 disconnect ? &unmounted : NULL);
@@ -1529,7 +1533,7 @@ void __detach_mounts(struct dentry *dentry)
                                umount_mnt(p);
                        }
                }
-               else umount_tree(mnt, 0);
+               else umount_tree(mnt, UMOUNT_CONNECTED);
        }
        unlock_mount_hash();
        put_mountpoint(mp);