// SPDX-License-Identifier: GPL-2.0
/*
 * What:		/sys/kernel/debug/orangefs/debug-help
 * Date:		June 2015
 * Contact:		Mike Marshall <hubcap@omnibond.com>
 * Description:
 * 			List of client and kernel debug keywords.
 *
 *
 * What:		/sys/kernel/debug/orangefs/client-debug
 * Date:		June 2015
 * Contact:		Mike Marshall <hubcap@omnibond.com>
 * Description:
 * 			Debug setting for "the client", the userspace
 * 			helper for the kernel module.
 *
 *
 * What:		/sys/kernel/debug/orangefs/kernel-debug
 * Date:		June 2015
 * Contact:		Mike Marshall <hubcap@omnibond.com>
 * Description:
 * 			Debug setting for the orangefs kernel module.
 *
 * 			Any of the keywords, or comma-separated lists
 * 			of keywords, from debug-help can be catted to
 * 			client-debug or kernel-debug.
 *
 * 			"none", "all" and "verbose" are special keywords
 * 			for client-debug. Setting client-debug to "all"
 * 			is kind of like trying to drink water from a
 * 			fire hose, "verbose" triggers most of the same
 * 			output except for the constant flow of output
 * 			from the main wait loop.
 *
 * 			"none" and "all" are similar settings for kernel-debug
 * 			no need for a "verbose".
 */
#include <linux/debugfs.h>
#include <linux/slab.h>

#include <linux/uaccess.h>

#include "orangefs-debugfs.h"
#include "protocol.h"
#include "orangefs-kernel.h"

#define DEBUG_HELP_STRING_SIZE 4096
#define HELP_STRING_UNINITIALIZED \
	"Client Debug Keywords are unknown until the first time\n" \
	"the client is started after boot.\n"
#define ORANGEFS_KMOD_DEBUG_HELP_FILE "debug-help"
#define ORANGEFS_KMOD_DEBUG_FILE "kernel-debug"
#define ORANGEFS_CLIENT_DEBUG_FILE "client-debug"
#define ORANGEFS_VERBOSE "verbose"
#define ORANGEFS_ALL "all"

/*
 * An array of client_debug_mask will be built to hold debug keyword/mask
 * values fetched from userspace.
 */
struct client_debug_mask {
	char *keyword;
	__u64 mask1;
	__u64 mask2;
};

static int orangefs_kernel_debug_init(void);

static int orangefs_debug_help_open(struct inode *, struct file *);
static void *help_start(struct seq_file *, loff_t *);
static void *help_next(struct seq_file *, void *, loff_t *);
static void help_stop(struct seq_file *, void *);
static int help_show(struct seq_file *, void *);

static int orangefs_debug_open(struct inode *, struct file *);

static ssize_t orangefs_debug_read(struct file *,
				 char __user *,
				 size_t,
				 loff_t *);

static ssize_t orangefs_debug_write(struct file *,
				  const char __user *,
				  size_t,
				  loff_t *);

static int orangefs_prepare_cdm_array(char *);
static void debug_mask_to_string(void *, int);
static void do_k_string(void *, int);
static void do_c_string(void *, int);
static int keyword_is_amalgam(char *);
static int check_amalgam_keyword(void *, int);
static void debug_string_to_mask(char *, void *, int);
static void do_c_mask(int, char *, struct client_debug_mask **);
static void do_k_mask(int, char *, __u64 **);

static char kernel_debug_string[ORANGEFS_MAX_DEBUG_STRING_LEN] = "none";
static char *debug_help_string;
static char client_debug_string[ORANGEFS_MAX_DEBUG_STRING_LEN];
static char client_debug_array_string[ORANGEFS_MAX_DEBUG_STRING_LEN];

static struct dentry *help_file_dentry;
static struct dentry *client_debug_dentry;
static struct dentry *debug_dir;

static unsigned int kernel_mask_set_mod_init;
static int orangefs_debug_disabled = 1;
static int help_string_initialized;

static const struct seq_operations help_debug_ops = {
	.start	= help_start,
	.next	= help_next,
	.stop	= help_stop,
	.show	= help_show,
};

