* Copyright (c) 2011, 2012 Commissariat a l'energie atomique et aux energies
* alternatives
*
- * Copyright (c) 2013, 2014, Intel Corporation.
+ * Copyright (c) 2013, 2016, Intel Corporation.
* Use is subject to license terms.
*/
/*
int request_sz;
ENTRY;
- cdt->cdt_thread.t_flags = SVC_RUNNING;
- wake_up(&cdt->cdt_thread.t_ctl_waitq);
+ cdt->cdt_flags = SVC_RUNNING;
+ wake_up(&cdt->cdt_waitq);
CDEBUG(D_HSM, "%s: coordinator thread starting, pid=%d\n",
mdt_obd_name(mdt), current_pid());
lwi = LWI_TIMEOUT(cfs_time_seconds(cdt->cdt_loop_period),
NULL, NULL);
- l_wait_event(cdt->cdt_thread.t_ctl_waitq,
- (cdt->cdt_thread.t_flags &
- (SVC_STOPPING|SVC_EVENT)),
+ l_wait_event(cdt->cdt_waitq,
+ cdt->cdt_flags & (SVC_STOPPING|SVC_EVENT),
&lwi);
CDEBUG(D_HSM, "coordinator resumes\n");
- if (cdt->cdt_thread.t_flags & SVC_STOPPING ||
+ if (cdt->cdt_flags & SVC_STOPPING ||
cdt->cdt_state == CDT_STOPPING) {
- cdt->cdt_thread.t_flags &= ~SVC_STOPPING;
+ cdt->cdt_flags &= ~SVC_STOPPING;
rc = 0;
break;
}
/* wake up before timeout, new work arrives */
- if (cdt->cdt_thread.t_flags & SVC_EVENT)
- cdt->cdt_thread.t_flags &= ~SVC_EVENT;
+ if (cdt->cdt_flags & SVC_EVENT)
+ cdt->cdt_flags &= ~SVC_EVENT;
/* if coordinator is suspended continue to wait */
if (cdt->cdt_state == CDT_DISABLE) {
* by mdt_stop_coordinator(), we have to ack
* and cdt cleaning will be done by event sender
*/
- cdt->cdt_thread.t_flags = SVC_STOPPED;
- wake_up(&cdt->cdt_thread.t_ctl_waitq);
+ cdt->cdt_flags = SVC_STOPPED;
+ wake_up(&cdt->cdt_waitq);
}
if (rc != 0)
RETURN(-ESRCH);
/* wake up coordinator */
- cdt->cdt_thread.t_flags = SVC_EVENT;
- wake_up(&cdt->cdt_thread.t_ctl_waitq);
+ cdt->cdt_flags = SVC_EVENT;
+ wake_up(&cdt->cdt_waitq);
RETURN(0);
}
cdt->cdt_state = CDT_STOPPED;
- init_waitqueue_head(&cdt->cdt_thread.t_ctl_waitq);
+ init_waitqueue_head(&cdt->cdt_waitq);
mutex_init(&cdt->cdt_llog_lock);
init_rwsem(&cdt->cdt_agent_lock);
init_rwsem(&cdt->cdt_request_lock);
* \retval 0 success
* \retval -ve failure
*/
-int mdt_hsm_cdt_start(struct mdt_device *mdt)
+static int mdt_hsm_cdt_start(struct mdt_device *mdt)
{
struct coordinator *cdt = &mdt->mdt_coordinator;
int rc;
" for registered restore: %d\n",
mdt_obd_name(mdt), rc);
+ if (mdt->mdt_bottom->dd_rdonly)
+ RETURN(0);
+
task = kthread_run(mdt_coordinator, cdt_mti, "hsm_cdtr");
if (IS_ERR(task)) {
rc = PTR_ERR(task);
rc = 0;
}
- wait_event(cdt->cdt_thread.t_ctl_waitq,
- (cdt->cdt_thread.t_flags & SVC_RUNNING));
+ wait_event(cdt->cdt_waitq,
+ (cdt->cdt_flags & SVC_RUNNING));
cdt->cdt_state = CDT_RUNNING;
mdt->mdt_opts.mo_coordinator = 1;
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));
if (cdt->cdt_state != CDT_STOPPING) {
/* stop coordinator thread before cleaning */
- cdt->cdt_thread.t_flags = SVC_STOPPING;
- wake_up(&cdt->cdt_thread.t_ctl_waitq);
- wait_event(cdt->cdt_thread.t_ctl_waitq,
- cdt->cdt_thread.t_flags & SVC_STOPPED);
+ cdt->cdt_flags = SVC_STOPPING;
+ wake_up(&cdt->cdt_waitq);
+ wait_event(cdt->cdt_waitq,
+ cdt->cdt_flags & SVC_STOPPED);
}
cdt->cdt_state = CDT_STOPPED;
/**
* swap layouts between 2 fids
* \param mti [IN] context
- * \param fid1 [IN]
- * \param fid2 [IN]
+ * \param obj [IN]
+ * \param dfid [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,
+ struct mdt_object *obj, const struct lu_fid *dfid,
struct md_hsm *mh_common)
{
- struct mdt_device *mdt = mti->mti_mdt;
- struct mdt_object *child1, *child2;
- struct mdt_lock_handle *lh2;
+ struct mdt_object *dobj;
+ struct mdt_lock_handle *dlh;
int rc;
ENTRY;
- child1 = mdt_object_find(mti->mti_env, mdt, fid);
- if (IS_ERR(child1))
- GOTO(out, rc = PTR_ERR(child1));
+ if (!mdt_object_exists(obj))
+ GOTO(out, rc = -ENOENT);
- /* we already have layout lock on FID so take only
+ /* we already have layout lock on obj so take only
* on dfid */
- lh2 = &mti->mti_lh[MDT_LH_OLD];
- mdt_lock_reg_init(lh2, LCK_EX);
- child2 = mdt_object_find_lock(mti, dfid, lh2, MDS_INODELOCK_LAYOUT);
- if (IS_ERR(child2))
- GOTO(out_child1, rc = PTR_ERR(child2));
+ dlh = &mti->mti_lh[MDT_LH_OLD];
+ mdt_lock_reg_init(dlh, LCK_EX);
+ dobj = mdt_object_find_lock(mti, dfid, dlh, MDS_INODELOCK_LAYOUT);
+ if (IS_ERR(dobj))
+ GOTO(out, rc = PTR_ERR(dobj));
/* 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)) {
+ if (!mdt_object_exists(dobj)) {
CERROR("%s: Copytool has closed volatile file "DFID"\n",
mdt_obd_name(mti->mti_mdt), PFID(dfid));
- GOTO(out_child2, rc = -ENOENT);
+ GOTO(out_dobj, rc = -ENOENT);
}
/* Since we only handle restores here, unconditionally use
* SWAP_LAYOUTS_MDS_HSM flag to ensure original layout will
* only need to clear RELEASED and DIRTY.
*/
mh_common->mh_flags &= ~(HS_RELEASED | HS_DIRTY);
- rc = mdt_hsm_attr_set(mti, child2, mh_common);
+ rc = mdt_hsm_attr_set(mti, dobj, mh_common);
if (rc == 0)
rc = mo_swap_layouts(mti->mti_env,
- mdt_object_child(child1),
- mdt_object_child(child2),
+ mdt_object_child(obj),
+ mdt_object_child(dobj),
SWAP_LAYOUTS_MDS_HSM);
-out_child2:
- mdt_object_unlock_put(mti, child2, lh2, 1);
-out_child1:
- mdt_object_put(mti->mti_env, child1);
+out_dobj:
+ mdt_object_unlock_put(mti, dobj, dlh, 1);
out:
RETURN(rc);
}
int cl_flags = 0, rc = 0;
struct md_hsm mh;
bool is_mh_changed;
+ bool need_changelog = true;
ENTRY;
/* default is to retry */
*status = ARS_WAITING;
- /* find object by FID */
+ /* 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);
/* we will update MD HSM only if needed */
is_mh_changed = false;
- if (IS_ERR(obj)) {
- /* object removed */
- *status = ARS_SUCCEED;
- goto unlock;
- }
/* no need to change mh->mh_arch_id
* mdt_hsm_get_md_hsm() got it from disk and it is still valid
*status = ARS_SUCCEED;
break;
default:
+ /* retry only if current policy or requested, and
+ * object is not on error/removed */
*status = (cdt->cdt_policy & CDT_NORETRY_ACTION ||
- !(pgs->hpk_flags & HP_FLAG_RETRY) ?
- ARS_FAILED : ARS_WAITING);
+ !(pgs->hpk_flags & HP_FLAG_RETRY) ||
+ IS_ERR(obj)) ? ARS_FAILED : ARS_WAITING;
break;
}
mh.mh_flags & HS_DIRTY ? CLF_HSM_DIRTY : 0);
/* unlock is done later, after layout lock management */
- if (is_mh_changed)
+ if (is_mh_changed && !IS_ERR(obj))
rc = mdt_hsm_attr_set(mti, obj, &mh);
-unlock:
/* we give back layout lock only if restore was successful or
- * if restore was canceled or if policy is to not retry
+ * 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 &&
- (pgs->hpk_errval == 0 || pgs->hpk_errval == ECANCELED ||
- cdt->cdt_policy & CDT_NORETRY_ACTION)) {
+ if (car->car_hai->hai_action == HSMA_RESTORE) {
struct cdt_restore_handle *crh;
/* restore in data FID done, we swap the layouts
* 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, &mh);
+ if (pgs->hpk_errval == 0 && !IS_ERR_OR_NULL(obj)) {
+ rc = hsm_swap_layouts(mti, obj, &car->car_hai->hai_dfid,
+ &mh);
if (rc) {
if (cdt->cdt_policy & CDT_NORETRY_ACTION)
*status = ARS_FAILED;
if (*status == ARS_WAITING)
GOTO(out, rc);
+ /* restore special case, need to create ChangeLog record
+ * before to give back layout lock to avoid concurrent
+ * file updater to post out of order ChangeLog */
+ mo_changelog(env, CL_HSM, cl_flags, mdt->mdt_child,
+ &car->car_hai->hai_fid);
+ need_changelog = false;
+
/* give back layout lock */
mutex_lock(&cdt->cdt_restore_lock);
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);
- /* just give back layout lock, we keep
- * the reference which is given back
- * later with the lock for HSM flags */
- if (!IS_ERR(obj) && crh != NULL)
- mdt_object_unlock(mti, obj, &crh->crh_lh, 1);
+ /* Just give back layout lock, we keep the reference
+ * which is given back later with the lock for HSM
+ * flags.
+ * XXX obj may be invalid so we do not pass it. */
+ if (crh != NULL)
+ mdt_object_unlock(mti, NULL, &crh->crh_lh, 1);
if (crh != NULL)
OBD_SLAB_FREE_PTR(crh, mdt_hsm_cdt_kmem);
GOTO(out, rc);
out:
- if (obj != NULL && !IS_ERR(obj)) {
- mo_changelog(env, CL_HSM, cl_flags,
- mdt_object_child(obj));
+ /* always add a ChangeLog record */
+ if (need_changelog)
+ mo_changelog(env, CL_HSM, cl_flags, mdt->mdt_child,
+ &car->car_hai->hai_fid);
+
+ if (!IS_ERR(obj))
mdt_object_put(mti->mti_env, obj);
- }
RETURN(rc);
}
*/
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;
enum cdt_states save_state;
ENTRY;
- /* retrieve coordinator context */
- mti = lu_context_key_get(&cdt->cdt_env.le_ctx, &mdt_thread_key);
+ rc = lu_env_init(&env, LCT_MD_THREAD);
+ if (rc < 0)
+ RETURN(rc);
+
+ /* for mdt_ucred(), lu_ucred stored in lu_ucred_key */
+ rc = lu_context_init(&session, LCT_SERVER_SESSION);
+ if (rc < 0)
+ GOTO(out_env, rc);
+
+ lu_context_enter(&session);
+ env.le_ses = &session;
+
+ mti = lu_context_key_get(&env.le_ctx, &mdt_thread_key);
+ LASSERT(mti != NULL);
+
+ mti->mti_env = &env;
+ mti->mti_mdt = mdt;
+
+ hsm_init_ucred(mdt_ucred(mti));
/* disable coordinator */
save_state = cdt->cdt_state;
if (hal == NULL) {
mdt_cdt_put_request(car);
up_read(&cdt->cdt_request_lock);
- GOTO(out, rc = -ENOMEM);
+ GOTO(out_cdt_state, rc = -ENOMEM);
}
}
rc = cdt_llog_process(mti->mti_env, mti->mti_mdt,
mdt_cancel_all_cb, &hcad);
-out:
+out_cdt_state:
/* enable coordinator */
cdt->cdt_state = save_state;
+ lu_context_exit(&session);
+ lu_context_fini(&session);
+out_env:
+ lu_env_fini(&env);
RETURN(rc);
}
}
/* remove last ' ' */
m->count--;
- seq_putc(m, '\0');
+ seq_putc(m, '\n');
}
/* methods to read/write HSM policy flags */