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 | ||||
| 		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); | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user