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