diff options
author | Philipp Reisner <philipp.reisner@linbit.com> | 2010-11-17 10:54:36 -0500 |
---|---|---|
committer | Philipp Reisner <philipp.reisner@linbit.com> | 2011-03-10 05:35:04 -0500 |
commit | ab17b68f4579b460753a416b0afc4446381d876f (patch) | |
tree | 78c88ce883d2c1e721171611f0899b159b24f290 /drivers/block/drbd | |
parent | 22afd7ee94c1c5857323b677267ba8bace09bcef (diff) |
drbd: Improvements in sanitize_state()
The relevant change is that the state change to C_FW_BITMAP_S should
implicitly change pdsk to C_CONSISTENT. (Think of it as C_OUTDATED, only
without the guarantee that the peer has the outdated written to its
meta data)
At that opportunity I restructured the switch statement so that it
gets evaluated every time. (Has declarative character)
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
Diffstat (limited to 'drivers/block/drbd')
-rw-r--r-- | drivers/block/drbd/drbd_main.c | 144 |
1 files changed, 89 insertions, 55 deletions
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index 975dc5a66549..74a6d55259af 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c | |||
@@ -817,6 +817,7 @@ static union drbd_state sanitize_state(struct drbd_conf *mdev, union drbd_state | |||
817 | union drbd_state ns, const char **warn_sync_abort) | 817 | union drbd_state ns, const char **warn_sync_abort) |
818 | { | 818 | { |
819 | enum drbd_fencing_p fp; | 819 | enum drbd_fencing_p fp; |
820 | enum drbd_disk_state disk_min, disk_max, pdsk_min, pdsk_max; | ||
820 | 821 | ||
821 | fp = FP_DONT_CARE; | 822 | fp = FP_DONT_CARE; |
822 | if (get_ldev(mdev)) { | 823 | if (get_ldev(mdev)) { |
@@ -869,61 +870,6 @@ static union drbd_state sanitize_state(struct drbd_conf *mdev, union drbd_state | |||
869 | ns.conn = C_CONNECTED; | 870 | ns.conn = C_CONNECTED; |
870 | } | 871 | } |
871 | 872 | ||
872 | if (ns.conn >= C_CONNECTED && | ||
873 | ((ns.disk == D_CONSISTENT || ns.disk == D_OUTDATED) || | ||
874 | (ns.disk == D_NEGOTIATING && ns.conn == C_WF_BITMAP_T) || | ||
875 | ns.conn >= C_AHEAD)) { | ||
876 | switch (ns.conn) { | ||
877 | case C_WF_BITMAP_T: | ||
878 | case C_PAUSED_SYNC_T: | ||
879 | case C_BEHIND: | ||
880 | ns.disk = D_OUTDATED; | ||
881 | break; | ||
882 | case C_CONNECTED: | ||
883 | case C_WF_BITMAP_S: | ||
884 | case C_SYNC_SOURCE: | ||
885 | case C_PAUSED_SYNC_S: | ||
886 | case C_AHEAD: | ||
887 | ns.disk = D_UP_TO_DATE; | ||
888 | break; | ||
889 | case C_SYNC_TARGET: | ||
890 | ns.disk = D_INCONSISTENT; | ||
891 | dev_warn(DEV, "Implicitly set disk state Inconsistent!\n"); | ||
892 | break; | ||
893 | } | ||
894 | if (os.disk == D_OUTDATED && ns.disk == D_UP_TO_DATE) | ||
895 | dev_warn(DEV, "Implicitly set disk from Outdated to UpToDate\n"); | ||
896 | } | ||
897 | |||
898 | if (ns.conn >= C_CONNECTED && | ||
899 | (ns.pdsk == D_CONSISTENT || ns.pdsk == D_OUTDATED || ns.conn >= C_AHEAD)) { | ||
900 | switch (ns.conn) { | ||
901 | case C_CONNECTED: | ||
902 | case C_WF_BITMAP_T: | ||
903 | case C_PAUSED_SYNC_T: | ||
904 | case C_SYNC_TARGET: | ||
905 | case C_BEHIND: | ||
906 | ns.pdsk = D_UP_TO_DATE; | ||
907 | break; | ||
908 | case C_WF_BITMAP_S: | ||
909 | case C_PAUSED_SYNC_S: | ||
910 | case C_AHEAD: | ||
911 | /* remap any consistent state to D_OUTDATED, | ||
912 | * but disallow "upgrade" of not even consistent states. | ||
913 | */ | ||
914 | ns.pdsk = | ||
915 | (D_DISKLESS < os.pdsk && os.pdsk < D_OUTDATED) | ||
916 | ? os.pdsk : D_OUTDATED; | ||
917 | break; | ||
918 | case C_SYNC_SOURCE: | ||
919 | ns.pdsk = D_INCONSISTENT; | ||
920 | dev_warn(DEV, "Implicitly set pdsk Inconsistent!\n"); | ||
921 | break; | ||
922 | } | ||
923 | if (os.pdsk == D_OUTDATED && ns.pdsk == D_UP_TO_DATE) | ||
924 | dev_warn(DEV, "Implicitly set pdsk from Outdated to UpToDate\n"); | ||
925 | } | ||
926 | |||
927 | /* Connection breaks down before we finished "Negotiating" */ | 873 | /* Connection breaks down before we finished "Negotiating" */ |
928 | if (ns.conn < C_CONNECTED && ns.disk == D_NEGOTIATING && | 874 | if (ns.conn < C_CONNECTED && ns.disk == D_NEGOTIATING && |
929 | get_ldev_if_state(mdev, D_NEGOTIATING)) { | 875 | get_ldev_if_state(mdev, D_NEGOTIATING)) { |
@@ -938,6 +884,94 @@ static union drbd_state sanitize_state(struct drbd_conf *mdev, union drbd_state | |||
938 | put_ldev(mdev); | 884 | put_ldev(mdev); |
939 | } | 885 | } |
940 | 886 | ||
887 | /* D_CONSISTENT and D_OUTDATED vanish when we get connected */ | ||
888 | if (ns.conn >= C_CONNECTED && ns.conn < C_AHEAD) { | ||
889 | if (ns.disk == D_CONSISTENT || ns.disk == D_OUTDATED) | ||
890 | ns.disk = D_UP_TO_DATE; | ||
891 | if (ns.pdsk == D_CONSISTENT || ns.pdsk == D_OUTDATED) | ||
892 | ns.pdsk = D_UP_TO_DATE; | ||
893 | } | ||
894 | |||
895 | /* Implications of the connection stat on the disk states */ | ||
896 | disk_min = D_DISKLESS; | ||
897 | disk_max = D_UP_TO_DATE; | ||
898 | pdsk_min = D_INCONSISTENT; | ||
899 | pdsk_max = D_UNKNOWN; | ||
900 | switch ((enum drbd_conns)ns.conn) { | ||
901 | case C_WF_BITMAP_T: | ||
902 | case C_PAUSED_SYNC_T: | ||
903 | case C_STARTING_SYNC_T: | ||
904 | case C_WF_SYNC_UUID: | ||
905 | case C_BEHIND: | ||
906 | disk_min = D_INCONSISTENT; | ||
907 | disk_max = D_OUTDATED; | ||
908 | pdsk_min = D_UP_TO_DATE; | ||
909 | pdsk_max = D_UP_TO_DATE; | ||
910 | break; | ||
911 | case C_VERIFY_S: | ||
912 | case C_VERIFY_T: | ||
913 | disk_min = D_UP_TO_DATE; | ||
914 | disk_max = D_UP_TO_DATE; | ||
915 | pdsk_min = D_UP_TO_DATE; | ||
916 | pdsk_max = D_UP_TO_DATE; | ||
917 | break; | ||
918 | case C_CONNECTED: | ||
919 | disk_min = D_DISKLESS; | ||
920 | disk_max = D_UP_TO_DATE; | ||
921 | pdsk_min = D_DISKLESS; | ||
922 | pdsk_max = D_UP_TO_DATE; | ||
923 | break; | ||
924 | case C_WF_BITMAP_S: | ||
925 | case C_PAUSED_SYNC_S: | ||
926 | case C_STARTING_SYNC_S: | ||
927 | case C_AHEAD: | ||
928 | disk_min = D_UP_TO_DATE; | ||
929 | disk_max = D_UP_TO_DATE; | ||
930 | pdsk_min = D_INCONSISTENT; | ||
931 | pdsk_max = D_CONSISTENT; /* D_OUTDATED would be nice. But explicit outdate necessary*/ | ||
932 | break; | ||
933 | case C_SYNC_TARGET: | ||
934 | disk_min = D_INCONSISTENT; | ||
935 | disk_max = D_INCONSISTENT; | ||
936 | pdsk_min = D_UP_TO_DATE; | ||
937 | pdsk_max = D_UP_TO_DATE; | ||
938 | break; | ||
939 | case C_SYNC_SOURCE: | ||
940 | disk_min = D_UP_TO_DATE; | ||
941 | disk_max = D_UP_TO_DATE; | ||
942 | pdsk_min = D_INCONSISTENT; | ||
943 | pdsk_max = D_INCONSISTENT; | ||
944 | break; | ||
945 | case C_STANDALONE: | ||
946 | case C_DISCONNECTING: | ||
947 | case C_UNCONNECTED: | ||
948 | case C_TIMEOUT: | ||
949 | case C_BROKEN_PIPE: | ||
950 | case C_NETWORK_FAILURE: | ||
951 | case C_PROTOCOL_ERROR: | ||
952 | case C_TEAR_DOWN: | ||
953 | case C_WF_CONNECTION: | ||
954 | case C_WF_REPORT_PARAMS: | ||
955 | case C_MASK: | ||
956 | break; | ||
957 | } | ||
958 | if (ns.disk > disk_max) | ||
959 | ns.disk = disk_max; | ||
960 | |||
961 | if (ns.disk < disk_min) { | ||
962 | dev_warn(DEV, "Implicitly set disk from %s to %s\n", | ||
963 | drbd_disk_str(ns.disk), drbd_disk_str(disk_min)); | ||
964 | ns.disk = disk_min; | ||
965 | } | ||
966 | if (ns.pdsk > pdsk_max) | ||
967 | ns.pdsk = pdsk_max; | ||
968 | |||
969 | if (ns.pdsk < pdsk_min) { | ||
970 | dev_warn(DEV, "Implicitly set pdsk from %s to %s\n", | ||
971 | drbd_disk_str(ns.pdsk), drbd_disk_str(pdsk_min)); | ||
972 | ns.pdsk = pdsk_min; | ||
973 | } | ||
974 | |||
941 | if (fp == FP_STONITH && | 975 | if (fp == FP_STONITH && |
942 | (ns.role == R_PRIMARY && ns.conn < C_CONNECTED && ns.pdsk > D_OUTDATED) && | 976 | (ns.role == R_PRIMARY && ns.conn < C_CONNECTED && ns.pdsk > D_OUTDATED) && |
943 | !(os.role == R_PRIMARY && os.conn < C_CONNECTED && os.pdsk > D_OUTDATED)) | 977 | !(os.role == R_PRIMARY && os.conn < C_CONNECTED && os.pdsk > D_OUTDATED)) |