xref: /linux/fs/fs_pin.c (revision 1ab0b8b200ae54a03aaf63fa8ae5a241dd0cb499)
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  }
79