[1/2] dm: update original bio sector on Zone Append
diff mbox series

Message ID 20200619065905.22228-2-johannes.thumshirn@wdc.com
State New
Headers show
Series
  • Two fixes for device-mapper with REQ_OP_ZONE_APPEND
Related show

Commit Message

Johannes Thumshirn June 19, 2020, 6:59 a.m. UTC
Naohiro reported that issuing zone-append bios to a zoned block device
underneath a dm-linear device does not work as expected.

This because we forgot to reverse-map the sector the device wrote to the
original bio.

For zone-append bios, get the offset in the zone of the written sector
from the clone bio and add that to the original bio's sector position.

Reported-by: Naohiro Aota <Naohiro.Aota@wdc.com>
Fixes: 0512a75b98f8 ("block: Introduce REQ_OP_ZONE_APPEND")
Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
---
 drivers/md/dm.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

Comments

Damien Le Moal June 19, 2020, 7:52 a.m. UTC | #1
On 2020/06/19 15:59, Johannes Thumshirn wrote:
> Naohiro reported that issuing zone-append bios to a zoned block device
> underneath a dm-linear device does not work as expected.
> 
> This because we forgot to reverse-map the sector the device wrote to the
> original bio.
> 
> For zone-append bios, get the offset in the zone of the written sector
> from the clone bio and add that to the original bio's sector position.
> 
> Reported-by: Naohiro Aota <Naohiro.Aota@wdc.com>
> Fixes: 0512a75b98f8 ("block: Introduce REQ_OP_ZONE_APPEND")
> Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
> ---
>  drivers/md/dm.c | 13 +++++++++++++
>  1 file changed, 13 insertions(+)
> 
> diff --git a/drivers/md/dm.c b/drivers/md/dm.c
> index 109e81f33edb..058c34abe9d1 100644
> --- a/drivers/md/dm.c
> +++ b/drivers/md/dm.c
> @@ -1009,6 +1009,7 @@ static void clone_endio(struct bio *bio)
>  	struct dm_io *io = tio->io;
>  	struct mapped_device *md = tio->io->md;
>  	dm_endio_fn endio = tio->ti->type->end_io;
> +	struct bio *orig_bio = io->orig_bio;
>  
>  	if (unlikely(error == BLK_STS_TARGET) && md->type != DM_TYPE_NVME_BIO_BASED) {
>  		if (bio_op(bio) == REQ_OP_DISCARD &&
> @@ -1022,6 +1023,18 @@ static void clone_endio(struct bio *bio)
>  			disable_write_zeroes(md);
>  	}
>  
> +	/*
> +	 * for zone-append bios get offset in zone of the written sector and add
> +	 * that to the original bio sector pos.
> +	 */
> +	if (bio_op(orig_bio) == REQ_OP_ZONE_APPEND) {
> +		sector_t written_sector = bio->bi_iter.bi_sector;
> +		struct request_queue *q = orig_bio->bi_disk->queue;
> +		u64 mask = (u64)blk_queue_zone_sectors(q) - 1;
> +
> +		orig_bio->bi_iter.bi_sector += written_sector & mask;
> +	}
> +
>  	if (endio) {
>  		int r = endio(tio->ti, bio, &error);
>  		switch (r) {
> 

Looks good.

Reviewed-by: Damien Le Moal <damien.lemoal@wdc.com>

Patch
diff mbox series

diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 109e81f33edb..058c34abe9d1 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -1009,6 +1009,7 @@  static void clone_endio(struct bio *bio)
 	struct dm_io *io = tio->io;
 	struct mapped_device *md = tio->io->md;
 	dm_endio_fn endio = tio->ti->type->end_io;
+	struct bio *orig_bio = io->orig_bio;
 
 	if (unlikely(error == BLK_STS_TARGET) && md->type != DM_TYPE_NVME_BIO_BASED) {
 		if (bio_op(bio) == REQ_OP_DISCARD &&
@@ -1022,6 +1023,18 @@  static void clone_endio(struct bio *bio)
 			disable_write_zeroes(md);
 	}
 
+	/*
+	 * for zone-append bios get offset in zone of the written sector and add
+	 * that to the original bio sector pos.
+	 */
+	if (bio_op(orig_bio) == REQ_OP_ZONE_APPEND) {
+		sector_t written_sector = bio->bi_iter.bi_sector;
+		struct request_queue *q = orig_bio->bi_disk->queue;
+		u64 mask = (u64)blk_queue_zone_sectors(q) - 1;
+
+		orig_bio->bi_iter.bi_sector += written_sector & mask;
+	}
+
 	if (endio) {
 		int r = endio(tio->ti, bio, &error);
 		switch (r) {