From f79a2f1a19decfd1bed4857772e63dee01e151b2 Mon Sep 17 00:00:00 2001 From: "hongchao.zhang" Date: Sat, 10 Jul 2010 12:39:37 +0400 Subject: [PATCH] b=19069 cleanup on nid_stats entry refcount 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 | 6 +++--- lustre/mdt/mdt_fs.c | 3 ++- lustre/mdt/mdt_handler.c | 4 ++-- lustre/mdt/mdt_internal.h | 1 + lustre/mgs/mgs_fs.c | 9 +++++---- lustre/mgs/mgs_handler.c | 4 ++-- lustre/mgs/mgs_internal.h | 4 ++-- lustre/obdclass/lprocfs_status.c | 26 ++++++++++---------------- lustre/obdfilter/filter.c | 9 +++++---- 9 files changed, 32 insertions(+), 34 deletions(-) diff --git a/lustre/include/lprocfs_status.h b/lustre/include/lprocfs_status.h index 4555343..5631f28 100644 --- a/lustre/include/lprocfs_status.h +++ b/lustre/include/lprocfs_status.h @@ -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; } diff --git a/lustre/mdt/mdt_fs.c b/lustre/mdt/mdt_fs.c index 1cb1fc4..aff8feb 100644 --- a/lustre/mdt/mdt_fs.c +++ b/lustre/mdt/mdt_fs.c @@ -46,13 +46,14 @@ 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 */ diff --git a/lustre/mdt/mdt_handler.c b/lustre/mdt/mdt_handler.c index bb61110..b584ed4 100644 --- a/lustre/mdt/mdt_handler.c +++ b/lustre/mdt/mdt_handler.c @@ -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); } diff --git a/lustre/mdt/mdt_internal.h b/lustre/mdt/mdt_internal.h index cecae70..fdee632 100644 --- a/lustre/mdt/mdt_internal.h +++ b/lustre/mdt/mdt_internal.h @@ -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); diff --git a/lustre/mgs/mgs_fs.c b/lustre/mgs/mgs_fs.c index fc643f8..43e185e 100644 --- a/lustre/mgs/mgs_fs.c +++ b/lustre/mgs/mgs_fs.c @@ -58,14 +58,15 @@ #include #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 */ diff --git a/lustre/mgs/mgs_handler.c b/lustre/mgs/mgs_handler.c index d2ee15d..a8d8570 100644 --- a/lustre/mgs/mgs_handler.c +++ b/lustre/mgs/mgs_handler.c @@ -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) diff --git a/lustre/mgs/mgs_internal.h b/lustre/mgs/mgs_internal.h index 703290b..35534d0 100644 --- a/lustre/mgs/mgs_internal.h +++ b/lustre/mgs/mgs_internal.h @@ -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); diff --git a/lustre/obdclass/lprocfs_status.c b/lustre/obdclass/lprocfs_status.c index a253894..f310c6d 100644 --- a/lustre/obdclass/lprocfs_status.c +++ b/lustre/obdclass/lprocfs_status.c @@ -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); } diff --git a/lustre/obdfilter/filter.c b/lustre/obdfilter/filter.c index 8d11d00..3836656 100644 --- a/lustre/obdfilter/filter.c +++ b/lustre/obdfilter/filter.c @@ -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); -- 1.8.3.1