aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilipp Reisner <philipp.reisner@linbit.com>2010-10-27 06:21:30 -0400
committerPhilipp Reisner <philipp.reisner@linbit.com>2011-03-10 05:34:46 -0500
commit67531718d8f1259f01ab84c2aa25f7b03c7afd46 (patch)
tree6f76323440f8ce3793b5d5f1a19808207f38db5b
parent422028b1ca4c07995af82a18abced022ff4c296c (diff)
drbd: Implemented two new connection states Ahead/Behind
In this connection mode, the ahead node no longer replicates application IO. The behind's disk becomes out dated. Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com> Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
-rw-r--r--drivers/block/drbd/drbd_int.h2
-rw-r--r--drivers/block/drbd/drbd_main.c12
-rw-r--r--drivers/block/drbd/drbd_receiver.c3
-rw-r--r--drivers/block/drbd/drbd_req.c23
-rw-r--r--drivers/block/drbd/drbd_strings.c4
-rw-r--r--include/linux/drbd.h4
6 files changed, 45 insertions, 3 deletions
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index c804e44b9455..21b7439438cd 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -2217,6 +2217,8 @@ static inline int drbd_state_is_stable(union drbd_state s)
2217 case C_VERIFY_T: 2217 case C_VERIFY_T:
2218 case C_PAUSED_SYNC_S: 2218 case C_PAUSED_SYNC_S:
2219 case C_PAUSED_SYNC_T: 2219 case C_PAUSED_SYNC_T:
2220 case C_AHEAD:
2221 case C_BEHIND:
2220 /* maybe stable, look at the disk state */ 2222 /* maybe stable, look at the disk state */
2221 break; 2223 break;
2222 2224
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index e81d009dd061..46f27d6c0b21 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -871,16 +871,19 @@ static union drbd_state sanitize_state(struct drbd_conf *mdev, union drbd_state
871 871
872 if (ns.conn >= C_CONNECTED && 872 if (ns.conn >= C_CONNECTED &&
873 ((ns.disk == D_CONSISTENT || ns.disk == D_OUTDATED) || 873 ((ns.disk == D_CONSISTENT || ns.disk == D_OUTDATED) ||
874 (ns.disk == D_NEGOTIATING && ns.conn == C_WF_BITMAP_T))) { 874 (ns.disk == D_NEGOTIATING && ns.conn == C_WF_BITMAP_T) ||
875 ns.conn >= C_AHEAD)) {
875 switch (ns.conn) { 876 switch (ns.conn) {
876 case C_WF_BITMAP_T: 877 case C_WF_BITMAP_T:
877 case C_PAUSED_SYNC_T: 878 case C_PAUSED_SYNC_T:
879 case C_BEHIND:
878 ns.disk = D_OUTDATED; 880 ns.disk = D_OUTDATED;
879 break; 881 break;
880 case C_CONNECTED: 882 case C_CONNECTED:
881 case C_WF_BITMAP_S: 883 case C_WF_BITMAP_S:
882 case C_SYNC_SOURCE: 884 case C_SYNC_SOURCE:
883 case C_PAUSED_SYNC_S: 885 case C_PAUSED_SYNC_S:
886 case C_AHEAD:
884 ns.disk = D_UP_TO_DATE; 887 ns.disk = D_UP_TO_DATE;
885 break; 888 break;
886 case C_SYNC_TARGET: 889 case C_SYNC_TARGET:
@@ -893,16 +896,18 @@ static union drbd_state sanitize_state(struct drbd_conf *mdev, union drbd_state
893 } 896 }
894 897
895 if (ns.conn >= C_CONNECTED && 898 if (ns.conn >= C_CONNECTED &&
896 (ns.pdsk == D_CONSISTENT || ns.pdsk == D_OUTDATED)) { 899 (ns.pdsk == D_CONSISTENT || ns.pdsk == D_OUTDATED || ns.conn >= C_AHEAD)) {
897 switch (ns.conn) { 900 switch (ns.conn) {
898 case C_CONNECTED: 901 case C_CONNECTED:
899 case C_WF_BITMAP_T: 902 case C_WF_BITMAP_T:
900 case C_PAUSED_SYNC_T: 903 case C_PAUSED_SYNC_T:
901 case C_SYNC_TARGET: 904 case C_SYNC_TARGET:
905 case C_BEHIND:
902 ns.pdsk = D_UP_TO_DATE; 906 ns.pdsk = D_UP_TO_DATE;
903 break; 907 break;
904 case C_WF_BITMAP_S: 908 case C_WF_BITMAP_S:
905 case C_PAUSED_SYNC_S: 909 case C_PAUSED_SYNC_S:
910 case C_AHEAD:
906 /* remap any consistent state to D_OUTDATED, 911 /* remap any consistent state to D_OUTDATED,
907 * but disallow "upgrade" of not even consistent states. 912 * but disallow "upgrade" of not even consistent states.
908 */ 913 */
@@ -1374,6 +1379,9 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
1374 if (os.conn == C_WF_REPORT_PARAMS && ns.conn >= C_CONNECTED) 1379 if (os.conn == C_WF_REPORT_PARAMS && ns.conn >= C_CONNECTED)
1375 drbd_send_state(mdev); 1380 drbd_send_state(mdev);
1376 1381
1382 if (os.conn != C_AHEAD && ns.conn == C_AHEAD)
1383 drbd_send_state(mdev);
1384
1377 /* We are in the progress to start a full sync... */ 1385 /* We are in the progress to start a full sync... */
1378 if ((os.conn != C_STARTING_SYNC_T && ns.conn == C_STARTING_SYNC_T) || 1386 if ((os.conn != C_STARTING_SYNC_T && ns.conn == C_STARTING_SYNC_T) ||
1379 (os.conn != C_STARTING_SYNC_S && ns.conn == C_STARTING_SYNC_S)) 1387 (os.conn != C_STARTING_SYNC_S && ns.conn == C_STARTING_SYNC_S))
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index f3052d871d31..b19e8b2c4ce5 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -3179,6 +3179,9 @@ static int receive_state(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned
3179 if (ns.conn == C_WF_REPORT_PARAMS) 3179 if (ns.conn == C_WF_REPORT_PARAMS)
3180 ns.conn = C_CONNECTED; 3180 ns.conn = C_CONNECTED;
3181 3181
3182 if (peer_state.conn == C_AHEAD)
3183 ns.conn = C_BEHIND;
3184
3182 if (mdev->p_uuid && peer_state.disk >= D_NEGOTIATING && 3185 if (mdev->p_uuid && peer_state.disk >= D_NEGOTIATING &&
3183 get_ldev_if_state(mdev, D_NEGOTIATING)) { 3186 get_ldev_if_state(mdev, D_NEGOTIATING)) {
3184 int cr; /* consider resync */ 3187 int cr; /* consider resync */
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c
index 5c60d77d447c..60288fb3c4d7 100644
--- a/drivers/block/drbd/drbd_req.c
+++ b/drivers/block/drbd/drbd_req.c
@@ -948,6 +948,29 @@ allocate_barrier:
948 ? queue_for_net_write 948 ? queue_for_net_write
949 : queue_for_net_read); 949 : queue_for_net_read);
950 } 950 }
951
952 if (remote && mdev->net_conf->on_congestion != OC_BLOCK) {
953 int congested = 0;
954
955 if (mdev->net_conf->cong_fill &&
956 atomic_read(&mdev->ap_in_flight) >= mdev->net_conf->cong_fill) {
957 dev_info(DEV, "Congestion-fill threshold reached\n");
958 congested = 1;
959 }
960
961 if (mdev->act_log->used >= mdev->net_conf->cong_extents) {
962 dev_info(DEV, "Congestion-extents threshold reached\n");
963 congested = 1;
964 }
965
966 if (congested) {
967 if (mdev->net_conf->on_congestion == OC_PULL_AHEAD)
968 _drbd_set_state(_NS(mdev, conn, C_AHEAD), 0, NULL);
969 else /*mdev->net_conf->on_congestion == OC_DISCONNECT */
970 _drbd_set_state(_NS(mdev, conn, C_DISCONNECTING), 0, NULL);
971 }
972 }
973
951 spin_unlock_irq(&mdev->req_lock); 974 spin_unlock_irq(&mdev->req_lock);
952 kfree(b); /* if someone else has beaten us to it... */ 975 kfree(b); /* if someone else has beaten us to it... */
953 976
diff --git a/drivers/block/drbd/drbd_strings.c b/drivers/block/drbd/drbd_strings.c
index 85179e1fb50a..5b970adc3b6f 100644
--- a/drivers/block/drbd/drbd_strings.c
+++ b/drivers/block/drbd/drbd_strings.c
@@ -48,6 +48,8 @@ static const char *drbd_conn_s_names[] = {
48 [C_PAUSED_SYNC_T] = "PausedSyncT", 48 [C_PAUSED_SYNC_T] = "PausedSyncT",
49 [C_VERIFY_S] = "VerifyS", 49 [C_VERIFY_S] = "VerifyS",
50 [C_VERIFY_T] = "VerifyT", 50 [C_VERIFY_T] = "VerifyT",
51 [C_AHEAD] = "Ahead",
52 [C_BEHIND] = "Behind",
51}; 53};
52 54
53static const char *drbd_role_s_names[] = { 55static const char *drbd_role_s_names[] = {
@@ -92,7 +94,7 @@ static const char *drbd_state_sw_errors[] = {
92const char *drbd_conn_str(enum drbd_conns s) 94const char *drbd_conn_str(enum drbd_conns s)
93{ 95{
94 /* enums are unsigned... */ 96 /* enums are unsigned... */
95 return s > C_PAUSED_SYNC_T ? "TOO_LARGE" : drbd_conn_s_names[s]; 97 return s > C_BEHIND ? "TOO_LARGE" : drbd_conn_s_names[s];
96} 98}
97 99
98const char *drbd_role_str(enum drbd_role s) 100const char *drbd_role_str(enum drbd_role s)
diff --git a/include/linux/drbd.h b/include/linux/drbd.h
index 03a08baabf11..23f31be6f00d 100644
--- a/include/linux/drbd.h
+++ b/include/linux/drbd.h
@@ -206,6 +206,10 @@ enum drbd_conns {
206 C_VERIFY_T, 206 C_VERIFY_T,
207 C_PAUSED_SYNC_S, 207 C_PAUSED_SYNC_S,
208 C_PAUSED_SYNC_T, 208 C_PAUSED_SYNC_T,
209
210 C_AHEAD,
211 C_BEHIND,
212
209 C_MASK = 31 213 C_MASK = 31
210}; 214};
211 215