diff --git a/CHANGELOG.md b/CHANGELOG.md index 775e4cc75..1ea926a99 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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. diff --git a/include/spdk/util.h b/include/spdk/util.h index d4ed4aab8..93e0260b5 100644 --- a/include/spdk/util.h +++ b/include/spdk/util.h @@ -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 diff --git a/lib/bdev/bdev.c b/lib/bdev/bdev.c index 5f7c1962d..9c318fcd0 100644 --- a/lib/bdev/bdev.c +++ b/lib/bdev/bdev.c @@ -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,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_memory_domain_get_dma_device_id(bdev_io->internal.ext_opts->memory_domain)); } else { - _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); + 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); } } diff --git a/lib/blobfs/blobfs.c b/lib/blobfs/blobfs.c index 208a690c2..e2c36bd5c 100644 --- a/lib/blobfs/blobfs.c +++ b/lib/blobfs/blobfs.c @@ -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, diff --git a/lib/util/Makefile b/lib/util/Makefile index 3a02ed853..fd03be6aa 100644 --- a/lib/util/Makefile +++ b/lib/util/Makefile @@ -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 \ diff --git a/lib/util/iov.c b/lib/util/iov.c index ea41658aa..3bc4c4cd8 100644 --- a/lib/util/iov.c +++ b/lib/util/iov.c @@ -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; + } +} diff --git a/lib/util/spdk_util.map b/lib/util/spdk_util.map index e72a2e254..a54e9f196 100644 --- a/lib/util/spdk_util.map +++ b/lib/util/spdk_util.map @@ -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; diff --git a/mk/spdk.lib_deps.mk b/mk/spdk.lib_deps.mk index ad5ea481f..4573cdca0 100644 --- a/mk/spdk.lib_deps.mk +++ b/mk/spdk.lib_deps.mk @@ -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 diff --git a/test/unit/lib/util/iov.c/iov_ut.c b/test/unit/lib/util/iov.c/iov_ut.c index a55aec437..bbef734eb 100644 --- a/test/unit/lib/util/iov.c/iov_ut.c +++ b/test/unit/lib/util/iov.c/iov_ut.c @@ -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);