int (*o_connect)(struct lustre_handle *conn, struct obd_device *src,
struct obd_uuid *cluuid, struct obd_connect_data *data,
unsigned long flags);
- int (*o_connect_post)(struct obd_export *exp, unsigned long flags);
+ int (*o_connect_post)(struct obd_export *exp, unsigned, unsigned long);
int (*o_disconnect)(struct obd_export *exp, unsigned long flags);
int (*o_statfs)(struct obd_device *obd, struct obd_statfs *osfs,
}
static inline int obd_connect_post(struct obd_export *exp,
+ unsigned initial,
unsigned long flags)
{
int rc;
if (!OBT(exp->exp_obd) || !OBP((exp->exp_obd), connect_post))
RETURN(0);
OBD_COUNTER_INCREMENT(exp->exp_obd, connect_post);
- rc = OBP(exp->exp_obd, connect_post)(exp, flags);
+ rc = OBP(exp->exp_obd, connect_post)(exp, initial, flags);
RETURN(rc);
}
class_import_put(revimp);
- rc = obd_connect_post(export, connect_flags);
+ rc = obd_connect_post(export, initial_conn, connect_flags);
out:
if (rc)
req->rq_status = rc;
return rc;
}
-static int mds_connect_post(struct obd_export *exp, unsigned long flags)
+static int mds_connect_post(struct obd_export *exp, unsigned initial,
+ unsigned long flags)
{
struct obd_device *obd = exp->exp_obd;
struct mds_obd *mds = &obd->u.mds;
+ struct mds_export_data *med;
+ struct mds_client_data *mcd;
int rc = 0;
ENTRY;
+ med = &exp->exp_mds_data;
+ mcd = med->med_mcd;
+
+ if (initial) {
+ /* some one reconnect initially, we have to reset
+ * data existing export can have. bug 6102 */
+ if (mcd->mcd_last_xid != 0)
+ CDEBUG(D_HA, "initial reconnect to existing export\n");
+ mcd->mcd_last_transno = 0;
+ mcd->mcd_last_xid = 0;
+ mcd->mcd_last_result = 0;
+ mcd->mcd_last_data = 0;
+ }
+
if (!(flags & OBD_OPT_MDS_CONNECTION)) {
if (!(exp->exp_flags & OBD_OPT_REAL_CLIENT)) {
atomic_inc(&mds->mds_real_clients);
return rc;
}
-int mds_postrecov(struct obd_device *obd)
+int mds_postrecov_common(struct obd_device *obd)
{
struct mds_obd *mds = &obd->u.mds;
struct llog_ctxt *ctxt;
goto out;
}
+int mds_postrecov(struct obd_device *obd)
+{
+ int rc;
+ ENTRY;
+ rc = mds_postrecov_common(obd);
+ if (rc == 0)
+ rc = mds_md_reconnect(obd);
+ RETURN(rc);
+}
+
int mds_dt_clean(struct obd_device *obd)
{
struct mds_obd *mds = &obd->u.mds;
extern struct lvfs_callback_ops mds_lvfs_ops;
int mds_dt_clean(struct obd_device *obd);
int mds_postrecov(struct obd_device *obd);
+int mds_postrecov_common(struct obd_device *obd);
extern struct lvfs_callback_ops mds_lvfs_ops;
extern int mds_iocontrol(unsigned int cmd,
int mds_lock_and_check_slave(int, struct ptlrpc_request *, struct lustre_handle *);
int mds_convert_mea_ea(struct obd_device *, struct inode *, struct lov_mds_md *, int);
int mds_is_dir_empty(struct obd_device *, struct dentry *);
+int mds_md_reconnect(struct obd_device *obd);
/* mds_lsd.c */
struct upcall_cache *__mds_get_global_lsd_cache(void);
RETURN(rc);
}
+int mds_md_reconnect(struct obd_device *obd)
+{
+ struct mds_obd *mds = &obd->u.mds;
+ struct obd_statfs osfs;
+ int err;
+ ENTRY;
+
+ /* We don't know state of connections to another MDSes
+ * before the failure. If MDS we were connected to before
+ * the failure gets failed, then it will wait for us to
+ * reconnect and will timed recovery out. bug 4920 */
+ if (mds->mds_md_connected == 0)
+ RETURN(0);
+ if (mds->mds_md_obd == NULL)
+ RETURN(0);
+
+ err = obd_statfs(mds->mds_md_obd, &osfs, jiffies - HZ);
+ if (err)
+ CERROR("can't reconnect to MDSes after recovery: %d\n", err);
+ RETURN(0);
+}
+
int mds_md_get_attr(struct obd_device *obd, struct inode *inode,
struct mea **mea, int *mea_size)
{
* it can use the obd_recovering flag to determine when the
* the OBD is full available. */
if (!obd->obd_recovering)
- rc = mds_postrecov(obd);
+ rc = mds_postrecov_common(obd);
RETURN(rc);
err_reg:
RETURN(0);
}
-static int filter_connect_post(struct obd_export *exp, unsigned long connect_flags)
+static int filter_connect_post(struct obd_export *exp, unsigned initial,
+ unsigned long connect_flags)
{
struct obd_device *obd = exp->exp_obd;
struct filter_export_data *fed;