|
@@ -451,16 +451,36 @@ static int lo_req_flush(struct loop_device *lo, struct request *rq)
|
|
|
static void lo_complete_rq(struct request *rq)
|
|
|
{
|
|
|
struct loop_cmd *cmd = blk_mq_rq_to_pdu(rq);
|
|
|
+ blk_status_t ret = BLK_STS_OK;
|
|
|
|
|
|
- if (unlikely(req_op(rq) == REQ_OP_READ && cmd->use_aio &&
|
|
|
- cmd->ret >= 0 && cmd->ret < blk_rq_bytes(rq))) {
|
|
|
- struct bio *bio = rq->bio;
|
|
|
-
|
|
|
- bio_advance(bio, cmd->ret);
|
|
|
- zero_fill_bio(bio);
|
|
|
+ if (!cmd->use_aio || cmd->ret < 0 || cmd->ret == blk_rq_bytes(rq) ||
|
|
|
+ req_op(rq) != REQ_OP_READ) {
|
|
|
+ if (cmd->ret < 0)
|
|
|
+ ret = BLK_STS_IOERR;
|
|
|
+ goto end_io;
|
|
|
}
|
|
|
|
|
|
- blk_mq_end_request(rq, cmd->ret < 0 ? BLK_STS_IOERR : BLK_STS_OK);
|
|
|
+ /*
|
|
|
+ * Short READ - if we got some data, advance our request and
|
|
|
+ * retry it. If we got no data, end the rest with EIO.
|
|
|
+ */
|
|
|
+ if (cmd->ret) {
|
|
|
+ blk_update_request(rq, BLK_STS_OK, cmd->ret);
|
|
|
+ cmd->ret = 0;
|
|
|
+ blk_mq_requeue_request(rq, true);
|
|
|
+ } else {
|
|
|
+ if (cmd->use_aio) {
|
|
|
+ struct bio *bio = rq->bio;
|
|
|
+
|
|
|
+ while (bio) {
|
|
|
+ zero_fill_bio(bio);
|
|
|
+ bio = bio->bi_next;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ret = BLK_STS_IOERR;
|
|
|
+end_io:
|
|
|
+ blk_mq_end_request(rq, ret);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
static void lo_rw_aio_do_completion(struct loop_cmd *cmd)
|