Commit b2503cb3 authored by Jim Harris's avatar Jim Harris
Browse files

blob: add spdk_bs_user_op_t



This allows a channel's request_set resources to be
used for queuing I/O requests.  This is needed
for upcoming thin provisioning functionality,
where we must queue I/O requests that need to
allocate a cluster, if another cluster allocation
is in progress.

Signed-off-by: default avatarJim Harris <james.r.harris@intel.com>
Change-Id: Ie8d3e799afc0b56bc95ba5ecab11253d8bc8608f
Reviewed-on: https://review.gerrithub.io/395037


Tested-by: default avatarSPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-by: default avatarDaniel Verkamp <daniel.verkamp@intel.com>
parent 4547f9bd
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -1233,6 +1233,10 @@ _spdk_blob_request_submit_op_split(struct spdk_io_channel *ch, struct spdk_blob
		case SPDK_BLOB_WRITE_ZEROES:
			spdk_bs_batch_write_zeroes_blob(batch, _blob, offset, op_length);
			break;
		case SPDK_BLOB_READV:
		case SPDK_BLOB_WRITEV:
			SPDK_ERRLOG("readv/write not valid for %s\n", __func__);
			break;
		}

		length -= op_length;
@@ -1284,6 +1288,10 @@ _spdk_blob_request_submit_op_single(struct spdk_io_channel *_ch, struct spdk_blo
	case SPDK_BLOB_WRITE_ZEROES:
		spdk_bs_batch_write_zeroes_dev(batch, lba, lba_count);
		break;
	case SPDK_BLOB_READV:
	case SPDK_BLOB_WRITEV:
		SPDK_ERRLOG("readv/write not valid for %s\n", __func__);
		break;
	}

	spdk_bs_batch_close(batch);
+2 −0
Original line number Diff line number Diff line
@@ -188,6 +188,8 @@ enum spdk_blob_op_type {
	SPDK_BLOB_READ,
	SPDK_BLOB_UNMAP,
	SPDK_BLOB_WRITE_ZEROES,
	SPDK_BLOB_WRITEV,
	SPDK_BLOB_READV,
};

