locking.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. /*
  2. * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
  3. * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
  4. *
  5. * This copyrighted material is made available to anyone wishing to use,
  6. * modify, copy, or redistribute it subject to the terms and conditions
  7. * of the GNU General Public License version 2.
  8. */
  9. #include <linux/module.h>
  10. #include <linux/init.h>
  11. #include <linux/string.h>
  12. #include <linux/slab.h>
  13. #include <linux/wait.h>
  14. #include <linux/sched.h>
  15. #include <linux/kmod.h>
  16. #include <linux/fs.h>
  17. #include <linux/delay.h>
  18. #include <linux/lm_interface.h>
  19. struct lmh_wrapper {
  20. struct list_head lw_list;
  21. const struct lm_lockops *lw_ops;
  22. };
  23. /* List of registered low-level locking protocols. A file system selects one
  24. of them by name at mount time, e.g. lock_nolock, lock_dlm. */
  25. static LIST_HEAD(lmh_list);
  26. static DEFINE_MUTEX(lmh_lock);
  27. /**
  28. * gfs2_register_lockproto - Register a low-level locking protocol
  29. * @proto: the protocol definition
  30. *
  31. * Returns: 0 on success, -EXXX on failure
  32. */
  33. int gfs2_register_lockproto(const struct lm_lockops *proto)
  34. {
  35. struct lmh_wrapper *lw;
  36. mutex_lock(&lmh_lock);
  37. list_for_each_entry(lw, &lmh_list, lw_list) {
  38. if (!strcmp(lw->lw_ops->lm_proto_name, proto->lm_proto_name)) {
  39. mutex_unlock(&lmh_lock);
  40. printk(KERN_INFO "GFS2: protocol %s already exists\n",
  41. proto->lm_proto_name);
  42. return -EEXIST;
  43. }
  44. }
  45. lw = kzalloc(sizeof(struct lmh_wrapper), GFP_KERNEL);
  46. if (!lw) {
  47. mutex_unlock(&lmh_lock);
  48. return -ENOMEM;
  49. }
  50. lw->lw_ops = proto;
  51. list_add(&lw->lw_list, &lmh_list);
  52. mutex_unlock(&lmh_lock);
  53. return 0;
  54. }
  55. /**
  56. * gfs2_unregister_lockproto - Unregister a low-level locking protocol
  57. * @proto: the protocol definition
  58. *
  59. */
  60. void gfs2_unregister_lockproto(const struct lm_lockops *proto)
  61. {
  62. struct lmh_wrapper *lw;
  63. mutex_lock(&lmh_lock);
  64. list_for_each_entry(lw, &lmh_list, lw_list) {
  65. if (!strcmp(lw->lw_ops->lm_proto_name, proto->lm_proto_name)) {
  66. list_del(&lw->lw_list);
  67. mutex_unlock(&lmh_lock);
  68. kfree(lw);
  69. return;
  70. }
  71. }
  72. mutex_unlock(&lmh_lock);
  73. printk(KERN_WARNING "GFS2: can't unregister lock protocol %s\n",
  74. proto->lm_proto_name);
  75. }
  76. /**
  77. * gfs2_mount_lockproto - Mount a lock protocol
  78. * @proto_name - the name of the protocol
  79. * @table_name - the name of the lock space
  80. * @host_data - data specific to this host
  81. * @cb - the callback to the code using the lock module
  82. * @sdp - The GFS2 superblock
  83. * @min_lvb_size - the mininum LVB size that the caller can deal with
  84. * @flags - LM_MFLAG_*
  85. * @lockstruct - a structure returned describing the mount
  86. *
  87. * Returns: 0 on success, -EXXX on failure
  88. */
  89. int gfs2_mount_lockproto(char *proto_name, char *table_name, char *host_data,
  90. lm_callback_t cb, void *cb_data,
  91. unsigned int min_lvb_size, int flags,
  92. struct lm_lockstruct *lockstruct,
  93. struct kobject *fskobj)
  94. {
  95. struct lmh_wrapper *lw = NULL;
  96. int try = 0;
  97. int error, found;
  98. retry:
  99. mutex_lock(&lmh_lock);
  100. found = 0;
  101. list_for_each_entry(lw, &lmh_list, lw_list) {
  102. if (!strcmp(lw->lw_ops->lm_proto_name, proto_name)) {
  103. found = 1;
  104. break;
  105. }
  106. }
  107. if (!found) {
  108. if (!try && capable(CAP_SYS_MODULE)) {
  109. try = 1;
  110. mutex_unlock(&lmh_lock);
  111. request_module(proto_name);
  112. goto retry;
  113. }
  114. printk(KERN_INFO "GFS2: can't find protocol %s\n", proto_name);
  115. error = -ENOENT;
  116. goto out;
  117. }
  118. if (!try_module_get(lw->lw_ops->lm_owner)) {
  119. try = 0;
  120. mutex_unlock(&lmh_lock);
  121. msleep(1000);
  122. goto retry;
  123. }
  124. error = lw->lw_ops->lm_mount(table_name, host_data, cb, cb_data,
  125. min_lvb_size, flags, lockstruct, fskobj);
  126. if (error)
  127. module_put(lw->lw_ops->lm_owner);
  128. out:
  129. mutex_unlock(&lmh_lock);
  130. return error;
  131. }
  132. void gfs2_unmount_lockproto(struct lm_lockstruct *lockstruct)
  133. {
  134. mutex_lock(&lmh_lock);
  135. lockstruct->ls_ops->lm_unmount(lockstruct->ls_lockspace);
  136. if (lockstruct->ls_ops->lm_owner)
  137. module_put(lockstruct->ls_ops->lm_owner);
  138. mutex_unlock(&lmh_lock);
  139. }
  140. /**
  141. * gfs2_withdraw_lockproto - abnormally unmount a lock module
  142. * @lockstruct: the lockstruct passed into mount
  143. *
  144. */
  145. void gfs2_withdraw_lockproto(struct lm_lockstruct *lockstruct)
  146. {
  147. mutex_lock(&lmh_lock);
  148. lockstruct->ls_ops->lm_withdraw(lockstruct->ls_lockspace);
  149. if (lockstruct->ls_ops->lm_owner)
  150. module_put(lockstruct->ls_ops->lm_owner);
  151. mutex_unlock(&lmh_lock);
  152. }
  153. EXPORT_SYMBOL_GPL(gfs2_register_lockproto);
  154. EXPORT_SYMBOL_GPL(gfs2_unregister_lockproto);