fe955c1
From: "Eric W. Biederman" <ebiederm@xmission.com>
fe955c1
Date: Thu, 2 Apr 2015 16:35:48 -0500
fe955c1
Subject: [PATCH] fs_pin: Allow for the possibility that m_list or s_list go
fe955c1
 unused.
fe955c1
fe955c1
commit 820f9f147dcce2602eefd9b575bbbd9ea14f0953 upstream.
fe955c1
fe955c1
This is needed to support lazily umounting locked mounts.  Because the
fe955c1
entire unmounted subtree needs to stay together until there are no
fe955c1
users with references to any part of the subtree.
fe955c1
fe955c1
To support this guarantee that the fs_pin m_list and s_list nodes
fe955c1
are initialized by initializing them in init_fs_pin allowing
fe955c1
for the possibility that pin_insert_group does not touch them.
fe955c1
fe955c1
Further use hlist_del_init in pin_remove so that there is
fe955c1
a hlist_unhashed test before the list we attempt to update
fe955c1
the previous list item.
fe955c1
fe955c1
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
fe955c1
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
fe955c1
---
fe955c1
 fs/fs_pin.c            | 4 ++--
fe955c1
 include/linux/fs_pin.h | 2 ++
fe955c1
 2 files changed, 4 insertions(+), 2 deletions(-)
fe955c1
fe955c1
diff --git a/fs/fs_pin.c b/fs/fs_pin.c
fe955c1
index b06c98796afb..611b5408f6ec 100644
fe955c1
--- a/fs/fs_pin.c
fe955c1
+++ b/fs/fs_pin.c
fe955c1
@@ -9,8 +9,8 @@ static DEFINE_SPINLOCK(pin_lock);
fe955c1
 void pin_remove(struct fs_pin *pin)
fe955c1
 {
fe955c1
 	spin_lock(&pin_lock);
fe955c1
-	hlist_del(&pin->m_list);
fe955c1
-	hlist_del(&pin->s_list);
fe955c1
+	hlist_del_init(&pin->m_list);
fe955c1
+	hlist_del_init(&pin->s_list);
fe955c1
 	spin_unlock(&pin_lock);
fe955c1
 	spin_lock_irq(&pin->wait.lock);
fe955c1
 	pin->done = 1;
fe955c1
diff --git a/include/linux/fs_pin.h b/include/linux/fs_pin.h
fe955c1
index 9dc4e0384bfb..3886b3bffd7f 100644
fe955c1
--- a/include/linux/fs_pin.h
fe955c1
+++ b/include/linux/fs_pin.h
fe955c1
@@ -13,6 +13,8 @@ struct vfsmount;
fe955c1
 static inline void init_fs_pin(struct fs_pin *p, void (*kill)(struct fs_pin *))
fe955c1
 {
fe955c1
 	init_waitqueue_head(&p->wait);
fe955c1
+	INIT_HLIST_NODE(&p->s_list);
fe955c1
+	INIT_HLIST_NODE(&p->m_list);
fe955c1
 	p->kill = kill;
fe955c1
 }
fe955c1