Al Viro | efb170c | 2014-08-07 08:39:04 -0400 | [diff] [blame] | 1 | #include <linux/fs.h> |
| 2 | #include <linux/slab.h> |
| 3 | #include <linux/fs_pin.h> |
Al Viro | 8fa1f1c | 2014-05-21 18:22:52 -0400 | [diff] [blame] | 4 | #include "internal.h" |
Al Viro | efb170c | 2014-08-07 08:39:04 -0400 | [diff] [blame] | 5 | #include "mount.h" |
| 6 | |
Al Viro | efb170c | 2014-08-07 08:39:04 -0400 | [diff] [blame] | 7 | static DEFINE_SPINLOCK(pin_lock); |
| 8 | |
Al Viro | efb170c | 2014-08-07 08:39:04 -0400 | [diff] [blame] | 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 | |
Al Viro | fdab684 | 2015-01-11 10:57:27 -0500 | [diff] [blame^] | 17 | void pin_insert_group(struct fs_pin *pin, struct vfsmount *m, struct hlist_head *p) |
Al Viro | efb170c | 2014-08-07 08:39:04 -0400 | [diff] [blame] | 18 | { |
| 19 | spin_lock(&pin_lock); |
Al Viro | fdab684 | 2015-01-11 10:57:27 -0500 | [diff] [blame^] | 20 | if (p) |
| 21 | hlist_add_head(&pin->s_list, p); |
Al Viro | efb170c | 2014-08-07 08:39:04 -0400 | [diff] [blame] | 22 | hlist_add_head(&pin->m_list, &real_mount(m)->mnt_pins); |
| 23 | spin_unlock(&pin_lock); |
| 24 | } |
| 25 | |
Al Viro | fdab684 | 2015-01-11 10:57:27 -0500 | [diff] [blame^] | 26 | void pin_insert(struct fs_pin *pin, struct vfsmount *m) |
| 27 | { |
| 28 | pin_insert_group(pin, m, &m->mnt_sb->s_pins); |
| 29 | } |
| 30 | |
Al Viro | 8fa1f1c | 2014-05-21 18:22:52 -0400 | [diff] [blame] | 31 | void mnt_pin_kill(struct mount *m) |
Al Viro | efb170c | 2014-08-07 08:39:04 -0400 | [diff] [blame] | 32 | { |
| 33 | while (1) { |
| 34 | struct hlist_node *p; |
| 35 | struct fs_pin *pin; |
| 36 | rcu_read_lock(); |
Al Viro | 8fa1f1c | 2014-05-21 18:22:52 -0400 | [diff] [blame] | 37 | p = ACCESS_ONCE(m->mnt_pins.first); |
Al Viro | efb170c | 2014-08-07 08:39:04 -0400 | [diff] [blame] | 38 | if (!p) { |
| 39 | rcu_read_unlock(); |
| 40 | break; |
| 41 | } |
| 42 | pin = hlist_entry(p, struct fs_pin, m_list); |
Al Viro | efb170c | 2014-08-07 08:39:04 -0400 | [diff] [blame] | 43 | pin->kill(pin); |
| 44 | } |
| 45 | } |
| 46 | |
Al Viro | fdab684 | 2015-01-11 10:57:27 -0500 | [diff] [blame^] | 47 | void group_pin_kill(struct hlist_head *p) |
Al Viro | efb170c | 2014-08-07 08:39:04 -0400 | [diff] [blame] | 48 | { |
| 49 | while (1) { |
Al Viro | fdab684 | 2015-01-11 10:57:27 -0500 | [diff] [blame^] | 50 | struct hlist_node *q; |
Al Viro | efb170c | 2014-08-07 08:39:04 -0400 | [diff] [blame] | 51 | struct fs_pin *pin; |
| 52 | rcu_read_lock(); |
Al Viro | fdab684 | 2015-01-11 10:57:27 -0500 | [diff] [blame^] | 53 | q = ACCESS_ONCE(p->first); |
| 54 | if (!q) { |
Al Viro | efb170c | 2014-08-07 08:39:04 -0400 | [diff] [blame] | 55 | rcu_read_unlock(); |
| 56 | break; |
| 57 | } |
Al Viro | fdab684 | 2015-01-11 10:57:27 -0500 | [diff] [blame^] | 58 | pin = hlist_entry(q, struct fs_pin, s_list); |
Al Viro | efb170c | 2014-08-07 08:39:04 -0400 | [diff] [blame] | 59 | pin->kill(pin); |
| 60 | } |
| 61 | } |