]> git.proxmox.com Git - mirror_spl.git/blobdiff - module/spl/spl-kstat.c
Avoid WARN() from procfs on kstat collision
[mirror_spl.git] / module / spl / spl-kstat.c
index c604a32f2aa1296e31824fdc9a0e2f5b2b1effa8..1b6a7df9b34858cf4bc3d256da7770588c75685f 100644 (file)
 
 #include <linux/seq_file.h>
 #include <sys/kstat.h>
-#include <spl-debug.h>
+#include <sys/vmem.h>
+#include <sys/cmn_err.h>
 
-#ifdef SS_DEBUG_SUBSYS
-#undef SS_DEBUG_SUBSYS
-#endif
-
-#define SS_DEBUG_SUBSYS SS_KSTAT
 #ifndef HAVE_PDE_DATA
 #define PDE_DATA(x) (PDE(x)->data)
 #endif
@@ -344,7 +340,6 @@ static void *
 kstat_seq_data_addr(kstat_t *ksp, loff_t n)
 {
         void *rc = NULL;
-        SENTRY;
 
        switch (ksp->ks_type) {
                 case KSTAT_TYPE_RAW:
@@ -369,7 +364,7 @@ kstat_seq_data_addr(kstat_t *ksp, loff_t n)
                         PANIC("Undefined kstat type %d\n", ksp->ks_type);
         }
 
-        SRETURN(rc);
+        return (rc);
 }
 
 static void *
@@ -378,7 +373,6 @@ kstat_seq_start(struct seq_file *f, loff_t *pos)
         loff_t n = *pos;
         kstat_t *ksp = (kstat_t *)f->private;
         ASSERT(ksp->ks_magic == KS_MAGIC);
-        SENTRY;
 
        mutex_enter(ksp->ks_lock);
 
@@ -393,12 +387,12 @@ kstat_seq_start(struct seq_file *f, loff_t *pos)
        ksp->ks_snaptime = gethrtime();
 
         if (!n && kstat_seq_show_headers(f))
-               SRETURN(NULL);
+               return (NULL);
 
         if (n >= ksp->ks_ndata)
-                SRETURN(NULL);
+                return (NULL);
 
-        SRETURN(kstat_seq_data_addr(ksp, n));
+        return (kstat_seq_data_addr(ksp, n));
 }
 
 static void *
@@ -406,13 +400,12 @@ kstat_seq_next(struct seq_file *f, void *p, loff_t *pos)
 {
         kstat_t *ksp = (kstat_t *)f->private;
         ASSERT(ksp->ks_magic == KS_MAGIC);
-        SENTRY;
 
         ++*pos;
         if (*pos >= ksp->ks_ndata)
-                SRETURN(NULL);
+                return (NULL);
 
-        SRETURN(kstat_seq_data_addr(ksp, *pos));
+        return (kstat_seq_data_addr(ksp, *pos));
 }
 
 static void
@@ -616,6 +609,29 @@ __kstat_create(const char *ks_module, int ks_instance, const char *ks_name,
 }
 EXPORT_SYMBOL(__kstat_create);
 
+static int
+kstat_detect_collision(kstat_t *ksp)
+{
+       kstat_module_t *module;
+       kstat_t *tmp;
+       char parent[KSTAT_STRLEN+1];
+       char *cp;
+
+       (void) strlcpy(parent, ksp->ks_module, sizeof(parent));
+
+       if ((cp = strrchr(parent, '/')) == NULL)
+               return (0);
+
+       cp[0] = '\0';
+       if ((module = kstat_find_module(parent)) != NULL) {
+               list_for_each_entry(tmp, &module->ksm_kstat_list, ks_list)
+                       if (strncmp(tmp->ks_name, cp+1, KSTAT_STRLEN) == 0)
+                               return (EEXIST);
+       }
+
+       return (0);
+}
+
 void
 __kstat_install(kstat_t *ksp)
 {
@@ -628,6 +644,11 @@ __kstat_install(kstat_t *ksp)
 
        module = kstat_find_module(ksp->ks_module);
        if (module == NULL) {
+               if (kstat_detect_collision(ksp) != 0) {
+                       cmn_err(CE_WARN, "kstat_create('%s', '%s'): namespace" \
+                           " collision", ksp->ks_module, ksp->ks_name);
+                       goto out;
+               }
                module = kstat_create_module(ksp->ks_module);
                if (module == NULL)
                        goto out;
@@ -689,19 +710,16 @@ EXPORT_SYMBOL(__kstat_delete);
 int
 spl_kstat_init(void)
 {
-       SENTRY;
        mutex_init(&kstat_module_lock, NULL, MUTEX_DEFAULT, NULL);
        INIT_LIST_HEAD(&kstat_module_list);
         kstat_id = 0;
-       SRETURN(0);
+       return (0);
 }
 
 void
 spl_kstat_fini(void)
 {
-       SENTRY;
        ASSERT(list_empty(&kstat_module_list));
        mutex_destroy(&kstat_module_lock);
-       SEXIT;
 }