diff options
-rw-r--r-- | drivers/block/drbd/drbd_nl.c | 7 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_state.c | 14 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_strings.c | 1 | ||||
-rw-r--r-- | include/linux/drbd.h | 3 |
4 files changed, 15 insertions, 10 deletions
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index 56bafdcd943e..39e9a91a8f31 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c | |||
@@ -2198,8 +2198,11 @@ static enum drbd_state_rv conn_try_disconnect(struct drbd_tconn *tconn, bool for | |||
2198 | return SS_SUCCESS; | 2198 | return SS_SUCCESS; |
2199 | case SS_PRIMARY_NOP: | 2199 | case SS_PRIMARY_NOP: |
2200 | /* Our state checking code wants to see the peer outdated. */ | 2200 | /* Our state checking code wants to see the peer outdated. */ |
2201 | rv = conn_request_state(tconn, NS2(conn, C_DISCONNECTING, | 2201 | rv = conn_request_state(tconn, NS2(conn, C_DISCONNECTING, pdsk, D_OUTDATED), 0); |
2202 | pdsk, D_OUTDATED), CS_VERBOSE); | 2202 | |
2203 | if (rv == SS_OUTDATE_WO_CONN) /* lost connection before graceful disconnect succeeded */ | ||
2204 | rv = conn_request_state(tconn, NS(conn, C_DISCONNECTING), CS_VERBOSE); | ||
2205 | |||
2203 | break; | 2206 | break; |
2204 | case SS_CW_FAILED_BY_PEER: | 2207 | case SS_CW_FAILED_BY_PEER: |
2205 | /* The peer probably wants to see us outdated. */ | 2208 | /* The peer probably wants to see us outdated. */ |
diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c index 22e259f34370..90c5be2b1d30 100644 --- a/drivers/block/drbd/drbd_state.c +++ b/drivers/block/drbd/drbd_state.c | |||
@@ -642,6 +642,10 @@ is_valid_soft_transition(union drbd_state os, union drbd_state ns, struct drbd_t | |||
642 | && os.conn < C_WF_REPORT_PARAMS) | 642 | && os.conn < C_WF_REPORT_PARAMS) |
643 | rv = SS_NEED_CONNECTION; /* No NetworkFailure -> SyncTarget etc... */ | 643 | rv = SS_NEED_CONNECTION; /* No NetworkFailure -> SyncTarget etc... */ |
644 | 644 | ||
645 | if (ns.conn == C_DISCONNECTING && ns.pdsk == D_OUTDATED && | ||
646 | os.conn < C_CONNECTED && os.pdsk > D_OUTDATED) | ||
647 | rv = SS_OUTDATE_WO_CONN; | ||
648 | |||
645 | return rv; | 649 | return rv; |
646 | } | 650 | } |
647 | 651 | ||
@@ -1748,13 +1752,9 @@ _conn_rq_cond(struct drbd_tconn *tconn, union drbd_state mask, union drbd_state | |||
1748 | if (test_and_clear_bit(CONN_WD_ST_CHG_FAIL, &tconn->flags)) | 1752 | if (test_and_clear_bit(CONN_WD_ST_CHG_FAIL, &tconn->flags)) |
1749 | return SS_CW_FAILED_BY_PEER; | 1753 | return SS_CW_FAILED_BY_PEER; |
1750 | 1754 | ||
1751 | rv = tconn->cstate != C_WF_REPORT_PARAMS ? SS_CW_NO_NEED : SS_UNKNOWN_ERROR; | 1755 | rv = conn_is_valid_transition(tconn, mask, val, 0); |
1752 | 1756 | if (rv == SS_SUCCESS && tconn->cstate == C_WF_REPORT_PARAMS) | |
1753 | if (rv == SS_UNKNOWN_ERROR) | 1757 | rv = SS_UNKNOWN_ERROR; /* continue waiting */ |
1754 | rv = conn_is_valid_transition(tconn, mask, val, 0); | ||
1755 | |||
1756 | if (rv == SS_SUCCESS) | ||
1757 | rv = SS_UNKNOWN_ERROR; /* cont waiting, otherwise fail. */ | ||
1758 | 1758 | ||
1759 | return rv; | 1759 | return rv; |
1760 | } | 1760 | } |
diff --git a/drivers/block/drbd/drbd_strings.c b/drivers/block/drbd/drbd_strings.c index 9a664bd27404..58e08ff2b2ce 100644 --- a/drivers/block/drbd/drbd_strings.c +++ b/drivers/block/drbd/drbd_strings.c | |||
@@ -89,6 +89,7 @@ static const char *drbd_state_sw_errors[] = { | |||
89 | [-SS_LOWER_THAN_OUTDATED] = "Disk state is lower than outdated", | 89 | [-SS_LOWER_THAN_OUTDATED] = "Disk state is lower than outdated", |
90 | [-SS_IN_TRANSIENT_STATE] = "In transient state, retry after next state change", | 90 | [-SS_IN_TRANSIENT_STATE] = "In transient state, retry after next state change", |
91 | [-SS_CONCURRENT_ST_CHG] = "Concurrent state changes detected and aborted", | 91 | [-SS_CONCURRENT_ST_CHG] = "Concurrent state changes detected and aborted", |
92 | [-SS_OUTDATE_WO_CONN] = "Need a connection for a graceful disconnect/outdate peer", | ||
92 | [-SS_O_VOL_PEER_PRI] = "Other vol primary on peer not allowed by config", | 93 | [-SS_O_VOL_PEER_PRI] = "Other vol primary on peer not allowed by config", |
93 | }; | 94 | }; |
94 | 95 | ||
diff --git a/include/linux/drbd.h b/include/linux/drbd.h index 0c5a18ec322c..316330705fd7 100644 --- a/include/linux/drbd.h +++ b/include/linux/drbd.h | |||
@@ -319,7 +319,8 @@ enum drbd_state_rv { | |||
319 | SS_IN_TRANSIENT_STATE = -18, /* Retry after the next state change */ | 319 | SS_IN_TRANSIENT_STATE = -18, /* Retry after the next state change */ |
320 | SS_CONCURRENT_ST_CHG = -19, /* Concurrent cluster side state change! */ | 320 | SS_CONCURRENT_ST_CHG = -19, /* Concurrent cluster side state change! */ |
321 | SS_O_VOL_PEER_PRI = -20, | 321 | SS_O_VOL_PEER_PRI = -20, |
322 | SS_AFTER_LAST_ERROR = -21, /* Keep this at bottom */ | 322 | SS_OUTDATE_WO_CONN = -21, |
323 | SS_AFTER_LAST_ERROR = -22, /* Keep this at bottom */ | ||
323 | }; | 324 | }; |
324 | 325 | ||
325 | /* from drbd_strings.c */ | 326 | /* from drbd_strings.c */ |