From a906ed3298cb4c25a42413a0bca27412bd3c1865 Mon Sep 17 00:00:00 2001 From: Xuehan Xu Date: Wed, 28 Feb 2024 13:42:04 +0800 Subject: [PATCH] crimson/os/seastore: copy attrs and omaps when cloning objects At present, we just copy attrs and omaps one by one, which is not efficient but very important in terms of functionality especially for the teuthology tests Signed-off-by: Xuehan Xu (cherry picked from commit eff9755f80443c33304dcee79750b8da1df9a420) --- src/crimson/os/seastore/seastore.cc | 69 ++++++++++++++++++++++++++++- src/crimson/os/seastore/seastore.h | 10 +++++ 2 files changed, 77 insertions(+), 2 deletions(-) diff --git a/src/crimson/os/seastore/seastore.cc b/src/crimson/os/seastore/seastore.cc index eba19eabebeb..1dcf5a7abab6 100644 --- a/src/crimson/os/seastore/seastore.cc +++ b/src/crimson/os/seastore/seastore.cc @@ -1559,6 +1559,69 @@ SeaStore::Shard::_write( }); } +SeaStore::Shard::tm_ret +SeaStore::Shard::_clone_omaps( + internal_context_t &ctx, + OnodeRef &onode, + OnodeRef &d_onode, + const omap_type_t otype) +{ + return trans_intr::repeat([&ctx, onode, d_onode, this, otype] { + return seastar::do_with( + std::optional(std::nullopt), + [&ctx, onode, d_onode, this, otype](auto &start) { + auto& layout = onode->get_layout(); + return omap_list( + *onode, + otype == omap_type_t::XATTR + ? layout.xattr_root + : layout.omap_root, + *ctx.transaction, + start, + OMapManager::omap_list_config_t().with_inclusive(false, false) + ).si_then([&ctx, onode, d_onode, this, otype, &start](auto p) mutable { + auto complete = std::get<0>(p); + auto &attrs = std::get<1>(p); + if (attrs.empty()) { + assert(complete); + return tm_iertr::make_ready_future< + seastar::stop_iteration>( + seastar::stop_iteration::yes); + } + std::string nstart = attrs.rbegin()->first; + return _omap_set_kvs( + d_onode, + otype == omap_type_t::XATTR + ? d_onode->get_layout().xattr_root + : d_onode->get_layout().omap_root, + *ctx.transaction, + std::map(attrs.begin(), attrs.end()) + ).si_then([complete, nstart=std::move(nstart), + &start, &ctx, d_onode, otype](auto root) mutable { + if (root.must_update()) { + if (otype == omap_type_t::XATTR) { + d_onode->update_xattr_root(*ctx.transaction, root); + } else { + assert(otype == omap_type_t::OMAP); + d_onode->update_omap_root(*ctx.transaction, root); + } + } + if (complete) { + return seastar::make_ready_future< + seastar::stop_iteration>( + seastar::stop_iteration::yes); + } else { + start = std::move(nstart); + return seastar::make_ready_future< + seastar::stop_iteration>( + seastar::stop_iteration::no); + } + }); + }); + }); + }); +} + SeaStore::Shard::tm_ret SeaStore::Shard::_clone( internal_context_t &ctx, @@ -1570,8 +1633,6 @@ SeaStore::Shard::_clone( return seastar::do_with( ObjectDataHandler(max_object_size), [this, &ctx, &onode, &d_onode](auto &objHandler) { - //TODO: currently, we only care about object data, leaving cloning - // of xattr/omap for future work auto &object_size = onode->get_layout().size; d_onode->update_onode_size(*ctx.transaction, object_size); return objHandler.clone( @@ -1580,6 +1641,10 @@ SeaStore::Shard::_clone( *ctx.transaction, *onode, d_onode.get()}); + }).si_then([&ctx, &onode, &d_onode, this] { + return _clone_omaps(ctx, onode, d_onode, omap_type_t::XATTR); + }).si_then([&ctx, &onode, &d_onode, this] { + return _clone_omaps(ctx, onode, d_onode, omap_type_t::OMAP); }); } diff --git a/src/crimson/os/seastore/seastore.h b/src/crimson/os/seastore/seastore.h index bff0092f4533..79a6d7c04c49 100644 --- a/src/crimson/os/seastore/seastore.h +++ b/src/crimson/os/seastore/seastore.h @@ -355,6 +355,16 @@ public: uint64_t offset, size_t len, ceph::bufferlist &&bl, uint32_t fadvise_flags); + enum class omap_type_t : uint8_t { + XATTR = 0, + OMAP, + NUM_TYPES + }; + tm_ret _clone_omaps( + internal_context_t &ctx, + OnodeRef &onode, + OnodeRef &d_onode, + const omap_type_t otype); tm_ret _clone( internal_context_t &ctx, OnodeRef &onode, -- 2.47.3