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:
yidong0635 2022-05-16 20:02:38 +08:00 committed by Tomasz Zawadzki
parent a8326f8155
commit dabca25646
9 changed files with 107 additions and 68 deletions

View File

@ -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
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
Removed deprecated spdk_bdev_module_finish_done(). Use spdk_bdev_module_fini_done() instead.

View File

@ -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);
/**
* 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
* dequeue NULL buffers even if they return success. This is obviously a false

View File

@ -787,34 +787,6 @@ _are_iovs_aligned(struct iovec *iovs, int iovcnt, uint32_t alignment)
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
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_memory_domain_get_dma_device_id(bdev_io->internal.ext_opts->memory_domain));
} 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,7 +1190,7 @@ _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_memory_domain_get_dma_device_id(bdev_io->internal.ext_opts->memory_domain));
} 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.bounce_iov.iov_base,
bdev_io->internal.bounce_iov.iov_len);

View File

@ -1707,36 +1707,6 @@ __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)
{
@ -1747,10 +1717,10 @@ __read_done(void *ctx, int bserrno)
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) {
_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);
} 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,
args->op.rw.pin_buf,
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) {
spdk_file_truncate_async(file, offset + length, __do_blob_read, req);
} 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,
args->op.rw.pin_buf,
args->op.rw.start_lba, args->op.rw.num_lba,

View File

@ -7,7 +7,7 @@ SPDK_ROOT_DIR := $(abspath $(CURDIR)/../..)
include $(SPDK_ROOT_DIR)/mk/spdk.common.mk
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 \
dif.c fd.c file.c iov.c math.c pipe.c strerror_tls.c string.c uuid.c \

View File

@ -103,3 +103,33 @@ spdk_iovcpy(struct iovec *siov, size_t siovcnt, struct iovec *diov, size_t diovc
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;
}
}

View File

@ -126,6 +126,8 @@
spdk_iovcpy;
spdk_ioviter_first;
spdk_ioviter_next;
spdk_copy_iovs_to_buf;
spdk_copy_buf_to_iovs;
# resolvers for functions in util.h
spdk_u32log2.resolver;

View File

@ -56,7 +56,7 @@ DEPDIRS-notify := log util $(JSON_LIBS)
DEPDIRS-trace := log util $(JSON_LIBS)
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-init := jsonrpc json log rpc thread util

View File

@ -195,6 +195,54 @@ test_complex_iov(void)
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
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_simple_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);