Whamcloud - gitweb
LU-15759 libcfs: debugfs file_operation should have an owner
[fs/lustre-release.git] / libcfs / libcfs / module.c
index 82a75a7..3345203 100644 (file)
@@ -768,19 +768,22 @@ static const struct file_operations lnet_debugfs_file_operations_wo = {
        .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 & S_IWUGO))
-               return &lnet_debugfs_file_operations_ro;
+               return &state[0];
 
        if (!(mode & S_IRUGO))
-               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);
 
@@ -788,16 +791,37 @@ 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 in next two calls, because
         * we don't call debugfs_remove() but rather remove_recursive()
         */
        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)
 {
@@ -819,6 +843,7 @@ void lnet_remove_debugfs(struct ctl_table *table)
 }
 EXPORT_SYMBOL_GPL(lnet_remove_debugfs);
 
+static void *debugfs_state;
 static int __init libcfs_init(void)
 {
        int rc;
@@ -865,7 +890,7 @@ static int __init libcfs_init(void)
                goto cleanup_wi;
        }
 
-       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);
 
@@ -898,6 +923,8 @@ static void __exit libcfs_exit(void)
        debugfs_remove_recursive(lnet_debugfs_root);
        lnet_debugfs_root = NULL;
 
+       lnet_debugfs_fini(&debugfs_state);
+
        CDEBUG(D_MALLOC, "before Portals cleanup: kmem %lld\n",
               libcfs_kmem_read());