From 3e5c64a92d84d984a194a62bb260f1c8ce5ffe1b Mon Sep 17 00:00:00 2001 From: Radoslaw Zarzynski Date: Fri, 25 Nov 2022 22:48:04 +0000 Subject: [PATCH] crimson/osd: wire SnapMapper::add_oid() with OpsExecuter Signed-off-by: Radoslaw Zarzynski --- src/crimson/osd/ops_executer.cc | 97 +++++++++++++++++++++++++++++++++ src/crimson/osd/ops_executer.h | 53 ++++++++++++++++-- 2 files changed, 144 insertions(+), 6 deletions(-) diff --git a/src/crimson/osd/ops_executer.cc b/src/crimson/osd/ops_executer.cc index dbccb8dcdf49e..544328f4df72f 100644 --- a/src/crimson/osd/ops_executer.cc +++ b/src/crimson/osd/ops_executer.cc @@ -19,6 +19,7 @@ #include "crimson/osd/pg.h" #include "crimson/osd/watch.h" #include "osd/ClassHandler.h" +#include "osd/SnapMapper.h" namespace { seastar::logger& logger() { @@ -827,6 +828,102 @@ std::vector OpsExecuter::prepare_transaction( return log_entries; } +void OpsExecuter::snap_map_remove( + const hobject_t& soid, + SnapMapper& snap_mapper, + SnapMapperTransaction& txn) +{ + logger().debug("{}: soid {}", __func__, soid); + const auto r = snap_mapper.remove_oid(soid, &txn); + if (r) { + logger().error("{}: remove_oid {} failed with {}", + __func__, soid, r); + } + // On removal tolerate missing key corruption + assert(r == 0 || r == -ENOENT); +} + +void OpsExecuter::snap_map_modify( + const hobject_t& soid, + const std::set& snaps, + SnapMapper& snap_mapper, + SnapMapperTransaction& txn) +{ + logger().debug("{}: soid {}, snaps {}", __func__, soid, snaps); + assert(std::size(snaps) > 0); + [[maybe_unused]] const auto r = snap_mapper.update_snaps( + soid, snaps, 0, &txn); + assert(r == 0); +} + +void OpsExecuter::snap_map_clone( + const hobject_t& soid, + const std::set& snaps, + SnapMapper& snap_mapper, + SnapMapperTransaction& txn) +{ + logger().debug("{}: soid {}, snaps {}", __func__, soid, snaps); + assert(std::size(snaps) > 0); + snap_mapper.add_oid(soid, snaps, &txn); +} + +OpsExecuter::interruptible_future<> OpsExecuter::flush_snap_map( + const std::vector& log_entries, + SnapMapper& snap_mapper, + OSDriver& osdriver, + ceph::os::Transaction& txn) +{ + logger().debug("{} log_entries.size()={}", + __func__, std::size(log_entries)); + for (const auto& le : log_entries) { + if (le.soid.snap >= CEPH_MAXSNAP) { + logger().debug("{} {} >= CEPH_MAXSNAP", + __func__, le.soid); + continue; + } + return interruptor::async([_t=osdriver.get_transaction(&txn), + &le, &snap_mapper]() mutable { + if (le.is_delete()) { + logger().debug("flush_snap_map: is_delete()"); + snap_mapper.remove_oid( + le.soid, + &_t); + } else if (le.is_update()) { + assert(le.snaps.length() > 0); + std::vector snaps; + ceph::bufferlist snapbl = le.snaps; + auto p = snapbl.cbegin(); + try { + decode(snaps, p); + } catch (...) { + logger().error("flush_snap_map: decode snaps failure on {}", le); + snaps.clear(); + } + std::set _snaps(snaps.begin(), snaps.end()); + if (le.is_clone() || le.is_promote()) { + logger().debug("flush_snap_map: le.is_clone() || le.is_promote()"); + snap_mapper.add_oid( + le.soid, + _snaps, + &_t); + } else if (le.is_modify()) { + logger().debug("flush_snap_map: is_modify()"); + int r = snap_mapper.update_snaps( + le.soid, + _snaps, + 0, + &_t); + assert(r == 0); + } else { + assert(le.is_clean()); + logger().debug("flush_snap_map: is_clean()"); + } + } + }); + } + return seastar::now(); +} + // Defined here because there is a circular dependency between OpsExecuter and PG uint32_t OpsExecuter::get_pool_stripe_width() const { return pg->get_pgpool().info.get_stripe_width(); diff --git a/src/crimson/osd/ops_executer.h b/src/crimson/osd/ops_executer.h index 3167b142649b9..14fd5a9c2d310 100644 --- a/src/crimson/osd/ops_executer.h +++ b/src/crimson/osd/ops_executer.h @@ -15,6 +15,7 @@ #include #include "common/dout.h" +#include "common/map_cacher.hpp" #include "common/static_ptr.h" #include "messages/MOSDOp.h" #include "os/Transaction.h" @@ -31,6 +32,10 @@ struct ObjectState; struct OSDOp; +class OSDriver; +class SnapMapper; +using SnapMapperTransaction = + MapCacher::Transaction; namespace crimson::osd { class PG; @@ -245,6 +250,27 @@ private: void flush_clone_metadata( std::vector& log_entries); + interruptible_future<> flush_snap_map( + const std::vector& log_entries, + SnapMapper& snap_mapper, + OSDriver& osdriver, + ceph::os::Transaction& txn); + + static void snap_map_remove( + const hobject_t& soid, + SnapMapper& snap_mapper, + SnapMapperTransaction& txn); + static void snap_map_modify( + const hobject_t& soid, + const std::set& snaps, + SnapMapper& snap_mapper, + SnapMapperTransaction& txn); + static void snap_map_clone( + const hobject_t& soid, + const std::set& snaps, + SnapMapper& snap_mapper, + SnapMapperTransaction& txn); + // this gizmo could be wrapped in std::optional for the sake of lazy // initialization. we don't need it for ops that doesn't have effect // TODO: verify the init overhead of chunked_fifo @@ -371,7 +397,10 @@ public: using rep_op_fut_t = interruptible_future; template - rep_op_fut_t flush_changes_n_do_ops_effects(const std::vector& ops, + rep_op_fut_t flush_changes_n_do_ops_effects( + const std::vector& ops, + SnapMapper& snap_mapper, + OSDriver& osdriver, MutFunc&& mut_func) &&; std::vector prepare_transaction( const std::vector& ops); @@ -455,6 +484,8 @@ template OpsExecuter::rep_op_fut_t OpsExecuter::flush_changes_n_do_ops_effects( const std::vector& ops, + SnapMapper& snap_mapper, + OSDriver& osdriver, MutFunc&& mut_func) && { const bool want_mutate = !txn.empty(); @@ -474,13 +505,23 @@ OpsExecuter::flush_changes_n_do_ops_effects( } auto log_entries = prepare_transaction(ops); flush_clone_metadata(log_entries); - auto [submitted, all_completed] = std::forward(mut_func)(std::move(txn), - std::move(obc), - std::move(*osd_op_params), - std::move(log_entries)); - maybe_mutated = interruptor::make_ready_future( + auto maybe_snap_mapped = flush_snap_map(std::as_const(log_entries), + snap_mapper, + osdriver, + txn); + apply_stats(); + maybe_mutated = maybe_snap_mapped.then_interruptible([mut_func=std::move(mut_func), + log_entries=std::move(log_entries), + this]() mutable { + auto [submitted, all_completed] = + std::forward(mut_func)(std::move(txn), + std::move(obc), + std::move(*osd_op_params), + std::move(log_entries)); + return interruptor::make_ready_future( std::move(submitted), osd_op_ierrorator::future<>(std::move(all_completed))); + }); } apply_stats(); -- 2.39.5