]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.19-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 2 May 2015 15:56:01 +0000 (17:56 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 2 May 2015 15:56:01 +0000 (17:56 +0200)
added patches:
mnt-don-t-propagate-umounts-in-__detach_mounts.patch
mnt-improve-the-umount_tree-flags.patch

queue-3.19/mnt-don-t-propagate-umounts-in-__detach_mounts.patch [new file with mode: 0644]
queue-3.19/mnt-improve-the-umount_tree-flags.patch [new file with mode: 0644]
queue-3.19/series

diff --git a/queue-3.19/mnt-don-t-propagate-umounts-in-__detach_mounts.patch b/queue-3.19/mnt-don-t-propagate-umounts-in-__detach_mounts.patch
new file mode 100644 (file)
index 0000000..a228c4a
--- /dev/null
@@ -0,0 +1,44 @@
+From 8318e667f176f7ea34451a1a530634e293f216ac Mon Sep 17 00:00:00 2001
+From: "Eric W. Biederman" <ebiederm@xmission.com>
+Date: Wed, 24 Dec 2014 07:35:10 -0600
+Subject: mnt: Don't propagate umounts in __detach_mounts
+
+From: "Eric W. Biederman" <ebiederm@xmission.com>
+
+commit 8318e667f176f7ea34451a1a530634e293f216ac upstream.
+
+Invoking mount propagation from __detach_mounts is inefficient and
+wrong.
+
+It is inefficient because __detach_mounts already walks the list of
+mounts that where something needs to be done, and mount propagation
+walks some subset of those mounts again.
+
+It is actively wrong because if the dentry that is passed to
+__detach_mounts is not part of the path to a mount that mount should
+not be affected.
+
+change_mnt_propagation(p,MS_PRIVATE) modifies the mount propagation
+tree of a master mount so it's slaves are connected to another master
+if possible.  Which means even removing a mount from the middle of a
+mount tree with __detach_mounts will not deprive any mount propagated
+mount events.
+
+Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/namespace.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/namespace.c
++++ b/fs/namespace.c
+@@ -1497,7 +1497,7 @@ void __detach_mounts(struct dentry *dent
+       lock_mount_hash();
+       while (!hlist_empty(&mp->m_list)) {
+               mnt = hlist_entry(mp->m_list.first, struct mount, mnt_mp_list);
+-              umount_tree(mnt, UMOUNT_PROPAGATE);
++              umount_tree(mnt, 0);
+       }
+       unlock_mount_hash();
+       put_mountpoint(mp);
diff --git a/queue-3.19/mnt-improve-the-umount_tree-flags.patch b/queue-3.19/mnt-improve-the-umount_tree-flags.patch
new file mode 100644 (file)
index 0000000..0f743b5
--- /dev/null
@@ -0,0 +1,156 @@
+From e819f152104c9f7c9fe50e1aecce6f5d4bf06d65 Mon Sep 17 00:00:00 2001
+From: "Eric W. Biederman" <ebiederm@xmission.com>
+Date: Wed, 24 Dec 2014 07:20:01 -0600
+Subject: mnt: Improve the umount_tree flags
+
+From: "Eric W. Biederman" <ebiederm@xmission.com>
+
+commit e819f152104c9f7c9fe50e1aecce6f5d4bf06d65 upstream.
+
+- Remove the unneeded declaration from pnode.h
+- Mark umount_tree static as it has no callers outside of namespace.c
+- Define an enumeration of umount_tree's flags.
+- Pass umount_tree's flags in by name
+
+This removes the magic numbers 0, 1 and 2 making the code a little
+clearer and makes it possible for there to be lazy unmounts that don't
+propagate.  Which is what __detach_mounts actually wants for example.
+
+Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/namespace.c |   31 ++++++++++++++++---------------
+ fs/pnode.h     |    1 -
+ 2 files changed, 16 insertions(+), 16 deletions(-)
+
+--- a/fs/namespace.c
++++ b/fs/namespace.c
+@@ -1323,14 +1323,15 @@ static inline void namespace_lock(void)
+       down_write(&namespace_sem);
+ }
++enum umount_tree_flags {
++      UMOUNT_SYNC = 1,
++      UMOUNT_PROPAGATE = 2,
++};
+ /*
+  * mount_lock must be held
+  * namespace_sem must be held for write
+- * how = 0 => just this tree, don't propagate
+- * how = 1 => propagate; we know that nobody else has reference to any victims
+- * how = 2 => lazy umount
+  */
+-void umount_tree(struct mount *mnt, int how)
++static void umount_tree(struct mount *mnt, enum umount_tree_flags how)
+ {
+       HLIST_HEAD(tmp_list);
+       struct mount *p;
+@@ -1344,7 +1345,7 @@ void umount_tree(struct mount *mnt, int
+       hlist_for_each_entry(p, &tmp_list, mnt_hash)
+               list_del_init(&p->mnt_child);
+-      if (how)
++      if (how & UMOUNT_PROPAGATE)
+               propagate_umount(&tmp_list);
+       hlist_for_each_entry(p, &tmp_list, mnt_hash) {
+@@ -1352,7 +1353,7 @@ void umount_tree(struct mount *mnt, int
+               list_del_init(&p->mnt_list);
+               __touch_mnt_namespace(p->mnt_ns);
+               p->mnt_ns = NULL;
+-              if (how < 2)
++              if (how & UMOUNT_SYNC)
+                       p->mnt.mnt_flags |= MNT_SYNC_UMOUNT;
+               if (mnt_has_parent(p)) {
+                       hlist_del_init(&p->mnt_mp_list);
+@@ -1457,14 +1458,14 @@ static int do_umount(struct mount *mnt,
+       if (flags & MNT_DETACH) {
+               if (!list_empty(&mnt->mnt_list))
+-                      umount_tree(mnt, 2);
++                      umount_tree(mnt, UMOUNT_PROPAGATE);
+               retval = 0;
+       } else {
+               shrink_submounts(mnt);
+               retval = -EBUSY;
+               if (!propagate_mount_busy(mnt, 2)) {
+                       if (!list_empty(&mnt->mnt_list))
+-                              umount_tree(mnt, 1);
++                              umount_tree(mnt, UMOUNT_PROPAGATE|UMOUNT_SYNC);
+                       retval = 0;
+               }
+       }
+@@ -1496,7 +1497,7 @@ void __detach_mounts(struct dentry *dent
+       lock_mount_hash();
+       while (!hlist_empty(&mp->m_list)) {
+               mnt = hlist_entry(mp->m_list.first, struct mount, mnt_mp_list);
+-              umount_tree(mnt, 2);
++              umount_tree(mnt, UMOUNT_PROPAGATE);
+       }
+       unlock_mount_hash();
+       put_mountpoint(mp);
+@@ -1658,7 +1659,7 @@ struct mount *copy_tree(struct mount *mn
+ out:
+       if (res) {
+               lock_mount_hash();
+-              umount_tree(res, 0);
++              umount_tree(res, UMOUNT_SYNC);
+               unlock_mount_hash();
+       }
+       return q;
+@@ -1682,7 +1683,7 @@ void drop_collected_mounts(struct vfsmou
+ {
+       namespace_lock();
+       lock_mount_hash();
+-      umount_tree(real_mount(mnt), 0);
++      umount_tree(real_mount(mnt), UMOUNT_SYNC);
+       unlock_mount_hash();
+       namespace_unlock();
+ }
+@@ -1865,7 +1866,7 @@ static int attach_recursive_mnt(struct m
+  out_cleanup_ids:
+       while (!hlist_empty(&tree_list)) {
+               child = hlist_entry(tree_list.first, struct mount, mnt_hash);
+-              umount_tree(child, 0);
++              umount_tree(child, UMOUNT_SYNC);
+       }
+       unlock_mount_hash();
+       cleanup_group_ids(source_mnt, NULL);
+@@ -2045,7 +2046,7 @@ static int do_loopback(struct path *path
+       err = graft_tree(mnt, parent, mp);
+       if (err) {
+               lock_mount_hash();
+-              umount_tree(mnt, 0);
++              umount_tree(mnt, UMOUNT_SYNC);
+               unlock_mount_hash();
+       }
+ out2:
+@@ -2416,7 +2417,7 @@ void mark_mounts_for_expiry(struct list_
+       while (!list_empty(&graveyard)) {
+               mnt = list_first_entry(&graveyard, struct mount, mnt_expire);
+               touch_mnt_namespace(mnt->mnt_ns);
+-              umount_tree(mnt, 1);
++              umount_tree(mnt, UMOUNT_PROPAGATE|UMOUNT_SYNC);
+       }
+       unlock_mount_hash();
+       namespace_unlock();
+@@ -2487,7 +2488,7 @@ static void shrink_submounts(struct moun
+                       m = list_first_entry(&graveyard, struct mount,
+                                               mnt_expire);
+                       touch_mnt_namespace(m->mnt_ns);
+-                      umount_tree(m, 1);
++                      umount_tree(m, UMOUNT_PROPAGATE|UMOUNT_SYNC);
+               }
+       }
+ }
+--- a/fs/pnode.h
++++ b/fs/pnode.h
+@@ -47,7 +47,6 @@ int get_dominating_id(struct mount *mnt,
+ unsigned int mnt_get_count(struct mount *mnt);
+ void mnt_set_mountpoint(struct mount *, struct mountpoint *,
+                       struct mount *);
+-void umount_tree(struct mount *, int);
+ struct mount *copy_tree(struct mount *, struct dentry *, int);
+ bool is_path_reachable(struct mount *, struct dentry *,
+                        const struct path *root);
index b44bfaf59ed98b848c0d12e567cb850cd2b341ad..76e7fb9db7ba3721972fd33019c4fb3a69f37a4d 100644 (file)
@@ -90,3 +90,5 @@ nfc-st21nfcb-retry-i2c_master_send-if-it-returns-a-negative-value.patch
 rtlwifi-rtl8192cu-add-new-usb-id.patch
 rtlwifi-rtl8192cu-add-new-device-id.patch
 ext4-make-fsync-to-sync-parent-dir-in-no-journal-for-real-this-time.patch
+mnt-improve-the-umount_tree-flags.patch
+mnt-don-t-propagate-umounts-in-__detach_mounts.patch