static const struct file_operations debug_help_fops = {
	.owner		= THIS_MODULE,
	.open           = orangefs_debug_help_open,
	.read           = seq_read,
	.release        = seq_release,
	.llseek         = seq_lseek,
};

static const struct file_operations kernel_debug_fops = {
	.owner		= THIS_MODULE,
	.open           = orangefs_debug_open,
	.read           = orangefs_debug_read,
	.write		= orangefs_debug_write,
	.llseek         = generic_file_llseek,
};

static int client_all_index;
static int client_verbose_index;

static struct client_debug_mask *cdm_array;
static int cdm_element_count;

static struct client_debug_mask client_debug_mask;

/*
 * Used to protect data in ORANGEFS_KMOD_DEBUG_FILE and
 * ORANGEFS_KMOD_DEBUG_FILE.
 */
static DEFINE_MUTEX(orangefs_debug_lock);

/* Used to protect data in ORANGEFS_KMOD_DEBUG_HELP_FILE */
static DEFINE_MUTEX(orangefs_help_file_lock);

/*
 * initialize kmod debug operations, create orangefs debugfs dir and
 * ORANGEFS_KMOD_DEBUG_HELP_FILE.
 */
int orangefs_debugfs_init(int debug_mask)
{
	int rc = -ENOMEM;

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

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

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

	/*
	 * if the mask has a non-zero value, then indicate that the mask
	 * was set when the kernel module was loaded.  The orangefs dev ioctl
	 * command will look at this boolean to determine if the kernel's
	 * debug mask should be overwritten when the client-core is started.
	 */
	if (orangefs_gossip_debug_mask != 0)
		kernel_mask_set_mod_init = true;

	pr_info("%s: called with debug mask: :%s: :%llx:\n",
		__func__,
		kernel_debug_string,
		(unsigned long long)orangefs_gossip_debug_mask);

	debug_dir = debugfs_create_dir("orangefs", NULL);
	if (!debug_dir) {
		pr_info("%s: debugfs_create_dir failed.\n", __func__);
		goto out;
	}

	help_file_dentry = debugfs_create_file(ORANGEFS_KMOD_DEBUG_HELP_FILE,
				  0444,
				  debug_dir,
				  debug_help_string,
				  &debug_help_fops);
	if (!help_file_dentry) {
		pr_info("%s: debugfs_create_file failed.\n", __func__);
		goto out;
	}

	orangefs_debug_disabled = 0;

	rc = orangefs_kernel_debug_init();

out:

	return rc;
}

/*
 * initialize the kernel-debug file.
 */
static int orangefs_kernel_debug_init(void)
{
	int rc = -ENOMEM;
	struct dentry *ret;
	char *k_buffer = NULL;

	gossip_debug(GOSSIP_DEBUGFS_DEBUG, "%s: start\n", __func__);

	k_buffer = kzalloc(ORANGEFS_MAX_DEBUG_STRING_LEN, GFP_KERNEL);
	if (!k_buffer)
		goto out;

	if (strlen(kernel_debug_string) + 1 < ORANGEFS_MAX_DEBUG_STRING_LEN) {
		strcpy(k_buffer, kernel_debug_string);
		strcat(k_buffer, "\n");
	} else {
		strcpy(k_buffer, "none\n");
		pr_info("%s: overflow 1!\n", __func__);
	}

	ret = debugfs_create_file(ORANGEFS_KMOD_DEBUG_FILE,
				  0444,
				  debug_dir,
				  k_buffer,
				  &kernel_debug_fops);
	if (!ret) {
		pr_info("%s: failed to create %s.\n",
			__func__,
			ORANGEFS_KMOD_DEBUG_FILE);
		goto out;
	}

	rc = 0;

out:

	gossip_debug(GOSSIP_DEBUGFS_DEBUG, "%s: rc:%d:\n", __func__, rc);
	return rc;
}


void orangefs_debugfs_cleanup(void)
{
	debugfs_remove_recursive(debug_dir);
}

