Discard DOM data when all object are put and unlocked.
So current thread will wait for discard but resources are
not blocked by it. Also cancel discard lock immediately.
Patch also add missing part for lock prolongation for DoM
locks and fix for tgt_blocking_ast() to don't miss a call to
ldlm_server_blocking_ast() in case of lu_env_init() failure.
Signed-off-by: Mikhail Pershin <mpershin@whamcloud.com>
Change-Id: I09aaa08e28d2a280ca1f9939315311c45d0334b5
Reviewed-on: https://review.whamcloud.com/33026
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
bool increase_only);
int mdt_dom_lvb_alloc(struct ldlm_resource *res);
-static inline void mdt_dom_check_and_discard(struct mdt_thread_info *mti,
+static inline bool mdt_dom_check_for_discard(struct mdt_thread_info *mti,
struct mdt_object *mo)
{
- if (lu_object_is_dying(&mo->mot_header) &&
- S_ISREG(lu_object_attr(&mo->mot_obj)))
- mdt_dom_discard_data(mti, mdt_object_fid(mo));
+ return lu_object_is_dying(&mo->mot_header) &&
+ S_ISREG(lu_object_attr(&mo->mot_obj));
}
int mdt_dom_object_size(const struct lu_env *env, struct mdt_device *mdt,
req_timeout);
}
+static void mdt_dom_resource_prolong(struct ldlm_prolong_args *arg)
+{
+ struct ldlm_resource *res;
+ struct ldlm_lock *lock;
+
+ ENTRY;
+
+ res = ldlm_resource_get(arg->lpa_export->exp_obd->obd_namespace, NULL,
+ &arg->lpa_resid, LDLM_EXTENT, 0);
+ if (IS_ERR(res)) {
+ CDEBUG(D_DLMTRACE,
+ "Failed to get resource for resid %llu/%llu\n",
+ arg->lpa_resid.name[0], arg->lpa_resid.name[1]);
+ RETURN_EXIT;
+ }
+
+ lock_res(res);
+ list_for_each_entry(lock, &res->lr_granted, l_res_link) {
+ if (ldlm_has_dom(lock)) {
+ LDLM_DEBUG(lock, "DOM lock to prolong ");
+ ldlm_lock_prolong_one(lock, arg);
+ break;
+ }
+ }
+ unlock_res(res);
+ ldlm_resource_putref(res);
+
+ EXIT;
+}
+
static void mdt_prolong_dom_lock(struct tgt_session_info *tsi,
struct ldlm_prolong_args *data)
{
ldlm_lock_prolong_one(lock, data);
lock->l_last_used = ktime_get();
LDLM_LOCK_PUT(lock);
- RETURN_EXIT;
+ if (data->lpa_locks_cnt > 0)
+ RETURN_EXIT;
}
}
+ mdt_dom_resource_prolong(data);
EXIT;
}
/* We only care about the side-effects, just drop the lock. */
if (rc == ELDLM_OK)
- ldlm_lock_decref(&dom_lh, LCK_PW);
+ ldlm_lock_decref_and_cancel(&dom_lh, LCK_PW);
}
/* check if client has already DoM lock for given resource */
struct mdt_object *o = mfd->mfd_object;
struct md_object *next = mdt_object_child(o);
struct md_attr *ma = &info->mti_attr;
+ struct lu_fid *ofid = &info->mti_tmp_fid1;
int rc = 0;
__u64 mode;
__u64 intent;
+ bool discard = false;
ENTRY;
mode = mfd->mfd_mode;
intent = ma->ma_attr_flags & MDS_CLOSE_INTENT;
+ *ofid = *mdt_object_fid(o);
CDEBUG(D_INODE, "%s: close file "DFID" with intent: %llx\n",
- mdt_obd_name(info->mti_mdt), PFID(mdt_object_fid(o)), intent);
+ mdt_obd_name(info->mti_mdt), PFID(ofid), intent);
switch (intent) {
case MDS_HSM_RELEASE: {
if (rc < 0) {
CDEBUG(D_HSM, "%s: File " DFID " release failed: %d\n",
mdt_obd_name(info->mti_mdt),
- PFID(mdt_object_fid(o)), rc);
+ PFID(ofid), rc);
/* continue to close even error occurred. */
}
break;
CDEBUG(D_INODE,
"%s: cannot swap layout of "DFID": rc = %d\n",
mdt_obd_name(info->mti_mdt),
- PFID(mdt_object_fid(o)), rc);
+ PFID(ofid), rc);
/* continue to close even if error occurred. */
}
break;
CDEBUG(D_INODE,
"%s: File " DFID " LSOM failed: rc = %d\n",
mdt_obd_name(info->mti_mdt),
- PFID(mdt_object_fid(o)), rc2);
+ PFID(ofid), rc2);
/* continue to close even if error occured. */
}
if (!MFD_CLOSED(mode)) {
rc = mo_close(info->mti_env, next, ma, mode);
- mdt_dom_check_and_discard(info, o);
+ discard = mdt_dom_check_for_discard(info, o);
}
/* adjust open and lease count */
mdt_mfd_free(mfd);
mdt_object_put(info->mti_env, o);
+ if (discard)
+ mdt_dom_discard_data(info, ofid);
+
RETURN(rc);
}
if (rc)
GOTO(out_stat, rc);
} else {
- discard = true;
+ discard = mdt_dom_check_for_discard(info, mc);
}
mdt_handle_last_unlink(info, mc, ma);
unlock_child:
mdt_reint_striped_unlock(info, mc, child_lh, einfo, rc);
put_child:
- if (discard)
- mdt_dom_check_and_discard(info, mc);
mdt_object_put(info->mti_env, mc);
unlock_parent:
mdt_object_unlock(info, mp, parent_lh, rc);
put_parent:
mdt_object_put(info->mti_env, mp);
+
+ /* discard is just a PW DOM lock to drop the data on a client
+ * no need to keep objects being get and locked, do that after all.
+ */
+ if (discard)
+ mdt_dom_discard_data(info, child_fid);
+
return rc;
}
mdt_counter_incr(req, LPROC_MDT_RENAME);
if (mnew) {
mdt_handle_last_unlink(info, mnew, ma);
- discard = true;
+ discard = mdt_dom_check_for_discard(info, mnew);
}
mdt_rename_counter_tally(info, info->mti_mdt, req,
out_unlock_old:
mdt_object_unlock(info, mold, lh_oldp, rc);
out_put_new:
- if (mnew != NULL) {
- if (discard)
- mdt_dom_check_and_discard(info, mnew);
+ if (mnew != NULL)
mdt_object_put(info->mti_env, mnew);
- }
out_put_old:
mdt_object_put(info->mti_env, mold);
out_unlock_parents:
mdt_object_put(info->mti_env, mtgtdir);
out_put_srcdir:
mdt_object_put(info->mti_env, msrcdir);
+
+ /* If 'discard' is set then new_fid must exits.
+ * DOM data discard need neither object nor lock,
+ * so do this at the end.
+ */
+ if (discard)
+ mdt_dom_discard_data(info, new_fid);
+
return rc;
}
rc = lu_env_init(&env, LCT_DT_THREAD);
if (unlikely(rc != 0))
- RETURN(rc);
+ GOTO(err, rc);
ost_fid_from_resid(&fid, &lock->l_resource->lr_name,
tgt->lut_lsd.lsd_osd_index);
err_env:
lu_env_fini(&env);
}
-
+err:
rc = ldlm_server_blocking_ast(lock, desc, data, flag);
RETURN(rc);
}
#!/bin/bash
trap 'kill $(jobs -p)' EXIT
RACER_ENABLE_PFL=${RACER_ENABLE_PFL:-true}
-RACER_ENABLE_DOM=${RACER_ENABLE_DOM:-false}
+RACER_ENABLE_DOM=${RACER_ENABLE_DOM:-true}
RACER_ENABLE_FLR=${RACER_ENABLE_FLR:-true}
DIR=$1
MAX=$2