diff options
author | David Teigland <teigland@redhat.com> | 2006-10-31 12:55:56 -0500 |
---|---|---|
committer | Steven Whitehouse <swhiteho@redhat.com> | 2006-11-30 10:35:10 -0500 |
commit | d4400156d415540086c34a06e5d233122d6bf56a (patch) | |
tree | 747e4d270fb453d57926d6b6cab564664d9d2c0f /fs/dlm/lock.c | |
parent | 435618b75b82b5ee511cc01fcdda9c44adb2f4bd (diff) |
[DLM] fix requestqueue race
Red Hat BZ 211914
There's a race between dlm_recoverd (1) enabling locking and (2) clearing
out the requestqueue, and dlm_recvd (1) checking if locking is enabled and
(2) adding a message to the requestqueue. An order of recoverd(1),
recvd(1), recvd(2), recoverd(2) will result in a message being left on the
requestqueue. The fix is to have dlm_recvd check if dlm_recoverd has
enabled locking after taking the mutex for the requestqueue and if it has
processing the message instead of queueing it.
Signed-off-by: David Teigland <teigland@redhat.com>
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/dlm/lock.c')
-rw-r--r-- | fs/dlm/lock.c | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c index 3f2befa4797b..6088a16926bf 100644 --- a/fs/dlm/lock.c +++ b/fs/dlm/lock.c | |||
@@ -3028,10 +3028,17 @@ int dlm_receive_message(struct dlm_header *hd, int nodeid, int recovery) | |||
3028 | 3028 | ||
3029 | while (1) { | 3029 | while (1) { |
3030 | if (dlm_locking_stopped(ls)) { | 3030 | if (dlm_locking_stopped(ls)) { |
3031 | if (!recovery) | 3031 | if (recovery) { |
3032 | dlm_add_requestqueue(ls, nodeid, hd); | 3032 | error = -EINTR; |
3033 | error = -EINTR; | 3033 | goto out; |
3034 | goto out; | 3034 | } |
3035 | error = dlm_add_requestqueue(ls, nodeid, hd); | ||
3036 | if (error == -EAGAIN) | ||
3037 | continue; | ||
3038 | else { | ||
3039 | error = -EINTR; | ||
3040 | goto out; | ||
3041 | } | ||
3035 | } | 3042 | } |
3036 | 3043 | ||
3037 | if (lock_recovery_try(ls)) | 3044 | if (lock_recovery_try(ls)) |