/* open ORANGEFS_KMOD_DEBUG_HELP_FILE */
static int orangefs_debug_help_open(struct inode *inode, struct file *file)
{
	int rc = -ENODEV;
	int ret;

	gossip_debug(GOSSIP_DEBUGFS_DEBUG,
		     "orangefs_debug_help_open: start\n");

	if (orangefs_debug_disabled)
		goto out;

	ret = seq_open(file, &help_debug_ops);
	if (ret)
		goto out;

	((struct seq_file *)(file->private_data))->private = inode->i_private;

	rc = 0;

out:
	gossip_debug(GOSSIP_DEBUGFS_DEBUG,
		     "orangefs_debug_help_open: rc:%d:\n",
		     rc);
	return rc;
}

/*
 * I think start always gets called again after stop. Start
 * needs to return NULL when it is done. The whole "payload"
 * in this case is a single (long) string, so by the second
 * time we get to start (pos = 1), we're done.
 */
static void *help_start(struct seq_file *m, loff_t *pos)
{
	void *payload = NULL;

	gossip_debug(GOSSIP_DEBUGFS_DEBUG, "help_start: start\n");

	mutex_lock(&orangefs_help_file_lock);

	if (*pos == 0)
		payload = m->private;

	return payload;
}

static void *help_next(struct seq_file *m, void *v, loff_t *pos)
{
	(*pos)++;
	gossip_debug(GOSSIP_DEBUGFS_DEBUG, "help_next: start\n");

	return NULL;
}

static void help_stop(struct seq_file *m, void *p)
{
	gossip_debug(GOSSIP_DEBUGFS_DEBUG, "help_stop: start\n");
	mutex_unlock(&orangefs_help_file_lock);
}

static int help_show(struct seq_file *m, void *v)
{
	gossip_debug(GOSSIP_DEBUGFS_DEBUG, "help_show: start\n");

	seq_puts(m, v);

	return 0;
}

/*
 * initialize the client-debug file.
 */
static int orangefs_client_debug_init(void)
{

	int rc = -ENOMEM;
	char *c_buffer = NULL;

	gossip_debug(GOSSIP_DEBUGFS_DEBUG, "%s: start\n", __func__);

	c_buffer = kzalloc(ORANGEFS_MAX_DEBUG_STRING_LEN, GFP_KERNEL);
	if (!c_buffer)
		goto out;

	if (strlen(client_debug_string) + 1 < ORANGEFS_MAX_DEBUG_STRING_LEN) {
		strcpy(c_buffer, client_debug_string);
		strcat(c_buffer, "\n");
	} else {
		strcpy(c_buffer, "none\n");
		pr_info("%s: overflow! 2\n", __func__);
	}

	client_debug_dentry = debugfs_create_file(ORANGEFS_CLIENT_DEBUG_FILE,
						  0444,
						  debug_dir,
						  c_buffer,
						  &kernel_debug_fops);
	if (!client_debug_dentry) {
		pr_info("%s: failed to create updated %s.\n",
			__func__,
			ORANGEFS_CLIENT_DEBUG_FILE);
		goto out;
	}

	rc = 0;

out:

	gossip_debug(GOSSIP_DEBUGFS_DEBUG, "%s: rc:%d:\n", __func__, rc);
	return rc;
}

/* open ORANGEFS_KMOD_DEBUG_FILE or ORANGEFS_CLIENT_DEBUG_FILE.*/
static int orangefs_debug_open(struct inode *inode, struct file *file)
{
	int rc = -ENODEV;

	gossip_debug(GOSSIP_DEBUGFS_DEBUG,
		     "%s: orangefs_debug_disabled: %d\n",
		     __func__,
		     orangefs_debug_disabled);

	if (orangefs_debug_disabled)
		goto out;

	rc = 0;
	mutex_lock(&orangefs_debug_lock);
	file->private_data = inode->i_private;
	mutex_unlock(&orangefs_debug_lock);

out:
	gossip_debug(GOSSIP_DEBUGFS_DEBUG,
		     "orangefs_debug_open: rc: %d\n",
		     rc);
	return rc;
}

