diff --git a/block/bio-integrity-fs.c b/block/bio-integrity-fs.c
index 4f67b34bf289..c8e91ada8ca6 100644
--- a/block/bio-integrity-fs.c
+++ b/block/bio-integrity-fs.c
@@ -54,14 +54,10 @@ void fs_bio_integrity_generate(struct bio *bio)
}
EXPORT_SYMBOL_GPL(fs_bio_integrity_generate);
-int fs_bio_integrity_verify(struct bio *bio, sector_t sector, unsigned int size)
+int fs_bio_integrity_verify(struct bio *bio, struct bvec_iter *data_iter)
{
struct blk_integrity *bi = blk_get_integrity(bio->bi_bdev->bd_disk);
struct bio_integrity_payload *bip = bio_integrity(bio);
- struct bvec_iter data_iter = {
- .bi_sector = sector,
- .bi_size = size,
- };
if (!bip || !(bip->bip_flags & BIP_CHECK_FLAGS))
return 0;@@ -73,9 +69,10 @@ int fs_bio_integrity_verify(struct bio *bio, sector_t sector, unsigned int size)
* bio. Requires the submitter to remember the sector and the size.
*/
memset(&bip->bip_iter, 0, sizeof(bip->bip_iter));
- bip->bip_iter.bi_sector = sector;
- bip->bip_iter.bi_size = bio_integrity_bytes(bi, size >> SECTOR_SHIFT);
- return blk_status_to_errno(bio_integrity_verify(bio, &data_iter));
+ bip->bip_iter.bi_sector = data_iter->bi_sector;
+ bip->bip_iter.bi_size =
+ bio_integrity_bytes(bi, data_iter->bi_size >> SECTOR_SHIFT);
+ return blk_status_to_errno(bio_integrity_verify(bio, data_iter));
}
static int __init fs_bio_integrity_init(void)
diff --git a/fs/iomap/bio.c b/fs/iomap/bio.c
index 48100c614431..d46c2f8ea18c 100644
--- a/fs/iomap/bio.c
+++ b/fs/iomap/bio.c
@@ -169,6 +169,7 @@ int iomap_bio_read_folio_range_sync(const struct iomap_iter *iter,
{
const struct iomap *srcmap = iomap_iter_srcmap(iter);
sector_t sector = iomap_sector(srcmap, pos);
+ struct bvec_iter saved_iter;
struct bio_vec bvec;
struct bio bio;
int error;@@ -178,10 +179,11 @@ int iomap_bio_read_folio_range_sync(const struct iomap_iter *iter,
bio_add_folio_nofail(&bio, folio, len, offset_in_folio(folio, pos));
if (srcmap->flags & IOMAP_F_INTEGRITY)
fs_bio_integrity_alloc(&bio);
+ saved_iter = bio.bi_iter;
error = submit_bio_wait(&bio);
if (bio_integrity(&bio)) {
if (!error)
- error = fs_bio_integrity_verify(&bio, sector, len);
+ error = fs_bio_integrity_verify(&bio, &saved_iter);
fs_bio_integrity_free(&bio);
}
bio_uninit(&bio);diff --git a/fs/iomap/ioend.c b/fs/iomap/ioend.c
index 573fa89c1632..332dbfb2230f 100644
--- a/fs/iomap/ioend.c
+++ b/fs/iomap/ioend.c
@@ -25,6 +25,7 @@ struct iomap_ioend *iomap_init_ioend(struct inode *inode,
ioend->io_parent = NULL;
INIT_LIST_HEAD(&ioend->io_list);
ioend->io_flags = ioend_flags;
+ ioend->io_bvec_offset = bio->bi_iter.bi_offset;
ioend->io_inode = inode;
ioend->io_offset = file_offset;
ioend->io_size = bio->bi_iter.bi_size;
@@ -308,6 +309,13 @@ ssize_t iomap_add_to_ioend(struct iomap_writepage_ctx *wpc, struct folio *folio,
}
EXPORT_SYMBOL_GPL(iomap_add_to_ioend);
+static int iomap_ioend_integrity_verify(struct iomap_ioend *ioend)
+{
+ struct bvec_iter data_iter = BVEC_ITER_IOEND(ioend);
+
+ return fs_bio_integrity_verify(&ioend->io_bio, &data_iter);
+}
+
static u32 iomap_finish_ioend(struct iomap_ioend *ioend, int error)
{
if (ioend->io_parent) {@@ -325,10 +333,8 @@ static u32 iomap_finish_ioend(struct iomap_ioend *ioend, int error)
if (!ioend->io_error &&
bio_integrity(&ioend->io_bio) &&
- bio_op(&ioend->io_bio) == REQ_OP_READ) {
- ioend->io_error = fs_bio_integrity_verify(&ioend->io_bio,
- ioend->io_sector, ioend->io_size);
- }
+ bio_op(&ioend->io_bio) == REQ_OP_READ)
+ ioend->io_error = iomap_ioend_integrity_verify(ioend);
if (ioend->io_flags & IOMAP_IOEND_DIRECT)
return iomap_finish_ioend_direct(ioend);diff --git a/include/linux/bio-integrity.h b/include/linux/bio-integrity.h
index 0ea2a8bf7efb..a954c97be0b3 100644
--- a/include/linux/bio-integrity.h
+++ b/include/linux/bio-integrity.h
@@ -151,7 +151,6 @@ void bio_integrity_setup_default(struct bio *bio);
unsigned int fs_bio_integrity_alloc(struct bio *bio);
void fs_bio_integrity_free(struct bio *bio);
void fs_bio_integrity_generate(struct bio *bio);
-int fs_bio_integrity_verify(struct bio *bio, sector_t sector,
- unsigned int size);
+int fs_bio_integrity_verify(struct bio *bio, struct bvec_iter *data_iter);
#endif /* _LINUX_BIO_INTEGRITY_H */
diff --git a/include/linux/iomap.h b/include/linux/iomap.h
index 1cc9a35fd5cc..bffdc217ad85 100644
--- a/include/linux/iomap.h
+++ b/include/linux/iomap.h
@@ -522,6 +522,7 @@ static inline u16 iomap_ioend_flags(const struct iomap *iomap)
struct iomap_ioend {
struct list_head io_list; /* next ioend in chain */
u16 io_flags; /* IOMAP_IOEND_* */
+ u32 io_bvec_offset; /* offset into first bvec */
struct inode *io_inode; /* file being written to */
size_t io_size; /* size of the extent */
atomic_t io_remaining; /* completetion defer count */@@ -539,6 +540,13 @@ static inline struct iomap_ioend *iomap_ioend_from_bio(struct bio *bio)
return container_of(bio, struct iomap_ioend, io_bio);
}
+#define BVEC_ITER_IOEND(_ioend) \
+{ \
+ .bi_sector = (_ioend)->io_sector, \
+ .bi_size = (_ioend)->io_size, \
+ .bi_offset = (_ioend)->io_bvec_offset, \
+}
+
struct iomap_writeback_ops {
/*
* Performs writeback on the passed in range--
2.53.0