nvme: store SGL callback in nvme_payload

Allows simplification of _nvme_qpair_build_sgl_request(), which does not
need to know whether a request is a child or not.

This also removes a read of req->parent for non-split I/Os; the parent
field is in the section of nvme_request that is only intended to be
initialized for split I/Os, which should be detected by looking at
num_children.

Additionally, this fixes a potential problem if requests were nested
more than one level deep (e.g. req->parent was not the original user
request).

Change-Id: I3ea1dc134bbb1e3b8c6b5a479f5d760bd97ea848
Signed-off-by: Daniel Verkamp <daniel.verkamp@intel.com>
This commit is contained in:
Daniel Verkamp 2016-02-18 14:23:28 -07:00
parent d0a543daf6
commit 7c34c2005d
3 changed files with 5 additions and 5 deletions

View File

@ -144,6 +144,7 @@ struct __attribute__((packed)) nvme_payload {
struct {
spdk_nvme_req_reset_sgl_cb reset_sgl_fn;
spdk_nvme_req_next_sge_cb next_sge_fn;
void *cb_arg;
} sgl;
} u;

View File

@ -209,6 +209,7 @@ spdk_nvme_ns_cmd_readv(struct spdk_nvme_ns *ns, uint64_t lba, uint32_t lba_count
payload.type = NVME_PAYLOAD_TYPE_SGL;
payload.u.sgl.reset_sgl_fn = reset_sgl_fn;
payload.u.sgl.next_sge_fn = next_sge_fn;
payload.u.sgl.cb_arg = cb_arg;
req = _nvme_ns_cmd_rw(ns, &payload, lba, lba_count, cb_fn, cb_arg, SPDK_NVME_OPC_READ, io_flags);
if (req != NULL) {
@ -254,6 +255,7 @@ spdk_nvme_ns_cmd_writev(struct spdk_nvme_ns *ns, uint64_t lba, uint32_t lba_coun
payload.type = NVME_PAYLOAD_TYPE_SGL;
payload.u.sgl.reset_sgl_fn = reset_sgl_fn;
payload.u.sgl.next_sge_fn = next_sge_fn;
payload.u.sgl.cb_arg = cb_arg;
req = _nvme_ns_cmd_rw(ns, &payload, lba, lba_count, cb_fn, cb_arg, SPDK_NVME_OPC_WRITE, io_flags);
if (req != NULL) {

View File

@ -727,16 +727,13 @@ _nvme_qpair_build_sgl_request(struct nvme_qpair *qpair, struct nvme_request *req
uint32_t nseg, cur_nseg, total_nseg, last_nseg, modulo, unaligned;
uint32_t sge_count = 0;
uint64_t prp2 = 0;
struct nvme_request *parent;
/*
* Build scattered payloads.
*/
parent = req->parent ? req->parent : req;
nvme_assert(req->payload.type == NVME_PAYLOAD_TYPE_SGL, ("sgl payload type required\n"));
nvme_assert(req->payload.u.sgl.reset_sgl_fn != NULL, ("sgl reset callback required\n"));
req->payload.u.sgl.reset_sgl_fn(parent->cb_arg, req->payload_offset);
req->payload.u.sgl.reset_sgl_fn(req->payload.u.sgl.cb_arg, req->payload_offset);
remaining_transfer_len = req->payload_size;
total_nseg = 0;
@ -744,7 +741,7 @@ _nvme_qpair_build_sgl_request(struct nvme_qpair *qpair, struct nvme_request *req
while (remaining_transfer_len > 0) {
nvme_assert(req->payload.u.sgl.next_sge_fn != NULL, ("sgl callback required\n"));
rc = req->payload.u.sgl.next_sge_fn(parent->cb_arg, &phys_addr, &length);
rc = req->payload.u.sgl.next_sge_fn(req->payload.u.sgl.cb_arg, &phys_addr, &length);
if (rc) {
_nvme_fail_request_bad_vtophys(qpair, tr);
return -1;