From 69c4b07a6466f9eeec791a166dc3206cc05f0892 Mon Sep 17 00:00:00 2001 From: Alexander Indenbaum Date: Tue, 15 Jul 2025 12:38:18 +0300 Subject: [PATCH] librbd: add rbd_aio_write_with_crc32c API for precomputed checksums Signed-off-by: Alexander Indenbaum --- src/include/rbd/librbd.h | 8 ++++++++ src/librbd/librbd.cc | 29 +++++++++++++++++++++++++++++ src/tracing/librbd.tp | 27 +++++++++++++++++++++++++++ 3 files changed, 64 insertions(+) diff --git a/src/include/rbd/librbd.h b/src/include/rbd/librbd.h index b347b03df9e..41f8e86ab20 100644 --- a/src/include/rbd/librbd.h +++ b/src/include/rbd/librbd.h @@ -1279,6 +1279,14 @@ CEPH_RBD_API int rbd_aio_write(rbd_image_t image, uint64_t off, size_t len, CEPH_RBD_API int rbd_aio_write2(rbd_image_t image, uint64_t off, size_t len, const char *buf, rbd_completion_t c, int op_flags); + +/* + * @param precomputed_crc32c: CRC32C checksum that was precomputed (e.g., by SPDK NVMf) + */ +CEPH_RBD_API int rbd_aio_write_with_crc32c(rbd_image_t image, uint64_t off, + size_t len, const char *buf, + uint32_t precomputed_crc32c, + rbd_completion_t c, int op_flags); CEPH_RBD_API int rbd_aio_writev(rbd_image_t image, const struct iovec *iov, int iovcnt, uint64_t off, rbd_completion_t c); CEPH_RBD_API int rbd_aio_read(rbd_image_t image, uint64_t off, size_t len, diff --git a/src/librbd/librbd.cc b/src/librbd/librbd.cc index 01ea33a5bd0..8e43f33394f 100644 --- a/src/librbd/librbd.cc +++ b/src/librbd/librbd.cc @@ -26,6 +26,7 @@ #include "common/errno.h" #include "common/TracepointProvider.h" #include "include/Context.h" +#include "include/buffer_raw.h" #include "cls/rbd/cls_rbd_client.h" #include "cls/rbd/cls_rbd_types.h" @@ -115,6 +116,15 @@ static auto create_write_raw(librbd::ImageCtx *ictx, const char *buf, deleter(new UserBufferDeleter(ictx->cct, aio_completion)))); } +static auto create_write_raw_with_crc32c(librbd::ImageCtx *ictx, const char *buf, + size_t len, uint32_t precomputed_crc32c, + librbd::io::AioCompletion* aio_completion) { + auto raw_buffer = create_write_raw(ictx, buf, len, aio_completion); + raw_buffer->set_crc(std::make_pair(0, len), + std::make_pair(0, precomputed_crc32c)); + return raw_buffer; +} + static int get_iovec_length(const struct iovec *iov, int iovcnt, size_t &len) { len = 0; @@ -6406,6 +6416,25 @@ extern "C" int rbd_aio_write2(rbd_image_t image, uint64_t off, size_t len, return 0; } +extern "C" int rbd_aio_write_with_crc32c(rbd_image_t image, uint64_t off, + size_t len, const char *buf, + uint32_t precomputed_crc32c, + rbd_completion_t c, int op_flags) +{ + librbd::ImageCtx *ictx = (librbd::ImageCtx *)image; + librbd::RBD::AioCompletion *comp = (librbd::RBD::AioCompletion *)c; + tracepoint(librbd, aio_write_with_crc32c_enter, ictx, ictx->name.c_str(), ictx->snap_name.c_str(), + ictx->read_only, off, len, buf, precomputed_crc32c, comp->pc, op_flags); + + auto aio_completion = get_aio_completion(comp); + bufferlist bl; + bl.push_back(create_write_raw_with_crc32c(ictx, buf, len, precomputed_crc32c, aio_completion)); + librbd::api::Io<>::aio_write( + *ictx, aio_completion, off, len, std::move(bl), op_flags, true); + tracepoint(librbd, aio_write_exit, 0); + return 0; +} + extern "C" int rbd_aio_writev(rbd_image_t image, const struct iovec *iov, int iovcnt, uint64_t off, rbd_completion_t c) { diff --git a/src/tracing/librbd.tp b/src/tracing/librbd.tp index 791171e27f5..99eecc60611 100644 --- a/src/tracing/librbd.tp +++ b/src/tracing/librbd.tp @@ -662,6 +662,33 @@ TRACEPOINT_EVENT(librbd, aio_write2_enter, ctf_integer(int, op_flags, op_flags) ) ) + +TRACEPOINT_EVENT(librbd, aio_write_with_crc32c_enter, + TP_ARGS( + void*, imagectx, + const char*, name, + const char*, snap_name, + char, read_only, + uint64_t, off, + size_t, len, + const char*, buf, + uint32_t, precomputed_crc32c, + const void*, completion, + int, op_flags), + TP_FIELDS( + ctf_integer_hex(void*, imagectx, imagectx) + ctf_string(name, name) + ctf_string(snap_name, snap_name) + ctf_integer(char, read_only, read_only) + ctf_integer(uint64_t, off, off) + ctf_integer(size_t, len, len) + ceph_ctf_sequence(unsigned char, buf, buf, size_t, len) + ctf_integer(uint32_t, precomputed_crc32c, precomputed_crc32c) + ctf_integer_hex(const void*, completion, completion) + ctf_integer(int, op_flags, op_flags) + ) +) + TRACEPOINT_EVENT(librbd, aio_write_exit, TP_ARGS( int, retval), -- 2.39.5