fs_pin.c 2.0 KB

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