static ssize_t orangefs_debug_read(struct file *file,
				 char __user *ubuf,
				 size_t count,
				 loff_t *ppos)
{
	char *buf;
	int sprintf_ret;
	ssize_t read_ret = -ENOMEM;

	gossip_debug(GOSSIP_DEBUGFS_DEBUG, "orangefs_debug_read: start\n");

	buf = kmalloc(ORANGEFS_MAX_DEBUG_STRING_LEN, GFP_KERNEL);
	if (!buf)
		goto out;

	mutex_lock(&orangefs_debug_lock);
	sprintf_ret = sprintf(buf, "%s", (char *)file->private_data);
	mutex_unlock(&orangefs_debug_lock);

	read_ret = simple_read_from_buffer(ubuf, count, ppos, buf, sprintf_ret);

	kfree(buf);

out:
	gossip_debug(GOSSIP_DEBUGFS_DEBUG,
		     "orangefs_debug_read: ret: %zu\n",
		     read_ret);

	return read_ret;
}

static ssize_t orangefs_debug_write(struct file *file,
				  const char __user *ubuf,
				  size_t count,
				  loff_t *ppos)
{
	char *buf;
	int rc = -EFAULT;
	size_t silly = 0;
	char *debug_string;
	struct orangefs_kernel_op_s *new_op = NULL;
	struct client_debug_mask c_mask = { NULL, 0, 0 };
	char *s;

	gossip_debug(GOSSIP_DEBUGFS_DEBUG,
		"orangefs_debug_write: %pD\n",
		file);

	if (count == 0)
		return 0;

	/*
	 * Thwart users who try to jamb a ridiculous number
	 * of bytes into the debug file...
	 */
	if (count > ORANGEFS_MAX_DEBUG_STRING_LEN + 1) {
		silly = count;
		count = ORANGEFS_MAX_DEBUG_STRING_LEN + 1;
	}

	buf = kzalloc(ORANGEFS_MAX_DEBUG_STRING_LEN, GFP_KERNEL);
	if (!buf)
		goto out;

	if (copy_from_user(buf, ubuf, count - 1)) {
		gossip_debug(GOSSIP_DEBUGFS_DEBUG,
			     "%s: copy_from_user failed!\n",
			     __func__);
		goto out;
	}

	/*
	 * Map the keyword string from userspace into a valid debug mask.
	 * The mapping process involves mapping the human-inputted string
	 * into a valid mask, and then rebuilding the string from the
	 * verified valid mask.
	 *
	 * A service operation is required to set a new client-side
	 * debug mask.
	 */
	if (!strcmp(file->f_path.dentry->d_name.name,
		    ORANGEFS_KMOD_DEBUG_FILE)) {
		debug_string_to_mask(buf, &orangefs_gossip_debug_mask, 0);
		debug_mask_to_string(&orangefs_gossip_debug_mask, 0);
		debug_string = kernel_debug_string;
		gossip_debug(GOSSIP_DEBUGFS_DEBUG,
			     "New kernel debug string is %s\n",
			     kernel_debug_string);
	} else {
		/* Can't reset client debug mask if client is not running. */
		if (is_daemon_in_service()) {
			pr_info("%s: Client not running :%d:\n",
				__func__,
				is_daemon_in_service());
			goto out;
		}

		debug_string_to_mask(buf, &c_mask, 1);
		debug_mask_to_string(&c_mask, 1);
		debug_string = client_debug_string;

		new_op = op_alloc(ORANGEFS_VFS_OP_PARAM);
		if (!new_op) {
			pr_info("%s: op_alloc failed!\n", __func__);
			goto out;
		}

		new_op->upcall.req.param.op =
			ORANGEFS_PARAM_REQUEST_OP_TWO_MASK_VALUES;
		new_op->upcall.req.param.type = ORANGEFS_PARAM_REQUEST_SET;
		memset(new_op->upcall.req.param.s_value,
		       0,
		       ORANGEFS_MAX_DEBUG_STRING_LEN);
		sprintf(new_op->upcall.req.param.s_value,
			"%llx %llx\n",
			c_mask.mask1,
			c_mask.mask2);

		/* service_operation returns 0 on success... */
		rc = service_operation(new_op,
				       "orangefs_param",
					ORANGEFS_OP_INTERRUPTIBLE);

		if (rc)
			gossip_debug(GOSSIP_DEBUGFS_DEBUG,
				     "%s: service_operation failed! rc:%d:\n",
				     __func__,
				     rc);

		op_release(new_op);
	}

	mutex_lock(&orangefs_debug_lock);
	s = file_inode(file)->i_private;
	memset(s, 0, ORANGEFS_MAX_DEBUG_STRING_LEN);
	sprintf(s, "%s\n", debug_string);
	mutex_unlock(&orangefs_debug_lock);

	*ppos += count;
	if (silly)
		rc = silly;
	else
		rc = count;

out:
	gossip_debug(GOSSIP_DEBUGFS_DEBUG,
		     "orangefs_debug_write: rc: %d\n",
		     rc);
	kfree(buf);
	return rc;
}

