diff options
Diffstat (limited to 'drivers/block/drbd/drbd_req.c')
-rw-r--r-- | drivers/block/drbd/drbd_req.c | 38 |
1 files changed, 17 insertions, 21 deletions
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c index 9e91a2545fc8..11a75d32a2e2 100644 --- a/drivers/block/drbd/drbd_req.c +++ b/drivers/block/drbd/drbd_req.c | |||
@@ -258,7 +258,7 @@ void _req_may_be_done(struct drbd_request *req, struct bio_and_error *m) | |||
258 | if (!hlist_unhashed(&req->colision)) | 258 | if (!hlist_unhashed(&req->colision)) |
259 | hlist_del(&req->colision); | 259 | hlist_del(&req->colision); |
260 | else | 260 | else |
261 | D_ASSERT((s & RQ_NET_MASK) == 0); | 261 | D_ASSERT((s & (RQ_NET_MASK & ~RQ_NET_DONE)) == 0); |
262 | 262 | ||
263 | /* for writes we need to do some extra housekeeping */ | 263 | /* for writes we need to do some extra housekeeping */ |
264 | if (rw == WRITE) | 264 | if (rw == WRITE) |
@@ -813,7 +813,8 @@ static int drbd_make_request_common(struct drbd_conf *mdev, struct bio *bio) | |||
813 | mdev->state.conn >= C_CONNECTED)); | 813 | mdev->state.conn >= C_CONNECTED)); |
814 | 814 | ||
815 | if (!(local || remote) && !is_susp(mdev->state)) { | 815 | if (!(local || remote) && !is_susp(mdev->state)) { |
816 | dev_err(DEV, "IO ERROR: neither local nor remote disk\n"); | 816 | if (__ratelimit(&drbd_ratelimit_state)) |
817 | dev_err(DEV, "IO ERROR: neither local nor remote disk\n"); | ||
817 | goto fail_free_complete; | 818 | goto fail_free_complete; |
818 | } | 819 | } |
819 | 820 | ||
@@ -942,12 +943,21 @@ allocate_barrier: | |||
942 | if (local) { | 943 | if (local) { |
943 | req->private_bio->bi_bdev = mdev->ldev->backing_bdev; | 944 | req->private_bio->bi_bdev = mdev->ldev->backing_bdev; |
944 | 945 | ||
945 | if (FAULT_ACTIVE(mdev, rw == WRITE ? DRBD_FAULT_DT_WR | 946 | /* State may have changed since we grabbed our reference on the |
946 | : rw == READ ? DRBD_FAULT_DT_RD | 947 | * mdev->ldev member. Double check, and short-circuit to endio. |
947 | : DRBD_FAULT_DT_RA)) | 948 | * In case the last activity log transaction failed to get on |
949 | * stable storage, and this is a WRITE, we may not even submit | ||
950 | * this bio. */ | ||
951 | if (get_ldev(mdev)) { | ||
952 | if (FAULT_ACTIVE(mdev, rw == WRITE ? DRBD_FAULT_DT_WR | ||
953 | : rw == READ ? DRBD_FAULT_DT_RD | ||
954 | : DRBD_FAULT_DT_RA)) | ||
955 | bio_endio(req->private_bio, -EIO); | ||
956 | else | ||
957 | generic_make_request(req->private_bio); | ||
958 | put_ldev(mdev); | ||
959 | } else | ||
948 | bio_endio(req->private_bio, -EIO); | 960 | bio_endio(req->private_bio, -EIO); |
949 | else | ||
950 | generic_make_request(req->private_bio); | ||
951 | } | 961 | } |
952 | 962 | ||
953 | /* we need to plug ALWAYS since we possibly need to kick lo_dev. | 963 | /* we need to plug ALWAYS since we possibly need to kick lo_dev. |
@@ -1022,20 +1032,6 @@ int drbd_make_request_26(struct request_queue *q, struct bio *bio) | |||
1022 | return 0; | 1032 | return 0; |
1023 | } | 1033 | } |
1024 | 1034 | ||
1025 | /* Reject barrier requests if we know the underlying device does | ||
1026 | * not support them. | ||
1027 | * XXX: Need to get this info from peer as well some how so we | ||
1028 | * XXX: reject if EITHER side/data/metadata area does not support them. | ||
1029 | * | ||
1030 | * because of those XXX, this is not yet enabled, | ||
1031 | * i.e. in drbd_init_set_defaults we set the NO_BARRIER_SUPP bit. | ||
1032 | */ | ||
1033 | if (unlikely(bio->bi_rw & REQ_HARDBARRIER) && test_bit(NO_BARRIER_SUPP, &mdev->flags)) { | ||
1034 | /* dev_warn(DEV, "Rejecting barrier request as underlying device does not support\n"); */ | ||
1035 | bio_endio(bio, -EOPNOTSUPP); | ||
1036 | return 0; | ||
1037 | } | ||
1038 | |||
1039 | /* | 1035 | /* |
1040 | * what we "blindly" assume: | 1036 | * what we "blindly" assume: |
1041 | */ | 1037 | */ |