@@ -57,8 +57,10 @@ static inline int notifier_from_ioctl_errno(int err)
extern struct workqueue_struct *cfs_rehash_wq;
-void lnet_insert_debugfs(struct ctl_table *table);
+void lnet_insert_debugfs(struct ctl_table *table, struct module *mod,
+ void **statep);
void lnet_remove_debugfs(struct ctl_table *table);
+void lnet_debugfs_fini(void **statep);
int debugfs_doint(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos);
@@ -569,6 +569,7 @@ unsigned int lnet_nid_cpt_hash(struct lnet_nid *nid,
int lnet_lib_init(void);
void lnet_lib_exit(void);
+void lnet_router_exit(void);
void lnet_mt_event_handler(struct lnet_event *event);
@@ -746,19 +746,23 @@ static ssize_t lnet_debugfs_write(struct file *filp, const char __user *buf,
.llseek = default_llseek,
};
-static const struct file_operations *lnet_debugfs_fops_select(umode_t mode)
+static const struct file_operations *
+lnet_debugfs_fops_select(umode_t mode, const struct file_operations state[3])
{
if (!(mode & 0222))
- return &lnet_debugfs_file_operations_ro;
+ return &state[0];
if (!(mode & 0444))
- return &lnet_debugfs_file_operations_wo;
+ return &state[1];
- return &lnet_debugfs_file_operations_rw;
+ return &state[2];
}
-void lnet_insert_debugfs(struct ctl_table *table)
+void lnet_insert_debugfs(struct ctl_table *table, struct module *mod,
+ void **statep)
{
+ struct file_operations *state = *statep;
+
if (!lnet_debugfs_root)
lnet_debugfs_root = debugfs_create_dir("lnet", NULL);
@@ -766,6 +770,19 @@ void lnet_insert_debugfs(struct ctl_table *table)
if (IS_ERR_OR_NULL(lnet_debugfs_root))
return;
+ if (!state) {
+ state = kmalloc(3 * sizeof(*state), GFP_KERNEL);
+ if (!state)
+ return;
+ state[0] = lnet_debugfs_file_operations_ro;
+ state[0].owner = mod;
+ state[1] = lnet_debugfs_file_operations_wo;
+ state[1].owner = mod;
+ state[2] = lnet_debugfs_file_operations_rw;
+ state[2].owner = mod;
+ *statep = state;
+ }
+
/*
* We don't save the dentry returned because we don't call
* debugfs_remove() but rather remove_recursive()
@@ -773,10 +790,18 @@ void lnet_insert_debugfs(struct ctl_table *table)
for (; table && table->procname; table++)
debugfs_create_file(table->procname, table->mode,
lnet_debugfs_root, table,
- lnet_debugfs_fops_select(table->mode));
+ lnet_debugfs_fops_select(table->mode,
+ (const struct file_operations *)state));
}
EXPORT_SYMBOL_GPL(lnet_insert_debugfs);
+void lnet_debugfs_fini(void **state)
+{
+ kfree(*state);
+ *state = NULL;
+}
+EXPORT_SYMBOL_GPL(lnet_debugfs_fini);
+
static void lnet_insert_debugfs_links(
const struct lnet_debugfs_symlink_def *symlinks)
{
@@ -801,6 +826,8 @@ void lnet_remove_debugfs(struct ctl_table *table)
static DEFINE_MUTEX(libcfs_startup);
static int libcfs_active;
+static void *debugfs_state;
+
int libcfs_setup(void)
{
int rc = -EINVAL;
@@ -855,7 +882,7 @@ static int libcfs_init(void)
{
int rc;
- lnet_insert_debugfs(lnet_table);
+ lnet_insert_debugfs(lnet_table, THIS_MODULE, &debugfs_state);
if (!IS_ERR_OR_NULL(lnet_debugfs_root))
lnet_insert_debugfs_links(lnet_debugfs_symlinks);
@@ -875,6 +902,8 @@ static void libcfs_exit(void)
debugfs_remove_recursive(lnet_debugfs_root);
lnet_debugfs_root = NULL;
+ lnet_debugfs_fini(&debugfs_state);
+
if (cfs_rehash_wq)
destroy_workqueue(cfs_rehash_wq);
@@ -271,6 +271,7 @@ static void __exit lnet_exit(void)
&lnet_ioctl_handler);
LASSERT(!rc);
+ lnet_router_exit();
lnet_lib_exit();
}
@@ -888,12 +888,20 @@ static int proc_lnet_portal_rotor(struct ctl_table *table, int write,
}
};
+static void *debugfs_state;
+
void lnet_router_debugfs_init(void)
{
- lnet_insert_debugfs(lnet_table);
+ lnet_insert_debugfs(lnet_table, THIS_MODULE,
+ &debugfs_state);
}
void lnet_router_debugfs_fini(void)
{
lnet_remove_debugfs(lnet_table);
}
+
+void lnet_router_exit(void)
+{
+ lnet_debugfs_fini(&debugfs_state);
+}