diff options
author | Lars Ellenberg <lars.ellenberg@linbit.com> | 2010-07-21 11:04:32 -0400 |
---|---|---|
committer | Philipp Reisner <philipp.reisner@linbit.com> | 2010-10-14 12:38:37 -0400 |
commit | f2906e183f5460df9d9e774f5952f5ff670b3913 (patch) | |
tree | f30736542841df13d66c5aa3f6507105fdc8f7ac /drivers | |
parent | 02bc7174ae83617b4364dc179d95d848d9fd6db5 (diff) |
drbd: fix for spurious full sync (becoming sync target looked like invalidate)
If a synctarget lost connection while being WFSyncUUID,
due to "state sanitizing", the attempted state change to SyncTarget
looked like an "invalidate" to after_state_ch() later,
thus caused a full sync on next handshake (Bug #318).
drbd0: PingAck did not arrive in time.
drbd0: peer( Primary -> Unknown ) conn( WFSyncUUID -> NetworkFailure ) pdsk( UpToDate -> DUnknown )
from : { cs:NetworkFailure ro:Secondary/Unknown ds:UpToDate/DUnknown r--- }
to : { cs:SyncTarget ro:Secondary/Unknown ds:Inconsistent/DUnknown r--- }
after sanizising, resulted in
state: { cs:NetworkFailure ro:Secondary/Unknown ds:Inconsistent/DUnknown r--- }
drbd0: disk( UpToDate -> Inconsistent )
Fix:
don't mask state transition errors in "sanitizing",
so the requested state change to SyncTarget fails,
instead of being implicitly "remaped" to invalidate.
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/block/drbd/drbd_main.c | 5 |
1 files changed, 3 insertions, 2 deletions
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index 2060db69f182..04c305d36f8e 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c | |||
@@ -827,9 +827,10 @@ static union drbd_state sanitize_state(struct drbd_conf *mdev, union drbd_state | |||
827 | os.conn <= C_DISCONNECTING) | 827 | os.conn <= C_DISCONNECTING) |
828 | ns.conn = os.conn; | 828 | ns.conn = os.conn; |
829 | 829 | ||
830 | /* After a network error (+C_TEAR_DOWN) only C_UNCONNECTED or C_DISCONNECTING can follow */ | 830 | /* After a network error (+C_TEAR_DOWN) only C_UNCONNECTED or C_DISCONNECTING can follow. |
831 | * If you try to go into some Sync* state, that shall fail (elsewhere). */ | ||
831 | if (os.conn >= C_TIMEOUT && os.conn <= C_TEAR_DOWN && | 832 | if (os.conn >= C_TIMEOUT && os.conn <= C_TEAR_DOWN && |
832 | ns.conn != C_UNCONNECTED && ns.conn != C_DISCONNECTING) | 833 | ns.conn != C_UNCONNECTED && ns.conn != C_DISCONNECTING && ns.conn <= C_TEAR_DOWN) |
833 | ns.conn = os.conn; | 834 | ns.conn = os.conn; |
834 | 835 | ||
835 | /* After C_DISCONNECTING only C_STANDALONE may follow */ | 836 | /* After C_DISCONNECTING only C_STANDALONE may follow */ |