diff options
author | Philipp Reisner <philipp.reisner@linbit.com> | 2010-05-31 04:14:17 -0400 |
---|---|---|
committer | Philipp Reisner <philipp.reisner@linbit.com> | 2010-10-14 08:52:53 -0400 |
commit | 265be2d09853d425ad14a61cda0ca63345613d0c (patch) | |
tree | cc2f419d8aaa41fd088f3d24ca134c4d7f51aa64 /drivers/block/drbd/drbd_main.c | |
parent | 905cd7d8ac9b18e1f122b90dbebe1246b1c364fd (diff) |
drbd: Finished the "on-no-data-accessible suspend-io;" functionality
When no data is accessible (no connection to the peer, nor a local disk)
allow the user to select to freeze all IO operations instead of getting
IO errors.
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_main.c')
-rw-r--r-- | drivers/block/drbd/drbd_main.c | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index 7d359863ae32..106b9abdc430 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c | |||
@@ -925,7 +925,12 @@ static union drbd_state sanitize_state(struct drbd_conf *mdev, union drbd_state | |||
925 | if (fp == FP_STONITH && | 925 | if (fp == FP_STONITH && |
926 | (ns.role == R_PRIMARY && ns.conn < C_CONNECTED && ns.pdsk > D_OUTDATED) && | 926 | (ns.role == R_PRIMARY && ns.conn < C_CONNECTED && ns.pdsk > D_OUTDATED) && |
927 | !(os.role == R_PRIMARY && os.conn < C_CONNECTED && os.pdsk > D_OUTDATED)) | 927 | !(os.role == R_PRIMARY && os.conn < C_CONNECTED && os.pdsk > D_OUTDATED)) |
928 | ns.susp = 1; | 928 | ns.susp = 1; /* Suspend IO while fence-peer handler runs (peer lost) */ |
929 | |||
930 | if (mdev->sync_conf.on_no_data == OND_SUSPEND_IO && | ||
931 | (ns.role == R_PRIMARY && ns.disk < D_UP_TO_DATE && ns.pdsk < D_UP_TO_DATE) && | ||
932 | !(os.role == R_PRIMARY && os.disk < D_UP_TO_DATE && os.pdsk < D_UP_TO_DATE)) | ||
933 | ns.susp = 1; /* Suspend IO while no data available (no accessible data available) */ | ||
929 | 934 | ||
930 | if (ns.aftr_isp || ns.peer_isp || ns.user_isp) { | 935 | if (ns.aftr_isp || ns.peer_isp || ns.user_isp) { |
931 | if (ns.conn == C_SYNC_SOURCE) | 936 | if (ns.conn == C_SYNC_SOURCE) |
@@ -1236,6 +1241,25 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os, | |||
1236 | /* Here we have the actions that are performed after a | 1241 | /* Here we have the actions that are performed after a |
1237 | state change. This function might sleep */ | 1242 | state change. This function might sleep */ |
1238 | 1243 | ||
1244 | if (os.susp && ns.susp && mdev->sync_conf.on_no_data == OND_SUSPEND_IO) { | ||
1245 | if (os.conn < C_CONNECTED && ns.conn >= C_CONNECTED) { | ||
1246 | if (ns.conn == C_CONNECTED) { | ||
1247 | spin_lock_irq(&mdev->req_lock); | ||
1248 | _tl_restart(mdev, resend); | ||
1249 | _drbd_set_state(_NS(mdev, susp, 0), CS_VERBOSE, NULL); | ||
1250 | spin_unlock_irq(&mdev->req_lock); | ||
1251 | } else /* ns.conn > C_CONNECTED */ | ||
1252 | dev_err(DEV, "Unexpected Resynd going on!\n"); | ||
1253 | } | ||
1254 | |||
1255 | if (os.disk == D_ATTACHING && ns.disk > D_ATTACHING) { | ||
1256 | spin_lock_irq(&mdev->req_lock); | ||
1257 | _tl_restart(mdev, restart_frozen_disk_io); | ||
1258 | _drbd_set_state(_NS(mdev, susp, 0), CS_VERBOSE, NULL); | ||
1259 | spin_unlock_irq(&mdev->req_lock); | ||
1260 | } | ||
1261 | } | ||
1262 | |||
1239 | if (fp == FP_STONITH && ns.susp) { | 1263 | if (fp == FP_STONITH && ns.susp) { |
1240 | /* case1: The outdate peer handler is successful: | 1264 | /* case1: The outdate peer handler is successful: |
1241 | * case2: The connection was established again: */ | 1265 | * case2: The connection was established again: */ |