1 #include <linux/fs.h> 2 #include <linux/sched.h> 3 #include <linux/slab.h> 4 #include "internal.h" 5 #include "mount.h" 6 7 static DEFINE_SPINLOCK(pin_lock); 8 9 void pin_remove(struct fs_pin *pin) 10 { 11 spin_lock(&pin_lock); 12 hlist_del_init(&pin->m_list); 13 hlist_del_init(&pin->s_list); 14 spin_unlock(&pin_lock); 15 spin_lock_irq(&pin->wait.lock); 16 pin->done = 1; 17 wake_up_locked(&pin->wait); 18 spin_unlock_irq(&pin->wait.lock); 19 } 20 21 void pin_insert_group(struct fs_pin *pin, struct vfsmount *m, struct hlist_head *p) 22 { 23 spin_lock(&pin_lock); 24 if (p) 25 hlist_add_head(&pin->s_list, p); 26 hlist_add_head(&pin->m_list, &real_mount(m)->mnt_pins); 27 spin_unlock(&pin_lock); 28 } 29 30 void pin_insert(struct fs_pin *pin, struct vfsmount *m) 31 { 32 pin_insert_group(pin, m, &m->mnt_sb->s_pins); 33 } 34 35 void pin_kill(struct fs_pin *p) 36 { 37 wait_queue_t wait; 38 39 if (!p) { 40 rcu_read_unlock(); 41 return; 42 } 43 init_wait(&wait); 44 spin_lock_irq(&p->wait.lock); 45 if (likely(!p->done)) { 46 p->done = -1; 47 spin_unlock_irq(&p->wait.lock); 48 rcu_read_unlock(); 49 p->kill(p); 50 return; 51 } 52 if (p->done > 0) { 53 spin_unlock_irq(&p->wait.lock); 54 rcu_read_unlock(); 55 return; 56 } 57 __add_wait_queue(&p->wait, &wait); 58 while (1) { 59 set_current_state(TASK_UNINTERRUPTIBLE); 60 spin_unlock_irq(&p->wait.lock); 61 rcu_read_unlock(); 62 schedule(); 63 rcu_read_lock(); 64 if (likely(list_empty(&wait.task_list))) 65 break; 66 /* OK, we know p couldn't have been freed yet */ 67 spin_lock_irq(&p->wait.lock); 68 if (p->done > 0) { 69 spin_unlock_irq(&p->wait.lock); 70 break; 71 } 72 } 73 rcu_read_unlock(); 74 } 75 76 void mnt_pin_kill(struct mount *m) 77 { 78 while (1) { 79 struct hlist_node *p; 80 rcu_read_lock(); 81 p = ACCESS_ONCE(m->mnt_pins.first); 82 if (!p) { 83 rcu_read_unlock(); 84 break; 85 } 86 pin_kill(hlist_entry(p, struct fs_pin, m_list)); 87 } 88 } 89 90 void group_pin_kill(struct hlist_head *p) 91 { 92 while (1) { 93 struct hlist_node *q; 94 rcu_read_lock(); 95 q = ACCESS_ONCE(p->first); 96 if (!q) { 97 rcu_read_unlock(); 98 break; 99 } 100 pin_kill(hlist_entry(q, struct fs_pin, s_list)); 101 } 102 } 103