* error may happen if coordinator crashes or stopped
* with running request
*/
- car = mdt_cdt_find_request(cdt, larr->arr_hai.hai_cookie, NULL);
+ car = mdt_cdt_find_request(cdt, larr->arr_hai.hai_cookie);
if (car == NULL) {
- last = larr->arr_req_create;
+ last = larr->arr_req_change;
} else {
last = car->car_req_update;
mdt_cdt_put_request(car);
*/
hsd.max_requests = cdt->cdt_max_requests;
request_sz = hsd.max_requests * sizeof(*hsd.request);
- OBD_ALLOC(hsd.request, request_sz);
+ OBD_ALLOC_LARGE(hsd.request, request_sz);
if (!hsd.request)
GOTO(out, rc = -ENOMEM);
/* cdt_max_requests has changed,
* we need to allocate a new buffer
*/
- OBD_FREE(hsd.request, request_sz);
+ OBD_FREE_LARGE(hsd.request, request_sz);
hsd.max_requests = cdt->cdt_max_requests;
request_sz = hsd.max_requests * sizeof(*hsd.request);
- OBD_ALLOC(hsd.request, request_sz);
+ OBD_ALLOC_LARGE(hsd.request, request_sz);
if (!hsd.request) {
rc = -ENOMEM;
break;
EXIT;
out:
if (hsd.request)
- OBD_FREE(hsd.request, request_sz);
+ OBD_FREE_LARGE(hsd.request, request_sz);
if (cdt->cdt_state == CDT_STOPPING) {
/* request comes from /proc path, so we need to clean cdt
init_rwsem(&cdt->cdt_request_lock);
mutex_init(&cdt->cdt_restore_lock);
- INIT_LIST_HEAD(&cdt->cdt_requests);
+ INIT_LIST_HEAD(&cdt->cdt_request_list);
INIT_LIST_HEAD(&cdt->cdt_agents);
INIT_LIST_HEAD(&cdt->cdt_restore_hdl);
+ cdt->cdt_request_cookie_hash = cfs_hash_create("REQUEST_COOKIE_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_request_cookie_hash_ops,
+ CFS_HASH_DEFAULT);
+ if (cdt->cdt_request_cookie_hash == NULL)
+ RETURN(-ENOMEM);
+
rc = lu_env_init(&cdt->cdt_env, LCT_MD_THREAD);
if (rc < 0)
- RETURN(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);
- if (rc == 0) {
- lu_context_enter(&cdt->cdt_session);
- cdt->cdt_env.le_ses = &cdt->cdt_session;
- } else {
- lu_env_fini(&cdt->cdt_env);
- RETURN(rc);
- }
+ if (rc < 0)
+ GOTO(out_env, rc);
+
+ lu_context_enter(&cdt->cdt_session);
+ cdt->cdt_env.le_ses = &cdt->cdt_session;
cdt_mti = lu_context_key_get(&cdt->cdt_env.le_ctx, &mdt_thread_key);
LASSERT(cdt_mti != NULL);
cdt->cdt_active_req_timeout = 3600;
RETURN(0);
+
+out_env:
+ lu_env_fini(&cdt->cdt_env);
+out_request_cookie_hash:
+ cfs_hash_putref(cdt->cdt_request_cookie_hash);
+ cdt->cdt_request_cookie_hash = NULL;
+
+ return rc;
}
/**
lu_env_fini(&cdt->cdt_env);
+ cfs_hash_putref(cdt->cdt_request_cookie_hash);
+ cdt->cdt_request_cookie_hash = NULL;
+
RETURN(0);
}
struct mdt_thread_info *cdt_mti;
ENTRY;
- if (mdt->mdt_opts.mo_coordinator == 0)
- RETURN(0);
-
if (cdt->cdt_state == CDT_STOPPED) {
CERROR("%s: Coordinator already stopped\n",
mdt_obd_name(mdt));
/* start cleaning */
down_write(&cdt->cdt_request_lock);
- list_for_each_entry_safe(car, tmp1, &cdt->cdt_requests,
+ 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_cookie_hash);
list_del(&car->car_request_list);
- mdt_cdt_free_request(car);
+ mdt_cdt_put_request(car);
}
up_write(&cdt->cdt_request_lock);
RETURN(0);
}
+static int mdt_hsm_set_exists(struct mdt_thread_info *mti,
+ const struct lu_fid *fid,
+ u32 archive_id)
+{
+ struct mdt_object *obj;
+ struct md_hsm mh;
+ int rc;
+
+ obj = mdt_hsm_get_md_hsm(mti, fid, &mh);
+ if (IS_ERR(obj))
+ GOTO(out, rc = PTR_ERR(obj));
+
+ if (mh.mh_flags & HS_EXISTS &&
+ mh.mh_arch_id == archive_id)
+ GOTO(out_obj, rc = 0);
+
+ mh.mh_flags |= HS_EXISTS;
+ mh.mh_arch_id = archive_id;
+ rc = mdt_hsm_attr_set(mti, obj, &mh);
+
+out_obj:
+ mdt_object_put(mti->mti_env, obj);
+out:
+ return rc;
+}
+
/**
* register all requests from an hal in the memory list
* \param mti [IN] context
}
/* find the running request to set it canceled */
- car = mdt_cdt_find_request(cdt, hai->hai_cookie, NULL);
+ 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
}
if (hai->hai_action == HSMA_ARCHIVE) {
- struct mdt_object *obj;
- struct md_hsm hsm;
-
- obj = mdt_hsm_get_md_hsm(mti, &hai->hai_fid, &hsm);
- if (IS_ERR(obj) && (PTR_ERR(obj) == -ENOENT))
+ rc = mdt_hsm_set_exists(mti, &hai->hai_fid,
+ hal->hal_archive_id);
+ if (rc == -ENOENT)
continue;
- if (IS_ERR(obj))
- GOTO(out, rc = PTR_ERR(obj));
-
- hsm.mh_flags |= HS_EXISTS;
- hsm.mh_arch_id = hal->hal_archive_id;
- rc = mdt_hsm_attr_set(mti, obj, &hsm);
- mdt_object_put(mti->mti_env, obj);
- if (rc)
+ else if (rc < 0)
GOTO(out, rc);
}
/* restore in data FID done, we swap the layouts
* only if restore is successful */
- if (pgs->hpk_errval == 0 && !IS_ERR_OR_NULL(obj)) {
+ if (pgs->hpk_errval == 0 && !IS_ERR(obj)) {
rc = hsm_swap_layouts(mti, obj, &car->car_hai->hai_dfid,
&mh);
if (rc) {
rc = hsm_cdt_request_completed(mti, pgs, car, &status);
- /* remove request from memory list */
- mdt_cdt_remove_request(cdt, pgs->hpk_cookie);
-
- CDEBUG(D_HSM, "Updating record: fid="DFID" cookie=%#llx"
- " action=%s status=%s\n", PFID(&pgs->hpk_fid),
- pgs->hpk_cookie,
+ CDEBUG(D_HSM, "%s record: fid="DFID" cookie=%#llx action=%s "
+ "status=%s\n",
+ update_record ? "Updating" : "Not updating",
+ PFID(&pgs->hpk_fid), pgs->hpk_cookie,
hsm_copytool_action2name(car->car_hai->hai_action),
agent_req_status2name(status));
+ /* update record first (LU-9075) */
if (update_record) {
int rc1;
pgs->hpk_cookie);
rc = (rc != 0 ? rc : rc1);
}
+
+ /* then remove request from memory list (LU-9075) */
+ mdt_cdt_remove_request(cdt, pgs->hpk_cookie);
+
/* ct has completed a request, so a slot is available, wakeup
* cdt to find new work */
mdt_hsm_cdt_wakeup(mdt);
/* send cancel to all running requests */
down_read(&cdt->cdt_request_lock);
- list_for_each_entry(car, &cdt->cdt_requests, car_request_list) {
+ list_for_each_entry(car, &cdt->cdt_request_list, car_request_list) {
mdt_cdt_get_request(car);
/* request is not yet removed from list, it will be done
* when copytool will return progress
/**
* check if a request is compatible with file status
* \param hai [IN] request description
- * \param hal_an [IN] request archive number (not used)
+ * \param archive_id [IN] request archive id
* \param rq_flags [IN] request flags
* \param hsm [IN] file HSM metadata
* \retval boolean
*/
bool mdt_hsm_is_action_compat(const struct hsm_action_item *hai,
- const int hal_an, const __u64 rq_flags,
+ u32 archive_id, u64 rq_flags,
const struct md_hsm *hsm)
{
int is_compat = false;
if (!(hsm_flags & HS_NOARCHIVE) &&
(hsm_flags & HS_DIRTY || !(hsm_flags & HS_ARCHIVED)))
is_compat = true;
+
+ if (hsm_flags & HS_EXISTS &&
+ archive_id != 0 &&
+ archive_id != hsm->mh_arch_id)
+ is_compat = false;
+
break;
case HSMA_RESTORE:
if (!(hsm_flags & HS_DIRTY) && (hsm_flags & HS_RELEASED) &&
}
/* remove last ' ' */
m->count--;
- seq_putc(m, '\0');
+ seq_putc(m, '\n');
}
/* methods to read/write HSM policy flags */
rc = -EALREADY;
} else {
cdt->cdt_state = CDT_STOPPING;
+ mdt_hsm_cdt_wakeup(mdt);
}
} else if (strcmp(kernbuf, CDT_DISABLE_CMD) == 0) {
if ((cdt->cdt_state == CDT_STOPPING) ||