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
{
30 // trim up to `max` objects for snapshot `snapid
31 class SnapTrimEvent final
: public PhasedOperationT
<SnapTrimEvent
> {
33 using remove_or_update_ertr
=
34 crimson::errorator
<crimson::ct_error::enoent
>;
35 using remove_or_update_iertr
=
36 crimson::interruptible::interruptible_errorator
<
37 IOInterruptCondition
, remove_or_update_ertr
>;
38 using snap_trim_ertr
= remove_or_update_ertr::extend
<
39 crimson::ct_error::eagain
>;
40 using snap_trim_iertr
= remove_or_update_iertr::extend
<
41 crimson::ct_error::eagain
>;
43 static constexpr OperationTypeCode type
= OperationTypeCode::snaptrim_event
;
45 SnapTrimEvent(Ref
<PG
> pg
,
46 SnapMapper
& snap_mapper
,
47 const snapid_t snapid
,
48 const bool needs_pause
)
50 snap_mapper(snap_mapper
),
52 needs_pause(needs_pause
) {}
54 void print(std::ostream
&) const final
;
55 void dump_detail(ceph::Formatter
* f
) const final
;
56 snap_trim_ertr::future
<seastar::stop_iteration
> start();
57 snap_trim_ertr::future
<seastar::stop_iteration
> with_pg(
58 ShardServices
&shard_services
, Ref
<PG
> pg
);
61 CommonPGPipeline
& pp();
63 // bases on 998cb8c141bb89aafae298a9d5e130fbd78fe5f2
64 struct SubOpBlocker
: crimson::BlockerT
<SubOpBlocker
> {
65 static constexpr const char* type_name
= "CompoundOpBlocker";
67 using id_done_t
= std::pair
<crimson::Operation::id_t
,
68 remove_or_update_iertr::future
<>>;
70 void dump_detail(Formatter
*f
) const final
;
72 template <class... Args
>
73 void emplace_back(Args
&&... args
);
75 remove_or_update_iertr::future
<> wait_completion();
77 std::vector
<id_done_t
> subops
;
80 // we don't need to synchronize with other instances of SnapTrimEvent;
81 // it's here for the sake of op tracking.
82 struct WaitSubop
: OrderedConcurrentPhaseT
<WaitSubop
> {
83 static constexpr auto type_name
= "SnapTrimEvent::wait_subop";
86 // an instantiator can instruct us to go over this stage and then
87 // wait for the future to implement throttling. It is implemented
88 // that way to for the sake of tracking ops.
89 struct WaitTrimTimer
: OrderedExclusivePhaseT
<WaitTrimTimer
> {
90 static constexpr auto type_name
= "SnapTrimEvent::wait_trim_timer";
93 PipelineHandle handle
;
95 SnapMapper
& snap_mapper
;
96 const snapid_t snapid
;
97 const bool needs_pause
;
100 PipelineHandle
& get_handle() { return handle
; }
104 CommonPGPipeline::WaitForActive::BlockingEvent
,
105 PGActivationBlocker::BlockingEvent
,
106 CommonPGPipeline::RecoverMissing::BlockingEvent
,
107 CommonPGPipeline::GetOBC::BlockingEvent
,
108 CommonPGPipeline::Process::BlockingEvent
,
109 WaitSubop::BlockingEvent
,
110 WaitTrimTimer::BlockingEvent
,
115 // remove single object. a SnapTrimEvent can create multiple subrequests.
116 // the division of labour is needed because of the restriction that an Op
117 // cannot revisite a pipeline's stage it already saw.
118 class SnapTrimObjSubEvent
: public PhasedOperationT
<SnapTrimObjSubEvent
> {
120 using remove_or_update_ertr
=
121 crimson::errorator
<crimson::ct_error::enoent
>;
122 using remove_or_update_iertr
=
123 crimson::interruptible::interruptible_errorator
<
124 IOInterruptCondition
, remove_or_update_ertr
>;
126 static constexpr OperationTypeCode type
=
127 OperationTypeCode::snaptrimobj_subevent
;
131 const hobject_t
& coid
,
132 snapid_t snap_to_trim
)
135 snap_to_trim(snap_to_trim
) {
138 void print(std::ostream
&) const final
;
139 void dump_detail(ceph::Formatter
* f
) const final
;
140 remove_or_update_iertr::future
<> start();
141 remove_or_update_iertr::future
<> with_pg(
142 ShardServices
&shard_services
, Ref
<PG
> pg
);
144 CommonPGPipeline
& pp();
147 object_stat_sum_t delta_stats
;
149 remove_or_update_iertr::future
<> remove_clone(
150 ObjectContextRef obc
,
151 ObjectContextRef head_obc
,
152 ceph::os::Transaction
& txn
,
153 std::vector
<pg_log_entry_t
>& log_entries
);
154 void remove_head_whiteout(
155 ObjectContextRef obc
,
156 ObjectContextRef head_obc
,
157 ceph::os::Transaction
& txn
,
158 std::vector
<pg_log_entry_t
>& log_entries
);
159 interruptible_future
<> adjust_snaps(
160 ObjectContextRef obc
,
161 ObjectContextRef head_obc
,
162 const std::set
<snapid_t
>& new_snaps
,
163 ceph::os::Transaction
& txn
,
164 std::vector
<pg_log_entry_t
>& log_entries
);
166 ObjectContextRef obc
,
167 ObjectContextRef head_obc
,
168 ceph::os::Transaction
& txn
,
169 std::vector
<pg_log_entry_t
>& log_entries
);
171 using remove_or_update_ret_t
=
172 std::pair
<ceph::os::Transaction
, std::vector
<pg_log_entry_t
>>;
173 remove_or_update_iertr::future
<remove_or_update_ret_t
>
174 remove_or_update(ObjectContextRef obc
, ObjectContextRef head_obc
);
176 // we don't need to synchronize with other instances started by
177 // SnapTrimEvent; it's here for the sake of op tracking.
178 struct WaitRepop
: OrderedConcurrentPhaseT
<WaitRepop
> {
179 static constexpr auto type_name
= "SnapTrimObjSubEvent::wait_repop";
183 PipelineHandle handle
;
184 osd_op_params_t osd_op_p
;
185 const hobject_t coid
;
186 const snapid_t snap_to_trim
;
189 PipelineHandle
& get_handle() { return handle
; }
193 CommonPGPipeline::WaitForActive::BlockingEvent
,
194 PGActivationBlocker::BlockingEvent
,
195 CommonPGPipeline::RecoverMissing::BlockingEvent
,
196 CommonPGPipeline::GetOBC::BlockingEvent
,
197 CommonPGPipeline::Process::BlockingEvent
,
198 WaitRepop::BlockingEvent
,
203 } // namespace crimson::osd
205 #if FMT_VERSION >= 90000
206 template <> struct fmt::formatter
<crimson::osd::SnapTrimEvent
> : fmt::ostream_formatter
{};
207 template <> struct fmt::formatter
<crimson::osd::SnapTrimObjSubEvent
> : fmt::ostream_formatter
{};