copy the integrity bits from the device and send them through
the wire, then the verification happens on the clients.
-Index: linux-4.18.0-80.el8/block/bio-integrity.c
+Index: linux-4.18.0-80.11.2.el8_0/block/bio-integrity.c
===================================================================
---- linux-4.18.0-80.el8.orig/block/bio-integrity.c
-+++ linux-4.18.0-80.el8/block/bio-integrity.c
+--- linux-4.18.0-80.11.2.el8_0.orig/block/bio-integrity.c
++++ linux-4.18.0-80.11.2.el8_0/block/bio-integrity.c
@@ -39,7 +39,7 @@ void blk_flush_integrity(void)
}
* @bio: bio to attach integrity metadata to
* @gfp_mask: Memory allocation mask
* @nr_vecs: Number of integrity metadata scatter-gather elements
-@@ -48,9 +48,11 @@ void blk_flush_integrity(void)
+@@ -48,9 +48,10 @@ void blk_flush_integrity(void)
* metadata. nr_vecs specifies the maximum number of pages containing
* integrity metadata that can be attached.
*/
+struct bio_integrity_payload *bio_integrity_alloc_fn(struct bio *bio,
+ gfp_t gfp_mask,
+ unsigned int nr_vecs,
-+ integrity_processing_fn *generate_fn,
+ integrity_processing_fn *verify_fn)
{
struct bio_integrity_payload *bip;
struct bio_set *bs = bio->bi_pool;
-@@ -85,6 +87,8 @@ struct bio_integrity_payload *bio_integr
+@@ -85,6 +86,7 @@ struct bio_integrity_payload *bio_integr
}
bip->bip_bio = bio;
-+ bip->bip_generate_fn = generate_fn;
+ bip->bip_verify_fn = verify_fn;
bio->bi_integrity = bip;
bio->bi_opf |= REQ_INTEGRITY;
-@@ -93,6 +97,13 @@ err:
+@@ -93,6 +95,14 @@ err:
mempool_free(bip, &bs->bio_integrity_pool);
return ERR_PTR(-ENOMEM);
}
+EXPORT_SYMBOL(bio_integrity_alloc_fn);
+
-+struct bio_integrity_payload *bio_integrity_alloc(struct bio *bio, gfp_t gfp,
-+ unsigned int nr)
++struct bio_integrity_payload *bio_integrity_alloc(struct bio *bio,
++ gfp_t gfp_mask,
++ unsigned int nr_vecs)
+{
-+ return bio_integrity_alloc_fn(bio, gfp, nr, NULL, NULL);
++ return bio_integrity_alloc_fn(bio, gfp_mask, nr_vecs, NULL);
+}
EXPORT_SYMBOL(bio_integrity_alloc);
/**
-@@ -213,7 +224,7 @@ static blk_status_t bio_integrity_proces
+@@ -200,7 +210,7 @@ static blk_status_t bio_integrity_proces
+ }
+
+ /**
+- * bio_integrity_prep - Prepare bio for integrity I/O
++ * bio_integrity_prep_fn - Prepare bio for integrity I/O
+ * @bio: bio to prepare
+ *
+ * Description: Checks if the bio already has an integrity payload attached.
+@@ -211,7 +221,9 @@ static blk_status_t bio_integrity_proces
+ * the block device's integrity function. In the READ case, the buffer
+ * will be prepared for DMA and a suitable end_io handler set up.
*/
- bool bio_integrity_prep(struct bio *bio)
+-bool bio_integrity_prep(struct bio *bio)
++bool bio_integrity_prep_fn(struct bio *bio,
++ integrity_processing_fn *generate_fn,
++ integrity_processing_fn *verify_fn)
{
-- struct bio_integrity_payload *bip;
-+ struct bio_integrity_payload *bip = bio_integrity(bio);
+ struct bio_integrity_payload *bip;
struct blk_integrity *bi = blk_get_integrity(bio->bi_disk);
- struct request_queue *q = bio->bi_disk->queue;
- void *buf;
-@@ -222,6 +233,8 @@ bool bio_integrity_prep(struct bio *bio)
- unsigned int bytes, offset, i;
- unsigned int intervals;
- blk_status_t status;
-+ integrity_processing_fn *generate_fn;
-+ integrity_processing_fn *verify_fn;
-
- if (!bi)
- return true;
-@@ -232,16 +245,20 @@ bool bio_integrity_prep(struct bio *bio)
- if (!bio_sectors(bio))
- return true;
-
-- /* Already protected? */
-- if (bio_integrity(bio))
-- return true;
-+ if (bip != NULL) {
-+ generate_fn = bip->bip_generate_fn ?: bi->profile->generate_fn;
-+ verify_fn = bip->bip_verify_fn ?: bi->profile->verify_fn;
-+ } else {
-+ generate_fn = bi->profile->generate_fn;
-+ verify_fn = bi->profile->verify_fn;
-+ }
-
- if (bio_data_dir(bio) == READ) {
-- if (!bi->profile->verify_fn ||
-+ if (!verify_fn ||
- !(bi->flags & BLK_INTEGRITY_VERIFY))
- return true;
- } else {
-- if (!bi->profile->generate_fn ||
-+ if (!generate_fn ||
- !(bi->flags & BLK_INTEGRITY_GENERATE))
- return true;
- }
-@@ -261,7 +278,8 @@ bool bio_integrity_prep(struct bio *bio)
+@@ -261,7 +273,7 @@ bool bio_integrity_prep(struct bio *bio)
nr_pages = end - start;
/* Allocate bio integrity payload and integrity vectors */
- bip = bio_integrity_alloc(bio, GFP_NOIO, nr_pages);
-+ bip = bio_integrity_alloc_fn(bio, GFP_NOIO, nr_pages,
-+ generate_fn, verify_fn);
++ bip = bio_integrity_alloc_fn(bio, GFP_NOIO, nr_pages, verify_fn);
if (IS_ERR(bip)) {
printk(KERN_ERR "could not allocate data integrity bioset\n");
kfree(buf);
-@@ -304,8 +322,7 @@ bool bio_integrity_prep(struct bio *bio)
-
+@@ -305,7 +317,7 @@ bool bio_integrity_prep(struct bio *bio)
/* Auto-generate integrity metadata if this is a write */
if (bio_data_dir(bio) == WRITE) {
-- bio_integrity_process(bio, &bio->bi_iter,
+ bio_integrity_process(bio, &bio->bi_iter,
- bi->profile->generate_fn);
-+ bio_integrity_process(bio, &bio->bi_iter, generate_fn);
++ generate_fn ?: bi->profile->generate_fn);
} else {
bip->bio_iter = bio->bi_iter;
}
-@@ -333,6 +350,13 @@ static void bio_integrity_verify_fn(stru
- container_of(work, struct bio_integrity_payload, bip_work);
- struct bio *bio = bip->bip_bio;
- struct blk_integrity *bi = blk_get_integrity(bio->bi_disk);
-+ struct bio_integrity_payload *bio_bip = bio_integrity(bio);
-+ integrity_processing_fn *verify_fn;
+@@ -317,6 +329,12 @@ err_end_io:
+ return false;
+
+ }
++EXPORT_SYMBOL(bio_integrity_prep_fn);
+
-+ if (bio_bip != NULL)
-+ verify_fn = bio_bip->bip_verify_fn ?: bi->profile->verify_fn;
-+ else
-+ verify_fn = bi->profile->verify_fn;
-
- /*
- * At the moment verify is called bio's iterator was advanced
-@@ -340,7 +364,7 @@ static void bio_integrity_verify_fn(stru
++bool bio_integrity_prep(struct bio *bio)
++{
++ return bio_integrity_prep_fn(bio, NULL, NULL);
++}
+ EXPORT_SYMBOL(bio_integrity_prep);
+
+ /**
+@@ -340,7 +358,7 @@ static void bio_integrity_verify_fn(stru
* it's original position.
*/
bio->bi_status = bio_integrity_process(bio, &bip->bio_iter,
- bi->profile->verify_fn);
-+ verify_fn);
++ bip->bip_verify_fn ?: bi->profile->verify_fn);
bio_integrity_free(bio);
bio_endio(bio);
}
-@@ -423,7 +447,9 @@ int bio_integrity_clone(struct bio *bio,
+@@ -423,7 +441,8 @@ int bio_integrity_clone(struct bio *bio,
BUG_ON(bip_src == NULL);
- bip = bio_integrity_alloc(bio, gfp_mask, bip_src->bip_vcnt);
+ bip = bio_integrity_alloc_fn(bio, gfp_mask, bip_src->bip_vcnt,
-+ bip_src->bip_generate_fn,
+ bip_src->bip_verify_fn);
if (IS_ERR(bip))
return PTR_ERR(bip);
-Index: linux-4.18.0-372.19.1.el8_6/include/linux/bio.h
+Index: linux-4.18.0-80.11.2.el8_0/include/linux/bio.h
===================================================================
---- linux-4.18.0-372.19.1.el8_6.orig/include/linux/bio.h
-+++ linux-4.18.0-372.19.1.el8_6/include/linux/bio.h
-@@ -307,8 +307,9 @@ struct bio_integrity_payload {
+--- linux-4.18.0-80.11.2.el8_0.orig/include/linux/bio.h
++++ linux-4.18.0-80.11.2.el8_0/include/linux/bio.h
+@@ -313,7 +313,8 @@ struct bio_integrity_payload {
struct bio_vec *bip_vec;
- RH_KABI_RESERVE(1)
-- RH_KABI_RESERVE(2)
+ /* put after bip_vec as that is last externally-accessed bip_ field */
-+ RH_KABI_USE(1, integrity_processing_fn *bip_generate_fn)
-+ RH_KABI_USE(2, integrity_processing_fn *bip_verify_fn)
++ RH_KABI_USE(1, integrity_processing_fn *bip_verify_fn)
+ RH_KABI_RESERVE(2)
struct bio_vec bip_inline_vecs[0];/* embedded bvec array */
- };
-@@ -728,6 +729,11 @@ static inline bool bioset_initialized(st
+@@ -760,8 +761,15 @@ static inline bool bioset_initialized(st
bip_for_each_vec(_bvl, _bio->bi_integrity, _iter)
extern struct bio_integrity_payload *bio_integrity_alloc(struct bio *, gfp_t, unsigned int);
+extern struct bio_integrity_payload *bio_integrity_alloc_fn(struct bio *bio,
-+ gfp_t gfp_mask,
-+ unsigned int nr_vecs,
-+ integrity_processing_fn *generate_fn,
-+ integrity_processing_fn *verify_fn);
++ gfp_t gfp_mask,
++ unsigned int nr_vecs,
++ integrity_processing_fn *verify_fn);
extern int bio_integrity_add_page(struct bio *, struct page *, unsigned int, unsigned int);
extern bool bio_integrity_prep(struct bio *);
++extern bool bio_integrity_prep_fn(struct bio *bio,
++ integrity_processing_fn *generate_fn,
++ integrity_processing_fn *verify_fn);
extern void bio_integrity_advance(struct bio *, unsigned int);
-Index: linux-4.18.0-80.el8/include/linux/blk_types.h
+ extern void bio_integrity_trim(struct bio *);
+ extern int bio_integrity_clone(struct bio *, struct bio *, gfp_t);
+Index: linux-4.18.0-80.11.2.el8_0/include/linux/blk_types.h
===================================================================
---- linux-4.18.0-80.el8.orig/include/linux/blk_types.h
-+++ linux-4.18.0-80.el8/include/linux/blk_types.h
+--- linux-4.18.0-80.11.2.el8_0.orig/include/linux/blk_types.h
++++ linux-4.18.0-80.11.2.el8_0/include/linux/blk_types.h
@@ -18,6 +18,7 @@ struct page;
struct block_device;
struct io_context;
typedef void (bio_end_io_t) (struct bio *);
/*
-@@ -29,6 +30,9 @@ typedef u32 __bitwise blk_status_t;
- #else
- typedef u8 __bitwise blk_status_t;
- #endif
-+
+@@ -41,6 +42,8 @@ typedef u8 __bitwise blk_status_t;
+ #define BLK_STS_RESOURCE ((__force blk_status_t)9)
+ #define BLK_STS_IOERR ((__force blk_status_t)10)
+
+typedef blk_status_t (integrity_processing_fn) (struct blk_integrity_iter *);
+
- #define BLK_STS_OK 0
- #define BLK_STS_NOTSUPP ((__force blk_status_t)1)
- #define BLK_STS_TIMEOUT ((__force blk_status_t)2)
+ /* hack for device mapper, don't use elsewhere: */
+ #define BLK_STS_DM_REQUEUE ((__force blk_status_t)11)
+
+Index: linux-4.18.0-80.11.2.el8_0/include/linux/blkdev.h
+===================================================================
+--- linux-4.18.0-80.11.2.el8_0.orig/include/linux/blkdev.h
++++ linux-4.18.0-80.11.2.el8_0/include/linux/blkdev.h
+@@ -1505,8 +1505,6 @@ struct blk_integrity_iter {
+ const char *disk_name;
+ };
+
+-typedef blk_status_t (integrity_processing_fn) (struct blk_integrity_iter *);
+-
+ struct blk_integrity_profile {
+ integrity_processing_fn *generate_fn;
+ integrity_processing_fn *verify_fn;