+ if (bits & (MDS_INODELOCK_LOOKUP | MDS_INODELOCK_PERM))
+ forget_all_cached_acls(inode);
+
+ iput(inode);
+ RETURN_EXIT;
+}
+
+/* Check if the given lock may be downgraded instead of canceling and
+ * that convert is really needed. */
+int ll_md_need_convert(struct ldlm_lock *lock)
+{
+ struct ldlm_namespace *ns = ldlm_lock_to_ns(lock);
+ struct inode *inode;
+ __u64 wanted = lock->l_policy_data.l_inodebits.cancel_bits;
+ __u64 bits = lock->l_policy_data.l_inodebits.bits & ~wanted;
+ enum ldlm_mode mode = LCK_MINMODE;
+
+ if (!lock->l_conn_export ||
+ !exp_connect_lock_convert(lock->l_conn_export))
+ return 0;
+
+ if (!wanted || !bits || ldlm_is_cancel(lock))
+ return 0;
+
+ /* do not convert locks other than DOM for now */
+ if (!((bits | wanted) & MDS_INODELOCK_DOM))
+ return 0;
+
+ /* We may have already remaining bits in some other lock so
+ * lock convert will leave us just extra lock for the same bit.
+ * Check if client has other lock with the same bits and the same
+ * or lower mode and don't convert if any.
+ */
+ switch (lock->l_req_mode) {
+ case LCK_PR:
+ mode = LCK_PR;
+ /* fallthrough */
+ case LCK_PW:
+ mode |= LCK_CR;
+ break;
+ case LCK_CW:
+ mode = LCK_CW;
+ /* fallthrough */
+ case LCK_CR:
+ mode |= LCK_CR;
+ break;
+ default:
+ /* do not convert other modes */
+ return 0;
+ }
+
+ /* is lock is too old to be converted? */
+ lock_res_and_lock(lock);
+ if (ktime_after(ktime_get(),
+ ktime_add(lock->l_last_used,
+ ktime_set(ns->ns_dirty_age_limit, 0)))) {
+ unlock_res_and_lock(lock);
+ return 0;
+ }
+ unlock_res_and_lock(lock);
+
+ inode = ll_inode_from_resource_lock(lock);
+ ll_have_md_lock(inode, &bits, mode);
+ iput(inode);
+ return !!(bits);
+}
+
+int ll_md_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *ld,
+ void *data, int flag)
+{
+ struct lustre_handle lockh;
+ int rc;
+
+ ENTRY;
+
+ switch (flag) {
+ case LDLM_CB_BLOCKING:
+ {
+ __u64 cancel_flags = LCF_ASYNC;
+
+ /* if lock convert is not needed then still have to
+ * pass lock via ldlm_cli_convert() to keep all states
+ * correct, set cancel_bits to full lock bits to cause
+ * full cancel to happen.
+ */
+ if (!ll_md_need_convert(lock)) {
+ lock_res_and_lock(lock);
+ lock->l_policy_data.l_inodebits.cancel_bits =
+ lock->l_policy_data.l_inodebits.bits;
+ unlock_res_and_lock(lock);
+ }
+ rc = ldlm_cli_convert(lock, cancel_flags);
+ if (!rc)
+ RETURN(0);
+ /* continue with cancel otherwise */
+ ldlm_lock2handle(lock, &lockh);
+ rc = ldlm_cli_cancel(&lockh, cancel_flags);
+ if (rc < 0) {
+ CDEBUG(D_INODE, "ldlm_cli_cancel: rc = %d\n", rc);
+ RETURN(rc);
+ }
+ break;
+ }
+ case LDLM_CB_CANCELING:
+ {
+ __u64 to_cancel = lock->l_policy_data.l_inodebits.bits;
+
+ /* Nothing to do for non-granted locks */
+ if (!ldlm_is_granted(lock))
+ break;
+
+ /* If 'ld' is supplied then bits to be cancelled are passed
+ * implicitly by lock converting and cancel_bits from 'ld'
+ * should be used. Otherwise full cancel is being performed
+ * and lock inodebits are used.
+ *
+ * Note: we cannot rely on cancel_bits in lock itself at this
+ * moment because they can be changed by concurrent thread,
+ * so ldlm_cli_inodebits_convert() pass cancel bits implicitly
+ * in 'ld' parameter.
+ */
+ if (ld) {
+ /* partial bits cancel allowed only during convert */
+ LASSERT(ldlm_is_converting(lock));
+ /* mask cancel bits by lock bits so only no any unused
+ * bits are passed to ll_lock_cancel_bits()
+ */
+ to_cancel &= ld->l_policy_data.l_inodebits.cancel_bits;
+ }
+ ll_lock_cancel_bits(lock, to_cancel);