|
@@ -219,7 +219,6 @@ void drbd_req_complete(struct drbd_request *req, struct bio_and_error *m)
|
|
{
|
|
{
|
|
const unsigned s = req->rq_state;
|
|
const unsigned s = req->rq_state;
|
|
struct drbd_device *device = req->device;
|
|
struct drbd_device *device = req->device;
|
|
- int rw;
|
|
|
|
int error, ok;
|
|
int error, ok;
|
|
|
|
|
|
/* we must not complete the master bio, while it is
|
|
/* we must not complete the master bio, while it is
|
|
@@ -243,8 +242,6 @@ void drbd_req_complete(struct drbd_request *req, struct bio_and_error *m)
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
- rw = bio_rw(req->master_bio);
|
|
|
|
-
|
|
|
|
/*
|
|
/*
|
|
* figure out whether to report success or failure.
|
|
* figure out whether to report success or failure.
|
|
*
|
|
*
|
|
@@ -268,7 +265,7 @@ void drbd_req_complete(struct drbd_request *req, struct bio_and_error *m)
|
|
* epoch number. If they match, increase the current_tle_nr,
|
|
* epoch number. If they match, increase the current_tle_nr,
|
|
* and reset the transfer log epoch write_cnt.
|
|
* and reset the transfer log epoch write_cnt.
|
|
*/
|
|
*/
|
|
- if (rw == WRITE &&
|
|
|
|
|
|
+ if (op_is_write(bio_op(req->master_bio)) &&
|
|
req->epoch == atomic_read(&first_peer_device(device)->connection->current_tle_nr))
|
|
req->epoch == atomic_read(&first_peer_device(device)->connection->current_tle_nr))
|
|
start_new_tl_epoch(first_peer_device(device)->connection);
|
|
start_new_tl_epoch(first_peer_device(device)->connection);
|
|
|
|
|
|
@@ -285,11 +282,14 @@ void drbd_req_complete(struct drbd_request *req, struct bio_and_error *m)
|
|
* because no path was available, in which case
|
|
* because no path was available, in which case
|
|
* it was not even added to the transfer_log.
|
|
* it was not even added to the transfer_log.
|
|
*
|
|
*
|
|
- * READA may fail, and will not be retried.
|
|
|
|
|
|
+ * read-ahead may fail, and will not be retried.
|
|
*
|
|
*
|
|
* WRITE should have used all available paths already.
|
|
* WRITE should have used all available paths already.
|
|
*/
|
|
*/
|
|
- if (!ok && rw == READ && !list_empty(&req->tl_requests))
|
|
|
|
|
|
+ if (!ok &&
|
|
|
|
+ bio_op(req->master_bio) == REQ_OP_READ &&
|
|
|
|
+ !(req->master_bio->bi_rw & REQ_RAHEAD) &&
|
|
|
|
+ !list_empty(&req->tl_requests))
|
|
req->rq_state |= RQ_POSTPONED;
|
|
req->rq_state |= RQ_POSTPONED;
|
|
|
|
|
|
if (!(req->rq_state & RQ_POSTPONED)) {
|
|
if (!(req->rq_state & RQ_POSTPONED)) {
|
|
@@ -645,7 +645,7 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
|
|
__drbd_chk_io_error(device, DRBD_READ_ERROR);
|
|
__drbd_chk_io_error(device, DRBD_READ_ERROR);
|
|
/* fall through. */
|
|
/* fall through. */
|
|
case READ_AHEAD_COMPLETED_WITH_ERROR:
|
|
case READ_AHEAD_COMPLETED_WITH_ERROR:
|
|
- /* it is legal to fail READA, no __drbd_chk_io_error in that case. */
|
|
|
|
|
|
+ /* it is legal to fail read-ahead, no __drbd_chk_io_error in that case. */
|
|
mod_rq_state(req, m, RQ_LOCAL_PENDING, RQ_LOCAL_COMPLETED);
|
|
mod_rq_state(req, m, RQ_LOCAL_PENDING, RQ_LOCAL_COMPLETED);
|
|
break;
|
|
break;
|
|
|
|
|
|
@@ -657,7 +657,7 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
|
|
break;
|
|
break;
|
|
|
|
|
|
case QUEUE_FOR_NET_READ:
|
|
case QUEUE_FOR_NET_READ:
|
|
- /* READ or READA, and
|
|
|
|
|
|
+ /* READ, and
|
|
* no local disk,
|
|
* no local disk,
|
|
* or target area marked as invalid,
|
|
* or target area marked as invalid,
|
|
* or just got an io-error. */
|
|
* or just got an io-error. */
|
|
@@ -1172,7 +1172,14 @@ drbd_submit_req_private_bio(struct drbd_request *req)
|
|
{
|
|
{
|
|
struct drbd_device *device = req->device;
|
|
struct drbd_device *device = req->device;
|
|
struct bio *bio = req->private_bio;
|
|
struct bio *bio = req->private_bio;
|
|
- const int rw = bio_rw(bio);
|
|
|
|
|
|
+ unsigned int type;
|
|
|
|
+
|
|
|
|
+ if (bio_op(bio) != REQ_OP_READ)
|
|
|
|
+ type = DRBD_FAULT_DT_WR;
|
|
|
|
+ else if (bio->bi_rw & REQ_RAHEAD)
|
|
|
|
+ type = DRBD_FAULT_DT_RA;
|
|
|
|
+ else
|
|
|
|
+ type = DRBD_FAULT_DT_RD;
|
|
|
|
|
|
bio->bi_bdev = device->ldev->backing_bdev;
|
|
bio->bi_bdev = device->ldev->backing_bdev;
|
|
|
|
|
|
@@ -1182,10 +1189,7 @@ drbd_submit_req_private_bio(struct drbd_request *req)
|
|
* stable storage, and this is a WRITE, we may not even submit
|
|
* stable storage, and this is a WRITE, we may not even submit
|
|
* this bio. */
|
|
* this bio. */
|
|
if (get_ldev(device)) {
|
|
if (get_ldev(device)) {
|
|
- if (drbd_insert_fault(device,
|
|
|
|
- rw == WRITE ? DRBD_FAULT_DT_WR
|
|
|
|
- : rw == READ ? DRBD_FAULT_DT_RD
|
|
|
|
- : DRBD_FAULT_DT_RA))
|
|
|
|
|
|
+ if (drbd_insert_fault(device, type))
|
|
bio_io_error(bio);
|
|
bio_io_error(bio);
|
|
else if (bio_op(bio) == REQ_OP_DISCARD)
|
|
else if (bio_op(bio) == REQ_OP_DISCARD)
|
|
drbd_process_discard_req(req);
|
|
drbd_process_discard_req(req);
|
|
@@ -1278,7 +1282,7 @@ static bool may_do_writes(struct drbd_device *device)
|
|
static void drbd_send_and_submit(struct drbd_device *device, struct drbd_request *req)
|
|
static void drbd_send_and_submit(struct drbd_device *device, struct drbd_request *req)
|
|
{
|
|
{
|
|
struct drbd_resource *resource = device->resource;
|
|
struct drbd_resource *resource = device->resource;
|
|
- const int rw = bio_rw(req->master_bio);
|
|
|
|
|
|
+ const int rw = bio_data_dir(req->master_bio);
|
|
struct bio_and_error m = { NULL, };
|
|
struct bio_and_error m = { NULL, };
|
|
bool no_remote = false;
|
|
bool no_remote = false;
|
|
bool submit_private_bio = false;
|
|
bool submit_private_bio = false;
|
|
@@ -1308,7 +1312,7 @@ static void drbd_send_and_submit(struct drbd_device *device, struct drbd_request
|
|
goto out;
|
|
goto out;
|
|
}
|
|
}
|
|
|
|
|
|
- /* We fail READ/READA early, if we can not serve it.
|
|
|
|
|
|
+ /* We fail READ early, if we can not serve it.
|
|
* We must do this before req is registered on any lists.
|
|
* We must do this before req is registered on any lists.
|
|
* Otherwise, drbd_req_complete() will queue failed READ for retry. */
|
|
* Otherwise, drbd_req_complete() will queue failed READ for retry. */
|
|
if (rw != WRITE) {
|
|
if (rw != WRITE) {
|