aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/drbd/drbd_nl.c
diff options
context:
space:
mode:
authorPhilipp Reisner <philipp.reisner@linbit.com>2010-09-08 17:20:21 -0400
committerPhilipp Reisner <philipp.reisner@linbit.com>2010-10-14 12:38:40 -0400
commitfb22c402ffdf61dd121795b5809de587185d5240 (patch)
tree7c3de5410eff21b3a3b105dc63d5e2034f2c7c63 /drivers/block/drbd/drbd_nl.c
parent78db89287ce0f146a1f2a019a0b243ea4557caac (diff)
drbd: Track the reasons to suspend IO in dedicated state bits
There are three ways to get IO suspended: * Loss of any access to data * Fence-peer-handler running * User requested to suspend IO Track those in different bits, so that one condition clearing its state bit does not interfere with the other two conditions. Only when the user resumes IO he overrules all three bits. The fact is hidden from the user, he sees only a single suspend bit. Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com> Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
Diffstat (limited to 'drivers/block/drbd/drbd_nl.c')
-rw-r--r--drivers/block/drbd/drbd_nl.c20
1 files changed, 14 insertions, 6 deletions
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index 5b30f90cab3e..9ee44568dce3 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -209,7 +209,8 @@ enum drbd_disk_state drbd_try_outdate_peer(struct drbd_conf *mdev)
209 put_ldev(mdev); 209 put_ldev(mdev);
210 } else { 210 } else {
211 dev_warn(DEV, "Not fencing peer, I'm not even Consistent myself.\n"); 211 dev_warn(DEV, "Not fencing peer, I'm not even Consistent myself.\n");
212 return mdev->state.pdsk; 212 nps = mdev->state.pdsk;
213 goto out;
213 } 214 }
214 215
215 r = drbd_khelper(mdev, "fence-peer"); 216 r = drbd_khelper(mdev, "fence-peer");
@@ -256,6 +257,14 @@ enum drbd_disk_state drbd_try_outdate_peer(struct drbd_conf *mdev)
256 257
257 dev_info(DEV, "fence-peer helper returned %d (%s)\n", 258 dev_info(DEV, "fence-peer helper returned %d (%s)\n",
258 (r>>8) & 0xff, ex_to_string); 259 (r>>8) & 0xff, ex_to_string);
260
261out:
262 if (mdev->state.susp_fen && nps >= D_UNKNOWN) {
263 /* The handler was not successful... unfreeze here, the
264 state engine can not unfreeze... */
265 _drbd_request_state(mdev, NS(susp_fen, 0), CS_VERBOSE);
266 }
267
259 return nps; 268 return nps;
260} 269}
261 270
@@ -550,7 +559,7 @@ char *ppsize(char *buf, unsigned long long size)
550void drbd_suspend_io(struct drbd_conf *mdev) 559void drbd_suspend_io(struct drbd_conf *mdev)
551{ 560{
552 set_bit(SUSPEND_IO, &mdev->flags); 561 set_bit(SUSPEND_IO, &mdev->flags);
553 if (mdev->state.susp) 562 if (is_susp(mdev->state))
554 return; 563 return;
555 wait_event(mdev->misc_wait, !atomic_read(&mdev->ap_bio_cnt)); 564 wait_event(mdev->misc_wait, !atomic_read(&mdev->ap_bio_cnt));
556} 565}
@@ -1016,7 +1025,7 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp
1016 1025
1017 drbd_suspend_io(mdev); 1026 drbd_suspend_io(mdev);
1018 /* also wait for the last barrier ack. */ 1027 /* also wait for the last barrier ack. */
1019 wait_event(mdev->misc_wait, !atomic_read(&mdev->ap_pending_cnt) || mdev->state.susp); 1028 wait_event(mdev->misc_wait, !atomic_read(&mdev->ap_pending_cnt) || is_susp(mdev->state));
1020 /* and for any other previously queued work */ 1029 /* and for any other previously queued work */
1021 drbd_flush_workqueue(mdev); 1030 drbd_flush_workqueue(mdev);
1022 1031
@@ -1114,8 +1123,7 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp
1114 clear_bit(CRASHED_PRIMARY, &mdev->flags); 1123 clear_bit(CRASHED_PRIMARY, &mdev->flags);
1115 1124
1116 if (drbd_md_test_flag(mdev->ldev, MDF_PRIMARY_IND) && 1125 if (drbd_md_test_flag(mdev->ldev, MDF_PRIMARY_IND) &&
1117 !(mdev->state.role == R_PRIMARY && mdev->state.susp && 1126 !(mdev->state.role == R_PRIMARY && mdev->state.susp_nod)) {
1118 mdev->sync_conf.on_no_data == OND_SUSPEND_IO)) {
1119 set_bit(CRASHED_PRIMARY, &mdev->flags); 1127 set_bit(CRASHED_PRIMARY, &mdev->flags);
1120 cp_discovered = 1; 1128 cp_discovered = 1;
1121 } 1129 }
@@ -1939,7 +1947,7 @@ static int drbd_nl_resume_io(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp
1939 drbd_md_sync(mdev); 1947 drbd_md_sync(mdev);
1940 } 1948 }
1941 drbd_suspend_io(mdev); 1949 drbd_suspend_io(mdev);
1942 reply->ret_code = drbd_request_state(mdev, NS(susp, 0)); 1950 reply->ret_code = drbd_request_state(mdev, NS3(susp, 0, susp_nod, 0, susp_fen, 0));
1943 if (reply->ret_code == SS_SUCCESS) { 1951 if (reply->ret_code == SS_SUCCESS) {
1944 if (mdev->state.conn < C_CONNECTED) 1952 if (mdev->state.conn < C_CONNECTED)
1945 tl_clear(mdev); 1953 tl_clear(mdev);