From: Xuehan Xu Date: Wed, 27 Sep 2023 09:13:44 +0000 (+0800) Subject: crimson/os/seastore/onode_manager: populate delta recorders for each X-Git-Tag: v19.0.0~286^2~3 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=bfd12365979a702bd0575acbd3d2b3eb5f103ec2;p=ceph.git crimson/os/seastore/onode_manager: populate delta recorders for each onode modification Signed-off-by: Xuehan Xu --- diff --git a/src/crimson/os/seastore/object_data_handler.cc b/src/crimson/os/seastore/object_data_handler.cc index 0d852696b714..025f91993efa 100644 --- a/src/crimson/os/seastore/object_data_handler.cc +++ b/src/crimson/os/seastore/object_data_handler.cc @@ -888,7 +888,7 @@ auto with_object_data( return std::invoke(f, object_data ).si_then([ctx, &object_data] { if (object_data.must_update()) { - ctx.onode.get_mutable_layout(ctx.t).object_data.update(object_data); + ctx.onode.update_object_data(ctx.t, object_data); } return seastar::now(); }); @@ -909,11 +909,10 @@ auto with_objects_data( return std::invoke(f, object_data, d_object_data ).si_then([ctx, &object_data, &d_object_data] { if (object_data.must_update()) { - ctx.onode.get_mutable_layout(ctx.t).object_data.update(object_data); + ctx.onode.update_object_data(ctx.t, object_data); } if (d_object_data.must_update()) { - ctx.d_onode->get_mutable_layout( - ctx.t).object_data.update(d_object_data); + ctx.d_onode->update_object_data(ctx.t, d_object_data); } return seastar::now(); }); diff --git a/src/crimson/os/seastore/onode.h b/src/crimson/os/seastore/onode.h index 069daa3df5b5..e803a2e4e74f 100644 --- a/src/crimson/os/seastore/onode.h +++ b/src/crimson/os/seastore/onode.h @@ -64,9 +64,17 @@ public: virtual bool is_alive() const = 0; virtual const onode_layout_t &get_layout() const = 0; - virtual onode_layout_t &get_mutable_layout(Transaction &t) = 0; virtual ~Onode() = default; + virtual void update_onode_size(Transaction&, uint32_t) = 0; + virtual void update_omap_root(Transaction&, omap_root_t&) = 0; + virtual void update_xattr_root(Transaction&, omap_root_t&) = 0; + virtual void update_object_data(Transaction&, object_data_t&) = 0; + virtual void update_object_info(Transaction&, ceph::bufferlist&) = 0; + virtual void update_snapset(Transaction&, ceph::bufferlist&) = 0; + virtual void clear_object_info(Transaction&) = 0; + virtual void clear_snapset(Transaction&) = 0; + laddr_t get_metadata_hint(uint64_t block_size) const { assert(default_metadata_offset); assert(default_metadata_range); 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 bff27ab65178..a1f593889d52 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 @@ -51,17 +51,17 @@ FLTreeOnodeManager::get_or_create_onode( ).si_then([this, &trans, &hoid, FNAME](auto p) -> get_or_create_onode_ret { auto [cursor, created] = std::move(p); - auto val = OnodeRef(new FLTreeOnode( + auto onode = new FLTreeOnode( default_data_reservation, default_metadata_range, - cursor.value())); + cursor.value()); if (created) { DEBUGT("created onode for entry for {}", trans, hoid); - val->get_mutable_layout(trans) = onode_layout_t{}; + onode->with_mutable_layout(trans, [](onode_layout_t &mlayout) { + mlayout = onode_layout_t{}; + }); } - return get_or_create_onode_iertr::make_ready_future( - val - ); + return get_or_create_onode_iertr::make_ready_future(onode); }); } 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 09998fbfaea9..619609419ad8 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 @@ -78,14 +78,16 @@ struct FLTreeOnode final : Onode, Value { return *read_payload(); } - onode_layout_t &get_mutable_layout(Transaction &t) final { + template + void with_mutable_layout(Transaction &t, Func&& f) { assert(status != status_t::DELETED); auto p = prepare_mutate_payload< onode_layout_t, Recorder>(t); status = status_t::MUTATED; - return *reinterpret_cast(p.first.get_write()); - }; + f(*reinterpret_cast(p.first.get_write())); + populate_recorder(t); + } void populate_recorder(Transaction &t) { assert(status == status_t::MUTATED); @@ -99,6 +101,66 @@ struct FLTreeOnode final : Onode, Value { status = status_t::STABLE; } + void update_onode_size(Transaction &t, uint32_t size) final { + with_mutable_layout(t, [size](onode_layout_t &mlayout) { + mlayout.size = size; + }); + } + + void update_omap_root(Transaction &t, omap_root_t &oroot) final { + with_mutable_layout(t, [&oroot](onode_layout_t &mlayout) { + mlayout.omap_root.update(oroot); + }); + } + + void update_xattr_root(Transaction &t, omap_root_t &xroot) final { + with_mutable_layout(t, [&xroot](onode_layout_t &mlayout) { + mlayout.xattr_root.update(xroot); + }); + } + + void update_object_data(Transaction &t, object_data_t &odata) final { + with_mutable_layout(t, [&odata](onode_layout_t &mlayout) { + mlayout.object_data.update(odata); + }); + } + + void update_object_info(Transaction &t, ceph::bufferlist &oi_bl) final { + with_mutable_layout(t, [&oi_bl](onode_layout_t &mlayout) { + maybe_inline_memcpy( + &mlayout.oi[0], + oi_bl.c_str(), + oi_bl.length(), + onode_layout_t::MAX_OI_LENGTH); + mlayout.oi_size = oi_bl.length(); + }); + } + + void clear_object_info(Transaction &t) final { + with_mutable_layout(t, [](onode_layout_t &mlayout) { + memset(&mlayout.oi[0], 0, mlayout.oi_size); + mlayout.oi_size = 0; + }); + } + + void update_snapset(Transaction &t, ceph::bufferlist &ss_bl) final { + with_mutable_layout(t, [&ss_bl](onode_layout_t &mlayout) { + maybe_inline_memcpy( + &mlayout.ss[0], + ss_bl.c_str(), + ss_bl.length(), + onode_layout_t::MAX_OI_LENGTH); + mlayout.ss_size = ss_bl.length(); + }); + } + + void clear_snapset(Transaction &t) final { + with_mutable_layout(t, [](onode_layout_t &mlayout) { + memset(&mlayout.ss[0], 0, mlayout.ss_size); + mlayout.ss_size = 0; + }); + } + void mark_delete() { assert(status != status_t::DELETED); status = status_t::DELETED; diff --git a/src/crimson/os/seastore/seastore.cc b/src/crimson/os/seastore/seastore.cc index 897a063e0fe6..edbc9a0115ec 100644 --- a/src/crimson/os/seastore/seastore.cc +++ b/src/crimson/os/seastore/seastore.cc @@ -1529,10 +1529,10 @@ SeaStore::Shard::_write( LOG_PREFIX(SeaStore::_write); DEBUGT("onode={} {}~{}", *ctx.transaction, *onode, offset, len); { - auto &object_size = onode->get_mutable_layout(*ctx.transaction).size; - object_size = std::max( - offset + len, - object_size); + const auto &object_size = onode->get_layout().size; + onode->update_onode_size( + *ctx.transaction, + std::max(offset + len, object_size)); } return seastar::do_with( std::move(_bl), @@ -1563,8 +1563,7 @@ SeaStore::Shard::_clone( //TODO: currently, we only care about object data, leaving cloning // of xattr/omap for future work auto &object_size = onode->get_layout().size; - auto &d_object_size = d_onode->get_mutable_layout(*ctx.transaction).size; - d_object_size = object_size; + d_onode->update_onode_size(*ctx.transaction, object_size); return objHandler.clone( ObjectDataHandler::context_t{ *transaction_manager, @@ -1586,8 +1585,10 @@ SeaStore::Shard::_zero( if (offset + len >= max_object_size) { return crimson::ct_error::input_output_error::make(); } - auto &object_size = onode->get_mutable_layout(*ctx.transaction).size; - object_size = std::max(offset + len, object_size); + const auto &object_size = onode->get_layout().size; + onode->update_onode_size( + *ctx.transaction, + std::max(offset + len, object_size)); return seastar::do_with( ObjectDataHandler(max_object_size), [=, this, &ctx, &onode](auto &objhandler) { @@ -1607,7 +1608,6 @@ SeaStore::Shard::_omap_set_kvs( OnodeRef &onode, const omap_root_le_t& omap_root, Transaction& t, - omap_root_le_t& mutable_omap_root, std::map&& kvs) { return seastar::do_with( @@ -1627,10 +1627,6 @@ SeaStore::Shard::_omap_set_kvs( return omap_manager.omap_set_keys(root, t, std::move(keys)); }).si_then([&] { return tm_iertr::make_ready_future(std::move(root)); - }).si_then([&mutable_omap_root](auto root) { - if (root.must_update()) { - mutable_omap_root.update(root); - } }); } ); @@ -1648,8 +1644,12 @@ SeaStore::Shard::_omap_set_values( onode, onode->get_layout().omap_root, *ctx.transaction, - onode->get_mutable_layout(*ctx.transaction).omap_root, - std::move(aset)); + std::move(aset) + ).si_then([onode, &ctx](auto root) { + if (root.must_update()) { + onode->update_omap_root(*ctx.transaction, root); + } + }); } SeaStore::Shard::tm_ret @@ -1691,8 +1691,7 @@ SeaStore::Shard::_omap_clear( *ctx.transaction) .si_then([&] { if (omap_root.must_update()) { - onode->get_mutable_layout(*ctx.transaction - ).omap_root.update(omap_root); + onode->update_omap_root(*ctx.transaction, omap_root); } }); }); @@ -1733,8 +1732,7 @@ SeaStore::Shard::_omap_rmkeys( } ).si_then([&] { if (omap_root.must_update()) { - onode->get_mutable_layout(*ctx.transaction - ).omap_root.update(omap_root); + onode->update_omap_root(*ctx.transaction, omap_root); } }); } @@ -1782,8 +1780,7 @@ SeaStore::Shard::_omap_rmkeyrange( config ).si_then([&] { if (omap_root.must_update()) { - onode->get_mutable_layout(*ctx.transaction - ).omap_root.update(omap_root); + onode->update_omap_root(*ctx.transaction, omap_root); } }); }); @@ -1798,7 +1795,7 @@ SeaStore::Shard::_truncate( { LOG_PREFIX(SeaStore::_truncate); DEBUGT("onode={} size={}", *ctx.transaction, *onode, size); - onode->get_mutable_layout(*ctx.transaction).size = size; + onode->update_onode_size(*ctx.transaction, size); return seastar::do_with( ObjectDataHandler(max_object_size), [=, this, &ctx, &onode](auto &objhandler) { @@ -1822,45 +1819,34 @@ SeaStore::Shard::_setattrs( DEBUGT("onode={}", *ctx.transaction, *onode); auto fut = tm_iertr::now(); - auto& layout = onode->get_mutable_layout(*ctx.transaction); + auto& layout = onode->get_layout(); if (auto it = aset.find(OI_ATTR); it != aset.end()) { auto& val = it->second; if (likely(val.length() <= onode_layout_t::MAX_OI_LENGTH)) { - maybe_inline_memcpy( - &layout.oi[0], - val.c_str(), - val.length(), - onode_layout_t::MAX_OI_LENGTH); if (!layout.oi_size) { // if oi was not in the layout, it probably exists in the omap, // need to remove it first fut = _xattr_rmattr(ctx, onode, OI_ATTR); } - layout.oi_size = val.length(); + onode->update_object_info(*ctx.transaction, val); aset.erase(it); } else { - layout.oi_size = 0; + onode->clear_object_info(*ctx.transaction); } } if (auto it = aset.find(SS_ATTR); it != aset.end()) { auto& val = it->second; if (likely(val.length() <= onode_layout_t::MAX_SS_LENGTH)) { - maybe_inline_memcpy( - &layout.ss[0], - val.c_str(), - val.length(), - onode_layout_t::MAX_SS_LENGTH); if (!layout.ss_size) { fut = _xattr_rmattr(ctx, onode, SS_ATTR); } - layout.ss_size = val.length(); - + onode->update_snapset(*ctx.transaction, val); aset.erase(it); } else { - layout.ss_size = 0; + onode->clear_snapset(*ctx.transaction); } } @@ -1869,14 +1855,17 @@ SeaStore::Shard::_setattrs( } return fut.si_then( - [this, onode, &ctx, &layout, - aset=std::move(aset)]() mutable { + [this, onode, &ctx, aset=std::move(aset)]() mutable { return _omap_set_kvs( onode, onode->get_layout().xattr_root, *ctx.transaction, - layout.xattr_root, - std::move(aset)); + std::move(aset) + ).si_then([onode, &ctx](auto root) { + if (root.must_update()) { + onode->update_xattr_root(*ctx.transaction, root); + } + }); }); } @@ -1888,14 +1877,12 @@ SeaStore::Shard::_rmattr( { LOG_PREFIX(SeaStore::_rmattr); DEBUGT("onode={}", *ctx.transaction, *onode); - auto& layout = onode->get_mutable_layout(*ctx.transaction); + auto& layout = onode->get_layout(); if ((name == OI_ATTR) && (layout.oi_size > 0)) { - memset(&layout.oi[0], 0, layout.oi_size); - layout.oi_size = 0; + onode->clear_object_info(*ctx.transaction); return tm_iertr::now(); } else if ((name == SS_ATTR) && (layout.ss_size > 0)) { - memset(&layout.ss[0], 0, layout.ss_size); - layout.ss_size = 0; + onode->clear_snapset(*ctx.transaction); return tm_iertr::now(); } else { return _xattr_rmattr( @@ -1927,8 +1914,7 @@ SeaStore::Shard::_xattr_rmattr( return omap_manager.omap_rm_key(xattr_root, *ctx.transaction, name) .si_then([&] { if (xattr_root.must_update()) { - onode->get_mutable_layout(*ctx.transaction - ).xattr_root.update(xattr_root); + onode->update_xattr_root(*ctx.transaction, xattr_root); } }); }); @@ -1942,11 +1928,8 @@ SeaStore::Shard::_rmattrs( { LOG_PREFIX(SeaStore::_rmattrs); DEBUGT("onode={}", *ctx.transaction, *onode); - auto& layout = onode->get_mutable_layout(*ctx.transaction); - memset(&layout.oi[0], 0, layout.oi_size); - layout.oi_size = 0; - memset(&layout.ss[0], 0, layout.ss_size); - layout.ss_size = 0; + onode->clear_object_info(*ctx.transaction); + onode->clear_snapset(*ctx.transaction); return _xattr_clear(ctx, onode); } @@ -1970,8 +1953,7 @@ SeaStore::Shard::_xattr_clear( return omap_manager.omap_clear(xattr_root, *ctx.transaction) .si_then([&] { if (xattr_root.must_update()) { - onode->get_mutable_layout(*ctx.transaction - ).xattr_root.update(xattr_root); + onode->update_xattr_root(*ctx.transaction, xattr_root); } }); }); diff --git a/src/crimson/os/seastore/seastore.h b/src/crimson/os/seastore/seastore.h index 876fadca8c78..def40a282208 100644 --- a/src/crimson/os/seastore/seastore.h +++ b/src/crimson/os/seastore/seastore.h @@ -408,12 +408,11 @@ public: tm_ret _remove_collection( internal_context_t &ctx, const coll_t& cid); - using omap_set_kvs_ret = tm_iertr::future<>; + using omap_set_kvs_ret = tm_iertr::future; omap_set_kvs_ret _omap_set_kvs( OnodeRef &onode, const omap_root_le_t& omap_root, Transaction& t, - omap_root_le_t& mutable_omap_root, std::map&& kvs); boost::intrusive_ptr _get_collection(const coll_t& cid); diff --git a/src/test/crimson/seastore/onode_tree/test_fltree_onode_manager.cc b/src/test/crimson/seastore/onode_tree/test_fltree_onode_manager.cc index 17ad975d5e87..3d98dcf5aef2 100644 --- a/src/test/crimson/seastore/onode_tree/test_fltree_onode_manager.cc +++ b/src/test/crimson/seastore/onode_tree/test_fltree_onode_manager.cc @@ -30,10 +30,12 @@ struct onode_item_t { uint32_t cnt_modify = 0; void initialize(Transaction& t, Onode& value) const { - auto& layout = value.get_mutable_layout(t); - layout.size = size; - layout.omap_root.update(omap_root_t(id, cnt_modify, - value.get_metadata_hint(block_size))); + auto &ftvalue = static_cast(value); + ftvalue.with_mutable_layout(t, [this, &value](auto &mlayout) { + mlayout.size = size; + mlayout.omap_root.update(omap_root_t(id, cnt_modify, + value.get_metadata_hint(block_size))); + }); validate(value); } diff --git a/src/test/crimson/seastore/test_object_data_handler.cc b/src/test/crimson/seastore/test_object_data_handler.cc index 6510cb5d93fe..47607643946e 100644 --- a/src/test/crimson/seastore/test_object_data_handler.cc +++ b/src/test/crimson/seastore/test_object_data_handler.cc @@ -30,9 +30,9 @@ public: const onode_layout_t &get_layout() const final { return layout; } - onode_layout_t &get_mutable_layout(Transaction &t) final { - dirty = true; - return layout; + template + void with_mutable_layout(Transaction &t, Func&& f) { + f(layout); } bool is_alive() const { return true; @@ -40,6 +40,67 @@ public: bool is_dirty() const { return dirty; } laddr_t get_hint() const final {return L_ADDR_MIN; } ~TestOnode() final = default; + + void update_onode_size(Transaction &t, uint32_t size) final { + with_mutable_layout(t, [size](onode_layout_t &mlayout) { + mlayout.size = size; + }); + } + + void update_omap_root(Transaction &t, omap_root_t &oroot) final { + with_mutable_layout(t, [&oroot](onode_layout_t &mlayout) { + mlayout.omap_root.update(oroot); + }); + } + + void update_xattr_root(Transaction &t, omap_root_t &xroot) final { + with_mutable_layout(t, [&xroot](onode_layout_t &mlayout) { + mlayout.xattr_root.update(xroot); + }); + } + + void update_object_data(Transaction &t, object_data_t &odata) final { + with_mutable_layout(t, [&odata](onode_layout_t &mlayout) { + mlayout.object_data.update(odata); + }); + } + + void update_object_info(Transaction &t, ceph::bufferlist &oi_bl) final { + with_mutable_layout(t, [&oi_bl](onode_layout_t &mlayout) { + maybe_inline_memcpy( + &mlayout.oi[0], + oi_bl.c_str(), + oi_bl.length(), + onode_layout_t::MAX_OI_LENGTH); + mlayout.oi_size = oi_bl.length(); + }); + } + + void clear_object_info(Transaction &t) final { + with_mutable_layout(t, [](onode_layout_t &mlayout) { + memset(&mlayout.oi[0], 0, mlayout.oi_size); + mlayout.oi_size = 0; + }); + } + + void update_snapset(Transaction &t, ceph::bufferlist &ss_bl) final { + with_mutable_layout(t, [&ss_bl](onode_layout_t &mlayout) { + maybe_inline_memcpy( + &mlayout.ss[0], + ss_bl.c_str(), + ss_bl.length(), + onode_layout_t::MAX_OI_LENGTH); + mlayout.ss_size = ss_bl.length(); + }); + } + + void clear_snapset(Transaction &t) final { + with_mutable_layout(t, [](onode_layout_t &mlayout) { + memset(&mlayout.ss[0], 0, mlayout.ss_size); + mlayout.ss_size = 0; + }); + } + }; struct object_data_handler_test_t: