On 14/01/2022, 12:25 +0000, "Martin K. Petersen" <martin.petersen@xxxxxxxxxx> wrote: > Can you please try the following patch? > > Martin K. Petersen Oracle Linux Engineering > > diff --git a/block/bio-integrity.c b/block/bio-integrity.c > index c0eb901315f9..fa5bc5b13c6a 100644 > --- a/block/bio-integrity.c > +++ b/block/bio-integrity.c > @@ -387,7 +387,7 @@ void bio_integrity_advance(struct bio *bio, unsigned int bytes_done) > struct blk_integrity *bi = blk_get_integrity(bio->bi_disk); > unsigned bytes = bio_integrity_bytes(bi, bytes_done >> 9); > > - bip->bip_iter.bi_sector += bytes_done >> 9; > + bip->bip_iter.bi_sector += bio_integrity_intervals(bi, bytes_done >> 9); > bvec_iter_advance(bip->bip_vec, &bip->bip_iter, bytes); > } I encountered the same issue as Alexey did when writing to DPS Type 2 formatted, 8 bytes metadata NVME device(s) from a stacked driver if bio was split in md layer. Virtual ref_tags were improperly converted to ref_tags by the block integrity prepare_fn(). The Martin's patch has resolved this issue. Martin, could you please advance with this patch? My only concern is dm_crypt target which operates on bip_iter directly with the code copy-pasted from bio_integrity_advance: static int dm_crypt_integrity_io_alloc(struct dm_crypt_io *io, struct bio *bio) { struct bio_integrity_payload *bip; unsigned int tag_len; int ret; if (!bio_sectors(bio) || !io->cc->on_disk_tag_size) return 0; bip = bio_integrity_alloc(bio, GFP_NOIO, 1); if (IS_ERR(bip)) return PTR_ERR(bip); tag_len = io->cc->on_disk_tag_size * (bio_sectors(bio) >> io->cc->sector_shift); bip->bip_iter.bi_size = tag_len; bip->bip_iter.bi_sector = io->cc->start + io->sector; ^^^ ret = bio_integrity_add_page(bio, virt_to_page(io->integrity_metadata), tag_len, offset_in_page(io->integrity_metadata)); ... } Not sure if there is another place in drivers where bip iterator is advanced explicitly, i.e. without calling bio_integrity_advance/bio_advance. -- Dmitry Ivanov Hewlett Packard Enterprise - HPC AI Labs