X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fmdt%2Fmdt_coordinator.c;h=caa57ca8355ebb34747aac16e72036f392aaf35c;hb=12daa707eada5dd8ca1280b133ff52d13daf4522;hp=87a5f3ea891bf311d1e2d639e628b229b29ee433;hpb=2edc131c4d00809d0afd7606e503ebae6f0618d8;p=fs%2Flustre-release.git diff --git a/lustre/mdt/mdt_coordinator.c b/lustre/mdt/mdt_coordinator.c index 87a5f3e..caa57ca 100644 --- a/lustre/mdt/mdt_coordinator.c +++ b/lustre/mdt/mdt_coordinator.c @@ -20,10 +20,11 @@ * GPL HEADER END */ /* - * Copyright (c) 2012, 2013, Intel Corporation. - * Use is subject to license terms. * Copyright (c) 2011, 2012 Commissariat a l'energie atomique et aux energies * alternatives + * + * Copyright (c) 2013, 2014, Intel Corporation. + * Use is subject to license terms. */ /* * lustre/mdt/mdt_coordinator.c @@ -37,13 +38,14 @@ #define DEBUG_SUBSYSTEM S_MDS +#include #include #include #include #include -#include #include #include +#include #include "mdt_internal.h" static struct lprocfs_vars lprocfs_mdt_hsm_vars[]; @@ -140,10 +142,6 @@ struct hsm_scan_data { int hal_used_sz; struct hsm_action_list *hal; } *request; - /* records to be canceled */ - int max_cookie; /** vector size */ - int cookie_cnt; /** used count */ - __u64 *cookies; }; /** @@ -162,7 +160,7 @@ static int mdt_coordinator_cb(const struct lu_env *env, struct llog_rec_hdr *hdr, void *data) { - const struct llog_agent_req_rec *larr; + struct llog_agent_req_rec *larr; struct hsm_scan_data *hsd; struct hsm_action_item *hai; struct mdt_device *mdt; @@ -185,8 +183,8 @@ static int mdt_coordinator_cb(const struct lu_env *env, cdt->cdt_max_requests) break; - /* first search if the request if known in the list we have - * build and if there is room in the request vector */ + /* first search whether the request is found in the list we + * have built and if there is room in the request vector */ empty_slot = -1; found = -1; for (i = 0; i < hsd->max_requests && @@ -228,9 +226,8 @@ static int mdt_coordinator_cb(const struct lu_env *env, RETURN(-ENOMEM); } hal->hal_version = HAL_VERSION; - strncpy(hal->hal_fsname, hsd->fs_name, - MTI_NAME_MAXLEN); - hal->hal_fsname[MTI_NAME_MAXLEN] = '\0'; + strlcpy(hal->hal_fsname, hsd->fs_name, + MTI_NAME_MAXLEN + 1); hal->hal_compound_id = larr->arr_compound_id; hal->hal_archive_id = larr->arr_archive_id; hal->hal_flags = larr->arr_flags; @@ -291,7 +288,9 @@ static int mdt_coordinator_cb(const struct lu_env *env, break; } case ARS_STARTED: { + struct hsm_progress_kernel pgs; struct cdt_agent_req *car; + cfs_time_t now = cfs_time_current_sec(); cfs_time_t last; /* we search for a running request @@ -308,65 +307,52 @@ static int mdt_coordinator_cb(const struct lu_env *env, /* test if request too long, if yes cancel it * the same way the copy tool acknowledge a cancel request */ - if ((last + cdt->cdt_active_req_timeout) - < cfs_time_current_sec()) { - struct hsm_progress_kernel pgs; - - dump_llog_agent_req_rec("mdt_coordinator_cb(): " - "request timeouted, start " - "cleaning", larr); - /* a too old cancel request just needs to be removed - * this can happen, if copy tool does not support cancel - * for other requests, we have to remove the running - * request and notify the copytool - */ - pgs.hpk_fid = larr->arr_hai.hai_fid; - pgs.hpk_cookie = larr->arr_hai.hai_cookie; - pgs.hpk_extent = larr->arr_hai.hai_extent; - pgs.hpk_flags = HP_FLAG_COMPLETED; - pgs.hpk_errval = ENOSYS; - pgs.hpk_data_version = 0; - /* update request state, but do not record in llog, to - * avoid deadlock on cdt_llog_lock - */ - rc = mdt_hsm_update_request_state(hsd->mti, &pgs, 0); - if (rc) - CERROR("%s: Cannot cleanup timeouted request: " - DFID" for cookie "LPX64" action=%s\n", - mdt_obd_name(mdt), - PFID(&pgs.hpk_fid), pgs.hpk_cookie, - hsm_copytool_action2name( - larr->arr_hai.hai_action)); - - /* add the cookie to the list of record to be - * canceled by caller */ - if (hsd->max_cookie == (hsd->cookie_cnt - 1)) { - __u64 *ptr, *old_ptr; - int old_sz, new_sz, new_cnt; + if (now <= last + cdt->cdt_active_req_timeout) + RETURN(0); - /* need to increase vector size */ - old_sz = sizeof(__u64) * hsd->max_cookie; - old_ptr = hsd->cookies; + dump_llog_agent_req_rec("request timed out, start cleaning", + larr); + /* a too old cancel request just needs to be removed + * this can happen, if copy tool does not support + * cancel for other requests, we have to remove the + * running request and notify the copytool */ + pgs.hpk_fid = larr->arr_hai.hai_fid; + pgs.hpk_cookie = larr->arr_hai.hai_cookie; + pgs.hpk_extent = larr->arr_hai.hai_extent; + pgs.hpk_flags = HP_FLAG_COMPLETED; + pgs.hpk_errval = ENOSYS; + pgs.hpk_data_version = 0; + + /* update request state, but do not record in llog, to + * avoid deadlock on cdt_llog_lock */ + rc = mdt_hsm_update_request_state(hsd->mti, &pgs, 0); + if (rc) + CERROR("%s: cannot cleanup timed out request: " + DFID" for cookie "LPX64" action=%s\n", + mdt_obd_name(mdt), + PFID(&pgs.hpk_fid), pgs.hpk_cookie, + hsm_copytool_action2name( + larr->arr_hai.hai_action)); + + if (rc == -ENOENT) { + /* The request no longer exists, forget + * about it, and do not send a cancel request + * to the client, for which an error will be + * sent back, leading to an endless cycle of + * cancellation. */ + RETURN(LLOG_DEL_RECORD); + } - new_cnt = 2 * hsd->max_cookie; - new_sz = sizeof(__u64) * new_cnt; + /* XXX A cancel request cannot be cancelled. */ + if (larr->arr_hai.hai_action == HSMA_CANCEL) + RETURN(0); - OBD_ALLOC(ptr, new_sz); - if (!ptr) { - CERROR("%s: Cannot allocate memory " - "(%d o) for cookie vector\n", - mdt_obd_name(mdt), new_sz); - RETURN(-ENOMEM); - } - memcpy(ptr, hsd->cookies, old_sz); - hsd->cookies = ptr; - hsd->max_cookie = new_cnt; - OBD_FREE(old_ptr, old_sz); - } - hsd->cookies[hsd->cookie_cnt] = - larr->arr_hai.hai_cookie; - hsd->cookie_cnt++; - } + larr->arr_status = ARS_CANCELED; + larr->arr_req_change = now; + rc = llog_write(hsd->mti->mti_env, llh, hdr, hdr->lrh_index); + if (rc < 0) + CERROR("%s: cannot update agent log: rc = %d\n", + mdt_obd_name(mdt), rc); break; } case ARS_FAILED: @@ -441,7 +427,7 @@ static int mdt_coordinator(void *data) struct mdt_thread_info *mti = data; struct mdt_device *mdt = mti->mti_mdt; struct coordinator *cdt = &mdt->mdt_coordinator; - struct hsm_scan_data hsd = { 0 }; + struct hsm_scan_data hsd = { NULL }; int rc = 0; ENTRY; @@ -451,10 +437,6 @@ static int mdt_coordinator(void *data) CDEBUG(D_HSM, "%s: coordinator thread starting, pid=%d\n", mdt_obd_name(mdt), current_pid()); - /* timeouted cookie vector initialization */ - hsd.max_cookie = 0; - hsd.cookie_cnt = 0; - hsd.cookies = NULL; /* we use a copy of cdt_max_requests in the cb, so if cdt_max_requests * increases due to a change from /proc we do not overflow the * hsd.request[] vector @@ -515,16 +497,6 @@ static int mdt_coordinator(void *data) } } - /* create canceled cookie vector for an arbitrary size - * if needed, vector will grow during llog scan - */ - hsd.max_cookie = 10; - hsd.cookie_cnt = 0; - OBD_ALLOC(hsd.cookies, hsd.max_cookie * sizeof(__u64)); - if (!hsd.cookies) { - rc = -ENOMEM; - goto clean_cb_alloc; - } hsd.request_cnt = 0; rc = cdt_llog_process(mti->mti_env, mdt, @@ -532,23 +504,7 @@ static int mdt_coordinator(void *data) if (rc < 0) goto clean_cb_alloc; - CDEBUG(D_HSM, "Found %d requests to send and %d" - " requests to cancel\n", - hsd.request_cnt, hsd.cookie_cnt); - /* first we cancel llog records of the timeouted requests */ - if (hsd.cookie_cnt > 0) { - rc = mdt_agent_record_update(mti->mti_env, mdt, - hsd.cookies, - hsd.cookie_cnt, - ARS_CANCELED); - if (rc) - CERROR("%s: mdt_agent_record_update() failed, " - "rc=%d, cannot update status to %s " - "for %d cookies\n", - mdt_obd_name(mdt), rc, - agent_req_status2name(ARS_CANCELED), - hsd.cookie_cnt); - } + CDEBUG(D_HSM, "found %d requests to send\n", hsd.request_cnt); if (list_empty(&cdt->cdt_agents)) { CDEBUG(D_HSM, "no agent available, " @@ -558,7 +514,7 @@ static int mdt_coordinator(void *data) /* here hsd contains a list of requests to be started */ for (i = 0; i < hsd.max_requests; i++) { - struct hsm_action_list *hal; + struct hsm_action_list *hal = hsd.request[i].hal; struct hsm_action_item *hai; __u64 *cookies; int sz, j; @@ -569,26 +525,10 @@ static int mdt_coordinator(void *data) cdt->cdt_max_requests) break; - if (hsd.request[i].hal == NULL) + if (hal == NULL) continue; /* found a request, we start it */ - /* kuc payload allocation so we avoid an additionnal - * allocation in mdt_hsm_agent_send() - */ - hal = kuc_alloc(hsd.request[i].hal_used_sz, - KUC_TRANSPORT_HSM, HMT_ACTION_LIST); - if (IS_ERR(hal)) { - CERROR("%s: Cannot allocate memory (%d o) " - "for compound "LPX64"\n", - mdt_obd_name(mdt), - hsd.request[i].hal_used_sz, - hsd.request[i].hal->hal_compound_id); - continue; - } - memcpy(hal, hsd.request[i].hal, - hsd.request[i].hal_used_sz); - rc = mdt_hsm_agent_send(mti, hal, 0); /* if failure, we suppose it is temporary * if the copy tool failed to do the request @@ -599,45 +539,34 @@ static int mdt_coordinator(void *data) /* set up cookie vector to set records status * after copy tools start or failed */ - sz = hsd.request[i].hal->hal_count * sizeof(__u64); + sz = hal->hal_count * sizeof(__u64); OBD_ALLOC(cookies, sz); if (cookies == NULL) { CERROR("%s: Cannot allocate memory (%d o) " "for cookies vector "LPX64"\n", mdt_obd_name(mdt), sz, - hsd.request[i].hal->hal_compound_id); - kuc_free(hal, hsd.request[i].hal_used_sz); + hal->hal_compound_id); continue; } hai = hai_first(hal); - for (j = 0; j < hsd.request[i].hal->hal_count; j++) { + for (j = 0; j < hal->hal_count; j++) { cookies[j] = hai->hai_cookie; hai = hai_next(hai); } rc = mdt_agent_record_update(mti->mti_env, mdt, cookies, - hsd.request[i].hal->hal_count, - status); + hal->hal_count, status); if (rc) CERROR("%s: mdt_agent_record_update() failed, " "rc=%d, cannot update status to %s " "for %d cookies\n", mdt_obd_name(mdt), rc, agent_req_status2name(status), - hsd.request[i].hal->hal_count); + hal->hal_count); OBD_FREE(cookies, sz); - kuc_free(hal, hsd.request[i].hal_used_sz); } clean_cb_alloc: - /* free cookie vector allocated for/by callback */ - if (hsd.cookies) { - OBD_FREE(hsd.cookies, hsd.max_cookie * sizeof(__u64)); - hsd.max_cookie = 0; - hsd.cookie_cnt = 0; - hsd.cookies = NULL; - } - /* free hal allocated by callback */ for (i = 0; i < hsd.max_requests; i++) { if (hsd.request[i].hal) { @@ -658,9 +587,6 @@ out: if (hsd.request) OBD_FREE(hsd.request, hsd.request_sz); - if (hsd.cookies) - OBD_FREE(hsd.cookies, hsd.max_cookie * sizeof(__u64)); - if (cdt->cdt_state == CDT_STOPPING) { /* request comes from /proc path, so we need to clean cdt * struct */ @@ -694,7 +620,7 @@ out: * \retval cdt_restore_handle found * \retval NULL not found */ -static struct cdt_restore_handle *hsm_restore_hdl_find(struct coordinator *cdt, +struct cdt_restore_handle *mdt_hsm_restore_hdl_find(struct coordinator *cdt, const struct lu_fid *fid) { struct cdt_restore_handle *crh; @@ -755,6 +681,17 @@ static int hsm_restore_cb(const struct lu_env *env, /* restore request not in a final state */ + /* force replay of restore requests left in started state from previous + * CDT context, to be canceled later if finally found to be incompatible + * when being re-started */ + if (larr->arr_status == ARS_STARTED) { + larr->arr_status = ARS_WAITING; + larr->arr_req_change = cfs_time_current_sec(); + rc = llog_write(env, llh, hdr, hdr->lrh_index); + if (rc != 0) + GOTO(out, rc); + } + OBD_SLAB_ALLOC_PTR(crh, mdt_hsm_cdt_kmem); if (crh == NULL) RETURN(-ENOMEM); @@ -870,9 +807,9 @@ int mdt_hsm_cdt_init(struct mdt_device *mdt) init_rwsem(&cdt->cdt_request_lock); mutex_init(&cdt->cdt_restore_lock); - CFS_INIT_LIST_HEAD(&cdt->cdt_requests); - CFS_INIT_LIST_HEAD(&cdt->cdt_agents); - CFS_INIT_LIST_HEAD(&cdt->cdt_restore_hdl); + INIT_LIST_HEAD(&cdt->cdt_requests); + INIT_LIST_HEAD(&cdt->cdt_agents); + INIT_LIST_HEAD(&cdt->cdt_restore_hdl); rc = lu_env_init(&cdt->cdt_env, LCT_MD_THREAD); if (rc < 0) @@ -973,7 +910,7 @@ int mdt_hsm_cdt_start(struct mdt_device *mdt) rc = mdt_hsm_pending_restore(cdt_mti); if (rc) CERROR("%s: cannot take the layout locks needed" - " for registered restore: %d", + " for registered restore: %d\n", mdt_obd_name(mdt), rc); task = kthread_run(mdt_coordinator, cdt_mti, "hsm_cdtr"); @@ -1157,9 +1094,11 @@ out: * \param mti [IN] context * \param fid1 [IN] * \param fid2 [IN] + * \param mh_common [IN] MD HSM */ static int hsm_swap_layouts(struct mdt_thread_info *mti, - const lustre_fid *fid, const lustre_fid *dfid) + const lustre_fid *fid, const lustre_fid *dfid, + struct md_hsm *mh_common) { struct mdt_device *mdt = mti->mti_mdt; struct mdt_object *child1, *child2; @@ -1182,15 +1121,28 @@ static int hsm_swap_layouts(struct mdt_thread_info *mti, /* if copy tool closes the volatile before sending the final * progress through llapi_hsm_copy_end(), all the objects * are removed and mdd_swap_layout LBUG */ - if (mdt_object_exists(child2)) { - rc = mo_swap_layouts(mti->mti_env, mdt_object_child(child1), - mdt_object_child(child2), 0); - } else { + if (!mdt_object_exists(child2)) { CERROR("%s: Copytool has closed volatile file "DFID"\n", mdt_obd_name(mti->mti_mdt), PFID(dfid)); - rc = -ENOENT; + GOTO(out_child2, rc = -ENOENT); } + /* Since we only handle restores here, unconditionally use + * SWAP_LAYOUTS_MDS_HSM flag to ensure original layout will + * be preserved in case of failure during swap_layout and not + * leave a file in an intermediate but incoherent state. + * But need to setup HSM xattr of data FID before, reuse + * mti and mh presets for FID in hsm_cdt_request_completed(), + * only need to clear RELEASED and DIRTY. + */ + mh_common->mh_flags &= ~(HS_RELEASED | HS_DIRTY); + rc = mdt_hsm_attr_set(mti, child2, mh_common); + if (rc == 0) + rc = mo_swap_layouts(mti->mti_env, + mdt_object_child(child1), + mdt_object_child(child2), + SWAP_LAYOUTS_MDS_HSM); +out_child2: mdt_object_unlock_put(mti, child2, lh2, 1); out_child1: mdt_object_put(mti->mti_env, child1); @@ -1247,7 +1199,7 @@ static int hsm_cdt_request_completed(struct mdt_thread_info *mti, * ENOSYS only if does not support cancel */ /* this can also happen when cdt calls it to - * for a timeouted request */ + * for a timed out request */ *status = ARS_FAILED; /* to have a cancel event in changelog */ pgs->hpk_errval = ECANCELED; @@ -1320,8 +1272,10 @@ static int hsm_cdt_request_completed(struct mdt_thread_info *mti, case HSMA_RESTORE: hsm_set_cl_event(&cl_flags, HE_RESTORE); - /* clear RELEASED and DIRTY */ - mh.mh_flags &= ~(HS_RELEASED | HS_DIRTY); + /* do not clear RELEASED and DIRTY here + * this will occur in hsm_swap_layouts() + */ + /* Restoring has changed the file version on * disk. */ mh.mh_arch_ver = pgs->hpk_data_version; @@ -1375,10 +1329,10 @@ unlock: struct cdt_restore_handle *crh; /* restore in data FID done, we swap the layouts - * only if restore is successfull */ + * only if restore is successful */ if (pgs->hpk_errval == 0) { rc = hsm_swap_layouts(mti, &car->car_hai->hai_fid, - &car->car_hai->hai_dfid); + &car->car_hai->hai_dfid, &mh); if (rc) { if (cdt->cdt_policy & CDT_NORETRY_ACTION) *status = ARS_FAILED; @@ -1391,7 +1345,7 @@ unlock: /* give back layout lock */ mutex_lock(&cdt->cdt_restore_lock); - crh = hsm_restore_hdl_find(cdt, &car->car_hai->hai_fid); + crh = mdt_hsm_restore_hdl_find(cdt, &car->car_hai->hai_fid); if (crh != NULL) list_del(&crh->crh_list); mutex_unlock(&cdt->cdt_restore_lock); @@ -1446,8 +1400,7 @@ int mdt_hsm_update_request_state(struct mdt_thread_info *mti, " on fid="DFID"\n", mdt_obd_name(mdt), pgs->hpk_cookie, PFID(&pgs->hpk_fid)); - if (car == NULL) - RETURN(-ENOENT); + RETURN(PTR_ERR(car)); } @@ -1578,10 +1531,9 @@ static int mdt_cancel_all_cb(const struct lu_env *env, larr->arr_status == ARS_STARTED) { larr->arr_status = ARS_CANCELED; larr->arr_req_change = cfs_time_current_sec(); - rc = mdt_agent_llog_update_rec(env, hcad->mdt, llh, larr); - if (rc == 0) - RETURN(LLOG_DEL_RECORD); + rc = llog_write(env, llh, hdr, hdr->lrh_index); } + RETURN(rc); } @@ -1686,7 +1638,7 @@ out: } /** - * check if a request is comptaible with file status + * check if a request is compatible with file status * \param hai [IN] request description * \param hal_an [IN] request archive number (not used) * \param rq_flags [IN] request flags @@ -1769,22 +1721,17 @@ static __u64 hsm_policy_str2bit(const char *name) * \param hexa [IN] print mask before bit names * \param buffer [OUT] string * \param count [IN] size of buffer - * \retval size filled in buffer */ -static int hsm_policy_bit2str(const __u64 mask, const bool hexa, char *buffer, - int count) +static void hsm_policy_bit2str(struct seq_file *m, const __u64 mask, + const bool hexa) { - int i, j, sz; - char *ptr; + int i, j; __u64 bit; ENTRY; - ptr = buffer; - if (hexa) { - sz = snprintf(buffer, count, "("LPX64") ", mask); - ptr += sz; - count -= sz; - } + if (hexa) + seq_printf(m, "("LPX64") ", mask); + for (i = 0; i < CDT_POLICY_SHIFT_COUNT; i++) { bit = (1ULL << i); @@ -1793,48 +1740,37 @@ static int hsm_policy_bit2str(const __u64 mask, const bool hexa, char *buffer, break; } if (bit & mask) - sz = snprintf(ptr, count, "[%s] ", - hsm_policy_names[j].name); + seq_printf(m, "[%s] ", hsm_policy_names[j].name); else - sz = snprintf(ptr, count, "%s ", - hsm_policy_names[j].name); - - ptr += sz; - count -= sz; + seq_printf(m, "%s ", hsm_policy_names[j].name); } /* remove last ' ' */ - *ptr = '\0'; - ptr--; - RETURN(ptr - buffer); + m->count--; + seq_putc(m, '\0'); } /* methods to read/write HSM policy flags */ -static int lprocfs_rd_hsm_policy(char *page, char **start, off_t off, - int count, int *eof, void *data) +static int mdt_hsm_policy_seq_show(struct seq_file *m, void *data) { - struct mdt_device *mdt = data; + struct mdt_device *mdt = m->private; struct coordinator *cdt = &mdt->mdt_coordinator; - int sz; ENTRY; - sz = hsm_policy_bit2str(cdt->cdt_policy, false, page, count); - page[sz] = '\n'; - sz++; - page[sz] = '\0'; - *eof = 1; - RETURN(sz); + hsm_policy_bit2str(m, cdt->cdt_policy, false); + RETURN(0); } -static int lprocfs_wr_hsm_policy(struct file *file, const char *buffer, - unsigned long count, void *data) +static ssize_t +mdt_hsm_policy_seq_write(struct file *file, const char __user *buffer, + size_t count, loff_t *off) { - struct mdt_device *mdt = data; + struct seq_file *m = file->private_data; + struct mdt_device *mdt = m->private; struct coordinator *cdt = &mdt->mdt_coordinator; char *start, *token, sign; char *buf; __u64 policy; __u64 add_mask, remove_mask, set_mask; - int sz; int rc; ENTRY; @@ -1846,7 +1782,8 @@ static int lprocfs_wr_hsm_policy(struct file *file, const char *buffer, RETURN(-ENOMEM); if (copy_from_user(buf, buffer, count)) - RETURN(-EFAULT); + GOTO(out, rc = -EFAULT); + buf[count] = '\0'; start = buf; @@ -1866,18 +1803,10 @@ static int lprocfs_wr_hsm_policy(struct file *file, const char *buffer, policy = hsm_policy_str2bit(token); if (policy == 0) { - char *msg; - - sz = PAGE_SIZE; - OBD_ALLOC(msg, sz); - if (!msg) - RETURN(-ENOMEM); - - hsm_policy_bit2str(0, false, msg, sz); CWARN("%s: '%s' is unknown, " - "supported policies are: %s\n", mdt_obd_name(mdt), - token, msg); - OBD_FREE(msg, sz); + "supported policies are:\n", mdt_obd_name(mdt), + token); + hsm_policy_bit2str(m, 0, false); GOTO(out, rc = -EINVAL); } switch (sign) { @@ -1916,39 +1845,39 @@ out: OBD_FREE(buf, count + 1); RETURN(rc); } +LPROC_SEQ_FOPS(mdt_hsm_policy); #define GENERATE_PROC_METHOD(VAR) \ -static int lprocfs_rd_hsm_##VAR(char *page, char **start, off_t off, \ - int count, int *eof, void *data) \ +static int mdt_hsm_##VAR##_seq_show(struct seq_file *m, void *data) \ { \ - struct mdt_device *mdt = data; \ + struct mdt_device *mdt = m->private; \ struct coordinator *cdt = &mdt->mdt_coordinator; \ - int sz; \ ENTRY; \ \ - sz = snprintf(page, count, LPU64"\n", (__u64)cdt->VAR); \ - *eof = 1; \ - RETURN(sz); \ + seq_printf(m, LPU64"\n", (__u64)cdt->VAR); \ + RETURN(0); \ } \ -static int lprocfs_wr_hsm_##VAR(struct file *file, const char *buffer, \ - unsigned long count, void *data) \ +static ssize_t \ +mdt_hsm_##VAR##_seq_write(struct file *file, const char __user *buffer, \ + size_t count, loff_t *off) \ \ { \ - struct mdt_device *mdt = data; \ + struct seq_file *m = file->private_data; \ + struct mdt_device *mdt = m->private; \ struct coordinator *cdt = &mdt->mdt_coordinator; \ - int val; \ + __s64 val; \ int rc; \ ENTRY; \ \ - rc = lprocfs_write_helper(buffer, count, &val); \ + rc = lprocfs_str_to_s64(buffer, count, &val); \ if (rc) \ RETURN(rc); \ - if (val > 0) { \ + if (val > 0 && val < INT_MAX) { \ cdt->VAR = val; \ RETURN(count); \ } \ RETURN(-EINVAL); \ -} +} \ GENERATE_PROC_METHOD(cdt_loop_period) GENERATE_PROC_METHOD(cdt_grace_delay) @@ -1965,25 +1894,39 @@ GENERATE_PROC_METHOD(cdt_default_archive_id) #define CDT_DISABLE_CMD "disabled" #define CDT_PURGE_CMD "purge" #define CDT_HELP_CMD "help" +#define CDT_MAX_CMD_LEN 10 -int lprocfs_wr_hsm_cdt_control(struct file *file, const char *buffer, - unsigned long count, void *data) +ssize_t +mdt_hsm_cdt_control_seq_write(struct file *file, const char __user *buffer, + size_t count, loff_t *off) { - struct obd_device *obd = data; + struct seq_file *m = file->private_data; + struct obd_device *obd = m->private; struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev); struct coordinator *cdt = &(mdt->mdt_coordinator); int rc, usage = 0; + char kernbuf[CDT_MAX_CMD_LEN]; ENTRY; + if (count == 0 || count >= sizeof(kernbuf)) + RETURN(-EINVAL); + + if (copy_from_user(kernbuf, buffer, count)) + RETURN(-EFAULT); + kernbuf[count] = 0; + + if (kernbuf[count - 1] == '\n') + kernbuf[count - 1] = 0; + rc = 0; - if (strncmp(buffer, CDT_ENABLE_CMD, strlen(CDT_ENABLE_CMD)) == 0) { + if (strcmp(kernbuf, CDT_ENABLE_CMD) == 0) { if (cdt->cdt_state == CDT_DISABLE) { cdt->cdt_state = CDT_RUNNING; mdt_hsm_cdt_wakeup(mdt); } else { rc = mdt_hsm_cdt_start(mdt); } - } else if (strncmp(buffer, CDT_STOP_CMD, strlen(CDT_STOP_CMD)) == 0) { + } else if (strcmp(kernbuf, CDT_STOP_CMD) == 0) { if ((cdt->cdt_state == CDT_STOPPING) || (cdt->cdt_state == CDT_STOPPED)) { CERROR("%s: Coordinator already stopped\n", @@ -1992,8 +1935,7 @@ int lprocfs_wr_hsm_cdt_control(struct file *file, const char *buffer, } else { cdt->cdt_state = CDT_STOPPING; } - } else if (strncmp(buffer, CDT_DISABLE_CMD, - strlen(CDT_DISABLE_CMD)) == 0) { + } else if (strcmp(kernbuf, CDT_DISABLE_CMD) == 0) { if ((cdt->cdt_state == CDT_STOPPING) || (cdt->cdt_state == CDT_STOPPED)) { CERROR("%s: Coordinator is stopped\n", @@ -2002,9 +1944,9 @@ int lprocfs_wr_hsm_cdt_control(struct file *file, const char *buffer, } else { cdt->cdt_state = CDT_DISABLE; } - } else if (strncmp(buffer, CDT_PURGE_CMD, strlen(CDT_PURGE_CMD)) == 0) { + } else if (strcmp(kernbuf, CDT_PURGE_CMD) == 0) { rc = hsm_cancel_all_actions(mdt); - } else if (strncmp(buffer, CDT_HELP_CMD, strlen(CDT_HELP_CMD)) == 0) { + } else if (strcmp(kernbuf, CDT_HELP_CMD) == 0) { usage = 1; } else { usage = 1; @@ -2023,83 +1965,74 @@ int lprocfs_wr_hsm_cdt_control(struct file *file, const char *buffer, RETURN(count); } -int lprocfs_rd_hsm_cdt_control(char *page, char **start, off_t off, - int count, int *eof, void *data) +int mdt_hsm_cdt_control_seq_show(struct seq_file *m, void *data) { - struct obd_device *obd = data; + struct obd_device *obd = m->private; struct coordinator *cdt; - int sz; ENTRY; cdt = &(mdt_dev(obd->obd_lu_dev)->mdt_coordinator); - *eof = 1; if (cdt->cdt_state == CDT_INIT) - sz = snprintf(page, count, "init\n"); + seq_printf(m, "init\n"); else if (cdt->cdt_state == CDT_RUNNING) - sz = snprintf(page, count, "enabled\n"); + seq_printf(m, "enabled\n"); else if (cdt->cdt_state == CDT_STOPPING) - sz = snprintf(page, count, "stopping\n"); + seq_printf(m, "stopping\n"); else if (cdt->cdt_state == CDT_STOPPED) - sz = snprintf(page, count, "stopped\n"); + seq_printf(m, "stopped\n"); else if (cdt->cdt_state == CDT_DISABLE) - sz = snprintf(page, count, "disabled\n"); + seq_printf(m, "disabled\n"); else - sz = snprintf(page, count, "unknown\n"); + seq_printf(m, "unknown\n"); - RETURN(sz); + RETURN(0); } static int -lprocfs_rd_hsm_request_mask(char *page, char **start, off_t off, - int count, int *eof, __u64 mask) +mdt_hsm_request_mask_show(struct seq_file *m, __u64 mask) { - int i, rc = 0; + bool first = true; + int i; ENTRY; for (i = 0; i < 8 * sizeof(mask); i++) { - if (mask & (1UL << i)) - rc += snprintf(page + rc, count - rc, "%s%s", - rc == 0 ? "" : " ", - hsm_copytool_action2name(i)); + if (mask & (1UL << i)) { + seq_printf(m, "%s%s", first ? "" : " ", + hsm_copytool_action2name(i)); + first = false; + } } + seq_putc(m, '\n'); - rc += snprintf(page + rc, count - rc, "\n"); - - RETURN(rc); + RETURN(0); } static int -lprocfs_rd_hsm_user_request_mask(char *page, char **start, off_t off, - int count, int *eof, void *data) +mdt_hsm_user_request_mask_seq_show(struct seq_file *m, void *data) { - struct mdt_device *mdt = data; + struct mdt_device *mdt = m->private; struct coordinator *cdt = &mdt->mdt_coordinator; - return lprocfs_rd_hsm_request_mask(page, start, off, count, eof, - cdt->cdt_user_request_mask); + return mdt_hsm_request_mask_show(m, cdt->cdt_user_request_mask); } static int -lprocfs_rd_hsm_group_request_mask(char *page, char **start, off_t off, - int count, int *eof, void *data) +mdt_hsm_group_request_mask_seq_show(struct seq_file *m, void *data) { - struct mdt_device *mdt = data; + struct mdt_device *mdt = m->private; struct coordinator *cdt = &mdt->mdt_coordinator; - return lprocfs_rd_hsm_request_mask(page, start, off, count, eof, - cdt->cdt_group_request_mask); + return mdt_hsm_request_mask_show(m, cdt->cdt_group_request_mask); } static int -lprocfs_rd_hsm_other_request_mask(char *page, char **start, off_t off, - int count, int *eof, void *data) +mdt_hsm_other_request_mask_seq_show(struct seq_file *m, void *data) { - struct mdt_device *mdt = data; + struct mdt_device *mdt = m->private; struct coordinator *cdt = &mdt->mdt_coordinator; - return lprocfs_rd_hsm_request_mask(page, start, off, count, eof, - cdt->cdt_other_request_mask); + return mdt_hsm_request_mask_show(m, cdt->cdt_other_request_mask); } static inline enum hsm_copytool_action @@ -2119,9 +2052,9 @@ hsm_copytool_name2action(const char *name) return -1; } -static int -lprocfs_wr_hsm_request_mask(struct file *file, const char __user *user_buf, - unsigned long user_count, __u64 *mask) +static ssize_t +mdt_write_hsm_request_mask(struct file *file, const char __user *user_buf, + size_t user_count, __u64 *mask) { char *buf, *pos, *name; size_t buf_size; @@ -2165,69 +2098,76 @@ out: RETURN(rc); } -static int -lprocfs_wr_hsm_user_request_mask(struct file *file, const char __user *buf, - unsigned long count, void *data) +static ssize_t +mdt_hsm_user_request_mask_seq_write(struct file *file, const char __user *buf, + size_t count, loff_t *off) { - struct mdt_device *mdt = data; + struct seq_file *m = file->private_data; + struct mdt_device *mdt = m->private; struct coordinator *cdt = &mdt->mdt_coordinator; - return lprocfs_wr_hsm_request_mask(file, buf, count, + return mdt_write_hsm_request_mask(file, buf, count, &cdt->cdt_user_request_mask); } -static int -lprocfs_wr_hsm_group_request_mask(struct file *file, const char __user *buf, - unsigned long count, void *data) +static ssize_t +mdt_hsm_group_request_mask_seq_write(struct file *file, const char __user *buf, + size_t count, loff_t *off) { - struct mdt_device *mdt = data; - struct coordinator *cdt = &mdt->mdt_coordinator; + struct seq_file *m = file->private_data; + struct mdt_device *mdt = m->private; + struct coordinator *cdt = &mdt->mdt_coordinator; - return lprocfs_wr_hsm_request_mask(file, buf, count, + return mdt_write_hsm_request_mask(file, buf, count, &cdt->cdt_group_request_mask); } -static int -lprocfs_wr_hsm_other_request_mask(struct file *file, const char __user *buf, - unsigned long count, void *data) +static ssize_t +mdt_hsm_other_request_mask_seq_write(struct file *file, const char __user *buf, + size_t count, loff_t *off) { - struct mdt_device *mdt = data; - struct coordinator *cdt = &mdt->mdt_coordinator; + struct seq_file *m = file->private_data; + struct mdt_device *mdt = m->private; + struct coordinator *cdt = &mdt->mdt_coordinator; - return lprocfs_wr_hsm_request_mask(file, buf, count, + return mdt_write_hsm_request_mask(file, buf, count, &cdt->cdt_other_request_mask); } +LPROC_SEQ_FOPS(mdt_hsm_cdt_loop_period); +LPROC_SEQ_FOPS(mdt_hsm_cdt_grace_delay); +LPROC_SEQ_FOPS(mdt_hsm_cdt_active_req_timeout); +LPROC_SEQ_FOPS(mdt_hsm_cdt_max_requests); +LPROC_SEQ_FOPS(mdt_hsm_cdt_default_archive_id); +LPROC_SEQ_FOPS(mdt_hsm_user_request_mask); +LPROC_SEQ_FOPS(mdt_hsm_group_request_mask); +LPROC_SEQ_FOPS(mdt_hsm_other_request_mask); + static struct lprocfs_vars lprocfs_mdt_hsm_vars[] = { - { "agents", NULL, NULL, NULL, &mdt_hsm_agent_fops, - 0 }, - { "actions", NULL, NULL, NULL, &mdt_hsm_actions_fops, - 0444 }, - { "default_archive_id", lprocfs_rd_hsm_cdt_default_archive_id, - lprocfs_wr_hsm_cdt_default_archive_id, - NULL, NULL, 0 }, - { "grace_delay", lprocfs_rd_hsm_cdt_grace_delay, - lprocfs_wr_hsm_cdt_grace_delay, - NULL, NULL, 0 }, - { "loop_period", lprocfs_rd_hsm_cdt_loop_period, - lprocfs_wr_hsm_cdt_loop_period, - NULL, NULL, 0 }, - { "max_requests", lprocfs_rd_hsm_cdt_max_requests, - lprocfs_wr_hsm_cdt_max_requests, - NULL, NULL, 0 }, - { "policy", lprocfs_rd_hsm_policy, - lprocfs_wr_hsm_policy, - NULL, NULL, 0 }, - { "active_request_timeout", lprocfs_rd_hsm_cdt_active_req_timeout, - lprocfs_wr_hsm_cdt_active_req_timeout, - NULL, NULL, 0 }, - { "active_requests", NULL, NULL, NULL, - &mdt_hsm_active_requests_fops, 0 }, - { "user_request_mask", lprocfs_rd_hsm_user_request_mask, - lprocfs_wr_hsm_user_request_mask, }, - { "group_request_mask", lprocfs_rd_hsm_group_request_mask, - lprocfs_wr_hsm_group_request_mask, }, - { "other_request_mask", lprocfs_rd_hsm_other_request_mask, - lprocfs_wr_hsm_other_request_mask, }, + { .name = "agents", + .fops = &mdt_hsm_agent_fops }, + { .name = "actions", + .fops = &mdt_hsm_actions_fops, + .proc_mode = 0444 }, + { .name = "default_archive_id", + .fops = &mdt_hsm_cdt_default_archive_id_fops }, + { .name = "grace_delay", + .fops = &mdt_hsm_cdt_grace_delay_fops }, + { .name = "loop_period", + .fops = &mdt_hsm_cdt_loop_period_fops }, + { .name = "max_requests", + .fops = &mdt_hsm_cdt_max_requests_fops }, + { .name = "policy", + .fops = &mdt_hsm_policy_fops }, + { .name = "active_request_timeout", + .fops = &mdt_hsm_cdt_active_req_timeout_fops }, + { .name = "active_requests", + .fops = &mdt_hsm_active_requests_fops }, + { .name = "user_request_mask", + .fops = &mdt_hsm_user_request_mask_fops, }, + { .name = "group_request_mask", + .fops = &mdt_hsm_group_request_mask_fops, }, + { .name = "other_request_mask", + .fops = &mdt_hsm_other_request_mask_fops, }, { 0 } };