From: Greg Kroah-Hartman Date: Sat, 2 May 2015 15:56:01 +0000 (+0200) Subject: 3.19-stable patches X-Git-Tag: v3.10.77~38 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=04a72cb0cb2512fe54a7fa63a44b799c5c0af258;p=thirdparty%2Fkernel%2Fstable-queue.git 3.19-stable patches added patches: mnt-don-t-propagate-umounts-in-__detach_mounts.patch mnt-improve-the-umount_tree-flags.patch --- 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 index 00000000000..a228c4a57e1 --- /dev/null +++ b/queue-3.19/mnt-don-t-propagate-umounts-in-__detach_mounts.patch @@ -0,0 +1,44 @@ +From 8318e667f176f7ea34451a1a530634e293f216ac Mon Sep 17 00:00:00 2001 +From: "Eric W. Biederman" +Date: Wed, 24 Dec 2014 07:35:10 -0600 +Subject: mnt: Don't propagate umounts in __detach_mounts + +From: "Eric W. Biederman" + +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" +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..0f743b588b9 --- /dev/null +++ b/queue-3.19/mnt-improve-the-umount_tree-flags.patch @@ -0,0 +1,156 @@ +From e819f152104c9f7c9fe50e1aecce6f5d4bf06d65 Mon Sep 17 00:00:00 2001 +From: "Eric W. Biederman" +Date: Wed, 24 Dec 2014 07:20:01 -0600 +Subject: mnt: Improve the umount_tree flags + +From: "Eric W. Biederman" + +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" +Signed-off-by: Greg Kroah-Hartman + +--- + 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); diff --git a/queue-3.19/series b/queue-3.19/series index b44bfaf59ed..76e7fb9db7b 100644 --- a/queue-3.19/series +++ b/queue-3.19/series @@ -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