Release 4.7 drivers/staging/lustre/lnet/libcfs/module.c
  
  
/*
 * GPL HEADER START
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 only,
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License version 2 for more details (a copy is included
 * in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU General Public License
 * version 2 along with this program; If not, see
 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 *
 * GPL HEADER END
 */
/*
 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
 * Use is subject to license terms.
 *
 * Copyright (c) 2012, 2015 Intel Corporation.
 */
/*
 * This file is part of Lustre, http://www.lustre.org/
 * Lustre is a trademark of Sun Microsystems, Inc.
 */
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/string.h>
#include <linux/stat.h>
#include <linux/errno.h>
#include <linux/unistd.h>
#include <net/sock.h>
#include <linux/uio.h>
#include <linux/uaccess.h>
#include <linux/fs.h>
#include <linux/file.h>
#include <linux/list.h>
#include <linux/sysctl.h>
#include <linux/debugfs.h>
# define DEBUG_SUBSYSTEM S_LNET
#include "../../include/linux/libcfs/libcfs.h"
#include <asm/div64.h>
#include "../../include/linux/libcfs/libcfs_crypto.h"
#include "../../include/linux/lnet/lib-lnet.h"
#include "../../include/linux/lnet/lib-dlc.h"
#include "../../include/linux/lnet/lnet.h"
#include "tracefile.h"
static struct dentry *lnet_debugfs_root;
static DECLARE_RWSEM(ioctl_list_sem);
static LIST_HEAD(ioctl_list);
int libcfs_register_ioctl(struct libcfs_ioctl_handler *hand)
{
	int rc = 0;
	down_write(&ioctl_list_sem);
	if (!list_empty(&hand->item))
		rc = -EBUSY;
	else
		list_add_tail(&hand->item, &ioctl_list);
	up_write(&ioctl_list_sem);
	return rc;
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| peng tao | peng tao | 58 | 100.00% | 1 | 100.00% | 
 | Total | 58 | 100.00% | 1 | 100.00% | 
EXPORT_SYMBOL(libcfs_register_ioctl);
int libcfs_deregister_ioctl(struct libcfs_ioctl_handler *hand)
{
	int rc = 0;
	down_write(&ioctl_list_sem);
	if (list_empty(&hand->item))
		rc = -ENOENT;
	else
		list_del_init(&hand->item);
	up_write(&ioctl_list_sem);
	return rc;
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| peng tao | peng tao | 54 | 100.00% | 1 | 100.00% | 
 | Total | 54 | 100.00% | 1 | 100.00% | 
EXPORT_SYMBOL(libcfs_deregister_ioctl);
int libcfs_ioctl(unsigned long cmd, void __user *uparam)
{
	struct libcfs_ioctl_data *data = NULL;
	struct libcfs_ioctl_hdr *hdr;
	int err;
	/* 'cmd' and permissions get checked in our arch-specific caller */
	err = libcfs_ioctl_getdata(&hdr, uparam);
	if (err) {
		CDEBUG_LIMIT(D_ERROR,
			     "libcfs ioctl: data header error %d\n", err);
		return err;
	}
	if (hdr->ioc_version == LIBCFS_IOCTL_VERSION) {
		/*
                 * The libcfs_ioctl_data_adjust() function performs adjustment
                 * operations on the libcfs_ioctl_data structure to make
                 * it usable by the code.  This doesn't need to be called
                 * for new data structures added.
                 */
		data = container_of(hdr, struct libcfs_ioctl_data, ioc_hdr);
		err = libcfs_ioctl_data_adjust(data);
		if (err)
			goto out;
	}
	CDEBUG(D_IOCTL, "libcfs ioctl cmd %lu\n", cmd);
	switch (cmd) {
	case IOC_LIBCFS_CLEAR_DEBUG:
		libcfs_debug_clear_buffer();
		break;
	case IOC_LIBCFS_MARK_DEBUG:
		if (!data || !data->ioc_inlbuf1 ||
		    data->ioc_inlbuf1[data->ioc_inllen1 - 1] != '\0') {
			err = -EINVAL;
			goto out;
		}
		libcfs_debug_mark_buffer(data->ioc_inlbuf1);
		break;
	default: {
		struct libcfs_ioctl_handler *hand;
		err = -EINVAL;
		down_read(&ioctl_list_sem);
		list_for_each_entry(hand, &ioctl_list, item) {
			err = hand->handle_ioctl(cmd, hdr);
			if (err == -EINVAL)
				continue;
			if (!err) {
				if (copy_to_user(uparam, hdr, hdr->ioc_len))
					err = -EFAULT;
			}
			break;
		}
		up_read(&ioctl_list_sem);
		break; }
	}
out:
	LIBCFS_FREE(hdr, hdr->ioc_len);
	return err;
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| peng tao | peng tao | 125 | 48.83% | 1 | 6.67% | 
| liang zhen | liang zhen | 68 | 26.56% | 7 | 46.67% | 
| amir shehata | amir shehata | 46 | 17.97% | 2 | 13.33% | 
| john l. hammond | john l. hammond | 10 | 3.91% | 1 | 6.67% | 
| james simmons | james simmons | 3 | 1.17% | 1 | 6.67% | 
| greg kroah-hartman | greg kroah-hartman | 2 | 0.78% | 1 | 6.67% | 
| m. vefa bicakci | m. vefa bicakci | 1 | 0.39% | 1 | 6.67% | 
| oleg drokin | oleg drokin | 1 | 0.39% | 1 | 6.67% | 
 | Total | 256 | 100.00% | 15 | 100.00% | 
int lprocfs_call_handler(void *data, int write, loff_t *ppos,
			 void __user *buffer, size_t *lenp,
			 int (*handler)(void *data, int write, loff_t pos,
					void __user *buffer, int len))
{
	int rc = handler(data, write, *ppos, buffer, *lenp);
	if (rc < 0)
		return rc;
	if (write) {
		*ppos += *lenp;
	} else {
		*lenp = rc;
		*ppos += rc;
	}
	return 0;
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| oleg drokin | oleg drokin | 79 | 75.24% | 1 | 25.00% | 
| peng tao | peng tao | 22 | 20.95% | 1 | 25.00% | 
| matthew tyler | matthew tyler | 3 | 2.86% | 1 | 25.00% | 
| james simmons | james simmons | 1 | 0.95% | 1 | 25.00% | 
 | Total | 105 | 100.00% | 4 | 100.00% | 
EXPORT_SYMBOL(lprocfs_call_handler);
static int __proc_dobitmasks(void *data, int write,
			     loff_t pos, void __user *buffer, int nob)
{
	const int     tmpstrlen = 512;
	char	 *tmpstr;
	int	   rc;
	unsigned int *mask = data;
	int	   is_subsys = (mask == &libcfs_subsystem_debug) ? 1 : 0;
	int	   is_printk = (mask == &libcfs_printk) ? 1 : 0;
	rc = cfs_trace_allocate_string_buffer(&tmpstr, tmpstrlen);
	if (rc < 0)
		return rc;
	if (!write) {
		libcfs_debug_mask2str(tmpstr, tmpstrlen, *mask, is_subsys);
		rc = strlen(tmpstr);
		if (pos >= rc) {
			rc = 0;
		} else {
			rc = cfs_trace_copyout_string(buffer, nob,
						      tmpstr + pos, "\n");
		}
	} else {
		rc = cfs_trace_copyin_string(tmpstr, tmpstrlen, buffer, nob);
		if (rc < 0) {
			kfree(tmpstr);
			return rc;
		}
		rc = libcfs_debug_str2mask(mask, tmpstr, is_subsys);
		/* Always print LBUG/LASSERT to console, so keep this mask */
		if (is_printk)
			*mask |= D_EMERG;
	}
	kfree(tmpstr);
	return rc;
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| oleg drokin | oleg drokin | 139 | 66.83% | 1 | 33.33% | 
| peng tao | peng tao | 67 | 32.21% | 1 | 33.33% | 
| shivani bhardwaj | shivani bhardwaj | 2 | 0.96% | 1 | 33.33% | 
 | Total | 208 | 100.00% | 3 | 100.00% | 
static int proc_dobitmasks(struct ctl_table *table, int write,
			   void __user *buffer, size_t *lenp, loff_t *ppos)
{
	return lprocfs_call_handler(table->data, write, ppos, buffer, lenp,
				    __proc_dobitmasks);
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| oleg drokin | oleg drokin | 26 | 57.78% | 1 | 33.33% | 
| matthew tyler | matthew tyler | 18 | 40.00% | 1 | 33.33% | 
| james simmons | james simmons | 1 | 2.22% | 1 | 33.33% | 
 | Total | 45 | 100.00% | 3 | 100.00% | 
static int __proc_dump_kernel(void *data, int write,
			      loff_t pos, void __user *buffer, int nob)
{
	if (!write)
		return 0;
	return cfs_trace_dump_debug_buffer_usrstr(buffer, nob);
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| matthew tyler | matthew tyler | 24 | 60.00% | 1 | 50.00% | 
| oleg drokin | oleg drokin | 16 | 40.00% | 1 | 50.00% | 
 | Total | 40 | 100.00% | 2 | 100.00% | 
static int proc_dump_kernel(struct ctl_table *table, int write,
			    void __user *buffer, size_t *lenp, loff_t *ppos)
{
	return lprocfs_call_handler(table->data, write, ppos, buffer, lenp,
				    __proc_dump_kernel);
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| oleg drokin | oleg drokin | 39 | 86.67% | 1 | 33.33% | 
| matthew tyler | matthew tyler | 5 | 11.11% | 1 | 33.33% | 
| james simmons | james simmons | 1 | 2.22% | 1 | 33.33% | 
 | Total | 45 | 100.00% | 3 | 100.00% | 
static int __proc_daemon_file(void *data, int write,
			      loff_t pos, void __user *buffer, int nob)
{
	if (!write) {
		int len = strlen(cfs_tracefile);
		if (pos >= len)
			return 0;
		return cfs_trace_copyout_string(buffer, nob,
						cfs_tracefile + pos, "\n");
	}
	return cfs_trace_daemon_command_usrstr(buffer, nob);
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| matthew tyler | matthew tyler | 56 | 80.00% | 1 | 50.00% | 
| oleg drokin | oleg drokin | 14 | 20.00% | 1 | 50.00% | 
 | Total | 70 | 100.00% | 2 | 100.00% | 
static int proc_daemon_file(struct ctl_table *table, int write,
			    void __user *buffer, size_t *lenp, loff_t *ppos)
{
	return lprocfs_call_handler(table->data, write, ppos, buffer, lenp,
				    __proc_daemon_file);
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| matthew tyler | matthew tyler | 42 | 93.33% | 1 | 33.33% | 
| oleg drokin | oleg drokin | 2 | 4.44% | 1 | 33.33% | 
| james simmons | james simmons | 1 | 2.22% | 1 | 33.33% | 
 | Total | 45 | 100.00% | 3 | 100.00% | 
static int libcfs_force_lbug(struct ctl_table *table, int write,
			     void __user *buffer,
			     size_t *lenp, loff_t *ppos)
{
	if (write)
		LBUG();
	return 0;
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| matthew tyler | matthew tyler | 33 | 89.19% | 1 | 50.00% | 
| oleg drokin | oleg drokin | 4 | 10.81% | 1 | 50.00% | 
 | Total | 37 | 100.00% | 2 | 100.00% | 
static int proc_fail_loc(struct ctl_table *table, int write,
			 void __user *buffer,
			 size_t *lenp, loff_t *ppos)
{
	int rc;
	long old_fail_loc = cfs_fail_loc;
	rc = proc_doulongvec_minmax(table, write, buffer, lenp, ppos);
	if (old_fail_loc != cfs_fail_loc)
		wake_up(&cfs_race_waitq);
	return rc;
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| matthew tyler | matthew tyler | 65 | 100.00% | 1 | 100.00% | 
 | Total | 65 | 100.00% | 1 | 100.00% | 
static int __proc_cpt_table(void *data, int write,
			    loff_t pos, void __user *buffer, int nob)
{
	char *buf = NULL;
	int   len = 4096;
	int   rc  = 0;
	if (write)
		return -EPERM;
	LASSERT(cfs_cpt_table);
	while (1) {
		LIBCFS_ALLOC(buf, len);
		if (!buf)
			return -ENOMEM;
		rc = cfs_cpt_table_print(cfs_cpt_table, buf, len);
		if (rc >= 0)
			break;
		if (rc == -EFBIG) {
			LIBCFS_FREE(buf, len);
			len <<= 1;
			continue;
		}
		goto out;
	}
	if (pos >= rc) {
		rc = 0;
		goto out;
	}
	rc = cfs_trace_copyout_string(buffer, nob, buf + pos, NULL);
 out:
	if (buf)
		LIBCFS_FREE(buf, len);
	return rc;
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| matthew tyler | matthew tyler | 162 | 99.39% | 1 | 50.00% | 
| oleg drokin | oleg drokin | 1 | 0.61% | 1 | 50.00% | 
 | Total | 163 | 100.00% | 2 | 100.00% | 
static int proc_cpt_table(struct ctl_table *table, int write,
			  void __user *buffer, size_t *lenp, loff_t *ppos)
{
	return lprocfs_call_handler(table->data, write, ppos, buffer, lenp,
				    __proc_cpt_table);
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| matthew tyler | matthew tyler | 44 | 97.78% | 1 | 50.00% | 
| james simmons | james simmons | 1 | 2.22% | 1 | 50.00% | 
 | Total | 45 | 100.00% | 2 | 100.00% | 
static struct ctl_table lnet_table[] = {
	{
		.procname = "debug",
		.data     = &libcfs_debug,
		.maxlen   = sizeof(int),
		.mode     = 0644,
		.proc_handler = &proc_dobitmasks,
        },
	{
		.procname = "subsystem_debug",
		.data     = &libcfs_subsystem_debug,
		.maxlen   = sizeof(int),
		.mode     = 0644,
		.proc_handler = &proc_dobitmasks,
        },
	{
		.procname = "printk",
		.data     = &libcfs_printk,
		.maxlen   = sizeof(int),
		.mode     = 0644,
		.proc_handler = &proc_dobitmasks,
        },
	{
		.procname = "cpu_partition_table",
		.maxlen   = 128,
		.mode     = 0444,
		.proc_handler = &proc_cpt_table,
        },
	{
		.procname = "upcall",
		.data     = lnet_upcall,
		.maxlen   = sizeof(lnet_upcall),
		.mode     = 0644,
		.proc_handler = &proc_dostring,
        },
	{
		.procname = "debug_log_upcall",
		.data     = lnet_debug_log_upcall,
		.maxlen   = sizeof(lnet_debug_log_upcall),
		.mode     = 0644,
		.proc_handler = &proc_dostring,
        },
	{
		.procname = "catastrophe",
		.data     = &libcfs_catastrophe,
		.maxlen   = sizeof(int),
		.mode     = 0444,
		.proc_handler = &proc_dointvec,
        },
	{
		.procname = "dump_kernel",
		.maxlen   = 256,
		.mode     = 0200,
		.proc_handler = &proc_dump_kernel,
        },
	{
		.procname = "daemon_file",
		.mode     = 0644,
		.maxlen   = 256,
		.proc_handler = &proc_daemon_file,
        },
	{
		.procname = "force_lbug",
		.data     = NULL,
		.maxlen   = 0,
		.mode     = 0200,
		.proc_handler = &libcfs_force_lbug
	},
	{
		.procname = "fail_loc",
		.data     = &cfs_fail_loc,
		.maxlen   = sizeof(cfs_fail_loc),
		.mode     = 0644,
		.proc_handler = &proc_fail_loc
	},
	{
		.procname = "fail_val",
		.data     = &cfs_fail_val,
		.maxlen   = sizeof(int),
		.mode     = 0644,
		.proc_handler = &proc_dointvec
	},
	{
		.procname	= "fail_err",
		.data		= &cfs_fail_err,
		.maxlen		= sizeof(cfs_fail_err),
		.mode		= 0644,
		.proc_handler	= &proc_dointvec,
        },
	{
        }
};
static const struct lnet_debugfs_symlink_def lnet_debugfs_symlinks[] = {
	{ "console_ratelimit",
	  "/sys/module/libcfs/parameters/libcfs_console_ratelimit"},
	{ "debug_path",
	  "/sys/module/libcfs/parameters/libcfs_debug_file_path"},
	{ "panic_on_lbug",
	  "/sys/module/libcfs/parameters/libcfs_panic_on_lbug"},
	{ "libcfs_console_backoff",
	  "/sys/module/libcfs/parameters/libcfs_console_backoff"},
	{ "debug_mb",
	  "/sys/module/libcfs/parameters/libcfs_debug_mb"},
	{ "console_min_delay_centisecs",
	  "/sys/module/libcfs/parameters/libcfs_console_min_delay"},
	{ "console_max_delay_centisecs",
	  "/sys/module/libcfs/parameters/libcfs_console_max_delay"},
	{},
};
static ssize_t lnet_debugfs_read(struct file *filp, char __user *buf,
				 size_t count, loff_t *ppos)
{
	struct ctl_table *table = filp->private_data;
	int error;
	error = table->proc_handler(table, 0, (void __user *)buf, &count, ppos);
	if (!error)
		error = count;
	return error;
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| oleg drokin | oleg drokin | 66 | 94.29% | 1 | 50.00% | 
| matthew tyler | matthew tyler | 4 | 5.71% | 1 | 50.00% | 
 | Total | 70 | 100.00% | 2 | 100.00% | 
static ssize_t lnet_debugfs_write(struct file *filp, const char __user *buf,
				  size_t count, loff_t *ppos)
{
	struct ctl_table *table = filp->private_data;
	int error;
	error = table->proc_handler(table, 1, (void __user *)buf, &count, ppos);
	if (!error)
		error = count;
	return error;
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| oleg drokin | oleg drokin | 69 | 97.18% | 1 | 50.00% | 
| matthew tyler | matthew tyler | 2 | 2.82% | 1 | 50.00% | 
 | Total | 71 | 100.00% | 2 | 100.00% | 
static const struct file_operations lnet_debugfs_file_operations_rw = {
	.open		= simple_open,
	.read		= lnet_debugfs_read,
	.write		= lnet_debugfs_write,
	.llseek		= default_llseek,
};
static const struct file_operations lnet_debugfs_file_operations_ro = {
	.open		= simple_open,
	.read		= lnet_debugfs_read,
	.llseek		= default_llseek,
};
static const struct file_operations lnet_debugfs_file_operations_wo = {
	.open		= simple_open,
	.write		= lnet_debugfs_write,
	.llseek		= default_llseek,
};
static const struct file_operations *lnet_debugfs_fops_select(umode_t mode)
{
	if (!(mode & S_IWUGO))
		return &lnet_debugfs_file_operations_ro;
	if (!(mode & S_IRUGO))
		return &lnet_debugfs_file_operations_wo;
	return &lnet_debugfs_file_operations_rw;
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| oleg drokin | oleg drokin | 42 | 100.00% | 1 | 100.00% | 
 | Total | 42 | 100.00% | 1 | 100.00% | 
void lustre_insert_debugfs(struct ctl_table *table,
			   const struct lnet_debugfs_symlink_def *symlinks)
{
	if (!lnet_debugfs_root)
		lnet_debugfs_root = debugfs_create_dir("lnet", NULL);
	/* Even if we cannot create, just ignore it altogether) */
	if (IS_ERR_OR_NULL(lnet_debugfs_root))
		return;
	/* We don't save the dentry returned in next two calls, because
         * we don't call debugfs_remove() but rather remove_recursive()
         */
	for (; table->procname; table++)
		debugfs_create_file(table->procname, table->mode,
				    lnet_debugfs_root, table,
				    lnet_debugfs_fops_select(table->mode));
	for (; symlinks && symlinks->name; symlinks++)
		debugfs_create_symlink(symlinks->name, lnet_debugfs_root,
				       symlinks->target);
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| oleg drokin | oleg drokin | 84 | 86.60% | 5 | 62.50% | 
| matthew tyler | matthew tyler | 11 | 11.34% | 1 | 12.50% | 
| valdis kletnieks | valdis kletnieks | 1 | 1.03% | 1 | 12.50% | 
| patrick boettcher | patrick boettcher | 1 | 1.03% | 1 | 12.50% | 
 | Total | 97 | 100.00% | 8 | 100.00% | 
EXPORT_SYMBOL_GPL(lustre_insert_debugfs);
static void lustre_remove_debugfs(void)
{
	debugfs_remove_recursive(lnet_debugfs_root);
	lnet_debugfs_root = NULL;
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| matthew tyler | matthew tyler | 13 | 76.47% | 1 | 33.33% | 
| oleg drokin | oleg drokin | 4 | 23.53% | 2 | 66.67% | 
 | Total | 17 | 100.00% | 3 | 100.00% | 
static int libcfs_init(void)
{
	int rc;
	rc = libcfs_debug_init(5 * 1024 * 1024);
	if (rc < 0) {
		pr_err("LustreError: libcfs_debug_init: %d\n", rc);
		return rc;
	}
	rc = cfs_cpu_init();
	if (rc != 0)
		goto cleanup_debug;
	rc = misc_register(&libcfs_dev);
	if (rc) {
		CERROR("misc_register: error %d\n", rc);
		goto cleanup_cpu;
	}
	rc = cfs_wi_startup();
	if (rc) {
		CERROR("initialize workitem: error %d\n", rc);
		goto cleanup_deregister;
	}
	/* max to 4 threads, should be enough for rehash */
	rc = min(cfs_cpt_weight(cfs_cpt_table, CFS_CPT_ANY), 4);
	rc = cfs_wi_sched_create("cfs_rh", cfs_cpt_table, CFS_CPT_ANY,
				 rc, &cfs_sched_rehash);
	if (rc != 0) {
		CERROR("Startup workitem scheduler: error: %d\n", rc);
		goto cleanup_deregister;
	}
	rc = cfs_crypto_register();
	if (rc) {
		CERROR("cfs_crypto_register: error %d\n", rc);
		goto cleanup_wi;
	}
	lustre_insert_debugfs(lnet_table, lnet_debugfs_symlinks);
	CDEBUG(D_OTHER, "portals setup OK\n");
	return 0;
 cleanup_wi:
	cfs_wi_shutdown();
 cleanup_deregister:
	misc_deregister(&libcfs_dev);
cleanup_cpu:
	cfs_cpu_fini();
 cleanup_debug:
	libcfs_debug_cleanup();
	return rc;
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| oleg drokin | oleg drokin | 211 | 99.53% | 1 | 50.00% | 
| andreas dilger | andreas dilger | 1 | 0.47% | 1 | 50.00% | 
 | Total | 212 | 100.00% | 2 | 100.00% | 
static void libcfs_exit(void)
{
	int rc;
	lustre_remove_debugfs();
	if (cfs_sched_rehash) {
		cfs_wi_sched_destroy(cfs_sched_rehash);
		cfs_sched_rehash = NULL;
	}
	cfs_crypto_unregister();
	cfs_wi_shutdown();
	misc_deregister(&libcfs_dev);
	cfs_cpu_fini();
	rc = libcfs_debug_cleanup();
	if (rc)
		pr_err("LustreError: libcfs_debug_cleanup: %d\n", rc);
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| oleg drokin | oleg drokin | 59 | 98.33% | 1 | 50.00% | 
| andreas dilger | andreas dilger | 1 | 1.67% | 1 | 50.00% | 
 | Total | 60 | 100.00% | 2 | 100.00% | 
MODULE_AUTHOR("OpenSFS, Inc. <http://www.lustre.org/>");
MODULE_DESCRIPTION("Lustre helper library");
MODULE_VERSION(LIBCFS_VERSION);
MODULE_LICENSE("GPL");
module_init(libcfs_init);
module_exit(libcfs_exit);
Overall Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| oleg drokin | oleg drokin | 961 | 38.97% | 6 | 16.67% | 
| matthew tyler | matthew tyler | 911 | 36.94% | 1 | 2.78% | 
| peng tao | peng tao | 360 | 14.60% | 1 | 2.78% | 
| james simmons | james simmons | 68 | 2.76% | 7 | 19.44% | 
| liang zhen | liang zhen | 68 | 2.76% | 7 | 19.44% | 
| amir shehata | amir shehata | 49 | 1.99% | 2 | 5.56% | 
| greg kroah-hartman | greg kroah-hartman | 15 | 0.61% | 3 | 8.33% | 
| dmitry eremin-solenikov | dmitry eremin-solenikov | 12 | 0.49% | 1 | 2.78% | 
| john l. hammond | john l. hammond | 10 | 0.41% | 1 | 2.78% | 
| andreas dilger | andreas dilger | 6 | 0.24% | 3 | 8.33% | 
| patrick boettcher | patrick boettcher | 2 | 0.08% | 1 | 2.78% | 
| shivani bhardwaj | shivani bhardwaj | 2 | 0.08% | 1 | 2.78% | 
| m. vefa bicakci | m. vefa bicakci | 1 | 0.04% | 1 | 2.78% | 
| valdis kletnieks | valdis kletnieks | 1 | 0.04% | 1 | 2.78% | 
 | Total | 2466 | 100.00% | 36 | 100.00% | 
  
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.