File 0029-nvme-discover-Re-check-generation-counter-after-log-.patch of Package nvme-cli.11415
From: Hannes Reinecke <hare@suse.de>
Date: Thu, 20 Sep 2018 11:09:36 +0200
Subject: [PATCH] nvme-discover: Re-check generation counter after log page
transfer
Git-commit: 36efbbbff9f0e5d854f0454e393012ae23c46646
References: bsc#1105314
The log page transfer might have been split up in several chunks, so
it might happen that the generation counter changed inbetween these
transfer. Hence we need to re-fetch the header again to figure out
if there had been changes to the generation counter; if so we need
to fetch the entire page again.
Signed-off-by: Hannes Reinecke <hare@suse.com>
---
fabrics.c | 22 ++++++++++++++++++----
1 file changed, 18 insertions(+), 4 deletions(-)
diff --git a/fabrics.c b/fabrics.c
index 23c5d22..1513c3f 100644
--- a/fabrics.c
+++ b/fabrics.c
@@ -280,7 +280,7 @@ static int nvmf_get_log_page_discovery(const char *dev_path,
struct nvmf_disc_rsp_page_hdr **logp, int *numrec)
{
struct nvmf_disc_rsp_page_hdr *log;
- unsigned int log_size = 0;
+ unsigned int hdr_size;
unsigned long genctr;
int error, fd, max_retries = MAX_DISC_RETRIES, retries = 0;
@@ -293,26 +293,28 @@ static int nvmf_get_log_page_discovery(const char *dev_path,
/* first get_log_page we just need numrec entry from discovery hdr.
* host supplies its desired bytes via dwords, per NVMe spec.
*/
- log_size = round_up((offsetof(struct nvmf_disc_rsp_page_hdr, numrec) +
+ hdr_size = round_up((offsetof(struct nvmf_disc_rsp_page_hdr, numrec) +
sizeof(log->numrec)), sizeof(__u32));
/*
* Issue first get log page w/numdl small enough to retrieve numrec.
* We just want to know how many records to retrieve.
*/
- log = calloc(1, log_size);
+ log = calloc(1, hdr_size);
if (!log) {
error = -ENOMEM;
goto out_close;
}
- error = nvme_discovery_log(fd, log, log_size);
+ error = nvme_discovery_log(fd, log, hdr_size);
if (error) {
error = DISC_GET_NUMRECS;
goto out_free_log;
}
do {
+ unsigned int log_size;
+
/* check numrec limits */
*numrec = le64_to_cpu(log->numrec);
genctr = le64_to_cpu(log->genctr);
@@ -348,6 +350,18 @@ static int nvmf_get_log_page_discovery(const char *dev_path,
goto out_free_log;
}
+ /*
+ * The above call to nvme_discovery_log() might result
+ * in several calls (with different offsets), so we need
+ * to fetch the header again to have the most up-to-date
+ * value for the generation counter
+ */
+ genctr = le64_to_cpu(log->genctr);
+ error = nvme_discovery_log(fd, log, hdr_size);
+ if (error) {
+ error = DISC_GET_LOG;
+ goto out_free_log;
+ }
} while (genctr != le64_to_cpu(log->genctr) &&
++retries < max_retries);
--
2.12.3