Commit 55f94793 authored by Konrad Sztyber's avatar Konrad Sztyber Committed by Tomasz Zawadzki
Browse files

bdev: remove spdk_bdev_ext_io_opts from spdk_bdev_io



The spdk_bdev_ext_io_opts structure is used to pass extra options when
submitting a bdev IO request, without having to modify/add functions to
handle new options.  Additionally, the structure has a size field to
allow adding new fields without breaking the ABI (and thus having to
bump up the major version of a library).

It is also a part of spdk_bdev_io and there are several reasons for
removing it from that structure:

  1. The size field only makes sense in structures that are passed
     through pointers.  And spdk_bdev_ext_io_opts is indeed passed as a
     pointer to spdk_bdev_{readv,writev}_blocks_ext(), however it is
     also embedded in spdk_bdev_io (internal.ext_opts_copy), which is
     also part of the API.  It means that each time a new field is added
     to spdk_bdev_ext_io_opts, the size of spdk_bdev_io will also
     change, so we will need to bump the major version of libspdk_bdev
     anyway, thus making spdk_bdev_ext_io_opts.size useless.
  2. The size field also makes internal.ext_opts cumbersome to use, as
     each time one of its fields is accessed, we need to check the size.
     Currently the code doesn't do that, because all of the existing
     spdk_bdev_ext_io_opts fields were present when this structure was
     initially introduced, but we'd need to do check the size before
     accessing any new fields.
  3. spdk_bdev_ext_io_opts has a metadata field, while spdk_bdev_io
     already has u.bdev.md_buf, which means that we store the same thing
     in several different places in spdk_bdev_io (u.bdev.md_buf,
     u.bdev.ext_opts->metadata, internal.ext_opts->metadata).

Therefore, this patch removes all references to spdk_bdev_ext_io_opts
from spdk_bdev_io and replaces them with fields (memory_domain,
memory_domain_ctx) that were missing in spdk_bdev_io.  Unfortunately,
this change breaks the API and requires changes in bdev modules that
supported spdk_bdev_io.u.bdev.ext_opts.

Signed-off-by: default avatarKonrad Sztyber <konrad.sztyber@intel.com>
Change-Id: I49b7524eb84d1d4d7f12b7ab025fec36da1ee01f
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/16773


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarAleksey Marchuk <alexeymar@nvidia.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
parent c30dfbc2
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -208,7 +208,6 @@ SPDK_STATIC_ASSERT(sizeof(struct spdk_bdev_opts) == 32, "Incorrect size");

/**
 * Structure with optional IO request parameters
 * The content of this structure must be valid until the IO request is completed
 */
