Skip to content

Commit 56cbb42

Browse files
author
Al Viro
committed
switch the remnants of releasing the mountpoint away from fs_pin
We used to need rather convoluted ordering trickery to guarantee that dput() of ex-mountpoints happens before the final mntput() of the same. Since we don't need that anymore, there's no point playing with fs_pin for that. Signed-off-by: Al Viro <[email protected]>
1 parent 2763d11 commit 56cbb42

File tree

4 files changed

+26
-29
lines changed

4 files changed

+26
-29
lines changed

fs/fs_pin.c

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,14 @@ void pin_remove(struct fs_pin *pin)
1919
spin_unlock_irq(&pin->wait.lock);
2020
}
2121

22-
void pin_insert_group(struct fs_pin *pin, struct vfsmount *m, struct hlist_head *p)
22+
void pin_insert(struct fs_pin *pin, struct vfsmount *m)
2323
{
2424
spin_lock(&pin_lock);
25-
if (p)
26-
hlist_add_head(&pin->s_list, p);
25+
hlist_add_head(&pin->s_list, &m->mnt_sb->s_pins);
2726
hlist_add_head(&pin->m_list, &real_mount(m)->mnt_pins);
2827
spin_unlock(&pin_lock);
2928
}
3029

31-
void pin_insert(struct fs_pin *pin, struct vfsmount *m)
32-
{
33-
pin_insert_group(pin, m, &m->mnt_sb->s_pins);
34-
}
35-
3630
void pin_kill(struct fs_pin *p)
3731
{
3832
wait_queue_entry_t wait;

fs/mount.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,10 @@ struct mount {
5858
struct mount *mnt_master; /* slave is on master->mnt_slave_list */
5959
struct mnt_namespace *mnt_ns; /* containing namespace */
6060
struct mountpoint *mnt_mp; /* where is it mounted */
61-
struct hlist_node mnt_mp_list; /* list mounts with the same mountpoint */
61+
union {
62+
struct hlist_node mnt_mp_list; /* list mounts with the same mountpoint */
63+
struct hlist_node mnt_umount;
64+
};
6265
struct list_head mnt_umounting; /* list entry for umount propagation */
6366
#ifdef CONFIG_FSNOTIFY
6467
struct fsnotify_mark_connector __rcu *mnt_fsnotify_marks;
@@ -68,7 +71,7 @@ struct mount {
6871
int mnt_group_id; /* peer group identifier */
6972
int mnt_expiry_mark; /* true if marked for expiry */
7073
struct hlist_head mnt_pins;
71-
struct fs_pin mnt_umount;
74+
struct hlist_head mnt_stuck_children;
7275
} __randomize_layout;
7376

7477
#define MNT_NS_INTERNAL ERR_PTR(-EINVAL) /* distinct from any mnt_namespace */

fs/namespace.c

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -171,13 +171,6 @@ unsigned int mnt_get_count(struct mount *mnt)
171171
#endif
172172
}
173173

174-
static void drop_mountpoint(struct fs_pin *p)
175-
{
176-
struct mount *m = container_of(p, struct mount, mnt_umount);
177-
pin_remove(p);
178-
mntput(&m->mnt);
179-
}
180-
181174
static struct mount *alloc_vfsmnt(const char *name)
182175
{
183176
struct mount *mnt = kmem_cache_zalloc(mnt_cache, GFP_KERNEL);
@@ -215,7 +208,7 @@ static struct mount *alloc_vfsmnt(const char *name)
215208
INIT_LIST_HEAD(&mnt->mnt_slave);
216209
INIT_HLIST_NODE(&mnt->mnt_mp_list);
217210
INIT_LIST_HEAD(&mnt->mnt_umounting);
218-
init_fs_pin(&mnt->mnt_umount, drop_mountpoint);
211+
INIT_HLIST_HEAD(&mnt->mnt_stuck_children);
219212
}
220213
return mnt;
221214

@@ -1087,19 +1080,22 @@ static struct mount *clone_mnt(struct mount *old, struct dentry *root,
10871080

10881081
static void cleanup_mnt(struct mount *mnt)
10891082
{
1083+
struct hlist_node *p;
1084+
struct mount *m;
10901085
/*
1091-
* This probably indicates that somebody messed
1092-
* up a mnt_want/drop_write() pair. If this
1093-
* happens, the filesystem was probably unable
1094-
* to make r/w->r/o transitions.
1095-
*/
1096-
/*
1086+
* The warning here probably indicates that somebody messed
1087+
* up a mnt_want/drop_write() pair. If this happens, the
1088+
* filesystem was probably unable to make r/w->r/o transitions.
10971089
* The locking used to deal with mnt_count decrement provides barriers,
10981090
* so mnt_get_writers() below is safe.
10991091
*/
11001092
WARN_ON(mnt_get_writers(mnt));
11011093
if (unlikely(mnt->mnt_pins.first))
11021094
mnt_pin_kill(mnt);
1095+
hlist_for_each_entry_safe(m, p, &mnt->mnt_stuck_children, mnt_umount) {
1096+
hlist_del(&m->mnt_umount);
1097+
mntput(&m->mnt);
1098+
}
11031099
fsnotify_vfsmount_delete(&mnt->mnt);
11041100
dput(mnt->mnt.mnt_root);
11051101
deactivate_super(mnt->mnt.mnt_sb);
@@ -1168,6 +1164,7 @@ static void mntput_no_expire(struct mount *mnt)
11681164
struct mount *p, *tmp;
11691165
list_for_each_entry_safe(p, tmp, &mnt->mnt_mounts, mnt_child) {
11701166
__put_mountpoint(unhash_mnt(p), &list);
1167+
hlist_add_head(&p->mnt_umount, &mnt->mnt_stuck_children);
11711168
}
11721169
}
11731170
unlock_mount_hash();
@@ -1360,6 +1357,8 @@ EXPORT_SYMBOL(may_umount);
13601357
static void namespace_unlock(void)
13611358
{
13621359
struct hlist_head head;
1360+
struct hlist_node *p;
1361+
struct mount *m;
13631362
LIST_HEAD(list);
13641363

13651364
hlist_move_list(&unmounted, &head);
@@ -1374,7 +1373,10 @@ static void namespace_unlock(void)
13741373

13751374
synchronize_rcu_expedited();
13761375

1377-
group_pin_kill(&head);
1376+
hlist_for_each_entry_safe(m, p, &head, mnt_umount) {
1377+
hlist_del(&m->mnt_umount);
1378+
mntput(&m->mnt);
1379+
}
13781380
}
13791381

13801382
static inline void namespace_lock(void)
@@ -1461,15 +1463,14 @@ static void umount_tree(struct mount *mnt, enum umount_tree_flags how)
14611463

14621464
disconnect = disconnect_mount(p, how);
14631465

1464-
pin_insert_group(&p->mnt_umount, &p->mnt_parent->mnt,
1465-
disconnect ? &unmounted : NULL);
14661466
if (mnt_has_parent(p)) {
14671467
mnt_add_count(p->mnt_parent, -1);
14681468
if (!disconnect) {
14691469
/* Don't forget about p */
14701470
list_add_tail(&p->mnt_child, &p->mnt_parent->mnt_mounts);
14711471
} else {
14721472
umount_mnt(p);
1473+
hlist_add_head(&p->mnt_umount, &unmounted);
14731474
}
14741475
}
14751476
change_mnt_propagation(p, MS_PRIVATE);
@@ -1622,8 +1623,8 @@ void __detach_mounts(struct dentry *dentry)
16221623
while (!hlist_empty(&mp->m_list)) {
16231624
mnt = hlist_entry(mp->m_list.first, struct mount, mnt_mp_list);
16241625
if (mnt->mnt.mnt_flags & MNT_UMOUNT) {
1625-
hlist_add_head(&mnt->mnt_umount.s_list, &unmounted);
16261626
umount_mnt(mnt);
1627+
hlist_add_head(&mnt->mnt_umount, &unmounted);
16271628
}
16281629
else umount_tree(mnt, UMOUNT_CONNECTED);
16291630
}

include/linux/fs_pin.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,5 @@ static inline void init_fs_pin(struct fs_pin *p, void (*kill)(struct fs_pin *))
2020
}
2121

2222
void pin_remove(struct fs_pin *);
23-
void pin_insert_group(struct fs_pin *, struct vfsmount *, struct hlist_head *);
2423
void pin_insert(struct fs_pin *, struct vfsmount *);
2524
void pin_kill(struct fs_pin *);

0 commit comments

Comments
 (0)