|
@@ -194,25 +194,21 @@ out_err:
|
|
|
|
|
|
|
|
static void lockres_free(struct dlm_lock_resource *res)
|
|
static void lockres_free(struct dlm_lock_resource *res)
|
|
|
{
|
|
{
|
|
|
- int ret;
|
|
|
|
|
|
|
+ int ret = 0;
|
|
|
|
|
|
|
|
if (!res)
|
|
if (!res)
|
|
|
return;
|
|
return;
|
|
|
|
|
|
|
|
- /* cancel a lock request or a conversion request that is blocked */
|
|
|
|
|
- res->flags |= DLM_LKF_CANCEL;
|
|
|
|
|
-retry:
|
|
|
|
|
- ret = dlm_unlock(res->ls, res->lksb.sb_lkid, 0, &res->lksb, res);
|
|
|
|
|
- if (unlikely(ret != 0)) {
|
|
|
|
|
- pr_info("%s: failed to unlock %s return %d\n", __func__, res->name, ret);
|
|
|
|
|
-
|
|
|
|
|
- /* if a lock conversion is cancelled, then the lock is put
|
|
|
|
|
- * back to grant queue, need to ensure it is unlocked */
|
|
|
|
|
- if (ret == -DLM_ECANCEL)
|
|
|
|
|
- goto retry;
|
|
|
|
|
- }
|
|
|
|
|
- res->flags &= ~DLM_LKF_CANCEL;
|
|
|
|
|
- wait_for_completion(&res->completion);
|
|
|
|
|
|
|
+ /*
|
|
|
|
|
+ * use FORCEUNLOCK flag, so we can unlock even the lock is on the
|
|
|
|
|
+ * waiting or convert queue
|
|
|
|
|
+ */
|
|
|
|
|
+ ret = dlm_unlock(res->ls, res->lksb.sb_lkid, DLM_LKF_FORCEUNLOCK,
|
|
|
|
|
+ &res->lksb, res);
|
|
|
|
|
+ if (unlikely(ret != 0))
|
|
|
|
|
+ pr_err("failed to unlock %s return %d\n", res->name, ret);
|
|
|
|
|
+ else
|
|
|
|
|
+ wait_for_completion(&res->completion);
|
|
|
|
|
|
|
|
kfree(res->name);
|
|
kfree(res->name);
|
|
|
kfree(res->lksb.sb_lvbptr);
|
|
kfree(res->lksb.sb_lvbptr);
|