Whamcloud - gitweb
b=19069 cleanup on nid_stats entry refcount
authorhongchao.zhang <Hongchao.Zhang@sun.com>
Sat, 10 Jul 2010 08:39:37 +0000 (12:39 +0400)
committerMikhail Pershin <tappro@sun.com>
Thu, 5 Aug 2010 15:16:30 +0000 (19:16 +0400)
introduce reconnect flag in "lprocfs_exp_setup" to cleanup
the refcount of nid_stats

i=andreas.dilger
i=yong.fan

lustre/include/lprocfs_status.h
lustre/mdt/mdt_fs.c
lustre/mdt/mdt_handler.c
lustre/mdt/mdt_internal.h
lustre/mgs/mgs_fs.c
lustre/mgs/mgs_handler.c
lustre/mgs/mgs_internal.h
lustre/obdclass/lprocfs_status.c
lustre/obdfilter/filter.c

index 4555343..5631f28 100644 (file)
@@ -430,7 +430,7 @@ struct nid_stat;
 extern int lprocfs_add_clear_entry(struct obd_device * obd,
                                    cfs_proc_dir_entry_t *entry);
 extern int lprocfs_exp_setup(struct obd_export *exp,
-                             lnet_nid_t *peer_nid, int *newnid);
+                             lnet_nid_t *peer_nid, int reconnect, int *newnid);
 extern int lprocfs_exp_cleanup(struct obd_export *exp);
 extern cfs_proc_dir_entry_t *lprocfs_add_simple(struct proc_dir_entry *root,
                                                 char *name,
@@ -763,8 +763,8 @@ static inline void lprocfs_free_md_stats(struct obd_device *obddev)
 struct obd_export;
 static inline int lprocfs_add_clear_entry(struct obd_export *exp)
 { return 0; }
-static inline int lprocfs_exp_setup(struct obd_export *exp,
-                                    lnet_nid_t *peer_nid, int *newnid)
+static inline int lprocfs_exp_setup(struct obd_export *exp,lnet_nid_t *peer_nid,
+                                    int reconnect, int *newnid)
 { return 0; }
 static inline int lprocfs_exp_cleanup(struct obd_export *exp)
 { return 0; }
index 1cb1fc4..aff8feb 100644 (file)
 
 int mdt_export_stats_init(struct obd_device *obd,
                           struct obd_export *exp,
+                          int               reconnect,
                           void              *localdata)
 {
         lnet_nid_t *client_nid = localdata;
         int        rc, newnid;
         ENTRY;
 
-        rc = lprocfs_exp_setup(exp, client_nid, &newnid);
+        rc = lprocfs_exp_setup(exp, client_nid, reconnect, &newnid);
         if (rc) {
                 /* Mask error for already created
                  * /proc entries */
index bb61110..b584ed4 100644 (file)
@@ -5030,7 +5030,7 @@ static int mdt_obd_connect(const struct lu_env *env,
                 memcpy(lcd->lcd_uuid, cluuid, sizeof lcd->lcd_uuid);
                 rc = mdt_client_new(env, mdt);
                 if (rc == 0)
-                        mdt_export_stats_init(obd, lexp, localdata);
+                        mdt_export_stats_init(obd, lexp, 0, localdata);
         }
 
 out:
@@ -5069,7 +5069,7 @@ static int mdt_obd_reconnect(const struct lu_env *env,
 
         rc = mdt_connect_internal(exp, mdt_dev(obd->obd_lu_dev), data);
         if (rc == 0)
-                mdt_export_stats_init(obd, exp, localdata);
+                mdt_export_stats_init(obd, exp, 1, localdata);
 
         RETURN(rc);
 }
index cecae70..fdee632 100644 (file)
@@ -576,6 +576,7 @@ int mdt_client_new(const struct lu_env *env,
 
 int mdt_export_stats_init(struct obd_device *obd,
                           struct obd_export *exp,
+                          int reconnect,
                           void *client_nid);
 
 int mdt_pin(struct mdt_thread_info* info);
index fc643f8..43e185e 100644 (file)
 #include <libcfs/list.h>
 #include "mgs_internal.h"
 
-static int mgs_export_stats_init(struct obd_device *obd, struct obd_export *exp,
-                                 void *localdata)
+int mgs_export_stats_init(struct obd_device *obd, struct obd_export *exp,
+                          int reconnect, void *localdata)
+
 {
         lnet_nid_t *client_nid = localdata;
         int rc, newnid;
         ENTRY;
 
-        rc = lprocfs_exp_setup(exp, client_nid, &newnid);
+        rc = lprocfs_exp_setup(exp, client_nid, reconnect, &newnid);
         if (rc) {
                 /* Mask error for already created
                  * /proc entries */
@@ -93,7 +94,7 @@ clean:
 int mgs_client_add(struct obd_device *obd, struct obd_export *exp,
                    void *localdata)
 {
-        return mgs_export_stats_init(obd, exp, localdata);
+        return 0;
 }
 
 /* Remove client export data from the MGS */
index d2ee15d..a8d8570 100644 (file)
@@ -90,7 +90,7 @@ static int mgs_connect(const struct lu_env *env,
                 data->ocd_version = LUSTRE_VERSION_CODE;
         }
 
-        rc = mgs_client_add(obd, lexp, localdata);
+        rc = mgs_export_stats_init(obd, lexp, 0, localdata);
 
         if (rc) {
                 class_disconnect(lexp);
@@ -119,7 +119,7 @@ static int mgs_reconnect(const struct lu_env *env,
                 data->ocd_version = LUSTRE_VERSION_CODE;
         }
 
-        RETURN(0);
+        RETURN(mgs_export_stats_init(obd, exp, 1, localdata));
 }
 
 static int mgs_disconnect(struct obd_export *exp)
index 703290b..35534d0 100644 (file)
@@ -114,8 +114,8 @@ int mgs_pool_cmd(struct obd_device *obd, enum lcfg_command_type cmd,
 void mgs_revoke_lock(struct obd_device *obd, struct fs_db *fsdb);
 
 /* mgs_fs.c */
-int mgs_client_add(struct obd_device *obd, struct obd_export *exp,
-                   void *localdata);
+int mgs_export_stats_init(struct obd_device *obd, struct obd_export *exp,
+                          int reconnect, void *localdata);
 int mgs_client_free(struct obd_export *exp);
 int mgs_fs_setup(struct obd_device *obd, struct vfsmount *mnt);
 int mgs_fs_cleanup(struct obd_device *obddev);
index a253894..f310c6d 100644 (file)
@@ -1761,7 +1761,8 @@ int lprocfs_nid_stats_clear_write(struct file *file, const char *buffer,
 }
 EXPORT_SYMBOL(lprocfs_nid_stats_clear_write);
 
-int lprocfs_exp_setup(struct obd_export *exp, lnet_nid_t *nid, int *newnid)
+int lprocfs_exp_setup(struct obd_export *exp, lnet_nid_t *nid, int reconnect,
+                      int *newnid)
 {
         struct nid_stat *new_stat, *old_stat;
         struct obd_device *obd = NULL;
@@ -1792,7 +1793,8 @@ int lprocfs_exp_setup(struct obd_export *exp, lnet_nid_t *nid, int *newnid)
 
         new_stat->nid               = *nid;
         new_stat->nid_obd           = exp->exp_obd;
-        cfs_atomic_set(&new_stat->nid_exp_ref_count, 0);
+        /* we need set default refcount to 1 to balance obd_disconnect */
+        cfs_atomic_set(&new_stat->nid_exp_ref_count, 1);
 
         old_stat = cfs_hash_findadd_unique(obd->obd_nid_stats_hash,
                                            nid, &new_stat->nid_hash);
@@ -1803,19 +1805,13 @@ int lprocfs_exp_setup(struct obd_export *exp, lnet_nid_t *nid, int *newnid)
         /* Return -EALREADY here so that we know that the /proc
          * entry already has been created */
         if (old_stat != new_stat) {
-                cfs_spin_lock(&obd->obd_nid_lock);
-                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 {
-                        /* cfs_hash_findadd_unique() has added
-                         * old_stat's refcount */
+                /* if this connects to the existing export of same nid,
+                 * we need to release old stats for obd_disconnect won't
+                 * balance the reference gotten in "cfs_hash_findadd_uinque" */
+                if (reconnect && exp->exp_nid_stats)
                         nidstat_putref(old_stat);
-                }
-
-                cfs_spin_unlock(&obd->obd_nid_lock);
 
+                exp->exp_nid_stats = old_stat;
                 GOTO(destroy_new, rc = -EALREADY);
         }
         /* not found - create */
@@ -1851,9 +1847,6 @@ 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 */
@@ -1869,6 +1862,7 @@ destroy_new_ns:
         cfs_hash_del(obd->obd_nid_stats_hash, nid, &new_stat->nid_hash);
 
 destroy_new:
+        nidstat_putref(new_stat);
         OBD_FREE_PTR(new_stat);
         RETURN(rc);
 }
index 8d11d00..3836656 100644 (file)
@@ -241,6 +241,7 @@ static int lprocfs_init_rw_stats(struct obd_device *obd,
    plus the procfs overhead :( */
 static int filter_export_stats_init(struct obd_device *obd,
                                     struct obd_export *exp,
+                                    int reconnect,
                                     void *client_nid)
 {
         int rc, newnid = 0;
@@ -250,7 +251,7 @@ static int filter_export_stats_init(struct obd_device *obd,
                 /* Self-export gets no proc entry */
                 RETURN(0);
 
-        rc = lprocfs_exp_setup(exp, client_nid, &newnid);
+        rc = lprocfs_exp_setup(exp, client_nid, reconnect, &newnid);
         if (rc) {
                 /* Mask error for already created
                  * /proc entries */
@@ -869,7 +870,7 @@ static int filter_init_server_data(struct obd_device *obd, struct file * filp)
                 fed = &exp->exp_filter_data;
                 *fed->fed_ted.ted_lcd = *lcd;
                 fed->fed_group = 0; /* will be assigned at connect */
-                filter_export_stats_init(obd, exp, NULL);
+                filter_export_stats_init(obd, exp, 0, NULL);
                 rc = filter_client_add(obd, exp, cl_idx);
                 /* can't fail for existing client */
                 LASSERTF(rc == 0, "rc = %d\n", rc);
@@ -2749,7 +2750,7 @@ static int filter_reconnect(const struct lu_env *env,
 
         rc = filter_connect_internal(exp, data, 1);
         if (rc == 0)
-                filter_export_stats_init(obd, exp, localdata);
+                filter_export_stats_init(obd, exp, 1, localdata);
 
         RETURN(rc);
 }
@@ -2780,7 +2781,7 @@ static int filter_connect(const struct lu_env *env,
         if (rc)
                 GOTO(cleanup, rc);
 
-        filter_export_stats_init(obd, lexp, localdata);
+        filter_export_stats_init(obd, lexp, 0, localdata);
         if (obd->obd_replayable) {
                 struct lsd_client_data *lcd = lexp->exp_target_data.ted_lcd;
                 LASSERT(lcd);