/* On-Disk Data Structures
+85 −0
Original line number Diff line number Diff line
@@ -470,4 +470,89 @@ spdk_bs_sequence_to_batch(spdk_bs_sequence_t *seq, spdk_bs_sequence_cpl cb_fn, v
	return set;
}

spdk_bs_user_op_t *
spdk_bs_user_op_alloc(struct spdk_io_channel *_channel, struct spdk_bs_cpl *cpl,
		      enum spdk_blob_op_type op_type, struct spdk_blob *blob,
		      void *payload, int iovcnt, uint64_t offset, uint64_t length)
{
	struct spdk_bs_channel		*channel;
	struct spdk_bs_request_set	*set;
	struct spdk_bs_user_op_args	*args;

	channel = spdk_io_channel_get_ctx(_channel);

	set = TAILQ_FIRST(&channel->reqs);
	if (!set) {
		return NULL;
	}
	TAILQ_REMOVE(&channel->reqs, set, link);

	set->cpl = *cpl;
	set->channel = channel;

	args = &set->u.user_op;

	args->type = op_type;
	args->iovcnt = 0;
	args->blob = blob;
	args->offset = offset;
	args->length = length;
	args->payload = payload;

	return (spdk_bs_user_op_t *)set;
}

void
spdk_bs_user_op_execute(spdk_bs_user_op_t *op)
{
	struct spdk_bs_request_set	*set;
	struct spdk_bs_user_op_args	*args;
	struct spdk_io_channel		*ch;

	set = (struct spdk_bs_request_set *)op;
	args = &set->u.user_op;
	ch = spdk_io_channel_from_ctx(set->channel);

	switch (args->type) {
	case SPDK_BLOB_READ:
		spdk_bs_io_read_blob(args->blob, ch, args->payload, args->offset, args->length,
				     set->cpl.u.blob_basic.cb_fn, set->cpl.u.blob_basic.cb_arg);
		break;
	case SPDK_BLOB_WRITE:
		spdk_bs_io_write_blob(args->blob, ch, args->payload, args->offset, args->length,
				      set->cpl.u.blob_basic.cb_fn, set->cpl.u.blob_basic.cb_arg);
		break;
	case SPDK_BLOB_UNMAP:
		spdk_bs_io_unmap_blob(args->blob, ch, args->offset, args->length,
				      set->cpl.u.blob_basic.cb_fn, set->cpl.u.blob_basic.cb_arg);
		break;
	case SPDK_BLOB_WRITE_ZEROES:
		spdk_bs_io_write_zeroes_blob(args->blob, ch, args->offset, args->length,
					     set->cpl.u.blob_basic.cb_fn, set->cpl.u.blob_basic.cb_arg);
		break;
	case SPDK_BLOB_READV:
		spdk_bs_io_readv_blob(args->blob, ch, args->payload, args->iovcnt,
				      args->offset, args->length,
				      set->cpl.u.blob_basic.cb_fn, set->cpl.u.blob_basic.cb_arg);
		break;
	case SPDK_BLOB_WRITEV:
		spdk_bs_io_writev_blob(args->blob, ch, args->payload, args->iovcnt,
				       args->offset, args->length,
				       set->cpl.u.blob_basic.cb_fn, set->cpl.u.blob_basic.cb_arg);
		break;
	}
	TAILQ_INSERT_TAIL(&set->channel->reqs, set, link);
}

void
spdk_bs_user_op_abort(spdk_bs_user_op_t *op)
{
	struct spdk_bs_request_set	*set;

	set = (struct spdk_bs_request_set *)op;

	set->cpl.u.blob_basic.cb_fn(set->cpl.u.blob_basic.cb_arg, -EIO);
	TAILQ_INSERT_TAIL(&set->channel->reqs, set, link);
}

SPDK_LOG_REGISTER_COMPONENT("blob_rw", SPDK_LOG_BLOB_RW)
+25 −1
Original line number Diff line number Diff line
@@ -48,6 +48,8 @@ enum spdk_bs_cpl_type {
	SPDK_BS_CPL_TYPE_NESTED_SEQUENCE,
};

enum spdk_blob_op_type;

struct spdk_bs_request_set;

/* Use a sequence to submit a set of requests serially */
@@ -56,6 +58,9 @@ typedef struct spdk_bs_request_set spdk_bs_sequence_t;
/* Use a batch to submit a set of requests in parallel */
typedef struct spdk_bs_request_set spdk_bs_batch_t;

/* Use a user_op to queue a user operation for later execution */
typedef struct spdk_bs_request_set spdk_bs_user_op_t;

typedef void (*spdk_bs_nested_seq_complete)(void *cb_arg, spdk_bs_sequence_t *parent, int bserrno);

struct spdk_bs_cpl {
@@ -100,7 +105,7 @@ struct spdk_bs_cpl {
typedef void (*spdk_bs_sequence_cpl)(spdk_bs_sequence_t *sequence,
				     void *cb_arg, int bserrno);

/* A generic request set. Can be a sequence or a batch. */
/* A generic request set. Can be a sequence, batch or a user_op. */
struct spdk_bs_request_set {
	struct spdk_bs_cpl      cpl;

@@ -122,6 +127,17 @@ struct spdk_bs_request_set {
			spdk_bs_sequence_cpl	cb_fn;
			void			*cb_arg;
		} batch;

		struct spdk_bs_user_op_args {
			int			type;
			int			iovcnt;
			struct spdk_blob	*blob;
			uint64_t		offset;
			uint64_t		length;
			spdk_blob_op_complete	cb_fn;
			void			*cb_arg;
			void			*payload; /* cast to iov for readv/writev */
		} user_op;
	} u;

	TAILQ_ENTRY(spdk_bs_request_set) link;
@@ -202,4 +218,12 @@ spdk_bs_batch_t *spdk_bs_sequence_to_batch(spdk_bs_sequence_t *seq,
		spdk_bs_sequence_cpl cb_fn,
		void *cb_arg);

spdk_bs_user_op_t *spdk_bs_user_op_alloc(struct spdk_io_channel *channel, struct spdk_bs_cpl *cpl,
		enum spdk_blob_op_type op_type, struct spdk_blob *blob,
		void *payload, int iovcnt, uint64_t offset, uint64_t length);

void spdk_bs_user_op_execute(spdk_bs_user_op_t *op);

void spdk_bs_user_op_abort(spdk_bs_user_op_t *op);

#endif