Commit 736ec496 authored by Daniel Verkamp's avatar Daniel Verkamp Committed by Gerrit Code Review
Browse files

nvme: refactor _nvme_ns_cmd_rw()



Pull the almost-identical request splitting code for driver-assisted
striping and maximum I/O size into its own function,
_nvme_ns_cmd_split_request().

Change-Id: I3c15ac2073f8f5aec721c427199c8fb1a5d6a1fc
Signed-off-by: default avatarDaniel Verkamp <daniel.verkamp@intel.com>
parent 766afaaa
Loading
Loading
Loading
Loading
+40 −34
Original line number Diff line number Diff line
@@ -38,6 +38,41 @@
 *
 */

static struct nvme_request *
_nvme_ns_cmd_rw(struct nvme_namespace *ns, void *payload, uint64_t lba,
		uint32_t lba_count, nvme_cb_fn_t cb_fn, void *cb_arg,
		uint32_t opc);

static struct nvme_request *
_nvme_ns_cmd_split_request(struct nvme_namespace *ns, void *payload,
			   uint64_t lba, uint32_t lba_count,
			   nvme_cb_fn_t cb_fn, void *cb_arg, uint32_t opc,
			   struct nvme_request *req,
			   uint32_t sectors_per_max_io, uint32_t sector_mask)
{
	uint32_t		sector_size = ns->sector_size;
	uint32_t		remaining_lba_count = lba_count;
	struct nvme_request	*child;

	while (remaining_lba_count > 0) {
		lba_count = sectors_per_max_io - (lba & sector_mask);
		lba_count = nvme_min(remaining_lba_count, lba_count);

		child = _nvme_ns_cmd_rw(ns, payload, lba, lba_count, cb_fn,
					cb_arg, opc);
		if (child == NULL) {
			nvme_free_request(req);
			return NULL;
		}
		nvme_request_add_child(req, child);
		remaining_lba_count -= lba_count;
		lba += lba_count;
		payload = (void *)((uintptr_t)payload + (lba_count * sector_size));
	}

	return req;
}

static struct nvme_request *
_nvme_ns_cmd_rw(struct nvme_namespace *ns, void *payload, uint64_t lba,
		uint32_t lba_count, nvme_cb_fn_t cb_fn, void *cb_arg,
@@ -67,41 +102,12 @@ _nvme_ns_cmd_rw(struct nvme_namespace *ns, void *payload, uint64_t lba,
	 */
	if (sectors_per_stripe > 0 &&
	    (((lba & (sectors_per_stripe - 1)) + lba_count) > sectors_per_stripe)) {
		uint64_t		remaining_lba_count = lba_count;
		struct nvme_request	*child;

		while (remaining_lba_count > 0) {
			lba_count = sectors_per_stripe - (lba & (sectors_per_stripe - 1));
			lba_count = nvme_min(remaining_lba_count, lba_count);

			child = _nvme_ns_cmd_rw(ns, payload, lba, lba_count, cb_fn,
						cb_arg, opc);
			if (child == NULL) {
				nvme_free_request(req);
				return NULL;
			}
			nvme_request_add_child(req, child);
			remaining_lba_count -= lba_count;
			lba += lba_count;
			payload = (void *)((uintptr_t)payload + (lba_count * sector_size));
		}
		return _nvme_ns_cmd_split_request(ns, payload, lba, lba_count, cb_fn, cb_arg, opc,
						  req, sectors_per_stripe, sectors_per_stripe - 1);
	} else if (lba_count > sectors_per_max_io) {
		uint64_t		remaining_lba_count = lba_count;
		struct nvme_request	*child;

		while (remaining_lba_count > 0) {
			lba_count = nvme_min(remaining_lba_count, sectors_per_max_io);
			child = _nvme_ns_cmd_rw(ns, payload, lba, lba_count, cb_fn,
						cb_arg, opc);
			if (child == NULL) {
				nvme_free_request(req);
				return NULL;
			}
			nvme_request_add_child(req, child);
			remaining_lba_count -= lba_count;
			lba += lba_count;
			payload = (void *)((uintptr_t)payload + (lba_count * sector_size));
		}
		return _nvme_ns_cmd_split_request(ns, payload, lba, lba_count, cb_fn, cb_arg, opc,
						  req, sectors_per_max_io, 0);
	} else {
		cmd = &req->cmd;
		cmd->opc = opc;