struct ldlm_lock,
l_sl_policy)->l_res_link;
- /* drop try_bits used by other locks */
- *try_bits &= ~(lock->l_policy_data.l_inodebits.bits);
+ /* no locks with trybits in either queues */
+ LASSERT(lock->l_policy_data.l_inodebits.try_bits == 0);
+
+ /* New lock's try_bits are filtered out by ibits
+ * of all locks in both granted and waiting queues.
+ */
+ *try_bits &= ~lock->l_policy_data.l_inodebits.bits;
+
if ((req_bits | *try_bits) == 0)
RETURN(0);
ldlm_is_cos_enabled(req) &&
lock->l_client_cookie == req->l_client_cookie)
goto not_conflicting;
+
+ /* The conflicting lock will keep only mandatory
+ * ibits and zero trybits in waiting queue.
+ * All actual trybits are cleared.
+ */
+ *try_bits = 0;
+
/* Found a conflicting policy group. */
if (!work_list)
RETURN(0);
if (lock->l_policy_data.l_inodebits.try_bits != 0) {
lock->l_policy_data.l_inodebits.bits |=
lock->l_policy_data.l_inodebits.try_bits;
+ lock->l_policy_data.l_inodebits.try_bits = 0;
*flags |= LDLM_FL_LOCK_CHANGED;
}
ldlm_resource_unlink_lock(lock);
if (lock->l_policy_data.l_inodebits.try_bits != 0) {
lock->l_policy_data.l_inodebits.bits |=
lock->l_policy_data.l_inodebits.try_bits;
+ lock->l_policy_data.l_inodebits.try_bits = 0;
*flags |= LDLM_FL_LOCK_CHANGED;
}
LASSERT(lock->l_policy_data.l_inodebits.bits);
}
/* Only enqueue LOOKUP lock for remote object */
- if (mdt_object_remote(o)) {
- LASSERT(*ibits == MDS_INODELOCK_LOOKUP);
- }
+ LASSERT(ergo(mdt_object_remote(o), *ibits == MDS_INODELOCK_LOOKUP));
if (lh->mlh_type == MDT_PDO_LOCK) {
/* check for exists after object is locked */
struct mdt_lock_handle *lh, __u64 *ibits,
__u64 trybits, bool cos_incompat)
{
- return mdt_object_lock_internal(info, o, lh, ibits, trybits,
- cos_incompat);
+ bool trylock_only = *ibits == 0;
+ int rc;
+
+ LASSERT(!(*ibits & trybits));
+ rc = mdt_object_lock_internal(info, o, lh, ibits, trybits,
+ cos_incompat);
+ if (rc && trylock_only) { /* clear error for try ibits lock only */
+ LASSERT(*ibits == 0);
+ rc = 0;
+ }
+ return rc;
}
/**
} else if (dom_lock) {
lm = (open_flags & FMODE_WRITE) ? LCK_PW : LCK_PR;
*ibits = MDS_INODELOCK_DOM;
- try_layout = false;
}
CDEBUG(D_INODE, "normal open:"DFID" lease count: %d, lm: %d\n",
/* one problem to return layout lock on open is that it may result
* in too many layout locks cached on the client side. */
if (!OBD_FAIL_CHECK(OBD_FAIL_MDS_NO_LL_OPEN) && try_layout) {
- /* return lookup lock to validate inode at the client side,
- * this is pretty important otherwise mdt will return layout
- * lock for each open.
- * However this is a double-edged sword because changing
- * permission will revoke huge # of LOOKUP locks. */
- trybits |= MDS_INODELOCK_LAYOUT | MDS_INODELOCK_LOOKUP;
+ trybits |= MDS_INODELOCK_LAYOUT;
}
- if (trybits != 0)
+ if (*ibits | trybits)
rc = mdt_object_lock_try(info, obj, lhc, ibits, trybits, false);
- else if (*ibits != 0)
- rc = mdt_object_lock(info, obj, lhc, *ibits);
CDEBUG(D_INODE, "%s: Requested bits lock:"DFID ", ibits = %#llx/%#llx"
", open_flags = %#llo, try_layout = %d : rc = %d\n",
rc = mdt_object_lock_try(info, mdt_pobj, &mll->mll_lh, &ibits,
MDS_INODELOCK_UPDATE, true);
if (!(ibits & MDS_INODELOCK_UPDATE)) {
- mdt_unlock_list(info, lock_list, rc);
+ mdt_unlock_list(info, lock_list, 0);
CDEBUG(D_INFO, "%s: busy lock on "DFID" %s retry %d\n",
mdt_obd_name(mdt), PFID(&fid), name.ln_name,
local br=$(grep -A 10 $tfile /proc/$PID/smaps | awk '/^Rss/{print $2}')
echo "Before revoking layout lock: $br KB mapped"
- # delete the file will revoke layout lock
- rm -f $DIR2/$tfile
+ # cancel layout lock manually
+ cancel_lru_locks mdc
# rss after revoking
local ar=$(grep -A 10 $tfile /proc/$PID/smaps | awk '/^Rss/{print $2}')