@@ -224,6 +224,7 @@ static void fld_client_debugfs_init(struct lu_client_fld *fld)
ldebugfs_add_vars(fld->lcf_debugfs_entry, fld_client_debugfs_list, fld);
}
+EXPORT_SYMBOL(fld_client_del_target);
void fld_client_debugfs_fini(struct lu_client_fld *fld)
{
@@ -1592,6 +1592,7 @@ struct lu_tgt_descs {
u64 lu_prandom_u64_max(u64 ep_ro);
int lu_qos_add_tgt(struct lu_qos *qos, struct lu_tgt_desc *ltd);
+int lu_qos_del_tgt(struct lu_qos *qos, struct lu_tgt_desc *ltd);
void lu_tgt_qos_weight_calc(struct lu_tgt_desc *tgt);
int lu_tgt_descs_init(struct lu_tgt_descs *ltd, bool is_mdt);
@@ -593,6 +593,16 @@ int client_connect_import(const struct lu_env *env,
LASSERT(obd->obd_namespace);
+ spin_lock(&imp->imp_lock);
+ if (imp->imp_state == LUSTRE_IMP_CLOSED && imp->imp_deactive) {
+ /* need to reactivate import if trying to connect
+ * to a previously disconnected
+ */
+ imp->imp_deactive = 0;
+ imp->imp_invalid = 0;
+ }
+ spin_unlock(&imp->imp_lock);
+
imp->imp_dlm_handle = conn;
rc = ptlrpc_init_import(imp);
if (rc != 0)
@@ -631,8 +641,7 @@ int client_connect_import(const struct lu_env *env,
out_sem:
up_write(&cli->cl_sem);
- if (!rc && localdata) {
- LASSERT(!cli->cl_cache); /* only once */
+ if (!rc && localdata && !cli->cl_cache) {
cli->cl_cache = (struct cl_client_cache *)localdata;
cl_cache_incref(cli->cl_cache);
cli->cl_lru_left = &cli->cl_cache->ccc_lru_left;
@@ -363,6 +363,9 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt)
data->ocd_brw_size = MD_MAX_BRW_SIZE;
+retry_connect:
+ if (sb_rdonly(sb))
+ data->ocd_connect_flags |= OBD_CONNECT_RDONLY;
err = obd_connect(NULL, &sbi->ll_md_exp, sbi->ll_md_obd,
&sbi->ll_sb_uuid, data, sbi->ll_cache);
if (err == -EBUSY) {
@@ -405,8 +408,20 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt)
err = obd_statfs(NULL, sbi->ll_md_exp, osfs,
ktime_get_seconds() - sbi->ll_statfs_max_age,
OBD_STATFS_FOR_MDT0);
- if (err)
+ if (err == -EROFS && !sb_rdonly(sb)) {
+ /* We got -EROFS from the server, maybe it is imposing
+ * read-only mount. So just retry like this.
+ */
+ LCONSOLE_INFO("Forcing read-only mount.\n\r");
+ CERROR("%s: mount failed with %d, forcing read-only mount.\n",
+ sbi->ll_md_exp->exp_obd->obd_name, err);
+ sb->s_flags |= SB_RDONLY;
+ obd_fid_fini(sbi->ll_md_exp->exp_obd);
+ obd_disconnect(sbi->ll_md_exp);
+ goto retry_connect;
+ } else if (err) {
goto out_md_fid;
+ }
/* This needs to be after statfs to ensure connect has finished.
* Note that "data" does NOT contain the valid connect reply.
@@ -1329,8 +1344,8 @@ int ll_fill_super(struct super_block *sb)
if (err)
ll_put_super(sb);
else if (test_bit(LL_SBI_VERBOSE, sbi->ll_flags))
- LCONSOLE_WARN("Mounted %s\n", profilenm);
-
+ LCONSOLE_WARN("Mounted %s%s\n", profilenm,
+ sb_rdonly(sb) ? " read-only" : "");
return err;
} /* ll_fill_super */
@@ -494,24 +494,33 @@ static int lmv_disconnect_mdc(struct obd_device *obd, struct lmv_tgt_desc *tgt)
mdc_obd->obd_name);
}
+ rc = lu_qos_del_tgt(&lmv->lmv_qos, tgt);
+ if (rc)
+ CERROR("%s: Can't del target from QoS table: rc = %d\n",
+ tgt->ltd_exp->exp_obd->obd_name, rc);
+
+ rc = fld_client_del_target(&lmv->lmv_fld, tgt->ltd_index);
+ if (rc)
+ CERROR("%s: Can't del fld targets: rc = %d\n",
+ tgt->ltd_exp->exp_obd->obd_name, rc);
+
rc = obd_fid_fini(tgt->ltd_exp->exp_obd);
if (rc)
- CERROR("Can't finalize fids factory\n");
+ CERROR("%s: Can't finalize fids factory: rc = %d\n",
+ tgt->ltd_exp->exp_obd->obd_name, rc);
CDEBUG(D_INFO, "Disconnected from %s(%s) successfully\n",
tgt->ltd_exp->exp_obd->obd_name,
tgt->ltd_exp->exp_obd->obd_uuid.uuid);
+ lmv_activate_target(lmv, tgt, 0);
obd_register_observer(tgt->ltd_exp->exp_obd, NULL);
rc = obd_disconnect(tgt->ltd_exp);
if (rc) {
- if (tgt->ltd_active) {
- CERROR("Target %s disconnect error %d\n",
- tgt->ltd_uuid.uuid, rc);
- }
+ CERROR("%s: Target %s disconnect error: rc = %d\n",
+ tgt->ltd_exp->exp_obd->obd_name,
+ tgt->ltd_uuid.uuid, rc);
}
-
- lmv_activate_target(lmv, tgt, 0);
tgt->ltd_exp = NULL;
return 0;
}
@@ -170,7 +170,7 @@ int lu_qos_add_tgt(struct lu_qos *qos, struct lu_tgt_desc *tgt)
* Return: 0 on success
* -ENOENT if no server was found
*/
-static int lu_qos_del_tgt(struct lu_qos *qos, struct lu_tgt_desc *ltd)
+int lu_qos_del_tgt(struct lu_qos *qos, struct lu_tgt_desc *ltd)
{
struct lu_svr_qos *svr;
int rc = 0;
@@ -182,12 +182,12 @@ static int lu_qos_del_tgt(struct lu_qos *qos, struct lu_tgt_desc *ltd)
goto out;
}
+ ltd->ltd_qos.ltq_svr = NULL;
svr->lsq_tgt_count--;
if (svr->lsq_tgt_count == 0) {
CDEBUG(D_OTHER, "removing server %s\n",
obd_uuid2str(&svr->lsq_uuid));
list_del(&svr->lsq_svr_list);
- ltd->ltd_qos.ltq_svr = NULL;
kfree(svr);
}
@@ -196,6 +196,7 @@ static int lu_qos_del_tgt(struct lu_qos *qos, struct lu_tgt_desc *ltd)
up_write(&qos->lq_rw_sem);
return rc;
}
+EXPORT_SYMBOL(lu_qos_del_tgt);
static inline u64 tgt_statfs_bavail(struct lu_tgt_desc *tgt)
{