Commit | Line | Data |
---|---|---|
efb170c2 AV |
1 | #include <linux/fs.h> |
2 | #include <linux/slab.h> | |
3 | #include <linux/fs_pin.h> | |
4 | #include "mount.h" | |
5 | ||
6 | static void pin_free_rcu(struct rcu_head *head) | |
7 | { | |
8 | kfree(container_of(head, struct fs_pin, rcu)); | |
9 | } | |
10 | ||
11 | static DEFINE_SPINLOCK(pin_lock); | |
12 | ||
13 | void pin_put(struct fs_pin *p) | |
14 | { | |
15 | if (atomic_long_dec_and_test(&p->count)) | |
16 | call_rcu(&p->rcu, pin_free_rcu); | |
17 | } | |
18 | ||
19 | void pin_remove(struct fs_pin *pin) | |
20 | { | |
21 | spin_lock(&pin_lock); | |
22 | hlist_del(&pin->m_list); | |
23 | hlist_del(&pin->s_list); | |
24 | spin_unlock(&pin_lock); | |
25 | } | |
26 | ||
27 | void pin_insert(struct fs_pin *pin, struct vfsmount *m) | |
28 | { | |
29 | spin_lock(&pin_lock); | |
30 | hlist_add_head(&pin->s_list, &m->mnt_sb->s_pins); | |
31 | hlist_add_head(&pin->m_list, &real_mount(m)->mnt_pins); | |
32 | spin_unlock(&pin_lock); | |
33 | } | |
34 | ||
35 | void acct_auto_close_mnt(struct hlist_head *list) | |
36 | { | |
37 | while (1) { | |
38 | struct hlist_node *p; | |
39 | struct fs_pin *pin; | |
40 | rcu_read_lock(); | |
41 | p = ACCESS_ONCE(list->first); | |
42 | if (!p) { | |
43 | rcu_read_unlock(); | |
44 | break; | |
45 | } | |
46 | pin = hlist_entry(p, struct fs_pin, m_list); | |
47 | if (!atomic_long_inc_not_zero(&pin->count)) { | |
48 | rcu_read_unlock(); | |
49 | cpu_relax(); | |
50 | continue; | |
51 | } | |
52 | rcu_read_unlock(); | |
53 | pin->kill(pin); | |
54 | } | |
55 | } | |
56 | ||
57 | void acct_auto_close(struct hlist_head *list) | |
58 | { | |
59 | while (1) { | |
60 | struct hlist_node *p; | |
61 | struct fs_pin *pin; | |
62 | rcu_read_lock(); | |
63 | p = ACCESS_ONCE(list->first); | |
64 | if (!p) { | |
65 | rcu_read_unlock(); | |
66 | break; | |
67 | } | |
68 | pin = hlist_entry(p, struct fs_pin, s_list); | |
69 | if (!atomic_long_inc_not_zero(&pin->count)) { | |
70 | rcu_read_unlock(); | |
71 | cpu_relax(); | |
72 | continue; | |
73 | } | |
74 | rcu_read_unlock(); | |
75 | pin->kill(pin); | |
76 | } | |
77 | } |