]>
Commit | Line | Data |
---|---|---|
1e59de90 TL |
1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
2 | // vim: ts=8 sw=2 smarttab | |
3 | ||
4 | #pragma once | |
5 | ||
6 | #include <iostream> | |
7 | #include <seastar/core/future.hh> | |
8 | ||
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" | |
17 | ||
18 | namespace ceph { | |
19 | class Formatter; | |
20 | } | |
21 | ||
22 | class SnapMapper; | |
23 | ||
24 | namespace crimson::osd { | |
25 | ||
26 | class OSD; | |
27 | class ShardServices; | |
1e59de90 TL |
28 | |
29 | // trim up to `max` objects for snapshot `snapid | |
30 | class SnapTrimEvent final : public PhasedOperationT<SnapTrimEvent> { | |
31 | public: | |
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>; | |
41 | ||
42 | static constexpr OperationTypeCode type = OperationTypeCode::snaptrim_event; | |
43 | ||
44 | SnapTrimEvent(Ref<PG> pg, | |
45 | SnapMapper& snap_mapper, | |
46 | const snapid_t snapid, | |
47 | const bool needs_pause) | |
48 | : pg(std::move(pg)), | |
49 | snap_mapper(snap_mapper), | |
50 | snapid(snapid), | |
51 | needs_pause(needs_pause) {} | |
52 | ||
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); | |
58 | ||
59 | private: | |
aee94f69 | 60 | CommonPGPipeline& client_pp(); |
1e59de90 TL |
61 | |
62 | // bases on 998cb8c141bb89aafae298a9d5e130fbd78fe5f2 | |
63 | struct SubOpBlocker : crimson::BlockerT<SubOpBlocker> { | |
64 | static constexpr const char* type_name = "CompoundOpBlocker"; | |
65 | ||
66 | using id_done_t = std::pair<crimson::Operation::id_t, | |
67 | remove_or_update_iertr::future<>>; | |
68 | ||
69 | void dump_detail(Formatter *f) const final; | |
70 | ||
71 | template <class... Args> | |
72 | void emplace_back(Args&&... args); | |
73 | ||
74 | remove_or_update_iertr::future<> wait_completion(); | |
75 | private: | |
76 | std::vector<id_done_t> subops; | |
77 | } subop_blocker; | |
78 | ||
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"; | |
83 | } wait_subop; | |
84 | ||
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"; | |
90 | } wait_trim_timer; | |
91 | ||
92 | PipelineHandle handle; | |
93 | Ref<PG> pg; | |
94 | SnapMapper& snap_mapper; | |
95 | const snapid_t snapid; | |
96 | const bool needs_pause; | |
97 | ||
98 | public: | |
99 | PipelineHandle& get_handle() { return handle; } | |
100 | ||
101 | std::tuple< | |
102 | StartEvent, | |
103 | CommonPGPipeline::WaitForActive::BlockingEvent, | |
104 | PGActivationBlocker::BlockingEvent, | |
105 | CommonPGPipeline::RecoverMissing::BlockingEvent, | |
106 | CommonPGPipeline::GetOBC::BlockingEvent, | |
107 | CommonPGPipeline::Process::BlockingEvent, | |
108 | WaitSubop::BlockingEvent, | |
aee94f69 | 109 | PG::SnapTrimMutex::WaitPG::BlockingEvent, |
1e59de90 TL |
110 | WaitTrimTimer::BlockingEvent, |
111 | CompletionEvent | |
112 | > tracking_events; | |
aee94f69 TL |
113 | |
114 | friend class PG::SnapTrimMutex; | |
1e59de90 TL |
115 | }; |
116 | ||
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> { | |
121 | public: | |
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>; | |
127 | ||
128 | static constexpr OperationTypeCode type = | |
129 | OperationTypeCode::snaptrimobj_subevent; | |
130 | ||
131 | SnapTrimObjSubEvent( | |
132 | Ref<PG> pg, | |
133 | const hobject_t& coid, | |
134 | snapid_t snap_to_trim) | |
135 | : pg(std::move(pg)), | |
136 | coid(coid), | |
137 | snap_to_trim(snap_to_trim) { | |
138 | } | |
139 | ||
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); | |
145 | ||
aee94f69 | 146 | CommonPGPipeline& client_pp(); |
1e59de90 TL |
147 | |
148 | private: | |
149 | object_stat_sum_t delta_stats; | |
150 | ||
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); | |
167 | void update_head( | |
168 | ObjectContextRef obc, | |
169 | ObjectContextRef head_obc, | |
170 | ceph::os::Transaction& txn, | |
171 | std::vector<pg_log_entry_t>& log_entries); | |
172 | ||
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); | |
177 | ||
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"; | |
182 | } wait_repop; | |
183 | ||
184 | Ref<PG> pg; | |
185 | PipelineHandle handle; | |
186 | osd_op_params_t osd_op_p; | |
187 | const hobject_t coid; | |
188 | const snapid_t snap_to_trim; | |
189 | ||
190 | public: | |
191 | PipelineHandle& get_handle() { return handle; } | |
192 | ||
193 | std::tuple< | |
194 | StartEvent, | |
195 | CommonPGPipeline::WaitForActive::BlockingEvent, | |
196 | PGActivationBlocker::BlockingEvent, | |
197 | CommonPGPipeline::RecoverMissing::BlockingEvent, | |
198 | CommonPGPipeline::GetOBC::BlockingEvent, | |
199 | CommonPGPipeline::Process::BlockingEvent, | |
200 | WaitRepop::BlockingEvent, | |
201 | CompletionEvent | |
202 | > tracking_events; | |
203 | }; | |
204 | ||
205 | } // namespace crimson::osd | |
206 | ||
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 {}; | |
210 | #endif |