Whamcloud - gitweb
Branch b1_8
authorbobijam <bobijam>
Tue, 5 May 2009 02:12:07 +0000 (02:12 +0000)
committerbobijam <bobijam>
Tue, 5 May 2009 02:12:07 +0000 (02:12 +0000)
b=17402
i=vitaly.fertman
i=eric.mei

Clear up nid_stat's nid_exp_ref_count usage.

lustre/include/lustre_export.h
lustre/obdclass/lprocfs_status.c
lustre/obdclass/obd_config.c

index a6d6142..a49a6a3 100644 (file)
@@ -94,24 +94,31 @@ struct filter_export_data {
 #define fed_lr_off      fed_led.led_lr_off
 #define fed_lr_idx      fed_led.led_lr_idx
 
-typedef struct nid_stat_uuid {
-        struct list_head ns_uuid_list;
-        struct obd_uuid  ns_uuid;
-} nid_stat_uuid_t;
-
 typedef struct nid_stat {
         lnet_nid_t               nid;
         struct hlist_node        nid_hash;
         struct list_head         nid_list;
-        struct list_head         nid_uuid_list;
         struct obd_device       *nid_obd;
         struct proc_dir_entry   *nid_proc;
         struct lprocfs_stats    *nid_stats;
         struct brw_stats        *nid_brw_stats;
         struct lprocfs_stats    *nid_ldlm_stats;
-        int                      nid_exp_ref_count;
+        atomic_t                 nid_exp_ref_count; /* for obd_nid_stats_hash
+                                                           exp_nid_stats */
 } nid_stat_t;
 
+#define nidstat_getref(nidstat)                                                \
+do {                                                                           \
+        atomic_inc(&(nidstat)->nid_exp_ref_count);                             \
+} while(0)
+
+#define nidstat_putref(nidstat)                                                \
+do {                                                                           \
+        atomic_dec(&(nidstat)->nid_exp_ref_count);                             \
+        LASSERTF(atomic_read(&(nidstat)->nid_exp_ref_count) >= 0,              \
+                 "stat %p nid_exp_ref_count < 0\n", nidstat);                  \
+} while(0)
+
 enum obd_option {
         OBD_OPT_FORCE =         0x0001,
         OBD_OPT_FAILOVER =      0x0002,
index f0ad1d4..59f981d 100644 (file)
@@ -1024,8 +1024,8 @@ static void lprocfs_free_client_stats(struct nid_stat *client_stat)
                client_stat->nid_proc, client_stat->nid_stats,
                client_stat->nid_brw_stats);
 
-        LASSERTF(client_stat->nid_exp_ref_count == 0, "count %d\n",
-                 client_stat->nid_exp_ref_count);
+        LASSERTF(atomic_read(&client_stat->nid_exp_ref_count) == 0,
+                 "count %d\n", atomic_read(&client_stat->nid_exp_ref_count));
 
         hlist_del_init(&client_stat->nid_hash);
 
@@ -1572,10 +1572,10 @@ void lprocfs_nid_stats_clear_write_cb(void *obj, void *data)
         ENTRY;
         /* object has only hash + iterate_all references.
          * add/delete blocked by hash bucket lock */
-        CDEBUG(D_INFO,"refcnt %d\n", stat->nid_exp_ref_count);
-        if (stat->nid_exp_ref_count == 2) {
+        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);
-                stat->nid_exp_ref_count--;
+                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);
@@ -1619,7 +1619,6 @@ int lprocfs_exp_setup(struct obd_export *exp, lnet_nid_t *nid, int *newnid)
 {
         int rc = 0;
         struct nid_stat *new_stat, *old_stat;
-        struct nid_stat_uuid *cursor, *new_ns_uuid;
         struct obd_device *obd;
         cfs_proc_dir_entry_t *entry;
         ENTRY;
@@ -1644,53 +1643,30 @@ int lprocfs_exp_setup(struct obd_export *exp, lnet_nid_t *nid, int *newnid)
         if (new_stat == NULL)
                 RETURN(-ENOMEM);
 
-        OBD_ALLOC_PTR(new_ns_uuid);
-        if (new_ns_uuid == NULL) {
-                OBD_FREE_PTR(new_stat);
-                RETURN(-ENOMEM);
-        }
-        CFS_INIT_LIST_HEAD(&new_ns_uuid->ns_uuid_list);
-        strncpy(new_ns_uuid->ns_uuid.uuid, exp->exp_client_uuid.uuid,
-                sizeof(struct obd_uuid));
-
-        CFS_INIT_LIST_HEAD(&new_stat->nid_uuid_list);
         new_stat->nid = *nid;
         new_stat->nid_obd = exp->exp_obd;
-        /* need live in hash after destroy export */
-        new_stat->nid_exp_ref_count = 1;
+        atomic_set(&new_stat->nid_exp_ref_count, 0);
 
         old_stat = lustre_hash_findadd_unique(obd->obd_nid_stats_hash,
-                                          nid, &new_stat->nid_hash);
+                                              nid, &new_stat->nid_hash);
         CDEBUG(D_INFO, "Found stats %p for nid %s - ref %d\n",
-               old_stat, libcfs_nid2str(*nid), new_stat->nid_exp_ref_count);
+               old_stat, libcfs_nid2str(*nid),
+               atomic_read(&new_stat->nid_exp_ref_count));
 
         /* Return -EALREADY here so that we know that the /proc
          * entry already has been created */
         if (old_stat != new_stat) {
-                int found = 0;
-
-                exp->exp_nid_stats = old_stat;
-
-                /* We need to decrement the refcount if the uuid was
-                 * already in our list */
                 spin_lock(&obd->obd_nid_lock);
-                list_for_each_entry(cursor,
-                                    &old_stat->nid_uuid_list,
-                                    ns_uuid_list) {
-                        if (cursor && obd_uuid_equals(&cursor->ns_uuid,
-                                                      &exp->exp_client_uuid)) {
-                                found = 1;
-                                --old_stat->nid_exp_ref_count;
-                                break;
-                        }
+                if (exp->exp_nid_stats != old_stat) {
+                        if (exp->exp_nid_stats)
+                                nidstat_putref(exp->exp_nid_stats);
+                        exp->exp_nid_stats = old_stat;
+                } else {
+                        /* lustre_hash_findadd_unique() has added
+                         * old_stat's refcount */
+                        nidstat_putref(old_stat);
                 }
 
-                if (!found)
-                        list_add(&new_ns_uuid->ns_uuid_list,
-                                 &old_stat->nid_uuid_list);
-                else
-                        OBD_FREE_PTR(new_ns_uuid);
-
                 spin_unlock(&obd->obd_nid_lock);
 
                 GOTO(destroy_new, rc = -EALREADY);
@@ -1704,11 +1680,6 @@ int lprocfs_exp_setup(struct obd_export *exp, lnet_nid_t *nid, int *newnid)
                 GOTO(destroy_new_ns, rc = -ENOMEM);
         }
 
-        /* Add in uuid to our nid_stats list */
-        spin_lock(&obd->obd_nid_lock);
-        list_add(&new_ns_uuid->ns_uuid_list, &new_stat->nid_uuid_list);
-        spin_unlock(&obd->obd_nid_lock);
-
         entry = lprocfs_add_simple(new_stat->nid_proc, "uuid",
                                    lprocfs_exp_rd_uuid, NULL, new_stat, NULL);
         if (IS_ERR(entry)) {
@@ -1725,6 +1696,9 @@ int lprocfs_exp_setup(struct obd_export *exp, lnet_nid_t *nid, int *newnid)
                 GOTO(destroy_new_ns, rc);
         }
 
+        if (exp->exp_nid_stats)
+                nidstat_putref(exp->exp_nid_stats);
+        nidstat_getref(new_stat);
         exp->exp_nid_stats = new_stat;
         *newnid = 1;
         /* protect competitive add to list, not need locking on destroy */
@@ -1738,7 +1712,6 @@ destroy_new_ns:
         if (new_stat->nid_proc != NULL)
                 lprocfs_remove(&new_stat->nid_proc);
         lustre_hash_del(obd->obd_nid_stats_hash, nid, &new_stat->nid_hash);
-        OBD_FREE_PTR(new_ns_uuid);
 
 destroy_new:
         OBD_FREE_PTR(new_stat);
@@ -1748,32 +1721,11 @@ destroy_new:
 int lprocfs_exp_cleanup(struct obd_export *exp)
 {
         struct nid_stat *stat = exp->exp_nid_stats;
-        struct nid_stat_uuid *cursor, *tmp;
-        int found = 0;
 
         if(!stat || !exp->exp_obd)
                 RETURN(0);
 
-        spin_lock(&exp->exp_obd->obd_nid_lock);
-        list_for_each_entry_safe(cursor, tmp,
-                                 &stat->nid_uuid_list,
-                                 ns_uuid_list) {
-                if (cursor && obd_uuid_equals(&cursor->ns_uuid,
-                                              &exp->exp_client_uuid)) {
-                        found = 1;
-                        list_del(&cursor->ns_uuid_list);
-                        OBD_FREE_PTR(cursor);
-                        --stat->nid_exp_ref_count;
-                        CDEBUG(D_INFO, "Put stat %p - %d\n", stat,
-                               stat->nid_exp_ref_count);
-                        break;
-                }
-        }
-        spin_unlock(&exp->exp_obd->obd_nid_lock);
-        if (!found)
-                CERROR("obd_export's client uuid %s are not found in its "
-                       "nid_stats list\n", exp->exp_client_uuid.uuid);
-
+        nidstat_putref(exp->exp_nid_stats);
         exp->exp_nid_stats = NULL;
         lprocfs_free_stats(&exp->exp_ops_stats);
 
index 519b427..7860bd9 100644 (file)
@@ -1528,7 +1528,7 @@ nidstats_get(struct hlist_node *hnode)
         struct nid_stat *ns;
 
         ns = hlist_entry(hnode, struct nid_stat, nid_hash);
-        ns->nid_exp_ref_count++;
+        nidstat_getref(ns);
 
         RETURN(ns);
 }
@@ -1539,7 +1539,7 @@ nidstats_put(struct hlist_node *hnode)
         struct nid_stat *ns;
 
         ns = hlist_entry(hnode, struct nid_stat, nid_hash);
-        ns->nid_exp_ref_count--;
+        nidstat_putref(ns);
 
         RETURN(ns);
 }