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:
parent
6d7b6e882c
commit
e2b330e989
@ -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
|
* We need to create a split here. Send what we have accumulated so far as a child
|
||||||
* child request.
|
* 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;
|
struct nvme_request *child;
|
||||||
uint32_t child_lba_count;
|
uint32_t child_lba_count;
|
||||||
|
|
||||||
|
@ -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);
|
typedef void (*nvme_build_io_req_fn_t)(struct io_request *req);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -475,7 +495,8 @@ int main(int argc, char **argv)
|
|||||||
|| TEST(build_io_request_6)
|
|| TEST(build_io_request_6)
|
||||||
|| TEST(build_io_request_7)
|
|| TEST(build_io_request_7)
|
||||||
|| TEST(build_io_request_8)
|
|| TEST(build_io_request_8)
|
||||||
|| TEST(build_io_request_9)) {
|
|| TEST(build_io_request_9)
|
||||||
|
|| TEST(build_io_request_10)) {
|
||||||
#undef TEST
|
#undef TEST
|
||||||
rc = 1;
|
rc = 1;
|
||||||
printf("%s: failed sgl tests\n", iter->name);
|
printf("%s: failed sgl tests\n", iter->name);
|
||||||
|
Loading…
Reference in New Issue
Block a user