From 1e6985b9e0c90e335325539b94c61d5581a04f6b Mon Sep 17 00:00:00 2001 From: Samuel Just Date: Thu, 6 Oct 2022 21:10:57 +0000 Subject: [PATCH] crimson/osd: add CEPH_OSD_OP_LIST_SNAPS Fixes: https://tracker.ceph.com/issues/57789 Signed-off-by: Samuel Just --- src/crimson/osd/ops_executer.cc | 73 +++++++++++++++++++++++++++++++++ src/crimson/osd/ops_executer.h | 19 +++++++++ 2 files changed, 92 insertions(+) diff --git a/src/crimson/osd/ops_executer.cc b/src/crimson/osd/ops_executer.cc index 1685cdf8a29..a032bf19b93 100644 --- a/src/crimson/osd/ops_executer.cc +++ b/src/crimson/osd/ops_executer.cc @@ -484,6 +484,75 @@ OpsExecuter::call_errorator::future<> OpsExecuter::do_assert_ver( return seastar::now(); } +OpsExecuter::list_snaps_iertr::future<> OpsExecuter::do_list_snaps( + OSDOp& osd_op, + const ObjectState& os, + const SnapSet& ss) +{ + obj_list_snap_response_t resp; + resp.clones.reserve(ss.clones.size() + 1); + for (auto &clone: ss.clones) { + clone_info ci; + ci.cloneid = clone; + + { + auto p = ss.clone_snaps.find(clone); + if (p == ss.clone_snaps.end()) { + logger().error( + "OpsExecutor::do_list_snaps: {} has inconsistent " + "clone_overlap, missing clone {}", + os.oi.soid, + clone); + return crimson::ct_error::invarg::make(); + } + ci.snaps.reserve(p->second.size()); + ci.snaps.insert(ci.snaps.end(), p->second.rbegin(), p->second.rend()); + } + + { + auto p = ss.clone_overlap.find(clone); + if (p == ss.clone_overlap.end()) { + logger().error( + "OpsExecutor::do_list_snaps: {} has inconsistent " + "clone_overlap, missing clone {}", + os.oi.soid, + clone); + return crimson::ct_error::invarg::make(); + } + ci.overlap.reserve(p->second.num_intervals()); + ci.overlap.insert(ci.overlap.end(), p->second.begin(), p->second.end()); + } + + { + auto p = ss.clone_size.find(clone); + if (p == ss.clone_size.end()) { + logger().error( + "OpsExecutor::do_list_snaps: {} has inconsistent " + "clone_size, missing clone {}", + os.oi.soid, + clone); + return crimson::ct_error::invarg::make(); + } + ci.size = p->second; + } + resp.clones.push_back(std::move(ci)); + } + + if (!os.oi.is_whiteout()) { + clone_info ci; + ci.cloneid = CEPH_NOSNAP; + ci.size = os.oi.size; + resp.clones.push_back(std::move(ci)); + } + resp.seq = ss.seq; + logger().error( + "OpsExecutor::do_list_snaps: {}, resp.clones.size(): {}", + os.oi.soid, + resp.clones.size()); + resp.encode(osd_op.outdata); + return read_ierrorator::now(); +} + OpsExecuter::interruptible_errorated_future OpsExecuter::execute_op(OSDOp& osd_op) { @@ -706,6 +775,10 @@ OpsExecuter::do_execute_op(OSDOp& osd_op) return do_read_op([this, &osd_op](auto&, const auto& os) { return do_assert_ver(osd_op, os); }); + case CEPH_OSD_OP_LIST_SNAPS: + return do_snapset_op([this, &osd_op](const auto &os, const auto &ss) { + return do_list_snaps(osd_op, os, ss); + }); default: logger().warn("unknown op {}", ceph_osd_op_name(op.op)); diff --git a/src/crimson/osd/ops_executer.h b/src/crimson/osd/ops_executer.h index 7f668ba1979..a9288ccbd3c 100644 --- a/src/crimson/osd/ops_executer.h +++ b/src/crimson/osd/ops_executer.h @@ -225,6 +225,16 @@ private: OSDOp& osd_op, const ObjectState& os); + using list_snaps_ertr = read_errorator::extend< + crimson::ct_error::invarg>; + using list_snaps_iertr = ::crimson::interruptible::interruptible_errorator< + ::crimson::osd::IOInterruptCondition, + list_snaps_ertr>; + list_snaps_iertr::future<> do_list_snaps( + OSDOp& osd_op, + const ObjectState& os, + const SnapSet& ss); + template auto do_const_op(Func&& f); @@ -235,6 +245,15 @@ private: return do_const_op(std::forward(f)); } + template + auto do_snapset_op(Func&& f) { + ++num_read; + return std::invoke( + std::forward(f), + std::as_const(obc->obs), + std::as_const(obc->ssc->snapset)); + } + enum class modified_by { user, sys, -- 2.39.5