struct dlm_lockstatus *lksb;
        enum dlm_status status = DLM_NORMAL;
        u32 flags;
-       int call_ast = 0, kick_thread = 0, ast_reserved = 0;
+       int call_ast = 0, kick_thread = 0, ast_reserved = 0, wake = 0;
 
        if (!dlm_grab(dlm)) {
                dlm_error(DLM_REJECTED);
                                             cnv->requested_type,
                                             &call_ast, &kick_thread);
                res->state &= ~DLM_LOCK_RES_IN_PROGRESS;
+               wake = 1;
        }
        spin_unlock(&res->spinlock);
+       if (wake)
+               wake_up(&res->wq);
 
        if (status != DLM_NORMAL) {
                if (status != DLM_NOTQUEUED)
 
                spin_unlock(&mle->spinlock);
 
                if (res) {
+                       int wake = 0;
                        spin_lock(&res->spinlock);
                        if (mle->type == DLM_MLE_MIGRATION) {
                                mlog(0, "finishing off migration of lockres %.*s, "
                                        res->lockname.len, res->lockname.name,
                                        dlm->node_num, mle->new_master);
                                res->state &= ~DLM_LOCK_RES_MIGRATING;
+                               wake = 1;
                                dlm_change_lockres_owner(dlm, res, mle->new_master);
                                BUG_ON(res->state & DLM_LOCK_RES_DIRTY);
                        } else {
                        }
                        spin_unlock(&res->spinlock);
                        have_lockres_ref = 1;
+                       if (wake)
+                               wake_up(&res->wq);
                }
 
                /* master is known, detach if not already detached.
        struct list_head *queue, *iter;
        int i;
        struct dlm_lock *lock;
-       int empty = 1;
+       int empty = 1, wake = 0;
 
        if (!dlm_grab(dlm))
                return -EINVAL;
                     res->lockname.name, target);
                spin_lock(&res->spinlock);
                res->state &= ~DLM_LOCK_RES_MIGRATING;
+               wake = 1;
                spin_unlock(&res->spinlock);
                ret = -EINVAL;
        }
                dlm_put_mle_inuse(mle);
                spin_lock(&res->spinlock);
                res->state &= ~DLM_LOCK_RES_MIGRATING;
+               wake = 1;
                spin_unlock(&res->spinlock);
                goto leave;
        }
                                dlm_put_mle_inuse(mle);
                                spin_lock(&res->spinlock);
                                res->state &= ~DLM_LOCK_RES_MIGRATING;
+                               wake = 1;
                                spin_unlock(&res->spinlock);
                                goto leave;
                        }
        if (ret < 0)
                dlm_kick_thread(dlm, res);
 
+       /* wake up waiters if the MIGRATING flag got set
+        * but migration failed */
+       if (wake)
+               wake_up(&res->wq);
+
        /* TODO: cleanup */
        if (mres)
                free_page((unsigned long)mres);