Commit e2b330e9 authored by Jim Harris's avatar Jim Harris
Browse files

nvme: correctly handle valid PRPs with non-block size first/last elements



Signed-off-by: default avatarJim Harris <james.r.harris@intel.com>
Change-Id: I801547126987b1a2c5e8e95d468c30e508a1c3b0
parent 6d7b6e88
Loading
Loading
Loading
Loading
+9 −3
Original line number Diff line number Diff line
@@ -270,11 +270,17 @@ _nvme_ns_cmd_split_sgl_request(struct spdk_nvme_ns *ns,
			}
		}

		if (start_valid && end_valid && !last_sge) {
			continue;
		}

		/*
		 * If one of these criteria is met, send what we have accumlated so far as a
		 *  child request.
		 * We need to create a split here.  Send what we have accumulated so far as a child
		 *  request.  Checking if child_equals_parent allows us to *not* create a child request
		 *  when no splitting is required - in that case we will fall-through and just create
		 *  a single request with no children for the entire I/O.
		 */
		if (!start_valid || !end_valid || !child_equals_parent) {
		if (!child_equals_parent) {
			struct nvme_request *child;
			uint32_t child_lba_count;

+22 −1
Original line number Diff line number Diff line
@@ -272,6 +272,26 @@ static void build_io_request_9(struct io_request *req)
	}
}

static void build_io_request_10(struct io_request *req)
{
	/*
	 * Test the case where we have a valid PRP list, but the first and last
	 * elements are not exact multiples of the logical block size.
	 */
	const size_t req_len[] = {  4004, 4096,  92 };
	const size_t req_off[] = {  0x5c,  0x0, 0x0 };
	struct sgl_element *iovs = req->iovs;
	uint32_t i;
	req->nseg = SPDK_COUNTOF(req_len);
	assert(SPDK_COUNTOF(req_len) == SPDK_COUNTOF(req_off));

	for (i = 0; i < req->nseg; i++) {
		iovs[i].base = spdk_zmalloc(req_off[i] + req_len[i], 0x4000, NULL);
		iovs[i].offset = req_off[i];
		iovs[i].len = req_len[i];
	}
}

typedef void (*nvme_build_io_req_fn_t)(struct io_request *req);

static void
@@ -475,7 +495,8 @@ int main(int argc, char **argv)
		    || TEST(build_io_request_6)
		    || TEST(build_io_request_7)
		    || TEST(build_io_request_8)
		    || TEST(build_io_request_9)) {
		    || TEST(build_io_request_9)
		    || TEST(build_io_request_10)) {
#undef TEST
			rc = 1;
			printf("%s: failed sgl tests\n", iter->name);