blob: f3ce0b874a44b8989ece5f7f90be7cb6b84ac8d7 [file] [log] [blame]
Al Viroefb170c2014-08-07 08:39:04 -04001#include <linux/fs.h>
2#include <linux/slab.h>
3#include <linux/fs_pin.h>
4#include "mount.h"
5
6static void pin_free_rcu(struct rcu_head *head)
7{
8 kfree(container_of(head, struct fs_pin, rcu));
9}
10
11static DEFINE_SPINLOCK(pin_lock);
12
13void 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
19void 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
27void 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
35void 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
57void 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}