aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/drbd/drbd_req.c
diff options
context:
space:
mode:
authorLars Ellenberg <lars.ellenberg@linbit.com>2012-09-27 09:18:21 -0400
committerPhilipp Reisner <philipp.reisner@linbit.com>2012-11-09 08:11:41 -0500
commitedc9f5eb7afa3d832f540fcfe10e3e1087e6f527 (patch)
treeeba63d771575a42a6aa81bd55a59f7d6253d18ea /drivers/block/drbd/drbd_req.c
parente34b677d09ce375a87acd0360537cbed33881b0c (diff)
drbd: always write bitmap on detach
If we detach due to local read-error (which sets a bit in the bitmap), stay Primary, and then re-attach (which re-reads the bitmap from disk), we potentially lost the "out-of-sync" (or, "bad block") information in the bitmap. Always (try to) write out the changed bitmap pages before going diskless. That way, we don't lose the bit for the bad block, the next resync will fetch it from the peer, and rewrite it locally, which may result in block reallocation in some lower layer (or the hardware), and thereby "heal" the bad blocks. If the bitmap writeout errors out as well, we will (again: try to) mark the "we need a full sync" bit in our super block, if it was a READ error; writes are covered by the activity log already. If that superblock does not make it to disk either, we are sorry. Maybe we just lost an entire disk or controller (or iSCSI connection), and there actually are no bad blocks at all, so we don't need to re-fetch from the peer, there is no "auto-healing" necessary. 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_req.c')
-rw-r--r--drivers/block/drbd/drbd_req.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c
index e307890e6afe..97a9e69dd239 100644
--- a/drivers/block/drbd/drbd_req.c
+++ b/drivers/block/drbd/drbd_req.c
@@ -492,11 +492,14 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
492 mod_rq_state(req, m, 0, RQ_LOCAL_ABORTED); 492 mod_rq_state(req, m, 0, RQ_LOCAL_ABORTED);
493 break; 493 break;
494 494
495 case WRITE_COMPLETED_WITH_ERROR:
496 __drbd_chk_io_error(mdev, DRBD_WRITE_ERROR);
497 mod_rq_state(req, m, RQ_LOCAL_PENDING, RQ_LOCAL_COMPLETED);
498 break;
499
495 case READ_COMPLETED_WITH_ERROR: 500 case READ_COMPLETED_WITH_ERROR:
496 drbd_set_out_of_sync(mdev, req->i.sector, req->i.size); 501 drbd_set_out_of_sync(mdev, req->i.sector, req->i.size);
497 /* fall through. */ 502 __drbd_chk_io_error(mdev, DRBD_READ_ERROR);
498 case WRITE_COMPLETED_WITH_ERROR:
499 __drbd_chk_io_error(mdev, DRBD_IO_ERROR);
500 /* fall through. */ 503 /* fall through. */
501 case READ_AHEAD_COMPLETED_WITH_ERROR: 504 case READ_AHEAD_COMPLETED_WITH_ERROR:
502 /* it is legal to fail READA, no __drbd_chk_io_error in that case. */ 505 /* it is legal to fail READA, no __drbd_chk_io_error in that case. */