mirror of
https://github.com/torvalds/linux.git
synced 2024-12-29 06:12:08 +00:00
ocfs2: do not modify lksb->status in the unlock ast
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>
This commit is contained in:
parent
4b1af77445
commit
a23eac99d4
@ -155,7 +155,7 @@ static enum dlm_status dlmunlock_common(struct dlm_ctxt *dlm,
|
|||||||
else
|
else
|
||||||
status = dlm_get_unlock_actions(dlm, res, lock, lksb, &actions);
|
status = dlm_get_unlock_actions(dlm, res, lock, lksb, &actions);
|
||||||
|
|
||||||
if (status != DLM_NORMAL)
|
if (status != DLM_NORMAL && status != DLM_CANCELGRANT)
|
||||||
goto leave;
|
goto leave;
|
||||||
|
|
||||||
/* By now this has been masked out of cancel requests. */
|
/* 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);
|
spin_lock(&lock->spinlock);
|
||||||
/* if the master told us the lock was already granted,
|
/* if the master told us the lock was already granted,
|
||||||
* let the ast handle all of these actions */
|
* let the ast handle all of these actions */
|
||||||
if (status == DLM_NORMAL &&
|
if (status == DLM_CANCELGRANT) {
|
||||||
lksb->status == DLM_CANCELGRANT) {
|
|
||||||
actions &= ~(DLM_UNLOCK_REMOVE_LOCK|
|
actions &= ~(DLM_UNLOCK_REMOVE_LOCK|
|
||||||
DLM_UNLOCK_REGRANT_LOCK|
|
DLM_UNLOCK_REGRANT_LOCK|
|
||||||
DLM_UNLOCK_CLEAR_CONVERT_TYPE);
|
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);
|
vec, veclen, owner, &status);
|
||||||
if (tmpret >= 0) {
|
if (tmpret >= 0) {
|
||||||
// successfully sent and received
|
// successfully sent and received
|
||||||
if (status == DLM_CANCELGRANT)
|
if (status == DLM_FORWARD)
|
||||||
ret = DLM_NORMAL;
|
|
||||||
else if (status == DLM_FORWARD) {
|
|
||||||
mlog(0, "master was in-progress. retry\n");
|
mlog(0, "master was in-progress. retry\n");
|
||||||
ret = DLM_FORWARD;
|
ret = status;
|
||||||
} else
|
|
||||||
ret = status;
|
|
||||||
lksb->status = status;
|
|
||||||
} else {
|
} else {
|
||||||
mlog_errno(tmpret);
|
mlog_errno(tmpret);
|
||||||
if (dlm_is_host_down(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 */
|
/* something bad. this will BUG in ocfs2 */
|
||||||
ret = dlm_err_to_dlm_status(tmpret);
|
ret = dlm_err_to_dlm_status(tmpret);
|
||||||
}
|
}
|
||||||
lksb->status = ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -511,11 +504,8 @@ not_found:
|
|||||||
"cookie=%u:%llu\n",
|
"cookie=%u:%llu\n",
|
||||||
dlm_get_lock_cookie_node(unlock->cookie),
|
dlm_get_lock_cookie_node(unlock->cookie),
|
||||||
dlm_get_lock_cookie_seq(unlock->cookie));
|
dlm_get_lock_cookie_seq(unlock->cookie));
|
||||||
else {
|
else
|
||||||
/* send the lksb->status back to the other node */
|
|
||||||
status = lksb->status;
|
|
||||||
dlm_lock_put(lock);
|
dlm_lock_put(lock);
|
||||||
}
|
|
||||||
|
|
||||||
leave:
|
leave:
|
||||||
if (res)
|
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)) {
|
if (dlm_lock_on_list(&res->blocked, lock)) {
|
||||||
/* cancel this outright */
|
/* cancel this outright */
|
||||||
lksb->status = DLM_NORMAL;
|
|
||||||
status = DLM_NORMAL;
|
status = DLM_NORMAL;
|
||||||
*actions = (DLM_UNLOCK_CALL_AST |
|
*actions = (DLM_UNLOCK_CALL_AST |
|
||||||
DLM_UNLOCK_REMOVE_LOCK);
|
DLM_UNLOCK_REMOVE_LOCK);
|
||||||
} else if (dlm_lock_on_list(&res->converting, lock)) {
|
} else if (dlm_lock_on_list(&res->converting, lock)) {
|
||||||
/* cancel the request, put back on granted */
|
/* cancel the request, put back on granted */
|
||||||
lksb->status = DLM_NORMAL;
|
|
||||||
status = DLM_NORMAL;
|
status = DLM_NORMAL;
|
||||||
*actions = (DLM_UNLOCK_CALL_AST |
|
*actions = (DLM_UNLOCK_CALL_AST |
|
||||||
DLM_UNLOCK_REMOVE_LOCK |
|
DLM_UNLOCK_REMOVE_LOCK |
|
||||||
DLM_UNLOCK_REGRANT_LOCK |
|
DLM_UNLOCK_REGRANT_LOCK |
|
||||||
DLM_UNLOCK_CLEAR_CONVERT_TYPE);
|
DLM_UNLOCK_CLEAR_CONVERT_TYPE);
|
||||||
} else if (dlm_lock_on_list(&res->granted, lock)) {
|
} else if (dlm_lock_on_list(&res->granted, lock)) {
|
||||||
/* too late, already granted. DLM_CANCELGRANT */
|
/* too late, already granted. */
|
||||||
lksb->status = DLM_CANCELGRANT;
|
status = DLM_CANCELGRANT;
|
||||||
status = DLM_NORMAL;
|
|
||||||
*actions = DLM_UNLOCK_CALL_AST;
|
*actions = DLM_UNLOCK_CALL_AST;
|
||||||
} else {
|
} else {
|
||||||
mlog(ML_ERROR, "lock to cancel is not on any list!\n");
|
mlog(ML_ERROR, "lock to cancel is not on any list!\n");
|
||||||
lksb->status = DLM_IVLOCKID;
|
|
||||||
status = DLM_IVLOCKID;
|
status = DLM_IVLOCKID;
|
||||||
*actions = 0;
|
*actions = 0;
|
||||||
}
|
}
|
||||||
@ -573,13 +559,11 @@ static enum dlm_status dlm_get_unlock_actions(struct dlm_ctxt *dlm,
|
|||||||
|
|
||||||
/* unlock request */
|
/* unlock request */
|
||||||
if (!dlm_lock_on_list(&res->granted, lock)) {
|
if (!dlm_lock_on_list(&res->granted, lock)) {
|
||||||
lksb->status = DLM_DENIED;
|
|
||||||
status = DLM_DENIED;
|
status = DLM_DENIED;
|
||||||
dlm_error(status);
|
dlm_error(status);
|
||||||
*actions = 0;
|
*actions = 0;
|
||||||
} else {
|
} else {
|
||||||
/* unlock granted lock */
|
/* unlock granted lock */
|
||||||
lksb->status = DLM_NORMAL;
|
|
||||||
status = DLM_NORMAL;
|
status = DLM_NORMAL;
|
||||||
*actions = (DLM_UNLOCK_FREE_LOCK |
|
*actions = (DLM_UNLOCK_FREE_LOCK |
|
||||||
DLM_UNLOCK_CALL_AST |
|
DLM_UNLOCK_CALL_AST |
|
||||||
@ -671,7 +655,7 @@ retry:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (call_ast) {
|
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) {
|
if (is_master) {
|
||||||
/* it is possible that there is one last bast
|
/* it is possible that there is one last bast
|
||||||
* pending. make sure it is flushed, then
|
* pending. make sure it is flushed, then
|
||||||
@ -683,9 +667,12 @@ retry:
|
|||||||
wait_event(dlm->ast_wq,
|
wait_event(dlm->ast_wq,
|
||||||
dlm_lock_basts_flushed(dlm, lock));
|
dlm_lock_basts_flushed(dlm, lock));
|
||||||
}
|
}
|
||||||
(*unlockast)(data, lksb->status);
|
(*unlockast)(data, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (status == DLM_CANCELGRANT)
|
||||||
|
status = DLM_NORMAL;
|
||||||
|
|
||||||
if (status == DLM_NORMAL) {
|
if (status == DLM_NORMAL) {
|
||||||
mlog(0, "kicking the thread\n");
|
mlog(0, "kicking the thread\n");
|
||||||
dlm_kick_thread(dlm, res);
|
dlm_kick_thread(dlm, res);
|
||||||
|
Loading…
Reference in New Issue
Block a user