X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fmdt%2Fmdt_hsm_cdt_agent.c;h=c3d41822211400bb58be7e4d80fbcc4df10cc11c;hb=6b8c570c40829873b01b7388a622ae04b63317aa;hp=f5c60eb0b0d46bffa7bd03cc40ae9f0f3c6041a6;hpb=f24d4c4a3146e2200a642fdb71aa0e11afd36874;p=fs%2Flustre-release.git diff --git a/lustre/mdt/mdt_hsm_cdt_agent.c b/lustre/mdt/mdt_hsm_cdt_agent.c index f5c60eb..c3d4182 100644 --- a/lustre/mdt/mdt_hsm_cdt_agent.c +++ b/lustre/mdt/mdt_hsm_cdt_agent.c @@ -21,6 +21,8 @@ */ /* * (C) Copyright 2012 Commissariat a l'energie atomique et aux energies + * + * Copyright (c) 2016, Intel Corporation. * alternatives * */ @@ -40,6 +42,7 @@ #include #include #include +#include #include "mdt_internal.h" /* @@ -48,7 +51,7 @@ /* * find a hsm_agent by uuid - * lock cdt_agent_lock needs to be hold by caller + * lock cdt_agent_lock needs to be held by caller * \param cdt [IN] coordinator * \param uuid [IN] agent UUID * \retval hsm_agent pointer or NULL if not found @@ -57,10 +60,8 @@ static struct hsm_agent *mdt_hsm_agent_lookup(struct coordinator *cdt, const struct obd_uuid *uuid) { struct hsm_agent *ha; - cfs_list_t *pos; - cfs_list_for_each(pos, &cdt->cdt_agents) { - ha = cfs_list_entry(pos, struct hsm_agent, ha_list); + list_for_each_entry(ha, &cdt->cdt_agents, ha_list) { if (obd_uuid_equals(&ha->ha_uuid, uuid)) return ha; } @@ -120,7 +121,7 @@ int mdt_hsm_agent_register(struct mdt_thread_info *mti, GOTO(out_free, rc = -EEXIST); } - cfs_list_add_tail(&ha->ha_list, &cdt->cdt_agents); + list_add_tail(&ha->ha_list, &cdt->cdt_agents); if (ha->ha_archive_cnt == 0) CDEBUG(D_HSM, "agent %s registered for all archives\n", @@ -134,7 +135,7 @@ int mdt_hsm_agent_register(struct mdt_thread_info *mti, out_free: - if ((ha != NULL) && (ha->ha_archive_id != NULL)) + if (ha != NULL && ha->ha_archive_id != NULL) OBD_FREE(ha->ha_archive_id, ha->ha_archive_cnt * sizeof(*ha->ha_archive_id)); if (ha != NULL) @@ -205,7 +206,7 @@ int mdt_hsm_agent_unregister(struct mdt_thread_info *mti, ha = mdt_hsm_agent_lookup(cdt, uuid); if (ha != NULL) - cfs_list_del_init(&ha->ha_list); + list_del_init(&ha->ha_list); up_write(&cdt->cdt_agent_lock); @@ -239,14 +240,14 @@ int mdt_hsm_agent_update_statistics(struct coordinator *cdt, int succ_rq, int fail_rq, int new_rq, const struct obd_uuid *uuid) { - struct hsm_agent *ha, *tmp; + struct hsm_agent *ha; int rc; ENTRY; down_read(&cdt->cdt_agent_lock); - cfs_list_for_each_entry_safe(ha, tmp, &cdt->cdt_agents, ha_list) { + list_for_each_entry(ha, &cdt->cdt_agents, ha_list) { if (obd_uuid_equals(&ha->ha_uuid, uuid)) { - if ((succ_rq == 0) && (fail_rq == 0) && (new_rq == 0)) { + if (succ_rq == 0 && fail_rq == 0 && new_rq == 0) { atomic_set(&ha->ha_success, 0); atomic_set(&ha->ha_failure, 0); atomic_set(&ha->ha_requests, 0); @@ -279,23 +280,22 @@ int mdt_hsm_find_best_agent(struct coordinator *cdt, __u32 archive, struct obd_uuid *uuid) { int rc = -EAGAIN, i, load = -1; - struct hsm_agent *ha, *tmp; + struct hsm_agent *ha; ENTRY; /* Choose an export to send a copytool req to */ down_read(&cdt->cdt_agent_lock); - cfs_list_for_each_entry_safe(ha, tmp, &cdt->cdt_agents, ha_list) { + list_for_each_entry(ha, &cdt->cdt_agents, ha_list) { for (i = 0; (i < ha->ha_archive_cnt) && (ha->ha_archive_id[i] != archive); i++) { /* nothing to do, just skip unmatching records */ } /* archive count == 0 means copy tool serves any backend */ - if ((ha->ha_archive_cnt != 0) && (i == ha->ha_archive_cnt)) + if (ha->ha_archive_cnt != 0 && i == ha->ha_archive_cnt) continue; - if ((load == -1) || - (load > atomic_read(&ha->ha_requests))) { + if (load == -1 || load > atomic_read(&ha->ha_requests)) { load = atomic_read(&ha->ha_requests); *uuid = ha->ha_uuid; rc = 0; @@ -308,6 +308,59 @@ int mdt_hsm_find_best_agent(struct coordinator *cdt, __u32 archive, 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 @@ -336,6 +389,61 @@ int mdt_hsm_agent_send(struct mdt_thread_info *mti, 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); @@ -346,51 +454,47 @@ int mdt_hsm_agent_send(struct mdt_thread_info *mti, hal->hal_archive_id); len = hal_size(hal); - if (kuc_ispayload(hal)) { - /* hal is already a kuc payload - * we do not need to alloc a new one - * this avoid a alloc/memcpy/free - */ - buf = hal; - } else { - buf = kuc_alloc(len, KUC_TRANSPORT_HSM, HMT_ACTION_LIST); - if (IS_ERR(buf)) - RETURN(PTR_ERR(buf)); - memcpy(buf, hal, len); - } + buf = kuc_alloc(len, KUC_TRANSPORT_HSM, HMT_ACTION_LIST); + if (IS_ERR(buf)) + RETURN(PTR_ERR(buf)); + memcpy(buf, hal, len); /* Check if request is still valid (cf file hsm flags) */ fail_request = false; - hai = hai_zero(hal); + 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; - obj = mdt_hsm_get_md_hsm(mti, &hai->hai_fid, &hsm, - NULL); - if (IS_ERR(obj) && (hai->hai_action == HSMA_REMOVE)) - continue; + 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 (IS_ERR(obj) && (PTR_ERR(obj) == -ENOENT)) { - fail_request = true; - rc = mdt_agent_record_update(mti->mti_env, mdt, + 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, rc=%d, cannot update " + if (rc) { + CERROR( + "%s: mdt_agent_record_update() " + "failed, cannot update " "status to %s for cookie " - LPX64": rc = %d\n", - mdt_obd_name(mdt), rc, + "%#llx: rc = %d\n", + mdt_obd_name(mdt), agent_req_status2name(ARS_FAILED), hai->hai_cookie, rc); - GOTO(out_buf, rc); + GOTO(out_buf, rc); + } + continue; } - continue; - } - if (IS_ERR(obj)) GOTO(out_buf, rc = PTR_ERR(obj)); + } if (!mdt_hsm_is_action_compat(hai, hal->hal_archive_id, hal->hal_flags, &hsm)) { @@ -404,14 +508,41 @@ int mdt_hsm_agent_send(struct mdt_thread_info *mti, 1, ARS_FAILED); if (rc) { CERROR("%s: mdt_agent_record_update() " - "failed, rc=%d, cannot update " + "failed, cannot update " "status to %s for cookie " - LPX64": rc = %d\n", - mdt_obd_name(mdt), rc, + "%#llx: 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; + struct mdt_object *obj = 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); + obj = mdt_object_find(mti->mti_env, + mti->mti_mdt, + &hai->hai_fid); + if (!IS_ERR(obj) && crh != NULL) + mdt_object_unlock(mti, obj, + &crh->crh_lh, + 1); + if (crh != NULL) + OBD_SLAB_FREE_PTR(crh, + mdt_hsm_cdt_kmem); + if (!IS_ERR(obj)) + mdt_object_put(mti->mti_env, + obj); + } } } } @@ -444,7 +575,9 @@ int mdt_hsm_agent_send(struct mdt_thread_info *mti, * from a server (MDT) to a client (MDC), backwards of normal comms. */ exp = cfs_hash_lookup(mdt2obd_dev(mdt)->obd_uuid_hash, &uuid); - if ((exp == NULL) || (exp->exp_disconnected)) { + 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:" @@ -476,7 +609,7 @@ int mdt_hsm_agent_send(struct mdt_thread_info *mti, out: if (rc != 0 && is_registered) { /* in case of error, we have to unregister requests */ - hai = hai_zero(hal); + hai = hai_first(hal); for (i = 0; i < hal->hal_count; i++, hai = hai_next(hai)) { if (hai->hai_action == HSMA_CANCEL) continue; @@ -485,8 +618,7 @@ out: } out_buf: - if (buf != hal) - kuc_free(buf, len); + kuc_free(buf, len); RETURN(rc); } @@ -504,7 +636,7 @@ int mdt_hsm_coordinator_update(struct mdt_thread_info *mti, int rc; ENTRY; - /* ask to coodinator to update request state and + /* ask to coordinator to update request state and * to record on disk the result */ rc = mdt_hsm_update_request_state(mti, pgs, 1); RETURN(rc); @@ -517,20 +649,20 @@ static void *mdt_hsm_agent_proc_start(struct seq_file *s, loff_t *off) { struct mdt_device *mdt = s->private; struct coordinator *cdt = &mdt->mdt_coordinator; - cfs_list_t *pos; + struct list_head *pos; loff_t i; ENTRY; down_read(&cdt->cdt_agent_lock); - if (cfs_list_empty(&cdt->cdt_agents)) + if (list_empty(&cdt->cdt_agents)) RETURN(NULL); if (*off == 0) RETURN(SEQ_START_TOKEN); i = 0; - cfs_list_for_each(pos, &cdt->cdt_agents) { + list_for_each(pos, &cdt->cdt_agents) { i++; if (i >= *off) RETURN(pos); @@ -547,7 +679,7 @@ static void *mdt_hsm_agent_proc_next(struct seq_file *s, void *v, loff_t *p) { struct mdt_device *mdt = s->private; struct coordinator *cdt = &mdt->mdt_coordinator; - cfs_list_t *pos = v; + struct list_head *pos = v; ENTRY; if (pos == SEQ_START_TOKEN) @@ -566,7 +698,7 @@ static void *mdt_hsm_agent_proc_next(struct seq_file *s, void *v, loff_t *p) */ static int mdt_hsm_agent_proc_show(struct seq_file *s, void *v) { - cfs_list_t *pos = v; + struct list_head *pos = v; struct hsm_agent *ha; int i; ENTRY; @@ -574,16 +706,17 @@ static int mdt_hsm_agent_proc_show(struct seq_file *s, void *v) if (pos == SEQ_START_TOKEN) RETURN(0); - ha = cfs_list_entry(pos, struct hsm_agent, ha_list); - seq_printf(s, "uuid=%s archive#=%d (", ha->ha_uuid.uuid, - ha->ha_archive_cnt); - if (ha->ha_archive_cnt == 0) - seq_printf(s, "all"); - else - for (i = 0; i < ha->ha_archive_cnt; i++) - seq_printf(s, "%d ", ha->ha_archive_id[i]); + ha = list_entry(pos, struct hsm_agent, ha_list); + seq_printf(s, "uuid=%s archive_id=", ha->ha_uuid.uuid); + if (ha->ha_archive_cnt == 0) { + seq_printf(s, "ANY"); + } else { + seq_printf(s, "%d", ha->ha_archive_id[0]); + for (i = 1; i < ha->ha_archive_cnt; i++) + seq_printf(s, ",%d", ha->ha_archive_id[i]); + } - seq_printf(s, ") r=%d s=%d f=%d\n", + seq_printf(s, " requests=[current:%d ok:%d errors:%d]\n", atomic_read(&ha->ha_requests), atomic_read(&ha->ha_success), atomic_read(&ha->ha_failure)); @@ -619,16 +752,12 @@ static int lprocfs_open_hsm_agent(struct inode *inode, struct file *file) int rc; ENTRY; - if (LPROCFS_ENTRY_AND_CHECK(PDE(inode))) - RETURN(-ENOENT); - rc = seq_open(file, &mdt_hsm_agent_proc_ops); - if (rc) { - LPROCFS_EXIT(); + if (rc) RETURN(rc); - } + s = file->private_data; - s->private = PDE(inode)->data; + s->private = PDE_DATA(inode); RETURN(rc); }