Add integrity param command line arguments to kublk. Plumb these to
struct ublk_params for the null and fault_inject targets, as they don't
need to actually read or write the integrity data. Forbid the integrity
params for loop or stripe until the integrity data copy is implemented.

Signed-off-by: Caleb Sander Mateos <[email protected]>
---
 tools/testing/selftests/ublk/fault_inject.c |  1 +
 tools/testing/selftests/ublk/file_backed.c  |  4 ++
 tools/testing/selftests/ublk/kublk.c        | 44 +++++++++++++++++++++
 tools/testing/selftests/ublk/kublk.h        | 21 ++++++++++
 tools/testing/selftests/ublk/null.c         |  1 +
 tools/testing/selftests/ublk/stripe.c       |  4 ++
 6 files changed, 75 insertions(+)

diff --git a/tools/testing/selftests/ublk/fault_inject.c 
b/tools/testing/selftests/ublk/fault_inject.c
index b227bd78b252..3b897f69c014 100644
--- a/tools/testing/selftests/ublk/fault_inject.c
+++ b/tools/testing/selftests/ublk/fault_inject.c
@@ -31,10 +31,11 @@ static int ublk_fault_inject_tgt_init(const struct dev_ctx 
*ctx,
                        .io_min_shift           = 9,
                        .max_sectors            = info->max_io_buf_bytes >> 9,
                        .dev_sectors            = dev_size >> 9,
                },
        };
+       ublk_set_integrity_params(ctx, &dev->tgt.params);
 
        dev->private_data = (void *)(unsigned long)(ctx->fault_inject.delay_us 
* 1000);
        return 0;
 }
 
diff --git a/tools/testing/selftests/ublk/file_backed.c 
b/tools/testing/selftests/ublk/file_backed.c
index 269d5f124e06..c14ce6608696 100644
--- a/tools/testing/selftests/ublk/file_backed.c
+++ b/tools/testing/selftests/ublk/file_backed.c
@@ -156,10 +156,14 @@ static int ublk_loop_tgt_init(const struct dev_ctx *ctx, 
struct ublk_dev *dev)
 
        if (ctx->auto_zc_fallback) {
                ublk_err("%s: not support auto_zc_fallback\n", __func__);
                return -EINVAL;
        }
+       if (ctx->metadata_size) {
+               ublk_err("%s: integrity not supported\n", __func__);
+               return -EINVAL;
+       }
 
        ret = backing_file_tgt_init(dev);
        if (ret)
                return ret;
 
diff --git a/tools/testing/selftests/ublk/kublk.c 
b/tools/testing/selftests/ublk/kublk.c
index 185ba553686a..cf58d3b60ace 100644
--- a/tools/testing/selftests/ublk/kublk.c
+++ b/tools/testing/selftests/ublk/kublk.c
@@ -1,10 +1,11 @@
 /* SPDX-License-Identifier: MIT */
 /*
  * Description: uring_cmd based ublk
  */
 
+#include <linux/fs.h>
 #include "kublk.h"
 
 #define MAX_NR_TGT_ARG         64
 
 unsigned int ublk_dbg_mask = UBLK_LOG;
