]> www.infradead.org Git - users/sagi/nvme-cli.git/commitdiff
nvme: 64-bit Reference Tags and TP-4068 changes
authorBrandon Paupore <brandon.paupore@wdc.com>
Fri, 18 Mar 2022 22:03:06 +0000 (17:03 -0500)
committerDaniel Wagner <dwagner@suse.de>
Thu, 2 Jun 2022 07:52:07 +0000 (09:52 +0200)
Signed-off-by: Brandon Paupore <brandon.paupore@wdc.com>
Signed-off-by: Jeff Lien <jeff.lien@wdc.com>
nvme-print.c
nvme.c
plugins/zns/zns.c

index 63987333a3b3e43a0927509ff1d5eed46def4e25..7d264490cb97f2fc9f76f310d18f88abb52ec3e7 100644 (file)
@@ -4797,12 +4797,14 @@ static void json_nvme_nvm_id_ns(struct nvme_nvm_id_ns *nvm_ns,
 
 static void nvme_show_nvm_id_ns_pic(__u8 pic)
 {
-       __u8 rsvd = (pic & 0xFC) >> 2;
+       __u8 rsvd = (pic & 0xF8) >> 3;
+       __u8 stcrs = (pic & 0x3) >> 2;
        __u8 pic_16bpistm = (pic & 0x2) >> 1;
        __u8 pic_16bpists = pic & 0x1;
 
        if (rsvd)
-               printf("  [7:2] : %#x\tReserved\n", rsvd);
+               printf("  [7:3] : %#x\tReserved\n", rsvd);
+       printf("  [2:2] : %#x\tStorage Tag Check Read Support\n", stcrs);
        printf("  [1:1] : %#x\t16b Guard Protection Information Storage Tag Mask\n",
                pic_16bpistm);
        printf("  [0:0] : %#x\t16b Guard Protection Information Storage Tag Support\n",
diff --git a/nvme.c b/nvme.c
index 0f951d6f17e8a747c2a3c93d226a148677fe8cb4..bd6a6addf8906d9e47d5bedba727d579aae9ca61 100644 (file)
--- a/nvme.c
+++ b/nvme.c
@@ -2438,7 +2438,7 @@ static int create_ns(int argc, char **argv, struct command *cmd, struct plugin *
                        }
                        goto close_fd;
                }
-               for (i = 0; i < 16; ++i) {
+               for (i = 0; i < ns.nlbaf; ++i) {
                        if ((1 << ns.lbaf[i].ds) == cfg.bs && ns.lbaf[i].ms == 0) {
                                cfg.flbas = i;
                                break;
@@ -4742,7 +4742,7 @@ static int format(int argc, char **argv, struct command *cmd, struct plugin *plu
                nvme_id_ns_flbas_to_lbaf_inuse(ns.flbas, &prev_lbaf);
 
                if (cfg.bs) {
-                       for (i = 0; i < 16; ++i) {
+                       for (i = 0; i < ns.nlbaf; ++i) {
                                if ((1ULL << ns.lbaf[i].ds) == cfg.bs &&
                                    ns.lbaf[i].ms == 0) {
                                        cfg.lbaf = i;
@@ -4770,7 +4770,7 @@ static int format(int argc, char **argv, struct command *cmd, struct plugin *plu
                err = -EINVAL;
                goto close_fd;
        }
-       if (cfg.lbaf > 15) {
+       if (cfg.lbaf > 63) {
                fprintf(stderr, "invalid lbaf:%d\n", cfg.lbaf);
                err = -EINVAL;
                goto close_fd;
@@ -4807,7 +4807,8 @@ static int format(int argc, char **argv, struct command *cmd, struct plugin *plu
                .args_size      = sizeof(args),
                .fd             = fd,
                .nsid           = cfg.namespace_id,
-               .lbaf           = cfg.lbaf,
+               .lbafu          = (cfg.lbaf & NVME_NS_FLBAS_HIGHER_MASK) >> 4,
+               .lbaf           = cfg.lbaf & NVME_NS_FLBAS_LOWER_MASK,
                .mset           = cfg.ms,
                .pi             = cfg.pi,
                .pil            = cfg.pil,
@@ -5398,10 +5399,47 @@ ret:
        return err;
 }
 
+static int invalid_tags(__u64 storage_tag, __u64 ref_tag, __u8 sts, __u8 pif)
+{
+       int result = 0;
+
+       if (sts < 64 && storage_tag >= (1LL << sts)) {
+               fprintf(stderr, "Storage tag larger than storage tag size\n");
+               return 1;
+       }
+
+       switch (pif) {
+       case 0:
+               if (ref_tag >= (1LL << (32 - sts)))
+                       result = 1;
+               break;
+       case 1:
+               if (sts > 16 && ref_tag >= (1LL << (80 - sts)))
+                       result = 1;
+               break;
+       case 2:
+               if (sts > 0 && ref_tag >= (1LL << (64 - sts)))
+                       result = 1;
+               break;
+       default:
+               fprintf(stderr, "Invalid PIF\n");
+               result = 1;
+       }
+
+       if (result)
+               fprintf(stderr, "Reference tag larger than allowed by PIF\n");
+       
+       return result;
+}
+
 static int write_zeroes(int argc, char **argv, struct command *cmd, struct plugin *plugin)
 {
        int err, fd;
        __u16 control = 0;
+       __u8 lba_index, sts = 0, pif = 0;
+       struct nvme_id_ns ns;
+       struct nvme_nvm_id_ns nvm_ns;
+
        const char *desc = "The Write Zeroes command is used to set a "\
                        "range of logical blocks to zero.";
        const char *namespace_id = "desired namespace";
@@ -5410,11 +5448,10 @@ static int write_zeroes(int argc, char **argv, struct command *cmd, struct plugi
        const char *limited_retry = "limit media access attempts";
        const char *force_unit_access = "force device to commit data before command completes";
        const char *prinfo = "PI and check field";
-       const char *ref_tag = "reference tag (for end to end PI)";
-       const char *app_tag_mask = "app tag mask (for end to end PI)";
-       const char *app_tag = "app tag (for end to end PI)";
-       const char *storage_tag = "storage tag, CDW2 and CDW3 (00:47) bits "\
-               "(for end to end PI)";
+       const char *ref_tag = "reference tag for end-to-end PI";
+       const char *app_tag_mask = "app tag mask for end-to-end PI";
+       const char *app_tag = "app tag for end-to-end PI";
+       const char *storage_tag = "storage tag for end-to-end PI";
        const char *deac = "Set DEAC bit, requesting controller to deallocate specified logical blocks";
        const char *storage_tag_check = "This bit specifies the Storage Tag field shall be checked as "\
                "part of end-to-end data protection processing";
@@ -5427,7 +5464,7 @@ static int write_zeroes(int argc, char **argv, struct command *cmd, struct plugi
                bool    limited_retry;
                bool    force_unit_access;
                __u8    prinfo;
-               __u32   ref_tag;
+               __u64   ref_tag;
                __u16   app_tag_mask;
                __u16   app_tag;
                __u64   storage_tag;
@@ -5457,7 +5494,7 @@ static int write_zeroes(int argc, char **argv, struct command *cmd, struct plugi
                OPT_FLAG("limited-retry",     'l', &cfg.limited_retry,     limited_retry),
                OPT_FLAG("force-unit-access", 'f', &cfg.force_unit_access, force_unit_access),
                OPT_BYTE("prinfo",            'p', &cfg.prinfo,            prinfo),
-               OPT_UINT("ref-tag",           'r', &cfg.ref_tag,           ref_tag),
+               OPT_SUFFIX("ref-tag",         'r', &cfg.ref_tag,           ref_tag),
                OPT_SHRT("app-tag-mask",      'm', &cfg.app_tag_mask,      app_tag_mask),
                OPT_SHRT("app-tag",           'a', &cfg.app_tag,           app_tag),
                OPT_SUFFIX("storage-tag",     'S', &cfg.storage_tag,       storage_tag),
@@ -5491,6 +5528,27 @@ static int write_zeroes(int argc, char **argv, struct command *cmd, struct plugi
                }
        }
 
+       err = nvme_identify_ns(fd, cfg.namespace_id, &ns);
+       if (err) {
+               nvme_show_status(err);
+               goto close_fd;
+       } else if (err < 0) {
+               fprintf(stderr, "identify namespace: %s\n", nvme_strerror(errno));
+               goto close_fd;
+       }
+
+       err = nvme_identify_ns_csi(fd, cfg.namespace_id, 0, NVME_CSI_NVM, &nvm_ns);
+       if (!err) {
+               nvme_id_ns_flbas_to_lbaf_inuse(ns.flbas, &lba_index);
+               sts = nvm_ns.elbaf[lba_index] & NVME_NVM_ELBAF_STS_MASK;
+               pif = (nvm_ns.elbaf[lba_index] & NVME_NVM_ELBAF_PIF_MASK) >> 7; 
+       }
+
+       if (invalid_tags(cfg.storage_tag, cfg.ref_tag, sts, pif)) {
+               err = -EINVAL;
+               goto close_fd;
+       }
+
        struct nvme_io_args args = {
                .args_size      = sizeof(args),
                .fd             = fd,
@@ -5498,9 +5556,11 @@ static int write_zeroes(int argc, char **argv, struct command *cmd, struct plugi
                .slba           = cfg.start_block,
                .nlb            = cfg.block_count,
                .control        = control,
-               .reftag         = cfg.ref_tag,
+               .reftag_u64     = cfg.ref_tag,
                .apptag         = cfg.app_tag,
                .appmask        = cfg.app_tag_mask,
+               .sts            = sts,
+               .pif            = pif,
                .storage_tag    = cfg.storage_tag,
                .timeout        = NVME_DEFAULT_IOCTL_TIMEOUT,
                .result         = NULL,
@@ -5653,10 +5713,19 @@ static int copy(int argc, char **argv, struct command *cmd, struct plugin *plugi
        uint16_t nr, nb, ns, nrts, natms, nats;
        __u16 nlbs[128] = { 0 };
        unsigned long long slbas[128] = {0,};
-       __u32 eilbrts[128] = { 0 };
+
+       union {
+               __u32 f0[128];
+               __u64 f1[101];
+       } eilbrts;
+
        __u32 elbatms[128] = { 0 };
        __u32 elbats[128] = { 0 };
-       struct nvme_copy_range copy[128];
+
+       union {
+               struct nvme_copy_range f0[128];
+               struct nvme_copy_range_f1 f1[101];
+       } copy;
 
        struct config {
                __u32   namespace_id;
@@ -5667,12 +5736,12 @@ static int copy(int argc, char **argv, struct command *cmd, struct plugin *plugi
                bool    fua;
                __u8    prinfow;
                __u8    prinfor;
-               __u32   ilbrt;
+               __u64   ilbrt;
                char    *eilbrts;
                __u16   lbat;
-               char    *elbatms;
-               __u16   lbatm;
                char    *elbats;
+               __u16   lbatm;
+               char    *elbatms;
                __u8    dtype;
                __u16   dspec;
                __u8    format;
@@ -5707,7 +5776,7 @@ static int copy(int argc, char **argv, struct command *cmd, struct plugin *plugi
                OPT_FLAG("force-unit-access",      'f', &cfg.fua,               d_fua),
                OPT_BYTE("prinfow",                'p', &cfg.prinfow,           d_prinfow),
                OPT_BYTE("prinfor",                'P', &cfg.prinfor,           d_prinfor),
-               OPT_UINT("ref-tag",                'r', &cfg.ilbrt,             d_ilbrt),
+               OPT_SUFFIX("ref-tag",              'r', &cfg.ilbrt,             d_ilbrt),
                OPT_LIST("expected-ref-tags",      'R', &cfg.eilbrts,           d_eilbrts),
                OPT_SHRT("app-tag",                'a', &cfg.lbat,              d_lbat),
                OPT_LIST("expected-app-tags",      'A', &cfg.elbats,            d_elbats),
@@ -5727,12 +5796,22 @@ static int copy(int argc, char **argv, struct command *cmd, struct plugin *plugi
 
        nb = argconfig_parse_comma_sep_array(cfg.nlbs, (int *)nlbs, ARRAY_SIZE(nlbs));
        ns = argconfig_parse_comma_sep_array_long(cfg.slbas, slbas, ARRAY_SIZE(slbas));
-       nrts = argconfig_parse_comma_sep_array(cfg.eilbrts, (int *)eilbrts, ARRAY_SIZE(eilbrts));
+       
+       if (cfg.format == 0)
+               nrts = argconfig_parse_comma_sep_array(cfg.eilbrts, (int *)eilbrts.f0, ARRAY_SIZE(eilbrts.f0));
+       else if (cfg.format == 1)
+               nrts = argconfig_parse_comma_sep_array_long(cfg.eilbrts, (__u64 *)eilbrts.f1, ARRAY_SIZE(eilbrts.f1));
+       else {
+               fprintf(stderr, "invalid format\n");
+               err = -EINVAL;
+               goto close_fd;
+       }
+
        natms = argconfig_parse_comma_sep_array(cfg.elbatms, (int *)elbatms, ARRAY_SIZE(elbatms));
        nats = argconfig_parse_comma_sep_array(cfg.elbats, (int *)elbats, ARRAY_SIZE(elbats));
 
        nr = max(nb, max(ns, max(nrts, max(natms, nats))));
-       if (!nr || nr > 128) {
+       if (!nr || nr > 128 || (cfg.format == 1 && nr > 101)) {
                fprintf(stderr, "invalid range\n");
                err = -EINVAL;
                goto close_fd;
@@ -5746,13 +5825,18 @@ static int copy(int argc, char **argv, struct command *cmd, struct plugin *plugi
                }
        }
 
-       nvme_init_copy_range(copy, nlbs, (__u64 *)slbas, eilbrts, elbatms, elbats, nr);
+       if (cfg.format == 0)
+               nvme_init_copy_range(copy.f0, nlbs, (__u64 *)slbas,
+                 eilbrts.f0, elbatms, elbats, nr);
+       else if (cfg.format == 1)
+               nvme_init_copy_range_f1(copy.f1, nlbs, (__u64 *)slbas,
+                 eilbrts.f1, elbatms, elbats, nr);
 
        struct nvme_copy_args args = {
                .args_size      = sizeof(args),
                .fd             = fd,
                .nsid           = cfg.namespace_id,
-               .copy           = copy,
+               .copy           = copy.f0,
                .sdlba          = cfg.sdlba,
                .nr             = nr,
                .prinfor        = cfg.prinfor,
@@ -5762,7 +5846,8 @@ static int copy(int argc, char **argv, struct command *cmd, struct plugin *plugi
                .format         = cfg.format,
                .lr             = cfg.lr,
                .fua            = cfg.fua,
-               .ilbrt          = cfg.ilbrt,
+               .prinfow        = cfg.prinfow,
+               .ilbrt_u64      = cfg.ilbrt,
                .lbatm          = cfg.lbatm,
                .lbat           = cfg.lbat,
                .timeout        = NVME_DEFAULT_IOCTL_TIMEOUT,
@@ -6210,14 +6295,15 @@ static int submit_io(int opcode, char *command, const char *desc,
        unsigned long long buffer_size = 0, mbuffer_size = 0;
        bool huge;
        struct nvme_id_ns ns;
-       __u8 lba_index, ms = 0;
+       struct nvme_nvm_id_ns nvm_ns;
+       __u8 lba_index, ms = 0, sts = 0, pif = 0;
 
        const char *namespace_id = "Identifier of desired namespace";
        const char *start_block = "64-bit addr of first block to access";
        const char *block_count = "number of blocks (zeroes based) on device to access";
        const char *data_size = "size of data in bytes";
        const char *metadata_size = "size of metadata in bytes";
-       const char *ref_tag = "reference tag (for end to end PI)";
+       const char *ref_tag = "reference tag for end-to-end PI";
        const char *data = "data file";
        const char *metadata = "metadata file";
        const char *prinfo = "PI and check field";
@@ -6233,8 +6319,7 @@ static int submit_io(int opcode, char *command, const char *desc,
        const char *dsm = "dataset management attributes (lower 8 bits)";
        const char *storage_tag_check = "This bit specifies the Storage Tag field shall be " \
                "checked as part of end-to-end data protection processing";
-       const char *storage_tag = "storage tag, CDW2 and CDW3 (00:47) bits "\
-               "(for end to end PI)";
+       const char *storage_tag = "storage tag for end-to-end PI";
        const char *force = "The \"I know what I'm doing\" flag, do not enforce exclusive access for write";
 
        struct config {
@@ -6243,7 +6328,7 @@ static int submit_io(int opcode, char *command, const char *desc,
                __u16   block_count;
                __u64   data_size;
                __u64   metadata_size;
-               __u32   ref_tag;
+               __u64   ref_tag;
                char    *data;
                char    *metadata;
                __u8    prinfo;
@@ -6293,7 +6378,7 @@ static int submit_io(int opcode, char *command, const char *desc,
                OPT_SHRT("block-count",       'c', &cfg.block_count,       block_count),
                OPT_SUFFIX("data-size",       'z', &cfg.data_size,         data_size),
                OPT_SUFFIX("metadata-size",   'y', &cfg.metadata_size,     metadata_size),
-               OPT_UINT("ref-tag",           'r', &cfg.ref_tag,           ref_tag),
+               OPT_SUFFIX("ref-tag",         'r', &cfg.ref_tag,           ref_tag),
                OPT_FILE("data",              'd', &cfg.data,              data),
                OPT_FILE("metadata",          'M', &cfg.metadata,          metadata),
                OPT_BYTE("prinfo",            'p', &cfg.prinfo,            prinfo),
@@ -6422,8 +6507,16 @@ static int submit_io(int opcode, char *command, const char *desc,
                        fprintf(stderr, "identify namespace: %s\n", nvme_strerror(errno));
                        goto free_buffer;
                }
+
                nvme_id_ns_flbas_to_lbaf_inuse(ns.flbas, &lba_index);
                ms = ns.lbaf[lba_index].ms;
+
+               err = nvme_identify_ns_csi(fd, 1, 0, NVME_CSI_NVM, &nvm_ns);
+               if (!err) {
+                       sts = nvm_ns.elbaf[lba_index] & NVME_NVM_ELBAF_STS_MASK;
+                       pif = (nvm_ns.elbaf[lba_index] & NVME_NVM_ELBAF_PIF_MASK) >> 7; 
+               }
+
                mbuffer_size = ((unsigned long long)cfg.block_count + 1) * ms;
                if (ms && cfg.metadata_size < mbuffer_size) {
                        fprintf(stderr, "Rounding metadata size to fit block count (%lld bytes)\n",
@@ -6439,6 +6532,11 @@ static int submit_io(int opcode, char *command, const char *desc,
                memset(mbuffer, 0, mbuffer_size);
        }
 
+       if (invalid_tags(cfg.storage_tag, cfg.ref_tag, sts, pif)) {
+               err = -EINVAL;
+               goto free_buffer;
+       }
+
        if ((opcode & 1)) {
                err = read(dfd, (void *)buffer, cfg.data_size);
                if (err < 0) {
@@ -6469,11 +6567,13 @@ static int submit_io(int opcode, char *command, const char *desc,
                printf("addr         : %"PRIx64"\n", (uint64_t)(uintptr_t)buffer);
                printf("slba         : %"PRIx64"\n", (uint64_t)cfg.start_block);
                printf("dsmgmt       : %08x\n", dsmgmt);
-               printf("reftag       : %08x\n", cfg.ref_tag);
+               printf("reftag       : %"PRIx64"\n", (uint64_t)cfg.ref_tag);
                printf("apptag       : %04x\n", cfg.app_tag);
                printf("appmask      : %04x\n", cfg.app_tag_mask);
                printf("storagetagcheck : %04x\n", cfg.storage_tag_check);
                printf("storagetag      : %"PRIx64"\n", (uint64_t)cfg.storage_tag);
+               printf("pif             : %02x\n", pif);
+               printf("sts             : %02x\n", sts);
        }
        if (cfg.dry_run)
                goto free_mbuffer;
@@ -6486,8 +6586,10 @@ static int submit_io(int opcode, char *command, const char *desc,
                .nlb            = cfg.block_count,
                .control        = control,
                .dsm            = cfg.dsmgmt,
+               .sts            = sts,
+               .pif            = pif,
                .dspec          = cfg.dspec,
-               .reftag         = cfg.ref_tag,
+               .reftag_u64     = cfg.ref_tag,
                .apptag         = cfg.app_tag,
                .appmask        = cfg.app_tag_mask,
                .storage_tag    = cfg.storage_tag,
@@ -6567,6 +6669,10 @@ static int verify_cmd(int argc, char **argv, struct command *cmd, struct plugin
 {
        int err, fd;
        __u16 control = 0;
+       __u8 lba_index, sts = 0, pif = 0;
+       struct nvme_id_ns ns;
+       struct nvme_nvm_id_ns nvm_ns;
+
        const char *desc = "Verify specified logical blocks on the given device.";
        const char *namespace_id = "desired namespace";
        const char *start_block = "64-bit LBA of first block to access";
@@ -6574,11 +6680,10 @@ static int verify_cmd(int argc, char **argv, struct command *cmd, struct plugin
        const char *limited_retry = "limit media access attempts";
        const char *force_unit_access = "force device to commit cached data before performing the verify operation";
        const char *prinfo = "PI and check field";
-       const char *ref_tag = "reference tag (for end to end PI)";
-       const char *app_tag_mask = "app tag mask (for end to end PI)";
-       const char *app_tag = "app tag (for end to end PI)";
-       const char *storage_tag = "storage tag, CDW2 and CDW3 (00:47) bits "\
-               "(for end to end PI)";
+       const char *ref_tag = "reference tag for end-to-end PI";
+       const char *app_tag_mask = "app tag mask for end-to-end PI";
+       const char *app_tag = "app tag for end-to-end PI";
+       const char *storage_tag = "storage tag for end-to-end PI";
        const char *storage_tag_check = "This bit specifies the Storage Tag field shall "\
                "be checked as part of Verify operation";
 
@@ -6617,7 +6722,7 @@ static int verify_cmd(int argc, char **argv, struct command *cmd, struct plugin
                OPT_FLAG("limited-retry",     'l', &cfg.limited_retry,     limited_retry),
                OPT_FLAG("force-unit-access", 'f', &cfg.force_unit_access, force_unit_access),
                OPT_BYTE("prinfo",            'p', &cfg.prinfo,            prinfo),
-               OPT_UINT("ref-tag",           'r', &cfg.ref_tag,           ref_tag),
+               OPT_SUFFIX("ref-tag",         'r', &cfg.ref_tag,           ref_tag),
                OPT_SHRT("app-tag",           'a', &cfg.app_tag,           app_tag),
                OPT_SHRT("app-tag-mask",      'm', &cfg.app_tag_mask,      app_tag_mask),
                OPT_SUFFIX("storage-tag",     'S', &cfg.storage_tag,       storage_tag),
@@ -6650,6 +6755,27 @@ static int verify_cmd(int argc, char **argv, struct command *cmd, struct plugin
                }
        }
 
+       err = nvme_identify_ns(fd, cfg.namespace_id, &ns);
+       if (err) {
+               nvme_show_status(err);
+               goto close_fd;
+       } else if (err < 0) {
+               fprintf(stderr, "identify namespace: %s\n", nvme_strerror(errno));
+               goto close_fd;
+       }
+
+       err = nvme_identify_ns_csi(fd, cfg.namespace_id, 0, NVME_CSI_NVM, &nvm_ns);
+       if (!err) {
+               nvme_id_ns_flbas_to_lbaf_inuse(ns.flbas, &lba_index);
+               sts = nvm_ns.elbaf[lba_index] & NVME_NVM_ELBAF_STS_MASK;
+               pif = (nvm_ns.elbaf[lba_index] & NVME_NVM_ELBAF_PIF_MASK) >> 7;
+       }
+
+       if (invalid_tags(cfg.storage_tag, cfg.ref_tag, sts, pif)) {
+               err = -EINVAL;
+               goto close_fd;
+       }
+
        struct nvme_io_args args = {
                .args_size      = sizeof(args),
                .fd             = fd,
@@ -6657,9 +6783,11 @@ static int verify_cmd(int argc, char **argv, struct command *cmd, struct plugin
                .slba           = cfg.start_block,
                .nlb            = cfg.block_count,
                .control        = control,
-               .reftag         = cfg.ref_tag,
+               .reftag_u64     = cfg.ref_tag,
                .apptag         = cfg.app_tag,
                .appmask        = cfg.app_tag_mask,
+               .sts            = sts,
+               .pif            = pif,
                .storage_tag    = cfg.storage_tag,
                .timeout        = NVME_DEFAULT_IOCTL_TIMEOUT,
                .result         = NULL,
index ab29d10f34b423556bd5b7cd1bf58c68a59bda12..0b96346fc30a8268e7761f560767dc9dac0687a6 100644 (file)
@@ -1018,9 +1018,9 @@ static int zone_append(int argc, char **argv, struct command *cmd, struct plugin
        const char *fua = "force unit access";
        const char *prinfo = "protection information action and checks field";
        const char *piremap = "protection information remap (for type 1 PI)";
-       const char *ref_tag = "reference tag (for end to end PI)";
-       const char *lbat = "logical block application tag (for end to end PI)";
-       const char *lbatm = "logical block application tag mask (for end to end PI)";
+       const char *ref_tag = "reference tag for end-to-end PI";
+       const char *lbat = "logical block application tag for end-to-end PI";
+       const char *lbatm = "logical block application tag mask for end-to-end PI";
        const char *metadata_size = "size of metadata in bytes";
        const char *data_size = "size of data in bytes";
        const char *latency = "output latency statistics";
@@ -1044,7 +1044,7 @@ static int zone_append(int argc, char **argv, struct command *cmd, struct plugin
                bool   limited_retry;
                bool   fua;
                __u32  namespace_id;
-               __u32  ref_tag;
+               __u64  ref_tag;
                __u16  lbat;
                __u16  lbatm;
                __u8   prinfo;
@@ -1063,7 +1063,7 @@ static int zone_append(int argc, char **argv, struct command *cmd, struct plugin
                OPT_FILE("metadata",          'M', &cfg.metadata,      metadata),
                OPT_FLAG("limited-retry",     'l', &cfg.limited_retry, limited_retry),
                OPT_FLAG("force-unit-access", 'f', &cfg.fua,           fua),
-               OPT_UINT("ref-tag",           'r', &cfg.ref_tag,       ref_tag),
+               OPT_SUFFIX("ref-tag",         'r', &cfg.ref_tag,       ref_tag),
                OPT_SHRT("app-tag-mask",      'm', &cfg.lbatm,         lbatm),
                OPT_SHRT("app-tag",           'a', &cfg.lbat,          lbat),
                OPT_BYTE("prinfo",            'p', &cfg.prinfo,        prinfo),
@@ -1184,7 +1184,7 @@ static int zone_append(int argc, char **argv, struct command *cmd, struct plugin
                .zslba          = cfg.zslba,
                .nlb            = nblocks,
                .control        = control,
-               .ilbrt          = cfg.ref_tag,
+               .ilbrt_u64      = cfg.ref_tag,
                .lbat           = cfg.lbat,
                .lbatm          = cfg.lbatm,
                .data_len       = cfg.data_size,