/*
 * After obtaining a string representation of the client's debug
 * keywords and their associated masks, this function is called to build an
 * array of these values.
 */
static int orangefs_prepare_cdm_array(char *debug_array_string)
{
	int i;
	int rc = -EINVAL;
	char *cds_head = NULL;
	char *cds_delimiter = NULL;
	int keyword_len = 0;

	gossip_debug(GOSSIP_UTILS_DEBUG, "%s: start\n", __func__);

	/*
	 * figure out how many elements the cdm_array needs.
	 */
	for (i = 0; i < strlen(debug_array_string); i++)
		if (debug_array_string[i] == '\n')
			cdm_element_count++;

	if (!cdm_element_count) {
		pr_info("No elements in client debug array string!\n");
		goto out;
	}

	cdm_array = kcalloc(cdm_element_count, sizeof(*cdm_array), GFP_KERNEL);
	if (!cdm_array) {
		rc = -ENOMEM;
		goto out;
	}

	cds_head = debug_array_string;

	for (i = 0; i < cdm_element_count; i++) {
		cds_delimiter = strchr(cds_head, '\n');
		*cds_delimiter = '\0';

		keyword_len = strcspn(cds_head, " ");

		cdm_array[i].keyword = kzalloc(keyword_len + 1, GFP_KERNEL);
		if (!cdm_array[i].keyword) {
			rc = -ENOMEM;
			goto out;
		}

		sscanf(cds_head,
		       "%s %llx %llx",
		       cdm_array[i].keyword,
		       (unsigned long long *)&(cdm_array[i].mask1),
		       (unsigned long long *)&(cdm_array[i].mask2));

		if (!strcmp(cdm_array[i].keyword, ORANGEFS_VERBOSE))
			client_verbose_index = i;

		if (!strcmp(cdm_array[i].keyword, ORANGEFS_ALL))
			client_all_index = i;

		cds_head = cds_delimiter + 1;
	}

	rc = cdm_element_count;

	gossip_debug(GOSSIP_UTILS_DEBUG, "%s: rc:%d:\n", __func__, rc);

out:

	return rc;

}

/*
 * /sys/kernel/debug/orangefs/debug-help can be catted to
 * see all the available kernel and client debug keywords.
 *
 * When orangefs.ko initializes, we have no idea what keywords the
 * client supports, nor their associated masks.
 *
 * We pass through this function once at module-load and stamp a
 * boilerplate "we don't know" message for the client in the
 * debug-help file. We pass through here again when the client
 * starts and then we can fill out the debug-help file fully.
 *
 * The client might be restarted any number of times between
 * module reloads, we only build the debug-help file the first time.
 */
