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

Signed-off-by: Jim Harris <james.r.harris@intel.com>
Change-Id: I801547126987b1a2c5e8e95d468c30e508a1c3b0
This commit is contained in:
Jim Harris 2017-03-20 10:12:51 -07:00
parent 6d7b6e882c
commit e2b330e989
2 changed files with 31 additions and 4 deletions

View File

@ -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;

View File

@ -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);