aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Ellenberg <lars.ellenberg@linbit.com>2012-09-27 07:03:45 -0400
committerJens Axboe <axboe@kernel.dk>2012-10-30 03:39:18 -0400
commit44edfb0d785ea06712b5a717fa2c1ae34e300845 (patch)
treeb886731330dc8b153f033d7c16729c47b146a026
parent8b45a5c8a190d0ea0077928fd8e95c0752e40e41 (diff)
drbd: wait for meta data IO completion even with failed disk, unless force-detached
The intention of force-detach is to be able to deal with a completely unresponsive lower level IO stack, which does not even deliver error completions anymore, but no completion at all. In all other cases, we must still wait for the meta data IO completion. Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com> Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
-rw-r--r--drivers/block/drbd/drbd_actlog.c17
-rw-r--r--drivers/block/drbd/drbd_bitmap.c8
-rw-r--r--drivers/block/drbd/drbd_int.h4
3 files changed, 13 insertions, 16 deletions
diff --git a/drivers/block/drbd/drbd_actlog.c b/drivers/block/drbd/drbd_actlog.c
index 3fbef018ce55..ec9b10cd65dd 100644
--- a/drivers/block/drbd/drbd_actlog.c
+++ b/drivers/block/drbd/drbd_actlog.c
@@ -82,22 +82,19 @@ void drbd_md_put_buffer(struct drbd_conf *mdev)
82 wake_up(&mdev->misc_wait); 82 wake_up(&mdev->misc_wait);
83} 83}
84 84
85static bool md_io_allowed(struct drbd_conf *mdev) 85void wait_until_done_or_force_detached(struct drbd_conf *mdev, struct drbd_backing_dev *bdev,
86{
87 enum drbd_disk_state ds = mdev->state.disk;
88 return ds >= D_NEGOTIATING || ds == D_ATTACHING;
89}
90
91void wait_until_done_or_disk_failure(struct drbd_conf *mdev, struct drbd_backing_dev *bdev,
92 unsigned int *done) 86 unsigned int *done)
93{ 87{
94 long dt = bdev->dc.disk_timeout * HZ / 10; 88 long dt = bdev->dc.disk_timeout * HZ / 10;
95 if (dt == 0) 89 if (dt == 0)
96 dt = MAX_SCHEDULE_TIMEOUT; 90 dt = MAX_SCHEDULE_TIMEOUT;
97 91
98 dt = wait_event_timeout(mdev->misc_wait, *done || !md_io_allowed(mdev), dt); 92 dt = wait_event_timeout(mdev->misc_wait,
99 if (dt == 0) 93 *done || test_bit(FORCE_DETACH, &mdev->flags), dt);
94 if (dt == 0) {
100 dev_err(DEV, "meta-data IO operation timed out\n"); 95 dev_err(DEV, "meta-data IO operation timed out\n");
96 drbd_chk_io_error(mdev, 1, DRBD_FORCE_DETACH);
97 }
101} 98}
102 99
103static int _drbd_md_sync_page_io(struct drbd_conf *mdev, 100static int _drbd_md_sync_page_io(struct drbd_conf *mdev,
@@ -137,7 +134,7 @@ static int _drbd_md_sync_page_io(struct drbd_conf *mdev,
137 bio_endio(bio, -EIO); 134 bio_endio(bio, -EIO);
138 else 135 else
139 submit_bio(rw, bio); 136 submit_bio(rw, bio);
140 wait_until_done_or_disk_failure(mdev, bdev, &mdev->md_io.done); 137 wait_until_done_or_force_detached(mdev, bdev, &mdev->md_io.done);
141 ok = bio_flagged(bio, BIO_UPTODATE) && mdev->md_io.error == 0; 138 ok = bio_flagged(bio, BIO_UPTODATE) && mdev->md_io.error == 0;
142 139
143 out: 140 out:
diff --git a/drivers/block/drbd/drbd_bitmap.c b/drivers/block/drbd/drbd_bitmap.c
index dda4e384929e..8d8069758042 100644
--- a/drivers/block/drbd/drbd_bitmap.c
+++ b/drivers/block/drbd/drbd_bitmap.c
@@ -1090,7 +1090,7 @@ static int bm_rw(struct drbd_conf *mdev, int rw, unsigned flags, unsigned lazy_w
1090 * "in_flight reached zero, all done" event. 1090 * "in_flight reached zero, all done" event.
1091 */ 1091 */
1092 if (!atomic_dec_and_test(&ctx->in_flight)) 1092 if (!atomic_dec_and_test(&ctx->in_flight))
1093 wait_until_done_or_disk_failure(mdev, mdev->ldev, &ctx->done); 1093 wait_until_done_or_force_detached(mdev, mdev->ldev, &ctx->done);
1094 else 1094 else
1095 kref_put(&ctx->kref, &bm_aio_ctx_destroy); 1095 kref_put(&ctx->kref, &bm_aio_ctx_destroy);
1096 1096
@@ -1105,7 +1105,7 @@ static int bm_rw(struct drbd_conf *mdev, int rw, unsigned flags, unsigned lazy_w
1105 } 1105 }
1106 1106
1107 if (atomic_read(&ctx->in_flight)) 1107 if (atomic_read(&ctx->in_flight))
1108 err = -EIO; /* Disk failed during IO... */ 1108 err = -EIO; /* Disk timeout/force-detach during IO... */
1109 1109
1110 now = jiffies; 1110 now = jiffies;
1111 if (rw == WRITE) { 1111 if (rw == WRITE) {
@@ -1224,11 +1224,11 @@ int drbd_bm_write_page(struct drbd_conf *mdev, unsigned int idx) __must_hold(loc
1224 } 1224 }
1225 1225
1226 bm_page_io_async(ctx, idx, WRITE_SYNC); 1226 bm_page_io_async(ctx, idx, WRITE_SYNC);
1227 wait_until_done_or_disk_failure(mdev, mdev->ldev, &ctx->done); 1227 wait_until_done_or_force_detached(mdev, mdev->ldev, &ctx->done);
1228 1228
1229 if (ctx->error) 1229 if (ctx->error)
1230 drbd_chk_io_error(mdev, 1, DRBD_META_IO_ERROR); 1230 drbd_chk_io_error(mdev, 1, DRBD_META_IO_ERROR);
1231 /* that should force detach, so the in memory bitmap will be 1231 /* that causes us to detach, so the in memory bitmap will be
1232 * gone in a moment as well. */ 1232 * gone in a moment as well. */
1233 1233
1234 mdev->bm_writ_cnt++; 1234 mdev->bm_writ_cnt++;
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 557dd5a2c0cc..619a4944feea 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -1581,8 +1581,8 @@ extern void *drbd_md_get_buffer(struct drbd_conf *mdev);
1581extern void drbd_md_put_buffer(struct drbd_conf *mdev); 1581extern void drbd_md_put_buffer(struct drbd_conf *mdev);
1582extern int drbd_md_sync_page_io(struct drbd_conf *mdev, 1582extern int drbd_md_sync_page_io(struct drbd_conf *mdev,
1583 struct drbd_backing_dev *bdev, sector_t sector, int rw); 1583 struct drbd_backing_dev *bdev, sector_t sector, int rw);
1584extern void wait_until_done_or_disk_failure(struct drbd_conf *mdev, struct drbd_backing_dev *bdev, 1584extern void wait_until_done_or_force_detached(struct drbd_conf *mdev,
1585 unsigned int *done); 1585 struct drbd_backing_dev *bdev, unsigned int *done);
1586extern void drbd_ov_oos_found(struct drbd_conf*, sector_t, int); 1586extern void drbd_ov_oos_found(struct drbd_conf*, sector_t, int);
1587extern void drbd_rs_controller_reset(struct drbd_conf *mdev); 1587extern void drbd_rs_controller_reset(struct drbd_conf *mdev);
1588 1588