Whamcloud - gitweb
LU-16413 osd-ldiskfs: fix T10PI for CentOS 8.x 41/49441/5
authorLi Dongyang <dongyangli@ddn.com>
Mon, 19 Dec 2022 10:03:47 +0000 (21:03 +1100)
committerOleg Drokin <green@whamcloud.com>
Sat, 7 Jan 2023 07:57:56 +0000 (07:57 +0000)
Recreate the currently broken lustre kernel patches
to allow using custom integrity functions for bio.
Note we don't need to save the generate_fn anymore,
it will be used once we call bio_integrity_prep_fn().

Add upstream fix
b13e0c718568 ("block: bio-integrity: Advance seed correctly
for larger interval sizes") for CentOS 8.0 to 8.6.

Handle the kernel api changes for the T10PI generate and
verify functions introduced in CentOS 8.x kernel,
mostly because of switching to blk_integrity_iter.

Update the custom generate and verify functions, to sync
with upstream versions.
- Add T10-DIF-TYPE2, currently only a place holder,
  not used in upstream either.
- Use __be16 instead of __u16 for guard tags.

Only reuse guard tags if the rpc checksum is the same
one supported on the target. We already have some protection
during checksum type negotiation, the server
will mark the target's T10PI type as the only
T10PI checksum type supported. But it's still good to
have the logic in place.

Do not call bio_integrity_prep() if the custom interface
bio_integrity_prep_fn() does not exist, submit_bio() will
do that for us.

On the servers, show the target's T10PI checksum as
the preferred checksum_type even if it's not the fastest.
Note this is only cosmetic and does not impact the checksum
type used, which is still done during negotiation.

Change-Id: I2d0ba0b80ba9cde2977da24db08095671aa5373c
Test-Parameters: trivial
Fixes: 293844d132 ("LU-16222 kernel: RHEL 8.7 client and server support")
Fixes: f176efd183 ("LU-12269 kernel: RHEL 8.0 server support")
Signed-off-by: Li Dongyang <dongyangli@ddn.com>
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/49441
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Li Xi <lixi@ddn.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
24 files changed:
lustre/autoconf/lustre-core.m4
lustre/include/obd.h
lustre/include/obd_cksum.h
lustre/kernel_patches/patches/block-bio-integrity-Advance-seed-correctly-for-large.patch [new file with mode: 0644]
lustre/kernel_patches/patches/block-integrity-allow-optional-integrity-functions-rhel8.3.patch [moved from lustre/kernel_patches/patches/block-integrity-allow-optional-integrity-functions-rhel8.7.patch with 52% similarity]
lustre/kernel_patches/patches/block-integrity-allow-optional-integrity-functions-rhel8.patch
lustre/kernel_patches/patches/block-pass-bio-into-integrity_processing_fn-rhel8.patch
lustre/kernel_patches/series/4.18-rhel8.1.series
lustre/kernel_patches/series/4.18-rhel8.2.series
lustre/kernel_patches/series/4.18-rhel8.3.series
lustre/kernel_patches/series/4.18-rhel8.4.series
lustre/kernel_patches/series/4.18-rhel8.5.series
lustre/kernel_patches/series/4.18-rhel8.6.series
lustre/kernel_patches/series/4.18-rhel8.7.series
lustre/kernel_patches/series/4.18-rhel8.series
lustre/mdt/mdt_lproc.c
lustre/obdclass/integrity.c
lustre/ofd/lproc_ofd.c
lustre/osc/osc_request.c
lustre/osd-ldiskfs/osd_handler.c
lustre/osd-ldiskfs/osd_integrity.c
lustre/osd-ldiskfs/osd_internal.h
lustre/osd-ldiskfs/osd_io.c
lustre/target/tgt_handler.c

index 2977a4a..99a30be 100644 (file)
@@ -979,6 +979,30 @@ key_match, [
 ]) # 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
@@ -2859,6 +2883,7 @@ AC_DEFUN([LC_PROG_LINUX], [
        # 3.17
        LC_HAVE_INTERVAL_BLK_INTEGRITY
        LC_KEY_MATCH_DATA
+       LC_HAVE_BLK_INTEGRITY_ITER
 
        # 3.18
        LC_PERCPU_COUNTER_INIT
index 3b8e6db..8e33ef0 100644 (file)
@@ -455,7 +455,7 @@ struct niobuf_local {
        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 */
index 029d1a7..1f9f0b1 100644 (file)
@@ -138,13 +138,13 @@ enum cksum_types obd_cksum_type_select(const char *obd_name,
 #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);
 /*
diff --git a/lustre/kernel_patches/patches/block-bio-integrity-Advance-seed-correctly-for-large.patch b/lustre/kernel_patches/patches/block-bio-integrity-Advance-seed-correctly-for-large.patch
new file mode 100644 (file)
index 0000000..149f8f6
--- /dev/null
@@ -0,0 +1,44 @@
+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
+
@@ -15,20 +15,20 @@ Verification shares the same principle: on the server we just
 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.
   */
@@ -38,179 +38,163 @@ Index: linux-4.18.0-80.el8/block/bio-integrity.c
 +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);
index 5b4ba43..aa257c8 100644 (file)
@@ -15,10 +15,10 @@ Verification shares the same principle: on the server we just
 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)
  }
  
@@ -28,7 +28,7 @@ Index: linux-4.18.0-80.el8/block/bio-integrity.c
   * @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.
   */
@@ -38,164 +38,137 @@ Index: linux-4.18.0-80.el8/block/bio-integrity.c
 +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;
@@ -204,13 +177,25 @@ Index: linux-4.18.0-80.el8/include/linux/blk_types.h
  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;
index 44c97e7..1ac4c25 100644 (file)
@@ -2,45 +2,24 @@ Having struct bio allows us to do more in the genrate/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;
@@ -49,4 +28,4 @@ Index: linux-4.18.0-372.19.1.el8_6/include/linux/blkdev.h
 +      RH_KABI_EXTEND(struct bio *bio)
  };
  
