summaryrefslogtreecommitdiffstats
path: root/block
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2017-05-11 12:34:38 +0200
committerJens Axboe <axboe@fb.com>2017-05-11 16:08:53 +0200
commited6565e734249ef021d5c13ba34c167eb4e42f62 (patch)
tree22be44b37efa7933c53a1ea90808cbc8db7a6ad8 /block
parentblk-mq: NVMe 512B/4K+T10 DIF/DIX format returns I/O error on dd with split op (diff)
downloadlinux-ed6565e734249ef021d5c13ba34c167eb4e42f62.tar.xz
linux-ed6565e734249ef021d5c13ba34c167eb4e42f62.zip
block: handle partial completions for special payload requests
SCSI devices can return short writes on Write Same just like for normal writes, so we need to handle this case for our special payload requests as well. Signed-off-by: Christoph Hellwig <hch@lst.de> Reported-by: Abdul Haleem <abdhalee@linux.vnet.ibm.com> Tested-by: Abdul Haleem <abdhalee@linux.vnet.ibm.com> Signed-off-by: Jens Axboe <axboe@fb.com>
Diffstat (limited to 'block')
-rw-r--r--block/blk-core.c24
1 files changed, 12 insertions, 12 deletions
diff --git a/block/blk-core.c b/block/blk-core.c
index c580b0138a7f..c7068520794b 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -2644,8 +2644,6 @@ bool blk_update_request(struct request *req, int error, unsigned int nr_bytes)
return false;
}
- WARN_ON_ONCE(req->rq_flags & RQF_SPECIAL_PAYLOAD);
-
req->__data_len -= total_bytes;
/* update sector only for requests with clear definition of sector */
@@ -2658,17 +2656,19 @@ bool blk_update_request(struct request *req, int error, unsigned int nr_bytes)
req->cmd_flags |= req->bio->bi_opf & REQ_FAILFAST_MASK;
}
- /*
- * If total number of sectors is less than the first segment
- * size, something has gone terribly wrong.
- */
- if (blk_rq_bytes(req) < blk_rq_cur_bytes(req)) {
- blk_dump_rq_flags(req, "request botched");
- req->__data_len = blk_rq_cur_bytes(req);
- }
+ if (!(req->rq_flags & RQF_SPECIAL_PAYLOAD)) {
+ /*
+ * If total number of sectors is less than the first segment
+ * size, something has gone terribly wrong.
+ */
+ if (blk_rq_bytes(req) < blk_rq_cur_bytes(req)) {
+ blk_dump_rq_flags(req, "request botched");
+ req->__data_len = blk_rq_cur_bytes(req);
+ }
- /* recalculate the number of segments */
- blk_recalc_rq_segments(req);
+ /* recalculate the number of segments */
+ blk_recalc_rq_segments(req);
+ }
return true;
}