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,
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; }
rc = mds_connect_internal(exp, data);
if (rc == 0)
- mds_export_stats_init(obd, exp, localdata);
+ mds_export_stats_init(obd, exp, 1, localdata);
RETURN(rc);
}
int mds_export_stats_init(struct obd_device *obd,
struct obd_export *exp,
+ int reconnect,
void *localdata)
{
lnet_nid_t *client_nid = localdata;
int rc, num_stats, newnid = 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 */
med->med_lr_off = le32_to_cpu(mds->mds_server_data->lsd_client_start) +
(cl_idx * le16_to_cpu(mds->mds_server_data->lsd_client_size));
LASSERTF(med->med_lr_off > 0, "med_lr_off = %llu\n", med->med_lr_off);
- mds_export_stats_init(obd, exp, localdata);
+ mds_export_stats_init(obd, exp, 0, localdata);
if (new_client) {
struct lvfs_run_ctxt *saved = NULL;
void mds_update_last_epoch(struct obd_device *obd);
int mds_export_stats_init(struct obd_device *obd,
struct obd_export *exp,
+ int reconnect,
void *client_nid);
int mds_client_add(struct obd_device *obd, struct obd_export *exp,
int cl_off, void *localdata);
#include "mgs_internal.h"
-static int mgs_export_stats_init(struct obd_device *obd,
+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, num_stats, newnid = 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 */
struct obd_export *exp,
void *localdata)
{
- return mgs_export_stats_init(obd, exp, localdata);
+ return 0;
}
/* Remove client export data from the MGS */
data->ocd_version = LUSTRE_VERSION_CODE;
}
- rc = mgs_client_add(obd, exp, localdata);
-
+ rc = mgs_export_stats_init(obd, exp, 0, localdata);
if (rc) {
class_disconnect(exp);
lprocfs_exp_cleanup(exp);
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)
char *poolname, char *fsname, char *ostname);
/* 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);
}
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)
{
int rc = 0;
struct nid_stat *new_stat, *old_stat;
new_stat->nid = *nid;
new_stat->nid_obd = exp->exp_obd;
- atomic_set(&new_stat->nid_exp_ref_count, 0);
+ /* we need set default refcount to 1 to balance obd_disconnect() */
+ atomic_set(&new_stat->nid_exp_ref_count, 1);
old_stat = lustre_hash_findadd_unique(obd->obd_nid_stats_hash,
nid, &new_stat->nid_hash);
/* Return -EALREADY here so that we know that the /proc
* entry already has been created */
if (old_stat != new_stat) {
- 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 {
- /* lustre_hash_findadd_unique() has added
- * old_stat's refcount */
- nidstat_putref(old_stat);
- }
-
- spin_unlock(&obd->obd_nid_lock);
+ /* if this reconnect to live export from diffrent nid, we need
+ * to release old stats because disconnect will be never called.
+ * */
+ if (reconnect && exp->exp_nid_stats)
+ nidstat_putref(exp->exp_nid_stats);
+ exp->exp_nid_stats = old_stat;
GOTO(destroy_new, rc = -EALREADY);
}
+
/* not found - create */
new_stat->nid_proc = proc_mkdir(libcfs_nid2str(*nid),
obd->obd_proc_exports_entry);
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 */
lustre_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);
}
plus the procfs overhead :( */
static int filter_export_stats_init(struct obd_device *obd,
struct obd_export *exp,
+ int reconnect,
void *client_nid)
{
struct proc_dir_entry *brw_entry;
if (obd_uuid_equals(&exp->exp_client_uuid, &obd->obd_uuid))
/* Self-export gets no proc entry */
RETURN(0);
- rc = lprocfs_exp_setup(exp, (lnet_nid_t *)client_nid, &newnid);
+ rc = lprocfs_exp_setup(exp, (lnet_nid_t *)client_nid,
+ reconnect, &newnid);
if (rc) {
/* Mask error for already created
* /proc entries */
} else {
fed = &exp->exp_filter_data;
fed->fed_lcd = lcd;
- 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);
rc = filter_connect_internal(exp, data);
if (rc == 0)
- filter_export_stats_init(obd, exp, localdata);
+ filter_export_stats_init(obd, exp, 1, localdata);
RETURN(rc);
}
if (rc)
GOTO(cleanup, rc);
- filter_export_stats_init(obd, exp, localdata);
+ filter_export_stats_init(obd, exp, 0, localdata);
if (!obd->obd_replayable)
GOTO(cleanup, rc = 0);