The commit is pushed to "branch-rh7-3.10.0-693.1.1.vz7.37.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git after rh7-3.10.0-693.1.1.vz7.37.5 ------> commit 15b70fe6002927ab5929740a277b5b4280515669 Author: Konstantin Khorenko <khore...@virtuozzo.com> Date: Mon Sep 18 12:12:11 2017 +0300
Revert "revert rh mnt: Honor MNT_LOCKED when detaching mounts" This reverts commit 0573dc863a9ef9a7c5cba27c8a35c415c7174ae1. This was a temporary fix for https://jira.sw.ru/browse/PSBM-71414 The issue will be fixed by next patch. Signed-off-by: Vasily Averin <v...@virtuozzo.com> --- fs/namespace.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 52 insertions(+), 3 deletions(-) diff --git a/fs/namespace.c b/fs/namespace.c index 6dbf827..2c98249 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -1125,6 +1125,13 @@ static void mntput_no_expire(struct mount *mnt) rcu_read_unlock(); list_del(&mnt->mnt_instance); + + if (unlikely(!list_empty(&mnt->mnt_mounts))) { + struct mount *p, *tmp; + list_for_each_entry_safe(p, tmp, &mnt->mnt_mounts, mnt_child) { + umount_mnt(p); + } + } unlock_mount_hash(); if (likely(!(mnt->mnt.mnt_flags & MNT_INTERNAL))) { @@ -1399,6 +1406,35 @@ enum umount_tree_flags { UMOUNT_CONNECTED = 4, }; +static bool disconnect_mount(struct mount *mnt, enum umount_tree_flags how) +{ + /* Leaving mounts connected is only valid for lazy umounts */ + if (how & UMOUNT_SYNC) + return true; + + /* A mount without a parent has nothing to be connected to */ + if (!mnt_has_parent(mnt)) + return true; + + /* Because the reference counting rules change when mounts are + * unmounted and connected, umounted mounts may not be + * connected to mounted mounts. + */ + if (!(mnt->mnt_parent->mnt.mnt_flags & MNT_UMOUNT)) + return true; + + /* Has it been requested that the mount remain connected? */ + if (how & UMOUNT_CONNECTED) + return false; + + /* Is the mount locked such that it needs to remain connected? */ + if (IS_MNT_LOCKED(mnt)) + return false; + + /* By default disconnect the mount */ + return true; +} + /* * mount_lock must be held * namespace_sem must be held for write @@ -1427,6 +1463,7 @@ static void umount_tree(struct mount *mnt, enum umount_tree_flags how) propagate_umount(&tmp_list); while (!list_empty(&tmp_list)) { + bool disconnect; p = list_first_entry(&tmp_list, struct mount, mnt_list); list_del_init(&p->mnt_expire); list_del_init(&p->mnt_list); @@ -1435,10 +1472,18 @@ static void umount_tree(struct mount *mnt, enum umount_tree_flags how) if (how & UMOUNT_SYNC) p->mnt.mnt_flags |= MNT_SYNC_UMOUNT; - pin_insert_group(&p->mnt_umount, &p->mnt_parent->mnt, &unmounted); + disconnect = disconnect_mount(p, how); + + pin_insert_group(&p->mnt_umount, &p->mnt_parent->mnt, + disconnect ? &unmounted : NULL); if (mnt_has_parent(p)) { mnt_add_count(p->mnt_parent, -1); - umount_mnt(p); + if (!disconnect) { + /* Don't forget about p */ + list_add_tail(&p->mnt_child, &p->mnt_parent->mnt_mounts); + } else { + umount_mnt(p); + } } change_mnt_propagation(p, MS_PRIVATE); } @@ -1566,7 +1611,11 @@ void __detach_mounts(struct dentry *dentry) event++; while (!hlist_empty(&mp->m_list)) { mnt = hlist_entry(mp->m_list.first, struct mount, mnt_mp_list); - umount_tree(mnt, UMOUNT_CONNECTED); + if (mnt->mnt.mnt_flags & MNT_UMOUNT) { + hlist_add_head(&mnt->mnt_umount.s_list, &unmounted); + umount_mnt(mnt); + } + else umount_tree(mnt, UMOUNT_CONNECTED); } put_mountpoint(mp); out_unlock: _______________________________________________ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel