]) # LC_KEY_MATCH_DATA
#
+# LC_HAVE_BLK_INTEGRITY_ITER
+#
+# Linux commit v3.17-rc5-69-g1859308853b1 replaces
+# struct blk_integrity_exchg with struct blk_integrity_iter
+#
+AC_DEFUN([LC_HAVE_BLK_INTEGRITY_ITER], [
+LB_CHECK_COMPILE([if struct blk_integrity_iter exist],
+blk_integrity_iter, [
+ #ifdef HAVE_LINUX_BLK_INTEGRITY_HEADER
+ # include <linux/blk-integrity.h>
+ #else
+ # include <linux/blkdev.h>
+ #endif
+],[
+ struct blk_integrity_iter iter;
+
+ iter.prot_buf = NULL;
+],[
+ AC_DEFINE(HAVE_BLK_INTEGRITY_ITER, 1,
+ [kernel has struct blk_integrity_iter])
+])
+]) # LC_HAVE_BLK_INTEGRITY_ITER
+
+#
# LC_NFS_FILLDIR_USE_CTX
#
# 3.18 kernel moved from void cookie to struct dir_context
# 3.17
LC_HAVE_INTERVAL_BLK_INTEGRITY
LC_KEY_MATCH_DATA
+ LC_HAVE_BLK_INTEGRITY_ITER
# 3.18
LC_PERCPU_COUNTER_INIT
int lnb_rc;
struct page *lnb_page;
void *lnb_data;
- __u16 lnb_guards[MAX_GUARD_NUMBER];
+ __be16 lnb_guards[MAX_GUARD_NUMBER];
__u16 lnb_guard_rpc:1;
__u16 lnb_guard_disk:1;
/* separate unlock for read path to allow shared access */
#define DECLARE_CKSUM_NAME const char *const cksum_name[] = {"crc32", "adler", \
"crc32c", "reserved", "t10ip512", "t10ip4K", "t10crc512", "t10crc4K"}
-typedef __u16 (obd_dif_csum_fn) (void *, unsigned int);
+typedef __be16 (obd_dif_csum_fn) (void *, unsigned int);
-__u16 obd_dif_crc_fn(void *data, unsigned int len);
-__u16 obd_dif_ip_fn(void *data, unsigned int len);
+__be16 obd_dif_crc_fn(void *data, unsigned int len);
+__be16 obd_dif_ip_fn(void *data, unsigned int len);
int obd_page_dif_generate_buffer(const char *obd_name, struct page *page,
__u32 offset, __u32 length,
- __u16 *guard_start, int guard_number,
+ __be16 *guard_start, int guard_number,
int *used_number, int sector_size,
obd_dif_csum_fn *fn);
/*
--- /dev/null
+From b13e0c71856817fca67159b11abac350e41289f5 Mon Sep 17 00:00:00 2001
+From: "Martin K. Petersen" <martin.petersen@oracle.com>
+Date: Thu, 3 Feb 2022 22:42:09 -0500
+Subject: [PATCH] block: bio-integrity: Advance seed correctly for larger
+ interval sizes
+
+Commit 309a62fa3a9e ("bio-integrity: bio_integrity_advance must update
+integrity seed") added code to update the integrity seed value when
+advancing a bio. However, it failed to take into account that the
+integrity interval might be larger than the 512-byte block layer
+sector size. This broke bio splitting on PI devices with 4KB logical
+blocks.
+
+The seed value should be advanced by bio_integrity_intervals() and not
+the number of sectors.
+
+Cc: Dmitry Monakhov <dmonakhov@openvz.org>
+Cc: stable@vger.kernel.org
+Fixes: 309a62fa3a9e ("bio-integrity: bio_integrity_advance must update integrity seed")
+Tested-by: Dmitry Ivanov <dmitry.ivanov2@hpe.com>
+Reported-by: Alexey Lyashkov <alexey.lyashkov@hpe.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Link: https://lore.kernel.org/r/20220204034209.4193-1-martin.petersen@oracle.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+---
+ block/bio-integrity.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/block/bio-integrity.c b/block/bio-integrity.c
+index d25114715459..0827b19820c5 100644
+--- a/block/bio-integrity.c
++++ b/block/bio-integrity.c
+@@ -373,7 +373,7 @@ void bio_integrity_advance(struct bio *bio, unsigned int bytes_done)
+ struct blk_integrity *bi = blk_get_integrity(bio->bi_bdev->bd_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);
+ }
+
+--
+2.39.0
+
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-240.22.1.el8_3/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-240.22.1.el8_3.orig/block/bio-integrity.c
++++ linux-4.18.0-240.22.1.el8_3/block/bio-integrity.c
@@ -39,7 +39,7 @@ void blk_flush_integrity(void)
}
-
+
/**
- * bio_integrity_alloc - Allocate integrity payload and attach it to bio
+ * bio_integrity_alloc_fn - Allocate integrity payload and attach it to bio
* @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)
-
+@@ -309,7 +321,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;
+@@ -321,6 +333,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);
+
+ /**
+@@ -344,7 +362,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,
-
+@@ -427,7 +445,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-240.22.1.el8_3/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-240.22.1.el8_3.orig/include/linux/bio.h
++++ linux-4.18.0-240.22.1.el8_3/include/linux/bio.h
+@@ -307,7 +307,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
+@@ -744,8 +745,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-423.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-240.22.1.el8_3/include/linux/blk_types.h
===================================================================
---- linux-4.18.0-423.el8.orig/include/linux/blk_types.h
-+++ linux-4.18.0-423.el8/include/linux/blk_types.h
+--- linux-4.18.0-240.22.1.el8_3.orig/include/linux/blk_types.h
++++ linux-4.18.0-240.22.1.el8_3/include/linux/blk_types.h
@@ -18,6 +18,7 @@ struct page;
struct block_device;
struct io_context;
struct cgroup_subsys_state;
+struct blk_integrity_iter;
typedef void (bio_end_io_t) (struct bio *);
-
+
/*
-@@ -31,6 +32,9 @@ typedef u32 blk_short_t;
- typedef u8 __bitwise blk_status_t;
- typedef u16 blk_short_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-240.22.1.el8_3/include/linux/blkdev.h
+===================================================================
+--- linux-4.18.0-240.22.1.el8_3.orig/include/linux/blkdev.h
++++ linux-4.18.0-240.22.1.el8_3/include/linux/blkdev.h
+@@ -1551,7 +1551,6 @@ struct blk_integrity_iter {
+ const char *disk_name;
+ };
+
+-typedef blk_status_t (integrity_processing_fn) (struct blk_integrity_iter *);
+ typedef void (integrity_prepare_fn) (struct request *);
+ typedef void (integrity_complete_fn) (struct request *, unsigned int);
+
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;
like copying a known good guard tag already available rather than
calculating it.
-Index: linux-4.18.0/block/bio-integrity.c
+Index: linux-4.18.0-80.11.2.el8_0/block/bio-integrity.c
===================================================================
---- linux-4.18.0.orig/block/bio-integrity.c
-+++ linux-4.18.0/block/bio-integrity.c
-@@ -209,17 +209,21 @@ static blk_status_t bio_integrity_proces
- blk_status_t ret = BLK_STS_OK;
- void *prot_buf = page_address(bip->bip_vec->bv_page) +
- bip->bip_vec->bv_offset;
-+ unsigned int i;
-
- iter.disk_name = bio->bi_disk->disk_name;
- iter.interval = 1 << bi->interval_exp;
- iter.seed = proc_iter->bi_sector;
- iter.prot_buf = prot_buf;
-
-+ i = 0;
- __bio_for_each_segment(bv, bio, bviter, *proc_iter) {
- void *kaddr = kmap_atomic(bv.bv_page);
+--- 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
+@@ -197,6 +197,8 @@ static blk_status_t bio_integrity_proces
iter.data_buf = kaddr + bv.bv_offset;
iter.data_size = bv.bv_len;
-+ iter.bi_idx = i;
++ iter.bi_idx = bviter.bi_idx;
+ iter.bio = bio;
ret = proc_fn(&iter);
if (ret) {
-@@ -228,6 +232,7 @@ static blk_status_t bio_integrity_proces
- }
-
- kunmap_atomic(kaddr);
-+ i++;
- }
- return ret;
- }
-Index: linux-4.18.0-372.19.1.el8_6/include/linux/blkdev.h
+Index: linux-4.18.0-80.11.2.el8_0/include/linux/blkdev.h
===================================================================
---- linux-4.18.0-372.19.1.el8_6.orig/include/linux/blkdev.h
-+++ linux-4.18.0-372.19.1.el8_6/include/linux/blkdev.h
-@@ -1615,7 +1615,9 @@ struct blk_integrity_iter {
+--- 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
+@@ -1502,7 +1502,9 @@ struct blk_integrity_iter {
sector_t seed;
unsigned int data_size;
unsigned short interval;
+ RH_KABI_EXTEND(struct bio *bio)
};
- typedef blk_status_t (integrity_processing_fn) (struct blk_integrity_iter *);
+ struct blk_integrity_profile {
+block-bio-integrity-Advance-seed-correctly-for-large.patch
block-integrity-allow-optional-integrity-functions-rhel8.patch
block-pass-bio-into-integrity_processing_fn-rhel8.patch
+block-bio-integrity-Advance-seed-correctly-for-large.patch
block-integrity-allow-optional-integrity-functions-rhel8.patch
block-pass-bio-into-integrity_processing_fn-rhel8.patch
-block-integrity-allow-optional-integrity-functions-rhel8.patch
+block-bio-integrity-Advance-seed-correctly-for-large.patch
+block-integrity-allow-optional-integrity-functions-rhel8.3.patch
block-pass-bio-into-integrity_processing_fn-rhel8.patch
-block-integrity-allow-optional-integrity-functions-rhel8.patch
+block-bio-integrity-Advance-seed-correctly-for-large.patch
+block-integrity-allow-optional-integrity-functions-rhel8.3.patch
block-pass-bio-into-integrity_processing_fn-rhel8.patch
-block-integrity-allow-optional-integrity-functions-rhel8.patch
+block-bio-integrity-Advance-seed-correctly-for-large.patch
+block-integrity-allow-optional-integrity-functions-rhel8.3.patch
block-pass-bio-into-integrity_processing_fn-rhel8.patch
-block-integrity-allow-optional-integrity-functions-rhel8.patch
+block-bio-integrity-Advance-seed-correctly-for-large.patch
+block-integrity-allow-optional-integrity-functions-rhel8.3.patch
block-pass-bio-into-integrity_processing_fn-rhel8.patch
-block-integrity-allow-optional-integrity-functions-rhel8.7.patch
+block-integrity-allow-optional-integrity-functions-rhel8.3.patch
block-pass-bio-into-integrity_processing_fn-rhel8.patch
+block-bio-integrity-Advance-seed-correctly-for-large.patch
block-integrity-allow-optional-integrity-functions-rhel8.patch
block-pass-bio-into-integrity_processing_fn-rhel8.patch
lut = obd2obt(obd)->obt_lut;
/* select fastest checksum type on the server */
pref = obd_cksum_type_select(obd->obd_name,
- lut->lut_cksum_types_supported, 0);
+ lut->lut_cksum_types_supported,
+ lut->lut_dt_conf.ddp_t10_cksum_type);
for (i = 0; i < ARRAY_SIZE(cksum_name); i++) {
if ((BIT(i) & lut->lut_cksum_types_supported) == 0)
#include <obd_cksum.h>
#if IS_ENABLED(CONFIG_CRC_T10DIF)
-__u16 obd_dif_crc_fn(void *data, unsigned int len)
+__be16 obd_dif_crc_fn(void *data, unsigned int len)
{
return cpu_to_be16(crc_t10dif(data, len));
}
EXPORT_SYMBOL(obd_dif_crc_fn);
-__u16 obd_dif_ip_fn(void *data, unsigned int len)
+__be16 obd_dif_ip_fn(void *data, unsigned int len)
{
- return ip_compute_csum(data, len);
+ return (__force __be16)ip_compute_csum(data, len);
}
EXPORT_SYMBOL(obd_dif_ip_fn);
int obd_page_dif_generate_buffer(const char *obd_name, struct page *page,
__u32 offset, __u32 length,
- __u16 *guard_start, int guard_number,
+ __be16 *guard_start, int guard_number,
int *used_number, int sector_size,
obd_dif_csum_fn *fn)
{
unsigned int i = offset;
unsigned int end = offset + length;
char *data_buf;
- __u16 *guard_buf = guard_start;
+ __be16 *guard_buf = guard_start;
unsigned int data_size;
int used = 0;
unsigned int bufsize;
unsigned char *buffer;
struct page *__page;
- __u16 *guard_start;
+ __be16 *guard_start;
int guard_number;
int used_number = 0;
int sector_size = 0;
}
buffer = kmap(__page);
- guard_start = (__u16 *)buffer;
+ guard_start = (__be16 *)buffer;
guard_number = PAGE_SIZE / sizeof(*guard_start);
for (i = 0; i < repeat_number; i++) {
/*
lut = obd2obt(obd)->obt_lut;
/* select fastest checksum type on the server */
pref = obd_cksum_type_select(obd->obd_name,
- lut->lut_cksum_types_supported, 0);
+ lut->lut_cksum_types_supported,
+ lut->lut_dt_conf.ddp_t10_cksum_type);
for (i = 0; i < ARRAY_SIZE(cksum_name); i++) {
if ((BIT(i) & lut->lut_cksum_types_supported) == 0)
unsigned char cfs_alg = cksum_obd2cfs(OBD_CKSUM_T10_TOP);
struct page *__page;
unsigned char *buffer;
- __u16 *guard_start;
+ __be16 *guard_start;
unsigned int bufsize;
int guard_number;
int used_number = 0;
}
buffer = kmap(__page);
- guard_start = (__u16 *)buffer;
+ guard_start = (__be16 *)buffer;
guard_number = PAGE_SIZE / sizeof(*guard_start);
CDEBUG(D_PAGE | (resend ? D_HA : 0),
"GRD tags per page=%u, resend=%u, bytes=%u, pages=%zu\n",
/*
* Expected values:
* T10-DIF-TYPE1-CRC
+ * T10-DIF-TYPE2-CRC
* T10-DIF-TYPE3-CRC
* T10-DIF-TYPE1-IP
+ * T10-DIF-TYPE2-IP
* T10-DIF-TYPE3-IP
*/
if (strncmp(name, "T10-DIF-TYPE",
sizeof("T10-DIF-TYPE") - 1) == 0) {
- /* also skip "1/3-" at end */
+ /* also skip "1/2/3-" at end */
const int type_off = sizeof("T10-DIF-TYPE.");
char type_number = name[type_off - 2];
if (interval != 512 && interval != 4096) {
CERROR("%s: unsupported T10PI sector size %u\n",
d->od_svname, interval);
- } else if (type_number != '1' && type_number != '3') {
+ goto out;
+ }
+ switch (type_number) {
+ case '1':
+ d->od_t10_type = OSD_T10_TYPE1;
+ break;
+ case '2':
+ d->od_t10_type = OSD_T10_TYPE2;
+ break;
+ case '3':
+ d->od_t10_type = OSD_T10_TYPE3;
+ break;
+ default:
CERROR("%s: unsupported T10PI type %s\n",
d->od_svname, name);
- } else if (strcmp(name + type_off, "CRC") == 0) {
- d->od_t10_type = type_number == '1' ?
- OSD_T10_TYPE1_CRC : OSD_T10_TYPE3_CRC;
+ goto out;
+ }
+ if (strcmp(name + type_off, "CRC") == 0) {
+ d->od_t10_type |= OSD_T10_TYPE_CRC;
param->ddp_t10_cksum_type = interval == 512 ?
OBD_CKSUM_T10CRC512 :
OBD_CKSUM_T10CRC4K;
} else if (strcmp(name + type_off, "IP") == 0) {
- d->od_t10_type = type_number == '1' ?
- OSD_T10_TYPE1_IP : OSD_T10_TYPE3_IP;
+ d->od_t10_type |= OSD_T10_TYPE_IP;
param->ddp_t10_cksum_type = interval == 512 ?
OBD_CKSUM_T10IP512 :
OBD_CKSUM_T10IP4K;
} else {
CERROR("%s: unsupported checksum type of T10PI type '%s'\n",
d->od_svname, name);
+ d->od_t10_type = 0;
}
} else {
}
}
+out:
param->ddp_has_lseek_data_hole = true;
}
* Codes copied from kernel 3.10.0-862.el7
* drivers/scsi/sd_dif.c and block/t10-pi.c
*/
-#include <linux/blkdev.h>
+#ifdef HAVE_LINUX_BLK_INTEGRITY_HEADER
+ #include <linux/blk-integrity.h>
+#else
+ #include <linux/blkdev.h>
+#endif
#include <linux/blk_types.h>
#include <obd_cksum.h>
#include "osd_internal.h"
#if IS_ENABLED(CONFIG_CRC_T10DIF)
+#ifdef HAVE_BLK_INTEGRITY_ITER
+# define blk_status_gen blk_status_t
+# define RETURN_GEN(_gen_fn) return _gen_fn
+#else
+# define blk_status_gen void
+# define RETURN_GEN(_gen_fn) _gen_fn
+# define blk_integrity_iter blk_integrity_exchg
+# define interval sector_size
+# define seed sector
+# define blk_status_t int
+# define BLK_STS_PROTECTION -EIO
+# define BLK_STS_OK 0
+#endif
/*
* Data Integrity Field tuple.
*/
-struct sd_dif_tuple {
+struct t10_pi_tuple {
__be16 guard_tag; /* Checksum */
__be16 app_tag; /* Opaque storage */
__be32 ref_tag; /* Target LBA or indirect LBA */
};
-static struct niobuf_local *find_lnb(struct blk_integrity_exchg *bix)
+#define T10_PI_APP_ESCAPE cpu_to_be16(0xffff)
+#define T10_PI_REF_ESCAPE cpu_to_be32(0xffffffff)
+
+static struct niobuf_local *find_lnb(struct blk_integrity_iter *iter)
{
- struct bio *bio = bix->bio;
- struct bio_vec *bv = bio_iovec_idx(bio, bix->bi_idx);
+ struct bio *bio = iter->bio;
+ struct bio_vec *bv = &bio->bi_io_vec[iter->bi_idx];
struct osd_bio_private *bio_private = bio->bi_private;
struct osd_iobuf *iobuf = bio_private->obp_iobuf;
- int index = bio_private->obp_start_page_idx + bix->bi_idx;
+ int index = bio_private->obp_start_page_idx + iter->bi_idx;
int i;
/*
* Type 3 protection has a 16-bit guard tag and 16 + 32 bits of opaque
* tag space.
*/
-static void osd_dif_generate(struct blk_integrity_exchg *bix,
- obd_dif_csum_fn *fn, enum osd_t10_type type)
+static blk_status_gen osd_dif_generate(struct blk_integrity_iter *iter,
+ obd_dif_csum_fn *fn, enum osd_t10_type type)
{
- void *buf = bix->data_buf;
- struct sd_dif_tuple *sdt = bix->prot_buf;
- struct niobuf_local *lnb = find_lnb(bix);
- __u16 *guard_buf = lnb ? lnb->lnb_guards : NULL;
- sector_t sector = bix->sector;
+ struct niobuf_local *lnb = find_lnb(iter);
+ __be16 *guard_buf = lnb ? lnb->lnb_guards : NULL;
unsigned int i;
ENTRY;
- for (i = 0 ; i < bix->data_size ; i += bix->sector_size, sdt++) {
+ for (i = 0 ; i < iter->data_size ; i += iter->interval) {
+ struct t10_pi_tuple *pi = iter->prot_buf;
+
if (lnb && lnb->lnb_guard_rpc) {
- sdt->guard_tag = *guard_buf;
+ pi->guard_tag = *guard_buf;
guard_buf++;
} else {
- sdt->guard_tag = fn(buf, bix->sector_size);
+ pi->guard_tag = fn(iter->data_buf, iter->interval);
}
- sdt->app_tag = 0;
+ pi->app_tag = 0;
+
if (type == OSD_T10_TYPE1)
- sdt->ref_tag = cpu_to_be32(sector & 0xffffffff);
+ pi->ref_tag = cpu_to_be32(lower_32_bits(iter->seed));
else /* if (type == OSD_T10_TYPE3) */
- sdt->ref_tag = 0;
+ pi->ref_tag = 0;
- buf += bix->sector_size;
- sector++;
+ iter->data_buf += iter->interval;
+ iter->prot_buf += sizeof(struct t10_pi_tuple);
+ iter->seed++;
}
+
+#ifdef HAVE_BLK_INTEGRITY_ITER
+ RETURN(BLK_STS_OK);
+#else
RETURN_EXIT;
+#endif
}
-static int osd_dif_verify(struct blk_integrity_exchg *bix,
- obd_dif_csum_fn *fn, enum osd_t10_type type)
+static blk_status_t osd_dif_verify(struct blk_integrity_iter *iter,
+ obd_dif_csum_fn *fn, enum osd_t10_type type)
{
- void *buf = bix->data_buf;
- struct sd_dif_tuple *sdt = bix->prot_buf;
- struct niobuf_local *lnb = find_lnb(bix);
- __u16 *guard_buf = lnb ? lnb->lnb_guards : NULL;
- sector_t sector = bix->sector;
+ struct niobuf_local *lnb = find_lnb(iter);
+ __be16 *guard_buf = lnb ? lnb->lnb_guards : NULL;
unsigned int i;
- __u16 csum;
ENTRY;
- for (i = 0 ; i < bix->data_size ; i += bix->sector_size, sdt++) {
- if (type == OSD_T10_TYPE1) {
- /* Unwritten sectors */
- if (sdt->app_tag == 0xffff)
- RETURN(0);
-
- if (be32_to_cpu(sdt->ref_tag) != (sector & 0xffffffff)) {
- CERROR("%s: ref tag error on sector %lu (rcvd %u): rc = %d\n",
- bix->disk_name, (unsigned long)sector,
- be32_to_cpu(sdt->ref_tag), -EIO);
- return -EIO;
+ for (i = 0 ; i < iter->data_size ; i += iter->interval) {
+ struct t10_pi_tuple *pi = iter->prot_buf;
+ __be16 csum;
+
+ if (type == OSD_T10_TYPE1 ||
+ type == OSD_T10_TYPE2) {
+ if (pi->app_tag == T10_PI_APP_ESCAPE) {
+ lnb = NULL;
+ goto next;
+ }
+
+ if (be32_to_cpu(pi->ref_tag) !=
+ lower_32_bits(iter->seed)) {
+ CERROR("%s: ref tag error at location %llu (rcvd %u): rc = %d\n",
+ iter->disk_name,
+ (unsigned long long)iter->seed,
+ be32_to_cpu(pi->ref_tag),
+ BLK_STS_PROTECTION);
+ RETURN(BLK_STS_PROTECTION);
+ }
+ } else if (type == OSD_T10_TYPE3) {
+ if (pi->app_tag == T10_PI_APP_ESCAPE &&
+ pi->ref_tag == T10_PI_REF_ESCAPE) {
+ lnb = NULL;
+ goto next;
}
- } else /* if (type == OSD_T10_TYPE3) */ {
- /* Unwritten sectors */
- if (sdt->app_tag == 0xffff &&
- sdt->ref_tag == 0xffffffff)
- RETURN(0);
}
- csum = fn(buf, bix->sector_size);
+ csum = fn(iter->data_buf, iter->interval);
- if (sdt->guard_tag != csum) {
- CERROR("%s: guard tag error on sector %lu (rcvd %04x, data %04x): rc = %d\n",
- bix->disk_name, (unsigned long)sector,
- be16_to_cpu(sdt->guard_tag), be16_to_cpu(csum),
- -EIO);
- return -EIO;
+ if (pi->guard_tag != csum) {
+ CERROR("%s: guard tag error on sector %llu (rcvd %04x, want %04x): rc = %d\n",
+ iter->disk_name, (unsigned long long)iter->seed,
+ be16_to_cpu(pi->guard_tag), be16_to_cpu(csum),
+ BLK_STS_PROTECTION);
+ RETURN(BLK_STS_PROTECTION);
}
if (guard_buf) {
guard_buf++;
}
- buf += bix->sector_size;
- sector++;
+next:
+ iter->data_buf += iter->interval;
+ iter->prot_buf += sizeof(struct t10_pi_tuple);
+ iter->seed++;
}
if (lnb)
lnb->lnb_guard_disk = 1;
- RETURN(0);
+ RETURN(BLK_STS_OK);
}
-static void osd_dif_type1_generate_crc(struct blk_integrity_exchg *bix)
+static blk_status_gen osd_dif_type1_generate_crc(struct blk_integrity_iter *iter)
{
- osd_dif_generate(bix, obd_dif_crc_fn, OSD_T10_TYPE1);
+ RETURN_GEN(osd_dif_generate(iter, obd_dif_crc_fn, OSD_T10_TYPE1));
}
-static void osd_dif_type1_generate_ip(struct blk_integrity_exchg *bix)
+static blk_status_gen osd_dif_type1_generate_ip(struct blk_integrity_iter *iter)
{
- osd_dif_generate(bix, obd_dif_ip_fn, OSD_T10_TYPE1);
+ RETURN_GEN(osd_dif_generate(iter, obd_dif_ip_fn, OSD_T10_TYPE1));
}
-static void osd_dif_type3_generate_crc(struct blk_integrity_exchg *bix)
+static blk_status_gen osd_dif_type3_generate_crc(struct blk_integrity_iter *iter)
{
- osd_dif_generate(bix, obd_dif_crc_fn, OSD_T10_TYPE3);
+ RETURN_GEN(osd_dif_generate(iter, obd_dif_crc_fn, OSD_T10_TYPE3));
}
-static void osd_dif_type3_generate_ip(struct blk_integrity_exchg *bix)
+static blk_status_gen osd_dif_type3_generate_ip(struct blk_integrity_iter *iter)
{
- osd_dif_generate(bix, obd_dif_ip_fn, OSD_T10_TYPE3);
+ RETURN_GEN(osd_dif_generate(iter, obd_dif_ip_fn, OSD_T10_TYPE3));
}
-
-static int osd_dif_type1_verify_crc(struct blk_integrity_exchg *bix)
+static blk_status_t osd_dif_type1_verify_crc(struct blk_integrity_iter *iter)
{
- return osd_dif_verify(bix, obd_dif_crc_fn, OSD_T10_TYPE1);
+ return osd_dif_verify(iter, obd_dif_crc_fn, OSD_T10_TYPE1);
}
-static int osd_dif_type1_verify_ip(struct blk_integrity_exchg *bix)
+static blk_status_t osd_dif_type1_verify_ip(struct blk_integrity_iter *iter)
{
- return osd_dif_verify(bix, obd_dif_ip_fn, OSD_T10_TYPE1);
+ return osd_dif_verify(iter, obd_dif_ip_fn, OSD_T10_TYPE1);
}
-static int osd_dif_type3_verify_crc(struct blk_integrity_exchg *bix)
+static blk_status_t osd_dif_type3_verify_crc(struct blk_integrity_iter *iter)
{
- return osd_dif_verify(bix, obd_dif_crc_fn, OSD_T10_TYPE3);
+ return osd_dif_verify(iter, obd_dif_crc_fn, OSD_T10_TYPE3);
}
-static int osd_dif_type3_verify_ip(struct blk_integrity_exchg *bix)
+static blk_status_t osd_dif_type3_verify_ip(struct blk_integrity_iter *iter)
{
- return osd_dif_verify(bix, obd_dif_ip_fn, OSD_T10_TYPE3);
+ return osd_dif_verify(iter, obd_dif_ip_fn, OSD_T10_TYPE3);
}
int osd_get_integrity_profile(struct osd_device *osd,
};
enum osd_t10_type {
- OSD_T10_TYPE_UNKNOWN = 0,
- OSD_T10_TYPE1 = 0x1,
- OSD_T10_TYPE3 = 0x2,
- OSD_T10_TYPE_CRC = 0x4,
+ OSD_T10_TYPE_UNKNOWN = 0x00,
+ OSD_T10_TYPE1 = 0x01,
+ OSD_T10_TYPE2 = 0x02,
+ OSD_T10_TYPE3 = 0x04,
+ OSD_T10_TYPE_CRC = 0x08,
+ OSD_T10_TYPE_IP = 0x10,
OSD_T10_TYPE1_CRC = OSD_T10_TYPE1 | OSD_T10_TYPE_CRC,
+ OSD_T10_TYPE2_CRC = OSD_T10_TYPE2 | OSD_T10_TYPE_CRC,
OSD_T10_TYPE3_CRC = OSD_T10_TYPE3 | OSD_T10_TYPE_CRC,
- OSD_T10_TYPE1_IP = OSD_T10_TYPE1,
- OSD_T10_TYPE3_IP = OSD_T10_TYPE3,
+ OSD_T10_TYPE1_IP = OSD_T10_TYPE1 | OSD_T10_TYPE_IP,
+ OSD_T10_TYPE2_IP = OSD_T10_TYPE2 | OSD_T10_TYPE_IP,
+ OSD_T10_TYPE3_IP = OSD_T10_TYPE3 | OSD_T10_TYPE_IP,
};
/*
};
#ifdef HAVE_BIO_INTEGRITY_PREP_FN
+# ifdef HAVE_BLK_INTEGRITY_ITER
+# define integrity_gen_fn integrity_processing_fn
+# define integrity_vrfy_fn integrity_processing_fn
+# endif
int osd_get_integrity_profile(struct osd_device *osd,
integrity_gen_fn **generate_fn,
integrity_vrfy_fn **verify_fn);
-#else
-#define integrity_gen_fn void
-#define integrity_vrfy_fn int
-static inline int osd_get_integrity_profile(struct osd_device *osd,
- integrity_gen_fn **generate_fn,
- integrity_vrfy_fn **verify_fn)
-{
- return 0;
-}
-
-static inline int bio_integrity_prep_fn(struct bio *bio,
- integrity_gen_fn *generate_fn,
- integrity_vrfy_fn *verify_fn)
-{
-#ifdef HAVE_BIO_INTEGRITY_PREP_FN_RETURNS_BOOL
- if (bio_integrity_prep(bio))
- return 0;
- else
- return -EIO;
-#else
- return bio_integrity_prep(bio);
-#endif
-}
-#endif /* HAVE_EXT4_INC_DEC_COUNT_2ARGS */
+#endif /* HAVE_BIO_INTEGRITY_PREP_FN */
#ifdef HAVE_BIO_BI_PHYS_SEGMENTS
#define osd_bio_nr_segs(bio) ((bio)->bi_phys_segments)
}
#if IS_ENABLED(CONFIG_BLK_DEV_INTEGRITY)
+#ifdef HAVE_BIO_INTEGRITY_PREP_FN
+# ifdef HAVE_BIO_ENDIO_USES_ONE_ARG
+static void dio_integrity_complete_routine(struct bio *bio)
+# else
+static void dio_integrity_complete_routine(struct bio *bio, int error)
+# endif
+{
+ struct osd_bio_private *bio_private = bio->bi_private;
+
+ bio->bi_private = bio_private->obp_iobuf;
+ osd_dio_complete_routine(bio, error);
+
+ OBD_FREE_PTR(bio_private);
+}
+
/*
* This function will change the data written, thus it should only be
* used when checking data integrity feature
static int bio_dif_compare(__u16 *expected_guard_buf, void *bio_prot_buf,
unsigned int sectors, int tuple_size)
{
- __u16 *expected_guard;
- __u16 *bio_guard;
+ __be16 *expected_guard;
+ __be16 *bio_guard;
int i;
expected_guard = expected_guard_buf;
sector_t sector = bio_start_sector(bio);
unsigned int i, sectors, total;
DECLARE_BVEC_ITER_ALL(iter_all);
- __u16 *expected_guard;
+ __be16 *expected_guard;
int rc;
total = 0;
}
return 0;
}
+#endif /* HAVE_BIO_INTEGRITY_PREP_FN */
static int osd_bio_integrity_handle(struct osd_device *osd, struct bio *bio,
struct osd_iobuf *iobuf,
int start_page_idx, bool fault_inject,
bool integrity_enabled)
{
+#ifdef HAVE_BIO_INTEGRITY_PREP_FN
struct super_block *sb = osd_sb(osd);
integrity_gen_fn *generate_fn = NULL;
integrity_vrfy_fn *verify_fn = NULL;
if (rc)
RETURN(rc);
+# ifdef HAVE_BIO_INTEGRITY_PREP_FN_RETURNS_BOOL
+ if (!bio_integrity_prep_fn(bio, generate_fn, verify_fn))
+ RETURN(blk_status_to_errno(bio->bi_status));
+# else
rc = bio_integrity_prep_fn(bio, generate_fn, verify_fn);
if (rc)
RETURN(rc);
+# endif
/* Verify and inject fault only when writing */
if (iobuf->dr_rw == 1) {
if (unlikely(fault_inject))
bio_integrity_fault_inject(bio);
}
+#endif /* HAVE_BIO_INTEGRITY_PREP_FN */
RETURN(0);
}
-
-#ifdef HAVE_BIO_INTEGRITY_PREP_FN
-# ifdef HAVE_BIO_ENDIO_USES_ONE_ARG
-static void dio_integrity_complete_routine(struct bio *bio)
-# else
-static void dio_integrity_complete_routine(struct bio *bio, int error)
-# endif
-{
- struct osd_bio_private *bio_private = bio->bi_private;
-
- bio->bi_private = bio_private->obp_iobuf;
- osd_dio_complete_routine(bio, error);
-
- OBD_FREE_PTR(bio_private);
-}
-#endif /* HAVE_BIO_INTEGRITY_PREP_FN */
#else /* !CONFIG_BLK_DEV_INTEGRITY */
#define osd_bio_integrity_handle(osd, bio, iobuf, start_page_idx, \
fault_inject, integrity_enabled) 0
}
static int tgt_checksum_niobuf_t10pi(struct lu_target *tgt,
+ enum cksum_types cksum_type,
struct niobuf_local *local_nb, int npages,
int opc, obd_dif_csum_fn *fn,
int sector_size, u32 *check_sum,
unsigned int bufsize;
unsigned char *buffer;
struct page *__page;
- __u16 *guard_start;
+ __be16 *guard_start;
int guard_number;
int used_number = 0;
__u32 cksum;
}
buffer = kmap(__page);
- guard_start = (__u16 *)buffer;
+ guard_start = (__be16 *)buffer;
guard_number = PAGE_SIZE / sizeof(*guard_start);
if (unlikely(resend))
CDEBUG(D_PAGE | D_HA, "GRD tags per page = %u\n", guard_number);
* The left guard number should be able to hold checksums of a
* whole page
*/
- use_t10_grd = t10_cksum_type && opc == OST_READ &&
+ use_t10_grd = t10_cksum_type && t10_cksum_type == cksum_type &&
+ opc == OST_READ &&
local_nb[i].lnb_len == PAGE_SIZE &&
local_nb[i].lnb_guard_disk;
if (use_t10_grd) {
guard_start + used_number);
}
if (!use_t10_grd || unlikely(resend)) {
- __u16 guard_tmp[MAX_GUARD_NUMBER];
- __u16 *guards = guard_start + used_number;
+ __be16 guard_tmp[MAX_GUARD_NUMBER];
+ __be16 *guards = guard_start + used_number;
int used_tmp = -1, *usedp = &used;
if (unlikely(use_t10_grd)) {
* partial page write, but it will only add minimal extra time
* of checksum calculation.
*/
- if (t10_cksum_type && opc == OST_WRITE &&
+ if (t10_cksum_type && t10_cksum_type == cksum_type &&
+ opc == OST_WRITE &&
local_nb[i].lnb_len == PAGE_SIZE) {
local_nb[i].lnb_guard_rpc = 1;
memcpy(local_nb[i].lnb_guards,
obd_t10_cksum2dif(cksum_type, &fn, §or_size);
if (fn)
- rc = tgt_checksum_niobuf_t10pi(tgt, local_nb, npages,
+ rc = tgt_checksum_niobuf_t10pi(tgt, cksum_type,
+ local_nb, npages,
opc, fn, sector_size,
check_sum, resend);
else