int orangefs_prepare_debugfs_help_string(int at_boot)
{
	char *client_title = "Client Debug Keywords:\n";
	char *kernel_title = "Kernel Debug Keywords:\n";
	size_t string_size =  DEBUG_HELP_STRING_SIZE;
	size_t result_size;
	size_t i;
	char *new;
	int rc = -EINVAL;

	gossip_debug(GOSSIP_UTILS_DEBUG, "%s: start\n", __func__);

	if (at_boot)
		client_title = HELP_STRING_UNINITIALIZED;

	/* build a new debug_help_string. */
	new = kzalloc(DEBUG_HELP_STRING_SIZE, GFP_KERNEL);
	if (!new) {
		rc = -ENOMEM;
		goto out;
	}

	/*
	 * strlcat(dst, src, size) will append at most
	 * "size - strlen(dst) - 1" bytes of src onto dst,
	 * null terminating the result, and return the total
	 * length of the string it tried to create.
	 *
	 * We'll just plow through here building our new debug
	 * help string and let strlcat take care of assuring that
	 * dst doesn't overflow.
	 */
	strlcat(new, client_title, string_size);

	if (!at_boot) {

                /*
		 * fill the client keyword/mask array and remember
		 * how many elements there were.
		 */
		cdm_element_count =
			orangefs_prepare_cdm_array(client_debug_array_string);
		if (cdm_element_count <= 0) {
			kfree(new);
			goto out;
		}

		for (i = 0; i < cdm_element_count; i++) {
			strlcat(new, "\t", string_size);
			strlcat(new, cdm_array[i].keyword, string_size);
			strlcat(new, "\n", string_size);
		}
	}

	strlcat(new, "\n", string_size);
	strlcat(new, kernel_title, string_size);

	for (i = 0; i < num_kmod_keyword_mask_map; i++) {
		strlcat(new, "\t", string_size);
		strlcat(new, s_kmod_keyword_mask_map[i].keyword, string_size);
		result_size = strlcat(new, "\n", string_size);
	}

	/* See if we tried to put too many bytes into "new"... */
	if (result_size >= string_size) {
		kfree(new);
		goto out;
	}

	if (at_boot) {
		debug_help_string = new;
	} else {
		mutex_lock(&orangefs_help_file_lock);
		memset(debug_help_string, 0, DEBUG_HELP_STRING_SIZE);
		strlcat(debug_help_string, new, string_size);
		mutex_unlock(&orangefs_help_file_lock);
	}

	rc = 0;

out:	return rc;

}

/*
 * kernel = type 0
 * client = type 1
 */
static void debug_mask_to_string(void *mask, int type)
{
	int i;
	int len = 0;
	char *debug_string;
	int element_count = 0;

	gossip_debug(GOSSIP_UTILS_DEBUG, "%s: start\n", __func__);

	if (type) {
		debug_string = client_debug_string;
		element_count = cdm_element_count;
	} else {
		debug_string = kernel_debug_string;
		element_count = num_kmod_keyword_mask_map;
	}

	memset(debug_string, 0, ORANGEFS_MAX_DEBUG_STRING_LEN);

	/*
	 * Some keywords, like "all" or "verbose", are amalgams of
	 * numerous other keywords. Make a special check for those
	 * before grinding through the whole mask only to find out
	 * later...
	 */
	if (check_amalgam_keyword(mask, type))
		goto out;

	/* Build the debug string. */
	for (i = 0; i < element_count; i++)
		if (type)
			do_c_string(mask, i);
		else
			do_k_string(mask, i);

	len = strlen(debug_string);

	if ((len) && (type))
		client_debug_string[len - 1] = '\0';
	else if (len)
		kernel_debug_string[len - 1] = '\0';
	else if (type)
		strcpy(client_debug_string, "none");
	else
		strcpy(kernel_debug_string, "none");

out:
gossip_debug(GOSSIP_UTILS_DEBUG, "%s: string:%s:\n", __func__, debug_string);

	return;

}

static void do_k_string(void *k_mask, int index)
{
	__u64 *mask = (__u64 *) k_mask;

	if (keyword_is_amalgam((char *) s_kmod_keyword_mask_map[index].keyword))
		goto out;

	if (*mask & s_kmod_keyword_mask_map[index].mask_val) {
		if ((strlen(kernel_debug_string) +
		     strlen(s_kmod_keyword_mask_map[index].keyword))
			< ORANGEFS_MAX_DEBUG_STRING_LEN - 1) {
				strcat(kernel_debug_string,
				       s_kmod_keyword_mask_map[index].keyword);
				strcat(kernel_debug_string, ",");
			} else {
				gossip_err("%s: overflow!\n", __func__);
				strcpy(kernel_debug_string, ORANGEFS_ALL);
				goto out;
			}
	}

out:

	return;
}

