aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilipp Reisner <philipp.reisner@linbit.com>2012-09-03 09:39:01 -0400
committerPhilipp Reisner <philipp.reisner@linbit.com>2012-11-09 08:11:38 -0500
commita3025a273700fc51dd561c7b2941f3c9db9be90a (patch)
treee4fc182421eb57b8863c3ba0aa4b6c2fa6e975ef
parent1393b59f8c46001c8dbd47078881483cf97813c3 (diff)
drbd: Fix comparison of is_valid_transition()'s return code
is_valid_transition() might return SS_NOTHING_TO_DO. The condition function _req_st_cond() returned SS_NOTHING_TO_DO, which caused the wait_event to abort too early. Therefore drbd_req_state() did not consume the next CL_ST_CHG_SUCCESS or SS_CW_FAILED_BY_PEER causing serve disruption of the state machine logic... Detaching from a single volue was one way to trigger this bug. Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com> Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
-rw-r--r--drivers/block/drbd/drbd_state.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c
index 84512ec19173..69ef35266bac 100644
--- a/drivers/block/drbd/drbd_state.c
+++ b/drivers/block/drbd/drbd_state.c
@@ -277,16 +277,16 @@ _req_st_cond(struct drbd_conf *mdev, union drbd_state mask,
277 os = drbd_read_state(mdev); 277 os = drbd_read_state(mdev);
278 ns = sanitize_state(mdev, apply_mask_val(os, mask, val), NULL); 278 ns = sanitize_state(mdev, apply_mask_val(os, mask, val), NULL);
279 rv = is_valid_transition(os, ns); 279 rv = is_valid_transition(os, ns);
280 if (rv == SS_SUCCESS) 280 if (rv >= SS_SUCCESS)
281 rv = SS_UNKNOWN_ERROR; /* cont waiting, otherwise fail. */ 281 rv = SS_UNKNOWN_ERROR; /* cont waiting, otherwise fail. */
282 282
283 if (!cl_wide_st_chg(mdev, os, ns)) 283 if (!cl_wide_st_chg(mdev, os, ns))
284 rv = SS_CW_NO_NEED; 284 rv = SS_CW_NO_NEED;
285 if (rv == SS_UNKNOWN_ERROR) { 285 if (rv == SS_UNKNOWN_ERROR) {
286 rv = is_valid_state(mdev, ns); 286 rv = is_valid_state(mdev, ns);
287 if (rv == SS_SUCCESS) { 287 if (rv >= SS_SUCCESS) {
288 rv = is_valid_soft_transition(os, ns, mdev->tconn); 288 rv = is_valid_soft_transition(os, ns, mdev->tconn);
289 if (rv == SS_SUCCESS) 289 if (rv >= SS_SUCCESS)
290 rv = SS_UNKNOWN_ERROR; /* cont waiting, otherwise fail. */ 290 rv = SS_UNKNOWN_ERROR; /* cont waiting, otherwise fail. */
291 } 291 }
292 } 292 }