From: Xuehan Xu Date: Tue, 12 Aug 2025 06:51:15 +0000 (+0800) Subject: crimson/os/seastore/onode: add the "need_cow" field to indicate whether X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=07b740728e1e1b5b5553a04827c72bf483ef878a;p=ceph-ci.git crimson/os/seastore/onode: add the "need_cow" field to indicate whether the onode's object data space needs to do clone before modification At present, it's only when the onode's object data space is sharing its own direct lba mappings with other onodes that the "need_cow" field would be true. Signed-off-by: Xuehan Xu --- diff --git a/src/crimson/os/seastore/onode.h b/src/crimson/os/seastore/onode.h index 71326c89167..470578c044b 100644 --- a/src/crimson/os/seastore/onode.h +++ b/src/crimson/os/seastore/onode.h @@ -40,6 +40,14 @@ struct onode_layout_t { char oi[MAX_OI_LENGTH] = {0}; char ss[MAX_SS_LENGTH] = {0}; + /** + * needs_cow + * + * If true, all lba mappings for onode must be cloned + * to a new range prior to mutation. See ObjectDataHandler::copy_on_write, + * do_clone, do_clonerange + */ + bool need_cow = false; onode_layout_t() : omap_root(omap_type_t::OMAP), log_root(omap_type_t::LOG), xattr_root(omap_type_t::XATTR) {} @@ -94,6 +102,8 @@ public: virtual void update_snapset(Transaction&, ceph::bufferlist&) = 0; virtual void clear_object_info(Transaction&) = 0; virtual void clear_snapset(Transaction&) = 0; + virtual void set_need_cow(Transaction&) = 0; + virtual void unset_need_cow(Transaction&) = 0; laddr_t get_metadata_hint(uint64_t block_size) const { assert(default_metadata_offset); diff --git a/src/crimson/os/seastore/onode_manager/staged-fltree/fltree_onode_manager.cc b/src/crimson/os/seastore/onode_manager/staged-fltree/fltree_onode_manager.cc index e675bf346f1..1f0ffcb0c6d 100644 --- a/src/crimson/os/seastore/onode_manager/staged-fltree/fltree_onode_manager.cc +++ b/src/crimson/os/seastore/onode_manager/staged-fltree/fltree_onode_manager.cc @@ -20,6 +20,18 @@ void FLTreeOnode::Recorder::apply_value_delta( ceph::decode(op, bliter); auto &mlayout = *reinterpret_cast(value.get_write()); switch (op) { + case delta_op_t::UNSET_NEED_COW: + DEBUG("setting need_cow"); + bliter.copy( + sizeof(mlayout.need_cow), + (char *)&mlayout.need_cow); + break; + case delta_op_t::SET_NEED_COW: + DEBUG("setting need_cow"); + bliter.copy( + sizeof(mlayout.need_cow), + (char *)&mlayout.need_cow); + break; case delta_op_t::UPDATE_ONODE_SIZE: DEBUG("update onode size"); bliter.copy(sizeof(mlayout.size), (char *)&mlayout.size); @@ -80,6 +92,18 @@ void FLTreeOnode::Recorder::encode_update( auto &encoded = get_encoded(payload_mut); ceph::encode(op, encoded); switch(op) { + case delta_op_t::UNSET_NEED_COW: + DEBUG("setting need_cow"); + encoded.append( + (const char *)&layout.need_cow, + sizeof(layout.need_cow)); + break; + case delta_op_t::SET_NEED_COW: + DEBUG("setting need_cow"); + encoded.append( + (const char *)&layout.need_cow, + sizeof(layout.need_cow)); + break; case delta_op_t::UPDATE_ONODE_SIZE: DEBUG("update onode size"); encoded.append( diff --git a/src/crimson/os/seastore/onode_manager/staged-fltree/fltree_onode_manager.h b/src/crimson/os/seastore/onode_manager/staged-fltree/fltree_onode_manager.h index 06a0809d932..8a1e3710648 100644 --- a/src/crimson/os/seastore/onode_manager/staged-fltree/fltree_onode_manager.h +++ b/src/crimson/os/seastore/onode_manager/staged-fltree/fltree_onode_manager.h @@ -56,7 +56,9 @@ struct FLTreeOnode final : Onode, Value { UPDATE_SNAPSET, CLEAR_OBJECT_INFO, CLEAR_SNAPSET, - CREATE_DEFAULT + CREATE_DEFAULT, + SET_NEED_COW, + UNSET_NEED_COW }; Recorder(bufferlist &bl) : ValueDeltaRecorder(bl) {} @@ -105,6 +107,34 @@ struct FLTreeOnode final : Onode, Value { }); } + void set_need_cow(Transaction &t) final { + with_mutable_layout( + t, + [](NodeExtentMutable &payload_mut, Recorder *recorder) { + auto &mlayout = *reinterpret_cast( + payload_mut.get_write()); + mlayout.need_cow = true; + if (recorder) { + recorder->encode_update( + payload_mut, Recorder::delta_op_t::SET_NEED_COW); + } + }); + } + + void unset_need_cow(Transaction &t) final { + with_mutable_layout( + t, + [](NodeExtentMutable &payload_mut, Recorder *recorder) { + auto &mlayout = *reinterpret_cast( + payload_mut.get_write()); + mlayout.need_cow = false; + if (recorder) { + recorder->encode_update( + payload_mut, Recorder::delta_op_t::UNSET_NEED_COW); + } + }); + } + void update_onode_size(Transaction &t, uint32_t size) final { with_mutable_layout( t, diff --git a/src/test/crimson/seastore/test_object_data_handler.cc b/src/test/crimson/seastore/test_object_data_handler.cc index fd6d2a00118..d1f1568e19c 100644 --- a/src/test/crimson/seastore/test_object_data_handler.cc +++ b/src/test/crimson/seastore/test_object_data_handler.cc @@ -39,6 +39,18 @@ public: laddr_t get_hint() const final {return L_ADDR_MIN; } ~TestOnode() final = default; + void set_need_cow(Transaction &t) final { + with_mutable_layout(t, [](onode_layout_t &mlayout) { + mlayout.need_cow = true; + }); + } + + void unset_need_cow(Transaction &t) final { + with_mutable_layout(t, [](onode_layout_t &mlayout) { + mlayout.need_cow = false; + }); + } + void update_onode_size(Transaction &t, uint32_t size) final { with_mutable_layout(t, [size](onode_layout_t &mlayout) { mlayout.size = size;