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:
parent
4547f9bdf8
commit
b2503cb335
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user