Commit | Line | Data |
---|---|---|
efb170c2 AV |
1 | #include <linux/fs.h> |
2 | #include <linux/slab.h> | |
3 | #include <linux/fs_pin.h> | |
8fa1f1c2 | 4 | #include "internal.h" |
efb170c2 AV |
5 | #include "mount.h" |
6 | ||
efb170c2 AV |
7 | static DEFINE_SPINLOCK(pin_lock); |
8 | ||
efb170c2 AV |
9 | void pin_remove(struct fs_pin *pin) |
10 | { | |
11 | spin_lock(&pin_lock); | |
12 | hlist_del(&pin->m_list); | |
13 | hlist_del(&pin->s_list); | |
14 | spin_unlock(&pin_lock); | |
15 | } | |
16 | ||
fdab684d | 17 | void pin_insert_group(struct fs_pin *pin, struct vfsmount *m, struct hlist_head *p) |
efb170c2 AV |
18 | { |
19 | spin_lock(&pin_lock); | |
fdab684d AV |
20 | if (p) |
21 | hlist_add_head(&pin->s_list, p); | |
efb170c2 AV |
22 | hlist_add_head(&pin->m_list, &real_mount(m)->mnt_pins); |
23 | spin_unlock(&pin_lock); | |
24 | } | |
25 | ||
fdab684d AV |
26 | void pin_insert(struct fs_pin *pin, struct vfsmount *m) |
27 | { | |
28 | pin_insert_group(pin, m, &m->mnt_sb->s_pins); | |
29 | } | |
30 | ||
8fa1f1c2 | 31 | void mnt_pin_kill(struct mount *m) |
efb170c2 AV |
32 | { |
33 | while (1) { | |
34 | struct hlist_node *p; | |
35 | struct fs_pin *pin; | |
36 | rcu_read_lock(); | |
8fa1f1c2 | 37 | p = ACCESS_ONCE(m->mnt_pins.first); |
efb170c2 AV |
38 | if (!p) { |
39 | rcu_read_unlock(); | |
40 | break; | |
41 | } | |
42 | pin = hlist_entry(p, struct fs_pin, m_list); | |
efb170c2 AV |
43 | pin->kill(pin); |
44 | } | |
45 | } | |
46 | ||
fdab684d | 47 | void group_pin_kill(struct hlist_head *p) |
efb170c2 AV |
48 | { |
49 | while (1) { | |
fdab684d | 50 | struct hlist_node *q; |
efb170c2 AV |
51 | struct fs_pin *pin; |
52 | rcu_read_lock(); | |
fdab684d AV |
53 | q = ACCESS_ONCE(p->first); |
54 | if (!q) { | |
efb170c2 AV |
55 | rcu_read_unlock(); |
56 | break; | |
57 | } | |
fdab684d | 58 | pin = hlist_entry(q, struct fs_pin, s_list); |
efb170c2 AV |
59 | pin->kill(pin); |
60 | } | |
61 | } |