util: Extract a common lib between iovs and buf.
It's useful to add these APIs. spdk_copy_iovs_to_buf and spdk_copy_buf_to_iovs. It prepares that other ones can call these. We don't need to define them in static state repeatedly. And add corresponding unit tests. Change-Id: Ife40fec8d047a48af67b04e6c055e4932282abfb Signed-off-by: yidong0635 <dongx.yi@intel.com> Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/12075 Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com> Community-CI: Mellanox Build Bot Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Konrad Sztyber <konrad.sztyber@intel.com> Reviewed-by: Shuhei Matsumoto <smatsumoto@nvidia.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
parent
a8326f8155
commit
dabca25646
@ -14,6 +14,9 @@ A new parameter `bounce_iovcnt` was added to `spdk_dif_generate_copy` and `spdk_
|
|||||||
The `bounce_iovcnt` is used to specify the number of bounce_iov to support multiple block-aligned
|
The `bounce_iovcnt` is used to specify the number of bounce_iov to support multiple block-aligned
|
||||||
fragment copies.
|
fragment copies.
|
||||||
|
|
||||||
|
A new API `spdk_copy_iovs_to_buf` and `spdk_copy_buf_to_iovs` were added to copy iovs to buf or
|
||||||
|
copy buf to iovs. There're many cases need to use these two APIs.
|
||||||
|
|
||||||
### bdev
|
### bdev
|
||||||
|
|
||||||
Removed deprecated spdk_bdev_module_finish_done(). Use spdk_bdev_module_fini_done() instead.
|
Removed deprecated spdk_bdev_module_finish_done(). Use spdk_bdev_module_fini_done() instead.
|
||||||
|
@ -147,6 +147,18 @@ size_t spdk_ioviter_first(struct spdk_ioviter *iter,
|
|||||||
*/
|
*/
|
||||||
size_t spdk_ioviter_next(struct spdk_ioviter *iter, void **src, void **dst);
|
size_t spdk_ioviter_next(struct spdk_ioviter *iter, void **src, void **dst);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy iovs contents to buf through memcpy.
|
||||||
|
*/
|
||||||
|
void spdk_copy_iovs_to_buf(void *buf, size_t buf_len, struct iovec *iovs,
|
||||||
|
int iovcnt);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy buf contents to iovs through memcpy.
|
||||||
|
*/
|
||||||
|
void spdk_copy_buf_to_iovs(struct iovec *iovs, int iovcnt, void *buf,
|
||||||
|
size_t buf_len);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scan build is really pessimistic and assumes that mempool functions can
|
* Scan build is really pessimistic and assumes that mempool functions can
|
||||||
* dequeue NULL buffers even if they return success. This is obviously a false
|
* dequeue NULL buffers even if they return success. This is obviously a false
|
||||||
|
@ -787,34 +787,6 @@ _are_iovs_aligned(struct iovec *iovs, int iovcnt, uint32_t alignment)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
buf_len -= len;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
bdev_io_get_buf_complete(struct spdk_bdev_io *bdev_io, bool status)
|
bdev_io_get_buf_complete(struct spdk_bdev_io *bdev_io, bool status)
|
||||||
{
|
{
|
||||||
@ -953,7 +925,7 @@ _bdev_io_pull_bounce_data_buf(struct spdk_bdev_io *bdev_io, void *buf, size_t le
|
|||||||
SPDK_ERRLOG("Failed to pull data from memory domain %s\n",
|
SPDK_ERRLOG("Failed to pull data from memory domain %s\n",
|
||||||
spdk_memory_domain_get_dma_device_id(bdev_io->internal.ext_opts->memory_domain));
|
spdk_memory_domain_get_dma_device_id(bdev_io->internal.ext_opts->memory_domain));
|
||||||
} else {
|
} else {
|
||||||
_copy_iovs_to_buf(buf, len, bdev_io->internal.orig_iovs, bdev_io->internal.orig_iovcnt);
|
spdk_copy_iovs_to_buf(buf, len, bdev_io->internal.orig_iovs, bdev_io->internal.orig_iovcnt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1218,10 +1190,10 @@ _bdev_io_push_bounce_data_buffer(struct spdk_bdev_io *bdev_io, bdev_copy_bounce_
|
|||||||
SPDK_ERRLOG("Failed to push data to memory domain %s\n",
|
SPDK_ERRLOG("Failed to push data to memory domain %s\n",
|
||||||
spdk_memory_domain_get_dma_device_id(bdev_io->internal.ext_opts->memory_domain));
|
spdk_memory_domain_get_dma_device_id(bdev_io->internal.ext_opts->memory_domain));
|
||||||
} else {
|
} else {
|
||||||
_copy_buf_to_iovs(bdev_io->internal.orig_iovs,
|
spdk_copy_buf_to_iovs(bdev_io->internal.orig_iovs,
|
||||||
bdev_io->internal.orig_iovcnt,
|
bdev_io->internal.orig_iovcnt,
|
||||||
bdev_io->internal.bounce_iov.iov_base,
|
bdev_io->internal.bounce_iov.iov_base,
|
||||||
bdev_io->internal.bounce_iov.iov_len);
|
bdev_io->internal.bounce_iov.iov_len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1707,36 +1707,6 @@ __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)
|
||||||
{
|
{
|
||||||
@ -1747,10 +1717,10 @@ __read_done(void *ctx, int bserrno)
|
|||||||
assert(req != NULL);
|
assert(req != NULL);
|
||||||
buf = (void *)((uintptr_t)args->op.rw.pin_buf + (args->op.rw.offset & (args->op.rw.blocklen - 1)));
|
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) {
|
||||||
_copy_buf_to_iovs(args->iovs, args->iovcnt, buf, args->op.rw.length);
|
spdk_copy_buf_to_iovs(args->iovs, args->iovcnt, buf, args->op.rw.length);
|
||||||
__rw_done(req, 0);
|
__rw_done(req, 0);
|
||||||
} else {
|
} else {
|
||||||
_copy_iovs_to_buf(buf, args->op.rw.length, args->iovs, args->iovcnt);
|
spdk_copy_iovs_to_buf(buf, args->op.rw.length, args->iovs, args->iovcnt);
|
||||||
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,
|
||||||
@ -1861,7 +1831,7 @@ __readvwritev(struct spdk_file *file, struct spdk_io_channel *_channel,
|
|||||||
if (!is_read && file->length < offset + length) {
|
if (!is_read && file->length < offset + length) {
|
||||||
spdk_file_truncate_async(file, offset + length, __do_blob_read, req);
|
spdk_file_truncate_async(file, offset + length, __do_blob_read, req);
|
||||||
} else if (!is_read && __is_lba_aligned(file, offset, length)) {
|
} else if (!is_read && __is_lba_aligned(file, offset, length)) {
|
||||||
_copy_iovs_to_buf(args->op.rw.pin_buf, args->op.rw.length, args->iovs, args->iovcnt);
|
spdk_copy_iovs_to_buf(args->op.rw.pin_buf, args->op.rw.length, args->iovs, args->iovcnt);
|
||||||
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,
|
||||||
|
@ -7,7 +7,7 @@ SPDK_ROOT_DIR := $(abspath $(CURDIR)/../..)
|
|||||||
include $(SPDK_ROOT_DIR)/mk/spdk.common.mk
|
include $(SPDK_ROOT_DIR)/mk/spdk.common.mk
|
||||||
|
|
||||||
SO_VER := 5
|
SO_VER := 5
|
||||||
SO_MINOR := 0
|
SO_MINOR := 1
|
||||||
|
|
||||||
C_SRCS = base64.c bit_array.c cpuset.c crc16.c crc32.c crc32c.c crc32_ieee.c \
|
C_SRCS = base64.c bit_array.c cpuset.c crc16.c crc32.c crc32c.c crc32_ieee.c \
|
||||||
dif.c fd.c file.c iov.c math.c pipe.c strerror_tls.c string.c uuid.c \
|
dif.c fd.c file.c iov.c math.c pipe.c strerror_tls.c string.c uuid.c \
|
||||||
|
@ -103,3 +103,33 @@ spdk_iovcpy(struct iovec *siov, size_t siovcnt, struct iovec *diov, size_t diovc
|
|||||||
|
|
||||||
return total_sz;
|
return total_sz;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
spdk_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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
spdk_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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -126,6 +126,8 @@
|
|||||||
spdk_iovcpy;
|
spdk_iovcpy;
|
||||||
spdk_ioviter_first;
|
spdk_ioviter_first;
|
||||||
spdk_ioviter_next;
|
spdk_ioviter_next;
|
||||||
|
spdk_copy_iovs_to_buf;
|
||||||
|
spdk_copy_buf_to_iovs;
|
||||||
|
|
||||||
# resolvers for functions in util.h
|
# resolvers for functions in util.h
|
||||||
spdk_u32log2.resolver;
|
spdk_u32log2.resolver;
|
||||||
|
@ -56,7 +56,7 @@ DEPDIRS-notify := log util $(JSON_LIBS)
|
|||||||
DEPDIRS-trace := log util $(JSON_LIBS)
|
DEPDIRS-trace := log util $(JSON_LIBS)
|
||||||
|
|
||||||
DEPDIRS-bdev := log util thread $(JSON_LIBS) notify trace dma
|
DEPDIRS-bdev := log util thread $(JSON_LIBS) notify trace dma
|
||||||
DEPDIRS-blobfs := log thread blob trace
|
DEPDIRS-blobfs := log thread blob trace util
|
||||||
DEPDIRS-event := log util thread $(JSON_LIBS) trace init
|
DEPDIRS-event := log util thread $(JSON_LIBS) trace init
|
||||||
DEPDIRS-init := jsonrpc json log rpc thread util
|
DEPDIRS-init := jsonrpc json log rpc thread util
|
||||||
|
|
||||||
|
@ -195,6 +195,54 @@ test_complex_iov(void)
|
|||||||
CU_ASSERT(_check_val(ddata, 64, 1) == 0);
|
CU_ASSERT(_check_val(ddata, 64, 1) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_iovs_to_buf(void)
|
||||||
|
{
|
||||||
|
struct iovec iov[4];
|
||||||
|
uint8_t sdata[64];
|
||||||
|
uint8_t ddata[64];
|
||||||
|
|
||||||
|
memset(&sdata, 1, sizeof(sdata));
|
||||||
|
memset(&ddata, 6, sizeof(ddata));
|
||||||
|
|
||||||
|
iov[0].iov_base = sdata;
|
||||||
|
iov[0].iov_len = 3;
|
||||||
|
iov[1].iov_base = iov[0].iov_base + iov[0].iov_len;
|
||||||
|
iov[1].iov_len = 11;
|
||||||
|
iov[2].iov_base = iov[1].iov_base + iov[1].iov_len;
|
||||||
|
iov[2].iov_len = 21;
|
||||||
|
iov[3].iov_base = iov[2].iov_base + iov[2].iov_len;
|
||||||
|
iov[3].iov_len = 29;
|
||||||
|
|
||||||
|
spdk_copy_iovs_to_buf(ddata, 64, iov, 4);
|
||||||
|
CU_ASSERT(_check_val(ddata, 64, 1) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_buf_to_iovs(void)
|
||||||
|
{
|
||||||
|
struct iovec iov[4];
|
||||||
|
uint8_t sdata[64];
|
||||||
|
uint8_t ddata[64];
|
||||||
|
|
||||||
|
memset(&sdata, 7, sizeof(sdata));
|
||||||
|
memset(&ddata, 4, sizeof(ddata));
|
||||||
|
|
||||||
|
iov[0].iov_base = sdata;
|
||||||
|
iov[0].iov_len = 5;
|
||||||
|
iov[1].iov_base = iov[0].iov_base + iov[0].iov_len;
|
||||||
|
iov[1].iov_len = 15;
|
||||||
|
iov[2].iov_base = iov[1].iov_base + iov[1].iov_len;
|
||||||
|
iov[2].iov_len = 21;
|
||||||
|
iov[3].iov_base = iov[2].iov_base + iov[2].iov_len;
|
||||||
|
iov[3].iov_len = 23;
|
||||||
|
|
||||||
|
spdk_copy_buf_to_iovs(iov, 4, sdata, 64);
|
||||||
|
spdk_copy_iovs_to_buf(ddata, 64, iov, 4);
|
||||||
|
|
||||||
|
CU_ASSERT(_check_val(ddata, 64, 7) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
@ -209,6 +257,8 @@ main(int argc, char **argv)
|
|||||||
CU_ADD_TEST(suite, test_single_iov);
|
CU_ADD_TEST(suite, test_single_iov);
|
||||||
CU_ADD_TEST(suite, test_simple_iov);
|
CU_ADD_TEST(suite, test_simple_iov);
|
||||||
CU_ADD_TEST(suite, test_complex_iov);
|
CU_ADD_TEST(suite, test_complex_iov);
|
||||||
|
CU_ADD_TEST(suite, test_iovs_to_buf);
|
||||||
|
CU_ADD_TEST(suite, test_buf_to_iovs);
|
||||||
|
|
||||||
CU_basic_set_mode(CU_BRM_VERBOSE);
|
CU_basic_set_mode(CU_BRM_VERBOSE);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user