We've got several cases when ploop could not be unmounted resulting in
-EBUSY. Sometimes we could find what holds it sometimes not, so let's
introduce the global list of mount namespaces: it will make it easier to
debug such cases.

https://jira.sw.ru/browse/PSBM-80869

Signed-off-by: Konstantin Khorenko <khore...@virtuozzo.com>

Changes:
v2: move sem lock/unlock inside free_mnt_ns() to fix calling copy_mnt_ns()
    without semaphore taken.
---
 fs/mount.h     |  1 +
 fs/namespace.c | 11 +++++++++++
 2 files changed, 12 insertions(+)

diff --git a/fs/mount.h b/fs/mount.h
index f3f39baf9a06..0c4448dbe5d1 100644
--- a/fs/mount.h
+++ b/fs/mount.h
@@ -16,6 +16,7 @@ struct mnt_namespace {
        u64 event;
        RH_KABI_EXTEND(unsigned int     mounts) /* # of mounts in the namespace 
*/
        RH_KABI_EXTEND(unsigned int     pending_mounts)
+       struct list_head        mntns_list;
 };
 
 struct mnt_pcp {
diff --git a/fs/namespace.c b/fs/namespace.c
index 377ba4f36639..e3b6fb36ea13 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -3125,6 +3125,10 @@ static void free_mnt_ns(struct mnt_namespace *ns)
        proc_free_inum(ns->proc_inum);
        dec_mnt_namespaces(ns->ucounts);
        put_user_ns(ns->user_ns);
+
+       namespace_lock();
+       list_del(&ns->mntns_list);
+       namespace_unlock();
        kfree(ns);
 }
 
@@ -3136,6 +3140,7 @@ static void free_mnt_ns(struct mnt_namespace *ns)
  * is effectively never, so we can ignore the possibility.
  */
 static atomic64_t mnt_ns_seq = ATOMIC64_INIT(1);
+static LIST_HEAD(all_mntns_list); /* protected by namespace_sem */
 
 static struct mnt_namespace *alloc_mnt_ns(struct user_namespace *user_ns)
 {
@@ -3162,6 +3167,7 @@ static struct mnt_namespace *alloc_mnt_ns(struct 
user_namespace *user_ns)
        atomic_set(&new_ns->count, 1);
        new_ns->root = NULL;
        INIT_LIST_HEAD(&new_ns->list);
+       INIT_LIST_HEAD(&new_ns->mntns_list);
        init_waitqueue_head(&new_ns->poll);
        new_ns->event = 0;
        new_ns->user_ns = get_user_ns(user_ns);
@@ -3199,6 +3205,8 @@ struct mnt_namespace *copy_mnt_ns(unsigned long flags, 
struct mnt_namespace *ns,
                return new_ns;
 
        namespace_lock();
+       list_add_tail(&new_ns->mntns_list, &all_mntns_list);
+
        /* First pass: copy the tree topology */
        copy_flags = CL_COPY_UNBINDABLE | CL_EXPIRE;
        if (user_ns != ns->user_ns)
@@ -3262,6 +3270,9 @@ static struct mnt_namespace *create_mnt_ns(struct 
vfsmount *m)
                new_ns->root = mnt;
                new_ns->mounts++;
                list_add(&mnt->mnt_list, &new_ns->list);
+               namespace_lock();
+               list_add_tail(&new_ns->mntns_list, &all_mntns_list);
+               namespace_unlock();
        } else {
                mntput(m);
        }
-- 
2.15.1

_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to