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: Jim Harris <james.r.harris@intel.com>
Change-Id: Ie8d3e799afc0b56bc95ba5ecab11253d8bc8608f
Reviewed-on: https://review.gerrithub.io/395037
Tested-by: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com>
This commit is contained in:
Jim Harris 2017-11-29 13:14:51 -07:00
parent 4547f9bdf8
commit b2503cb335
4 changed files with 120 additions and 1 deletions

View File

@ -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);

View File

@ -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

View File

@ -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)

View File

@ -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