aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/drbd
diff options
context:
space:
mode:
authorPhilipp Reisner <philipp.reisner@linbit.com>2010-11-17 10:54:36 -0500
committerPhilipp Reisner <philipp.reisner@linbit.com>2011-03-10 05:35:04 -0500
commitab17b68f4579b460753a416b0afc4446381d876f (patch)
tree78c88ce883d2c1e721171611f0899b159b24f290 /drivers/block/drbd
parent22afd7ee94c1c5857323b677267ba8bace09bcef (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.c144
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))