@@ -1547,10 +1548,12 @@ static void __cmd_create_help(char *exe, bool recovery)
        printf("%s %s -t [null|loop|stripe|fault_inject] [-q nr_queues] [-d 
depth] [-n dev_id]\n",
                        exe, recovery ? "recover" : "add");
        printf("\t[--foreground] [--quiet] [-z] [--auto_zc] 
[--auto_zc_fallback] [--debug_mask mask] [-r 0|1] [-g] [-u]\n");
        printf("\t[-e 0|1 ] [-i 0|1] [--no_ublk_fixed_fd]\n");
        printf("\t[--nthreads threads] [--per_io_tasks]\n");
+       printf("\t[--integrity_capable] [--integrity_reftag] [--metadata_size 
SIZE] "
+                "[--pi_offset OFFSET] [--csum_type ip|t10dif|nvme] [--tag_size 
SIZE]\n");
        printf("\t[target options] [backfile1] [backfile2] ...\n");
        printf("\tdefault: nr_queues=2(max 32), depth=128(max 1024), 
dev_id=-1(auto allocation)\n");
        printf("\tdefault: nthreads=nr_queues");
 
        for (i = 0; i < ARRAY_SIZE(tgt_ops_list); i++) {
@@ -1610,20 +1613,27 @@ int main(int argc, char *argv[])
                { "user_copy",          0,      NULL, 'u'},
                { "size",               1,      NULL, 's'},
                { "nthreads",           1,      NULL,  0 },
                { "per_io_tasks",       0,      NULL,  0 },
                { "no_ublk_fixed_fd",   0,      NULL,  0 },
+               { "integrity_capable",  0,      NULL,  0 },
+               { "integrity_reftag",   0,      NULL,  0 },
+               { "metadata_size",      1,      NULL,  0 },
+               { "pi_offset",          1,      NULL,  0 },
+               { "csum_type",          1,      NULL,  0 },
+               { "tag_size",           1,      NULL,  0 },
                { 0, 0, 0, 0 }
        };
        const struct ublk_tgt_ops *ops = NULL;
        int option_idx, opt;
        const char *cmd = argv[1];
        struct dev_ctx ctx = {
                .queue_depth    =       128,
                .nr_hw_queues   =       2,
                .dev_id         =       -1,
                .tgt_type       =       "unknown",
+               .csum_type      =       LBMD_PI_CSUM_NONE,
        };
        int ret = -EINVAL, i;
        int tgt_argc = 1;
        char *tgt_argv[MAX_NR_TGT_ARG] = { NULL };
        int value;
@@ -1694,10 +1704,32 @@ int main(int argc, char *argv[])
                                ctx.nthreads = strtol(optarg, NULL, 10);
                        if (!strcmp(longopts[option_idx].name, "per_io_tasks"))
                                ctx.per_io_tasks = 1;
                        if (!strcmp(longopts[option_idx].name, 
"no_ublk_fixed_fd"))
                                ctx.no_ublk_fixed_fd = 1;
+                       if (!strcmp(longopts[option_idx].name, 
"integrity_capable"))
+                               ctx.integrity_flags |= LBMD_PI_CAP_INTEGRITY;
+                       if (!strcmp(longopts[option_idx].name, 
"integrity_reftag"))
+                               ctx.integrity_flags |= LBMD_PI_CAP_REFTAG;
+                       if (!strcmp(longopts[option_idx].name, "metadata_size"))
+                               ctx.metadata_size = strtoul(optarg, NULL, 0);
+                       if (!strcmp(longopts[option_idx].name, "pi_offset"))
+                               ctx.pi_offset = strtoul(optarg, NULL, 0);
+                       if (!strcmp(longopts[option_idx].name, "csum_type")) {
+                               if (!strcmp(optarg, "ip")) {
+                                       ctx.csum_type = LBMD_PI_CSUM_IP;
+                               } else if (!strcmp(optarg, "t10dif")) {
+                                       ctx.csum_type = 
LBMD_PI_CSUM_CRC16_T10DIF;
+                               } else if (!strcmp(optarg, "nvme")) {
+                                       ctx.csum_type = LBMD_PI_CSUM_CRC64_NVME;
+                               } else {
+                                       ublk_err("invalid csum_type: %s\n", 
optarg);
+                                       return -EINVAL;
+                               }
+                       }
+                       if (!strcmp(longopts[option_idx].name, "tag_size"))
+                               ctx.tag_size = strtoul(optarg, NULL, 0);
                        break;
                case '?':
                        /*
                         * target requires every option must have argument
                         */
@@ -1736,10 +1768,22 @@ int main(int argc, char *argv[])
            ctx.auto_zc_fallback > 1) {
                fprintf(stderr, "too many data copy modes specified\n");
                return -EINVAL;
        }
 
