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