mount.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. /******************************************************************************
  2. *******************************************************************************
  3. **
  4. ** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
  5. ** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
  6. **
  7. ** This copyrighted material is made available to anyone wishing to use,
  8. ** modify, copy, or redistribute it subject to the terms and conditions
  9. ** of the GNU General Public License v.2.
  10. **
  11. *******************************************************************************
  12. ******************************************************************************/
  13. #include "lock_dlm.h"
  14. int gdlm_drop_count;
  15. int gdlm_drop_period;
  16. struct lm_lockops gdlm_ops;
  17. static struct gdlm_ls *init_gdlm(lm_callback_t cb, lm_fsdata_t *fsdata,
  18. int flags, char *table_name)
  19. {
  20. struct gdlm_ls *ls;
  21. char buf[256], *p;
  22. ls = kmalloc(sizeof(struct gdlm_ls), GFP_KERNEL);
  23. if (!ls)
  24. return NULL;
  25. memset(ls, 0, sizeof(struct gdlm_ls));
  26. ls->drop_locks_count = gdlm_drop_count;
  27. ls->drop_locks_period = gdlm_drop_period;
  28. ls->fscb = cb;
  29. ls->fsdata = fsdata;
  30. ls->fsflags = flags;
  31. spin_lock_init(&ls->async_lock);
  32. INIT_LIST_HEAD(&ls->complete);
  33. INIT_LIST_HEAD(&ls->blocking);
  34. INIT_LIST_HEAD(&ls->delayed);
  35. INIT_LIST_HEAD(&ls->submit);
  36. INIT_LIST_HEAD(&ls->all_locks);
  37. init_waitqueue_head(&ls->thread_wait);
  38. init_waitqueue_head(&ls->wait_control);
  39. ls->thread1 = NULL;
  40. ls->thread2 = NULL;
  41. ls->drop_time = jiffies;
  42. ls->jid = -1;
  43. strncpy(buf, table_name, 256);
  44. buf[255] = '\0';
  45. p = strstr(buf, ":");
  46. if (!p) {
  47. printk("lock_dlm: invalid table_name \"%s\"\n", table_name);
  48. kfree(ls);
  49. return NULL;
  50. }
  51. *p = '\0';
  52. p++;
  53. strncpy(ls->clustername, buf, 128);
  54. strncpy(ls->fsname, p, 128);
  55. return ls;
  56. }
  57. static int gdlm_mount(char *table_name, char *host_data,
  58. lm_callback_t cb, lm_fsdata_t *fsdata,
  59. unsigned int min_lvb_size, int flags,
  60. struct lm_lockstruct *lockstruct)
  61. {
  62. struct gdlm_ls *ls;
  63. int error = -ENOMEM;
  64. if (min_lvb_size > GDLM_LVB_SIZE)
  65. goto out;
  66. ls = init_gdlm(cb, fsdata, flags, table_name);
  67. if (!ls)
  68. goto out;
  69. error = gdlm_init_threads(ls);
  70. if (error)
  71. goto out_free;
  72. error = dlm_new_lockspace(ls->fsname, strlen(ls->fsname),
  73. &ls->dlm_lockspace, 0, GDLM_LVB_SIZE);
  74. if (error) {
  75. printk("lock_dlm: dlm_new_lockspace error %d\n", error);
  76. goto out_thread;
  77. }
  78. error = gdlm_kobject_setup(ls);
  79. if (error)
  80. goto out_dlm;
  81. kobject_uevent(&ls->kobj, KOBJ_MOUNT, NULL);
  82. /* Now we depend on userspace to notice the new mount,
  83. join the appropriate group, and do a write to our sysfs
  84. "mounted" or "terminate" file. Before the start, userspace
  85. must set "jid" and "first". */
  86. error = wait_event_interruptible(ls->wait_control,
  87. test_bit(DFL_JOIN_DONE, &ls->flags));
  88. if (error)
  89. goto out_sysfs;
  90. if (test_bit(DFL_TERMINATE, &ls->flags)) {
  91. error = -ERESTARTSYS;
  92. goto out_sysfs;
  93. }
  94. lockstruct->ls_jid = ls->jid;
  95. lockstruct->ls_first = ls->first;
  96. lockstruct->ls_lockspace = ls;
  97. lockstruct->ls_ops = &gdlm_ops;
  98. lockstruct->ls_flags = 0;
  99. lockstruct->ls_lvb_size = GDLM_LVB_SIZE;
  100. return 0;
  101. out_sysfs:
  102. gdlm_kobject_release(ls);
  103. out_dlm:
  104. dlm_release_lockspace(ls->dlm_lockspace, 2);
  105. out_thread:
  106. gdlm_release_threads(ls);
  107. out_free:
  108. kfree(ls);
  109. out:
  110. return error;
  111. }
  112. static void gdlm_unmount(lm_lockspace_t *lockspace)
  113. {
  114. struct gdlm_ls *ls = (struct gdlm_ls *) lockspace;
  115. int rv;
  116. log_debug("unmount flags %lx", ls->flags);
  117. if (test_bit(DFL_WITHDRAW, &ls->flags)) {
  118. gdlm_kobject_release(ls);
  119. goto out;
  120. }
  121. kobject_uevent(&ls->kobj, KOBJ_UMOUNT, NULL);
  122. wait_event_interruptible(ls->wait_control,
  123. test_bit(DFL_LEAVE_DONE, &ls->flags));
  124. gdlm_kobject_release(ls);
  125. dlm_release_lockspace(ls->dlm_lockspace, 2);
  126. gdlm_release_threads(ls);
  127. rv = gdlm_release_all_locks(ls);
  128. if (rv)
  129. log_all("lm_dlm_unmount: %d stray locks freed", rv);
  130. out:
  131. kfree(ls);
  132. }
  133. static void gdlm_recovery_done(lm_lockspace_t *lockspace, unsigned int jid,
  134. unsigned int message)
  135. {
  136. struct gdlm_ls *ls = (struct gdlm_ls *) lockspace;
  137. ls->recover_done = jid;
  138. kobject_uevent(&ls->kobj, KOBJ_CHANGE, NULL);
  139. }
  140. static void gdlm_others_may_mount(lm_lockspace_t *lockspace)
  141. {
  142. struct gdlm_ls *ls = (struct gdlm_ls *) lockspace;
  143. ls->first_done = 1;
  144. kobject_uevent(&ls->kobj, KOBJ_CHANGE, NULL);
  145. }
  146. static void gdlm_withdraw(lm_lockspace_t *lockspace)
  147. {
  148. struct gdlm_ls *ls = (struct gdlm_ls *) lockspace;
  149. /* userspace suspends locking on all other members */
  150. kobject_uevent(&ls->kobj, KOBJ_OFFLINE, NULL);
  151. wait_event_interruptible(ls->wait_control,
  152. test_bit(DFL_WITHDRAW, &ls->flags));
  153. dlm_release_lockspace(ls->dlm_lockspace, 2);
  154. gdlm_release_threads(ls);
  155. gdlm_release_all_locks(ls);
  156. kobject_uevent(&ls->kobj, KOBJ_UMOUNT, NULL);
  157. /* userspace leaves the mount group, we don't need to wait for
  158. that to complete */
  159. }
  160. int gdlm_plock_get(lm_lockspace_t *lockspace, struct lm_lockname *name,
  161. struct file *file, struct file_lock *fl)
  162. {
  163. return -ENOSYS;
  164. }
  165. int gdlm_punlock(lm_lockspace_t *lockspace, struct lm_lockname *name,
  166. struct file *file, struct file_lock *fl)
  167. {
  168. return -ENOSYS;
  169. }
  170. int gdlm_plock(lm_lockspace_t *lockspace, struct lm_lockname *name,
  171. struct file *file, int cmd, struct file_lock *fl)
  172. {
  173. return -ENOSYS;
  174. }
  175. struct lm_lockops gdlm_ops = {
  176. lm_proto_name:"lock_dlm",
  177. lm_mount:gdlm_mount,
  178. lm_others_may_mount:gdlm_others_may_mount,
  179. lm_unmount:gdlm_unmount,
  180. lm_withdraw:gdlm_withdraw,
  181. lm_get_lock:gdlm_get_lock,
  182. lm_put_lock:gdlm_put_lock,
  183. lm_lock:gdlm_lock,
  184. lm_unlock:gdlm_unlock,
  185. lm_plock:gdlm_plock,
  186. lm_punlock:gdlm_punlock,
  187. lm_plock_get:gdlm_plock_get,
  188. lm_cancel:gdlm_cancel,
  189. lm_hold_lvb:gdlm_hold_lvb,
  190. lm_unhold_lvb:gdlm_unhold_lvb,
  191. lm_sync_lvb:gdlm_sync_lvb,
  192. lm_recovery_done:gdlm_recovery_done,
  193. lm_owner:THIS_MODULE,
  194. };