Whamcloud - gitweb
LU-2071 lprocfs: Memory leak on lustre proc access
[fs/lustre-release.git] / lustre / obdclass / lprocfs_status.c
index 0b4941f..624140c 100644 (file)
@@ -63,6 +63,13 @@ CFS_MODULE_PARM(lprocfs_no_percpu_stats, "i", int, 0644,
 CFS_DECLARE_RWSEM(_lprocfs_lock);
 EXPORT_SYMBOL(_lprocfs_lock);
 
+int lprocfs_single_release(struct inode *inode, struct file *file)
+{
+        LPROCFS_EXIT();
+        return single_release(inode, file);
+}
+EXPORT_SYMBOL(lprocfs_single_release);
+
 int lprocfs_seq_release(struct inode *inode, struct file *file)
 {
         LPROCFS_EXIT();
@@ -379,7 +386,7 @@ out:
 }
 EXPORT_SYMBOL(lprocfs_add_vars);
 
-void lprocfs_remove(struct proc_dir_entry **rooth)
+void lprocfs_remove_nolock(struct proc_dir_entry **rooth)
 {
         struct proc_dir_entry *root = *rooth;
         struct proc_dir_entry *temp = root;
@@ -392,7 +399,6 @@ void lprocfs_remove(struct proc_dir_entry **rooth)
 
         parent = root->parent;
         LASSERT(parent != NULL);
-        LPROCFS_WRITE_ENTRY(); /* search vs remove race */
 
         while (1) {
                 while (temp->subdir != NULL)
@@ -428,7 +434,13 @@ void lprocfs_remove(struct proc_dir_entry **rooth)
                 if (temp == parent)
                         break;
         }
-        LPROCFS_WRITE_EXIT();
+}
+
+void lprocfs_remove(struct proc_dir_entry **rooth)
+{
+       LPROCFS_WRITE_ENTRY(); /* search vs remove race */
+       lprocfs_remove_nolock(rooth);
+       LPROCFS_WRITE_EXIT();
 }
 EXPORT_SYMBOL(lprocfs_remove);
 
@@ -439,6 +451,52 @@ void lprocfs_remove_proc_entry(const char *name, struct proc_dir_entry *parent)
 }
 EXPORT_SYMBOL(lprocfs_remove_proc_entry);
 
+void lprocfs_try_remove_proc_entry(const char *name,
+                                  struct proc_dir_entry *parent)
+{
+       struct proc_dir_entry    *t = NULL;
+       struct proc_dir_entry   **p;
+       int                       len, busy = 0;
+
+       LASSERT(parent != NULL);
+       len = strlen(name);
+
+       LPROCFS_WRITE_ENTRY();
+
+       /* lookup target name */
+       for (p = &parent->subdir; *p; p = &(*p)->next) {
+               if ((*p)->namelen != len)
+                       continue;
+               if (memcmp(name, (*p)->name, len))
+                       continue;
+               t = *p;
+               break;
+       }
+
+       if (t) {
+               /* verify it's empty: do not count "num_refs" */
+               for (p = &t->subdir; *p; p = &(*p)->next) {
+                       if ((*p)->namelen != strlen("num_refs")) {
+                               busy = 1;
+                               break;
+                       }
+                       if (memcmp("num_refs", (*p)->name,
+                                  strlen("num_refs"))) {
+                               busy = 1;
+                               break;
+                       }
+               }
+       }
+
+       if (busy == 0)
+               lprocfs_remove_nolock(&t);
+
+       LPROCFS_WRITE_EXIT();
+
+       return;
+}
+EXPORT_SYMBOL(lprocfs_try_remove_proc_entry);
+
 struct proc_dir_entry *lprocfs_register(const char *name,
                                         struct proc_dir_entry *parent,
                                         struct lprocfs_vars *list, void *data)
@@ -952,6 +1010,10 @@ static const char *obd_connect_names[] = {
         "umask",
         "einprogress",
         "grant_param",
+       "nanoseconds_times",
+       "lvb_type",
+       "unknown",
+       "lightweight_conn",
         NULL
 };
 
@@ -1654,7 +1716,6 @@ void lprocfs_init_ops_stats(int num_private_stats, struct lprocfs_stats *stats)
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, get_uuid);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, quotacheck);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, quotactl);
-        LPROCFS_OBD_OP_INIT(num_private_stats, stats, quota_adjust_qunit);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, ping);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_new);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_rem);
@@ -2355,11 +2416,6 @@ int lprocfs_obd_rd_hash(char *page, char **start, off_t off,
         c += cfs_hash_debug_str(obd->obd_uuid_hash, page + c, count - c);
         c += cfs_hash_debug_str(obd->obd_nid_hash, page + c, count - c);
         c += cfs_hash_debug_str(obd->obd_nid_stats_hash, page+c, count-c);
-#ifdef HAVE_QUOTA_SUPPORT
-        if (obd->u.obt.obt_qctxt.lqc_lqs_hash)
-                c += cfs_hash_debug_str(obd->u.obt.obt_qctxt.lqc_lqs_hash,
-                                        page + c, count - c);
-#endif
 
         return c;
 }