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);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1710,22 +1710,50 @@ __rw_done(void *ctx, int bserrno)
|
|||||||
free_fs_request(req);
|
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
|
static void
|
||||||
__read_done(void *ctx, int bserrno)
|
__read_done(void *ctx, int bserrno)
|
||||||
{
|
{
|
||||||
struct spdk_fs_request *req = ctx;
|
struct spdk_fs_request *req = ctx;
|
||||||
struct spdk_fs_cb_args *args = &req->args;
|
struct spdk_fs_cb_args *args = &req->args;
|
||||||
|
void *buf;
|
||||||
|
|
||||||
assert(req != NULL);
|
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) {
|
if (args->op.rw.is_read) {
|
||||||
memcpy(args->iovs[0].iov_base,
|
_copy_buf_to_iovs(args->iovs, args->iovcnt, buf, args->op.rw.length);
|
||||||
args->op.rw.pin_buf + (args->op.rw.offset & (args->op.rw.blocklen - 1)),
|
|
||||||
args->iovs[0].iov_len);
|
|
||||||
__rw_done(req, 0);
|
__rw_done(req, 0);
|
||||||
} else {
|
} else {
|
||||||
memcpy(args->op.rw.pin_buf + (args->op.rw.offset & (args->op.rw.blocklen - 1)),
|
_copy_iovs_to_buf(buf, args->op.rw.length, args->iovs, args->iovcnt);
|
||||||
args->iovs[0].iov_base,
|
|
||||||
args->iovs[0].iov_len);
|
|
||||||
spdk_blob_io_write(args->file->blob, args->op.rw.channel,
|
spdk_blob_io_write(args->file->blob, args->op.rw.channel,
|
||||||
args->op.rw.pin_buf,
|
args->op.rw.pin_buf,
|
||||||
args->op.rw.start_lba, args->op.rw.num_lba,
|
args->op.rw.start_lba, args->op.rw.num_lba,
|
||||||
@ -1762,9 +1790,20 @@ __get_page_parameters(struct spdk_file *file, uint64_t offset, uint64_t length,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
__readwrite(struct spdk_file *file, struct spdk_io_channel *_channel,
|
_fs_request_setup_iovs(struct spdk_fs_request *req, struct iovec *iovs, uint32_t iovcnt)
|
||||||
void *payload, uint64_t offset, uint64_t length,
|
{
|
||||||
spdk_file_op_complete cb_fn, void *cb_arg, int is_read)
|
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;
|
struct spdk_fs_request *req;
|
||||||
struct spdk_fs_cb_args *args;
|
struct spdk_fs_cb_args *args;
|
||||||
@ -1777,7 +1816,7 @@ __readwrite(struct spdk_file *file, struct spdk_io_channel *_channel,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
req = alloc_fs_request_with_iov(channel, 1);
|
req = alloc_fs_request_with_iov(channel, iovcnt);
|
||||||
if (req == NULL) {
|
if (req == NULL) {
|
||||||
cb_fn(cb_arg, -ENOMEM);
|
cb_fn(cb_arg, -ENOMEM);
|
||||||
return;
|
return;
|
||||||
@ -1790,13 +1829,13 @@ __readwrite(struct spdk_file *file, struct spdk_io_channel *_channel,
|
|||||||
args->arg = cb_arg;
|
args->arg = cb_arg;
|
||||||
args->file = file;
|
args->file = file;
|
||||||
args->op.rw.channel = channel->bs_channel;
|
args->op.rw.channel = channel->bs_channel;
|
||||||
args->iovs[0].iov_base = payload;
|
_fs_request_setup_iovs(req, iovs, iovcnt);
|
||||||
args->iovs[0].iov_len = (size_t)length;
|
|
||||||
args->op.rw.is_read = is_read;
|
args->op.rw.is_read = is_read;
|
||||||
args->op.rw.offset = offset;
|
args->op.rw.offset = offset;
|
||||||
args->op.rw.blocklen = lba_size;
|
args->op.rw.blocklen = lba_size;
|
||||||
|
|
||||||
pin_buf_length = num_lba * 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,
|
args->op.rw.pin_buf = spdk_malloc(pin_buf_length, lba_size, NULL,
|
||||||
SPDK_ENV_SOCKET_ID_ANY, SPDK_MALLOC_DMA);
|
SPDK_ENV_SOCKET_ID_ANY, SPDK_MALLOC_DMA);
|
||||||
if (args->op.rw.pin_buf == NULL) {
|
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
|
void
|
||||||
spdk_file_write_async(struct spdk_file *file, struct spdk_io_channel *channel,
|
spdk_file_write_async(struct spdk_file *file, struct spdk_io_channel *channel,
|
||||||
void *payload, uint64_t offset, uint64_t length,
|
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);
|
__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
|
void
|
||||||
spdk_file_read_async(struct spdk_file *file, struct spdk_io_channel *channel,
|
spdk_file_read_async(struct spdk_file *file, struct spdk_io_channel *channel,
|
||||||
void *payload, uint64_t offset, uint64_t length,
|
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);
|
__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 *
|
struct spdk_io_channel *
|
||||||
spdk_fs_alloc_io_channel(struct spdk_filesystem *fs)
|
spdk_fs_alloc_io_channel(struct spdk_filesystem *fs)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user