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