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