struct spdk_bdev_ext_io_opts {
	/** Size of this structure in bytes */
+6 −7
Original line number Diff line number Diff line
@@ -790,8 +790,9 @@ struct spdk_bdev_io {
			/** Starting offset (in blocks) of the bdev for this I/O. */
			uint64_t offset_blocks;

			/** Pointer to user's ext opts to be used by bdev modules */
			struct spdk_bdev_ext_io_opts *ext_opts;
			/** Memory domain and its context to be used by bdev modules */
			struct spdk_memory_domain *memory_domain;
			void *memory_domain_ctx;

			/** stored user callback in case we split the I/O and use a temporary callback */
			spdk_bdev_io_completion_cb stored_user_cb;
@@ -974,11 +975,9 @@ struct spdk_bdev_io {
		/** Enables queuing parent I/O when no bdev_ios available for split children. */
		struct spdk_bdev_io_wait_entry waitq_entry;

		/** Pointer to a structure passed by the user in ext API */
		struct spdk_bdev_ext_io_opts *ext_opts;

		/** Copy of user's opts, used when I/O is split */
		struct spdk_bdev_ext_io_opts ext_opts_copy;
		/** Memory domain and its context passed by the user in ext API */
		struct spdk_memory_domain *memory_domain;
		void *memory_domain_ctx;

		/** Data transfer completion callback */
		void (*data_transfer_cpl)(void *ctx, int rc);
+82 −84
Original line number Diff line number Diff line
@@ -370,13 +370,14 @@ static void bdev_enable_qos_done(struct spdk_bdev *bdev, void *_ctx, int status)

static int bdev_readv_blocks_with_md(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
				     struct iovec *iov, int iovcnt, void *md_buf, uint64_t offset_blocks,
				     uint64_t num_blocks, spdk_bdev_io_completion_cb cb, void *cb_arg,
				     struct spdk_bdev_ext_io_opts *opts, bool copy_opts);
				     uint64_t num_blocks,
				     struct spdk_memory_domain *domain, void *domain_ctx,
				     spdk_bdev_io_completion_cb cb, void *cb_arg);
static int bdev_writev_blocks_with_md(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
				      struct iovec *iov, int iovcnt, void *md_buf,
				      uint64_t offset_blocks, uint64_t num_blocks,
				      spdk_bdev_io_completion_cb cb, void *cb_arg,
				      struct spdk_bdev_ext_io_opts *opts, bool copy_opts);
				      struct spdk_memory_domain *domain, void *domain_ctx,
				      spdk_bdev_io_completion_cb cb, void *cb_arg);

static int bdev_lock_lba_range(struct spdk_bdev_desc *desc, struct spdk_io_channel *_ch,
			       uint64_t offset, uint64_t length,
@@ -395,6 +396,10 @@ static bool claim_type_is_v2(enum spdk_bdev_claim_type type);
static void bdev_desc_release_claims(struct spdk_bdev_desc *desc);
static void claim_reset(struct spdk_bdev *bdev);

#define bdev_get_ext_io_opt(opts, field, defval) \
	(((opts) != NULL && offsetof(struct spdk_bdev_ext_io_opts, field) + \
	 sizeof((opts)->field) <= sizeof(*(opts))) ? (opts)->field : (defval))

void
spdk_bdev_get_opts(struct spdk_bdev_opts *opts, size_t opts_size)
{
@@ -888,7 +893,7 @@ spdk_bdev_next_leaf(struct spdk_bdev *prev)
static inline bool
bdev_io_use_memory_domain(struct spdk_bdev_io *bdev_io)
{
	return bdev_io->internal.ext_opts && bdev_io->internal.ext_opts->memory_domain;
	return bdev_io->internal.memory_domain;
}

void
@@ -992,8 +997,8 @@ _bdev_io_pull_bounce_md_buf(struct spdk_bdev_io *bdev_io, void *md_buf, size_t l

	if (bdev_io->type == SPDK_BDEV_IO_TYPE_WRITE) {
		if (bdev_io_use_memory_domain(bdev_io)) {
			rc = spdk_memory_domain_pull_data(bdev_io->internal.ext_opts->memory_domain,
							  bdev_io->internal.ext_opts->memory_domain_ctx,
			rc = spdk_memory_domain_pull_data(bdev_io->internal.memory_domain,
							  bdev_io->internal.memory_domain_ctx,
							  &bdev_io->internal.orig_md_iov, 1,
							  &bdev_io->internal.bounce_md_iov, 1,
							  bdev_io->internal.data_transfer_cpl,
@@ -1003,7 +1008,7 @@ _bdev_io_pull_bounce_md_buf(struct spdk_bdev_io *bdev_io, void *md_buf, size_t l
				return;
			}
			SPDK_ERRLOG("Failed to pull data from memory domain %s, rc %d\n",
				    spdk_memory_domain_get_dma_device_id(bdev_io->internal.ext_opts->memory_domain), rc);
				    spdk_memory_domain_get_dma_device_id(bdev_io->internal.memory_domain), rc);
		} else {
			memcpy(md_buf, bdev_io->internal.orig_md_iov.iov_base, bdev_io->internal.orig_md_iov.iov_len);
		}
@@ -1071,8 +1076,8 @@ _bdev_io_pull_bounce_data_buf(struct spdk_bdev_io *bdev_io, void *buf, size_t le
	/* if this is write path, copy data from original buffer to bounce buffer */
	if (bdev_io->type == SPDK_BDEV_IO_TYPE_WRITE) {
		if (bdev_io_use_memory_domain(bdev_io)) {
			rc = spdk_memory_domain_pull_data(bdev_io->internal.ext_opts->memory_domain,
							  bdev_io->internal.ext_opts->memory_domain_ctx,
			rc = spdk_memory_domain_pull_data(bdev_io->internal.memory_domain,
							  bdev_io->internal.memory_domain_ctx,
							  bdev_io->internal.orig_iovs,
							  (uint32_t) bdev_io->internal.orig_iovcnt,
							  bdev_io->u.bdev.iovs, 1,
@@ -1083,7 +1088,7 @@ _bdev_io_pull_bounce_data_buf(struct spdk_bdev_io *bdev_io, void *buf, size_t le
				return;
			}
			SPDK_ERRLOG("Failed to pull data from memory domain %s\n",
				    spdk_memory_domain_get_dma_device_id(bdev_io->internal.ext_opts->memory_domain));
				    spdk_memory_domain_get_dma_device_id(bdev_io->internal.memory_domain));
		} else {
			spdk_copy_iovs_to_buf(buf, len, bdev_io->internal.orig_iovs, bdev_io->internal.orig_iovcnt);
		}
@@ -1267,8 +1272,8 @@ _bdev_io_push_bounce_md_buffer(struct spdk_bdev_io *bdev_io)
		    bdev_io->internal.status == SPDK_BDEV_IO_STATUS_SUCCESS) {
			if (bdev_io_use_memory_domain(bdev_io)) {
				/* If memory domain is used then we need to call async push function */
				rc = spdk_memory_domain_push_data(bdev_io->internal.ext_opts->memory_domain,
								  bdev_io->internal.ext_opts->memory_domain_ctx,
				rc = spdk_memory_domain_push_data(bdev_io->internal.memory_domain,
								  bdev_io->internal.memory_domain_ctx,
								  &bdev_io->internal.orig_md_iov,
								  (uint32_t)bdev_io->internal.orig_iovcnt,
								  &bdev_io->internal.bounce_md_iov, 1,
@@ -1279,7 +1284,7 @@ _bdev_io_push_bounce_md_buffer(struct spdk_bdev_io *bdev_io)
					return;
				}
				SPDK_ERRLOG("Failed to push md to memory domain %s\n",
					    spdk_memory_domain_get_dma_device_id(bdev_io->internal.ext_opts->memory_domain));
					    spdk_memory_domain_get_dma_device_id(bdev_io->internal.memory_domain));
			} else {
				memcpy(bdev_io->internal.orig_md_iov.iov_base, bdev_io->u.bdev.md_buf,
				       bdev_io->internal.orig_md_iov.iov_len);
@@ -1325,8 +1330,8 @@ _bdev_io_push_bounce_data_buffer(struct spdk_bdev_io *bdev_io, bdev_copy_bounce_
	    bdev_io->internal.status == SPDK_BDEV_IO_STATUS_SUCCESS) {
		if (bdev_io_use_memory_domain(bdev_io)) {
			/* If memory domain is used then we need to call async push function */
			rc = spdk_memory_domain_push_data(bdev_io->internal.ext_opts->memory_domain,
							  bdev_io->internal.ext_opts->memory_domain_ctx,
			rc = spdk_memory_domain_push_data(bdev_io->internal.memory_domain,
							  bdev_io->internal.memory_domain_ctx,
							  bdev_io->internal.orig_iovs,
							  (uint32_t)bdev_io->internal.orig_iovcnt,
							  &bdev_io->internal.bounce_iov, 1,
@@ -1337,7 +1342,7 @@ _bdev_io_push_bounce_data_buffer(struct spdk_bdev_io *bdev_io, bdev_copy_bounce_
				return;
			}
			SPDK_ERRLOG("Failed to push data to memory domain %s\n",
				    spdk_memory_domain_get_dma_device_id(bdev_io->internal.ext_opts->memory_domain));
				    spdk_memory_domain_get_dma_device_id(bdev_io->internal.memory_domain));
		} else {
			spdk_copy_buf_to_iovs(bdev_io->internal.orig_iovs,
					      bdev_io->internal.orig_iovcnt,
@@ -2544,17 +2549,17 @@ bdev_io_split_submit(struct spdk_bdev_io *bdev_io, struct iovec *iov, int iovcnt
		rc = bdev_readv_blocks_with_md(bdev_io->internal.desc,
					       spdk_io_channel_from_ctx(bdev_io->internal.ch),
					       iov, iovcnt, md_buf, current_offset,
					       num_blocks,
					       bdev_io_split_done, bdev_io,
					       bdev_io->internal.ext_opts, true);
					       num_blocks, bdev_io->internal.memory_domain,
					       bdev_io->internal.memory_domain_ctx,
					       bdev_io_split_done, bdev_io);
		break;
	case SPDK_BDEV_IO_TYPE_WRITE:
		rc = bdev_writev_blocks_with_md(bdev_io->internal.desc,
						spdk_io_channel_from_ctx(bdev_io->internal.ch),
						iov, iovcnt, md_buf, current_offset,
						num_blocks,
						bdev_io_split_done, bdev_io,
						bdev_io->internal.ext_opts, true);
						num_blocks, bdev_io->internal.memory_domain,
						bdev_io->internal.memory_domain_ctx,
						bdev_io_split_done, bdev_io);
		break;
	case SPDK_BDEV_IO_TYPE_UNMAP:
		io_wait_fn = _bdev_unmap_split;
@@ -3082,20 +3087,6 @@ bdev_io_submit(struct spdk_bdev_io *bdev_io)
	}
}

static inline void
_bdev_io_copy_ext_opts(struct spdk_bdev_io *bdev_io, struct spdk_bdev_ext_io_opts *opts)
{
	struct spdk_bdev_ext_io_opts *opts_copy = &bdev_io->internal.ext_opts_copy;

	/* Zero part we don't copy */
	memset(((char *)opts_copy) + opts->size, 0, sizeof(*opts) - opts->size);
	memcpy(opts_copy, opts, opts->size);
	opts_copy->size = sizeof(*opts_copy);
	opts_copy->metadata = bdev_io->u.bdev.md_buf;
	/* Save pointer to the copied ext_opts which will be used by bdev modules */
	bdev_io->u.bdev.ext_opts = opts_copy;
}

static inline void
_bdev_io_ext_use_bounce_buffer(struct spdk_bdev_io *bdev_io)
{
@@ -3104,33 +3095,21 @@ _bdev_io_ext_use_bounce_buffer(struct spdk_bdev_io *bdev_io)
	 * For write operation we need to pull buffers from memory domain before submitting IO.
	 * Once read operation completes, we need to use memory_domain push functionality to
	 * update data in original memory domain IO buffer
	 * This IO request will go through a regular IO flow, so clear memory domains pointers in
	 * the copied ext_opts */
	bdev_io->internal.ext_opts_copy.memory_domain = NULL;
	bdev_io->internal.ext_opts_copy.memory_domain_ctx = NULL;
	 * This IO request will go through a regular IO flow, so clear memory domains pointers */
	bdev_io->u.bdev.memory_domain = NULL;
	bdev_io->u.bdev.memory_domain_ctx = NULL;
	_bdev_memory_domain_io_get_buf(bdev_io, _bdev_memory_domain_get_io_cb,
				       bdev_io->u.bdev.num_blocks * bdev_io->bdev->blocklen);
}

static inline void
_bdev_io_submit_ext(struct spdk_bdev_desc *desc, struct spdk_bdev_io *bdev_io,
		    struct spdk_bdev_ext_io_opts *opts, bool copy_opts)
_bdev_io_submit_ext(struct spdk_bdev_desc *desc, struct spdk_bdev_io *bdev_io)
{
	if (opts) {
		bool use_pull_push = opts->memory_domain && !desc->memory_domains_supported;
		assert(opts->size <= sizeof(*opts));
		/*
		 * copy if size is smaller than opts struct to avoid having to check size
		 * on every access to bdev_io->u.bdev.ext_opts
		 */
		if (copy_opts || use_pull_push || opts->size < sizeof(*opts)) {
			_bdev_io_copy_ext_opts(bdev_io, opts);
			if (use_pull_push) {
	if (bdev_io->internal.memory_domain && !desc->memory_domains_supported) {
		_bdev_io_ext_use_bounce_buffer(bdev_io);
		return;
	}
		}
	}

	bdev_io_submit(bdev_io);
}

@@ -3167,7 +3146,8 @@ bdev_io_init(struct spdk_bdev_io *bdev_io,
	bdev_io->num_retries = 0;
	bdev_io->internal.get_buf_cb = NULL;
	bdev_io->internal.get_aux_buf_cb = NULL;
	bdev_io->internal.ext_opts = NULL;
	bdev_io->internal.memory_domain = NULL;
	bdev_io->internal.memory_domain_ctx = NULL;
	bdev_io->internal.data_transfer_cpl = NULL;
}

@@ -4722,7 +4702,8 @@ bdev_read_blocks_with_md(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch
	bdev_io->u.bdev.md_buf = md_buf;
	bdev_io->u.bdev.num_blocks = num_blocks;
	bdev_io->u.bdev.offset_blocks = offset_blocks;
	bdev_io->u.bdev.ext_opts = NULL;
	bdev_io->u.bdev.memory_domain = NULL;
	bdev_io->u.bdev.memory_domain_ctx = NULL;
	bdev_io_init(bdev_io, bdev, cb_arg, cb);

	bdev_io_submit(bdev_io);
@@ -4792,8 +4773,8 @@ spdk_bdev_readv(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
static int
bdev_readv_blocks_with_md(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
			  struct iovec *iov, int iovcnt, void *md_buf, uint64_t offset_blocks,
			  uint64_t num_blocks, spdk_bdev_io_completion_cb cb, void *cb_arg,
			  struct spdk_bdev_ext_io_opts *opts, bool copy_opts)
			  uint64_t num_blocks, struct spdk_memory_domain *domain, void *domain_ctx,
			  spdk_bdev_io_completion_cb cb, void *cb_arg)
{
	struct spdk_bdev *bdev = spdk_bdev_desc_get_bdev(desc);
	struct spdk_bdev_io *bdev_io;
@@ -4817,10 +4798,12 @@ bdev_readv_blocks_with_md(struct spdk_bdev_desc *desc, struct spdk_io_channel *c
	bdev_io->u.bdev.num_blocks = num_blocks;
	bdev_io->u.bdev.offset_blocks = offset_blocks;
	bdev_io_init(bdev_io, bdev, cb_arg, cb);
	bdev_io->internal.ext_opts = opts;
	bdev_io->u.bdev.ext_opts = opts;
	bdev_io->internal.memory_domain = domain;
	bdev_io->internal.memory_domain_ctx = domain_ctx;
	bdev_io->u.bdev.memory_domain = domain;
	bdev_io->u.bdev.memory_domain_ctx = domain_ctx;

	_bdev_io_submit_ext(desc, bdev_io, opts, copy_opts);
	_bdev_io_submit_ext(desc, bdev_io);

	return 0;
}
@@ -4832,7 +4815,7 @@ spdk_bdev_readv_blocks(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
		       spdk_bdev_io_completion_cb cb, void *cb_arg)
{
	return bdev_readv_blocks_with_md(desc, ch, iov, iovcnt, NULL, offset_blocks,
					 num_blocks, cb, cb_arg, NULL, false);
					 num_blocks, NULL, NULL, cb, cb_arg);
}

int
@@ -4850,7 +4833,7 @@ spdk_bdev_readv_blocks_with_md(struct spdk_bdev_desc *desc, struct spdk_io_chann
	}

	return bdev_readv_blocks_with_md(desc, ch, iov, iovcnt, md_buf, offset_blocks,
					 num_blocks, cb, cb_arg, NULL, false);
					 num_blocks, NULL, NULL, cb, cb_arg);
}

static inline bool
@@ -4893,7 +4876,10 @@ spdk_bdev_readv_blocks_ext(struct spdk_bdev_desc *desc, struct spdk_io_channel *
	}

	return bdev_readv_blocks_with_md(desc, ch, iov, iovcnt, md, offset_blocks,
					 num_blocks, cb, cb_arg, opts, false);
					 num_blocks,
					 bdev_get_ext_io_opt(opts, memory_domain, NULL),
					 bdev_get_ext_io_opt(opts, memory_domain_ctx, NULL),
					 cb, cb_arg);
}

static int
@@ -4928,7 +4914,8 @@ bdev_write_blocks_with_md(struct spdk_bdev_desc *desc, struct spdk_io_channel *c
	bdev_io->u.bdev.md_buf = md_buf;
	bdev_io->u.bdev.num_blocks = num_blocks;
	bdev_io->u.bdev.offset_blocks = offset_blocks;
	bdev_io->u.bdev.ext_opts = NULL;
	bdev_io->u.bdev.memory_domain = NULL;
	bdev_io->u.bdev.memory_domain_ctx = NULL;
	bdev_io_init(bdev_io, bdev, cb_arg, cb);

	bdev_io_submit(bdev_io);
@@ -4984,8 +4971,8 @@ static int
bdev_writev_blocks_with_md(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
			   struct iovec *iov, int iovcnt, void *md_buf,
			   uint64_t offset_blocks, uint64_t num_blocks,
			   spdk_bdev_io_completion_cb cb, void *cb_arg,
			   struct spdk_bdev_ext_io_opts *opts, bool copy_opts)
			   struct spdk_memory_domain *domain, void *domain_ctx,
			   spdk_bdev_io_completion_cb cb, void *cb_arg)
{
	struct spdk_bdev *bdev = spdk_bdev_desc_get_bdev(desc);
	struct spdk_bdev_io *bdev_io;
@@ -5013,10 +5000,12 @@ bdev_writev_blocks_with_md(struct spdk_bdev_desc *desc, struct spdk_io_channel *
	bdev_io->u.bdev.num_blocks = num_blocks;
	bdev_io->u.bdev.offset_blocks = offset_blocks;
	bdev_io_init(bdev_io, bdev, cb_arg, cb);
	bdev_io->internal.ext_opts = opts;
	bdev_io->u.bdev.ext_opts = opts;
	bdev_io->internal.memory_domain = domain;
	bdev_io->internal.memory_domain_ctx = domain_ctx;
	bdev_io->u.bdev.memory_domain = domain;
	bdev_io->u.bdev.memory_domain_ctx = domain_ctx;

	_bdev_io_submit_ext(desc, bdev_io, opts, copy_opts);
	_bdev_io_submit_ext(desc, bdev_io);

	return 0;
}
@@ -5044,7 +5033,7 @@ spdk_bdev_writev_blocks(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
			spdk_bdev_io_completion_cb cb, void *cb_arg)
{
	return bdev_writev_blocks_with_md(desc, ch, iov, iovcnt, NULL, offset_blocks,
					  num_blocks, cb, cb_arg, NULL, false);
					  num_blocks, NULL, NULL, cb, cb_arg);
}

int
@@ -5062,7 +5051,7 @@ spdk_bdev_writev_blocks_with_md(struct spdk_bdev_desc *desc, struct spdk_io_chan
	}

	return bdev_writev_blocks_with_md(desc, ch, iov, iovcnt, md_buf, offset_blocks,
					  num_blocks, cb, cb_arg, NULL, false);
					  num_blocks, NULL, NULL, cb, cb_arg);
}

int
@@ -5089,8 +5078,10 @@ spdk_bdev_writev_blocks_ext(struct spdk_bdev_desc *desc, struct spdk_io_channel
		return -EINVAL;
	}

	return bdev_writev_blocks_with_md(desc, ch, iov, iovcnt, md, offset_blocks,
					  num_blocks, cb, cb_arg, opts, false);
	return bdev_writev_blocks_with_md(desc, ch, iov, iovcnt, md, offset_blocks, num_blocks,
					  bdev_get_ext_io_opt(opts, memory_domain, NULL),
					  bdev_get_ext_io_opt(opts, memory_domain_ctx, NULL),
					  cb, cb_arg);
}

static void
@@ -5182,7 +5173,8 @@ bdev_comparev_blocks_with_md(struct spdk_bdev_desc *desc, struct spdk_io_channel
	bdev_io->u.bdev.num_blocks = num_blocks;
	bdev_io->u.bdev.offset_blocks = offset_blocks;
	bdev_io_init(bdev_io, bdev, cb_arg, cb);
	bdev_io->u.bdev.ext_opts = NULL;
	bdev_io->u.bdev.memory_domain = NULL;
	bdev_io->u.bdev.memory_domain_ctx = NULL;

	if (bdev_io_type_supported(bdev, SPDK_BDEV_IO_TYPE_COMPARE)) {
		bdev_io_submit(bdev_io);
@@ -5251,7 +5243,8 @@ bdev_compare_blocks_with_md(struct spdk_bdev_desc *desc, struct spdk_io_channel
	bdev_io->u.bdev.num_blocks = num_blocks;
	bdev_io->u.bdev.offset_blocks = offset_blocks;
	bdev_io_init(bdev_io, bdev, cb_arg, cb);
	bdev_io->u.bdev.ext_opts = NULL;
	bdev_io->u.bdev.memory_domain = NULL;
	bdev_io->u.bdev.memory_domain_ctx = NULL;

	if (bdev_io_type_supported(bdev, SPDK_BDEV_IO_TYPE_COMPARE)) {
		bdev_io_submit(bdev_io);
@@ -5437,7 +5430,8 @@ spdk_bdev_comparev_and_writev_blocks(struct spdk_bdev_desc *desc, struct spdk_io
	bdev_io->u.bdev.num_blocks = num_blocks;
	bdev_io->u.bdev.offset_blocks = offset_blocks;
	bdev_io_init(bdev_io, bdev, cb_arg, cb);
	bdev_io->u.bdev.ext_opts = NULL;
	bdev_io->u.bdev.memory_domain = NULL;
	bdev_io->u.bdev.memory_domain_ctx = NULL;

	if (bdev_io_type_supported(bdev, SPDK_BDEV_IO_TYPE_COMPARE_AND_WRITE)) {
		bdev_io_submit(bdev_io);
@@ -5488,7 +5482,8 @@ spdk_bdev_zcopy_start(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
	bdev_io->u.bdev.zcopy.commit = 0;
	bdev_io->u.bdev.zcopy.start = 1;
	bdev_io_init(bdev_io, bdev, cb_arg, cb);
	bdev_io->u.bdev.ext_opts = NULL;
	bdev_io->u.bdev.memory_domain = NULL;
	bdev_io->u.bdev.memory_domain_ctx = NULL;

	bdev_io_submit(bdev_io);

@@ -5563,7 +5558,8 @@ spdk_bdev_write_zeroes_blocks(struct spdk_bdev_desc *desc, struct spdk_io_channe
	bdev_io->u.bdev.offset_blocks = offset_blocks;
	bdev_io->u.bdev.num_blocks = num_blocks;
	bdev_io_init(bdev_io, bdev, cb_arg, cb);
	bdev_io->u.bdev.ext_opts = NULL;
	bdev_io->u.bdev.memory_domain = NULL;
	bdev_io->u.bdev.memory_domain_ctx = NULL;

	if (bdev_io_type_supported(bdev, SPDK_BDEV_IO_TYPE_WRITE_ZEROES)) {
		bdev_io_submit(bdev_io);
@@ -5633,7 +5629,8 @@ spdk_bdev_unmap_blocks(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
	bdev_io->u.bdev.offset_blocks = offset_blocks;
	bdev_io->u.bdev.num_blocks = num_blocks;
	bdev_io_init(bdev_io, bdev, cb_arg, cb);
	bdev_io->u.bdev.ext_opts = NULL;
	bdev_io->u.bdev.memory_domain = NULL;
	bdev_io->u.bdev.memory_domain_ctx = NULL;

	bdev_io_submit(bdev_io);
	return 0;
@@ -9077,7 +9074,8 @@ spdk_bdev_copy_blocks(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
	bdev_io->u.bdev.offset_blocks = dst_offset_blocks;
	bdev_io->u.bdev.copy.src_offset_blocks = src_offset_blocks;
	bdev_io->u.bdev.num_blocks = num_blocks;
	bdev_io->u.bdev.ext_opts = NULL;
	bdev_io->u.bdev.memory_domain = NULL;
	bdev_io->u.bdev.memory_domain_ctx = NULL;
	bdev_io_init(bdev_io, bdev, cb_arg, cb);

	bdev_io_submit(bdev_io);
+21 −29
Original line number Diff line number Diff line
@@ -275,6 +275,16 @@ bdev_part_complete_io(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg)
	spdk_bdev_free_io(bdev_io);
}

static inline void
bdev_part_init_ext_io_opts(struct spdk_bdev_io *bdev_io, struct spdk_bdev_ext_io_opts *opts)
{
	memset(opts, 0, sizeof(*opts));
	opts->size = sizeof(*opts);
	opts->memory_domain = bdev_io->u.bdev.memory_domain;
	opts->memory_domain_ctx = bdev_io->u.bdev.memory_domain_ctx;
	opts->metadata = bdev_io->u.bdev.md_buf;
}

int
spdk_bdev_part_submit_request_ext(struct spdk_bdev_part_channel *ch, struct spdk_bdev_io *bdev_io,
				  spdk_bdev_io_completion_cb cb)
@@ -282,6 +292,7 @@ spdk_bdev_part_submit_request_ext(struct spdk_bdev_part_channel *ch, struct spdk
	struct spdk_bdev_part *part = ch->part;
	struct spdk_io_channel *base_ch = ch->base_ch;
	struct spdk_bdev_desc *base_desc = part->internal.base->desc;
	struct spdk_bdev_ext_io_opts io_opts;
	uint64_t offset, remapped_offset, remapped_src_offset;
	int rc = 0;

@@ -293,41 +304,22 @@ spdk_bdev_part_submit_request_ext(struct spdk_bdev_part_channel *ch, struct spdk
	/* Modify the I/O to adjust for the offset within the base bdev. */
	switch (bdev_io->type) {
	case SPDK_BDEV_IO_TYPE_READ:
		if (bdev_io->u.bdev.ext_opts) {
		bdev_part_init_ext_io_opts(bdev_io, &io_opts);
		rc = spdk_bdev_readv_blocks_ext(base_desc, base_ch, bdev_io->u.bdev.iovs,
						bdev_io->u.bdev.iovcnt, remapped_offset,
						bdev_io->u.bdev.num_blocks,
							bdev_part_complete_io, bdev_io,
							bdev_io->u.bdev.ext_opts);
		} else {
			rc = spdk_bdev_readv_blocks_with_md(base_desc, base_ch,
							    bdev_io->u.bdev.iovs,
							    bdev_io->u.bdev.iovcnt,
							    bdev_io->u.bdev.md_buf, remapped_offset,
							    bdev_io->u.bdev.num_blocks,
							    bdev_part_complete_io, bdev_io);
		}
						bdev_part_complete_io, bdev_io, &io_opts);
		break;
	case SPDK_BDEV_IO_TYPE_WRITE:
		rc = bdev_part_remap_dif(bdev_io, offset, remapped_offset);
		if (rc != 0) {
			return SPDK_BDEV_IO_STATUS_FAILED;
		}

		if (bdev_io->u.bdev.ext_opts) {
		bdev_part_init_ext_io_opts(bdev_io, &io_opts);
		rc = spdk_bdev_writev_blocks_ext(base_desc, base_ch, bdev_io->u.bdev.iovs,
						 bdev_io->u.bdev.iovcnt, remapped_offset,
						 bdev_io->u.bdev.num_blocks,
							 bdev_part_complete_io, bdev_io,
							 bdev_io->u.bdev.ext_opts);
		} else {
			rc = spdk_bdev_writev_blocks_with_md(base_desc, base_ch,
							     bdev_io->u.bdev.iovs,
							     bdev_io->u.bdev.iovcnt,
							     bdev_io->u.bdev.md_buf, remapped_offset,
							     bdev_io->u.bdev.num_blocks,
							     bdev_part_complete_io, bdev_io);
		}
						 bdev_part_complete_io, bdev_io, &io_opts);
		break;
	case SPDK_BDEV_IO_TYPE_WRITE_ZEROES:
		rc = spdk_bdev_write_zeroes_blocks(base_desc, base_ch, remapped_offset,
+16 −2
Original line number Diff line number Diff line
@@ -253,12 +253,23 @@ vbdev_delay_queue_io(struct spdk_bdev_io *bdev_io)
	}
}

static void
delay_init_ext_io_opts(struct spdk_bdev_io *bdev_io, struct spdk_bdev_ext_io_opts *opts)
{
	memset(opts, 0, sizeof(*opts));
	opts->size = sizeof(*opts);
	opts->memory_domain = bdev_io->u.bdev.memory_domain;
	opts->memory_domain_ctx = bdev_io->u.bdev.memory_domain_ctx;
	opts->metadata = bdev_io->u.bdev.md_buf;
}

static void
delay_read_get_buf_cb(struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_io, bool success)
{
	struct vbdev_delay *delay_node = SPDK_CONTAINEROF(bdev_io->bdev, struct vbdev_delay,
					 delay_bdev);
	struct delay_io_channel *delay_ch = spdk_io_channel_get_ctx(ch);
	struct spdk_bdev_ext_io_opts io_opts;
	int rc;

	if (!success) {
@@ -266,10 +277,11 @@ delay_read_get_buf_cb(struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_io,
		return;
	}

	delay_init_ext_io_opts(bdev_io, &io_opts);
	rc = spdk_bdev_readv_blocks_ext(delay_node->base_desc, delay_ch->base_ch, bdev_io->u.bdev.iovs,
					bdev_io->u.bdev.iovcnt, bdev_io->u.bdev.offset_blocks,
					bdev_io->u.bdev.num_blocks, _delay_complete_io,
					bdev_io, bdev_io->u.bdev.ext_opts);
					bdev_io, &io_opts);

	if (rc == -ENOMEM) {
		SPDK_ERRLOG("No memory, start to queue io for delay.\n");
@@ -381,6 +393,7 @@ vbdev_delay_submit_request(struct spdk_io_channel *ch, struct spdk_bdev_io *bdev
	struct vbdev_delay *delay_node = SPDK_CONTAINEROF(bdev_io->bdev, struct vbdev_delay, delay_bdev);
	struct delay_io_channel *delay_ch = spdk_io_channel_get_ctx(ch);
	struct delay_bdev_io *io_ctx = (struct delay_bdev_io *)bdev_io->driver_ctx;
	struct spdk_bdev_ext_io_opts io_opts;
	int rc = 0;
	bool is_p99;

@@ -400,10 +413,11 @@ vbdev_delay_submit_request(struct spdk_io_channel *ch, struct spdk_bdev_io *bdev
		break;
	case SPDK_BDEV_IO_TYPE_WRITE:
		io_ctx->type = is_p99 ? DELAY_P99_WRITE : DELAY_AVG_WRITE;
		delay_init_ext_io_opts(bdev_io, &io_opts);
		rc = spdk_bdev_writev_blocks_ext(delay_node->base_desc, delay_ch->base_ch, bdev_io->u.bdev.iovs,
						 bdev_io->u.bdev.iovcnt, bdev_io->u.bdev.offset_blocks,
						 bdev_io->u.bdev.num_blocks, _delay_complete_io,
						 bdev_io, bdev_io->u.bdev.ext_opts);
						 bdev_io, &io_opts);
		break;
	case SPDK_BDEV_IO_TYPE_WRITE_ZEROES:
		rc = spdk_bdev_write_zeroes_blocks(delay_node->base_desc, delay_ch->base_ch,
Loading