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 | ||
17 | void pin_insert(struct fs_pin *pin, struct vfsmount *m) | |
18 | { | |
19 | spin_lock(&pin_lock); | |
20 | hlist_add_head(&pin->s_list, &m->mnt_sb->s_pins); | |
21 | hlist_add_head(&pin->m_list, &real_mount(m)->mnt_pins); | |
22 | spin_unlock(&pin_lock); | |
23 | } | |
24 | ||
8fa1f1c2 | 25 | void mnt_pin_kill(struct mount *m) |
efb170c2 AV |
26 | { |
27 | while (1) { | |
28 | struct hlist_node *p; | |
29 | struct fs_pin *pin; | |
30 | rcu_read_lock(); | |
8fa1f1c2 | 31 | p = ACCESS_ONCE(m->mnt_pins.first); |
efb170c2 AV |
32 | if (!p) { |
33 | rcu_read_unlock(); | |
34 | break; | |
35 | } | |
36 | pin = hlist_entry(p, struct fs_pin, m_list); | |
efb170c2 AV |
37 | pin->kill(pin); |
38 | } | |
39 | } | |
40 | ||
8fa1f1c2 | 41 | void sb_pin_kill(struct super_block *sb) |
efb170c2 AV |
42 | { |
43 | while (1) { | |
44 | struct hlist_node *p; | |
45 | struct fs_pin *pin; | |
46 | rcu_read_lock(); | |
8fa1f1c2 | 47 | p = ACCESS_ONCE(sb->s_pins.first); |
efb170c2 AV |
48 | if (!p) { |
49 | rcu_read_unlock(); | |
50 | break; | |
51 | } | |
52 | pin = hlist_entry(p, struct fs_pin, s_list); | |
efb170c2 AV |
53 | pin->kill(pin); |
54 | } | |
55 | } |