From: Alexander Boyko Date: Fri, 13 Dec 2024 12:57:17 +0000 (+0100) Subject: LU-18556 hsm: optimize llog record modification X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=07f6a59ad71324ed253c2eba519cf095f346bde9;p=fs%2Flustre-release.git LU-18556 hsm: optimize llog record modification This commit introduces a new llog modification mechanism for HSM operations to address inefficiencies caused by prior reliance on catalog processing. The new approach directly modifies llog record, eliminating the need for catalog-based processing and reducing latency. Key changes include: * Replacing the hsm_action_item (HAI) with a full in-memory llog record representation, increasing memory usage by ~80 bytes per record but removing the need for a dedicated llog cookie hash table. * Unifying the coordinator's read/store logic for HAI data into a single in-memory item shared by mdt_hsm_agent_send() and mdt_hsm_add_hsr(). This reduces memory allocation steps: only one cdt_agent_req allocation is now required during llog read operations, eliminating subsequent allocations/copies. Performance results on VMs 2 MDTs/2 OSTs/2 Clients no-op copytool: Test 1 (1M archive requests): 572s -> 187s (~3 times faster) Test 2 (1M archive + 1M queued): 558s -> 392s (~1.4 times faster) HPE-bug-id: LUS-12583 Signed-off-by: Alexander Boyko Change-Id: I4b6e697bc3b1f0cf2c76f5433b49affbc933c653 Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/57428 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Nikitas Angelinas Reviewed-by: Etienne AUJAMES Reviewed-by: Oleg Drokin --- diff --git a/lustre/include/lustre_log.h b/lustre/include/lustre_log.h index 31d0305..a88b13e 100644 --- a/lustre/include/lustre_log.h +++ b/lustre/include/lustre_log.h @@ -164,6 +164,9 @@ int llog_cat_reverse_process(const struct lu_env *env, void *data); int llog_cat_retain_cb(const struct lu_env *env, struct llog_handle *cat, struct llog_rec_hdr *rec, void *data); +int llog_cat_modify_rec(const struct lu_env *env, struct llog_handle *cathandle, + struct llog_logid *lid, struct llog_rec_hdr *hdr, + struct llog_cookie *cookie); /* llog_obd.c */ int llog_setup(const struct lu_env *env, struct obd_device *obd, struct obd_llog_group *olg, int index, @@ -600,7 +603,7 @@ int llog_open_create(const struct lu_env *env, struct llog_ctxt *ctxt, char *name); int llog_erase(const struct lu_env *env, struct llog_ctxt *ctxt, struct llog_logid *logid, char *name); -int llog_get_cookie(const struct lu_env *env, struct llog_cookie *out); +void llog_get_cookie(const struct lu_env *env, struct llog_cookie *out); int llog_write_cookie(const struct lu_env *env, struct llog_handle *loghandle, struct llog_rec_hdr *rec, struct llog_cookie *cookie, int idx); diff --git a/lustre/include/uapi/linux/lustre/lustre_idl.h b/lustre/include/uapi/linux/lustre/lustre_idl.h index cc59756..ef4bc35 100644 --- a/lustre/include/uapi/linux/lustre/lustre_idl.h +++ b/lustre/include/uapi/linux/lustre/lustre_idl.h @@ -2920,6 +2920,12 @@ struct llog_rec_tail { __u32 lrt_index; } __attribute__((packed)); +static inline struct llog_rec_tail *llog_get_rec_tail(struct llog_rec_hdr *rec) +{ + return (struct llog_rec_tail *)((char *)rec + rec->lrh_len - + sizeof(struct llog_rec_tail)); +} + /* Where data follow just after header */ #define REC_DATA(ptr) \ ((void *)((char *)ptr + sizeof(struct llog_rec_hdr))) diff --git a/lustre/mdt/mdt_coordinator.c b/lustre/mdt/mdt_coordinator.c index a1d113c..ec2411c 100644 --- a/lustre/mdt/mdt_coordinator.c +++ b/lustre/mdt/mdt_coordinator.c @@ -104,16 +104,6 @@ void mdt_hsm_dump_hal(int level, const char *prefix, } } -/** - * data passed to llog_cat_process() callback - * to scan requests and take actions - */ -struct hsm_scan_request { - int hal_sz; - int hal_used_sz; - struct hsm_action_list *hal; -}; - struct hsm_scan_data { struct mdt_thread_info *hsd_mti; char hsd_fsname[MTI_NAME_MAXLEN + 1]; @@ -130,6 +120,32 @@ struct hsm_scan_data { struct hsm_scan_request *hsd_request; }; +static inline int mdt_cdt_check_rec(struct llog_agent_req_rec *rec, size_t size) +{ + ENTRY; + + if (rec->arr_hdr.lrh_len > size || + rec->arr_hdr.lrh_len < sizeof(*rec) || + rec->arr_hdr.lrh_type != HSM_AGENT_REC || + rec->arr_hdr.lrh_index != + llog_get_rec_tail(&rec->arr_hdr)->lrt_index || + rec->arr_hdr.lrh_len != llog_get_rec_tail(&rec->arr_hdr)->lrt_len) + RETURN(-EBADR); + + if (rec->arr_status > ARS_SUCCEED) + RETURN(-EBADR); + + if (rec->arr_hai.hai_len > rec->arr_hdr.lrh_len || + rec->arr_hai.hai_len < sizeof(rec->arr_hai) || + (rec->arr_hai.hai_action != HSMA_NONE && + rec->arr_hai.hai_action < HSMA_ARCHIVE && + rec->arr_hai.hai_action > HSMA_CANCEL) || + rec->arr_hai.hai_cookie == 0) + RETURN(-EBADR); + + RETURN(0); +} + static int mdt_cdt_waiting_cb(const struct lu_env *env, struct mdt_device *mdt, struct llog_handle *llh, @@ -138,7 +154,9 @@ static int mdt_cdt_waiting_cb(const struct lu_env *env, { struct coordinator *cdt = &mdt->mdt_coordinator; struct hsm_scan_request *request; - struct hsm_action_item *hai; + struct cdt_agent_req *car; + struct obd_uuid uuid = {.uuid = {0}}; + struct llog_cookie cookie; size_t hai_size; u32 archive_id; bool wrapped; @@ -165,11 +183,10 @@ static int mdt_cdt_waiting_cb(const struct lu_env *env, hai_size = round_up(larr->arr_hai.hai_len, 8); archive_id = larr->arr_archive_id; - /* Can we add this action to one of the existing HALs in hsd. */ request = NULL; for (i = 0; i < hsd->hsd_request_count; i++) { - if (hsd->hsd_request[i].hal->hal_archive_id == archive_id && - hsd->hsd_request[i].hal_used_sz + hai_size <= + if (hsr_get_archive_id(&hsd->hsd_request[i]) == archive_id && + hsd->hsd_request[i].hsr_used_sz + hai_size <= LDLM_MAXREQSIZE) { request = &hsd->hsd_request[i]; break; @@ -182,7 +199,7 @@ static int mdt_cdt_waiting_cb(const struct lu_env *env, /* Is there really no compatible hsm_scan_request? */ if (!request) { for (i -= 1; i >= 0; i--) { - if (hsd->hsd_request[i].hal->hal_archive_id == + if (hsr_get_archive_id(&hsd->hsd_request[i]) == archive_id) { request = &hsd->hsd_request[i]; break; @@ -190,30 +207,40 @@ static int mdt_cdt_waiting_cb(const struct lu_env *env, } } - /* Make room for the hai */ + /* Make room for the car */ if (request) { - /* Discard the last hai until there is enough space */ + /* Discard the last car until there is enough space */ do { - request->hal->hal_count--; + request->hsr_count--; - hai = hai_first(request->hal); - for (i = 0; i < request->hal->hal_count; i++) - hai = hai_next(hai); - request->hal_used_sz -= - round_up(hai->hai_len, 8); + car = list_last_entry(&request->hsr_cars, + struct cdt_agent_req, + car_scan_list); + list_del_init(&car->car_scan_list); + + request->hsr_used_sz -= + round_up(car->car_hai.hai_len, 8); + + mdt_cdt_put_request(car); hsd->hsd_action_count--; - } while (request->hal_used_sz + hai_size > + } while (request->hsr_used_sz + hai_size > LDLM_MAXREQSIZE); } else if (hsd->hsd_housekeeping) { struct hsm_scan_request *tmp; + struct cdt_agent_req *pos; + struct cdt_agent_req *tmp2; - /* Discard the (whole) last hal */ + /* Discard the (whole) records from request */ hsd->hsd_request_count--; LASSERT(hsd->hsd_request_count >= 0); tmp = &hsd->hsd_request[hsd->hsd_request_count]; - hsd->hsd_action_count -= tmp->hal->hal_count; + hsd->hsd_action_count -= tmp->hsr_count; LASSERT(hsd->hsd_action_count >= 0); - OBD_FREE(tmp->hal, tmp->hal_sz); + list_for_each_entry_safe(pos, tmp2, &tmp->hsr_cars, + car_scan_list) { + list_del_init(&pos->car_scan_list); + mdt_cdt_put_request(pos); + } } else { /* Bailing out, this code path is too hot */ RETURN(LLOG_PROC_BREAK); @@ -222,66 +249,47 @@ static int mdt_cdt_waiting_cb(const struct lu_env *env, } if (!request) { - size_t count = round_up(MTI_NAME_MAXLEN + 1, 8) + 2 * hai_size; - struct hsm_action_list *hal; - LASSERT(hsd->hsd_request_count < hsd->hsd_request_len); request = &hsd->hsd_request[hsd->hsd_request_count]; - /* allocates hai vector size just needs to be large - * enough */ - request->hal_sz = sizeof(*request->hal) + count; - OBD_ALLOC_LARGE(hal, request->hal_sz); - if (!hal) - RETURN(-ENOMEM); - - hal->hal_version = HAL_VERSION; - strscpy(hal->hal_fsname, hsd->hsd_fsname, MTI_NAME_MAXLEN + 1); - hal->hal_archive_id = larr->arr_archive_id; - hal->hal_flags = larr->arr_flags; - hal->hal_count = 0; - request->hal_used_sz = hal_size(hal); - request->hal = hal; + INIT_LIST_HEAD(&request->hsr_cars); + request->hsr_fsname = &hsd->hsd_fsname[0]; + request->hsr_version = HAL_VERSION; + request->hsr_count = 0; + request->hsr_used_sz = sizeof(struct hsm_action_list) + + __ALIGN_KERNEL(strlen(hsd->hsd_fsname) + 1, 8); hsd->hsd_request_count++; - } else if (request->hal_sz < request->hal_used_sz + hai_size) { - /* Not enough room, need an extension */ - void *hal_buffer; - int sz; - - sz = min_t(int, 2 * request->hal_sz, LDLM_MAXREQSIZE); - LASSERT(request->hal_used_sz + hai_size < sz); - - OBD_ALLOC_LARGE(hal_buffer, sz); - if (!hal_buffer) - RETURN(-ENOMEM); - - memcpy(hal_buffer, request->hal, request->hal_used_sz); - OBD_FREE_LARGE(request->hal, request->hal_sz); - request->hal = hal_buffer; - request->hal_sz = sz; } - hai = hai_first(request->hal); - for (i = 0; i < request->hal->hal_count; i++) - hai = hai_next(hai); + cookie.lgc_offset = 0; + llog_get_cookie(env, &cookie); + LASSERTF(cookie.lgc_offset >= llh->lgh_hdr->llh_size, + "Bad record offset %llx for idx %d", cookie.lgc_offset, + larr->arr_hdr.lrh_index); - memcpy(hai, &larr->arr_hai, larr->arr_hai.hai_len); + car = mdt_cdt_alloc_request(&uuid, larr); + if (IS_ERR(car)) + RETURN(PTR_ERR(car)); - request->hal_used_sz += hai_size; - request->hal->hal_count++; + car->car_hmm->mr_offset = cookie.lgc_offset; + car->car_hmm->mr_lid = llh->lgh_id; + list_add_tail(&car->car_scan_list, &request->hsr_cars); + CDEBUG(D_HSM, "Copying record %d to request %px, count %d\n", + larr->arr_hdr.lrh_index, request, request->hsr_count); + + request->hsr_count++; + request->hsr_used_sz += hai_size; hsd->hsd_action_count++; - switch (hai->hai_action) { + switch (car->car_hmm->mr_rec.arr_hai.hai_action) { case HSMA_CANCEL: break; case HSMA_RESTORE: hsd->hsd_one_restore = true; fallthrough; default: - cdt_agent_record_hash_add(cdt, hai->hai_cookie, - llh->lgh_hdr->llh_cat_idx, - larr->arr_hdr.lrh_index); + break; } wrapped = llh->lgh_hdr->llh_cat_idx >= llh->lgh_last_idx && @@ -408,12 +416,22 @@ static int mdt_coordinator_cb(const struct lu_env *env, struct hsm_scan_data *hsd = data; struct mdt_device *mdt = hsd->hsd_mti->mti_mdt; struct coordinator *cdt = &mdt->mdt_coordinator; + int rc; + ENTRY; if (cdt->cdt_state == CDT_DISABLE) RETURN(-ECANCELED); larr = (struct llog_agent_req_rec *)hdr; + rc = mdt_cdt_check_rec(larr, larr->arr_hdr.lrh_len); + if (rc) { + CDEBUG(D_HSM, "%s: bad llog record "DOSTID" idx %d, rc = %d\n", + llh->lgh_ctxt->loc_obd->obd_name, + POSTID(&llh->lgh_id.lgl_oi), larr->arr_hdr.lrh_index, + rc); + RETURN(LLOG_DEL_RECORD); + } dump_llog_agent_req_rec("mdt_coordinator_cb(): ", larr); switch (larr->arr_status) { case ARS_WAITING: @@ -426,8 +444,6 @@ static int mdt_coordinator_cb(const struct lu_env *env, if ((larr->arr_req_change + cdt->cdt_grace_delay) < ktime_get_real_seconds()) { - cdt_agent_record_hash_del(cdt, - larr->arr_hai.hai_cookie); RETURN(LLOG_DEL_RECORD); } @@ -487,7 +503,7 @@ static void mdt_hsm_cdt_cleanup(struct mdt_device *mdt) list_for_each_entry_safe(car, tmp1, &cdt->cdt_request_list, car_request_list) { cfs_hash_del(cdt->cdt_request_cookie_hash, - &car->car_hai->hai_cookie, + &car->car_hai.hai_cookie, &car->car_cookie_hash); list_del(&car->car_request_list); mdt_cdt_put_request(car); @@ -641,12 +657,8 @@ static int mdt_coordinator(void *data) while (1) { int i; - int update_idx = 0; - int updates_sz; - int updates_cnt; u32 start_cat_idx; u32 start_rec_idx; - struct hsm_record_update *updates; if (cdt->cdt_state == CDT_DISABLE) { cdt->cdt_idle = true; @@ -749,32 +761,9 @@ static int mdt_coordinator(void *data) goto clean_cb_alloc; } - /* Compute how many HAI we have in all the requests */ - updates_cnt = 0; - for (i = 0; i < hsd.hsd_request_count; i++) { - const struct hsm_scan_request *request = - &hsd.hsd_request[i]; - - updates_cnt += request->hal->hal_count; - } - - /* Allocate a temporary array to store the cookies to - * update, and their status. */ - updates_sz = updates_cnt * sizeof(*updates); - OBD_ALLOC_LARGE(updates, updates_sz); - if (updates == NULL) { - CERROR("%s: Cannot allocate memory (%d bytes) " - "for %d updates. Too many HSM requests?\n", - mdt_obd_name(mdt), updates_sz, updates_cnt); - goto clean_cb_alloc; - } - /* here hsd contains a list of requests to be started */ for (i = 0; i < hsd.hsd_request_count; i++) { struct hsm_scan_request *request = &hsd.hsd_request[i]; - struct hsm_action_list *hal = request->hal; - struct hsm_action_item *hai; - int j; /* still room for work ? */ if (atomic_read(&cdt->cdt_request_count) >= @@ -785,27 +774,14 @@ static int mdt_coordinator(void *data) * assumes that other records are cancelled */ if (cdt->cdt_state == CDT_DISABLE) - goto update_recs; - + goto clean_cb_alloc; - rc = mdt_hsm_agent_send(mti, hal, 0); + rc = mdt_hsm_agent_send(mti, request, 0); /* if failure, we suppose it is temporary * if the copy tool failed to do the request * it has to use hsm_progress */ - /* set up cookie vector to set records status - * after copy tools start or failed - */ - hai = hai_first(hal); - for (j = 0; j < hal->hal_count; j++) { - updates[update_idx].cookie = hai->hai_cookie; - updates[update_idx].status = - (rc ? ARS_WAITING : ARS_STARTED); - hai = hai_next(hai); - update_idx++; - } - /* TODO: narrow down the HSM action range that already * scanned accroding to the cookies when a failure * occurs. @@ -816,24 +792,19 @@ static int mdt_coordinator(void *data) } } -update_recs: - if (update_idx) { - rc = mdt_agent_record_update(mti, updates, update_idx); - if (rc) - CERROR("%s: mdt_agent_record_update() failed, " - "rc=%d, cannot update records " - "for %d cookies\n", - mdt_obd_name(mdt), rc, update_idx); - } - - OBD_FREE_LARGE(updates, updates_sz); - clean_cb_alloc: /* free hal allocated by callback */ for (i = 0; i < hsd.hsd_request_count; i++) { struct hsm_scan_request *request = &hsd.hsd_request[i]; + struct cdt_agent_req *pos; + struct cdt_agent_req *tmp; + + list_for_each_entry_safe(pos, tmp, &request->hsr_cars, + car_scan_list) { + list_del_init(&pos->car_scan_list); + mdt_cdt_put_request(pos); + } - OBD_FREE_LARGE(request->hal, request->hal_sz); } } @@ -1124,21 +1095,9 @@ int mdt_hsm_cdt_init(struct mdt_device *mdt) if (cdt->cdt_request_cookie_hash == NULL) RETURN(-ENOMEM); - cdt->cdt_agent_record_hash = cfs_hash_create("AGENT_RECORD_HASH", - CFS_HASH_BITS_MIN, - CFS_HASH_BITS_MAX, - CFS_HASH_BKT_BITS, - 0 /* extra bytes */, - CFS_HASH_MIN_THETA, - CFS_HASH_MAX_THETA, - &cdt_agent_record_hash_ops, - CFS_HASH_DEFAULT); - if (cdt->cdt_agent_record_hash == NULL) - GOTO(out_request_cookie_hash, rc = -ENOMEM); - rc = lu_env_init(&cdt->cdt_env, LCT_MD_THREAD); if (rc < 0) - GOTO(out_agent_record_hash, rc); + GOTO(out_request_cookie_hash, rc); /* for mdt_ucred(), lu_ucred stored in lu_ucred_key */ rc = lu_context_init(&cdt->cdt_session, LCT_SERVER_SESSION); @@ -1173,9 +1132,6 @@ int mdt_hsm_cdt_init(struct mdt_device *mdt) out_env: lu_env_fini(&cdt->cdt_env); -out_agent_record_hash: - cfs_hash_putref(cdt->cdt_agent_record_hash); - cdt->cdt_agent_record_hash = NULL; out_request_cookie_hash: cfs_hash_putref(cdt->cdt_request_cookie_hash); cdt->cdt_request_cookie_hash = NULL; @@ -1197,9 +1153,6 @@ int mdt_hsm_cdt_fini(struct mdt_device *mdt) lu_env_fini(&cdt->cdt_env); - cfs_hash_putref(cdt->cdt_agent_record_hash); - cdt->cdt_agent_record_hash = NULL; - cfs_hash_putref(cdt->cdt_request_cookie_hash); cdt->cdt_request_cookie_hash = NULL; @@ -1329,27 +1282,32 @@ out: } /** - * register all requests from an hal in the memory list + * register all agent requests from a scan phase * \param mti [IN] context - * \param hal [IN] request + * \param rq [IN] request * \param uuid [OUT] in case of CANCEL, the uuid of the agent * which is running the CT * \retval 0 success * \retval -ve failure */ -int mdt_hsm_add_hal(struct mdt_thread_info *mti, - struct hsm_action_list *hal, struct obd_uuid *uuid) +int mdt_hsm_add_hsr(struct mdt_thread_info *mti, struct hsm_scan_request *rq, + struct obd_uuid *uuid) { struct mdt_device *mdt = mti->mti_mdt; struct coordinator *cdt = &mdt->mdt_coordinator; + struct cdt_agent_req *car; + struct hsm_mem_req_rec *hmm; struct hsm_action_item *hai; - int rc = 0, i; + int rc = 0; ENTRY; /* register request in memory list */ - hai = hai_first(hal); - for (i = 0; i < hal->hal_count; i++, hai = hai_next(hai)) { - struct cdt_agent_req *car; + list_for_each_entry(car, &rq->hsr_cars, car_scan_list) { + hmm = car->car_hmm; + if (hmm->mr_rec.arr_status == ARS_FAILED) + continue; + + hai = &car->car_hai; /* in case of a cancel request, we first mark the ondisk * record of the request we want to stop as canceled @@ -1357,55 +1315,62 @@ int mdt_hsm_add_hal(struct mdt_thread_info *mti, * it will be done when updating the request status */ if (hai->hai_action == HSMA_CANCEL) { - struct hsm_record_update update = { - .cookie = hai->hai_cookie, - .status = ARS_CANCELED, - }; + struct cdt_agent_req *orig; + struct hsm_action_item *h; + + /* find the running request to set it canceled */ + orig = mdt_cdt_find_request(cdt, hai->hai_cookie); + if (!orig) + continue; + + h = &orig->car_hai; + if (orig->car_cancel) { + CDEBUG(D_HSM, + "%s: %llx already canceled %s "DFID"\n", + mdt_obd_name(mdt), h->hai_cookie, + hsm_copytool_action2name(h->hai_action), + PFID(&h->hai_fid)); + mdt_cdt_put_request(orig); + continue; + } + orig->car_hmm->mr_rec.arr_status = ARS_CANCELED; + + rc = mdt_hsm_agent_modify_record(mti->mti_env, mdt, + orig->car_hmm); - rc = mdt_agent_record_update(mti, &update, 1); if (rc) { - CERROR("%s: mdt_agent_record_update() failed, " - "rc=%d, cannot update status to %s " - "for cookie %#llx\n", - mdt_obd_name(mdt), rc, + CERROR("%s: modify record failed, cannot update status to %s for cookie %#llx : rc = %d\n", + mdt_obd_name(mdt), agent_req_status2name(ARS_CANCELED), - hai->hai_cookie); + hai->hai_cookie, rc); + mdt_cdt_put_request(orig); GOTO(out, rc); } - /* find the running request to set it canceled */ - car = mdt_cdt_find_request(cdt, hai->hai_cookie); - if (car != NULL) { - car->car_canceled = 1; - /* uuid has to be changed to the one running the - * request to cancel */ - *uuid = car->car_uuid; - mdt_cdt_put_request(car); - } - /* no need to memorize cancel request - * this also avoid a deadlock when we receive - * a purge all requests command + /* orig holding cancel request orig->car_cancel */ + mdt_cdt_get_request(car); + /* uuid has to be changed to the one running the + * request to cancel */ + *uuid = orig->car_uuid; + car->car_uuid = orig->car_uuid; + orig->car_cancel = car; continue; } if (hai->hai_action == HSMA_ARCHIVE) { rc = mdt_hsm_set_exists(mti, &hai->hai_fid, - hal->hal_archive_id); + hsr_get_archive_id(rq)); if (rc == -ENOENT) continue; else if (rc < 0) GOTO(out, rc); } - car = mdt_cdt_alloc_request(hal->hal_archive_id, hal->hal_flags, - uuid, hai); - if (IS_ERR(car)) - GOTO(out, rc = PTR_ERR(car)); - + car->car_uuid = *uuid; rc = mdt_cdt_add_request(cdt, car); - if (rc != 0) - mdt_cdt_free_request(car); + if (rc) + break; } out: RETURN(rc); @@ -1504,7 +1469,7 @@ static int hsm_cdt_request_completed(struct mdt_thread_info *mti, /* find object by FID, mdt_hsm_get_md_hsm() returns obj or err * if error/removed continue anyway to get correct reporting done */ - obj = mdt_hsm_get_md_hsm(mti, &car->car_hai->hai_fid, &mh); + obj = mdt_hsm_get_md_hsm(mti, &car->car_hai.hai_fid, &mh); /* we will update MD HSM only if needed */ is_mh_changed = false; @@ -1550,7 +1515,7 @@ static int hsm_cdt_request_completed(struct mdt_thread_info *mti, rc = 0; } - switch (car->car_hai->hai_action) { + switch (car->car_hai.hai_action) { case HSMA_ARCHIVE: hsm_set_cl_event(&clf_flags, HE_ARCHIVE); break; @@ -1573,13 +1538,13 @@ static int hsm_cdt_request_completed(struct mdt_thread_info *mti, " %d is an unknown action\n", mdt_obd_name(mdt), pgs->hpk_cookie, PFID(&pgs->hpk_fid), - car->car_hai->hai_action); + car->car_hai.hai_action); rc = -EINVAL; break; } } else { *status = ARS_SUCCEED; - switch (car->car_hai->hai_action) { + switch (car->car_hai.hai_action) { case HSMA_ARCHIVE: hsm_set_cl_event(&clf_flags, HE_ARCHIVE); /* set ARCHIVE keep EXIST and clear LOST and @@ -1618,7 +1583,7 @@ static int hsm_cdt_request_completed(struct mdt_thread_info *mti, CERROR("%s: Successful request %#llx on "DFID" %d is an unknown action\n", mdt_obd_name(mdt), pgs->hpk_cookie, PFID(&pgs->hpk_fid), - car->car_hai->hai_action); + car->car_hai.hai_action); rc = -EINVAL; break; } @@ -1640,13 +1605,13 @@ static int hsm_cdt_request_completed(struct mdt_thread_info *mti, /* we give back layout lock only if restore was successful or * if no retry will be attempted and if object is still alive, * in other cases we just unlock the object */ - if (car->car_hai->hai_action == HSMA_RESTORE) { + if (car->car_hai.hai_action == HSMA_RESTORE) { struct mdt_lock_handle *lh; /* restore in data FID done, we swap the layouts * only if restore is successful */ if (pgs->hpk_errval == 0 && !IS_ERR(obj)) { - rc = hsm_swap_layouts(mti, obj, &car->car_hai->hai_dfid, + rc = hsm_swap_layouts(mti, obj, &car->car_hai.hai_dfid, &mh); if (rc) { if (cdt->cdt_policy & CDT_NORETRY_ACTION) @@ -1663,10 +1628,10 @@ static int hsm_cdt_request_completed(struct mdt_thread_info *mti, * before to give back layout lock to avoid concurrent * file updater to post out of order ChangeLog */ mo_changelog(env, CL_HSM, clf_flags, mdt->mdt_child, - &car->car_hai->hai_fid); + &car->car_hai.hai_fid); need_changelog = false; - cdt_restore_handle_del(mti, cdt, &car->car_hai->hai_fid); + cdt_restore_handle_del(mti, cdt, &car->car_hai.hai_fid); if (!IS_ERR_OR_NULL(obj)) { /* flush UPDATE lock so attributes are upadated */ lh = &mti->mti_lh[MDT_LH_OLD]; @@ -1682,7 +1647,7 @@ out: /* always add a ChangeLog record */ if (need_changelog) mo_changelog(env, CL_HSM, clf_flags, mdt->mdt_child, - &car->car_hai->hai_fid); + &car->car_hai.hai_fid); if (!IS_ERR(obj)) mdt_object_put(mti->mti_env, obj); @@ -1724,29 +1689,29 @@ int mdt_hsm_update_request_state(struct mdt_thread_info *mti, CDEBUG(D_HSM, "Progress received for fid="DFID" cookie=%#llx" " action=%s flags=%d err=%d fid="DFID" dfid="DFID"\n", PFID(&pgs->hpk_fid), pgs->hpk_cookie, - hsm_copytool_action2name(car->car_hai->hai_action), + hsm_copytool_action2name(car->car_hai.hai_action), pgs->hpk_flags, pgs->hpk_errval, - PFID(&car->car_hai->hai_fid), - PFID(&car->car_hai->hai_dfid)); + PFID(&car->car_hai.hai_fid), + PFID(&car->car_hai.hai_dfid)); /* progress is done on FID or data FID depending of the action and * of the copy progress */ /* for restore progress is used to send back the data FID to cdt */ - if (car->car_hai->hai_action == HSMA_RESTORE && - lu_fid_eq(&car->car_hai->hai_fid, &car->car_hai->hai_dfid)) - car->car_hai->hai_dfid = pgs->hpk_fid; - - if ((car->car_hai->hai_action == HSMA_RESTORE || - car->car_hai->hai_action == HSMA_ARCHIVE) && - (!lu_fid_eq(&pgs->hpk_fid, &car->car_hai->hai_dfid) && - !lu_fid_eq(&pgs->hpk_fid, &car->car_hai->hai_fid))) { + if (car->car_hai.hai_action == HSMA_RESTORE && + lu_fid_eq(&car->car_hai.hai_fid, &car->car_hai.hai_dfid)) + car->car_hai.hai_dfid = pgs->hpk_fid; + + if ((car->car_hai.hai_action == HSMA_RESTORE || + car->car_hai.hai_action == HSMA_ARCHIVE) && + (!lu_fid_eq(&pgs->hpk_fid, &car->car_hai.hai_dfid) && + !lu_fid_eq(&pgs->hpk_fid, &car->car_hai.hai_fid))) { CERROR("%s: Progress on "DFID" for cookie %#llx" " does not match request FID "DFID" nor data FID " DFID"\n", mdt_obd_name(mdt), PFID(&pgs->hpk_fid), pgs->hpk_cookie, - PFID(&car->car_hai->hai_fid), - PFID(&car->car_hai->hai_dfid)); + PFID(&car->car_hai.hai_fid), + PFID(&car->car_hai.hai_dfid)); GOTO(out, rc = -EINVAL); } @@ -1756,7 +1721,7 @@ int mdt_hsm_update_request_state(struct mdt_thread_info *mti, " (flags=%d))\n", mdt_obd_name(mdt), PFID(&pgs->hpk_fid), pgs->hpk_cookie, - hsm_copytool_action2name(car->car_hai->hai_action), + hsm_copytool_action2name(car->car_hai.hai_action), pgs->hpk_errval, pgs->hpk_flags); GOTO(out, rc = -EINVAL); } @@ -1768,31 +1733,38 @@ int mdt_hsm_update_request_state(struct mdt_thread_info *mti, if (pgs->hpk_flags & HP_FLAG_COMPLETED) { enum agent_req_status status; - struct hsm_record_update update; + struct hsm_mem_req_rec *hmm; int rc1; rc = hsm_cdt_request_completed(mti, pgs, car, &status); - CDEBUG(D_HSM, "updating record: fid="DFID" cookie=%#llx action=%s " - "status=%s\n", + /* if original record was canceled, need to update cancel rec */ + if (unlikely(car->car_cancel)) + hmm = car->car_cancel->car_hmm; + else + hmm = car->car_hmm; + + CDEBUG(D_HSM, "updating record: fid="DFID" cookie=%#llx action=%s status=%s to %s\n", PFID(&pgs->hpk_fid), pgs->hpk_cookie, - hsm_copytool_action2name(car->car_hai->hai_action), + hsm_copytool_action2name(hmm->mr_rec.arr_hai.hai_action), + agent_req_status2name(hmm->mr_rec.arr_status), agent_req_status2name(status)); - /* update record first (LU-9075) */ - update.cookie = pgs->hpk_cookie; - update.status = status; + if (hmm->mr_rec.arr_status == ARS_STARTED || + hmm->mr_rec.arr_status == ARS_WAITING) { + /* update record first (LU-9075) */ + hmm->mr_rec.arr_status = status; - rc1 = mdt_agent_record_update(mti, &update, 1); - if (rc1) - CERROR("%s: mdt_agent_record_update() failed," - " rc=%d, cannot update status to %s" - " for cookie %#llx\n", - mdt_obd_name(mdt), rc1, - agent_req_status2name(status), - pgs->hpk_cookie); - rc = (rc != 0 ? rc : rc1); + rc1 = mdt_hsm_agent_modify_record(mti->mti_env, mdt, + hmm); + if (rc1) + CERROR("%s: modify record failed, cannot update status to %s for cookie %#llx: rc = %d\n", + mdt_obd_name(mdt), + agent_req_status2name(status), + pgs->hpk_cookie, rc1); + rc = (rc != 0 ? rc : rc1); + } /* then remove request from memory list (LU-9075) */ mdt_cdt_remove_request(cdt, pgs->hpk_cookie); @@ -1803,7 +1775,7 @@ int mdt_hsm_update_request_state(struct mdt_thread_info *mti, /* if copytool send a progress on a canceled request * we inform copytool it should stop */ - if (car->car_canceled == 1) + if (car->car_cancel) rc = -ECANCELED; } GOTO(out, rc); @@ -1839,6 +1811,11 @@ static int mdt_cancel_all_cb(const struct lu_env *env, int rc; ENTRY; + CDEBUG(D_TRACE, "%s: HSM record idx %d "DFID" status %s\n", + mdt_obd_name(mti->mti_mdt), hdr->lrh_index, + PFID(&hai->hai_fid), + agent_req_status2name(larr->arr_status)); + if (larr->arr_status != ARS_WAITING && larr->arr_status != ARS_STARTED) RETURN(0); @@ -1865,15 +1842,19 @@ static int mdt_cancel_all_cb(const struct lu_env *env, */ static int hsm_cancel_all_actions(struct mdt_device *mdt) { - struct lu_env env; - struct lu_context session; - struct mdt_thread_info *mti; - struct coordinator *cdt = &mdt->mdt_coordinator; - struct cdt_agent_req *car; - struct hsm_action_list *hal = NULL; - struct hsm_action_item *hai; - int hal_sz = 0, hal_len, rc; - enum cdt_states old_state; + struct lu_env env; + struct lu_context session; + struct mdt_thread_info *mti; + struct coordinator *cdt = &mdt->mdt_coordinator; + struct cdt_agent_req *car; + char fsname[MTI_NAME_MAXLEN]; + struct hsm_scan_request rq = { + .hsr_version = HAL_VERSION, + .hsr_fsname = &fsname[0], + .hsr_count = 1,}; + enum cdt_states old_state; + int rc; + ENTRY; rc = lu_env_init(&env, LCT_MD_THREAD); @@ -1895,6 +1876,7 @@ static int hsm_cancel_all_actions(struct mdt_device *mdt) mti->mti_mdt = mdt; hsm_init_ucred(mdt_ucred(mti)); + obd_uuid2fsname(rq.hsr_fsname, mdt_obd_name(mdt), MTI_NAME_MAXLEN); mutex_lock(&cdt->cdt_state_lock); old_state = cdt->cdt_state; @@ -1911,66 +1893,43 @@ static int hsm_cancel_all_actions(struct mdt_device *mdt) /* send cancel to all running requests */ down_read(&cdt->cdt_request_lock); list_for_each_entry(car, &cdt->cdt_request_list, car_request_list) { + u32 action; + + /* a cdt_agent_req could be at coordinator sending process + * still mdt_coordinator()->mdt_hsm_agent_send() in case + * of network resend inside ptlrpc. Skip it. + */ + if (!list_empty(&car->car_scan_list)) + continue; + mdt_cdt_get_request(car); /* request is not yet removed from list, it will be done * when copytool will return progress */ - if (car->car_hai->hai_action == HSMA_CANCEL) { + if (car->car_hai.hai_action == HSMA_CANCEL) { mdt_cdt_put_request(car); continue; } - /* needed size */ - hal_len = sizeof(*hal) + round_up(MTI_NAME_MAXLEN + 1, 8) + - round_up(car->car_hai->hai_len, 8); - - if (hal_len > hal_sz && hal_sz > 0) { - /* not enough room, free old buffer */ - OBD_FREE(hal, hal_sz); - hal = NULL; - } - - /* empty buffer, allocate one */ - if (hal == NULL) { - hal_sz = hal_len; - OBD_ALLOC(hal, hal_sz); - if (hal == NULL) { - mdt_cdt_put_request(car); - up_read(&cdt->cdt_request_lock); - GOTO(out_cdt_state, rc = -ENOMEM); - } - } + INIT_LIST_HEAD(&rq.hsr_cars); + list_add_tail(&car->car_scan_list, &rq.hsr_cars); + action = car->car_hai.hai_action; + car->car_hai.hai_action = HSMA_CANCEL; - hal->hal_version = HAL_VERSION; - obd_uuid2fsname(hal->hal_fsname, mdt_obd_name(mdt), - MTI_NAME_MAXLEN); - hal->hal_fsname[MTI_NAME_MAXLEN] = '\0'; - hal->hal_archive_id = car->car_archive_id; - hal->hal_flags = car->car_flags; - hal->hal_count = 0; - - hai = hai_first(hal); - memcpy(hai, car->car_hai, car->car_hai->hai_len); - hai->hai_action = HSMA_CANCEL; - hal->hal_count = 1; - - /* it is possible to safely call mdt_hsm_agent_send() - * (ie without a deadlock on cdt_request_lock), because the - * write lock is taken only if we are not in purge mode - * (mdt_hsm_agent_send() does not call mdt_cdt_add_request() - * nor mdt_cdt_remove_request()) - */ /* no conflict with cdt thread because cdt is disable and we * have the request lock */ - mdt_hsm_agent_send(mti, hal, 1); + mdt_hsm_agent_send(mti, &rq, 1); + + car->car_hai.hai_action = action; + /* Unlock the EX layout lock */ + if (action == HSMA_RESTORE) + cdt_restore_handle_del(mti, cdt, &car->car_hai.hai_fid); mdt_cdt_put_request(car); } up_read(&cdt->cdt_request_lock); - OBD_FREE(hal, hal_sz); - /* cancel all on-disk records */ rc = cdt_llog_process(mti->mti_env, mti->mti_mdt, mdt_cancel_all_cb, (void *)mti, 0, 0); diff --git a/lustre/mdt/mdt_hsm_cdt_actions.c b/lustre/mdt/mdt_hsm_cdt_actions.c index 21256d3..2869c5d 100644 --- a/lustre/mdt/mdt_hsm_cdt_actions.c +++ b/lustre/mdt/mdt_hsm_cdt_actions.c @@ -24,134 +24,6 @@ #include #include "mdt_internal.h" -struct cdt_agent_record_loc { - struct hlist_node carl_hnode; - struct kref carl_refcount; - u64 carl_cookie; - u32 carl_cat_idx; - u32 carl_rec_idx; -}; - -static inline void cdt_agent_record_loc_get(struct cdt_agent_record_loc *carl) -{ - kref_get(&carl->carl_refcount); -} - -static void cdt_agent_record_loc_put_free(struct kref *kref) -{ - struct cdt_agent_record_loc *carl; - - carl = container_of(kref, struct cdt_agent_record_loc, carl_refcount); - OBD_FREE_PTR(carl); - -} - -static inline void cdt_agent_record_loc_put(struct cdt_agent_record_loc *carl) -{ - kref_put(&carl->carl_refcount, cdt_agent_record_loc_put_free); -} - -static unsigned int -cdt_agent_record_hash(struct cfs_hash *hs, const void *key, - const unsigned int bits) -{ - return cfs_hash_djb2_hash(key, sizeof(u64), bits); -} - -static void *cdt_agent_record_object(struct hlist_node *hnode) -{ - return hlist_entry(hnode, struct cdt_agent_record_loc, carl_hnode); -} - -static void *cdt_agent_record_key(struct hlist_node *hnode) -{ - struct cdt_agent_record_loc *carl = cdt_agent_record_object(hnode); - - return &carl->carl_cookie; -} - -static int cdt_agent_record_keycmp(const void *key, struct hlist_node *hnode) -{ - const u64 *cookie2 = cdt_agent_record_key(hnode); - - return *(const u64 *)key == *cookie2; -} - -static void cdt_agent_record_get(struct cfs_hash *hs, struct hlist_node *hnode) -{ - struct cdt_agent_record_loc *carl = cdt_agent_record_object(hnode); - - cdt_agent_record_loc_get(carl); -} - -static void cdt_agent_record_put(struct cfs_hash *hs, struct hlist_node *hnode) -{ - struct cdt_agent_record_loc *carl = cdt_agent_record_object(hnode); - - cdt_agent_record_loc_put(carl); -} - -struct cfs_hash_ops cdt_agent_record_hash_ops = { - .hs_hash = cdt_agent_record_hash, - .hs_key = cdt_agent_record_key, - .hs_keycmp = cdt_agent_record_keycmp, - .hs_object = cdt_agent_record_object, - .hs_get = cdt_agent_record_get, - .hs_put_locked = cdt_agent_record_put, -}; - -void cdt_agent_record_hash_add(struct coordinator *cdt, u64 cookie, u32 cat_idx, - u32 rec_idx) -{ - struct cdt_agent_record_loc *carl0; - struct cdt_agent_record_loc *carl1; - - OBD_ALLOC_PTR(carl1); - if (carl1 == NULL) - return; - - INIT_HLIST_NODE(&carl1->carl_hnode); - kref_init(&carl1->carl_refcount); - carl1->carl_cookie = cookie; - carl1->carl_cat_idx = cat_idx; - carl1->carl_rec_idx = rec_idx; - - carl0 = cfs_hash_findadd_unique(cdt->cdt_agent_record_hash, - &carl1->carl_cookie, - &carl1->carl_hnode); - - LASSERT(carl0->carl_cookie == carl1->carl_cookie); - LASSERT(carl0->carl_cat_idx == carl1->carl_cat_idx); - LASSERT(carl0->carl_rec_idx == carl1->carl_rec_idx); - - if (carl0 != carl1) - cdt_agent_record_loc_put(carl0); - - cdt_agent_record_loc_put(carl1); -} - -void cdt_agent_record_hash_lookup(struct coordinator *cdt, u64 cookie, - u32 *cat_idx, u32 *rec_idx) -{ - struct cdt_agent_record_loc *carl; - - carl = cfs_hash_lookup(cdt->cdt_agent_record_hash, &cookie); - if (carl != NULL) { - LASSERT(carl->carl_cookie == cookie); - *cat_idx = carl->carl_cat_idx; - *rec_idx = carl->carl_rec_idx; - cdt_agent_record_loc_put(carl); - } else { - *cat_idx = 0; - *rec_idx = 0; - } -} - -void cdt_agent_record_hash_del(struct coordinator *cdt, u64 cookie) -{ - cfs_hash_del_key(cdt->cdt_agent_record_hash, &cookie); -} - void dump_llog_agent_req_rec(const char *prefix, const struct llog_agent_req_rec *larr) { @@ -335,166 +207,17 @@ int mdt_agent_record_add(const struct lu_env *env, struct mdt_device *mdt, putctxt: llog_ctxt_put(lctxt); + CDEBUG(D_TRACE, + "%s: HSM added record idx %d "DFID" action %s: rc = %d\n", + mdt_obd_name(mdt), larr->arr_hdr.lrh_index, PFID(&hai->hai_fid), + hsm_copytool_action2name(hai->hai_action), rc); + EXIT; free: OBD_FREE(larr, sz); return rc; } -/** - * data passed to llog_cat_process() callback - * to find requests - */ -struct data_update_cb { - struct mdt_thread_info *mti; - struct hsm_record_update *updates; - unsigned int updates_count; - unsigned int updates_done; - time64_t change_time; -}; - -/** - * llog_cat_process() callback, used to update a record - * \param env [IN] environment - * \param llh [IN] llog handle - * \param hdr [IN] llog record - * \param data [IN] cb data = data_update_cb - * \retval 0 success - * \retval -ve failure - */ -static int mdt_agent_record_update_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_action_item *hai = &larr->arr_hai; - struct data_update_cb *ducb = data; - struct mdt_thread_info *mti = ducb->mti; - struct mdt_device *mdt = ducb->mti->mti_mdt; - struct coordinator *cdt = &mdt->mdt_coordinator; - int rc, i; - ENTRY; - - /* check if all done */ - if (ducb->updates_count == ducb->updates_done) - RETURN(LLOG_PROC_BREAK); - - /* if record is in final state, never change */ - if (agent_req_in_final_state(larr->arr_status)) - RETURN(0); - - rc = 0; - for (i = 0 ; i < ducb->updates_count ; i++) { - struct hsm_record_update *update = &ducb->updates[i]; - - CDEBUG(D_HSM, "%s: search %#llx, found %#llx\n", - mdt_obd_name(mdt), update->cookie, - hai->hai_cookie); - if (hai->hai_cookie == update->cookie) { - - /* If record is a cancel request, it cannot be - * canceled. This is to manage the following - * case: when a request is canceled, we have 2 - * records with the the same cookie: the one - * to cancel and the cancel request the 1st - * has to be set to ARS_CANCELED and the 2nd - * to ARS_SUCCEED - */ - if (hai->hai_action == HSMA_CANCEL && - update->status == ARS_CANCELED) - RETURN(0); - - larr->arr_status = update->status; - larr->arr_req_change = ducb->change_time; - rc = llog_write(env, llh, hdr, hdr->lrh_index); - if (rc < 0) - break; - - ducb->updates_done++; - - /* Unlock the EX layout lock */ - if (hai->hai_action == HSMA_RESTORE && - update->status == ARS_CANCELED) - cdt_restore_handle_del(mti, cdt, &hai->hai_fid); - - break; - } - } - - if (rc < 0) - CERROR("%s: mdt_agent_llog_update_rec() failed, rc = %d\n", - mdt_obd_name(mdt), rc); - - RETURN(rc); -} - -/** - * update an entry in agent llog - * - * \param env [IN] environment - * \param mdt [IN] MDT device - * \param updates [IN] array of entries to update - * \param updates_count [IN] number of entries in updates - * - * \retval 0 on success - * \retval negative on failure - */ -int mdt_agent_record_update(struct mdt_thread_info *mti, - struct hsm_record_update *updates, - unsigned int updates_count) -{ - const struct lu_env *env = mti->mti_env; - struct mdt_device *mdt = mti->mti_mdt; - struct data_update_cb ducb; - u32 start_cat_idx = -1; - u32 start_rec_idx = -1; - u32 cat_idx; - u32 rec_idx; - int i; - int rc; - ENTRY; - - /* Find the first location (start_cat_idx, start_rec_idx) - * among the records corresponding to cookies. */ - for (i = 0; i < updates_count; i++) { - /* If we cannot find a cached location for a cookie - * (perhaps because the MDT was restart then we must - * start from the beginning. In this case - * mdt_agent_record_hash_get() sets both of cat_idx and - * rec_idx to 0. */ - cdt_agent_record_hash_lookup(&mdt->mdt_coordinator, - updates[i].cookie, - &cat_idx, &rec_idx); - if (cat_idx < start_cat_idx) { - start_cat_idx = cat_idx; - start_rec_idx = rec_idx; - } else if (cat_idx == start_cat_idx && - rec_idx < start_rec_idx) { - start_rec_idx = rec_idx; - } - } - - /* Fixup starting record index for llog_cat_process(). */ - if (start_rec_idx != 0) - start_rec_idx -= 1; - - ducb.mti = mti; - ducb.updates = updates; - ducb.updates_count = updates_count; - ducb.updates_done = 0; - ducb.change_time = ktime_get_real_seconds(); - - rc = cdt_llog_process(env, mdt, mdt_agent_record_update_cb, &ducb, - start_cat_idx, start_rec_idx); - if (rc < 0) - CERROR("%s: cdt_llog_process() failed, rc=%d, cannot update " - "status for %u cookies, done %u\n", - mdt_obd_name(mdt), rc, - updates_count, ducb.updates_done); - RETURN(rc); -} - /* * Agent actions /proc seq_file methods * As llog processing uses a callback for each entry, we cannot do a sequential diff --git a/lustre/mdt/mdt_hsm_cdt_agent.c b/lustre/mdt/mdt_hsm_cdt_agent.c index 0166557..a5e51ff 100644 --- a/lustre/mdt/mdt_hsm_cdt_agent.c +++ b/lustre/mdt/mdt_hsm_cdt_agent.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "mdt_internal.h" /* @@ -339,35 +340,109 @@ static int mdt_hsm_send_action_to_each_archive(struct mdt_thread_info *mti, RETURN(rc); } +int mdt_hsm_agent_modify_record(const struct lu_env *env, + struct mdt_device *mdt, + struct hsm_mem_req_rec *hmm) +{ + struct obd_device *obd = mdt2obd_dev(mdt); + struct llog_ctxt *lctxt; + struct llog_cookie cookie; + int rc; + + lctxt = llog_get_context(obd, LLOG_AGENT_ORIG_CTXT); + if (lctxt == NULL || lctxt->loc_handle == NULL) + RETURN(-ENOENT); + + cookie.lgc_offset = hmm->mr_offset; + cookie.lgc_index = hmm->mr_rec.arr_hdr.lrh_index; + hmm->mr_rec.arr_req_change = ktime_get_real_seconds(); + rc = llog_cat_modify_rec(env, lctxt->loc_handle, &hmm->mr_lid, + (struct llog_rec_hdr *)&hmm->mr_rec, + &cookie); + + llog_ctxt_put(lctxt); + return rc; +} + +static size_t hsr_hal_size(struct hsm_scan_request *rq) +{ + struct cdt_agent_req *car; + struct hsm_action_item *hai; + size_t sz; + + sz = sizeof(struct hsm_action_list) + + __ALIGN_KERNEL(strlen(rq->hsr_fsname) + 1, 8); + list_for_each_entry(car, &rq->hsr_cars, car_scan_list) { + hai = &car->car_hai; + sz += __ALIGN_KERNEL(hai->hai_len, 8); + } + return sz; +} + +static int hsr_hal_copy(struct hsm_scan_request *rq, void *buf, size_t buf_size) +{ + struct hsm_action_list *hal = buf; + struct cdt_agent_req *car; + struct hsm_action_item *hai; + struct hsm_action_item *shai; + + hal->hal_version = rq->hsr_version; + strscpy(hal->hal_fsname, rq->hsr_fsname, MTI_NAME_MAXLEN + 1); + hal->hal_archive_id = hsr_get_archive_id(rq); + hal->hal_count = 0; + + hai = hai_first(hal); + /* Copy only valid hai base on a record status */ + list_for_each_entry(car, &rq->hsr_cars, car_scan_list) { + shai = &car->car_hai; + hal->hal_flags = car->car_flags; + if (car->car_hmm->mr_rec.arr_status == ARS_FAILED) + continue; + if ((buf_size - ((char *)hai - (char *)buf)) < shai->hai_len) { + CDEBUG(D_HA, "buffer overflow for hsm_action_item\n"); + return -EOVERFLOW; + } + memcpy(hai, shai, shai->hai_len); + hal->hal_count++; + hai = hai_next(hai); + } + + return 0; +} + /** - * send a HAL to the agent + * Checks agent records, creates a hal and sends it to the agent. Updates llog + * records at the end. * \param mti [IN] context - * \param hal [IN] request (can be a kuc payload) - * \param purge [IN] purge mode (no record) + * \param rq [IN] request + * \param purge [IN] purge mode (not register a record) * \retval 0 success * \retval -ve failure * This function supposes: * - all actions are for the same archive number * - in case of cancel, all cancel are for the same agent * This implies that request split has to be done - * before when building the hal + * before when building the rq */ -int mdt_hsm_agent_send(struct mdt_thread_info *mti, - struct hsm_action_list *hal, bool purge) +int mdt_hsm_agent_send(struct mdt_thread_info *mti, struct hsm_scan_request *rq, + bool purge) { - struct obd_export *exp; - struct mdt_device *mdt = mti->mti_mdt; - struct coordinator *cdt = &mti->mti_mdt->mdt_coordinator; - struct hsm_action_list *buf = NULL; - struct hsm_action_item *hai; - struct obd_uuid uuid; - int len, i, rc = 0; - bool fail_request; - bool is_registered = false; + struct obd_export *exp; + struct mdt_device *mdt = mti->mti_mdt; + struct coordinator *cdt = &mti->mti_mdt->mdt_coordinator; + struct hsm_action_list *buf = NULL; + struct hsm_action_item *hai; + struct cdt_agent_req *car; + struct obd_uuid uuid; + int len, rc = 0; + int fail_request = 0; + bool is_registered = false; + u32 archive_id = hsr_get_archive_id(rq); + ENTRY; - rc = mdt_hsm_find_best_agent(cdt, hal->hal_archive_id, &uuid); - if (rc && hal->hal_archive_id == 0) { + rc = mdt_hsm_find_best_agent(cdt, archive_id, &uuid); + if (rc && archive_id == 0) { uint notrmcount = 0; int rc2 = 0; @@ -380,11 +455,8 @@ int mdt_hsm_agent_send(struct mdt_thread_info *mti, * _ 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)) { - struct hsm_record_update update; - + list_for_each_entry(car, &rq->hsr_cars, car_scan_list) { + hai = &car->car_hai; /* only removes are concerned */ if (hai->hai_action != HSMA_REMOVE) { /* count if other actions than HSMA_REMOVE, @@ -405,102 +477,51 @@ int mdt_hsm_agent_send(struct mdt_thread_info *mti, * unless a method to record already successfully * reached archive_ids is implemented */ - update.cookie = hai->hai_cookie; - update.status = ARS_SUCCEED; - rc2 = mdt_agent_record_update(mti, &update, 1); - 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; - } + car->car_hmm->mr_rec.arr_status = ARS_SUCCEED; } /* only remove requests with archive_id=0 */ if (notrmcount == 0) - RETURN(rc2); + GOTO(update_records, rc = rc2); } if (rc) { CERROR("%s: Cannot find agent for archive %d: rc = %d\n", - mdt_obd_name(mdt), hal->hal_archive_id, rc); - RETURN(rc); + mdt_obd_name(mdt), archive_id, rc); + GOTO(update_records, rc); } - CDEBUG(D_HSM, "Agent %s selected for archive %d\n", obd_uuid2str(&uuid), - hal->hal_archive_id); - - len = hal_size(hal); - buf = kuc_alloc(len, KUC_TRANSPORT_HSM, HMT_ACTION_LIST); - if (IS_ERR(buf)) - RETURN(PTR_ERR(buf)); - memcpy(buf, hal, len); + CDEBUG(D_HSM, "Agent %s selected for archive %d request %px items %d\n", + obd_uuid2str(&uuid), archive_id, rq, rq->hsr_count); /* Check if request is still valid (cf file hsm flags) */ - fail_request = false; - hai = hai_first(hal); - for (i = 0; i < hal->hal_count; i++, hai = hai_next(hai)) { + list_for_each_entry(car, &rq->hsr_cars, car_scan_list) { struct mdt_object *obj; struct md_hsm hsm; + hai = &car->car_hai; 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) { - struct hsm_record_update update = { - .cookie = hai->hai_cookie, - .status = ARS_FAILED, - }; - - if (hai->hai_action == HSMA_REMOVE) + } else { + if (PTR_ERR(obj) == -ENOENT && + hai->hai_action == HSMA_REMOVE) continue; - fail_request = true; - rc = mdt_agent_record_update(mti, &update, 1); - 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); - } - + fail_request++; + car->car_hmm->mr_rec.arr_status = ARS_FAILED; continue; - } else { - GOTO(out_buf, rc = PTR_ERR(obj)); } - if (!mdt_hsm_is_action_compat(hai, hal->hal_archive_id, - hal->hal_flags, &hsm)) { - struct hsm_record_update update = { - .cookie = hai->hai_cookie, - .status = ARS_FAILED, - }; + if (!mdt_hsm_is_action_compat(hai, archive_id, car->car_flags, + &hsm)) { /* incompatible request, we abort the request */ - /* next time coordinator will wake up, it will - * make the same HAL with valid only - * records */ - fail_request = true; - rc = mdt_agent_record_update(mti, &update, 1); - 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); - } + fail_request++; + car->car_hmm->mr_rec.arr_status = ARS_FAILED; /* if restore and record status updated, give * back granted layout lock */ @@ -509,13 +530,24 @@ int mdt_hsm_agent_send(struct mdt_thread_info *mti, } } - /* we found incompatible requests, so the HAL cannot be sent - * as is. Bad records have been invalidated in llog. - * Valid one will be reschedule next time coordinator will wake up - * So no need the rebuild a full valid HAL now + /* we found incompatible requests, so the HAL will be built only + * with a vaild one. Bad records have been invalidated in llog. */ if (fail_request) - GOTO(out_buf, rc = -EAGAIN); + CDEBUG(D_HSM, "Some HSM actions are invalid, skipping it\n"); + + /* nothing to send to agent */ + if (fail_request == rq->hsr_count) + GOTO(update_records, rc = 0); + + len = hsr_hal_size(rq); + buf = kuc_alloc(len, KUC_TRANSPORT_HSM, HMT_ACTION_LIST); + if (IS_ERR(buf)) + GOTO(update_records, rc = PTR_ERR(buf)); + + rc = hsr_hal_copy(rq, buf, len); + if (rc) + GOTO(update_records, rc); /* Cancel memory registration is useless for purge * non registration avoid a deadlock : @@ -524,12 +556,10 @@ int mdt_hsm_agent_send(struct mdt_thread_info *mti, * by purge */ if (!purge) { - /* set is_registered even if failure because we may have - * partial work done */ is_registered = true; - rc = mdt_hsm_add_hal(mti, hal, &uuid); + rc = mdt_hsm_add_hsr(mti, rq, &uuid); if (rc) - GOTO(out_buf, rc); + GOTO(update_records, rc); } /* Uses the ldlm reverse import; this rpc will be seen by @@ -546,7 +576,7 @@ int mdt_hsm_agent_send(struct mdt_thread_info *mti, " rc = %d\n", mdt_obd_name(mdt), obd_uuid2str(&uuid), rc); mdt_hsm_agent_unregister(mti, &uuid); - GOTO(out, rc); + GOTO(update_records, rc); } /* send request to agent */ @@ -568,19 +598,38 @@ int mdt_hsm_agent_send(struct mdt_thread_info *mti, mdt_hsm_agent_unregister(mti, &uuid); } -out: - if (rc != 0 && is_registered) { - /* in case of error, we have to unregister requests */ - hai = hai_first(hal); - for (i = 0; i < hal->hal_count; i++, hai = hai_next(hai)) { - if (hai->hai_action == HSMA_CANCEL) - continue; +update_records: + /* for purge record updates do hsm_cancel_all_actions() */ + if (purge) + GOTO(out_free, rc); + + /* in case of error, we have to unregister requests + * also update request status here + */ + list_for_each_entry(car, &rq->hsr_cars, car_scan_list) { + int rc2; + + hai = &car->car_hai; + if (rc != 0 && hai->hai_action != HSMA_CANCEL) mdt_cdt_remove_request(cdt, hai->hai_cookie); - } - } -out_buf: - kuc_free(buf, len); + if (car->car_hmm->mr_rec.arr_status == ARS_WAITING && !rc) + car->car_hmm->mr_rec.arr_status = ARS_STARTED; + + /* update llog record with ARS_ status */ + rc2 = mdt_hsm_agent_modify_record(mti->mti_env, mdt, + car->car_hmm); + if (!rc2) + continue; + + CERROR("%s: modify record failed, cannot update status to %s for cookie %#llx: rc = %d\n", + mdt_obd_name(mdt), + agent_req_status2name(car->car_hmm->mr_rec.arr_status), + hai->hai_cookie, rc2); + } +out_free: + if (!IS_ERR_OR_NULL(buf)) + kuc_free(buf, len); RETURN(rc); } diff --git a/lustre/mdt/mdt_hsm_cdt_requests.c b/lustre/mdt/mdt_hsm_cdt_requests.c index 09662b3..829b094 100644 --- a/lustre/mdt/mdt_hsm_cdt_requests.c +++ b/lustre/mdt/mdt_hsm_cdt_requests.c @@ -38,7 +38,7 @@ static void *cdt_request_cookie_key(struct hlist_node *hnode) { struct cdt_agent_req *car = cdt_request_cookie_object(hnode); - return &car->car_hai->hai_cookie; + return &car->car_hai.hai_cookie; } static int cdt_request_cookie_keycmp(const void *key, struct hlist_node *hnode) @@ -88,16 +88,16 @@ void dump_requests(char *prefix, struct coordinator *cdt) " action=%s archive#=%d flags=%#llx" " extent=%#llx-%#llx" " gid=%#llx refcount=%d canceled=%d\n", - prefix, PFID(&car->car_hai->hai_fid), - PFID(&car->car_hai->hai_dfid), - car->car_hai->hai_cookie, - hsm_copytool_action2name(car->car_hai->hai_action), + prefix, PFID(&car->car_hai.hai_fid), + PFID(&car->car_hai.hai_dfid), + car->car_hai.hai_cookie, + hsm_copytool_action2name(car->car_hai.hai_action), car->car_archive_id, car->car_flags, - car->car_hai->hai_extent.offset, - car->car_hai->hai_extent.length, - car->car_hai->hai_gid, + car->car_hai.hai_extent.offset, + car->car_hai.hai_extent.length, + car->car_hai.hai_gid, kref_read(&car->car_refcount), - car->car_canceled); + car->car_cancel ? 1 : 0); } up_read(&cdt->cdt_request_lock); } @@ -199,18 +199,21 @@ static void mdt_cdt_init_request_tree(struct cdt_req_progress *crp) progress_iter_next(NULL, 0, 0); } +static inline int hmmr_size(int rec_size) +{ + return __ALIGN_KERNEL(offsetof(struct hsm_mem_req_rec, mr_rec) + + rec_size, 8); +} + /** Allocate/init an agent request and its sub-structures. * - * \param archive_id [IN] - * \param flags [IN] * \param uuid [IN] - * \param hai [IN] + * \param rec [IN] * \retval car [OUT] success valid structure - * \retval car [OUT] + * \retval -ve failure */ -struct cdt_agent_req *mdt_cdt_alloc_request(__u32 archive_id, __u64 flags, - struct obd_uuid *uuid, - struct hsm_action_item *hai) +struct cdt_agent_req *mdt_cdt_alloc_request(struct obd_uuid *uuid, + struct llog_agent_req_rec *rec) { struct cdt_agent_req *car; ENTRY; @@ -220,20 +223,15 @@ struct cdt_agent_req *mdt_cdt_alloc_request(__u32 archive_id, __u64 flags, RETURN(ERR_PTR(-ENOMEM)); kref_init(&car->car_refcount); - car->car_archive_id = archive_id; - car->car_flags = flags; - car->car_canceled = 0; - car->car_req_start = ktime_get_real_seconds(); - car->car_req_update = car->car_req_start; car->car_uuid = *uuid; - OBD_ALLOC(car->car_hai, hai->hai_len); - if (car->car_hai == NULL) { + OBD_ALLOC(car->car_hmm, hmmr_size(rec->arr_hdr.lrh_len)); + if (car->car_hmm == NULL) { OBD_SLAB_FREE_PTR(car, mdt_hsm_car_kmem); RETURN(ERR_PTR(-ENOMEM)); } - memcpy(car->car_hai, hai, hai->hai_len); + memcpy(&car->car_hmm->mr_rec, rec, rec->arr_hdr.lrh_len); mdt_cdt_init_request_tree(&car->car_progress); - + car->car_cancel = NULL; RETURN(car); } @@ -245,7 +243,7 @@ struct cdt_agent_req *mdt_cdt_alloc_request(__u32 archive_id, __u64 flags, void mdt_cdt_free_request(struct cdt_agent_req *car) { mdt_cdt_free_request_tree(&car->car_progress); - OBD_FREE(car->car_hai, car->car_hai->hai_len); + OBD_FREE(car->car_hmm, hmmr_size(car->car_hmm->mr_rec.arr_hdr.lrh_len)); OBD_SLAB_FREE_PTR(car, mdt_hsm_car_kmem); } @@ -289,12 +287,12 @@ int mdt_cdt_add_request(struct coordinator *cdt, struct cdt_agent_req *car) ENTRY; /* cancel requests are not kept in memory */ - LASSERT(car->car_hai->hai_action != HSMA_CANCEL); + LASSERT(car->car_hai.hai_action != HSMA_CANCEL); down_write(&cdt->cdt_request_lock); rc = cfs_hash_add_unique(cdt->cdt_request_cookie_hash, - &car->car_hai->hai_cookie, + &car->car_hai.hai_cookie, &car->car_cookie_hash); if (rc < 0) { up_write(&cdt->cdt_request_lock); @@ -303,11 +301,13 @@ int mdt_cdt_add_request(struct coordinator *cdt, struct cdt_agent_req *car) list_add_tail(&car->car_request_list, &cdt->cdt_request_list); + mdt_cdt_get_request(car); + up_write(&cdt->cdt_request_lock); mdt_hsm_agent_update_statistics(cdt, 0, 0, 1, &car->car_uuid); - switch (car->car_hai->hai_action) { + switch (car->car_hai.hai_action) { case HSMA_ARCHIVE: atomic_inc(&cdt->cdt_archive_count); break; @@ -363,7 +363,7 @@ int mdt_cdt_remove_request(struct coordinator *cdt, __u64 cookie) list_del(&car->car_request_list); up_write(&cdt->cdt_request_lock); - switch (car->car_hai->hai_action) { + switch (car->car_hai.hai_action) { case HSMA_ARCHIVE: atomic_dec(&cdt->cdt_archive_count); break; @@ -375,6 +375,13 @@ int mdt_cdt_remove_request(struct coordinator *cdt, __u64 cookie) break; } + if (car->car_cancel) { + mdt_cdt_put_request(car->car_cancel); + /* ref from mdt_hsm_add_hsr()->mdt_cdt_find_request() */ + mdt_cdt_put_request(car); + car->car_cancel = NULL; + } + /* Drop reference from cdt_request_list. */ mdt_cdt_put_request(car); @@ -410,7 +417,7 @@ struct cdt_agent_req *mdt_cdt_update_request(struct coordinator *cdt, car->car_req_update = ktime_get_real_seconds(); /* update data move progress done by copy tool */ - if (car->car_hai->hai_action != HSMA_REMOVE && pgs->hpk_errval == 0 && + if (car->car_hai.hai_action != HSMA_REMOVE && pgs->hpk_errval == 0 && pgs->hpk_extent.length != 0) { rc = hsm_update_work(&car->car_progress, &pgs->hpk_extent); if (rc) { @@ -502,16 +509,16 @@ static int mdt_hsm_active_requests_proc_show(struct seq_file *s, void *v) " action=%s archive#=%d flags=%#llx" " extent=%#llx-%#llx gid=%#llx" " data=[%s] canceled=%d uuid=%s done=%llu\n", - PFID(&car->car_hai->hai_fid), - PFID(&car->car_hai->hai_dfid), - 0ULL /* compound_id */, car->car_hai->hai_cookie, - hsm_copytool_action2name(car->car_hai->hai_action), + PFID(&car->car_hai.hai_fid), + PFID(&car->car_hai.hai_dfid), + 0ULL /* compound_id */, car->car_hai.hai_cookie, + hsm_copytool_action2name(car->car_hai.hai_action), car->car_archive_id, car->car_flags, - car->car_hai->hai_extent.offset, - car->car_hai->hai_extent.length, - car->car_hai->hai_gid, - hai_dump_data_field(car->car_hai, buf, sizeof(buf)), - car->car_canceled, obd_uuid2str(&car->car_uuid), + car->car_hai.hai_extent.offset, + car->car_hai.hai_extent.length, + car->car_hai.hai_gid, + hai_dump_data_field(&car->car_hai, buf, sizeof(buf)), + car->car_cancel ? 1 : 0, obd_uuid2str(&car->car_uuid), car->car_progress.crp_total); RETURN(0); } diff --git a/lustre/mdt/mdt_internal.h b/lustre/mdt/mdt_internal.h index ed954cb..b7ce7e2 100644 --- a/lustre/mdt/mdt_internal.h +++ b/lustre/mdt/mdt_internal.h @@ -151,11 +151,6 @@ struct coordinator { * restore requests */ - /* Hash of cookies to locations of record locations in agent - * request log. - */ - struct cfs_hash *cdt_agent_record_hash; - /* Bitmasks indexed by the HSMA_XXX constants. */ __u64 cdt_user_request_mask; __u64 cdt_group_request_mask; @@ -604,17 +599,19 @@ struct cdt_req_progress { struct cdt_agent_req { struct hlist_node car_cookie_hash; /**< find req by cookie */ struct list_head car_request_list; /**< to chain all the req. */ + struct list_head car_scan_list; /**< list for scan process */ struct kref car_refcount; /**< reference counter */ - __u64 car_flags; /**< request original flags */ struct obd_uuid car_uuid; /**< agent doing the req. */ - __u32 car_archive_id; /**< archive id */ - int car_canceled; /**< request was canceled */ - time64_t car_req_start; /**< start time */ - time64_t car_req_update; /**< last update time */ - struct hsm_action_item *car_hai; /**< req. to the agent */ + struct hsm_mem_req_rec *car_hmm; /**< llog rec with cookies */ struct cdt_req_progress car_progress; /**< track data mvt * progress */ + struct cdt_agent_req *car_cancel; /**< corresponding cancel */ }; +#define car_flags car_hmm->mr_rec.arr_flags /**< request original flags */ +#define car_archive_id car_hmm->mr_rec.arr_archive_id /**< archive id */ +#define car_req_update car_hmm->mr_rec.arr_req_change /**< last update time */ +#define car_hai car_hmm->mr_rec.arr_hai /**< req. to the agent */ + extern struct kmem_cache *mdt_hsm_car_kmem; struct hsm_agent { @@ -643,6 +640,37 @@ struct hsm_record_update { enum agent_req_status status; }; +struct hsm_mem_req_rec { + struct llog_logid mr_lid; + u64 mr_offset; + struct llog_agent_req_rec mr_rec; +}; + +/** + * data passed to llog_cat_process() callback + * to scan requests and take actions + */ +struct hsm_scan_request { + struct list_head hsr_cars; + char *hsr_fsname; + int hsr_used_sz; + u32 hsr_version; + u32 hsr_count; +}; + +static inline u32 hsr_get_archive_id(struct hsm_scan_request *rq) +{ + struct cdt_agent_req *car; + + if (rq->hsr_count > 0) { + car = list_first_entry(&rq->hsr_cars, struct cdt_agent_req, + car_scan_list); + + return car->car_archive_id; + } + return 0; +} + static inline const struct md_device_operations *mdt_child_ops(struct mdt_device *m) { @@ -1071,15 +1099,9 @@ int cdt_llog_process(const struct lu_env *env, struct mdt_device *mdt, int mdt_agent_record_add(const struct lu_env *env, struct mdt_device *mdt, __u32 archive_id, __u64 flags, struct hsm_action_item *hai); -int mdt_agent_record_update(struct mdt_thread_info *mti, - struct hsm_record_update *updates, - unsigned int updates_count); -void cdt_agent_record_hash_add(struct coordinator *cdt, u64 cookie, u32 cat_idt, - u32 rec_idx); -void cdt_agent_record_hash_lookup(struct coordinator *cdt, u64 cookie, - u32 *cat_idt, u32 *rec_idx); -void cdt_agent_record_hash_del(struct coordinator *cdt, u64 cookie); - +int mdt_hsm_agent_modify_record(const struct lu_env *env, + struct mdt_device *mdt, + struct hsm_mem_req_rec *hmm); /* mdt/mdt_hsm_cdt_agent.c */ extern const struct file_operations mdt_hsm_agent_fops; int mdt_hsm_agent_register(struct mdt_thread_info *info, @@ -1095,7 +1117,7 @@ int mdt_hsm_agent_update_statistics(struct coordinator *cdt, const struct obd_uuid *uuid); int mdt_hsm_find_best_agent(struct coordinator *cdt, __u32 archive, struct obd_uuid *uuid); -int mdt_hsm_agent_send(struct mdt_thread_info *mti, struct hsm_action_list *hal, +int mdt_hsm_agent_send(struct mdt_thread_info *mti, struct hsm_scan_request *rq, bool purge); /* mdt/mdt_hsm_cdt_client.c */ int mdt_hsm_add_actions(struct mdt_thread_info *info, @@ -1109,12 +1131,10 @@ bool mdt_hsm_restore_is_running(struct mdt_thread_info *mti, const struct lu_fid *fid); /* mdt/mdt_hsm_cdt_requests.c */ extern struct cfs_hash_ops cdt_request_cookie_hash_ops; -extern struct cfs_hash_ops cdt_agent_record_hash_ops; extern const struct file_operations mdt_hsm_active_requests_fops; void dump_requests(char *prefix, struct coordinator *cdt); -struct cdt_agent_req *mdt_cdt_alloc_request(__u32 archive_id, __u64 flags, - struct obd_uuid *uuid, - struct hsm_action_item *hai); +struct cdt_agent_req *mdt_cdt_alloc_request(struct obd_uuid *uuid, + struct llog_agent_req_rec *rec); void mdt_cdt_free_request(struct cdt_agent_req *car); int mdt_cdt_add_request(struct coordinator *cdt, struct cdt_agent_req *new_car); struct cdt_agent_req *mdt_cdt_find_request(struct coordinator *cdt, u64 cookie); @@ -1161,8 +1181,8 @@ struct mdt_object *mdt_hsm_get_md_hsm(struct mdt_thread_info *mti, const struct lu_fid *fid, struct md_hsm *hsm); /* actions/request helpers */ -int mdt_hsm_add_hal(struct mdt_thread_info *mti, - struct hsm_action_list *hal, struct obd_uuid *uuid); +int mdt_hsm_add_hsr(struct mdt_thread_info *mti, struct hsm_scan_request *hsr, + struct obd_uuid *uuid); bool mdt_hsm_is_action_compat(const struct hsm_action_item *hai, u32 archive_id, u64 rq_flags, const struct md_hsm *hsm); diff --git a/lustre/mgs/mgs_llog.c b/lustre/mgs/mgs_llog.c index 1934e27..a8b9ee2 100644 --- a/lustre/mgs/mgs_llog.c +++ b/lustre/mgs/mgs_llog.c @@ -1152,9 +1152,7 @@ static int mgs_modify_param_hdl(const struct lu_env *env, GOTO(free_mdp, rc = -EBADMSG); /* save the start marker to skip */ - rc = llog_get_cookie(env, &mpm->mpm_start_cookie); - if (rc) - RETURN(rc); + llog_get_cookie(env, &mpm->mpm_start_cookie); OBD_ALLOC(mpm->mpm_start, rec->lrh_len); if (!mpm->mpm_start) diff --git a/lustre/obdclass/llog.c b/lustre/obdclass/llog.c index 982d21b..0a1119f 100644 --- a/lustre/obdclass/llog.c +++ b/lustre/obdclass/llog.c @@ -1325,17 +1325,19 @@ int llog_erase(const struct lu_env *env, struct llog_ctxt *ctxt, } EXPORT_SYMBOL(llog_erase); -/* Get current llog cookie from llog_process_thread session */ -int llog_get_cookie(const struct lu_env *env, struct llog_cookie *out) +/* + * Get record cookie, with record file offset, should be called only by + * llog_process_thread() callbacks. + */ +void llog_get_cookie(const struct lu_env *env, struct llog_cookie *out) { struct llog_thread_info *lti = llog_info(env); - if (!out || !lti) - return -EINVAL; + LASSERT(out && env && lti); memcpy(out, <i->lgi_cookie, sizeof(lti->lgi_cookie)); - return 0; + return; } EXPORT_SYMBOL(llog_get_cookie); diff --git a/lustre/obdclass/llog_cat.c b/lustre/obdclass/llog_cat.c index 4252abd..93b9ac1 100644 --- a/lustre/obdclass/llog_cat.c +++ b/lustre/obdclass/llog_cat.c @@ -1272,4 +1272,36 @@ int llog_cat_retain_cb(const struct lu_env *env, struct llog_handle *cat, } EXPORT_SYMBOL(llog_cat_retain_cb); +/* Modify a llog record base on llog_logid and record cookie, + * with valid offset. + */ +int llog_cat_modify_rec(const struct lu_env *env, struct llog_handle *cathandle, + struct llog_logid *lid, struct llog_rec_hdr *rec, + struct llog_cookie *cookie) +{ + struct llog_handle *llh; + int rc; + + ENTRY; + + rc = llog_cat_id2handle(env, cathandle, &llh, lid); + if (rc) { + CDEBUG(D_OTHER, "%s: failed to find log file "DFID": rc = %d\n", + loghandle2name(llh), PLOGID(lid), rc); + RETURN(rc); + } + + rc = llog_write_cookie(env, llh, rec, cookie, rec->lrh_index); + if (rc < 0) { + CDEBUG(D_OTHER, + "%s: failed to modify record "DFID".%d: rc = %d\n", + loghandle2name(llh), PLOGID(lid), rec->lrh_index, rc); + } else { + rc = 0; + } + llog_handle_put(env, llh); + + RETURN(rc); +} +EXPORT_SYMBOL(llog_cat_modify_rec); diff --git a/lustre/obdclass/llog_osd.c b/lustre/obdclass/llog_osd.c index af20930..3669b6d 100644 --- a/lustre/obdclass/llog_osd.c +++ b/lustre/obdclass/llog_osd.c @@ -109,12 +109,6 @@ static int llog_osd_exist(struct llog_handle *handle) return dt_object_exists(handle->lgh_obj) && !handle->lgh_destroyed; } -static void *rec_tail(struct llog_rec_hdr *rec) -{ - return (void *)((char *)rec + rec->lrh_len - - sizeof(struct llog_rec_tail)); -} - /** * Write a padding record to the llog * @@ -159,7 +153,7 @@ static int llog_osd_pad(const struct lu_env *env, struct dt_object *o, rec->lrh_index = index; rec->lrh_type = LLOG_PAD_MAGIC; - tail = rec_tail(rec); + tail = llog_get_rec_tail(rec); tail->lrt_len = len; tail->lrt_index = index; @@ -600,7 +594,7 @@ static int llog_osd_write_rec(const struct lu_env *env, */ LASSERT(index < LLOG_HDR_BITMAP_SIZE(llh)); rec->lrh_index = index; - lrt = rec_tail(rec); + lrt = llog_get_rec_tail(rec); lrt->lrt_len = rec->lrh_len; lrt->lrt_index = rec->lrh_index;