@@ -821,6 +821,12 @@ struct ldlm_lock {
#endif
};
+enum ldlm_match_flags {
+ LDLM_MATCH_UNREF = BIT(0),
+ LDLM_MATCH_AST = BIT(1),
+ LDLM_MATCH_AST_ANY = BIT(2),
+};
+
/**
* Describe the overlap between two locks. itree_overlap_cb data.
*/
@@ -831,8 +837,7 @@ struct ldlm_match_data {
union ldlm_policy_data *lmd_policy;
u64 lmd_flags;
u64 lmd_skip_flags;
- int lmd_unref;
- bool lmd_has_ast_data;
+ enum ldlm_match_flags lmd_match;
};
/**
@@ -1172,6 +1177,7 @@ void ldlm_lock_decref_and_cancel(const struct lustre_handle *lockh,
void ldlm_lock_fail_match_locked(struct ldlm_lock *lock);
void ldlm_lock_allow_match(struct ldlm_lock *lock);
void ldlm_lock_allow_match_locked(struct ldlm_lock *lock);
+
enum ldlm_mode ldlm_lock_match_with_skip(struct ldlm_namespace *ns,
u64 flags, u64 skip_flags,
const struct ldlm_res_id *res_id,
@@ -1179,18 +1185,17 @@ enum ldlm_mode ldlm_lock_match_with_skip(struct ldlm_namespace *ns,
union ldlm_policy_data *policy,
enum ldlm_mode mode,
struct lustre_handle *lh,
- int unref);
+ enum ldlm_match_flags match_flags);
static inline enum ldlm_mode ldlm_lock_match(struct ldlm_namespace *ns,
u64 flags,
const struct ldlm_res_id *res_id,
enum ldlm_type type,
union ldlm_policy_data *policy,
enum ldlm_mode mode,
- struct lustre_handle *lh,
- int unref)
+ struct lustre_handle *lh)
{
return ldlm_lock_match_with_skip(ns, flags, 0, res_id, type, policy,
- mode, lh, unref);
+ mode, lh, 0);
}
struct ldlm_lock *search_itree(struct ldlm_resource *res,
struct ldlm_match_data *data);
@@ -244,6 +244,10 @@ enum osc_dap_flags {
* Return the lock even if it is being canceled.
*/
OSC_DAP_FL_CANCELING = BIT(1),
+ /**
+ * check ast data is present, requested to cancel cb
+ */
+ OSC_DAP_FL_AST = BIT(2),
};
/*
@@ -1074,7 +1074,7 @@ static bool lock_matches(struct ldlm_lock *lock, void *vdata)
!(data->lmd_flags & LDLM_FL_CBPENDING))
return false;
- if (!data->lmd_unref && ldlm_is_cbpending(lock) &&
+ if (!(data->lmd_match & LDLM_MATCH_UNREF) && ldlm_is_cbpending(lock) &&
!lock->l_readers && !lock->l_writers)
return false;
@@ -1084,11 +1084,12 @@ static bool lock_matches(struct ldlm_lock *lock, void *vdata)
/* When we search for ast_data, we are not doing a traditional match,
* so we don't worry about IBITS or extent matching.
*/
- if (data->lmd_has_ast_data) {
+ if (data->lmd_match & (LDLM_MATCH_AST | LDLM_MATCH_AST_ANY)) {
if (!lock->l_ast_data)
return false;
- goto matched;
+ if (data->lmd_match & LDLM_MATCH_AST_ANY)
+ goto matched;
}
match = lock->l_req_mode;
@@ -1121,7 +1122,7 @@ static bool lock_matches(struct ldlm_lock *lock, void *vdata)
* We match if we have existing lock with same or wider set
* of bits.
*/
- if (!data->lmd_unref && LDLM_HAVE_MASK(lock, GONE))
+ if (!(data->lmd_match & LDLM_MATCH_UNREF) && LDLM_HAVE_MASK(lock, GONE))
return false;
if (!equi(data->lmd_flags & LDLM_FL_LOCAL_ONLY, ldlm_is_local(lock)))
@@ -1273,7 +1274,8 @@ enum ldlm_mode ldlm_lock_match_with_skip(struct ldlm_namespace *ns,
enum ldlm_type type,
union ldlm_policy_data *policy,
enum ldlm_mode mode,
- struct lustre_handle *lockh, int unref)
+ struct lustre_handle *lockh,
+ enum ldlm_match_flags match_flags)
{
struct ldlm_match_data data = {
.lmd_old = NULL,
@@ -1282,8 +1284,7 @@ enum ldlm_mode ldlm_lock_match_with_skip(struct ldlm_namespace *ns,
.lmd_policy = policy,
.lmd_flags = flags,
.lmd_skip_flags = skip_flags,
- .lmd_unref = unref,
- .lmd_has_ast_data = false,
+ .lmd_match = match_flags,
};
struct ldlm_resource *res;
struct ldlm_lock *lock;
@@ -92,14 +92,16 @@ int mdc_dom_lock_match(const struct lu_env *env, struct obd_export *exp,
struct ldlm_res_id *res_id, enum ldlm_type type,
union ldlm_policy_data *policy, enum ldlm_mode mode,
u64 *flags, struct osc_object *obj,
- struct lustre_handle *lockh, int unref)
+ struct lustre_handle *lockh,
+ enum ldlm_match_flags match_flags)
{
struct obd_device *obd = exp->exp_obd;
u64 lflags = *flags;
enum ldlm_mode rc;
- rc = ldlm_lock_match(obd->obd_namespace, lflags,
- res_id, type, policy, mode, lockh, unref);
+ rc = ldlm_lock_match_with_skip(obd->obd_namespace, lflags, 0,
+ res_id, type, policy, mode, lockh,
+ match_flags);
if (rc == 0 || lflags & LDLM_FL_TEST_LOCK)
return rc;
@@ -139,6 +141,7 @@ struct ldlm_lock *mdc_dlmlock_at_pgoff(const struct lu_env *env,
struct ldlm_lock *lock = NULL;
enum ldlm_mode mode;
u64 flags;
+ enum ldlm_match_flags match_flags = 0;
fid_build_reg_res_name(lu_object_fid(osc2lu(obj)), resname);
mdc_lock_build_policy(env, policy);
@@ -147,6 +150,12 @@ struct ldlm_lock *mdc_dlmlock_at_pgoff(const struct lu_env *env,
if (dap_flags & OSC_DAP_FL_TEST_LOCK)
flags |= LDLM_FL_TEST_LOCK;
+ if (dap_flags & OSC_DAP_FL_AST)
+ match_flags |= LDLM_MATCH_AST;
+
+ if (dap_flags & OSC_DAP_FL_CANCELING)
+ match_flags |= LDLM_MATCH_UNREF;
+
again:
/* Next, search for already existing extent locks that will cover us */
/* If we're trying to read, we also search for an existing PW lock. The
@@ -155,8 +164,7 @@ struct ldlm_lock *mdc_dlmlock_at_pgoff(const struct lu_env *env,
*/
mode = mdc_dom_lock_match(env, osc_export(obj), resname, LDLM_IBITS,
policy, LCK_PR | LCK_PW | LCK_GROUP, &flags,
- obj, &lockh,
- dap_flags & OSC_DAP_FL_CANCELING);
+ obj, &lockh, match_flags);
if (mode) {
lock = ldlm_handle2lock(&lockh);
/* RACE: the lock is cancelled so let's try again */
@@ -184,7 +192,7 @@ static bool mdc_check_and_discard_cb(const struct lu_env *env, struct cl_io *io,
/* refresh non-overlapped index */
tmp = mdc_dlmlock_at_pgoff(env, osc, index,
- OSC_DAP_FL_TEST_LOCK);
+ OSC_DAP_FL_TEST_LOCK | OSC_DAP_FL_AST);
if (tmp) {
info->oti_fn_index = CL_PAGE_EOF;
LDLM_LOCK_PUT(tmp);
@@ -692,7 +700,7 @@ int mdc_enqueue_send(const struct lu_env *env, struct obd_export *exp,
* such locks should be skipped.
*/
mode = ldlm_lock_match(obd->obd_namespace, match_flags, res_id,
- einfo->ei_type, policy, mode, &lockh, 0);
+ einfo->ei_type, policy, mode, &lockh);
if (mode) {
struct ldlm_lock *matched;
@@ -146,7 +146,7 @@ enum ldlm_mode mdc_lock_match(struct obd_export *exp, u64 flags,
/* LU-4405: Clear bits not supported by server */
policy->l_inodebits.bits &= exp_connect_ibits(exp);
rc = ldlm_lock_match(class_exp2obd(exp)->obd_namespace, flags,
- &res_id, type, policy, mode, lockh, 0);
+ &res_id, type, policy, mode, lockh);
return rc;
}
@@ -1185,8 +1185,7 @@ static int mdc_finish_intent_lock(struct obd_export *exp,
memcpy(&old_lock, lockh, sizeof(*lockh));
if (ldlm_lock_match(NULL, LDLM_FL_BLOCK_GRANTED, NULL,
- LDLM_IBITS, &policy, LCK_NL,
- &old_lock, 0)) {
+ LDLM_IBITS, &policy, LCK_NL, &old_lock)) {
ldlm_lock_decref_and_cancel(lockh,
it->it_lock_mode);
memcpy(lockh, &old_lock, sizeof(old_lock));
@@ -3216,7 +3216,7 @@ static bool check_and_discard_cb(const struct lu_env *env, struct cl_io *io,
/* refresh non-overlapped index */
tmp = osc_dlmlock_at_pgoff(env, osc, index,
- OSC_DAP_FL_TEST_LOCK);
+ OSC_DAP_FL_TEST_LOCK | OSC_DAP_FL_AST);
if (tmp) {
u64 end = tmp->l_policy_data.l_extent.end;
/* Cache the first-non-overlapped index so as to skip
@@ -68,7 +68,8 @@ int osc_match_base(const struct lu_env *env, struct obd_export *exp,
struct ldlm_res_id *res_id, enum ldlm_type type,
union ldlm_policy_data *policy, enum ldlm_mode mode,
u64 *flags, struct osc_object *obj,
- struct lustre_handle *lockh, int unref);
+ struct lustre_handle *lockh,
+ enum ldlm_match_flags match_flags);
int osc_setattr_async(struct obd_export *exp, struct obdo *oa,
obd_enqueue_update_f upcall, void *cookie,
@@ -579,8 +579,7 @@ int osc_ldlm_glimpse_ast(struct ldlm_lock *dlmlock, void *data)
matchdata.lmd_mode = &mode;
matchdata.lmd_policy = &policy;
matchdata.lmd_flags = LDLM_FL_TEST_LOCK | LDLM_FL_CBPENDING;
- matchdata.lmd_unref = 1;
- matchdata.lmd_has_ast_data = true;
+ matchdata.lmd_match = LDLM_MATCH_UNREF | LDLM_MATCH_AST_ANY;
LDLM_LOCK_GET(dlmlock);
@@ -1267,6 +1266,7 @@ struct ldlm_lock *osc_obj_dlmlock_at_pgoff(const struct lu_env *env,
struct ldlm_lock *lock = NULL;
enum ldlm_mode mode;
u64 flags;
+ enum ldlm_match_flags match_flags = 0;
ostid_build_res_name(&obj->oo_oinfo->loi_oi, resname);
osc_index2policy(policy, osc2cl(obj), index, index);
@@ -1276,6 +1276,12 @@ struct ldlm_lock *osc_obj_dlmlock_at_pgoff(const struct lu_env *env,
if (dap_flags & OSC_DAP_FL_TEST_LOCK)
flags |= LDLM_FL_TEST_LOCK;
+ if (dap_flags & OSC_DAP_FL_AST)
+ match_flags |= LDLM_MATCH_AST;
+
+ if (dap_flags & OSC_DAP_FL_CANCELING)
+ match_flags |= LDLM_MATCH_UNREF;
+
/*
* It is fine to match any group lock since there could be only one
* with a uniq gid and it conflicts with all other lock modes too
@@ -1283,7 +1289,7 @@ struct ldlm_lock *osc_obj_dlmlock_at_pgoff(const struct lu_env *env,
again:
mode = osc_match_base(env, osc_export(obj), resname, LDLM_EXTENT,
policy, LCK_PR | LCK_PW | LCK_GROUP, &flags,
- obj, &lockh, dap_flags & OSC_DAP_FL_CANCELING);
+ obj, &lockh, match_flags);
if (mode != 0) {
lock = ldlm_handle2lock(&lockh);
/* RACE: the lock is cancelled so let's try again */
@@ -275,7 +275,7 @@ static int osc_object_fiemap(const struct lu_env *env, struct cl_object *obj,
mode = ldlm_lock_match(exp->exp_obd->obd_namespace,
LDLM_FL_BLOCK_GRANTED | LDLM_FL_LVB_READY,
&resid, LDLM_EXTENT, &policy,
- LCK_PR | LCK_PW, &lockh, 0);
+ LCK_PR | LCK_PW, &lockh);
if (mode) { /* lock is cached on client */
if (mode != LCK_PR) {
ldlm_lock_addref(&lockh, LCK_PR);
@@ -2723,7 +2723,7 @@ int osc_enqueue_base(struct obd_export *exp, struct ldlm_res_id *res_id,
if (intent != 0)
match_flags |= LDLM_FL_BLOCK_GRANTED;
mode = ldlm_lock_match(obd->obd_namespace, match_flags, res_id,
- einfo->ei_type, policy, mode, &lockh, 0);
+ einfo->ei_type, policy, mode, &lockh);
if (mode) {
struct ldlm_lock *matched;
@@ -2830,7 +2830,8 @@ int osc_match_base(const struct lu_env *env, struct obd_export *exp,
struct ldlm_res_id *res_id, enum ldlm_type type,
union ldlm_policy_data *policy, enum ldlm_mode mode,
u64 *flags, struct osc_object *obj,
- struct lustre_handle *lockh, int unref)
+ struct lustre_handle *lockh,
+ enum ldlm_match_flags match_flags)
{
struct obd_device *obd = exp->exp_obd;
u64 lflags = *flags;
@@ -2853,8 +2854,10 @@ int osc_match_base(const struct lu_env *env, struct obd_export *exp,
rc = mode;
if (mode == LCK_PR)
rc |= LCK_PW;
- rc = ldlm_lock_match(obd->obd_namespace, lflags,
- res_id, type, policy, rc, lockh, unref);
+
+ rc = ldlm_lock_match_with_skip(obd->obd_namespace, lflags, 0,
+ res_id, type, policy, rc, lockh,
+ match_flags);
if (!rc || lflags & LDLM_FL_TEST_LOCK)
return rc;