]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
drbd: Fix comparison of is_valid_transition()'s return code
authorPhilipp Reisner <philipp.reisner@linbit.com>
Mon, 3 Sep 2012 13:39:01 +0000 (15:39 +0200)
committerPhilipp Reisner <philipp.reisner@linbit.com>
Fri, 9 Nov 2012 13:11:38 +0000 (14:11 +0100)
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>
drivers/block/drbd/drbd_state.c

index 84512ec19173e1e5f84ebe6b9d482d8a91349f93..69ef35266bac2980fe56eabcc6f3972ab9374af6 100644 (file)
@@ -277,16 +277,16 @@ _req_st_cond(struct drbd_conf *mdev, union drbd_state mask,
        os = drbd_read_state(mdev);
        ns = sanitize_state(mdev, apply_mask_val(os, mask, val), NULL);
        rv = is_valid_transition(os, ns);
-       if (rv == SS_SUCCESS)
+       if (rv >= SS_SUCCESS)
                rv = SS_UNKNOWN_ERROR;  /* cont waiting, otherwise fail. */
 
        if (!cl_wide_st_chg(mdev, os, ns))
                rv = SS_CW_NO_NEED;
        if (rv == SS_UNKNOWN_ERROR) {
                rv = is_valid_state(mdev, ns);
-               if (rv == SS_SUCCESS) {
+               if (rv >= SS_SUCCESS) {
                        rv = is_valid_soft_transition(os, ns, mdev->tconn);
-                       if (rv == SS_SUCCESS)
+                       if (rv >= SS_SUCCESS)
                                rv = SS_UNKNOWN_ERROR; /* cont waiting, otherwise fail. */
                }
        }