]> www.infradead.org Git - users/sagi/nvme-cli.git/commitdiff
nvme: check MD size with PI size when PRACT set to 1
authorFrancis Pravin <francis.p@samsung.com>
Fri, 12 Jul 2024 06:18:51 +0000 (11:48 +0530)
committerDaniel Wagner <wagi@monom.org>
Fri, 12 Jul 2024 07:39:21 +0000 (09:39 +0200)
As per NVM Command Set Specification, Rev 1.0d, Sec-5.2.2 PRACT Bit:
"If PRACT bit is set to 1 and Metadata size equals to the Protection
Information size, the protection information is stripped or inserted
by the controller."
Currently NVMe supports 8 and 16 byte size of Protection Information.
So, use pi_size instead of 8 byte.

Signed-off-by: Francis Pravin <francis.p@samsung.com>
Reviewed-by: Steven Seungcheol Lee <sc108.lee@samsung.com>
nvme.c

diff --git a/nvme.c b/nvme.c
index b09f09a13d3a5b4fb54cf5e0c9c1917245d8cc55..fd0e9e976da2e18cf8fe8a4b50872e9153fae730 100644 (file)
--- a/nvme.c
+++ b/nvme.c
@@ -7691,7 +7691,7 @@ static int submit_io(int opcode, char *command, const char *desc, int argc, char
        _cleanup_free_ void *mbuffer = NULL;
        int err = 0;
        _cleanup_fd_ int dfd = -1, mfd = -1;
-       int flags;
+       int flags, pi_size;
        int mode = 0644;
        __u16 control = 0, nblocks = 0;
        __u32 dsmgmt = 0;
@@ -7887,13 +7887,23 @@ static int submit_io(int opcode, char *command, const char *desc, int argc, char
        nvme_id_ns_flbas_to_lbaf_inuse(ns->flbas, &lba_index);
        logical_block_size = 1 << ns->lbaf[lba_index].ds;
        ms = ns->lbaf[lba_index].ms;
+
+       nvm_ns = nvme_alloc(sizeof(*nvm_ns));
+       if (!nvm_ns)
+               return -ENOMEM;
+
+       err = nvme_identify_ns_csi(dev_fd(dev), cfg.namespace_id, 0, NVME_CSI_NVM, nvm_ns);
+       if (!err)
+               get_pif_sts(ns, nvm_ns, &pif, &sts);
+
+       pi_size = (pif == NVME_NVM_PIF_16B_GUARD) ? 8 : 16;
        if (NVME_FLBAS_META_EXT(ns->flbas)) {
                /*
-                * No meta data is transferred for PRACT=1 and MD=8:
+                * No meta data is transferred for PRACT=1 and MD=PI size:
                 *   5.2.2.1 Protection Information and Write Commands
                 *   5.2.2.2 Protection Information and Read Commands
                 */
-               if (!((cfg.prinfo & 0x8) != 0 && ms == 8))
+               if (!((cfg.prinfo & 0x8) != 0 && ms == pi_size))
                        logical_block_size += ms;
        }
 
@@ -7918,16 +7928,7 @@ static int submit_io(int opcode, char *command, const char *desc, int argc, char
        if (!buffer)
                return -ENOMEM;
 
-       nvm_ns = nvme_alloc(sizeof(*nvm_ns));
-       if (!nvm_ns)
-               return -ENOMEM;
-
        if (cfg.metadata_size) {
-               err = nvme_identify_ns_csi(dev_fd(dev), 1, 0, NVME_CSI_NVM, nvm_ns);
-               if (!err) {
-                       get_pif_sts(ns, nvm_ns, &pif, &sts);
-               }
-
                mbuffer_size = ((unsigned long long)cfg.block_count + 1) * ms;
                if (ms && cfg.metadata_size < mbuffer_size)
                        nvme_show_error("Rounding metadata size to fit block count (%lld bytes)",