The introduction of completion batching with commit 07b679f70d73 ("virtio-blk: support completion batching for the IRQ path") overlloked handling correctly the completion of zone append operations, which require an update of the request __sector field, as is done in virtblk_request_done(): the function virtblk_complete_batch() only executes virtblk_unmap_data() and virtblk_cleanup_cmd() without doing this update. This causes problems with zone append operations, e.g. zonefs complains about invalid zone append locations. Fix this by introducing the function virtblk_end_request(), which is almost identicatl to virtblk_request_done() but without the call to blk_mq_end_request(). Use this new function to rewrite virtblk_request_done() and call it in virtblk_complete_batch() to end all request of a batch. Reported-by: Sam Li <faithilikerun@xxxxxxxxx> Fixes: 07b679f70d73 ("virtio-blk: support completion batching for the IRQ path") Cc: stable@xxxxxxxxxxxxxxx Signed-off-by: Damien Le Moal <dlemoal@xxxxxxxxxx> --- drivers/block/virtio_blk.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 2b918e28acaa..513d8b582aec 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -332,10 +332,9 @@ static inline u8 virtblk_vbr_status(struct virtblk_req *vbr) return *((u8 *)&vbr->in_hdr + vbr->in_hdr_len - 1); } -static inline void virtblk_request_done(struct request *req) +static inline blk_status_t virtblk_end_request(struct request *req) { struct virtblk_req *vbr = blk_mq_rq_to_pdu(req); - blk_status_t status = virtblk_result(virtblk_vbr_status(vbr)); struct virtio_blk *vblk = req->mq_hctx->queue->queuedata; virtblk_unmap_data(req, vbr); @@ -345,17 +344,21 @@ static inline void virtblk_request_done(struct request *req) req->__sector = virtio64_to_cpu(vblk->vdev, vbr->in_hdr.zone_append.sector); - blk_mq_end_request(req, status); + return virtblk_result(virtblk_vbr_status(vbr)); +} + +static inline void virtblk_request_done(struct request *req) +{ + blk_mq_end_request(req, virtblk_end_request(req)); } static void virtblk_complete_batch(struct io_comp_batch *iob) { struct request *req; - rq_list_for_each(&iob->req_list, req) { - virtblk_unmap_data(req, blk_mq_rq_to_pdu(req)); - virtblk_cleanup_cmd(req); - } + rq_list_for_each(&iob->req_list, req) + virtblk_end_request(req); + blk_mq_end_request_batch(iob); } -- 2.40.1