blobfs: add writev/readv asynchronous APIs support
Change-Id: Id1172f546852fcf25c6d13cb63f9d875b02e768c Signed-off-by: Changpeng Liu <changpeng.liu@intel.com> Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/453493 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
parent
c74ea9fa8e
commit
1966f1eef3
@ -406,6 +406,42 @@ int spdk_file_sync(struct spdk_file *file, struct spdk_fs_thread_ctx *ctx);
|
||||
*/
|
||||
int spdk_file_get_id(struct spdk_file *file, void *id, size_t size);
|
||||
|
||||
/**
|
||||
* Read data to user buffer from the given file.
|
||||
*
|
||||
* \param file File to read.
|
||||
* \param channel I/O channel for asynchronous operations.
|
||||
* \param iovs A scatter gather list of buffers to be read into.
|
||||
* \param iovcnt The number of elements in iov.
|
||||
* \param offset The beginning position to read.
|
||||
* \param length The size in bytes of data to read.
|
||||
* \param cb_fn Called when the request is complete.
|
||||
* \param cb_arg Argument passed to cb_fn.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
void spdk_file_readv_async(struct spdk_file *file, struct spdk_io_channel *channel,
|
||||
struct iovec *iovs, uint32_t iovcnt, uint64_t offset, uint64_t length,
|
||||
spdk_file_op_complete cb_fn, void *cb_arg);
|
||||
|
||||
/**
|
||||
* Write data to the given file.
|
||||
*
|
||||
* \param file File to write.
|
||||
* \param channel I/O channel for asynchronous operations.
|
||||
* \param iovs A scatter gather list of buffers to be written from.
|
||||
* \param iovcnt The number of elements in iov.
|
||||
* \param offset The beginning position to write.
|
||||
* \param length The size in bytes of data to write.
|
||||
* \param cb_fn Called when the request is complete.
|
||||
* \param cb_arg Argument passed to cb_fn.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
void spdk_file_writev_async(struct spdk_file *file, struct spdk_io_channel *channel,
|
||||
struct iovec *iovs, uint32_t iovcnt, uint64_t offset, uint64_t length,
|
||||
spdk_file_op_complete cb_fn, void *cb_arg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -1710,22 +1710,50 @@ __rw_done(void *ctx, int bserrno)
|
||||
free_fs_request(req);
|
||||
}
|
||||
|
||||
static void
|
||||
_copy_iovs_to_buf(void *buf, size_t buf_len, struct iovec *iovs, int iovcnt)
|
||||
{
|
||||
int i;
|
||||
size_t len;
|
||||
|
||||
for (i = 0; i < iovcnt; i++) {
|
||||
len = spdk_min(iovs[i].iov_len, buf_len);
|
||||
memcpy(buf, iovs[i].iov_base, len);
|
||||
buf += len;
|
||||
assert(buf_len >= len);
|
||||
buf_len -= len;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_copy_buf_to_iovs(struct iovec *iovs, int iovcnt, void *buf, size_t buf_len)
|
||||
{
|
||||
int i;
|
||||
size_t len;
|
||||
|
||||
for (i = 0; i < iovcnt; i++) {
|
||||
len = spdk_min(iovs[i].iov_len, buf_len);
|
||||
memcpy(iovs[i].iov_base, buf, len);
|
||||
buf += len;
|
||||
assert(buf_len >= len);
|
||||
buf_len -= len;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
__read_done(void *ctx, int bserrno)
|
||||
{
|
||||
struct spdk_fs_request *req = ctx;
|
||||
struct spdk_fs_cb_args *args = &req->args;
|
||||
void *buf;
|
||||
|
||||
assert(req != NULL);
|
||||
buf = (void *)((uintptr_t)args->op.rw.pin_buf + (args->op.rw.offset & (args->op.rw.blocklen - 1)));
|
||||
if (args->op.rw.is_read) {
|
||||
memcpy(args->iovs[0].iov_base,
|
||||
args->op.rw.pin_buf + (args->op.rw.offset & (args->op.rw.blocklen - 1)),
|
||||
args->iovs[0].iov_len);
|
||||
_copy_buf_to_iovs(args->iovs, args->iovcnt, buf, args->op.rw.length);
|
||||
__rw_done(req, 0);
|
||||
} else {
|
||||
memcpy(args->op.rw.pin_buf + (args->op.rw.offset & (args->op.rw.blocklen - 1)),
|
||||
args->iovs[0].iov_base,
|
||||
args->iovs[0].iov_len);
|
||||
_copy_iovs_to_buf(buf, args->op.rw.length, args->iovs, args->iovcnt);
|
||||
spdk_blob_io_write(args->file->blob, args->op.rw.channel,
|
||||
args->op.rw.pin_buf,
|
||||
args->op.rw.start_lba, args->op.rw.num_lba,
|
||||
@ -1762,8 +1790,19 @@ __get_page_parameters(struct spdk_file *file, uint64_t offset, uint64_t length,
|
||||
}
|
||||
|
||||
static void
|
||||
__readwrite(struct spdk_file *file, struct spdk_io_channel *_channel,
|
||||
void *payload, uint64_t offset, uint64_t length,
|
||||
_fs_request_setup_iovs(struct spdk_fs_request *req, struct iovec *iovs, uint32_t iovcnt)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < iovcnt; i++) {
|
||||
req->args.iovs[i].iov_base = iovs[i].iov_base;
|
||||
req->args.iovs[i].iov_len = iovs[i].iov_len;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
__readvwritev(struct spdk_file *file, struct spdk_io_channel *_channel,
|
||||
struct iovec *iovs, uint32_t iovcnt, uint64_t offset, uint64_t length,
|
||||
spdk_file_op_complete cb_fn, void *cb_arg, int is_read)
|
||||
{
|
||||
struct spdk_fs_request *req;
|
||||
@ -1777,7 +1816,7 @@ __readwrite(struct spdk_file *file, struct spdk_io_channel *_channel,
|
||||
return;
|
||||
}
|
||||
|
||||
req = alloc_fs_request_with_iov(channel, 1);
|
||||
req = alloc_fs_request_with_iov(channel, iovcnt);
|
||||
if (req == NULL) {
|
||||
cb_fn(cb_arg, -ENOMEM);
|
||||
return;
|
||||
@ -1790,13 +1829,13 @@ __readwrite(struct spdk_file *file, struct spdk_io_channel *_channel,
|
||||
args->arg = cb_arg;
|
||||
args->file = file;
|
||||
args->op.rw.channel = channel->bs_channel;
|
||||
args->iovs[0].iov_base = payload;
|
||||
args->iovs[0].iov_len = (size_t)length;
|
||||
_fs_request_setup_iovs(req, iovs, iovcnt);
|
||||
args->op.rw.is_read = is_read;
|
||||
args->op.rw.offset = offset;
|
||||
args->op.rw.blocklen = lba_size;
|
||||
|
||||
pin_buf_length = num_lba * lba_size;
|
||||
args->op.rw.length = pin_buf_length;
|
||||
args->op.rw.pin_buf = spdk_malloc(pin_buf_length, lba_size, NULL,
|
||||
SPDK_ENV_SOCKET_ID_ANY, SPDK_MALLOC_DMA);
|
||||
if (args->op.rw.pin_buf == NULL) {
|
||||
@ -1817,6 +1856,19 @@ __readwrite(struct spdk_file *file, struct spdk_io_channel *_channel,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
__readwrite(struct spdk_file *file, struct spdk_io_channel *channel,
|
||||
void *payload, uint64_t offset, uint64_t length,
|
||||
spdk_file_op_complete cb_fn, void *cb_arg, int is_read)
|
||||
{
|
||||
struct iovec iov;
|
||||
|
||||
iov.iov_base = payload;
|
||||
iov.iov_len = (size_t)length;
|
||||
|
||||
__readvwritev(file, channel, &iov, 1, offset, length, cb_fn, cb_arg, is_read);
|
||||
}
|
||||
|
||||
void
|
||||
spdk_file_write_async(struct spdk_file *file, struct spdk_io_channel *channel,
|
||||
void *payload, uint64_t offset, uint64_t length,
|
||||
@ -1825,6 +1877,17 @@ spdk_file_write_async(struct spdk_file *file, struct spdk_io_channel *channel,
|
||||
__readwrite(file, channel, payload, offset, length, cb_fn, cb_arg, 0);
|
||||
}
|
||||
|
||||
void
|
||||
spdk_file_writev_async(struct spdk_file *file, struct spdk_io_channel *channel,
|
||||
struct iovec *iovs, uint32_t iovcnt, uint64_t offset, uint64_t length,
|
||||
spdk_file_op_complete cb_fn, void *cb_arg)
|
||||
{
|
||||
SPDK_DEBUGLOG(SPDK_LOG_BLOBFS, "file=%s offset=%jx length=%jx\n",
|
||||
file->name, offset, length);
|
||||
|
||||
__readvwritev(file, channel, iovs, iovcnt, offset, length, cb_fn, cb_arg, 0);
|
||||
}
|
||||
|
||||
void
|
||||
spdk_file_read_async(struct spdk_file *file, struct spdk_io_channel *channel,
|
||||
void *payload, uint64_t offset, uint64_t length,
|
||||
@ -1835,6 +1898,17 @@ spdk_file_read_async(struct spdk_file *file, struct spdk_io_channel *channel,
|
||||
__readwrite(file, channel, payload, offset, length, cb_fn, cb_arg, 1);
|
||||
}
|
||||
|
||||
void
|
||||
spdk_file_readv_async(struct spdk_file *file, struct spdk_io_channel *channel,
|
||||
struct iovec *iovs, uint32_t iovcnt, uint64_t offset, uint64_t length,
|
||||
spdk_file_op_complete cb_fn, void *cb_arg)
|
||||
{
|
||||
SPDK_DEBUGLOG(SPDK_LOG_BLOBFS, "file=%s offset=%jx length=%jx\n",
|
||||
file->name, offset, length);
|
||||
|
||||
__readvwritev(file, channel, iovs, iovcnt, offset, length, cb_fn, cb_arg, 1);
|
||||
}
|
||||
|
||||
struct spdk_io_channel *
|
||||
spdk_fs_alloc_io_channel(struct spdk_filesystem *fs)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user