orangefs-mod.c 7.5 KB
Newer Older
M
Mike Marshall 已提交
1 2 3 4 5 6 7 8 9 10
/*
 * (C) 2001 Clemson University and The University of Chicago
 *
 * Changes by Acxiom Corporation to add proc file handler for pvfs2 client
 * parameters, Copyright Acxiom Corporation, 2005.
 *
 * See COPYING in top-level directory.
 */

#include "protocol.h"
11 12 13
#include "orangefs-kernel.h"
#include "orangefs-debugfs.h"
#include "orangefs-sysfs.h"
M
Mike Marshall 已提交
14

15 16
/* ORANGEFS_VERSION is a ./configure define */
#ifndef ORANGEFS_VERSION
17
#define ORANGEFS_VERSION "upstream"
M
Mike Marshall 已提交
18 19 20 21 22 23 24 25 26 27
#endif

/*
 * global variables declared here
 */

/* array of client debug keyword/mask values */
struct client_debug_mask *cdm_array;
int cdm_element_count;

28 29 30
char kernel_debug_string[ORANGEFS_MAX_DEBUG_STRING_LEN] = "none";
char client_debug_string[ORANGEFS_MAX_DEBUG_STRING_LEN];
char client_debug_array_string[ORANGEFS_MAX_DEBUG_STRING_LEN];
M
Mike Marshall 已提交
31 32 33 34 35 36 37 38

char *debug_help_string;
int help_string_initialized;
struct dentry *help_file_dentry;
struct dentry *client_debug_dentry;
struct dentry *debug_dir;
int client_verbose_index;
int client_all_index;
39
struct orangefs_stats g_orangefs_stats;
M
Mike Marshall 已提交
40 41 42 43 44 45 46 47

/* the size of the hash tables for ops in progress */
int hash_table_size = 509;

static ulong module_parm_debug_mask;
__u64 gossip_debug_mask;
struct client_debug_mask client_debug_mask = { NULL, 0, 0 };
unsigned int kernel_mask_set_mod_init; /* implicitly false */
48 49
int op_timeout_secs = ORANGEFS_DEFAULT_OP_TIMEOUT_SECS;
int slot_timeout_secs = ORANGEFS_DEFAULT_SLOT_TIMEOUT_SECS;
M
Mike Marshall 已提交
50 51

MODULE_LICENSE("GPL");
52 53 54
MODULE_AUTHOR("ORANGEFS Development Team");
MODULE_DESCRIPTION("The Linux Kernel VFS interface to ORANGEFS");
MODULE_PARM_DESC(module_parm_debug_mask, "debugging level (see orangefs-debug.h for values)");
M
Mike Marshall 已提交
55 56 57 58 59
MODULE_PARM_DESC(op_timeout_secs, "Operation timeout in seconds");
MODULE_PARM_DESC(slot_timeout_secs, "Slot timeout in seconds");
MODULE_PARM_DESC(hash_table_size,
		 "size of hash table for operations in progress");

60
static struct file_system_type orangefs_fs_type = {
M
Mike Marshall 已提交
61
	.name = "pvfs2",
62 63
	.mount = orangefs_mount,
	.kill_sb = orangefs_kill_sb,
M
Mike Marshall 已提交
64 65 66 67
	.owner = THIS_MODULE,
};

module_param(hash_table_size, int, 0);
68
module_param(module_parm_debug_mask, ulong, 0644);
M
Mike Marshall 已提交
69 70 71 72
module_param(op_timeout_secs, int, 0);
module_param(slot_timeout_secs, int, 0);

/* synchronizes the request device file */
73
DEFINE_MUTEX(devreq_mutex);
M
Mike Marshall 已提交
74 75

/*
76 77 78 79 80
 * Blocks non-priority requests from being queued for servicing.  This
 * could be used for protecting the request list data structure, but
 * for now it's only being used to stall the op addition to the request
 * list
 */
81
DEFINE_MUTEX(request_mutex);
M
Mike Marshall 已提交
82 83 84 85 86 87

