orangefs-mod.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. /*
  2. * (C) 2001 Clemson University and The University of Chicago
  3. *
  4. * Changes by Acxiom Corporation to add proc file handler for pvfs2 client
  5. * parameters, Copyright Acxiom Corporation, 2005.
  6. *
  7. * See COPYING in top-level directory.
  8. */
  9. #include "protocol.h"
  10. #include "orangefs-kernel.h"
  11. #include "orangefs-debugfs.h"
  12. #include "orangefs-sysfs.h"
  13. /* ORANGEFS_VERSION is a ./configure define */
  14. #ifndef ORANGEFS_VERSION
  15. #define ORANGEFS_VERSION "upstream"
  16. #endif
  17. /*
  18. * global variables declared here
  19. */
  20. /* array of client debug keyword/mask values */
  21. struct client_debug_mask *cdm_array;
  22. int cdm_element_count;
  23. char kernel_debug_string[ORANGEFS_MAX_DEBUG_STRING_LEN] = "none";
  24. char client_debug_string[ORANGEFS_MAX_DEBUG_STRING_LEN];
  25. char client_debug_array_string[ORANGEFS_MAX_DEBUG_STRING_LEN];
  26. char *debug_help_string;
  27. int help_string_initialized;
  28. struct dentry *help_file_dentry;
  29. struct dentry *client_debug_dentry;
  30. struct dentry *debug_dir;
  31. int client_verbose_index;
  32. int client_all_index;
  33. struct orangefs_stats g_orangefs_stats;
  34. /* the size of the hash tables for ops in progress */
  35. int hash_table_size = 509;
  36. static ulong module_parm_debug_mask;
  37. __u64 gossip_debug_mask;
  38. struct client_debug_mask client_debug_mask = { NULL, 0, 0 };
  39. unsigned int kernel_mask_set_mod_init; /* implicitly false */
  40. int op_timeout_secs = ORANGEFS_DEFAULT_OP_TIMEOUT_SECS;
  41. int slot_timeout_secs = ORANGEFS_DEFAULT_SLOT_TIMEOUT_SECS;
  42. int dcache_timeout_msecs = 50;
  43. int getattr_timeout_msecs = 50;
  44. MODULE_LICENSE("GPL");
  45. MODULE_AUTHOR("ORANGEFS Development Team");
  46. MODULE_DESCRIPTION("The Linux Kernel VFS interface to ORANGEFS");
  47. MODULE_PARM_DESC(module_parm_debug_mask, "debugging level (see orangefs-debug.h for values)");
  48. MODULE_PARM_DESC(op_timeout_secs, "Operation timeout in seconds");
  49. MODULE_PARM_DESC(slot_timeout_secs, "Slot timeout in seconds");
  50. MODULE_PARM_DESC(hash_table_size,
  51. "size of hash table for operations in progress");
  52. static struct file_system_type orangefs_fs_type = {
  53. .name = "pvfs2",
  54. .mount = orangefs_mount,
  55. .kill_sb = orangefs_kill_sb,
  56. .owner = THIS_MODULE,
  57. };
  58. module_param(hash_table_size, int, 0);
  59. module_param(module_parm_debug_mask, ulong, 0644);
  60. module_param(op_timeout_secs, int, 0);
  61. module_param(slot_timeout_secs, int, 0);
  62. /* synchronizes the request device file */
  63. DEFINE_MUTEX(devreq_mutex);
  64. /*
  65. * Blocks non-priority requests from being queued for servicing. This
  66. * could be used for protecting the request list data structure, but
  67. * for now it's only being used to stall the op addition to the request
  68. * list
  69. */
  70. DEFINE_MUTEX(request_mutex);
  71. /* hash table for storing operations waiting for matching downcall */
  72. struct list_head *htable_ops_in_progress;
  73. DEFINE_SPINLOCK(htable_ops_in_progress_lock);
  74. /* list for queueing upcall operations */
  75. LIST_HEAD(orangefs_request_list);
  76. /* used to protect the above orangefs_request_list */
  77. DEFINE_SPINLOCK(orangefs_request_list_lock);
  78. /* used for incoming request notification */
  79. DECLARE_WAIT_QUEUE_HEAD(orangefs_request_list_waitq);
  80. static int __init orangefs_init(void)
  81. {
  82. int ret = -1;
  83. __u32 i = 0;
  84. /* convert input debug mask to a 64-bit unsigned integer */
  85. gossip_debug_mask = (unsigned long long) module_parm_debug_mask;
  86. /*
  87. * set the kernel's gossip debug string; invalid mask values will
  88. * be ignored.
  89. */
  90. debug_mask_to_string(&gossip_debug_mask, 0);
  91. /* remove any invalid values from the mask */
  92. debug_string_to_mask(kernel_debug_string, &gossip_debug_mask, 0);
  93. /*
  94. * if the mask has a non-zero value, then indicate that the mask
  95. * was set when the kernel module was loaded. The orangefs dev ioctl
  96. * command will look at this boolean to determine if the kernel's
  97. * debug mask should be overwritten when the client-core is started.
  98. */
  99. if (gossip_debug_mask != 0)
  100. kernel_mask_set_mod_init = true;
  101. pr_info("%s: called with debug mask: :%s: :%llx:\n",
  102. __func__,
  103. kernel_debug_string,
  104. (unsigned long long)gossip_debug_mask);
  105. ret = bdi_init(&orangefs_backing_dev_info);
  106. if (ret)
  107. return ret;
  108. if (op_timeout_secs < 0)
  109. op_timeout_secs = 0;
  110. if (slot_timeout_secs < 0)
  111. slot_timeout_secs = 0;
  112. /* initialize global book keeping data structures */
  113. ret = op_cache_initialize();
  114. if (ret < 0)
  115. goto err;
  116. ret = orangefs_inode_cache_initialize();
  117. if (ret < 0)
  118. goto cleanup_op;
  119. htable_ops_in_progress =
  120. kcalloc(hash_table_size, sizeof(struct list_head), GFP_KERNEL);
  121. if (!htable_ops_in_progress) {
  122. gossip_err("Failed to initialize op hashtable");
  123. ret = -ENOMEM;
  124. goto cleanup_inode;
  125. }
  126. /* initialize a doubly linked at each hash table index */
  127. for (i = 0; i < hash_table_size; i++)
  128. INIT_LIST_HEAD(&htable_ops_in_progress[i]);
  129. ret = fsid_key_table_initialize();
  130. if (ret < 0)
  131. goto cleanup_progress_table;
  132. /*
  133. * Build the contents of /sys/kernel/debug/orangefs/debug-help
  134. * from the keywords in the kernel keyword/mask array.
  135. *
  136. * The keywords in the client keyword/mask array are
  137. * unknown at boot time.
  138. *
  139. * orangefs_prepare_debugfs_help_string will be used again
  140. * later to rebuild the debug-help file after the client starts
  141. * and passes along the needed info. The argument signifies
  142. * which time orangefs_prepare_debugfs_help_string is being
  143. * called.
  144. */
  145. ret = orangefs_prepare_debugfs_help_string(1);
  146. if (ret)
  147. goto cleanup_key_table;
  148. ret = orangefs_debugfs_init();
  149. if (ret)
  150. goto debugfs_init_failed;
  151. ret = orangefs_kernel_debug_init();
  152. if (ret)
  153. goto kernel_debug_init_failed;
  154. ret = orangefs_sysfs_init();
  155. if (ret)
  156. goto sysfs_init_failed;
  157. /* Initialize the orangefsdev subsystem. */
  158. ret = orangefs_dev_init();
  159. if (ret < 0) {
  160. gossip_err("%s: could not initialize device subsystem %d!\n",
  161. __func__,
  162. ret);
  163. goto cleanup_device;
  164. }
  165. ret = register_filesystem(&orangefs_fs_type);
  166. if (ret == 0) {
  167. pr_info("orangefs: module version %s loaded\n", ORANGEFS_VERSION);
  168. ret = 0;
  169. goto out;
  170. }
  171. orangefs_sysfs_exit();
  172. cleanup_device:
  173. orangefs_dev_cleanup();
  174. sysfs_init_failed:
  175. kernel_debug_init_failed:
  176. debugfs_init_failed:
  177. orangefs_debugfs_cleanup();
  178. cleanup_key_table:
  179. fsid_key_table_finalize();
  180. cleanup_progress_table:
  181. kfree(htable_ops_in_progress);
  182. cleanup_inode:
  183. orangefs_inode_cache_finalize();
  184. cleanup_op:
  185. op_cache_finalize();
  186. err:
  187. bdi_destroy(&orangefs_backing_dev_info);
  188. out:
  189. return ret;
  190. }
  191. static void __exit orangefs_exit(void)
  192. {
  193. int i = 0;
  194. gossip_debug(GOSSIP_INIT_DEBUG, "orangefs: orangefs_exit called\n");
  195. unregister_filesystem(&orangefs_fs_type);
  196. orangefs_debugfs_cleanup();
  197. orangefs_sysfs_exit();
  198. fsid_key_table_finalize();
  199. orangefs_dev_cleanup();
  200. BUG_ON(!list_empty(&orangefs_request_list));
  201. for (i = 0; i < hash_table_size; i++)
  202. BUG_ON(!list_empty(&htable_ops_in_progress[i]));
  203. orangefs_inode_cache_finalize();
  204. op_cache_finalize();
  205. kfree(htable_ops_in_progress);
  206. bdi_destroy(&orangefs_backing_dev_info);
  207. pr_info("orangefs: module version %s unloaded\n", ORANGEFS_VERSION);
  208. }
  209. /*
  210. * What we do in this function is to walk the list of operations
  211. * that are in progress in the hash table and mark them as purged as well.
  212. */
  213. void purge_inprogress_ops(void)
  214. {
  215. int i;
  216. for (i = 0; i < hash_table_size; i++) {
  217. struct orangefs_kernel_op_s *op;
  218. struct orangefs_kernel_op_s *next;
  219. spin_lock(&htable_ops_in_progress_lock);
  220. list_for_each_entry_safe(op,
  221. next,
  222. &htable_ops_in_progress[i],
  223. list) {
  224. set_op_state_purged(op);
  225. gossip_debug(GOSSIP_DEV_DEBUG,
  226. "%s: op:%s: op_state:%d: process:%s:\n",
  227. __func__,
  228. get_opname_string(op),
  229. op->op_state,
  230. current->comm);
  231. }
  232. spin_unlock(&htable_ops_in_progress_lock);
  233. }
  234. }
  235. module_init(orangefs_init);
  236. module_exit(orangefs_exit);