]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/os/seastore: copy attrs and omaps when cloning objects 55806/head
authorXuehan Xu <xuxuehan@qianxin.com>
Wed, 28 Feb 2024 05:42:04 +0000 (13:42 +0800)
committerXuehan Xu <xuxuehan@qianxin.com>
Wed, 28 Feb 2024 08:59:26 +0000 (16:59 +0800)
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 <xuxuehan@qianxin.com>
src/crimson/os/seastore/seastore.cc
src/crimson/os/seastore/seastore.h

index a2ccd3bd17709f091a87849ae10d325e2853bfa2..d3a84fc49758b8ade96719b63ebde6a43a9c186b 100644 (file)
@@ -1584,6 +1584,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::string>(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<std::string, ceph::bufferlist>(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,
@@ -1595,8 +1658,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(
@@ -1605,6 +1666,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);
   });
 }
 
index 79f0bb82e12c7e280b07a3808896a934e6070d7e..3f9ec175c9054d71de438065837821a5203c7376 100644 (file)
@@ -359,6 +359,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,