*/
int mdt_hsm_action(struct tgt_session_info *tsi)
{
- struct mdt_thread_info *info;
- struct hsm_current_action *hca;
- struct hsm_action_list *hal = NULL;
- struct hsm_action_item *hai;
- int hal_size;
- int rc;
+ struct mdt_thread_info *info;
+ struct hsm_current_action *hca;
+ enum hsm_copytool_action action; /* HSMA_* */
+ enum agent_req_status status; /* ARS_* */
+ struct hsm_extent extent;
+ int rc;
ENTRY;
hca = req_capsule_server_get(tsi->tsi_pill,
info = tsi2mdt_info(tsi);
/* Only valid if client is remote */
rc = mdt_init_ucred(info, (struct mdt_body *)info->mti_body);
- if (rc)
+ if (rc < 0)
GOTO(out, rc = err_serious(rc));
- /* Coordinator information */
- hal_size = sizeof(*hal) +
- cfs_size_round(MTI_NAME_MAXLEN) /* fsname */ +
- cfs_size_round(sizeof(*hai));
-
- MDT_HSM_ALLOC(hal, hal_size);
- if (hal == NULL)
- GOTO(out_ucred, rc = -ENOMEM);
-
- hal->hal_version = HAL_VERSION;
- hal->hal_archive_id = 0;
- hal->hal_flags = 0;
- obd_uuid2fsname(hal->hal_fsname, mdt_obd_name(info->mti_mdt),
- MTI_NAME_MAXLEN);
- hal->hal_count = 1;
- hai = hai_first(hal);
- hai->hai_action = HSMA_NONE;
- hai->hai_cookie = 0;
- hai->hai_gid = 0;
- hai->hai_fid = info->mti_body->mbo_fid1;
- hai->hai_len = sizeof(*hai);
-
- rc = mdt_hsm_get_actions(info, hal);
- if (rc)
- GOTO(out_free, rc);
-
- /* cookie is used to give back request status */
- if (hai->hai_cookie == 0)
- hca->hca_state = HPS_WAITING;
- else
- hca->hca_state = HPS_RUNNING;
+ rc = mdt_hsm_get_action(info, &info->mti_body->mbo_fid1, &action,
+ &status, &extent);
+ if (rc < 0)
+ GOTO(out_ucred, rc);
- switch (hai->hai_action) {
+ switch (action) {
case HSMA_NONE:
hca->hca_action = HUA_NONE;
break;
default:
hca->hca_action = HUA_NONE;
CERROR("%s: Unknown hsm action: %d on "DFID"\n",
- mdt_obd_name(info->mti_mdt),
- hai->hai_action, PFID(&hai->hai_fid));
+ mdt_obd_name(info->mti_mdt), action,
+ PFID(&info->mti_body->mbo_fid1));
break;
}
- hca->hca_location = hai->hai_extent;
+ switch (status) {
+ case ARS_WAITING:
+ hca->hca_state = HPS_WAITING;
+ break;
+ case ARS_STARTED:
+ hca->hca_state = HPS_RUNNING;
+ break;
+ default:
+ hca->hca_state = HPS_NONE;
+ break;
+ }
+
+ hca->hca_location = extent;
EXIT;
-out_free:
- MDT_HSM_FREE(hal, hal_size);
out_ucred:
mdt_exit_ucred(info);
out:
if (!lu_fid_eq(&hai->hai_fid, &larr->arr_hai.hai_fid))
continue;
- /* HSMA_NONE is used to find running request for some FID */
- if (hai->hai_action == HSMA_NONE) {
- hal->hal_archive_id = larr->arr_archive_id;
- hal->hal_flags = larr->arr_flags;
- *hai = larr->arr_hai;
- continue;
- }
/* in V1 we do not manage partial transfer
* so extent is always whole file
*/
ok_cnt = 0;
hai = hai_first(hal);
for (i = 0; i < hal->hal_count; i++, hai = hai_next(hai)) {
+ /* We only support ARCHIVE, RESTORE, REMOVE and CANCEL here. */
+ if (hai->hai_action == HSMA_NONE)
+ RETURN(-EINVAL);
+
/* in a cancel request hai_cookie may be set by caller to
* show the request to be canceled
* if not we need to search by FID
RETURN(is_running);
}
+struct hsm_get_action_data {
+ const struct lu_fid *hgad_fid;
+ struct hsm_action_item hgad_hai;
+ enum agent_req_status hgad_status;
+};
+
+static int hsm_get_action_cb(const struct lu_env *env,
+ struct llog_handle *llh,
+ struct llog_rec_hdr *hdr, void *data)
+{
+ struct llog_agent_req_rec *larr = (struct llog_agent_req_rec *)hdr;
+ struct hsm_get_action_data *hgad = data;
+
+ /* A compatible request must be WAITING or STARTED and not a
+ * cancel. */
+ if ((larr->arr_status != ARS_WAITING &&
+ larr->arr_status != ARS_STARTED) ||
+ larr->arr_hai.hai_action == HSMA_CANCEL ||
+ !lu_fid_eq(&larr->arr_hai.hai_fid, hgad->hgad_fid))
+ RETURN(0);
+
+ hgad->hgad_hai = larr->arr_hai;
+ hgad->hgad_status = larr->arr_status;
+
+ RETURN(LLOG_PROC_BREAK);
+}
+
/**
- * get registered action on a FID list
+ * get registered action on a FID
* \param mti [IN]
- * \param hal [IN/OUT] requests
+ * \param fid [IN]
+ * \param action [OUT]
+ * \param status [OUT]
+ * \param extent [OUT]
* \retval 0 success
* \retval -ve failure
*/
-int mdt_hsm_get_actions(struct mdt_thread_info *mti,
- struct hsm_action_list *hal)
+int mdt_hsm_get_action(struct mdt_thread_info *mti,
+ const struct lu_fid *fid,
+ enum hsm_copytool_action *action,
+ enum agent_req_status *status,
+ struct hsm_extent *extent)
{
- struct mdt_device *mdt = mti->mti_mdt;
- struct coordinator *cdt = &mdt->mdt_coordinator;
- struct hsm_action_item *hai;
- int i, rc;
+ const struct lu_env *env = mti->mti_env;
+ struct mdt_device *mdt = mti->mti_mdt;
+ struct coordinator *cdt = &mdt->mdt_coordinator;
+ struct hsm_get_action_data hgad = {
+ .hgad_fid = fid,
+ .hgad_hai.hai_action = HSMA_NONE,
+ };
+ struct cdt_agent_req *car;
+ int rc;
ENTRY;
- hai = hai_first(hal);
- for (i = 0; i < hal->hal_count; i++, hai = hai_next(hai)) {
- hai->hai_action = HSMA_NONE;
- if (!fid_is_sane(&hai->hai_fid))
- RETURN(-EINVAL);
- }
-
/* 1st we search in recorded requests */
- rc = hsm_find_compatible(mti->mti_env, mdt, hal);
- /* if llog file is not created, no action is recorded */
- if (rc == -ENOENT)
- RETURN(0);
-
- if (rc)
+ rc = cdt_llog_process(env, mdt, hsm_get_action_cb, &hgad, 0, 0, READ);
+ if (rc < 0)
RETURN(rc);
- /* 2nd we search if the request are running
- * cookie is cleared to tell to caller, the request is
- * waiting
- * we could in place use the record status, but in the future
- * we may want do give back dynamic informations on the
- * running request
- */
- hai = hai_first(hal);
- for (i = 0; i < hal->hal_count; i++, hai = hai_next(hai)) {
- struct cdt_agent_req *car;
+ *action = hgad.hgad_hai.hai_action;
+ *extent = hgad.hgad_hai.hai_extent;
+ *status = hgad.hgad_status;
- car = mdt_cdt_find_request(cdt, hai->hai_cookie);
- if (car == NULL) {
- hai->hai_cookie = 0;
- } else {
- __u64 data_moved;
-
- mdt_cdt_get_work_done(car, &data_moved);
- /* this is just to give the volume of data moved
- * it means data_moved data have been moved from the
- * original request but we do not know which one
- */
- hai->hai_extent.length = data_moved;
- mdt_cdt_put_request(car);
- }
+ if (*action == HSMA_NONE || *status != ARS_STARTED)
+ RETURN(0);
+
+ car = mdt_cdt_find_request(cdt, hgad.hgad_hai.hai_cookie);
+ if (car != NULL) {
+ __u64 data_moved;
+
+ mdt_cdt_get_work_done(car, &data_moved);
+ /* this is just to give the volume of data moved
+ * it means data_moved data have been moved from the
+ * original request but we do not know which one
+ */
+ extent->length = data_moved;
+ mdt_cdt_put_request(car);
}
RETURN(0);