diff options
author | Lars Ellenberg <lars.ellenberg@linbit.com> | 2012-09-27 09:19:38 -0400 |
---|---|---|
committer | Philipp Reisner <philipp.reisner@linbit.com> | 2012-11-09 08:11:41 -0500 |
commit | 42839f65361baa0fa62494c32f1dae570e9dce19 (patch) | |
tree | 1ddd9c433dfed793d3cbe45f900f470cd7d781d1 | |
parent | edc9f5eb7afa3d832f540fcfe10e3e1087e6f527 (diff) |
drbd: log request sector offset and size for IO errors
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_req.c | 19 |
1 files changed, 18 insertions, 1 deletions
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c index 97a9e69dd239..b905a0453bf9 100644 --- a/drivers/block/drbd/drbd_req.c +++ b/drivers/block/drbd/drbd_req.c | |||
@@ -425,6 +425,20 @@ static void mod_rq_state(struct drbd_request *req, struct bio_and_error *m, | |||
425 | kref_sub(&req->kref, k_put, drbd_req_destroy); | 425 | kref_sub(&req->kref, k_put, drbd_req_destroy); |
426 | } | 426 | } |
427 | 427 | ||
428 | static void drbd_report_io_error(struct drbd_conf *mdev, struct drbd_request *req) | ||
429 | { | ||
430 | char b[BDEVNAME_SIZE]; | ||
431 | |||
432 | if (!__ratelimit(&drbd_ratelimit_state)) | ||
433 | return; | ||
434 | |||
435 | dev_warn(DEV, "local %s IO error sector %llu+%u on %s\n", | ||
436 | (req->rq_state & RQ_WRITE) ? "WRITE" : "READ", | ||
437 | (unsigned long long)req->i.sector, | ||
438 | req->i.size >> 9, | ||
439 | bdevname(mdev->ldev->backing_bdev, b)); | ||
440 | } | ||
441 | |||
428 | /* obviously this could be coded as many single functions | 442 | /* obviously this could be coded as many single functions |
429 | * instead of one huge switch, | 443 | * instead of one huge switch, |
430 | * or by putting the code directly in the respective locations | 444 | * or by putting the code directly in the respective locations |
@@ -493,12 +507,14 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what, | |||
493 | break; | 507 | break; |
494 | 508 | ||
495 | case WRITE_COMPLETED_WITH_ERROR: | 509 | case WRITE_COMPLETED_WITH_ERROR: |
510 | drbd_report_io_error(mdev, req); | ||
496 | __drbd_chk_io_error(mdev, DRBD_WRITE_ERROR); | 511 | __drbd_chk_io_error(mdev, DRBD_WRITE_ERROR); |
497 | mod_rq_state(req, m, RQ_LOCAL_PENDING, RQ_LOCAL_COMPLETED); | 512 | mod_rq_state(req, m, RQ_LOCAL_PENDING, RQ_LOCAL_COMPLETED); |
498 | break; | 513 | break; |
499 | 514 | ||
500 | case READ_COMPLETED_WITH_ERROR: | 515 | case READ_COMPLETED_WITH_ERROR: |
501 | drbd_set_out_of_sync(mdev, req->i.sector, req->i.size); | 516 | drbd_set_out_of_sync(mdev, req->i.sector, req->i.size); |
517 | drbd_report_io_error(mdev, req); | ||
502 | __drbd_chk_io_error(mdev, DRBD_READ_ERROR); | 518 | __drbd_chk_io_error(mdev, DRBD_READ_ERROR); |
503 | /* fall through. */ | 519 | /* fall through. */ |
504 | case READ_AHEAD_COMPLETED_WITH_ERROR: | 520 | case READ_AHEAD_COMPLETED_WITH_ERROR: |
@@ -1108,7 +1124,8 @@ void __drbd_make_request(struct drbd_conf *mdev, struct bio *bio, unsigned long | |||
1108 | } else if (no_remote) { | 1124 | } else if (no_remote) { |
1109 | nodata: | 1125 | nodata: |
1110 | if (__ratelimit(&drbd_ratelimit_state)) | 1126 | if (__ratelimit(&drbd_ratelimit_state)) |
1111 | dev_err(DEV, "IO ERROR: neither local nor remote disk\n"); | 1127 | dev_err(DEV, "IO ERROR: neither local nor remote data, sector %llu+%u\n", |
1128 | (unsigned long long)req->i.sector, req->i.size >> 9); | ||
1112 | /* A write may have been queued for send_oos, however. | 1129 | /* A write may have been queued for send_oos, however. |
1113 | * So we can not simply free it, we must go through drbd_req_put_completion_ref() */ | 1130 | * So we can not simply free it, we must go through drbd_req_put_completion_ref() */ |
1114 | } | 1131 | } |