]> www.infradead.org Git - users/sagi/nvme-cli.git/commitdiff
fix reservation report 0's based dword count
authorKeith Busch <keith.busch@intel.com>
Thu, 5 Jul 2018 14:59:09 +0000 (08:59 -0600)
committerKeith Busch <keith.busch@intel.com>
Thu, 5 Jul 2018 14:59:09 +0000 (08:59 -0600)
Some parts of treating this as a 0's based value as the spec requires,
and others were not. This patch fixes that.

Link: https://github.com/linux-nvme/nvme-cli/issues/385
Signed-off-by: Keith Busch <keith.busch@intel.com>
nvme-ioctl.c
nvme.c

index edb2ea37bd7ade007fe71427b166eb559f7566c0..9cf2a337200ace7d7b2c7677bb6faa5e11d3fb80 100644 (file)
@@ -319,7 +319,7 @@ int nvme_resv_report(int fd, __u32 nsid, __u32 numd, __u32 cdw11, void *data)
                .cdw10          = numd,
                .cdw11          = cdw11,
                .addr           = (__u64)(uintptr_t) data,
-               .data_len       = numd << 2,
+               .data_len       = (numd + 1) << 2,
        };
 
        return nvme_submit_io_passthru(fd, &cmd);
diff --git a/nvme.c b/nvme.c
index e43f7bf4830ac14930f311d6977dcb60cc9d3919..4815caaf20a6ee55967a9013d75e4a0904d652eb 100644 (file)
--- a/nvme.c
+++ b/nvme.c
@@ -3706,7 +3706,7 @@ static int resv_report(int argc, char **argv, struct command *cmd, struct plugin
        const char *cdw11 = "command dword 11 value";
        const char *raw_binary = "dump output in binary format";
 
-       int err, fmt, fd;
+       int err, fmt, fd, size;
        struct nvme_reservation_status *status;
 
        struct config {
@@ -3752,17 +3752,19 @@ static int resv_report(int argc, char **argv, struct command *cmd, struct plugin
                        goto close_fd;
                }
        }
-       if (!cfg.numd || cfg.numd > (0x1000 >> 2))
-               cfg.numd = 0x1000 >> 2;
+       if (!cfg.numd || cfg.numd >= (0x1000 >> 2))
+               cfg.numd = (0x1000 >> 2) - 1;
        if (cfg.numd < 3)
                cfg.numd = 3; /* get the header fields at least */
 
-       if (posix_memalign((void **)&status, getpagesize(), cfg.numd << 2)) {
-               fprintf(stderr, "No memory for resv report:%d\n", cfg.numd << 2);
+       size = (cfg.numd + 1) << 2;
+
+       if (posix_memalign((void **)&status, getpagesize(), size)) {
+               fprintf(stderr, "No memory for resv report:%d\n", size);
                err = ENOMEM;
                goto close_fd;
        }
-       memset(status, 0, cfg.numd << 2);
+       memset(status, 0, size);
 
        err = nvme_resv_report(fd, cfg.namespace_id, cfg.numd, cfg.cdw11, status);
        if (err < 0)
@@ -3771,12 +3773,12 @@ static int resv_report(int argc, char **argv, struct command *cmd, struct plugin
                fprintf(stderr, "NVME IO command error:%04x\n", err);
        else {
                if (fmt == BINARY)
-                       d_raw((unsigned char *)status, cfg.numd << 2);
+                       d_raw((unsigned char *)status, size);
                else if (fmt == JSON)
-                       json_nvme_resv_report(status, cfg.numd << 2, cfg.cdw11);
+                       json_nvme_resv_report(status, size, cfg.cdw11);
                else {
                        printf("NVME Reservation Report success\n");
-                       show_nvme_resv_report(status, cfg.numd << 2, cfg.cdw11);
+                       show_nvme_resv_report(status, size, cfg.cdw11);
                }
        }
        free(status);