4.0-stable review patch.  If anyone has any objections, please let me know.

------------------

From: "Eric W. Biederman" <[email protected]>

commit 5d88457eb5b86b475422dc882f089203faaeedb5 upstream.

A prerequisite of calling umount_tree is that the point where the tree
is mounted at is valid to unmount.

If we are propagating the effect of the unmount clear MNT_LOCKED in
every instance where the same filesystem is mounted on the same
mountpoint in the mount tree, as we know (by virtue of the fact
that umount_tree was called) that it is safe to reveal what
is at that mountpoint.

Signed-off-by: "Eric W. Biederman" <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
 fs/namespace.c |    3 +++
 fs/pnode.c     |   20 ++++++++++++++++++++
 fs/pnode.h     |    1 +
 3 files changed, 24 insertions(+)

--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -1335,6 +1335,9 @@ static void umount_tree(struct mount *mn
        LIST_HEAD(tmp_list);
        struct mount *p;
 
+       if (how & UMOUNT_PROPAGATE)
+               propagate_mount_unlock(mnt);
+
        /* Gather the mounts to umount */
        for (p = mnt; p; p = next_mnt(p, mnt)) {
                p->mnt.mnt_flags |= MNT_UMOUNT;
--- a/fs/pnode.c
+++ b/fs/pnode.c
@@ -362,6 +362,26 @@ int propagate_mount_busy(struct mount *m
 }
 
 /*
+ * Clear MNT_LOCKED when it can be shown to be safe.
+ *
+ * mount_lock lock must be held for write
+ */
+void propagate_mount_unlock(struct mount *mnt)
+{
+       struct mount *parent = mnt->mnt_parent;
+       struct mount *m, *child;
+
+       BUG_ON(parent == mnt);
+
+       for (m = propagation_next(parent, parent); m;
+                       m = propagation_next(m, parent)) {
+               child = __lookup_mnt_last(&m->mnt, mnt->mnt_mountpoint);
+               if (child)
+                       child->mnt.mnt_flags &= ~MNT_LOCKED;
+       }
+}
+
+/*
  * NOTE: unmounting 'mnt' naturally propagates to all other mounts its
  * parent propagates to.
  */
--- a/fs/pnode.h
+++ b/fs/pnode.h
@@ -42,6 +42,7 @@ int propagate_mnt(struct mount *, struct
                struct hlist_head *);
 int propagate_umount(struct list_head *);
 int propagate_mount_busy(struct mount *, int);
+void propagate_mount_unlock(struct mount *);
 void mnt_release_group_id(struct mount *);
 int get_dominating_id(struct mount *mnt, const struct path *root);
 unsigned int mnt_get_count(struct mount *mnt);


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to