On Mon, Oct 26, 2026 at 07:55:19PM +0800, [email protected] wrote: > From: Shao Mingyin <[email protected]> > > For zone append, the block layer copies req->__sector back into the > bio in blk_zone_append_update_request_bio(), so the driver must update > req->__sector with the sector reported by the device. > virtblk_request_done() does that, but the batched completion path used > by virtblk_poll() only unmaps and cleans up the requests before calling > blk_mq_end_request_batch(). > > A zone append completed through polling therefore keeps the sector that > was assigned at submission time, and the file system or application sees > the wrong LBA for the written data. > > Move the sector update into a helper and call it from both completion > paths. > > Fixes: 95bfec41bd3d ("virtio-blk: add support for zoned block devices") > Signed-off-by: Shao Mingyin <[email protected]>
Acked-by: Michael S. Tsirkin <[email protected]> > --- > diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c > index c8bfbf8435ac..cc29b8238a4d 100644 > --- a/drivers/block/virtio_blk.c > +++ b/drivers/block/virtio_blk.c > @@ -331,18 +331,25 @@ static inline u8 virtblk_vbr_status(struct virtblk_req > *vbr) > return *((u8 *)&vbr->in_hdr + vbr->in_hdr_len - 1); > } > > +static inline void virtblk_update_zone_append_sector(struct request *req, > + struct virtblk_req *vbr) > +{ > + struct virtio_blk *vblk = req->mq_hctx->queue->queuedata; > + > + if (req_op(req) == REQ_OP_ZONE_APPEND) > + req->__sector = virtio64_to_cpu(vblk->vdev, > + vbr->in_hdr.zone_append.sector); > +} > + > static inline void virtblk_request_done(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); > virtblk_cleanup_cmd(req); > > - if (req_op(req) == REQ_OP_ZONE_APPEND) > - req->__sector = virtio64_to_cpu(vblk->vdev, > - vbr->in_hdr.zone_append.sector); > + virtblk_update_zone_append_sector(req, vbr); > > blk_mq_end_request(req, status); > } > @@ -1196,8 +1203,11 @@ 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)); > + struct virtblk_req *vbr = blk_mq_rq_to_pdu(req); > + > + virtblk_unmap_data(req, vbr); > virtblk_cleanup_cmd(req); > + virtblk_update_zone_append_sector(req, vbr); > } > blk_mq_end_request_batch(iob); > }
