1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
7 #include <seastar/core/future.hh>
9 #include "crimson/osd/osdmap_gate.h"
10 #include "crimson/osd/osd_operation.h"
11 #include "crimson/osd/osd_operations/common/pg_pipeline.h"
12 #include "crimson/osd/pg.h"
13 #include "crimson/osd/pg_activation_blocker.h"
14 #include "osd/osd_types.h"
15 #include "osd/PGPeeringEvent.h"
16 #include "osd/PeeringState.h"
24 namespace crimson::osd
{
29 // trim up to `max` objects for snapshot `snapid
30 class SnapTrimEvent final
: public PhasedOperationT
<SnapTrimEvent
> {
32 using remove_or_update_ertr
=
33 crimson::errorator
<crimson::ct_error::enoent
>;
34 using remove_or_update_iertr
=
35 crimson::interruptible::interruptible_errorator
<
36 IOInterruptCondition
, remove_or_update_ertr
>;
37 using snap_trim_ertr
= remove_or_update_ertr::extend
<
38 crimson::ct_error::eagain
>;
39 using snap_trim_iertr
= remove_or_update_iertr::extend
<
40 crimson::ct_error::eagain
>;
42 static constexpr OperationTypeCode type
= OperationTypeCode::snaptrim_event
;
44 SnapTrimEvent(Ref
<PG
> pg
,
45 SnapMapper
& snap_mapper
,
46 const snapid_t snapid
,
47 const bool needs_pause
)
49 snap_mapper(snap_mapper
),
51 needs_pause(needs_pause
) {}
53 void print(std::ostream
&) const final
;
54 void dump_detail(ceph::Formatter
* f
) const final
;
55 snap_trim_ertr::future
<seastar::stop_iteration
> start();
56 snap_trim_ertr::future
<seastar::stop_iteration
> with_pg(
57 ShardServices
&shard_services
, Ref
<PG
> pg
);
60 CommonPGPipeline
& client_pp();
62 // bases on 998cb8c141bb89aafae298a9d5e130fbd78fe5f2
63 struct SubOpBlocker
: crimson::BlockerT
<SubOpBlocker
> {
64 static constexpr const char* type_name
= "CompoundOpBlocker";
66 using id_done_t
= std::pair
<crimson::Operation::id_t
,
67 remove_or_update_iertr::future
<>>;
69 void dump_detail(Formatter
*f
) const final
;
71 template <class... Args
>
72 void emplace_back(Args
&&... args
);
74 remove_or_update_iertr::future
<> wait_completion();
76 std::vector
<id_done_t
> subops
;
79 // we don't need to synchronize with other instances of SnapTrimEvent;
80 // it's here for the sake of op tracking.
81 struct WaitSubop
: OrderedConcurrentPhaseT
<WaitSubop
> {
82 static constexpr auto type_name
= "SnapTrimEvent::wait_subop";
85 // an instantiator can instruct us to go over this stage and then
86 // wait for the future to implement throttling. It is implemented
87 // that way to for the sake of tracking ops.
88 struct WaitTrimTimer
: OrderedExclusivePhaseT
<WaitTrimTimer
> {
89 static constexpr auto type_name
= "SnapTrimEvent::wait_trim_timer";
92 PipelineHandle handle
;
94 SnapMapper
& snap_mapper
;
95 const snapid_t snapid
;
96 const bool needs_pause
;
99 PipelineHandle
& get_handle() { return handle
; }
103 CommonPGPipeline::WaitForActive::BlockingEvent
,
104 PGActivationBlocker::BlockingEvent
,
105 CommonPGPipeline::RecoverMissing::BlockingEvent
,
106 CommonPGPipeline::GetOBC::BlockingEvent
,
107 CommonPGPipeline::Process::BlockingEvent
,
108 WaitSubop::BlockingEvent
,
109 PG::SnapTrimMutex::WaitPG::BlockingEvent
,
110 WaitTrimTimer::BlockingEvent
,
114 friend class PG::SnapTrimMutex
;
117 // remove single object. a SnapTrimEvent can create multiple subrequests.
118 // the division of labour is needed because of the restriction that an Op
119 // cannot revisite a pipeline's stage it already saw.
120 class SnapTrimObjSubEvent
: public PhasedOperationT
<SnapTrimObjSubEvent
> {
122 using remove_or_update_ertr
=
123 crimson::errorator
<crimson::ct_error::enoent
>;
124 using remove_or_update_iertr
=
125 crimson::interruptible::interruptible_errorator
<
126 IOInterruptCondition
, remove_or_update_ertr
>;
128 static constexpr OperationTypeCode type
=
129 OperationTypeCode::snaptrimobj_subevent
;
133 const hobject_t
& coid
,
134 snapid_t snap_to_trim
)
137 snap_to_trim(snap_to_trim
) {
140 void print(std::ostream
&) const final
;
141 void dump_detail(ceph::Formatter
* f
) const final
;
142 remove_or_update_iertr::future
<> start();
143 remove_or_update_iertr::future
<> with_pg(
144 ShardServices
&shard_services
, Ref
<PG
> pg
);
146 CommonPGPipeline
& client_pp();
149 object_stat_sum_t delta_stats
;
151 remove_or_update_iertr::future
<> remove_clone(
152 ObjectContextRef obc
,
153 ObjectContextRef head_obc
,
154 ceph::os::Transaction
& txn
,
155 std::vector
<pg_log_entry_t
>& log_entries
);
156 void remove_head_whiteout(
157 ObjectContextRef obc
,
158 ObjectContextRef head_obc
,
159 ceph::os::Transaction
& txn
,
160 std::vector
<pg_log_entry_t
>& log_entries
);
161 interruptible_future
<> adjust_snaps(
162 ObjectContextRef obc
,
163 ObjectContextRef head_obc
,
164 const std::set
<snapid_t
>& new_snaps
,
165 ceph::os::Transaction
& txn
,
166 std::vector
<pg_log_entry_t
>& log_entries
);
168 ObjectContextRef obc
,
169 ObjectContextRef head_obc
,
170 ceph::os::Transaction
& txn
,
171 std::vector
<pg_log_entry_t
>& log_entries
);
173 using remove_or_update_ret_t
=
174 std::pair
<ceph::os::Transaction
, std::vector
<pg_log_entry_t
>>;
175 remove_or_update_iertr::future
<remove_or_update_ret_t
>
176 remove_or_update(ObjectContextRef obc
, ObjectContextRef head_obc
);
178 // we don't need to synchronize with other instances started by
179 // SnapTrimEvent; it's here for the sake of op tracking.
180 struct WaitRepop
: OrderedConcurrentPhaseT
<WaitRepop
> {
181 static constexpr auto type_name
= "SnapTrimObjSubEvent::wait_repop";
185 PipelineHandle handle
;
186 osd_op_params_t osd_op_p
;
187 const hobject_t coid
;
188 const snapid_t snap_to_trim
;
191 PipelineHandle
& get_handle() { return handle
; }
195 CommonPGPipeline::WaitForActive::BlockingEvent
,
196 PGActivationBlocker::BlockingEvent
,
197 CommonPGPipeline::RecoverMissing::BlockingEvent
,
198 CommonPGPipeline::GetOBC::BlockingEvent
,
199 CommonPGPipeline::Process::BlockingEvent
,
200 WaitRepop::BlockingEvent
,
205 } // namespace crimson::osd
207 #if FMT_VERSION >= 90000
208 template <> struct fmt::formatter
<crimson::osd::SnapTrimEvent
> : fmt::ostream_formatter
{};
209 template <> struct fmt::formatter
<crimson::osd::SnapTrimObjSubEvent
> : fmt::ostream_formatter
{};