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