static void do_c_string(void *c_mask, int index)
{
	struct client_debug_mask *mask = (struct client_debug_mask *) c_mask;

	if (keyword_is_amalgam(cdm_array[index].keyword))
		goto out;

	if ((mask->mask1 & cdm_array[index].mask1) ||
	    (mask->mask2 & cdm_array[index].mask2)) {
		if ((strlen(client_debug_string) +
		     strlen(cdm_array[index].keyword) + 1)
			< ORANGEFS_MAX_DEBUG_STRING_LEN - 2) {
				strcat(client_debug_string,
				       cdm_array[index].keyword);
				strcat(client_debug_string, ",");
			} else {
				gossip_err("%s: overflow!\n", __func__);
				strcpy(client_debug_string, ORANGEFS_ALL);
				goto out;
			}
	}
out:
	return;
}

static int keyword_is_amalgam(char *keyword)
{
	int rc = 0;

	if ((!strcmp(keyword, ORANGEFS_ALL)) || (!strcmp(keyword, ORANGEFS_VERBOSE)))
		rc = 1;

	return rc;
}

/*
 * kernel = type 0
 * client = type 1
 *
 * return 1 if we found an amalgam.
 */
static int check_amalgam_keyword(void *mask, int type)
{
	__u64 *k_mask;
	struct client_debug_mask *c_mask;
	int k_all_index = num_kmod_keyword_mask_map - 1;
	int rc = 0;

	if (type) {
		c_mask = (struct client_debug_mask *) mask;

		if ((c_mask->mask1 == cdm_array[client_all_index].mask1) &&
		    (c_mask->mask2 == cdm_array[client_all_index].mask2)) {
			strcpy(client_debug_string, ORANGEFS_ALL);
			rc = 1;
			goto out;
		}

		if ((c_mask->mask1 == cdm_array[client_verbose_index].mask1) &&
		    (c_mask->mask2 == cdm_array[client_verbose_index].mask2)) {
			strcpy(client_debug_string, ORANGEFS_VERBOSE);
			rc = 1;
			goto out;
		}

	} else {
		k_mask = (__u64 *) mask;

		if (*k_mask >= s_kmod_keyword_mask_map[k_all_index].mask_val) {
			strcpy(kernel_debug_string, ORANGEFS_ALL);
			rc = 1;
			goto out;
		}
	}

out:

	return rc;
}

/*
 * kernel = type 0
 * client = type 1
 */
static void debug_string_to_mask(char *debug_string, void *mask, int type)
{
	char *unchecked_keyword;
	int i;
	char *strsep_fodder = kstrdup(debug_string, GFP_KERNEL);
	char *original_pointer;
	int element_count = 0;
	struct client_debug_mask *c_mask = NULL;
	__u64 *k_mask = NULL;

	gossip_debug(GOSSIP_UTILS_DEBUG, "%s: start\n", __func__);

	if (type) {
		c_mask = (struct client_debug_mask *)mask;
		element_count = cdm_element_count;
	} else {
		k_mask = (__u64 *)mask;
		*k_mask = 0;
		element_count = num_kmod_keyword_mask_map;
	}

	original_pointer = strsep_fodder;
	while ((unchecked_keyword = strsep(&strsep_fodder, ",")))
		if (strlen(unchecked_keyword)) {
			for (i = 0; i < element_count; i++)
				if (type)
					do_c_mask(i,
						  unchecked_keyword,
						  &c_mask);
				else
					do_k_mask(i,
						  unchecked_keyword,
						  &k_mask);
		}

	kfree(original_pointer);
}

static void do_c_mask(int i, char *unchecked_keyword,
    struct client_debug_mask **sane_mask)
{