- typedef blk_status_t (integrity_processing_fn) (struct blk_integrity_iter *);
+ struct blk_integrity_profile {
index c74f6e8..67fc309 100644 (file)
@@ -1,2 +1,3 @@
+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
index c74f6e8..67fc309 100644 (file)
@@ -1,2 +1,3 @@
+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
index c74f6e8..7c2908c 100644 (file)
@@ -1,2 +1,3 @@
-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
index c74f6e8..7c2908c 100644 (file)
@@ -1,2 +1,3 @@
-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
index c74f6e8..7c2908c 100644 (file)
@@ -1,2 +1,3 @@
-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
index c74f6e8..7c2908c 100644 (file)
@@ -1,2 +1,3 @@
-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
index 2c08c6e..ccf4b53 100644 (file)
@@ -1,2 +1,2 @@
-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
index c74f6e8..67fc309 100644 (file)
@@ -1,2 +1,3 @@
+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
index 64be129..601a199 100644 (file)
@@ -1461,7 +1461,8 @@ static int mdt_checksum_type_seq_show(struct seq_file *m, void *data)
        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)
index e6528f1..1ccec8a 100644 (file)
 #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;
 
@@ -91,7 +91,7 @@ static int __obd_t10_performance_test(const char *obd_name,
        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;
@@ -118,7 +118,7 @@ static int __obd_t10_performance_test(const char *obd_name,
        }
 
        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++) {
                /*
index f24bb16..7f65e98 100644 (file)
@@ -489,7 +489,8 @@ static int ofd_checksum_type_seq_show(struct seq_file *m, void *data)
        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)
index f7323c8..580e4d4 100644 (file)
@@ -1188,7 +1188,7 @@ static int osc_checksum_bulk_t10pi(const char *obd_name, int nob,
        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;
@@ -1212,7 +1212,7 @@ static int osc_checksum_bulk_t10pi(const char *obd_name, int nob,
        }
 
        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",
index 77df8db..759b83f 100644 (file)
@@ -2415,37 +2415,52 @@ static void osd_conf_get(const struct lu_env *env,
                /*
                 * 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 {
@@ -2454,6 +2469,7 @@ static void osd_conf_get(const struct lu_env *env,
                }
        }
 
+out:
        param->ddp_has_lseek_data_hole = true;
 }
 
index 0c1412f..a6b4978 100644 (file)
  * 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;
 
        /*
@@ -74,75 +94,86 @@ static struct niobuf_local *find_lnb(struct blk_integrity_exchg *bix)
  * 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) {
@@ -150,54 +181,55 @@ static int osd_dif_verify(struct blk_integrity_exchg *bix,
                        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,
index 343cef6..a57cfe0 100644 (file)
@@ -249,14 +249,18 @@ struct osd_obj_orphan {
 };
 
 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,
 };
 
 /*
@@ -1637,33 +1641,14 @@ struct osd_bio_private {
 };
 
 #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)
index 4730f6a..a104ae7 100644 (file)
@@ -274,6 +274,21 @@ static int can_be_merged(struct bio *bio, sector_t sector)
 }
 
 #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
@@ -299,8 +314,8 @@ static void bio_integrity_fault_inject(struct bio *bio)
 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;
@@ -332,7 +347,7 @@ static int osd_bio_integrity_compare(struct bio *bio, struct block_device *bdev,
        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;
@@ -363,12 +378,14 @@ static int osd_bio_integrity_compare(struct bio *bio, struct block_device *bdev,
        }
        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;
@@ -383,9 +400,14 @@ static int osd_bio_integrity_handle(struct osd_device *osd, struct bio *bio,
        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) {
@@ -399,25 +421,10 @@ static int osd_bio_integrity_handle(struct osd_device *osd, struct bio *bio,
                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
index 357e2fb..145f993 100644 (file)
@@ -2053,6 +2053,7 @@ static int tgt_pages2shortio(struct niobuf_local *local, int npages,
 }
 
 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,
@@ -2065,7 +2066,7 @@ static int tgt_checksum_niobuf_t10pi(struct lu_target *tgt,
        unsigned int bufsize;
        unsigned char *buffer;
        struct page *__page;
-       __u16 *guard_start;
+       __be16 *guard_start;
        int guard_number;
        int used_number = 0;
        __u32 cksum;
@@ -2086,7 +2087,7 @@ static int tgt_checksum_niobuf_t10pi(struct lu_target *tgt,
        }
 
        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);
@@ -2126,7 +2127,8 @@ static int tgt_checksum_niobuf_t10pi(struct lu_target *tgt,
                 * 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) {
@@ -2148,8 +2150,8 @@ static int tgt_checksum_niobuf_t10pi(struct lu_target *tgt,
                                       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)) {
@@ -2198,7 +2200,8 @@ static int tgt_checksum_niobuf_t10pi(struct lu_target *tgt,
                 * 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,
@@ -2274,7 +2277,8 @@ static int tgt_checksum_niobuf_rw(struct lu_target *tgt,
        obd_t10_cksum2dif(cksum_type, &fn, &sector_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