Whamcloud - gitweb
b=21815 Avoid operating lustre-hash internal structures directly.
authoryangsheng <Sheng.Yang@Sun.COM>
Mon, 1 Mar 2010 13:24:33 +0000 (21:24 +0800)
committerJohann Lombardi <johann@sun.com>
Mon, 1 Mar 2010 22:37:22 +0000 (23:37 +0100)
i=johann
i=nathan

lustre/include/class_hash.h
lustre/include/obd_class.h
lustre/mds/mds_fs.c
lustre/mgs/mgs_fs.c
lustre/obdclass/class_hash.c
lustre/obdclass/lprocfs_status.c
lustre/obdfilter/filter.c

index 9d43ac4..06cb691 100644 (file)
@@ -252,6 +252,8 @@ void *lustre_hash_findadd_unique(lustre_hash_t *lh, void *key,
 /* Hash deletion functions */
 void *lustre_hash_del(lustre_hash_t *lh, void *key, struct hlist_node *hnode);
 void *lustre_hash_del_key(lustre_hash_t *lh, void *key);
+typedef int (*lh_cond_opt_cb)(void *obj, void *data);
+void lustre_hash_cond_del(lustre_hash_t *lh, lh_cond_opt_cb, void *data);
 
 /* Hash lookup/for_each functions */
 void *lustre_hash_lookup(lustre_hash_t *lh, void *key);
index c50c71f..fcd7070 100644 (file)
@@ -306,6 +306,26 @@ do {                                                            \
 #define EXP_COUNTER_INCREMENT(exp, op);
 #endif
 
+static inline int lprocfs_nid_ldlm_stats_init(struct nid_stat* tmp) {
+        int rc;
+
+        rc = lprocfs_register_stats(tmp->nid_proc, "stats",
+                                    tmp->nid_stats);
+        if (rc)
+                return rc;
+
+        /* Always add in ldlm_stats */
+        tmp->nid_ldlm_stats = lprocfs_alloc_stats(LDLM_LAST_OPC - LDLM_FIRST_OPC
+                                                  ,LPROCFS_STATS_FLAG_NOPERCPU);
+        if (tmp->nid_ldlm_stats == NULL)
+                return -ENOMEM;
+
+        lprocfs_init_ldlm_stats(tmp->nid_ldlm_stats);
+
+        return lprocfs_register_stats(tmp->nid_proc, "ldlm_stats",
+                                      tmp->nid_ldlm_stats);
+}
+
 #define OBD_CHECK_OP(obd, op, err)                              \
 do {                                                            \
         if (!OBT(obd) || !OBP((obd), op)) {\
index d551891..5374670 100644 (file)
@@ -91,24 +91,9 @@ int mds_export_stats_init(struct obd_device *obd,
                         return -ENOMEM;
 
                 lprocfs_init_ops_stats(LPROC_MDS_LAST, tmp->nid_stats);
-                rc = lprocfs_register_stats(tmp->nid_proc, "stats",
-                                            tmp->nid_stats);
-                if (rc)
-                        return rc;
-
                 mds_stats_counter_init(tmp->nid_stats);
 
-                /* Always add in ldlm_stats */
-                tmp->nid_ldlm_stats =
-                        lprocfs_alloc_stats(LDLM_LAST_OPC - LDLM_FIRST_OPC,
-                                            LPROCFS_STATS_FLAG_NOPERCPU);
-                if (tmp->nid_ldlm_stats == NULL)
-                        return -ENOMEM;
-
-                lprocfs_init_ldlm_stats(tmp->nid_ldlm_stats);
-
-                rc = lprocfs_register_stats(tmp->nid_proc, "ldlm_stats",
-                                            tmp->nid_ldlm_stats);
+                rc = lprocfs_nid_ldlm_stats_init(tmp);
                 if (rc)
                         return rc;
         }
index 7ee3eb1..e3b7981 100644 (file)
@@ -88,22 +88,8 @@ int mgs_export_stats_init(struct obd_device *obd,
 
                 lprocfs_init_ops_stats(LPROC_MGS_LAST, tmp->nid_stats);
                 mgs_stats_counter_init(tmp->nid_stats);
-                rc = lprocfs_register_stats(tmp->nid_proc, "stats",
-                                            tmp->nid_stats);
-                if (rc)
-                        return rc;
-
-                /* Always add in ldlm_stats */
-                tmp->nid_ldlm_stats =
-                        lprocfs_alloc_stats(LDLM_LAST_OPC - LDLM_FIRST_OPC,
-                                            LPROCFS_STATS_FLAG_NOPERCPU);
-                if (tmp->nid_ldlm_stats == NULL)
-                        return -ENOMEM;
-
-                lprocfs_init_ldlm_stats(tmp->nid_ldlm_stats);
 
-                rc = lprocfs_register_stats(tmp->nid_proc, "ldlm_stats",
-                                            tmp->nid_ldlm_stats);
+                rc = lprocfs_nid_ldlm_stats_init(tmp);
                 if (rc)
                         return rc;
         }
index 13bf2d6..68aca4f 100644 (file)
@@ -362,6 +362,42 @@ lustre_hash_del(lustre_hash_t *lh, void *key, struct hlist_node *hnode)
 EXPORT_SYMBOL(lustre_hash_del);
 
 /**
+ * Delete item from the lustre hash @lh when @func return true.
+ * The write lock being hold during loop for each bucket to avoid
+ * any object be reference.
+ */
+void
+lustre_hash_cond_del(lustre_hash_t *lh, lh_cond_opt_cb func, void *data)
+{
+        lustre_hash_bucket_t *lhb;
+        struct hlist_node    *hnode;
+        struct hlist_node    *pos;
+        int                   i;
+        ENTRY;
+
+        LASSERT(lh != NULL);
+
+        lh_write_lock(lh);
+        lh_for_each_bucket(lh, lhb, i) {
+                if (lhb == NULL)
+                        continue;
+
+                write_lock(&lhb->lhb_rwlock);
+                hlist_for_each_safe(hnode, pos, &(lhb->lhb_head)) {
+                        __lustre_hash_bucket_validate(lh, lhb, hnode);
+                        if (func(lh_get(lh, hnode), data))
+                                __lustre_hash_bucket_del(lh, lhb, hnode);
+                        (void)lh_put(lh, hnode);
+                }
+                write_unlock(&lhb->lhb_rwlock);
+        }
+        lh_write_unlock(lh);
+
+        EXIT;
+}
+EXPORT_SYMBOL(lustre_hash_cond_del);
+
+/**
  * Delete item given @key in lustre hash @lh.  The first @key found in
  * the hash will be removed, if the key exists multiple times in the hash
  * @lh this function must be called once per key.  The removed object
index 36cb078..03ad827 100644 (file)
@@ -1589,7 +1589,7 @@ int lprocfs_nid_stats_clear_read(char *page, char **start, off_t off,
 }
 EXPORT_SYMBOL(lprocfs_nid_stats_clear_read);
 
-void lprocfs_nid_stats_clear_write_cb(void *obj, void *data)
+int lprocfs_nid_stats_clear_write_cb(void *obj, void *data)
 {
         struct nid_stat *stat = obj;
         int i;
@@ -1598,13 +1598,10 @@ void lprocfs_nid_stats_clear_write_cb(void *obj, void *data)
          * add/delete blocked by hash bucket lock */
         CDEBUG(D_INFO,"refcnt %d\n", atomic_read(&stat->nid_exp_ref_count));
         if (atomic_read(&stat->nid_exp_ref_count) == 2) {
-                hlist_del_init(&stat->nid_hash);
-                nidstat_putref(stat);
                 spin_lock(&stat->nid_obd->obd_nid_lock);
                 list_move(&stat->nid_list, data);
                 spin_unlock(&stat->nid_obd->obd_nid_lock);
-                EXIT;
-                return;
+                RETURN(1);
         }
         /* we has reference to object - only clear data*/
         if (stat->nid_stats)
@@ -1614,8 +1611,7 @@ void lprocfs_nid_stats_clear_write_cb(void *obj, void *data)
                 for (i = 0; i < BRW_LAST; i++)
                         lprocfs_oh_clear(&stat->nid_brw_stats->hist[i]);
         }
-        EXIT;
-        return;
+        RETURN(0);
 }
 
 int lprocfs_nid_stats_clear_write(struct file *file, const char *buffer,
@@ -1625,7 +1621,7 @@ int lprocfs_nid_stats_clear_write(struct file *file, const char *buffer,
         struct nid_stat *client_stat;
         CFS_LIST_HEAD(free_list);
 
-        lustre_hash_for_each(obd->obd_nid_stats_hash,
+        lustre_hash_cond_del(obd->obd_nid_stats_hash,
                              lprocfs_nid_stats_clear_write_cb, &free_list);
 
         while (!list_empty(&free_list)) {
index ec22359..210c9ba 100644 (file)
@@ -276,22 +276,9 @@ static int filter_export_stats_init(struct obd_device *obd,
                 if (rc)
                         RETURN(rc);
 
-                rc = lprocfs_register_stats(tmp->nid_proc, "stats",
-                                            tmp->nid_stats);
+                rc = lprocfs_nid_ldlm_stats_init(tmp);
                 if (rc)
                         RETURN(rc);
-
-                /* Always add in ldlm_stats */
-                tmp->nid_ldlm_stats =
-                        lprocfs_alloc_stats(LDLM_LAST_OPC - LDLM_FIRST_OPC,
-                                            LPROCFS_STATS_FLAG_NOPERCPU);
-                if (tmp->nid_ldlm_stats == NULL)
-                        return -ENOMEM;
-
-                lprocfs_init_ldlm_stats(tmp->nid_ldlm_stats);
-
-                rc = lprocfs_register_stats(tmp->nid_proc, "ldlm_stats",
-                                            tmp->nid_ldlm_stats);
         }
 
         RETURN(0);