+       if (!ctx.metadata_size && (ctx.integrity_flags ||
+                                  ctx.pi_offset ||
+                                  ctx.csum_type != LBMD_PI_CSUM_NONE ||
+                                  ctx.tag_size)) {
+               ublk_err("integrity parameters require metadata_size\n");
+               return -EINVAL;
+       }
+       if (ctx.metadata_size && !(ctx.flags & UBLK_F_USER_COPY)) {
+               ublk_err("integrity requires user_copy\n");
+               return -EINVAL;
+       }
+
        i = optind;
        while (i < argc && ctx.nr_files < MAX_BACK_FILES) {
                ctx.files[ctx.nr_files++] = argv[i++];
        }
 
diff --git a/tools/testing/selftests/ublk/kublk.h 
b/tools/testing/selftests/ublk/kublk.h
index 8a83b90ec603..d00f2b465cdf 100644
--- a/tools/testing/selftests/ublk/kublk.h
+++ b/tools/testing/selftests/ublk/kublk.h
@@ -76,10 +76,15 @@ struct dev_ctx {
        unsigned int    fg:1;
        unsigned int    recovery:1;
        unsigned int    auto_zc_fallback:1;
        unsigned int    per_io_tasks:1;
        unsigned int    no_ublk_fixed_fd:1;
+       __u32 integrity_flags;
+       __u8 metadata_size;
+       __u8 pi_offset;
+       __u8 csum_type;
+       __u8 tag_size;
 
        int _evtfd;
        int _shmid;
 
        /* built from shmem, only for ublk_dump_dev() */
@@ -200,10 +205,26 @@ struct ublk_dev {
        void *private_data;
 };
 
 extern int ublk_queue_io_cmd(struct ublk_thread *t, struct ublk_io *io);
 
+static inline void ublk_set_integrity_params(const struct dev_ctx *ctx,
+                                            struct ublk_params *params)
+{
+       if (!ctx->metadata_size)
+               return;
+
+       params->types |= UBLK_PARAM_TYPE_INTEGRITY;
+       params->integrity = (struct ublk_param_integrity) {
+               .flags = ctx->integrity_flags,
+               .interval_exp = params->basic.logical_bs_shift,
+               .metadata_size = ctx->metadata_size,
+               .pi_offset = ctx->pi_offset,
+               .csum_type = ctx->csum_type,
+               .tag_size = ctx->tag_size,
+       };
+}
 
 static inline int ublk_io_auto_zc_fallback(const struct ublksrv_io_desc *iod)
 {
        return !!(iod->op_flags & UBLK_IO_F_NEED_REG_BUF);
 }
diff --git a/tools/testing/selftests/ublk/null.c 
b/tools/testing/selftests/ublk/null.c
index 280043f6b689..3aa162f08476 100644
--- a/tools/testing/selftests/ublk/null.c
+++ b/tools/testing/selftests/ublk/null.c
@@ -34,10 +34,11 @@ static int ublk_null_tgt_init(const struct dev_ctx *ctx, 
struct ublk_dev *dev)
                        .seg_boundary_mask      = 4095,
                        .max_segment_size       = 32 << 10,
                        .max_segments           = 32,
                },
        };
+       ublk_set_integrity_params(ctx, &dev->tgt.params);
 
        if (info->flags & UBLK_F_SUPPORT_ZERO_COPY)
                dev->tgt.sq_depth = dev->tgt.cq_depth = 2 * info->queue_depth;
        return 0;
 }
diff --git a/tools/testing/selftests/ublk/stripe.c 
b/tools/testing/selftests/ublk/stripe.c
index fd412e1f01c0..d4aaf3351d71 100644
--- a/tools/testing/selftests/ublk/stripe.c
+++ b/tools/testing/selftests/ublk/stripe.c
@@ -296,10 +296,14 @@ static int ublk_stripe_tgt_init(const struct dev_ctx 
*ctx, struct ublk_dev *dev)
 
        if (ctx->auto_zc_fallback) {
                ublk_err("%s: not support auto_zc_fallback\n", __func__);
                return -EINVAL;
        }
+       if (ctx->metadata_size) {
+               ublk_err("%s: integrity not supported\n", __func__);
+               return -EINVAL;
+       }
 
        if ((chunk_size & (chunk_size - 1)) || !chunk_size) {
                ublk_err("invalid chunk size %u\n", chunk_size);
                return -EINVAL;
        }
-- 
2.45.2


Reply via email to