]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/os/seastore/onode: add the interface for swapping onode layouts
authorXuehan Xu <xuxuehan@qianxin.com>
Sat, 23 Aug 2025 05:31:40 +0000 (13:31 +0800)
committerXuehan Xu <xuxuehan@qianxin.com>
Sun, 28 Sep 2025 06:48:59 +0000 (14:48 +0800)
Signed-off-by: Xuehan Xu <xuxuehan@qianxin.com>
src/crimson/os/seastore/onode.h
src/crimson/os/seastore/onode_manager/staged-fltree/fltree_onode_manager.h
src/test/crimson/seastore/test_object_data_handler.cc

index 470578c044b915817058fddfff6bdc48aef5add9..98369424011f35e740c57fa74a0ce1ab7c00f9be 100644 (file)
@@ -104,6 +104,7 @@ public:
   virtual void clear_snapset(Transaction&) = 0;
   virtual void set_need_cow(Transaction&) = 0;
   virtual void unset_need_cow(Transaction&) = 0;
+  virtual void swap_layout(Transaction&, Onode&) = 0;
 
   laddr_t get_metadata_hint(uint64_t block_size) const {
     assert(default_metadata_offset);
index 8a1e3710648d18c438e61d9be2b57bb9b8d10398..e939dc303762199d31d9e8a156232fdef4add78e 100644 (file)
@@ -93,6 +93,47 @@ struct FLTreeOnode final : Onode, Value {
     layout_func(p.first, p.second);
   }
 
+  void swap_layout(Transaction &t, Onode &onode) final {
+    _swap_layout(t, static_cast<FLTreeOnode&>(onode));
+  }
+
+  void _swap_layout(Transaction &t, FLTreeOnode &other) {
+    assert(status != status_t::DELETED);
+    assert(other.status != status_t::DELETED);
+    auto [payload_mut, recorder] = prepare_mutate_payload<
+      onode_layout_t, Recorder>(t);
+    auto &mlayout = *reinterpret_cast<onode_layout_t*>(
+      payload_mut.get_write());
+    auto [o_payload_mut, o_recorder] = other.prepare_mutate_payload<
+      onode_layout_t, Recorder>(t);
+    auto &o_mlayout = *reinterpret_cast<onode_layout_t*>(
+      o_payload_mut.get_write());
+    std::swap(mlayout.object_data, o_mlayout.object_data);
+    std::swap(mlayout.omap_root, o_mlayout.omap_root);
+    std::swap(mlayout.log_root, o_mlayout.log_root);
+    std::swap(mlayout.xattr_root, o_mlayout.xattr_root);
+    if (recorder) {
+      recorder->encode_update(
+       payload_mut, Recorder::delta_op_t::UPDATE_OBJECT_DATA);
+      recorder->encode_update(
+       payload_mut, Recorder::delta_op_t::UPDATE_OMAP_ROOT);
+      recorder->encode_update(
+       payload_mut, Recorder::delta_op_t::UPDATE_LOG_ROOT);
+      recorder->encode_update(
+       payload_mut, Recorder::delta_op_t::UPDATE_XATTR_ROOT);
+    }
+    if (o_recorder) {
+      o_recorder->encode_update(
+       o_payload_mut, Recorder::delta_op_t::UPDATE_OBJECT_DATA);
+      o_recorder->encode_update(
+       o_payload_mut, Recorder::delta_op_t::UPDATE_OMAP_ROOT);
+      o_recorder->encode_update(
+       o_payload_mut, Recorder::delta_op_t::UPDATE_LOG_ROOT);
+      o_recorder->encode_update(
+       o_payload_mut, Recorder::delta_op_t::UPDATE_XATTR_ROOT);
+    }
+  }
+
   void create_default_layout(Transaction &t) {
     with_mutable_layout(
       t,
index d1f1568e19c1e18fe60787bf8752fb22e86151ac..4e86be5bd708b1e9cccb45c958d0524d7df9a28e 100644 (file)
@@ -36,6 +36,16 @@ public:
   bool is_alive() const final {
     return true;
   }
+  void swap_layout(Transaction &t, Onode& other) final {
+    static_cast<TestOnode&>(other).with_mutable_layout(
+      t,
+      [this](auto &o_mlayout) {
+      std::swap(layout.object_data, o_mlayout.object_data);
+      std::swap(layout.omap_root, o_mlayout.omap_root);
+      std::swap(layout.log_root, o_mlayout.log_root);
+      std::swap(layout.xattr_root, o_mlayout.xattr_root);
+    });
+  }
   laddr_t get_hint() const final {return L_ADDR_MIN; }
   ~TestOnode() final = default;