/* hash table for storing operations waiting for matching downcall */
struct list_head *htable_ops_in_progress;
DEFINE_SPINLOCK(htable_ops_in_progress_lock);

/* list for queueing upcall operations */
88
LIST_HEAD(orangefs_request_list);
M
Mike Marshall 已提交
89

90 91
/* used to protect the above orangefs_request_list */
DEFINE_SPINLOCK(orangefs_request_list_lock);
M
Mike Marshall 已提交
92 93

/* used for incoming request notification */
94
DECLARE_WAIT_QUEUE_HEAD(orangefs_request_list_waitq);
M
Mike Marshall 已提交
95

96
static int __init orangefs_init(void)
M
Mike Marshall 已提交
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
{
	int ret = -1;
	__u32 i = 0;

	/* convert input debug mask to a 64-bit unsigned integer */
	gossip_debug_mask = (unsigned long long) module_parm_debug_mask;

	/*
	 * set the kernel's gossip debug string; invalid mask values will
	 * be ignored.
	 */
	debug_mask_to_string(&gossip_debug_mask, 0);

	/* remove any invalid values from the mask */
	debug_string_to_mask(kernel_debug_string, &gossip_debug_mask, 0);

	/*
	 * if the mask has a non-zero value, then indicate that the mask
115
	 * was set when the kernel module was loaded.  The orangefs dev ioctl
M
Mike Marshall 已提交
116 117 118 119 120 121
	 * command will look at this boolean to determine if the kernel's
	 * debug mask should be overwritten when the client-core is started.
	 */
	if (gossip_debug_mask != 0)
		kernel_mask_set_mod_init = true;

M
Mike Marshall 已提交
122 123 124 125
	pr_info("%s: called with debug mask: :%s: :%llx:\n",
		__func__,
		kernel_debug_string,
		(unsigned long long)gossip_debug_mask);
M
Mike Marshall 已提交
126

127
	ret = bdi_init(&orangefs_backing_dev_info);
M
Mike Marshall 已提交
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142

	if (ret)
		return ret;

	if (op_timeout_secs < 0)
		op_timeout_secs = 0;

	if (slot_timeout_secs < 0)
		slot_timeout_secs = 0;

	/* initialize global book keeping data structures */
	ret = op_cache_initialize();
	if (ret < 0)
		goto err;

143
	ret = orangefs_inode_cache_initialize();
M
Mike Marshall 已提交
144
	if (ret < 0)
145
		goto cleanup_op;
M
Mike Marshall 已提交
146 147 148 149 150 151

	htable_ops_in_progress =
	    kcalloc(hash_table_size, sizeof(struct list_head), GFP_KERNEL);
	if (!htable_ops_in_progress) {
		gossip_err("Failed to initialize op hashtable");
		ret = -ENOMEM;
152
		goto cleanup_inode;
M
Mike Marshall 已提交
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
	}

	/* initialize a doubly linked at each hash table index */
	for (i = 0; i < hash_table_size; i++)
		INIT_LIST_HEAD(&htable_ops_in_progress[i]);

	ret = fsid_key_table_initialize();
	if (ret < 0)
		goto cleanup_progress_table;

	/*
	 * Build the contents of /sys/kernel/debug/orangefs/debug-help
	 * from the keywords in the kernel keyword/mask array.
	 *
	 * The keywords in the client keyword/mask array are
	 * unknown at boot time.
	 *
	 * orangefs_prepare_debugfs_help_string will be used again
	 * later to rebuild the debug-help file after the client starts
	 * and passes along the needed info. The argument signifies
	 * which time orangefs_prepare_debugfs_help_string is being
	 * called.
	 */
	ret = orangefs_prepare_debugfs_help_string(1);
	if (ret)
178
		goto cleanup_key_table;
179 180 181 182

	ret = orangefs_debugfs_init();
	if (ret)
		goto debugfs_init_failed;
M
Mike Marshall 已提交
183

184 185 186 187 188 189 190
	ret = orangefs_kernel_debug_init();
	if (ret)
		goto kernel_debug_init_failed;

	ret = orangefs_sysfs_init();
	if (ret)
		goto sysfs_init_failed;
M
Mike Marshall 已提交
191

192 193 194 195 196 197 198 199 200
	/* Initialize the orangefsdev subsystem. */
	ret = orangefs_dev_init();
	if (ret < 0) {
		gossip_err("%s: could not initialize device subsystem %d!\n",
			   __func__,
			   ret);
		goto cleanup_device;
	}

201
	ret = register_filesystem(&orangefs_fs_type);
M
Mike Marshall 已提交
202
	if (ret == 0) {
203
		pr_info("orangefs: module version %s loaded\n", ORANGEFS_VERSION);
204 205
		ret = 0;
		goto out;
M
Mike Marshall 已提交
206 207 208 209
	}

	orangefs_sysfs_exit();

210 211 212
cleanup_device:
	orangefs_dev_cleanup();

213 214 215 216 217 218 219
sysfs_init_failed:

kernel_debug_init_failed:

debugfs_init_failed:
	orangefs_debugfs_cleanup();

220 221
cleanup_key_table:
	fsid_key_table_finalize();
222

M
Mike Marshall 已提交
223 224 225 226
cleanup_progress_table:
	kfree(htable_ops_in_progress);

cleanup_inode:
227
	orangefs_inode_cache_finalize();
M
Mike Marshall 已提交
228 229 230 231 232

cleanup_op:
	op_cache_finalize();

err:
233
	bdi_destroy(&orangefs_backing_dev_info);
M
Mike Marshall 已提交
234 235 236 237 238

out:
	return ret;
}

