*/
/*
* (C) Copyright 2012 Commissariat a l'energie atomique et aux energies
+ *
+ * Copyright (c) 2016, Intel Corporation.
* alternatives
*
*/
RETURN(rc);
}
+int mdt_hsm_send_action_to_each_archive(struct mdt_thread_info *mti,
+ struct hsm_action_item *hai)
+{
+ __u64 compound_id;
+ struct hsm_agent *ha;
+ __u32 archive_mask = 0;
+ struct coordinator *cdt = &mti->mti_mdt->mdt_coordinator;
+ int i;
+ /* return error by default in case all archive_ids have unregistered */
+ int rc = -EAGAIN;
+ ENTRY;
+
+ /* send action to all registered archive_ids */
+ down_read(&cdt->cdt_agent_lock);
+ list_for_each_entry(ha, &cdt->cdt_agents, ha_list) {
+ for (i = 0; (i < ha->ha_archive_cnt); i++) {
+ /* only send once for each archive_id */
+ if ((1 << ha->ha_archive_id[i]) & archive_mask)
+ continue;
+ archive_mask |= (1 << ha->ha_archive_id[i]);
+
+ /* XXX: instead of creating one request record per
+ * new action, it could make sense to gather
+ * all for the same archive_id as one compound
+ * request/id, like in mdt_hsm_add_actions() ?? */
+ compound_id = atomic_inc_return(&cdt->cdt_compound_id);
+ rc = mdt_agent_record_add(mti->mti_env, mti->mti_mdt,
+ compound_id,
+ ha->ha_archive_id[i], 0,
+ hai);
+ if (rc) {
+ CERROR("%s: unable to add HSM remove request "
+ "for "DFID": rc=%d\n",
+ mdt_obd_name(mti->mti_mdt),
+ PFID(&hai->hai_fid), rc);
+ break;
+ } else {
+ CDEBUG(D_HSM, "%s: added HSM remove request "
+ "for "DFID", archive_id=%d\n",
+ mdt_obd_name(mti->mti_mdt),
+ PFID(&hai->hai_fid),
+ ha->ha_archive_id[i]);
+ }
+ }
+ /* early exit from loop due to error? */
+ if (i != ha->ha_archive_cnt)
+ break;
+ }
+ up_read(&cdt->cdt_agent_lock);
+
+ RETURN(rc);
+}
+
/**
* send a compound request to the agent
* \param mti [IN] context
ENTRY;
rc = mdt_hsm_find_best_agent(cdt, hal->hal_archive_id, &uuid);
+ if (rc && hal->hal_archive_id == 0) {
+ uint notrmcount = 0;
+ int rc2 = 0;
+
+ /* special case of remove requests with no archive_id specified,
+ * and no agent registered to serve all archives, then create a
+ * set of new requests, each to be sent to each registered
+ * archives.
+ * Todo so, find all HSMA_REMOVE entries, and then :
+ * _ set completed status as SUCCESS (or FAIL?)
+ * _ create a new LLOG record for each archive_id
+ * presently being served by any CT
+ */
+ hai = hai_first(hal);
+ for (i = 0; i < hal->hal_count; i++,
+ hai = hai_next(hai)) {
+ /* only removes are concerned */
+ if (hai->hai_action != HSMA_REMOVE) {
+ /* count if other actions than HSMA_REMOVE,
+ * to return original error/rc */
+ notrmcount++;
+ continue;
+ }
+
+ /* send remove request to all registered archive_ids */
+ rc2 = mdt_hsm_send_action_to_each_archive(mti, hai);
+ if (rc2)
+ break;
+
+ /* only update original request as SUCCEED if it has
+ * been successfully broadcasted to all available
+ * archive_ids
+ * XXX: this should only cause duplicates to be sent,
+ * unless a method to record already successfully
+ * reached archive_ids is implemented */
+ rc2 = mdt_agent_record_update(mti->mti_env, mdt,
+ &hai->hai_cookie,
+ 1, ARS_SUCCEED);
+ if (rc2) {
+ CERROR("%s: mdt_agent_record_update() "
+ "failed, cannot update "
+ "status to %s for cookie "
+ "%#llx: rc = %d\n",
+ mdt_obd_name(mdt),
+ agent_req_status2name(ARS_SUCCEED),
+ hai->hai_cookie, rc2);
+ break;
+ }
+ }
+ /* only remove requests with archive_id=0 */
+ if (notrmcount == 0)
+ RETURN(rc2);
+
+ }
+
if (rc) {
CERROR("%s: Cannot find agent for archive %d: rc = %d\n",
mdt_obd_name(mdt), hal->hal_archive_id, rc);
fail_request = false;
hai = hai_first(hal);
for (i = 0; i < hal->hal_count; i++, hai = hai_next(hai)) {
- if (hai->hai_action != HSMA_CANCEL) {
- struct mdt_object *obj;
- struct md_hsm hsm;
+ struct mdt_object *obj;
+ struct md_hsm hsm;
- obj = mdt_hsm_get_md_hsm(mti, &hai->hai_fid, &hsm);
- if (!IS_ERR(obj) && obj != NULL) {
- mdt_object_put(mti->mti_env, obj);
- } else {
- if (hai->hai_action == HSMA_REMOVE)
- continue;
-
- if (obj == NULL) {
- fail_request = true;
- rc = mdt_agent_record_update(
- mti->mti_env, mdt,
- &hai->hai_cookie,
- 1, ARS_FAILED);
- if (rc) {
- CERROR(
- "%s: mdt_agent_record_update() "
- "failed, cannot update "
- "status to %s for cookie "
- LPX64": rc = %d\n",
- mdt_obd_name(mdt),
- agent_req_status2name(ARS_FAILED),
- hai->hai_cookie, rc);
- GOTO(out_buf, rc);
- }
- continue;
- }
- GOTO(out_buf, rc = PTR_ERR(obj));
+ if (hai->hai_action == HSMA_CANCEL)
+ continue;
+
+ obj = mdt_hsm_get_md_hsm(mti, &hai->hai_fid, &hsm);
+ if (!IS_ERR(obj)) {
+ mdt_object_put(mti->mti_env, obj);
+ } else if (PTR_ERR(obj) == -ENOENT) {
+ if (hai->hai_action == HSMA_REMOVE)
+ continue;
+
+ fail_request = true;
+ rc = mdt_agent_record_update(mti->mti_env, mdt,
+ &hai->hai_cookie,
+ 1, ARS_FAILED);
+ if (rc < 0) {
+ CERROR("%s: mdt_agent_record_update() failed, "
+ "cannot update status to %s for cookie "
+ "%#llx: rc = %d\n",
+ mdt_obd_name(mdt),
+ agent_req_status2name(ARS_FAILED),
+ hai->hai_cookie, rc);
+ GOTO(out_buf, rc);
+ }
+
+ continue;
+ } else {
+ GOTO(out_buf, rc = PTR_ERR(obj));
+ }
+
+ if (!mdt_hsm_is_action_compat(hai, hal->hal_archive_id,
+ hal->hal_flags, &hsm)) {
+ /* incompatible request, we abort the request */
+ /* next time coordinator will wake up, it will
+ * make the same compound with valid only
+ * records */
+ fail_request = true;
+ rc = mdt_agent_record_update(mti->mti_env, mdt,
+ &hai->hai_cookie,
+ 1, ARS_FAILED);
+ if (rc) {
+ CERROR("%s: mdt_agent_record_update() failed, "
+ "cannot update status to %s for cookie "
+ "%#llx: rc = %d\n",
+ mdt_obd_name(mdt),
+ agent_req_status2name(ARS_FAILED),
+ hai->hai_cookie, rc);
+ GOTO(out_buf, rc);
}
- if (!mdt_hsm_is_action_compat(hai, hal->hal_archive_id,
- hal->hal_flags, &hsm)) {
- /* incompatible request, we abort the request */
- /* next time coordinator will wake up, it will
- * make the same compound with valid only
- * records */
- fail_request = true;
- rc = mdt_agent_record_update(mti->mti_env, mdt,
- &hai->hai_cookie,
- 1, ARS_FAILED);
- if (rc) {
- CERROR("%s: mdt_agent_record_update() "
- "failed, cannot update "
- "status to %s for cookie "
- LPX64": rc = %d\n",
- mdt_obd_name(mdt),
- agent_req_status2name(ARS_FAILED),
- hai->hai_cookie, rc);
- GOTO(out_buf, rc);
+ /* if restore and record status updated, give
+ * back granted layout lock */
+ if (hai->hai_action == HSMA_RESTORE) {
+ struct cdt_restore_handle *crh = NULL;
+
+ mutex_lock(&cdt->cdt_restore_lock);
+ crh = mdt_hsm_restore_hdl_find(cdt,
+ &hai->hai_fid);
+ if (crh != NULL)
+ list_del(&crh->crh_list);
+ mutex_unlock(&cdt->cdt_restore_lock);
+ if (crh != NULL) {
+ mdt_object_unlock(mti, NULL,
+ &crh->crh_lh, 1);
+ OBD_SLAB_FREE_PTR(crh,
+ mdt_hsm_cdt_kmem);
}
}
}
*/
exp = cfs_hash_lookup(mdt2obd_dev(mdt)->obd_uuid_hash, &uuid);
if (exp == NULL || exp->exp_disconnected) {
+ if (exp != NULL)
+ class_export_put(exp);
/* This should clean up agents on evicted exports */
rc = -ENOENT;
CERROR("%s: agent uuid (%s) not found, unregistering:"