ocfs2: do not modify lksb->status in the unlock ast
authorKurt Hackel <kurt.hackel@oracle.com>
Mon, 19 Jun 2006 04:28:01 +0000 (21:28 -0700)
committerMark Fasheh <mark.fasheh@oracle.com>
Mon, 7 Aug 2006 17:54:59 +0000 (10:54 -0700)
This can race with other ast notification, which can cause bad status values
to propagate into the unlock ast.

Signed-off-by: Kurt Hackel <kurt.hackel@oracle.com>
Signed-off-by: Mark Fasheh <mark.fasheh@oracle.com>
fs/ocfs2/dlm/dlmunlock.c

index 4ce3f82..59866e4 100644 (file)
@@ -155,7 +155,7 @@ static enum dlm_status dlmunlock_common(struct dlm_ctxt *dlm,
        else
                status = dlm_get_unlock_actions(dlm, res, lock, lksb, &actions);
 
-       if (status != DLM_NORMAL)
+       if (status != DLM_NORMAL && status != DLM_CANCELGRANT)
                goto leave;
 
        /* By now this has been masked out of cancel requests. */
@@ -183,8 +183,7 @@ static enum dlm_status dlmunlock_common(struct dlm_ctxt *dlm,
                spin_lock(&lock->spinlock);
                /* if the master told us the lock was already granted,
                 * let the ast handle all of these actions */
-               if (status == DLM_NORMAL &&
-                   lksb->status == DLM_CANCELGRANT) {
+               if (status == DLM_CANCELGRANT) {
                        actions &= ~(DLM_UNLOCK_REMOVE_LOCK|
                                     DLM_UNLOCK_REGRANT_LOCK|
                                     DLM_UNLOCK_CLEAR_CONVERT_TYPE);
@@ -349,14 +348,9 @@ static enum dlm_status dlm_send_remote_unlock_request(struct dlm_ctxt *dlm,
                                        vec, veclen, owner, &status);
        if (tmpret >= 0) {
                // successfully sent and received
-               if (status == DLM_CANCELGRANT)
-                       ret = DLM_NORMAL;
-               else if (status == DLM_FORWARD) {
+               if (status == DLM_FORWARD)
                        mlog(0, "master was in-progress.  retry\n");
-                       ret = DLM_FORWARD;
-               } else
-                       ret = status;
-               lksb->status = status;
+               ret = status;
        } else {
                mlog_errno(tmpret);
                if (dlm_is_host_down(tmpret)) {
@@ -372,7 +366,6 @@ static enum dlm_status dlm_send_remote_unlock_request(struct dlm_ctxt *dlm,
                        /* something bad.  this will BUG in ocfs2 */
                        ret = dlm_err_to_dlm_status(tmpret);
                }
-               lksb->status = ret;
        }
 
        return ret;
@@ -511,11 +504,8 @@ not_found:
                               "cookie=%u:%llu\n",
                               dlm_get_lock_cookie_node(unlock->cookie),
                               dlm_get_lock_cookie_seq(unlock->cookie));
-       else {
-               /* send the lksb->status back to the other node */
-               status = lksb->status;
+       else
                dlm_lock_put(lock);
-       }
 
 leave:
        if (res)
@@ -537,26 +527,22 @@ static enum dlm_status dlm_get_cancel_actions(struct dlm_ctxt *dlm,
 
        if (dlm_lock_on_list(&res->blocked, lock)) {
                /* cancel this outright */
-               lksb->status = DLM_NORMAL;
                status = DLM_NORMAL;
                *actions = (DLM_UNLOCK_CALL_AST |
                            DLM_UNLOCK_REMOVE_LOCK);
        } else if (dlm_lock_on_list(&res->converting, lock)) {
                /* cancel the request, put back on granted */
-               lksb->status = DLM_NORMAL;
                status = DLM_NORMAL;
                *actions = (DLM_UNLOCK_CALL_AST |
                            DLM_UNLOCK_REMOVE_LOCK |
                            DLM_UNLOCK_REGRANT_LOCK |
                            DLM_UNLOCK_CLEAR_CONVERT_TYPE);
        } else if (dlm_lock_on_list(&res->granted, lock)) {
-               /* too late, already granted.  DLM_CANCELGRANT */
-               lksb->status = DLM_CANCELGRANT;
-               status = DLM_NORMAL;
+               /* too late, already granted. */
+               status = DLM_CANCELGRANT;
                *actions = DLM_UNLOCK_CALL_AST;
        } else {
                mlog(ML_ERROR, "lock to cancel is not on any list!\n");
-               lksb->status = DLM_IVLOCKID;
                status = DLM_IVLOCKID;
                *actions = 0;
        }
@@ -573,13 +559,11 @@ static enum dlm_status dlm_get_unlock_actions(struct dlm_ctxt *dlm,
 
        /* unlock request */
        if (!dlm_lock_on_list(&res->granted, lock)) {
-               lksb->status = DLM_DENIED;
                status = DLM_DENIED;
                dlm_error(status);
                *actions = 0;
        } else {
                /* unlock granted lock */
-               lksb->status = DLM_NORMAL;
                status = DLM_NORMAL;
                *actions = (DLM_UNLOCK_FREE_LOCK |
                            DLM_UNLOCK_CALL_AST |
@@ -671,7 +655,7 @@ retry:
        }
 
        if (call_ast) {
-               mlog(0, "calling unlockast(%p, %d)\n", data, lksb->status);
+               mlog(0, "calling unlockast(%p, %d)\n", data, status);
                if (is_master) {
                        /* it is possible that there is one last bast 
                         * pending.  make sure it is flushed, then
@@ -683,9 +667,12 @@ retry:
                        wait_event(dlm->ast_wq, 
                                   dlm_lock_basts_flushed(dlm, lock));
                }
-               (*unlockast)(data, lksb->status);
+               (*unlockast)(data, status);
        }
 
+       if (status == DLM_CANCELGRANT)
+               status = DLM_NORMAL;
+
        if (status == DLM_NORMAL) {
                mlog(0, "kicking the thread\n");
                dlm_kick_thread(dlm, res);