diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c index 3199bf92e46e..b381faade0a7 100644 --- a/drivers/block/drbd/drbd_state.c +++ b/drivers/block/drbd/drbd_state.c @@ -396,6 +396,27 @@ is_valid_soft_transition(union drbd_state os, union drbd_state ns) return rv; } +static enum drbd_state_rv +is_valid_conn_transition(enum drbd_conns oc, enum drbd_conns nc) +{ + enum drbd_state_rv rv = SS_SUCCESS; + + /* Disallow Network errors to configure a device's network part */ + if ((nc >= C_TIMEOUT && nc <= C_TEAR_DOWN) && oc <= C_DISCONNECTING) + rv = SS_NEED_CONNECTION; + + /* After a network error only C_UNCONNECTED or C_DISCONNECTING may follow. */ + if (oc >= C_TIMEOUT && oc <= C_TEAR_DOWN && nc != C_UNCONNECTED && nc != C_DISCONNECTING) + rv = SS_IN_TRANSIENT_STATE; + + /* After C_DISCONNECTING only C_STANDALONE may follow */ + if (oc == C_DISCONNECTING && nc != C_STANDALONE) + rv = SS_IN_TRANSIENT_STATE; + + return rv; +} + + /** * is_valid_transition() - Returns an SS_ error code if the state transition is not possible * This limits hard state transitions. Hard state transitions are facts there are @@ -407,21 +428,9 @@ is_valid_soft_transition(union drbd_state os, union drbd_state ns) static enum drbd_state_rv is_valid_transition(union drbd_state os, union drbd_state ns) { - enum drbd_state_rv rv = SS_SUCCESS; + enum drbd_state_rv rv; - /* Disallow Network errors to configure a device's network part */ - if ((ns.conn >= C_TIMEOUT && ns.conn <= C_TEAR_DOWN) && - os.conn <= C_DISCONNECTING) - rv = SS_NEED_CONNECTION; - - /* After a network error only C_UNCONNECTED or C_DISCONNECTING may follow. */ - if (os.conn >= C_TIMEOUT && os.conn <= C_TEAR_DOWN && - ns.conn != C_UNCONNECTED && ns.conn != C_DISCONNECTING) - rv = SS_IN_TRANSIENT_STATE; - - /* After C_DISCONNECTING only C_STANDALONE may follow */ - if (os.conn == C_DISCONNECTING && ns.conn != C_STANDALONE) - rv = SS_IN_TRANSIENT_STATE; + rv = is_valid_conn_transition(os.conn, ns.conn); /* we cannot fail (again) if we already detached */ if (ns.disk == D_FAILED && os.disk == D_DISKLESS)