239
static void __exit orangefs_exit(void)
M
Mike Marshall 已提交
240 241
{
	int i = 0;
242
	gossip_debug(GOSSIP_INIT_DEBUG, "orangefs: orangefs_exit called\n");
M
Mike Marshall 已提交
243

244 245
	unregister_filesystem(&orangefs_fs_type);
	orangefs_debugfs_cleanup();
M
Mike Marshall 已提交
246 247
	orangefs_sysfs_exit();
	fsid_key_table_finalize();
248
	orangefs_dev_cleanup();
249
	BUG_ON(!list_empty(&orangefs_request_list));
M
Mike Marshall 已提交
250
	for (i = 0; i < hash_table_size; i++)
251
		BUG_ON(!list_empty(&htable_ops_in_progress[i]));
M
Mike Marshall 已提交
252

253
	orangefs_inode_cache_finalize();
M
Mike Marshall 已提交
254 255 256 257
	op_cache_finalize();

	kfree(htable_ops_in_progress);

258
	bdi_destroy(&orangefs_backing_dev_info);
M
Mike Marshall 已提交
259

260
	pr_info("orangefs: module version %s unloaded\n", ORANGEFS_VERSION);
M
Mike Marshall 已提交
261 262 263 264 265 266 267 268 269 270 271
}

/*
 * What we do in this function is to walk the list of operations
 * that are in progress in the hash table and mark them as purged as well.
 */
void purge_inprogress_ops(void)
{
	int i;

	for (i = 0; i < hash_table_size; i++) {
272 273
		struct orangefs_kernel_op_s *op;
		struct orangefs_kernel_op_s *next;
M
Mike Marshall 已提交
274

275
		spin_lock(&htable_ops_in_progress_lock);
M
Mike Marshall 已提交
276 277 278 279 280
		list_for_each_entry_safe(op,
					 next,
					 &htable_ops_in_progress[i],
					 list) {
			set_op_state_purged(op);
281 282 283 284 285 286
			gossip_debug(GOSSIP_DEV_DEBUG,
				     "%s: op:%s: op_state:%d: process:%s:\n",
				     __func__,
				     get_opname_string(op),
				     op->op_state,
				     current->comm);
M
Mike Marshall 已提交
287
		}
288
		spin_unlock(&htable_ops_in_progress_lock);
M
Mike Marshall 已提交
289 290 291
	}
}

292 293
module_init(orangefs_init);
module_exit(orangefs_exit);