*rootfid = body->fid1;
CDEBUG(D_NET,
- "root fid="DFID", last_committed="LPU64", last_xid="LPU64"\n",
+ "root fid="DFID", last_committed="LPU64"\n",
PFID(rootfid),
- lustre_msg_get_last_committed(req->rq_repmsg),
- lustre_msg_get_last_xid(req->rq_repmsg));
+ lustre_msg_get_last_committed(req->rq_repmsg));
EXIT;
out:
ptlrpc_req_finished(req);
RETURN(rc);
}
-static int mdt_mfd_cleanup(struct obd_export *exp)
+static int mdt_export_cleanup(struct obd_export *exp)
{
struct mdt_export_data *med = &exp->exp_mdt_data;
struct obd_device *obd = exp->exp_obd;
ma->ma_valid = MA_FLAGS;
mdt_mfd_close(info, mfd);
}
- info->mti_mdt = NULL;
OBD_FREE(ma->ma_cookie, cookie_size);
ma->ma_cookie = NULL;
out_cookie:
ma->ma_lmm = NULL;
}
out_lmm:
+ info->mti_mdt = NULL;
+ /* cleanup client slot early */
+ mdt_client_del(&env, mdt);
lu_env_fini(&env);
RETURN(rc);
if (rc != 0)
CDEBUG(D_IOCTL, "server disconnect error: %d\n", rc);
- rc = mdt_mfd_cleanup(exp);
+ rc = mdt_export_cleanup(exp);
class_export_put(exp);
RETURN(rc);
}
RETURN(rc);
}
-static int mdt_destroy_export(struct obd_export *export)
+static int mdt_destroy_export(struct obd_export *exp)
{
struct mdt_export_data *med;
- struct obd_device *obd = export->exp_obd;
- struct mdt_device *mdt;
- struct mdt_thread_info *info;
- struct lu_env env;
int rc = 0;
ENTRY;
- med = &export->exp_mdt_data;
- if (exp_connect_rmtclient(export))
- mdt_cleanup_idmap(med);
+ med = &exp->exp_mdt_data;
+ if (exp_connect_rmtclient(exp))
+ mdt_cleanup_idmap(&exp->exp_mdt_data);
- target_destroy_export(export);
- ldlm_destroy_export(export);
+ target_destroy_export(exp);
+ ldlm_destroy_export(exp);
- LASSERT(list_empty(&export->exp_outstanding_replies));
- LASSERT(list_empty(&med->med_open_head));
- if (obd_uuid_equals(&export->exp_client_uuid, &obd->obd_uuid))
+ LASSERT(list_empty(&exp->exp_outstanding_replies));
+ LASSERT(list_empty(&exp->exp_mdt_data.med_open_head));
+ if (obd_uuid_equals(&exp->exp_client_uuid, &exp->exp_obd->obd_uuid))
RETURN(0);
- mdt = mdt_dev(obd->obd_lu_dev);
- LASSERT(mdt != NULL);
-
- rc = lu_env_init(&env, LCT_MD_THREAD);
- if (rc)
- RETURN(rc);
-
- info = lu_context_key_get(&env.le_ctx, &mdt_thread_key);
- LASSERT(info != NULL);
- memset(info, 0, sizeof *info);
- info->mti_env = &env;
- info->mti_exp = export;
- info->mti_mdt = NULL;
- mdt_client_del(&env, mdt);
-
- lu_env_fini(&env);
RETURN(rc);
}
req->rq_transno = info->mti_transno;
lustre_msg_set_transno(req->rq_repmsg, info->mti_transno);
- lustre_msg_set_last_xid(req->rq_repmsg, req->rq_xid);
EXIT;
}
mutex_down(&med->med_lcd_lock);
memset(lcd, 0, sizeof *lcd);
rc = mdt_last_rcvd_write(env, mdt, lcd, &off, th);
+ med->med_lcd = NULL;
mutex_up(&med->med_lcd_lock);
mdt_trans_stop(env, mdt, th);
CDEBUG(rc == 0 ? D_INFO : D_ERROR, "Zeroing out client idx %u in "
"%s, rc %d\n", med->med_lr_idx, LAST_RCVD, rc);
- EXIT;
-free:
OBD_FREE_PTR(lcd);
+ RETURN(0);
+free:
+ mutex_down(&med->med_lcd_lock);
med->med_lcd = NULL;
+ mutex_up(&med->med_lcd_lock);
+ OBD_FREE_PTR(lcd);
return 0;
}
LASSERT(mdt);
med = &req->rq_export->exp_mdt_data;
LASSERT(med);
+
+ mutex_down(&med->med_lcd_lock);
lcd = med->med_lcd;
- /* if the export has already been failed, we have no last_rcvd slot */
- if (req->rq_export->exp_failed) {
+ /* if the export has already been disconnected, we have no last_rcvd slot,
+ * update server data with latest transno then */
+ if (lcd == NULL) {
+ mutex_up(&med->med_lcd_lock);
CWARN("commit transaction for disconnected client %s: rc %d\n",
req->rq_export->exp_client_uuid.uuid, rc);
- if (rc == 0)
- rc = -ENOTCONN;
- RETURN(rc);
+ err = mdt_last_rcvd_header_write(mti->mti_env, mdt, th);
+ RETURN(err);
}
off = med->med_lr_off;
LASSERT(ergo(mti->mti_transno == 0, rc != 0));
- mutex_down(&med->med_lcd_lock);
if (lustre_msg_get_opc(req->rq_reqmsg) == MDS_CLOSE ||
lustre_msg_get_opc(req->rq_reqmsg) == MDS_DONE_WRITING) {
if (mti->mti_transno != 0)
req->rq_transno = mti->mti_transno;
lustre_msg_set_transno(req->rq_repmsg, mti->mti_transno);
- lustre_msg_set_last_xid(req->rq_repmsg,
- lcd_last_xid(req->rq_export->exp_mdt_data.med_lcd));
/* save transno for the commit callback */
txi->txi_transno = mti->mti_transno;
{
struct filter_obd *filter = &exp->exp_obd->u.filter;
struct filter_export_data *fed = &exp->exp_filter_data;
- struct lsd_client_data *lcd = fed->fed_lcd;
+ struct lsd_client_data *lcd;
__u64 last_rcvd;
loff_t off;
int err, log_pri = D_RPCTRACE;
if (!exp->exp_obd->obd_replayable || oti == NULL)
RETURN(rc);
+ mutex_down(&fed->fed_lcd_lock);
+ lcd = fed->fed_lcd;
+ /* if the export has already been disconnected, we have no last_rcvd slot,
+ * update server data with latest transno then */
+ if (lcd == NULL) {
+ mutex_up(&fed->fed_lcd_lock);
+ CWARN("commit transaction for disconnected client %s: rc %d\n",
+ exp->exp_client_uuid.uuid, rc);
+ err = filter_update_server_data(exp->exp_obd,
+ filter->fo_rcvd_filp,
+ filter->fo_fsd);
+ RETURN(err);
+ }
+
/* we don't allocate new transnos for replayed requests */
spin_lock(&filter->fo_translock);
if (oti->oti_transno == 0) {
CDEBUG(log_pri, "wrote trans "LPU64" for client %s at #%d: err = %d\n",
last_rcvd, lcd->lcd_uuid, fed->fed_lr_idx, err);
-
+ mutex_up(&fed->fed_lcd_lock);
RETURN(rc);
}
fed->fed_lr_idx = cl_idx;
fed->fed_lr_off = le32_to_cpu(filter->fo_fsd->lsd_client_start) +
cl_idx * le16_to_cpu(filter->fo_fsd->lsd_client_size);
+ init_mutex(&fed->fed_lcd_lock);
LASSERTF(fed->fed_lr_off > 0, "fed_lr_off = %llu\n", fed->fed_lr_off);
CDEBUG(D_INFO, "client at index %d (%llu) with UUID '%s' added\n",
struct filter_obd *filter = &exp->exp_obd->u.filter;
struct obd_device *obd = exp->exp_obd;
struct lvfs_run_ctxt saved;
+ struct lsd_client_data *lcd = fed->fed_lcd;
int rc;
loff_t off;
ENTRY;
- if (fed->fed_lcd == NULL)
+ if (lcd == NULL)
RETURN(0);
/* XXX if lcd_uuid were a real obd_uuid, I could use obd_uuid_equals */
- if (strcmp(fed->fed_lcd->lcd_uuid, obd->obd_uuid.uuid ) == 0)
+ if (strcmp(lcd->lcd_uuid, obd->obd_uuid.uuid ) == 0)
GOTO(free, 0);
LASSERT(filter->fo_last_rcvd_slots != NULL);
off = fed->fed_lr_off;
CDEBUG(D_INFO, "freeing client at idx %u, offset %lld with UUID '%s'\n",
- fed->fed_lr_idx, fed->fed_lr_off, fed->fed_lcd->lcd_uuid);
+ fed->fed_lr_idx, fed->fed_lr_off, lcd->lcd_uuid);
/* Don't clear fed_lr_idx here as it is likely also unset. At worst
* we leak a client slot that will be cleaned on the next recovery. */
* be in server data or in client data in case of failure */
filter_update_server_data(obd, filter->fo_rcvd_filp, filter->fo_fsd);
+ mutex_down(&fed->fed_lcd_lock);
rc = fsfilt_write_record(obd, filter->fo_rcvd_filp, &zero_lcd,
sizeof(zero_lcd), &off, 0);
+ fed->fed_lcd = NULL;
+ mutex_up(&fed->fed_lcd_lock);
pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
CDEBUG(rc == 0 ? D_INFO : D_ERROR,
"zero out client %s at idx %u/%llu in %s, rc %d\n",
- fed->fed_lcd->lcd_uuid, fed->fed_lr_idx, fed->fed_lr_off,
+ lcd->lcd_uuid, fed->fed_lr_idx, fed->fed_lr_off,
LAST_RCVD, rc);
if (!test_and_clear_bit(fed->fed_lr_idx, filter->fo_last_rcvd_slots)) {
fed->fed_lr_idx);
LBUG();
}
-
- EXIT;
+ OBD_FREE_PTR(lcd);
+ RETURN(0);
free:
- OBD_FREE_PTR(fed->fed_lcd);
+ mutex_down(&fed->fed_lcd_lock);
fed->fed_lcd = NULL;
+ mutex_up(&fed->fed_lcd_lock);
+ OBD_FREE_PTR(lcd);
return 0;
}
RETURN(0);
- if (exp->exp_obd->obd_replayable)
- filter_client_free(exp);
- else
+ if (!exp->exp_obd->obd_replayable)
fsfilt_sync(exp->exp_obd, exp->exp_obd->u.obt.obt_sb);
filter_grant_discard(exp);
rc = server_disconnect_export(exp);
- fsfilt_sync(obd, obd->u.obt.obt_sb);
+ if (exp->exp_obd->obd_replayable)
+ filter_client_free(exp);
+ else
+ fsfilt_sync(obd, obd->u.obt.obt_sb);
class_export_put(exp);
RETURN(rc);