	if (!strcmp(cdm_array[i].keyword, unchecked_keyword)) {
		(**sane_mask).mask1 = (**sane_mask).mask1 | cdm_array[i].mask1;
		(**sane_mask).mask2 = (**sane_mask).mask2 | cdm_array[i].mask2;
	}
}

static void do_k_mask(int i, char *unchecked_keyword, __u64 **sane_mask)
{

	if (!strcmp(s_kmod_keyword_mask_map[i].keyword, unchecked_keyword))
		**sane_mask = (**sane_mask) |
				s_kmod_keyword_mask_map[i].mask_val;
}

int orangefs_debugfs_new_client_mask(void __user *arg)
{
	struct dev_mask2_info_s mask2_info = {0};
	int ret;

	ret = copy_from_user(&mask2_info,
			     (void __user *)arg,
			     sizeof(struct dev_mask2_info_s));

	if (ret != 0)
		return -EIO;

	client_debug_mask.mask1 = mask2_info.mask1_value;
	client_debug_mask.mask2 = mask2_info.mask2_value;

	pr_info("%s: client debug mask has been been received "
		":%llx: :%llx:\n",
		__func__,
		(unsigned long long)client_debug_mask.mask1,
		(unsigned long long)client_debug_mask.mask2);

	return ret;
}

int orangefs_debugfs_new_client_string(void __user *arg) 
{
	int ret;

	ret = copy_from_user(&client_debug_array_string,
			     (void __user *)arg,
			     ORANGEFS_MAX_DEBUG_STRING_LEN);

	if (ret != 0) {
		pr_info("%s: CLIENT_STRING: copy_from_user failed\n",
			__func__);
		return -EFAULT;
	}

	/*
	 * The real client-core makes an effort to ensure
	 * that actual strings that aren't too long to fit in
	 * this buffer is what we get here. We're going to use
	 * string functions on the stuff we got, so we'll make
	 * this extra effort to try and keep from
	 * flowing out of this buffer when we use the string
	 * functions, even if somehow the stuff we end up
	 * with here is garbage.
	 */
	client_debug_array_string[ORANGEFS_MAX_DEBUG_STRING_LEN - 1] =
		'\0';

	pr_info("%s: client debug array string has been received.\n",
		__func__);

	if (!help_string_initialized) {

		/* Build a proper debug help string. */
		ret = orangefs_prepare_debugfs_help_string(0);
		if (ret) {
			gossip_err("%s: no debug help string \n",
				   __func__);
			return ret;
		}

	}

	debug_mask_to_string(&client_debug_mask, 1);

	debugfs_remove(client_debug_dentry);

	orangefs_client_debug_init();

	help_string_initialized++;

	return 0;
}

int orangefs_debugfs_new_debug(void __user *arg) 
{
	struct dev_mask_info_s mask_info = {0};
	int ret;

	ret = copy_from_user(&mask_info,
			     (void __user *)arg,
			     sizeof(mask_info));

	if (ret != 0)
		return -EIO;

	if (mask_info.mask_type == KERNEL_MASK) {
		if ((mask_info.mask_value == 0)
		    && (kernel_mask_set_mod_init)) {
			/*
			 * the kernel debug mask was set when the
			 * kernel module was loaded; don't override
			 * it if the client-core was started without
			 * a value for ORANGEFS_KMODMASK.
			 */
			return 0;
		}
		debug_mask_to_string(&mask_info.mask_value,
				     mask_info.mask_type);
		orangefs_gossip_debug_mask = mask_info.mask_value;
		pr_info("%s: kernel debug mask has been modified to "
			":%s: :%llx:\n",
			__func__,
			kernel_debug_string,
			(unsigned long long)orangefs_gossip_debug_mask);
	} else if (mask_info.mask_type == CLIENT_MASK) {
		debug_mask_to_string(&mask_info.mask_value,
				     mask_info.mask_type);
		pr_info("%s: client debug mask has been modified to"
			":%s: :%llx:\n",
			__func__,
			client_debug_string,
			llu(mask_info.mask_value));
	} else {
		gossip_err("Invalid mask type....\n");
		return -EINVAL;
	}

	return ret;
}
