Blame SOURCES/0003-nvme-discover-Re-check-generation-counter-after-log-.patch

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