]>
Commit | Line | Data |
---|---|---|
7c673cae | 1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
9f95a23c | 2 | // vim: ts=8 sw=2 smarttab ft=cpp |
7c673cae FG |
3 | |
4 | #ifndef CEPH_RGWRADOS_H | |
5 | #define CEPH_RGWRADOS_H | |
6 | ||
7 | #include <functional> | |
9f95a23c | 8 | #include <boost/container/flat_map.hpp> |
7c673cae FG |
9 | |
10 | #include "include/rados/librados.hpp" | |
11 | #include "include/Context.h" | |
a4b75251 | 12 | #include "include/random.h" |
7c673cae | 13 | #include "common/RefCountedObj.h" |
7c673cae | 14 | #include "common/ceph_time.h" |
a4b75251 | 15 | #include "common/Timer.h" |
7c673cae FG |
16 | #include "rgw_common.h" |
17 | #include "cls/rgw/cls_rgw_types.h" | |
18 | #include "cls/version/cls_version_types.h" | |
19 | #include "cls/log/cls_log_types.h" | |
7c673cae | 20 | #include "cls/timeindex/cls_timeindex_types.h" |
11fdf7f2 | 21 | #include "cls/otp/cls_otp_types.h" |
7c673cae FG |
22 | #include "rgw_log.h" |
23 | #include "rgw_metadata.h" | |
24 | #include "rgw_meta_sync_status.h" | |
25 | #include "rgw_period_puller.h" | |
9f95a23c | 26 | #include "rgw_obj_manifest.h" |
7c673cae | 27 | #include "rgw_sync_module.h" |
9f95a23c | 28 | #include "rgw_trim_bilog.h" |
11fdf7f2 | 29 | #include "rgw_service.h" |
f67539c2 | 30 | #include "rgw_sal.h" |
20effc67 TL |
31 | #include "rgw_aio.h" |
32 | #include "rgw_d3n_cacherequest.h" | |
11fdf7f2 TL |
33 | |
34 | #include "services/svc_rados.h" | |
9f95a23c | 35 | #include "services/svc_bi_rados.h" |
20effc67 TL |
36 | #include "common/Throttle.h" |
37 | #include "common/ceph_mutex.h" | |
38 | #include "rgw_cache.h" | |
39 | ||
40 | struct D3nDataCache; | |
7c673cae FG |
41 | |
42 | class RGWWatcher; | |
7c673cae FG |
43 | class ACLOwner; |
44 | class RGWGC; | |
45 | class RGWMetaNotifier; | |
46 | class RGWDataNotifier; | |
47 | class RGWLC; | |
48 | class RGWObjectExpirer; | |
49 | class RGWMetaSyncProcessorThread; | |
50 | class RGWDataSyncProcessorThread; | |
51 | class RGWSyncLogTrimThread; | |
11fdf7f2 | 52 | class RGWSyncTraceManager; |
7c673cae FG |
53 | struct RGWZoneGroup; |
54 | struct RGWZoneParams; | |
31f18b77 FG |
55 | class RGWReshard; |
56 | class RGWReshardWait; | |
7c673cae | 57 | |
11fdf7f2 | 58 | class RGWSysObjectCtx; |
20effc67 | 59 | struct get_obj_data; |
11fdf7f2 | 60 | |
7c673cae FG |
61 | /* flags for put_obj_meta() */ |
62 | #define PUT_OBJ_CREATE 0x01 | |
63 | #define PUT_OBJ_EXCL 0x02 | |
64 | #define PUT_OBJ_CREATE_EXCL (PUT_OBJ_CREATE | PUT_OBJ_EXCL) | |
65 | ||
66 | #define RGW_OBJ_NS_MULTIPART "multipart" | |
67 | #define RGW_OBJ_NS_SHADOW "shadow" | |
68 | ||
20effc67 | 69 | static inline void prepend_bucket_marker(const rgw_bucket& bucket, const std::string& orig_oid, std::string& oid) |
7c673cae FG |
70 | { |
71 | if (bucket.marker.empty() || orig_oid.empty()) { | |
72 | oid = orig_oid; | |
73 | } else { | |
74 | oid = bucket.marker; | |
75 | oid.append("_"); | |
76 | oid.append(orig_oid); | |
77 | } | |
78 | } | |
79 | ||
20effc67 | 80 | static inline void get_obj_bucket_and_oid_loc(const rgw_obj& obj, std::string& oid, std::string& locator) |
7c673cae FG |
81 | { |
82 | const rgw_bucket& bucket = obj.bucket; | |
83 | prepend_bucket_marker(bucket, obj.get_oid(), oid); | |
20effc67 | 84 | const std::string& loc = obj.key.get_loc(); |
7c673cae FG |
85 | if (!loc.empty()) { |
86 | prepend_bucket_marker(bucket, loc, locator); | |
87 | } else { | |
88 | locator.clear(); | |
89 | } | |
90 | } | |
91 | ||
20effc67 TL |
92 | int rgw_policy_from_attrset(const DoutPrefixProvider *dpp, |
93 | CephContext *cct, | |
94 | std::map<std::string, bufferlist>& attrset, | |
95 | RGWAccessControlPolicy *policy); | |
7c673cae | 96 | |
7c673cae FG |
97 | struct RGWOLHInfo { |
98 | rgw_obj target; | |
99 | bool removed; | |
100 | ||
101 | RGWOLHInfo() : removed(false) {} | |
102 | ||
103 | void encode(bufferlist& bl) const { | |
104 | ENCODE_START(1, 1, bl); | |
11fdf7f2 TL |
105 | encode(target, bl); |
106 | encode(removed, bl); | |
7c673cae FG |
107 | ENCODE_FINISH(bl); |
108 | } | |
109 | ||
11fdf7f2 | 110 | void decode(bufferlist::const_iterator& bl) { |
7c673cae | 111 | DECODE_START(1, bl); |
11fdf7f2 TL |
112 | decode(target, bl); |
113 | decode(removed, bl); | |
7c673cae FG |
114 | DECODE_FINISH(bl); |
115 | } | |
20effc67 | 116 | static void generate_test_instances(std::list<RGWOLHInfo*>& o); |
7c673cae FG |
117 | void dump(Formatter *f) const; |
118 | }; | |
119 | WRITE_CLASS_ENCODER(RGWOLHInfo) | |
120 | ||
121 | struct RGWOLHPendingInfo { | |
122 | ceph::real_time time; | |
123 | ||
124 | RGWOLHPendingInfo() {} | |
125 | ||
126 | void encode(bufferlist& bl) const { | |
127 | ENCODE_START(1, 1, bl); | |
11fdf7f2 | 128 | encode(time, bl); |
7c673cae FG |
129 | ENCODE_FINISH(bl); |
130 | } | |
131 | ||
11fdf7f2 | 132 | void decode(bufferlist::const_iterator& bl) { |
7c673cae | 133 | DECODE_START(1, bl); |
11fdf7f2 | 134 | decode(time, bl); |
7c673cae FG |
135 | DECODE_FINISH(bl); |
136 | } | |
137 | ||
138 | void dump(Formatter *f) const; | |
139 | }; | |
140 | WRITE_CLASS_ENCODER(RGWOLHPendingInfo) | |
141 | ||
142 | struct RGWUsageBatch { | |
20effc67 | 143 | std::map<ceph::real_time, rgw_usage_log_entry> m; |
7c673cae FG |
144 | |
145 | void insert(ceph::real_time& t, rgw_usage_log_entry& entry, bool *account) { | |
146 | bool exists = m.find(t) != m.end(); | |
147 | *account = !exists; | |
148 | m[t].aggregate(entry); | |
149 | } | |
150 | }; | |
151 | ||
7c673cae FG |
152 | struct RGWCloneRangeInfo { |
153 | rgw_obj src; | |
154 | off_t src_ofs; | |
155 | off_t dst_ofs; | |
156 | uint64_t len; | |
157 | }; | |
158 | ||
9f95a23c TL |
159 | class RGWFetchObjFilter { |
160 | public: | |
161 | virtual ~RGWFetchObjFilter() {} | |
162 | ||
163 | virtual int filter(CephContext *cct, | |
164 | const rgw_obj_key& source_key, | |
165 | const RGWBucketInfo& dest_bucket_info, | |
166 | std::optional<rgw_placement_rule> dest_placement_rule, | |
20effc67 | 167 | const std::map<std::string, bufferlist>& obj_attrs, |
9f95a23c TL |
168 | std::optional<rgw_user> *poverride_owner, |
169 | const rgw_placement_rule **prule) = 0; | |
170 | }; | |
171 | ||
172 | class RGWFetchObjFilter_Default : public RGWFetchObjFilter { | |
173 | protected: | |
174 | rgw_placement_rule dest_rule; | |
175 | public: | |
176 | RGWFetchObjFilter_Default() {} | |
177 | ||
178 | int filter(CephContext *cct, | |
179 | const rgw_obj_key& source_key, | |
180 | const RGWBucketInfo& dest_bucket_info, | |
181 | std::optional<rgw_placement_rule> dest_placement_rule, | |
20effc67 | 182 | const std::map<std::string, bufferlist>& obj_attrs, |
9f95a23c TL |
183 | std::optional<rgw_user> *poverride_owner, |
184 | const rgw_placement_rule **prule) override; | |
185 | }; | |
186 | ||
187 | class RGWObjectCtx { | |
20effc67 | 188 | rgw::sal::Store* store; |
9f95a23c TL |
189 | ceph::shared_mutex lock = ceph::make_shared_mutex("RGWObjectCtx"); |
190 | void *s{nullptr}; | |
191 | ||
192 | std::map<rgw_obj, RGWObjState> objs_state; | |
193 | public: | |
20effc67 TL |
194 | explicit RGWObjectCtx(rgw::sal::Store* _store) : store(_store) {} |
195 | explicit RGWObjectCtx(rgw::sal::Store* _store, void *_s) : store(_store), s(_s) {} | |
9f95a23c TL |
196 | |
197 | void *get_private() { | |
198 | return s; | |
199 | } | |
200 | ||
20effc67 | 201 | rgw::sal::Store* get_store() { |
9f95a23c TL |
202 | return store; |
203 | } | |
204 | ||
205 | RGWObjState *get_state(const rgw_obj& obj); | |
206 | ||
20effc67 | 207 | void set_compressed(const rgw_obj& obj); |
9f95a23c TL |
208 | void set_atomic(rgw_obj& obj); |
209 | void set_prefetch_data(const rgw_obj& obj); | |
210 | void invalidate(const rgw_obj& obj); | |
211 | }; | |
212 | ||
213 | ||
7c673cae FG |
214 | struct RGWRawObjState { |
215 | rgw_raw_obj obj; | |
216 | bool has_attrs{false}; | |
217 | bool exists{false}; | |
218 | uint64_t size{0}; | |
219 | ceph::real_time mtime; | |
11fdf7f2 | 220 | uint64_t epoch{0}; |
7c673cae FG |
221 | bufferlist obj_tag; |
222 | bool has_data{false}; | |
223 | bufferlist data; | |
224 | bool prefetch_data{false}; | |
225 | uint64_t pg_ver{0}; | |
226 | ||
227 | /* important! don't forget to update copy constructor */ | |
228 | ||
229 | RGWObjVersionTracker objv_tracker; | |
230 | ||
20effc67 | 231 | std::map<std::string, bufferlist> attrset; |
7c673cae FG |
232 | RGWRawObjState() {} |
233 | RGWRawObjState(const RGWRawObjState& rhs) : obj (rhs.obj) { | |
234 | has_attrs = rhs.has_attrs; | |
235 | exists = rhs.exists; | |
236 | size = rhs.size; | |
237 | mtime = rhs.mtime; | |
238 | epoch = rhs.epoch; | |
239 | if (rhs.obj_tag.length()) { | |
240 | obj_tag = rhs.obj_tag; | |
241 | } | |
242 | has_data = rhs.has_data; | |
243 | if (rhs.data.length()) { | |
244 | data = rhs.data; | |
245 | } | |
246 | prefetch_data = rhs.prefetch_data; | |
247 | pg_ver = rhs.pg_ver; | |
248 | objv_tracker = rhs.objv_tracker; | |
249 | } | |
250 | }; | |
251 | ||
252 | struct RGWPoolIterCtx { | |
253 | librados::IoCtx io_ctx; | |
254 | librados::NObjectIterator iter; | |
255 | }; | |
256 | ||
257 | struct RGWListRawObjsCtx { | |
258 | bool initialized; | |
259 | RGWPoolIterCtx iter_ctx; | |
260 | ||
261 | RGWListRawObjsCtx() : initialized(false) {} | |
262 | }; | |
263 | ||
7c673cae | 264 | struct objexp_hint_entry { |
20effc67 TL |
265 | std::string tenant; |
266 | std::string bucket_name; | |
267 | std::string bucket_id; | |
7c673cae FG |
268 | rgw_obj_key obj_key; |
269 | ceph::real_time exp_time; | |
270 | ||
271 | void encode(bufferlist& bl) const { | |
272 | ENCODE_START(2, 1, bl); | |
11fdf7f2 TL |
273 | encode(bucket_name, bl); |
274 | encode(bucket_id, bl); | |
275 | encode(obj_key, bl); | |
276 | encode(exp_time, bl); | |
277 | encode(tenant, bl); | |
7c673cae FG |
278 | ENCODE_FINISH(bl); |
279 | } | |
280 | ||
11fdf7f2 | 281 | void decode(bufferlist::const_iterator& bl) { |
7c673cae FG |
282 | // XXX Do we want DECODE_START_LEGACY_COMPAT_LEN(2, 1, 1, bl); ? |
283 | DECODE_START(2, bl); | |
11fdf7f2 TL |
284 | decode(bucket_name, bl); |
285 | decode(bucket_id, bl); | |
286 | decode(obj_key, bl); | |
287 | decode(exp_time, bl); | |
7c673cae | 288 | if (struct_v >= 2) { |
11fdf7f2 | 289 | decode(tenant, bl); |
7c673cae FG |
290 | } else { |
291 | tenant.clear(); | |
292 | } | |
293 | DECODE_FINISH(bl); | |
294 | } | |
9f95a23c TL |
295 | |
296 | void dump(Formatter *f) const; | |
20effc67 | 297 | static void generate_test_instances(std::list<objexp_hint_entry*>& o); |
7c673cae FG |
298 | }; |
299 | WRITE_CLASS_ENCODER(objexp_hint_entry) | |
300 | ||
7c673cae FG |
301 | class RGWMetaSyncStatusManager; |
302 | class RGWDataSyncStatusManager; | |
7c673cae | 303 | class RGWCoroutinesManagerRegistry; |
7c673cae | 304 | |
7c673cae FG |
305 | class RGWGetDirHeader_CB; |
306 | class RGWGetUserHeader_CB; | |
f67539c2 | 307 | namespace rgw { namespace sal { |
20effc67 TL |
308 | class Store; |
309 | class RadosStore; | |
f67539c2 TL |
310 | class MPRadosSerializer; |
311 | class LCRadosSerializer; | |
312 | } } | |
7c673cae | 313 | |
7c673cae FG |
314 | class RGWAsyncRadosProcessor; |
315 | ||
316 | template <class T> | |
317 | class RGWChainedCacheImpl; | |
318 | ||
319 | struct bucket_info_entry { | |
320 | RGWBucketInfo info; | |
321 | real_time mtime; | |
20effc67 | 322 | std::map<std::string, bufferlist> attrs; |
7c673cae FG |
323 | }; |
324 | ||
9f95a23c | 325 | struct tombstone_entry; |
7c673cae | 326 | |
9f95a23c TL |
327 | template <class K, class V> |
328 | class lru_map; | |
329 | using tombstone_cache_t = lru_map<rgw_obj, tombstone_entry>; | |
7c673cae | 330 | |
31f18b77 FG |
331 | class RGWIndexCompletionManager; |
332 | ||
9f95a23c | 333 | class RGWRados |
7c673cae FG |
334 | { |
335 | friend class RGWGC; | |
336 | friend class RGWMetaNotifier; | |
337 | friend class RGWDataNotifier; | |
7c673cae FG |
338 | friend class RGWObjectExpirer; |
339 | friend class RGWMetaSyncProcessorThread; | |
340 | friend class RGWDataSyncProcessorThread; | |
31f18b77 FG |
341 | friend class RGWReshard; |
342 | friend class RGWBucketReshard; | |
f64942e4 | 343 | friend class RGWBucketReshardLock; |
31f18b77 | 344 | friend class BucketIndexLockGuard; |
f67539c2 TL |
345 | friend class rgw::sal::MPRadosSerializer; |
346 | friend class rgw::sal::LCRadosSerializer; | |
20effc67 | 347 | friend class rgw::sal::RadosStore; |
7c673cae FG |
348 | |
349 | /** Open the pool used as root for this gateway */ | |
b3b6e05e TL |
350 | int open_root_pool_ctx(const DoutPrefixProvider *dpp); |
351 | int open_gc_pool_ctx(const DoutPrefixProvider *dpp); | |
352 | int open_lc_pool_ctx(const DoutPrefixProvider *dpp); | |
353 | int open_objexp_pool_ctx(const DoutPrefixProvider *dpp); | |
354 | int open_reshard_pool_ctx(const DoutPrefixProvider *dpp); | |
355 | int open_notif_pool_ctx(const DoutPrefixProvider *dpp); | |
356 | ||
357 | int open_pool_ctx(const DoutPrefixProvider *dpp, const rgw_pool& pool, librados::IoCtx& io_ctx, | |
494da23a | 358 | bool mostly_omap); |
7c673cae | 359 | |
a4b75251 | 360 | |
9f95a23c | 361 | ceph::mutex lock = ceph::make_mutex("rados_timer_lock"); |
7c673cae FG |
362 | SafeTimer *timer; |
363 | ||
20effc67 | 364 | rgw::sal::RadosStore* store = nullptr; |
522d829b | 365 | RGWGC *gc = nullptr; |
7c673cae FG |
366 | RGWLC *lc; |
367 | RGWObjectExpirer *obj_expirer; | |
368 | bool use_gc_thread; | |
369 | bool use_lc_thread; | |
370 | bool quota_threads; | |
371 | bool run_sync_thread; | |
31f18b77 | 372 | bool run_reshard_thread; |
7c673cae | 373 | |
7c673cae FG |
374 | RGWMetaNotifier *meta_notifier; |
375 | RGWDataNotifier *data_notifier; | |
376 | RGWMetaSyncProcessorThread *meta_sync_processor_thread; | |
11fdf7f2 | 377 | RGWSyncTraceManager *sync_tracer = nullptr; |
20effc67 | 378 | std::map<rgw_zone_id, RGWDataSyncProcessorThread *> data_sync_processor_threads; |
7c673cae | 379 | |
b32b8144 | 380 | boost::optional<rgw::BucketTrimManager> bucket_trim; |
7c673cae FG |
381 | RGWSyncLogTrimThread *sync_log_trimmer{nullptr}; |
382 | ||
9f95a23c TL |
383 | ceph::mutex meta_sync_thread_lock = ceph::make_mutex("meta_sync_thread_lock"); |
384 | ceph::mutex data_sync_thread_lock = ceph::make_mutex("data_sync_thread_lock"); | |
7c673cae | 385 | |
7c673cae | 386 | librados::IoCtx root_pool_ctx; // .rgw |
11fdf7f2 TL |
387 | |
388 | double inject_notify_timeout_probability = 0; | |
389 | unsigned max_notify_retries = 0; | |
7c673cae FG |
390 | |
391 | friend class RGWWatcher; | |
392 | ||
9f95a23c | 393 | ceph::mutex bucket_id_lock = ceph::make_mutex("rados_bucket_id"); |
7c673cae FG |
394 | |
395 | // This field represents the number of bucket index object shards | |
396 | uint32_t bucket_index_max_shards; | |
397 | ||
20effc67 TL |
398 | std::string get_cluster_fsid(const DoutPrefixProvider *dpp, optional_yield y); |
399 | ||
400 | int get_obj_head_ref(const DoutPrefixProvider *dpp, const rgw_placement_rule& target_placement_rule, const rgw_obj& obj, rgw_rados_ref *ref); | |
b3b6e05e TL |
401 | int get_obj_head_ref(const DoutPrefixProvider *dpp, const RGWBucketInfo& bucket_info, const rgw_obj& obj, rgw_rados_ref *ref); |
402 | int get_system_obj_ref(const DoutPrefixProvider *dpp, const rgw_raw_obj& obj, rgw_rados_ref *ref); | |
7c673cae FG |
403 | uint64_t max_bucket_id; |
404 | ||
b3b6e05e | 405 | int get_olh_target_state(const DoutPrefixProvider *dpp, RGWObjectCtx& rctx, const RGWBucketInfo& bucket_info, const rgw_obj& obj, |
9f95a23c | 406 | RGWObjState *olh_state, RGWObjState **target_state, optional_yield y); |
b3b6e05e | 407 | int get_obj_state_impl(const DoutPrefixProvider *dpp, RGWObjectCtx *rctx, const RGWBucketInfo& bucket_info, const rgw_obj& obj, RGWObjState **state, |
9f95a23c | 408 | bool follow_olh, optional_yield y, bool assume_noent = false); |
b3b6e05e | 409 | int append_atomic_test(const DoutPrefixProvider *dpp, RGWObjectCtx *rctx, const RGWBucketInfo& bucket_info, const rgw_obj& obj, |
9f95a23c | 410 | librados::ObjectOperation& op, RGWObjState **state, optional_yield y); |
20effc67 | 411 | |
7c673cae | 412 | int update_placement_map(); |
20effc67 | 413 | int store_bucket_info(RGWBucketInfo& info, std::map<std::string, bufferlist> *pattrs, RGWObjVersionTracker *objv_tracker, bool exclusive); |
7c673cae FG |
414 | |
415 | void remove_rgw_head_obj(librados::ObjectWriteOperation& op); | |
20effc67 | 416 | void cls_obj_check_prefix_exist(librados::ObjectOperation& op, const std::string& prefix, bool fail_if_exist); |
7c673cae FG |
417 | void cls_obj_check_mtime(librados::ObjectOperation& op, const real_time& mtime, bool high_precision_time, RGWCheckMTimeType type); |
418 | protected: | |
419 | CephContext *cct; | |
420 | ||
494da23a | 421 | librados::Rados rados; |
7c673cae FG |
422 | |
423 | using RGWChainedCacheImpl_bucket_info_entry = RGWChainedCacheImpl<bucket_info_entry>; | |
424 | RGWChainedCacheImpl_bucket_info_entry *binfo_cache; | |
425 | ||
7c673cae FG |
426 | tombstone_cache_t *obj_tombstone_cache; |
427 | ||
428 | librados::IoCtx gc_pool_ctx; // .rgw.gc | |
429 | librados::IoCtx lc_pool_ctx; // .rgw.lc | |
430 | librados::IoCtx objexp_pool_ctx; | |
31f18b77 | 431 | librados::IoCtx reshard_pool_ctx; |
f67539c2 | 432 | librados::IoCtx notif_pool_ctx; // .rgw.notif |
7c673cae | 433 | |
11fdf7f2 | 434 | bool pools_initialized; |
7c673cae | 435 | |
11fdf7f2 | 436 | RGWQuotaHandler *quota_handler; |
7c673cae | 437 | |
11fdf7f2 | 438 | RGWCoroutinesManagerRegistry *cr_registry; |
7c673cae | 439 | |
11fdf7f2 TL |
440 | RGWSyncModuleInstanceRef sync_module; |
441 | bool writeable_zone{false}; | |
7c673cae | 442 | |
11fdf7f2 | 443 | RGWIndexCompletionManager *index_completion_manager{nullptr}; |
7c673cae | 444 | |
11fdf7f2 | 445 | bool use_cache{false}; |
522d829b | 446 | bool use_gc{true}; |
20effc67 | 447 | bool use_datacache{false}; |
f67539c2 | 448 | |
b3b6e05e | 449 | int get_obj_head_ioctx(const DoutPrefixProvider *dpp, const RGWBucketInfo& bucket_info, const rgw_obj& obj, librados::IoCtx *ioctx); |
11fdf7f2 | 450 | public: |
9f95a23c | 451 | RGWRados(): timer(NULL), |
11fdf7f2 | 452 | gc(NULL), lc(NULL), obj_expirer(NULL), use_gc_thread(false), use_lc_thread(false), quota_threads(false), |
9f95a23c | 453 | run_sync_thread(false), run_reshard_thread(false), meta_notifier(NULL), |
11fdf7f2 | 454 | data_notifier(NULL), meta_sync_processor_thread(NULL), |
11fdf7f2 TL |
455 | bucket_index_max_shards(0), |
456 | max_bucket_id(0), cct(NULL), | |
11fdf7f2 TL |
457 | binfo_cache(NULL), obj_tombstone_cache(nullptr), |
458 | pools_initialized(false), | |
459 | quota_handler(NULL), | |
460 | cr_registry(NULL), | |
9f95a23c TL |
461 | pctl(&ctl), |
462 | reshard(NULL) {} | |
7c673cae | 463 | |
11fdf7f2 TL |
464 | RGWRados& set_use_cache(bool status) { |
465 | use_cache = status; | |
466 | return *this; | |
7c673cae FG |
467 | } |
468 | ||
522d829b TL |
469 | RGWRados& set_use_gc(bool status) { |
470 | use_gc = status; | |
471 | return *this; | |
472 | } | |
473 | ||
20effc67 TL |
474 | RGWRados& set_use_datacache(bool status) { |
475 | use_datacache = status; | |
476 | return *this; | |
477 | } | |
478 | ||
479 | bool get_use_datacache() { | |
480 | return use_datacache; | |
481 | } | |
482 | ||
11fdf7f2 TL |
483 | RGWLC *get_lc() { |
484 | return lc; | |
7c673cae FG |
485 | } |
486 | ||
20effc67 TL |
487 | RGWGC *get_gc() { |
488 | return gc; | |
489 | } | |
490 | ||
11fdf7f2 TL |
491 | RGWRados& set_run_gc_thread(bool _use_gc_thread) { |
492 | use_gc_thread = _use_gc_thread; | |
493 | return *this; | |
7c673cae FG |
494 | } |
495 | ||
11fdf7f2 TL |
496 | RGWRados& set_run_lc_thread(bool _use_lc_thread) { |
497 | use_lc_thread = _use_lc_thread; | |
498 | return *this; | |
7c673cae FG |
499 | } |
500 | ||
11fdf7f2 TL |
501 | RGWRados& set_run_quota_threads(bool _run_quota_threads) { |
502 | quota_threads = _run_quota_threads; | |
503 | return *this; | |
7c673cae FG |
504 | } |
505 | ||
11fdf7f2 TL |
506 | RGWRados& set_run_sync_thread(bool _run_sync_thread) { |
507 | run_sync_thread = _run_sync_thread; | |
508 | return *this; | |
7c673cae FG |
509 | } |
510 | ||
11fdf7f2 TL |
511 | RGWRados& set_run_reshard_thread(bool _run_reshard_thread) { |
512 | run_reshard_thread = _run_reshard_thread; | |
513 | return *this; | |
7c673cae FG |
514 | } |
515 | ||
11fdf7f2 | 516 | uint64_t get_new_req_id() { |
a4b75251 | 517 | return ceph::util::generate_random_number<uint64_t>(); |
7c673cae FG |
518 | } |
519 | ||
11fdf7f2 TL |
520 | librados::IoCtx* get_lc_pool_ctx() { |
521 | return &lc_pool_ctx; | |
7c673cae | 522 | } |
f67539c2 TL |
523 | |
524 | librados::IoCtx& get_notif_pool_ctx() { | |
525 | return notif_pool_ctx; | |
526 | } | |
527 | ||
11fdf7f2 TL |
528 | void set_context(CephContext *_cct) { |
529 | cct = _cct; | |
7c673cae | 530 | } |
20effc67 | 531 | void set_store(rgw::sal::RadosStore* _store) { |
9f95a23c TL |
532 | store = _store; |
533 | } | |
31f18b77 | 534 | |
11fdf7f2 | 535 | RGWServices svc; |
9f95a23c TL |
536 | RGWCtl ctl; |
537 | ||
538 | RGWCtl *pctl{nullptr}; | |
11fdf7f2 TL |
539 | |
540 | /** | |
541 | * AmazonS3 errors contain a HostId string, but is an opaque base64 blob; we | |
542 | * try to be more transparent. This has a wrapper so we can update it when zonegroup/zone are changed. | |
543 | */ | |
20effc67 | 544 | std::string host_id; |
31f18b77 | 545 | |
31f18b77 FG |
546 | RGWReshard *reshard; |
547 | std::shared_ptr<RGWReshardWait> reshard_wait; | |
548 | ||
7c673cae FG |
549 | virtual ~RGWRados() = default; |
550 | ||
551 | tombstone_cache_t *get_tombstone_cache() { | |
552 | return obj_tombstone_cache; | |
553 | } | |
7c673cae FG |
554 | const RGWSyncModuleInstanceRef& get_sync_module() { |
555 | return sync_module; | |
556 | } | |
11fdf7f2 TL |
557 | RGWSyncTraceManager *get_sync_tracer() { |
558 | return sync_tracer; | |
559 | } | |
7c673cae | 560 | |
b3b6e05e | 561 | int get_required_alignment(const DoutPrefixProvider *dpp, const rgw_pool& pool, uint64_t *alignment); |
11fdf7f2 | 562 | void get_max_aligned_size(uint64_t size, uint64_t alignment, uint64_t *max_size); |
b3b6e05e TL |
563 | int get_max_chunk_size(const rgw_pool& pool, uint64_t *max_chunk_size, const DoutPrefixProvider *dpp, uint64_t *palignment = nullptr); |
564 | int get_max_chunk_size(const rgw_placement_rule& placement_rule, const rgw_obj& obj, uint64_t *max_chunk_size, const DoutPrefixProvider *dpp, uint64_t *palignment = nullptr); | |
7c673cae FG |
565 | |
566 | uint32_t get_max_bucket_shards() { | |
9f95a23c | 567 | return RGWSI_BucketIndex_RADOS::shards_max(); |
7c673cae FG |
568 | } |
569 | ||
181888fb | 570 | |
b3b6e05e | 571 | int get_raw_obj_ref(const DoutPrefixProvider *dpp, const rgw_raw_obj& obj, rgw_rados_ref *ref); |
7c673cae | 572 | |
20effc67 TL |
573 | int list_raw_objects_init(const DoutPrefixProvider *dpp, const rgw_pool& pool, const std::string& marker, RGWListRawObjsCtx *ctx); |
574 | int list_raw_objects_next(const DoutPrefixProvider *dpp, const std::string& prefix_filter, int max, | |
575 | RGWListRawObjsCtx& ctx, std::list<std::string>& oids, | |
181888fb | 576 | bool *is_truncated); |
20effc67 TL |
577 | int list_raw_objects(const DoutPrefixProvider *dpp, const rgw_pool& pool, const std::string& prefix_filter, int max, |
578 | RGWListRawObjsCtx& ctx, std::list<std::string>& oids, | |
7c673cae | 579 | bool *is_truncated); |
20effc67 | 580 | std::string list_raw_objs_get_cursor(RGWListRawObjsCtx& ctx); |
7c673cae | 581 | |
7c673cae FG |
582 | CephContext *ctx() { return cct; } |
583 | /** do all necessary setup of the storage device */ | |
b3b6e05e | 584 | int initialize(CephContext *_cct, const DoutPrefixProvider *dpp) { |
7c673cae | 585 | set_context(_cct); |
b3b6e05e | 586 | return initialize(dpp); |
7c673cae FG |
587 | } |
588 | /** Initialize the RADOS instance and prepare to do other ops */ | |
b3b6e05e TL |
589 | int init_svc(bool raw, const DoutPrefixProvider *dpp); |
590 | int init_ctl(const DoutPrefixProvider *dpp); | |
20effc67 | 591 | virtual int init_rados(); |
b3b6e05e TL |
592 | int init_complete(const DoutPrefixProvider *dpp); |
593 | int initialize(const DoutPrefixProvider *dpp); | |
7c673cae FG |
594 | void finalize(); |
595 | ||
20effc67 TL |
596 | int register_to_service_map(const DoutPrefixProvider *dpp, const std::string& daemon_type, const std::map<std::string, std::string>& meta); |
597 | int update_service_map(const DoutPrefixProvider *dpp, std::map<std::string, std::string>&& status); | |
7c673cae FG |
598 | |
599 | /// list logs | |
20effc67 TL |
600 | int log_list_init(const DoutPrefixProvider *dpp, const std::string& prefix, RGWAccessHandle *handle); |
601 | int log_list_next(RGWAccessHandle handle, std::string *name); | |
7c673cae FG |
602 | |
603 | /// remove log | |
20effc67 | 604 | int log_remove(const DoutPrefixProvider *dpp, const std::string& name); |
7c673cae FG |
605 | |
606 | /// show log | |
20effc67 TL |
607 | int log_show_init(const DoutPrefixProvider *dpp, const std::string& name, RGWAccessHandle *handle); |
608 | int log_show_next(const DoutPrefixProvider *dpp, RGWAccessHandle handle, rgw_log_entry *entry); | |
7c673cae FG |
609 | |
610 | // log bandwidth info | |
20effc67 TL |
611 | int log_usage(const DoutPrefixProvider *dpp, std::map<rgw_user_bucket, RGWUsageBatch>& usage_info); |
612 | int read_usage(const DoutPrefixProvider *dpp, const rgw_user& user, const std::string& bucket_name, uint64_t start_epoch, uint64_t end_epoch, | |
613 | uint32_t max_entries, bool *is_truncated, RGWUsageIter& read_iter, std::map<rgw_user_bucket, | |
11fdf7f2 | 614 | rgw_usage_log_entry>& usage); |
20effc67 | 615 | int trim_usage(const DoutPrefixProvider *dpp, const rgw_user& user, const std::string& bucket_name, uint64_t start_epoch, uint64_t end_epoch); |
b3b6e05e | 616 | int clear_usage(const DoutPrefixProvider *dpp); |
7c673cae | 617 | |
b3b6e05e | 618 | int create_pool(const DoutPrefixProvider *dpp, const rgw_pool& pool); |
7c673cae | 619 | |
20effc67 | 620 | void create_bucket_id(std::string *bucket_id); |
7c673cae | 621 | |
11fdf7f2 TL |
622 | bool get_obj_data_pool(const rgw_placement_rule& placement_rule, const rgw_obj& obj, rgw_pool *pool); |
623 | bool obj_to_raw(const rgw_placement_rule& placement_rule, const rgw_obj& obj, rgw_raw_obj *raw_obj); | |
7c673cae | 624 | |
11fdf7f2 | 625 | int create_bucket(const RGWUserInfo& owner, rgw_bucket& bucket, |
20effc67 | 626 | const std::string& zonegroup_id, |
f67539c2 | 627 | const rgw_placement_rule& placement_rule, |
20effc67 | 628 | const std::string& swift_ver_location, |
f67539c2 | 629 | const RGWQuotaInfo * pquota_info, |
20effc67 | 630 | std::map<std::string,bufferlist>& attrs, |
f67539c2 TL |
631 | RGWBucketInfo& bucket_info, |
632 | obj_version *pobjv, | |
633 | obj_version *pep_objv, | |
634 | ceph::real_time creation_time, | |
635 | rgw_bucket *master_bucket, | |
636 | uint32_t *master_num_shards, | |
637 | optional_yield y, | |
b3b6e05e | 638 | const DoutPrefixProvider *dpp, |
f67539c2 | 639 | bool exclusive = true); |
7c673cae FG |
640 | |
641 | RGWCoroutinesManagerRegistry *get_cr_registry() { return cr_registry; } | |
642 | ||
7c673cae FG |
643 | struct BucketShard { |
644 | RGWRados *store; | |
645 | rgw_bucket bucket; | |
646 | int shard_id; | |
9f95a23c | 647 | RGWSI_RADOS::Obj bucket_obj; |
7c673cae FG |
648 | |
649 | explicit BucketShard(RGWRados *_store) : store(_store), shard_id(-1) {} | |
b3b6e05e TL |
650 | int init(const rgw_bucket& _bucket, const rgw_obj& obj, RGWBucketInfo* out, const DoutPrefixProvider *dpp); |
651 | int init(const rgw_bucket& _bucket, int sid, const rgw::bucket_index_layout_generation& idx_layout, RGWBucketInfo* out, const DoutPrefixProvider *dpp); | |
652 | int init(const DoutPrefixProvider *dpp, const RGWBucketInfo& bucket_info, const rgw_obj& obj); | |
653 | int init(const DoutPrefixProvider *dpp, const RGWBucketInfo& bucket_info, const rgw::bucket_index_layout_generation& idx_layout, int sid); | |
7c673cae FG |
654 | }; |
655 | ||
656 | class Object { | |
657 | RGWRados *store; | |
658 | RGWBucketInfo bucket_info; | |
659 | RGWObjectCtx& ctx; | |
660 | rgw_obj obj; | |
661 | ||
662 | BucketShard bs; | |
663 | ||
664 | RGWObjState *state; | |
665 | ||
666 | bool versioning_disabled; | |
667 | ||
668 | bool bs_initialized; | |
669 | ||
20effc67 TL |
670 | const rgw_placement_rule *pmeta_placement_rule; |
671 | ||
7c673cae | 672 | protected: |
b3b6e05e | 673 | int get_state(const DoutPrefixProvider *dpp, RGWObjState **pstate, bool follow_olh, optional_yield y, bool assume_noent = false); |
7c673cae FG |
674 | void invalidate_state(); |
675 | ||
20effc67 | 676 | int prepare_atomic_modification(const DoutPrefixProvider *dpp, librados::ObjectWriteOperation& op, bool reset_obj, const std::string *ptag, |
9f95a23c | 677 | const char *ifmatch, const char *ifnomatch, bool removal_op, bool modify_tail, optional_yield y); |
b3b6e05e | 678 | int complete_atomic_modification(const DoutPrefixProvider *dpp); |
7c673cae FG |
679 | |
680 | public: | |
681 | Object(RGWRados *_store, const RGWBucketInfo& _bucket_info, RGWObjectCtx& _ctx, const rgw_obj& _obj) : store(_store), bucket_info(_bucket_info), | |
682 | ctx(_ctx), obj(_obj), bs(store), | |
683 | state(NULL), versioning_disabled(false), | |
20effc67 TL |
684 | bs_initialized(false), |
685 | pmeta_placement_rule(nullptr) {} | |
7c673cae FG |
686 | |
687 | RGWRados *get_store() { return store; } | |
688 | rgw_obj& get_obj() { return obj; } | |
689 | RGWObjectCtx& get_ctx() { return ctx; } | |
690 | RGWBucketInfo& get_bucket_info() { return bucket_info; } | |
b3b6e05e | 691 | int get_manifest(const DoutPrefixProvider *dpp, RGWObjManifest **pmanifest, optional_yield y); |
7c673cae | 692 | |
b3b6e05e | 693 | int get_bucket_shard(BucketShard **pbs, const DoutPrefixProvider *dpp) { |
7c673cae | 694 | if (!bs_initialized) { |
f64942e4 | 695 | int r = |
b3b6e05e | 696 | bs.init(bucket_info.bucket, obj, nullptr /* no RGWBucketInfo */, dpp); |
7c673cae FG |
697 | if (r < 0) { |
698 | return r; | |
699 | } | |
700 | bs_initialized = true; | |
701 | } | |
702 | *pbs = &bs; | |
703 | return 0; | |
704 | } | |
705 | ||
706 | void set_versioning_disabled(bool status) { | |
707 | versioning_disabled = status; | |
708 | } | |
709 | ||
710 | bool versioning_enabled() { | |
711 | return (!versioning_disabled && bucket_info.versioning_enabled()); | |
712 | } | |
713 | ||
20effc67 TL |
714 | void set_meta_placement_rule(const rgw_placement_rule *p) { |
715 | pmeta_placement_rule = p; | |
716 | } | |
717 | ||
718 | const rgw_placement_rule& get_meta_placement_rule() { | |
719 | return pmeta_placement_rule ? *pmeta_placement_rule : bucket_info.placement_rule; | |
720 | } | |
721 | ||
7c673cae FG |
722 | struct Read { |
723 | RGWRados::Object *source; | |
724 | ||
725 | struct GetObjState { | |
20effc67 | 726 | std::map<rgw_pool, librados::IoCtx> io_ctxs; |
11fdf7f2 TL |
727 | rgw_pool cur_pool; |
728 | librados::IoCtx *cur_ioctx{nullptr}; | |
7c673cae FG |
729 | rgw_obj obj; |
730 | rgw_raw_obj head_obj; | |
731 | } state; | |
732 | ||
733 | struct ConditionParams { | |
734 | const ceph::real_time *mod_ptr; | |
735 | const ceph::real_time *unmod_ptr; | |
736 | bool high_precision_time; | |
737 | uint32_t mod_zone_id; | |
738 | uint64_t mod_pg_ver; | |
739 | const char *if_match; | |
740 | const char *if_nomatch; | |
741 | ||
742 | ConditionParams() : | |
743 | mod_ptr(NULL), unmod_ptr(NULL), high_precision_time(false), mod_zone_id(0), mod_pg_ver(0), | |
744 | if_match(NULL), if_nomatch(NULL) {} | |
745 | } conds; | |
746 | ||
747 | struct Params { | |
748 | ceph::real_time *lastmod; | |
749 | uint64_t *obj_size; | |
20effc67 | 750 | std::map<std::string, bufferlist> *attrs; |
eafe8130 | 751 | rgw_obj *target_obj; |
7c673cae | 752 | |
eafe8130 TL |
753 | Params() : lastmod(nullptr), obj_size(nullptr), attrs(nullptr), |
754 | target_obj(nullptr) {} | |
7c673cae FG |
755 | } params; |
756 | ||
757 | explicit Read(RGWRados::Object *_source) : source(_source) {} | |
758 | ||
b3b6e05e | 759 | int prepare(optional_yield y, const DoutPrefixProvider *dpp); |
7c673cae | 760 | static int range_to_ofs(uint64_t obj_size, int64_t &ofs, int64_t &end); |
b3b6e05e TL |
761 | int read(int64_t ofs, int64_t end, bufferlist& bl, optional_yield y, const DoutPrefixProvider *dpp); |
762 | int iterate(const DoutPrefixProvider *dpp, int64_t ofs, int64_t end, RGWGetDataCB *cb, optional_yield y); | |
763 | int get_attr(const DoutPrefixProvider *dpp, const char *name, bufferlist& dest, optional_yield y); | |
7c673cae FG |
764 | }; |
765 | ||
766 | struct Write { | |
767 | RGWRados::Object *target; | |
768 | ||
769 | struct MetaParams { | |
770 | ceph::real_time *mtime; | |
20effc67 | 771 | std::map<std::string, bufferlist>* rmattrs; |
7c673cae FG |
772 | const bufferlist *data; |
773 | RGWObjManifest *manifest; | |
20effc67 TL |
774 | const std::string *ptag; |
775 | std::list<rgw_obj_index_key> *remove_objs; | |
7c673cae FG |
776 | ceph::real_time set_mtime; |
777 | rgw_user owner; | |
778 | RGWObjCategory category; | |
779 | int flags; | |
780 | const char *if_match; | |
781 | const char *if_nomatch; | |
11fdf7f2 | 782 | std::optional<uint64_t> olh_epoch; |
7c673cae FG |
783 | ceph::real_time delete_at; |
784 | bool canceled; | |
20effc67 | 785 | const std::string *user_data; |
31f18b77 | 786 | rgw_zone_set *zones_trace; |
181888fb | 787 | bool modify_tail; |
3efd9988 | 788 | bool completeMultipart; |
11fdf7f2 | 789 | bool appendable; |
7c673cae FG |
790 | |
791 | MetaParams() : mtime(NULL), rmattrs(NULL), data(NULL), manifest(NULL), ptag(NULL), | |
11fdf7f2 | 792 | remove_objs(NULL), category(RGWObjCategory::Main), flags(0), |
91327a77 | 793 | if_match(NULL), if_nomatch(NULL), canceled(false), user_data(nullptr), zones_trace(nullptr), |
11fdf7f2 | 794 | modify_tail(false), completeMultipart(false), appendable(false) {} |
7c673cae FG |
795 | } meta; |
796 | ||
797 | explicit Write(RGWRados::Object *_target) : target(_target) {} | |
798 | ||
20effc67 | 799 | int _do_write_meta(const DoutPrefixProvider *dpp, |
b3b6e05e | 800 | uint64_t size, uint64_t accounted_size, |
20effc67 | 801 | std::map<std::string, bufferlist>& attrs, |
181888fb | 802 | bool modify_tail, bool assume_noent, |
9f95a23c | 803 | void *index_op, optional_yield y); |
b3b6e05e | 804 | int write_meta(const DoutPrefixProvider *dpp, uint64_t size, uint64_t accounted_size, |
20effc67 | 805 | std::map<std::string, bufferlist>& attrs, optional_yield y); |
7c673cae | 806 | int write_data(const char *data, uint64_t ofs, uint64_t len, bool exclusive); |
11fdf7f2 TL |
807 | const req_state* get_req_state() { |
808 | return (req_state *)target->get_ctx().get_private(); | |
809 | } | |
7c673cae FG |
810 | }; |
811 | ||
812 | struct Delete { | |
813 | RGWRados::Object *target; | |
814 | ||
815 | struct DeleteParams { | |
816 | rgw_user bucket_owner; | |
20effc67 | 817 | int versioning_status; // versioning flags defined in enum RGWBucketFlags |
b3b6e05e | 818 | ACLOwner obj_owner; // needed for creation of deletion marker |
7c673cae | 819 | uint64_t olh_epoch; |
20effc67 | 820 | std::string marker_version_id; |
7c673cae | 821 | uint32_t bilog_flags; |
20effc67 | 822 | std::list<rgw_obj_index_key> *remove_objs; |
7c673cae FG |
823 | ceph::real_time expiration_time; |
824 | ceph::real_time unmod_since; | |
825 | ceph::real_time mtime; /* for setting delete marker mtime */ | |
826 | bool high_precision_time; | |
31f18b77 | 827 | rgw_zone_set *zones_trace; |
9f95a23c TL |
828 | bool abortmp; |
829 | uint64_t parts_accounted_size; | |
7c673cae | 830 | |
9f95a23c | 831 | DeleteParams() : versioning_status(0), olh_epoch(0), bilog_flags(0), remove_objs(NULL), high_precision_time(false), zones_trace(nullptr), abortmp(false), parts_accounted_size(0) {} |
7c673cae FG |
832 | } params; |
833 | ||
834 | struct DeleteResult { | |
835 | bool delete_marker; | |
20effc67 | 836 | std::string version_id; |
7c673cae FG |
837 | |
838 | DeleteResult() : delete_marker(false) {} | |
839 | } result; | |
840 | ||
841 | explicit Delete(RGWRados::Object *_target) : target(_target) {} | |
842 | ||
b3b6e05e | 843 | int delete_obj(optional_yield y, const DoutPrefixProvider *dpp); |
7c673cae FG |
844 | }; |
845 | ||
846 | struct Stat { | |
847 | RGWRados::Object *source; | |
848 | ||
849 | struct Result { | |
850 | rgw_obj obj; | |
9f95a23c TL |
851 | std::optional<RGWObjManifest> manifest; |
852 | uint64_t size{0}; | |
853 | struct timespec mtime {}; | |
20effc67 | 854 | std::map<std::string, bufferlist> attrs; |
7c673cae FG |
855 | } result; |
856 | ||
857 | struct State { | |
858 | librados::IoCtx io_ctx; | |
859 | librados::AioCompletion *completion; | |
860 | int ret; | |
861 | ||
862 | State() : completion(NULL), ret(0) {} | |
863 | } state; | |
864 | ||
865 | ||
866 | explicit Stat(RGWRados::Object *_source) : source(_source) {} | |
867 | ||
b3b6e05e | 868 | int stat_async(const DoutPrefixProvider *dpp); |
20effc67 | 869 | int wait(const DoutPrefixProvider *dpp); |
7c673cae FG |
870 | int stat(); |
871 | private: | |
20effc67 | 872 | int finish(const DoutPrefixProvider *dpp); |
7c673cae FG |
873 | }; |
874 | }; | |
875 | ||
876 | class Bucket { | |
877 | RGWRados *store; | |
878 | RGWBucketInfo bucket_info; | |
879 | rgw_bucket& bucket; | |
880 | int shard_id; | |
881 | ||
882 | public: | |
883 | Bucket(RGWRados *_store, const RGWBucketInfo& _bucket_info) : store(_store), bucket_info(_bucket_info), bucket(bucket_info.bucket), | |
884 | shard_id(RGW_NO_SHARD) {} | |
885 | RGWRados *get_store() { return store; } | |
886 | rgw_bucket& get_bucket() { return bucket; } | |
887 | RGWBucketInfo& get_bucket_info() { return bucket_info; } | |
888 | ||
20effc67 | 889 | int update_bucket_id(const std::string& new_bucket_id, const DoutPrefixProvider *dpp); |
31f18b77 | 890 | |
7c673cae FG |
891 | int get_shard_id() { return shard_id; } |
892 | void set_shard_id(int id) { | |
893 | shard_id = id; | |
894 | } | |
895 | ||
896 | class UpdateIndex { | |
897 | RGWRados::Bucket *target; | |
20effc67 | 898 | std::string optag; |
7c673cae FG |
899 | rgw_obj obj; |
900 | uint16_t bilog_flags{0}; | |
901 | BucketShard bs; | |
902 | bool bs_initialized{false}; | |
903 | bool blind; | |
904 | bool prepared{false}; | |
31f18b77 FG |
905 | rgw_zone_set *zones_trace{nullptr}; |
906 | ||
b3b6e05e | 907 | int init_bs(const DoutPrefixProvider *dpp) { |
f64942e4 | 908 | int r = |
b3b6e05e | 909 | bs.init(target->get_bucket(), obj, nullptr /* no RGWBucketInfo */, dpp); |
31f18b77 FG |
910 | if (r < 0) { |
911 | return r; | |
912 | } | |
913 | bs_initialized = true; | |
914 | return 0; | |
915 | } | |
916 | ||
917 | void invalidate_bs() { | |
918 | bs_initialized = false; | |
919 | } | |
920 | ||
b3b6e05e | 921 | int guard_reshard(const DoutPrefixProvider *dpp, BucketShard **pbs, std::function<int(BucketShard *)> call); |
7c673cae FG |
922 | public: |
923 | ||
924 | UpdateIndex(RGWRados::Bucket *_target, const rgw_obj& _obj) : target(_target), obj(_obj), | |
925 | bs(target->get_store()) { | |
f67539c2 | 926 | blind = (target->get_bucket_info().layout.current_index.layout.type == rgw::BucketIndexType::Indexless); |
7c673cae FG |
927 | } |
928 | ||
b3b6e05e | 929 | int get_bucket_shard(BucketShard **pbs, const DoutPrefixProvider *dpp) { |
7c673cae | 930 | if (!bs_initialized) { |
b3b6e05e | 931 | int r = init_bs(dpp); |
7c673cae FG |
932 | if (r < 0) { |
933 | return r; | |
934 | } | |
7c673cae FG |
935 | } |
936 | *pbs = &bs; | |
937 | return 0; | |
938 | } | |
939 | ||
940 | void set_bilog_flags(uint16_t flags) { | |
941 | bilog_flags = flags; | |
942 | } | |
31f18b77 FG |
943 | |
944 | void set_zones_trace(rgw_zone_set *_zones_trace) { | |
945 | zones_trace = _zones_trace; | |
946 | } | |
7c673cae | 947 | |
20effc67 | 948 | int prepare(const DoutPrefixProvider *dpp, RGWModifyOp, const std::string *write_tag, optional_yield y); |
b3b6e05e | 949 | int complete(const DoutPrefixProvider *dpp, int64_t poolid, uint64_t epoch, uint64_t size, |
7c673cae | 950 | uint64_t accounted_size, ceph::real_time& ut, |
20effc67 TL |
951 | const std::string& etag, const std::string& content_type, |
952 | const std::string& storage_class, | |
7c673cae | 953 | bufferlist *acl_bl, RGWObjCategory category, |
20effc67 TL |
954 | std::list<rgw_obj_index_key> *remove_objs, const std::string *user_data = nullptr, bool appendable = false); |
955 | int complete_del(const DoutPrefixProvider *dpp, | |
b3b6e05e | 956 | int64_t poolid, uint64_t epoch, |
7c673cae | 957 | ceph::real_time& removed_mtime, /* mtime of removed object */ |
20effc67 TL |
958 | std::list<rgw_obj_index_key> *remove_objs); |
959 | int cancel(const DoutPrefixProvider *dpp, | |
960 | std::list<rgw_obj_index_key> *remove_objs); | |
7c673cae | 961 | |
20effc67 | 962 | const std::string *get_optag() { return &optag; } |
7c673cae FG |
963 | |
964 | bool is_prepared() { return prepared; } | |
1adf2230 AA |
965 | }; // class UpdateIndex |
966 | ||
967 | class List { | |
968 | protected: | |
eafe8130 TL |
969 | // absolute maximum number of objects that |
970 | // list_objects_(un)ordered can return | |
971 | static constexpr int64_t bucket_list_objects_absolute_max = 25000; | |
7c673cae | 972 | |
7c673cae FG |
973 | RGWRados::Bucket *target; |
974 | rgw_obj_key next_marker; | |
975 | ||
20effc67 | 976 | int list_objects_ordered(const DoutPrefixProvider *dpp, |
b3b6e05e | 977 | int64_t max, |
20effc67 TL |
978 | std::vector<rgw_bucket_dir_entry> *result, |
979 | std::map<std::string, bool> *common_prefixes, | |
9f95a23c TL |
980 | bool *is_truncated, |
981 | optional_yield y); | |
20effc67 | 982 | int list_objects_unordered(const DoutPrefixProvider *dpp, |
b3b6e05e | 983 | int64_t max, |
20effc67 TL |
984 | std::vector<rgw_bucket_dir_entry> *result, |
985 | std::map<std::string, bool> *common_prefixes, | |
9f95a23c TL |
986 | bool *is_truncated, |
987 | optional_yield y); | |
1adf2230 AA |
988 | |
989 | public: | |
990 | ||
7c673cae | 991 | struct Params { |
20effc67 TL |
992 | std::string prefix; |
993 | std::string delim; | |
7c673cae FG |
994 | rgw_obj_key marker; |
995 | rgw_obj_key end_marker; | |
20effc67 | 996 | std::string ns; |
7c673cae | 997 | bool enforce_ns; |
20effc67 TL |
998 | RGWAccessListFilter* access_list_filter; |
999 | RGWBucketListNameFilter force_check_filter; | |
7c673cae | 1000 | bool list_versions; |
1adf2230 AA |
1001 | bool allow_unordered; |
1002 | ||
1003 | Params() : | |
1004 | enforce_ns(true), | |
20effc67 | 1005 | access_list_filter(nullptr), |
1adf2230 AA |
1006 | list_versions(false), |
1007 | allow_unordered(false) | |
1008 | {} | |
7c673cae FG |
1009 | } params; |
1010 | ||
7c673cae FG |
1011 | explicit List(RGWRados::Bucket *_target) : target(_target) {} |
1012 | ||
b3b6e05e | 1013 | int list_objects(const DoutPrefixProvider *dpp, int64_t max, |
20effc67 TL |
1014 | std::vector<rgw_bucket_dir_entry> *result, |
1015 | std::map<std::string, bool> *common_prefixes, | |
9f95a23c TL |
1016 | bool *is_truncated, |
1017 | optional_yield y) { | |
1adf2230 | 1018 | if (params.allow_unordered) { |
b3b6e05e | 1019 | return list_objects_unordered(dpp, max, result, common_prefixes, |
9f95a23c | 1020 | is_truncated, y); |
1adf2230 | 1021 | } else { |
b3b6e05e | 1022 | return list_objects_ordered(dpp, max, result, common_prefixes, |
9f95a23c | 1023 | is_truncated, y); |
1adf2230 AA |
1024 | } |
1025 | } | |
7c673cae FG |
1026 | rgw_obj_key& get_next_marker() { |
1027 | return next_marker; | |
1028 | } | |
1adf2230 AA |
1029 | }; // class List |
1030 | }; // class Bucket | |
7c673cae | 1031 | |
20effc67 | 1032 | int on_last_entry_in_listing(const DoutPrefixProvider *dpp, |
b3b6e05e | 1033 | RGWBucketInfo& bucket_info, |
7c673cae FG |
1034 | const std::string& obj_prefix, |
1035 | const std::string& obj_delim, | |
1036 | std::function<int(const rgw_bucket_dir_entry&)> handler); | |
1037 | ||
20effc67 | 1038 | bool swift_versioning_enabled(rgw::sal::Bucket* bucket) const; |
7c673cae FG |
1039 | |
1040 | int swift_versioning_copy(RGWObjectCtx& obj_ctx, /* in/out */ | |
1041 | const rgw_user& user, /* in */ | |
20effc67 TL |
1042 | rgw::sal::Bucket* bucket, /* in */ |
1043 | rgw::sal::Object* obj, /* in */ | |
9f95a23c TL |
1044 | const DoutPrefixProvider *dpp, /* in/out */ |
1045 | optional_yield y); /* in */ | |
1046 | int swift_versioning_restore(RGWObjectCtx& obj_ctx, /* in/out */ | |
7c673cae | 1047 | const rgw_user& user, /* in */ |
20effc67 TL |
1048 | rgw::sal::Bucket* bucket, /* in */ |
1049 | rgw::sal::Object* obj, /* in */ | |
9f95a23c TL |
1050 | bool& restored, /* out */ |
1051 | const DoutPrefixProvider *dpp); /* in/out */ | |
b3b6e05e TL |
1052 | int copy_obj_to_remote_dest(const DoutPrefixProvider *dpp, |
1053 | RGWObjState *astate, | |
20effc67 | 1054 | std::map<std::string, bufferlist>& src_attrs, |
7c673cae FG |
1055 | RGWRados::Object::Read& read_op, |
1056 | const rgw_user& user_id, | |
20effc67 | 1057 | rgw::sal::Object* dest_obj, |
7c673cae FG |
1058 | ceph::real_time *mtime); |
1059 | ||
1060 | enum AttrsMod { | |
1061 | ATTRSMOD_NONE = 0, | |
1062 | ATTRSMOD_REPLACE = 1, | |
1063 | ATTRSMOD_MERGE = 2 | |
1064 | }; | |
1065 | ||
20effc67 TL |
1066 | D3nDataCache* d3n_data_cache{nullptr}; |
1067 | ||
1068 | int rewrite_obj(rgw::sal::Object* obj, const DoutPrefixProvider *dpp, optional_yield y); | |
7c673cae | 1069 | |
b3b6e05e TL |
1070 | int stat_remote_obj(const DoutPrefixProvider *dpp, |
1071 | RGWObjectCtx& obj_ctx, | |
7c673cae | 1072 | const rgw_user& user_id, |
7c673cae | 1073 | req_info *info, |
9f95a23c | 1074 | const rgw_zone_id& source_zone, |
20effc67 | 1075 | rgw::sal::Object* src_obj, |
9f95a23c | 1076 | const RGWBucketInfo *src_bucket_info, |
7c673cae FG |
1077 | real_time *src_mtime, |
1078 | uint64_t *psize, | |
1079 | const real_time *mod_ptr, | |
1080 | const real_time *unmod_ptr, | |
1081 | bool high_precision_time, | |
1082 | const char *if_match, | |
1083 | const char *if_nomatch, | |
20effc67 TL |
1084 | std::map<std::string, bufferlist> *pattrs, |
1085 | std::map<std::string, std::string> *pheaders, | |
1086 | std::string *version_id, | |
1087 | std::string *ptag, | |
1088 | std::string *petag); | |
7c673cae FG |
1089 | |
1090 | int fetch_remote_obj(RGWObjectCtx& obj_ctx, | |
1091 | const rgw_user& user_id, | |
7c673cae | 1092 | req_info *info, |
9f95a23c | 1093 | const rgw_zone_id& source_zone, |
20effc67 TL |
1094 | rgw::sal::Object* dest_obj, |
1095 | rgw::sal::Object* src_obj, | |
1096 | rgw::sal::Bucket* dest_bucket, | |
1097 | rgw::sal::Bucket* src_bucket, | |
11fdf7f2 | 1098 | std::optional<rgw_placement_rule> dest_placement, |
7c673cae FG |
1099 | ceph::real_time *src_mtime, |
1100 | ceph::real_time *mtime, | |
1101 | const ceph::real_time *mod_ptr, | |
1102 | const ceph::real_time *unmod_ptr, | |
1103 | bool high_precision_time, | |
1104 | const char *if_match, | |
1105 | const char *if_nomatch, | |
1106 | AttrsMod attrs_mod, | |
1107 | bool copy_if_newer, | |
20effc67 | 1108 | rgw::sal::Attrs& attrs, |
7c673cae | 1109 | RGWObjCategory category, |
11fdf7f2 | 1110 | std::optional<uint64_t> olh_epoch, |
7c673cae | 1111 | ceph::real_time delete_at, |
20effc67 TL |
1112 | std::string *ptag, |
1113 | std::string *petag, | |
7c673cae | 1114 | void (*progress_cb)(off_t, void *), |
31f18b77 | 1115 | void *progress_data, |
9f95a23c TL |
1116 | const DoutPrefixProvider *dpp, |
1117 | RGWFetchObjFilter *filter, | |
81eedcae TL |
1118 | rgw_zone_set *zones_trace= nullptr, |
1119 | std::optional<uint64_t>* bytes_transferred = 0); | |
7c673cae FG |
1120 | /** |
1121 | * Copy an object. | |
1122 | * dest_obj: the object to copy into | |
1123 | * src_obj: the object to copy from | |
1124 | * attrs: usage depends on attrs_mod parameter | |
1125 | * attrs_mod: the modification mode of the attrs, may have the following values: | |
1126 | * ATTRSMOD_NONE - the attributes of the source object will be | |
1127 | * copied without modifications, attrs parameter is ignored; | |
1128 | * ATTRSMOD_REPLACE - new object will have the attributes provided by attrs | |
1129 | * parameter, source object attributes are not copied; | |
1130 | * ATTRSMOD_MERGE - any conflicting meta keys on the source object's attributes | |
1131 | * are overwritten by values contained in attrs parameter. | |
7c673cae FG |
1132 | * Returns: 0 on success, -ERR# otherwise. |
1133 | */ | |
1134 | int copy_obj(RGWObjectCtx& obj_ctx, | |
1135 | const rgw_user& user_id, | |
7c673cae | 1136 | req_info *info, |
9f95a23c | 1137 | const rgw_zone_id& source_zone, |
20effc67 TL |
1138 | rgw::sal::Object* dest_obj, |
1139 | rgw::sal::Object* src_obj, | |
1140 | rgw::sal::Bucket* dest_bucket, | |
1141 | rgw::sal::Bucket* src_bucket, | |
11fdf7f2 | 1142 | const rgw_placement_rule& dest_placement, |
7c673cae FG |
1143 | ceph::real_time *src_mtime, |
1144 | ceph::real_time *mtime, | |
1145 | const ceph::real_time *mod_ptr, | |
1146 | const ceph::real_time *unmod_ptr, | |
1147 | bool high_precision_time, | |
1148 | const char *if_match, | |
1149 | const char *if_nomatch, | |
1150 | AttrsMod attrs_mod, | |
1151 | bool copy_if_newer, | |
20effc67 | 1152 | std::map<std::string, bufferlist>& attrs, |
7c673cae FG |
1153 | RGWObjCategory category, |
1154 | uint64_t olh_epoch, | |
1155 | ceph::real_time delete_at, | |
20effc67 TL |
1156 | std::string *version_id, |
1157 | std::string *ptag, | |
1158 | std::string *petag, | |
7c673cae | 1159 | void (*progress_cb)(off_t, void *), |
9f95a23c TL |
1160 | void *progress_data, |
1161 | const DoutPrefixProvider *dpp, | |
1162 | optional_yield y); | |
7c673cae FG |
1163 | |
1164 | int copy_obj_data(RGWObjectCtx& obj_ctx, | |
20effc67 | 1165 | rgw::sal::Bucket* bucket, |
11fdf7f2 | 1166 | const rgw_placement_rule& dest_placement, |
7c673cae | 1167 | RGWRados::Object::Read& read_op, off_t end, |
20effc67 | 1168 | rgw::sal::Object* dest_obj, |
7c673cae FG |
1169 | ceph::real_time *mtime, |
1170 | ceph::real_time set_mtime, | |
20effc67 | 1171 | std::map<std::string, bufferlist>& attrs, |
7c673cae FG |
1172 | uint64_t olh_epoch, |
1173 | ceph::real_time delete_at, | |
20effc67 | 1174 | std::string *petag, |
9f95a23c TL |
1175 | const DoutPrefixProvider *dpp, |
1176 | optional_yield y); | |
7c673cae | 1177 | |
11fdf7f2 | 1178 | int transition_obj(RGWObjectCtx& obj_ctx, |
20effc67 TL |
1179 | rgw::sal::Bucket* bucket, |
1180 | rgw::sal::Object& obj, | |
11fdf7f2 TL |
1181 | const rgw_placement_rule& placement_rule, |
1182 | const real_time& mtime, | |
9f95a23c TL |
1183 | uint64_t olh_epoch, |
1184 | const DoutPrefixProvider *dpp, | |
1185 | optional_yield y); | |
11fdf7f2 | 1186 | |
b3b6e05e | 1187 | int check_bucket_empty(const DoutPrefixProvider *dpp, RGWBucketInfo& bucket_info, optional_yield y); |
7c673cae FG |
1188 | |
1189 | /** | |
1190 | * Delete a bucket. | |
1191 | * bucket: the name of the bucket to delete | |
1192 | * Returns 0 on success, -ERR# otherwise. | |
1193 | */ | |
b3b6e05e | 1194 | int delete_bucket(RGWBucketInfo& bucket_info, RGWObjVersionTracker& objv_tracker, optional_yield y, const DoutPrefixProvider *dpp, bool check_empty = true); |
7c673cae | 1195 | |
20effc67 TL |
1196 | void wakeup_meta_sync_shards(std::set<int>& shard_ids); |
1197 | void wakeup_data_sync_shards(const DoutPrefixProvider *dpp, | |
1198 | const rgw_zone_id& source_zone, | |
1199 | std::map<int, std::set<std::string> >& shard_ids); | |
7c673cae FG |
1200 | |
1201 | RGWMetaSyncStatusManager* get_meta_sync_manager(); | |
9f95a23c | 1202 | RGWDataSyncStatusManager* get_data_sync_manager(const rgw_zone_id& source_zone); |
7c673cae | 1203 | |
b3b6e05e TL |
1204 | int set_bucket_owner(rgw_bucket& bucket, ACLOwner& owner, const DoutPrefixProvider *dpp); |
1205 | int set_buckets_enabled(std::vector<rgw_bucket>& buckets, bool enabled, const DoutPrefixProvider *dpp); | |
1206 | int bucket_suspended(const DoutPrefixProvider *dpp, rgw_bucket& bucket, bool *suspended); | |
7c673cae FG |
1207 | |
1208 | /** Delete an object.*/ | |
b3b6e05e TL |
1209 | int delete_obj(const DoutPrefixProvider *dpp, |
1210 | RGWObjectCtx& obj_ctx, | |
f67539c2 TL |
1211 | const RGWBucketInfo& bucket_owner, |
1212 | const rgw_obj& src_obj, | |
20effc67 | 1213 | int versioning_status, // versioning flags defined in enum RGWBucketFlags |
f67539c2 TL |
1214 | uint16_t bilog_flags = 0, |
1215 | const ceph::real_time& expiration_time = ceph::real_time(), | |
1216 | rgw_zone_set *zones_trace = nullptr); | |
7c673cae | 1217 | |
b3b6e05e | 1218 | int delete_raw_obj(const DoutPrefixProvider *dpp, const rgw_raw_obj& obj); |
7c673cae | 1219 | |
7c673cae | 1220 | /** Remove an object from the bucket index */ |
b3b6e05e | 1221 | int delete_obj_index(const rgw_obj& obj, ceph::real_time mtime, const DoutPrefixProvider *dpp); |
7c673cae | 1222 | |
7c673cae FG |
1223 | /** |
1224 | * Set an attr on an object. | |
1225 | * bucket: name of the bucket holding the object | |
1226 | * obj: name of the object to set the attr on | |
1227 | * name: the attr to set | |
1228 | * bl: the contents of the attr | |
1229 | * Returns: 0 on success, -ERR# otherwise. | |
1230 | */ | |
b3b6e05e | 1231 | int set_attr(const DoutPrefixProvider *dpp, void *ctx, const RGWBucketInfo& bucket_info, rgw_obj& obj, const char *name, bufferlist& bl); |
7c673cae | 1232 | |
b3b6e05e | 1233 | int set_attrs(const DoutPrefixProvider *dpp, void *ctx, const RGWBucketInfo& bucket_info, rgw_obj& obj, |
20effc67 TL |
1234 | std::map<std::string, bufferlist>& attrs, |
1235 | std::map<std::string, bufferlist>* rmattrs, | |
9f95a23c | 1236 | optional_yield y); |
7c673cae | 1237 | |
b3b6e05e | 1238 | int get_obj_state(const DoutPrefixProvider *dpp, RGWObjectCtx *rctx, const RGWBucketInfo& bucket_info, const rgw_obj& obj, RGWObjState **state, |
9f95a23c | 1239 | bool follow_olh, optional_yield y, bool assume_noent = false); |
b3b6e05e TL |
1240 | int get_obj_state(const DoutPrefixProvider *dpp, RGWObjectCtx *rctx, const RGWBucketInfo& bucket_info, const rgw_obj& obj, RGWObjState **state, optional_yield y) { |
1241 | return get_obj_state(dpp, rctx, bucket_info, obj, state, true, y); | |
7c673cae FG |
1242 | } |
1243 | ||
b3b6e05e | 1244 | using iterate_obj_cb = int (*)(const DoutPrefixProvider*, const rgw_raw_obj&, off_t, off_t, |
11fdf7f2 TL |
1245 | off_t, bool, RGWObjState*, void*); |
1246 | ||
b3b6e05e | 1247 | int iterate_obj(const DoutPrefixProvider *dpp, RGWObjectCtx& ctx, const RGWBucketInfo& bucket_info, |
11fdf7f2 | 1248 | const rgw_obj& obj, off_t ofs, off_t end, |
9f95a23c TL |
1249 | uint64_t max_chunk_size, iterate_obj_cb cb, void *arg, |
1250 | optional_yield y); | |
7c673cae | 1251 | |
20effc67 TL |
1252 | int append_atomic_test(const DoutPrefixProvider *dpp, const RGWObjState* astate, librados::ObjectOperation& op); |
1253 | ||
1254 | virtual int get_obj_iterate_cb(const DoutPrefixProvider *dpp, | |
b3b6e05e | 1255 | const rgw_raw_obj& read_obj, off_t obj_ofs, |
11fdf7f2 TL |
1256 | off_t read_ofs, off_t len, bool is_head_obj, |
1257 | RGWObjState *astate, void *arg); | |
7c673cae | 1258 | |
7c673cae FG |
1259 | /** |
1260 | * a simple object read without keeping state | |
1261 | */ | |
1262 | ||
20effc67 | 1263 | int raw_obj_stat(const DoutPrefixProvider *dpp, |
b3b6e05e | 1264 | rgw_raw_obj& obj, uint64_t *psize, ceph::real_time *pmtime, uint64_t *epoch, |
20effc67 | 1265 | std::map<std::string, bufferlist> *attrs, bufferlist *first_chunk, |
9f95a23c | 1266 | RGWObjVersionTracker *objv_tracker, optional_yield y); |
7c673cae | 1267 | |
b3b6e05e TL |
1268 | int obj_operate(const DoutPrefixProvider *dpp, const RGWBucketInfo& bucket_info, const rgw_obj& obj, librados::ObjectWriteOperation *op); |
1269 | int obj_operate(const DoutPrefixProvider *dpp, const RGWBucketInfo& bucket_info, const rgw_obj& obj, librados::ObjectReadOperation *op); | |
7c673cae | 1270 | |
39ae355f TL |
1271 | int fetch_new_bucket_id(const RGWBucketInfo& curr_bucket_info, |
1272 | RGWBucketInfo* save_bucket_info, | |
1273 | std::string& new_bucket_id, | |
1274 | const DoutPrefixProvider* dpp); | |
20effc67 | 1275 | int guard_reshard(const DoutPrefixProvider *dpp, |
b3b6e05e | 1276 | BucketShard *bs, |
f64942e4 AA |
1277 | const rgw_obj& obj_instance, |
1278 | const RGWBucketInfo& bucket_info, | |
1279 | std::function<int(BucketShard *)> call); | |
1280 | int block_while_resharding(RGWRados::BucketShard *bs, | |
20effc67 | 1281 | std::string *new_bucket_id, |
11fdf7f2 | 1282 | const RGWBucketInfo& bucket_info, |
b3b6e05e TL |
1283 | optional_yield y, |
1284 | const DoutPrefixProvider *dpp); | |
1285 | ||
1286 | void bucket_index_guard_olh_op(const DoutPrefixProvider *dpp, RGWObjState& olh_state, librados::ObjectOperation& op); | |
20effc67 TL |
1287 | int olh_init_modification(const DoutPrefixProvider *dpp, const RGWBucketInfo& bucket_info, RGWObjState& state, const rgw_obj& olh_obj, std::string *op_tag); |
1288 | int olh_init_modification_impl(const DoutPrefixProvider *dpp, const RGWBucketInfo& bucket_info, RGWObjState& state, const rgw_obj& olh_obj, std::string *op_tag); | |
1289 | int bucket_index_link_olh(const DoutPrefixProvider *dpp, | |
b3b6e05e | 1290 | const RGWBucketInfo& bucket_info, RGWObjState& olh_state, |
7c673cae | 1291 | const rgw_obj& obj_instance, bool delete_marker, |
20effc67 | 1292 | const std::string& op_tag, struct rgw_bucket_dir_entry_meta *meta, |
7c673cae | 1293 | uint64_t olh_epoch, |
91327a77 AA |
1294 | ceph::real_time unmod_since, bool high_precision_time, |
1295 | rgw_zone_set *zones_trace = nullptr, | |
1296 | bool log_data_change = false); | |
20effc67 | 1297 | int bucket_index_unlink_instance(const DoutPrefixProvider *dpp, const RGWBucketInfo& bucket_info, const rgw_obj& obj_instance, const std::string& op_tag, const std::string& olh_tag, uint64_t olh_epoch, rgw_zone_set *zones_trace = nullptr); |
b3b6e05e | 1298 | int bucket_index_read_olh_log(const DoutPrefixProvider *dpp, const RGWBucketInfo& bucket_info, RGWObjState& state, const rgw_obj& obj_instance, uint64_t ver_marker, |
20effc67 | 1299 | std::map<uint64_t, std::vector<rgw_bucket_olh_log_entry> > *log, bool *is_truncated); |
b3b6e05e TL |
1300 | int bucket_index_trim_olh_log(const DoutPrefixProvider *dpp, const RGWBucketInfo& bucket_info, RGWObjState& obj_state, const rgw_obj& obj_instance, uint64_t ver); |
1301 | int bucket_index_clear_olh(const DoutPrefixProvider *dpp, const RGWBucketInfo& bucket_info, RGWObjState& state, const rgw_obj& obj_instance); | |
1302 | int apply_olh_log(const DoutPrefixProvider *dpp, RGWObjectCtx& ctx, RGWObjState& obj_state, const RGWBucketInfo& bucket_info, const rgw_obj& obj, | |
20effc67 | 1303 | bufferlist& obj_tag, std::map<uint64_t, std::vector<rgw_bucket_olh_log_entry> >& log, |
31f18b77 | 1304 | uint64_t *plast_ver, rgw_zone_set *zones_trace = nullptr); |
b3b6e05e TL |
1305 | int update_olh(const DoutPrefixProvider *dpp, RGWObjectCtx& obj_ctx, RGWObjState *state, const RGWBucketInfo& bucket_info, const rgw_obj& obj, rgw_zone_set *zones_trace = nullptr); |
1306 | int set_olh(const DoutPrefixProvider *dpp, RGWObjectCtx& obj_ctx, const RGWBucketInfo& bucket_info, const rgw_obj& target_obj, bool delete_marker, rgw_bucket_dir_entry_meta *meta, | |
91327a77 | 1307 | uint64_t olh_epoch, ceph::real_time unmod_since, bool high_precision_time, |
9f95a23c | 1308 | optional_yield y, rgw_zone_set *zones_trace = nullptr, bool log_data_change = false); |
b3b6e05e | 1309 | int repair_olh(const DoutPrefixProvider *dpp, RGWObjState* state, const RGWBucketInfo& bucket_info, |
a8e16298 | 1310 | const rgw_obj& obj); |
b3b6e05e | 1311 | int unlink_obj_instance(const DoutPrefixProvider *dpp, RGWObjectCtx& obj_ctx, RGWBucketInfo& bucket_info, const rgw_obj& target_obj, |
9f95a23c | 1312 | uint64_t olh_epoch, optional_yield y, rgw_zone_set *zones_trace = nullptr); |
7c673cae | 1313 | |
20effc67 TL |
1314 | void check_pending_olh_entries(const DoutPrefixProvider *dpp, std::map<std::string, bufferlist>& pending_entries, std::map<std::string, bufferlist> *rm_pending_entries); |
1315 | int remove_olh_pending_entries(const DoutPrefixProvider *dpp, const RGWBucketInfo& bucket_info, RGWObjState& state, const rgw_obj& olh_obj, std::map<std::string, bufferlist>& pending_attrs); | |
b3b6e05e TL |
1316 | int follow_olh(const DoutPrefixProvider *dpp, const RGWBucketInfo& bucket_info, RGWObjectCtx& ctx, RGWObjState *state, const rgw_obj& olh_obj, rgw_obj *target); |
1317 | int get_olh(const DoutPrefixProvider *dpp, const RGWBucketInfo& bucket_info, const rgw_obj& obj, RGWOLHInfo *olh); | |
7c673cae | 1318 | |
11fdf7f2 | 1319 | void gen_rand_obj_instance_name(rgw_obj_key *target_key); |
7c673cae FG |
1320 | void gen_rand_obj_instance_name(rgw_obj *target); |
1321 | ||
20effc67 | 1322 | int update_containers_stats(std::map<std::string, RGWBucketEnt>& m, const DoutPrefixProvider *dpp); |
b3b6e05e | 1323 | int append_async(const DoutPrefixProvider *dpp, rgw_raw_obj& obj, size_t size, bufferlist& bl); |
7c673cae | 1324 | |
11fdf7f2 | 1325 | public: |
7c673cae FG |
1326 | void set_atomic(void *ctx, rgw_obj& obj) { |
1327 | RGWObjectCtx *rctx = static_cast<RGWObjectCtx *>(ctx); | |
11fdf7f2 | 1328 | rctx->set_atomic(obj); |
7c673cae | 1329 | } |
11fdf7f2 | 1330 | void set_prefetch_data(void *ctx, const rgw_obj& obj) { |
7c673cae | 1331 | RGWObjectCtx *rctx = static_cast<RGWObjectCtx *>(ctx); |
11fdf7f2 | 1332 | rctx->set_prefetch_data(obj); |
7c673cae | 1333 | } |
20effc67 TL |
1334 | void set_compressed(void *ctx, const rgw_obj& obj) { |
1335 | RGWObjectCtx *rctx = static_cast<RGWObjectCtx *>(ctx); | |
1336 | rctx->set_compressed(obj); | |
1337 | } | |
1338 | int decode_policy(const DoutPrefixProvider *dpp, bufferlist& bl, ACLOwner *owner); | |
1339 | int get_bucket_stats(const DoutPrefixProvider *dpp, RGWBucketInfo& bucket_info, int shard_id, std::string *bucket_ver, std::string *master_ver, | |
1340 | std::map<RGWObjCategory, RGWStorageStats>& stats, std::string *max_marker, bool* syncstopped = NULL); | |
b3b6e05e | 1341 | int get_bucket_stats_async(const DoutPrefixProvider *dpp, RGWBucketInfo& bucket_info, int shard_id, RGWGetBucketStats_CB *cb); |
3a9019d9 | 1342 | |
20effc67 | 1343 | int put_bucket_instance_info(RGWBucketInfo& info, bool exclusive, ceph::real_time mtime, std::map<std::string, bufferlist> *pattrs, const DoutPrefixProvider *dpp); |
9f95a23c | 1344 | /* xxx dang obj_ctx -> svc */ |
20effc67 TL |
1345 | int get_bucket_instance_info(RGWSysObjectCtx& obj_ctx, const std::string& meta_key, RGWBucketInfo& info, ceph::real_time *pmtime, std::map<std::string, bufferlist> *pattrs, optional_yield y, const DoutPrefixProvider *dpp); |
1346 | int get_bucket_instance_info(RGWSysObjectCtx& obj_ctx, const rgw_bucket& bucket, RGWBucketInfo& info, ceph::real_time *pmtime, std::map<std::string, bufferlist> *pattrs, optional_yield y, const DoutPrefixProvider *dpp); | |
3a9019d9 | 1347 | |
20effc67 | 1348 | static void make_bucket_entry_name(const std::string& tenant_name, const std::string& bucket_name, std::string& bucket_entry); |
b32b8144 | 1349 | |
9f95a23c | 1350 | int get_bucket_info(RGWServices *svc, |
20effc67 | 1351 | const std::string& tenant_name, const std::string& bucket_name, |
b32b8144 | 1352 | RGWBucketInfo& info, |
b3b6e05e | 1353 | ceph::real_time *pmtime, optional_yield y, |
20effc67 | 1354 | const DoutPrefixProvider *dpp, std::map<std::string, bufferlist> *pattrs = NULL); |
b32b8144 | 1355 | |
81eedcae TL |
1356 | // Returns 0 on successful refresh. Returns error code if there was |
1357 | // an error or the version stored on the OSD is the same as that | |
b32b8144 FG |
1358 | // presented in the BucketInfo structure. |
1359 | // | |
1360 | int try_refresh_bucket_info(RGWBucketInfo& info, | |
1361 | ceph::real_time *pmtime, | |
b3b6e05e | 1362 | const DoutPrefixProvider *dpp, |
20effc67 | 1363 | std::map<std::string, bufferlist> *pattrs = nullptr); |
b32b8144 | 1364 | |
7c673cae | 1365 | int put_linked_bucket_info(RGWBucketInfo& info, bool exclusive, ceph::real_time mtime, obj_version *pep_objv, |
20effc67 | 1366 | std::map<std::string, bufferlist> *pattrs, bool create_entry_point, |
b3b6e05e | 1367 | const DoutPrefixProvider *dpp); |
7c673cae | 1368 | |
20effc67 TL |
1369 | int cls_obj_prepare_op(const DoutPrefixProvider *dpp, BucketShard& bs, RGWModifyOp op, std::string& tag, rgw_obj& obj, uint16_t bilog_flags, optional_yield y, rgw_zone_set *zones_trace = nullptr); |
1370 | int cls_obj_complete_op(BucketShard& bs, const rgw_obj& obj, RGWModifyOp op, std::string& tag, int64_t pool, uint64_t epoch, | |
1371 | rgw_bucket_dir_entry& ent, RGWObjCategory category, std::list<rgw_obj_index_key> *remove_objs, uint16_t bilog_flags, rgw_zone_set *zones_trace = nullptr); | |
1372 | int cls_obj_complete_add(BucketShard& bs, const rgw_obj& obj, std::string& tag, int64_t pool, uint64_t epoch, rgw_bucket_dir_entry& ent, | |
1373 | RGWObjCategory category, std::list<rgw_obj_index_key> *remove_objs, uint16_t bilog_flags, rgw_zone_set *zones_trace = nullptr); | |
1374 | int cls_obj_complete_del(BucketShard& bs, std::string& tag, int64_t pool, uint64_t epoch, rgw_obj& obj, | |
1375 | ceph::real_time& removed_mtime, std::list<rgw_obj_index_key> *remove_objs, uint16_t bilog_flags, rgw_zone_set *zones_trace = nullptr); | |
1376 | int cls_obj_complete_cancel(BucketShard& bs, std::string& tag, rgw_obj& obj, | |
1377 | std::list<rgw_obj_index_key> *remove_objs, | |
1378 | uint16_t bilog_flags, rgw_zone_set *zones_trace = nullptr); | |
b3b6e05e | 1379 | int cls_obj_set_bucket_tag_timeout(const DoutPrefixProvider *dpp, RGWBucketInfo& bucket_info, uint64_t timeout); |
9f95a23c TL |
1380 | |
1381 | using ent_map_t = | |
1382 | boost::container::flat_map<std::string, rgw_bucket_dir_entry>; | |
1383 | ||
b3b6e05e TL |
1384 | int cls_bucket_list_ordered(const DoutPrefixProvider *dpp, |
1385 | RGWBucketInfo& bucket_info, | |
9f95a23c TL |
1386 | const int shard_id, |
1387 | const rgw_obj_index_key& start_after, | |
20effc67 TL |
1388 | const std::string& prefix, |
1389 | const std::string& delimiter, | |
9f95a23c TL |
1390 | const uint32_t num_entries, |
1391 | const bool list_versions, | |
1392 | const uint16_t exp_factor, // 0 means ignore | |
1393 | ent_map_t& m, | |
1394 | bool* is_truncated, | |
1395 | bool* cls_filtered, | |
1adf2230 | 1396 | rgw_obj_index_key *last_entry, |
9f95a23c | 1397 | optional_yield y, |
20effc67 | 1398 | RGWBucketListNameFilter force_check_filter = {}); |
b3b6e05e TL |
1399 | int cls_bucket_list_unordered(const DoutPrefixProvider *dpp, |
1400 | RGWBucketInfo& bucket_info, | |
9f95a23c TL |
1401 | int shard_id, |
1402 | const rgw_obj_index_key& start_after, | |
20effc67 | 1403 | const std::string& prefix, |
9f95a23c TL |
1404 | uint32_t num_entries, |
1405 | bool list_versions, | |
20effc67 | 1406 | std::vector<rgw_bucket_dir_entry>& ent_list, |
9f95a23c TL |
1407 | bool *is_truncated, |
1408 | rgw_obj_index_key *last_entry, | |
1409 | optional_yield y, | |
20effc67 TL |
1410 | RGWBucketListNameFilter force_check_filter = {}); |
1411 | int cls_bucket_head(const DoutPrefixProvider *dpp, | |
1412 | const RGWBucketInfo& bucket_info, | |
1413 | int shard_id, | |
1414 | std::vector<rgw_bucket_dir_header>& headers, | |
1415 | std::map<int, std::string> *bucket_instance_ids = NULL); | |
b3b6e05e | 1416 | int cls_bucket_head_async(const DoutPrefixProvider *dpp, const RGWBucketInfo& bucket_info, int shard_id, RGWGetDirHeader_CB *ctx, int *num_aio); |
7c673cae | 1417 | |
b3b6e05e TL |
1418 | int bi_get_instance(const DoutPrefixProvider *dpp, const RGWBucketInfo& bucket_info, const rgw_obj& obj, rgw_bucket_dir_entry *dirent); |
1419 | int bi_get_olh(const DoutPrefixProvider *dpp, const RGWBucketInfo& bucket_info, const rgw_obj& obj, rgw_bucket_olh_entry *olh); | |
1420 | int bi_get(const DoutPrefixProvider *dpp, const RGWBucketInfo& bucket_info, const rgw_obj& obj, BIIndexType index_type, rgw_cls_bi_entry *entry); | |
7c673cae FG |
1421 | void bi_put(librados::ObjectWriteOperation& op, BucketShard& bs, rgw_cls_bi_entry& entry); |
1422 | int bi_put(BucketShard& bs, rgw_cls_bi_entry& entry); | |
b3b6e05e | 1423 | int bi_put(const DoutPrefixProvider *dpp, rgw_bucket& bucket, rgw_obj& obj, rgw_cls_bi_entry& entry); |
20effc67 TL |
1424 | int bi_list(const DoutPrefixProvider *dpp, |
1425 | const RGWBucketInfo& bucket_info, | |
1426 | int shard_id, | |
1427 | const std::string& filter_obj, | |
1428 | const std::string& marker, | |
1429 | uint32_t max, | |
1430 | std::list<rgw_cls_bi_entry> *entries, | |
1431 | bool *is_truncated); | |
1432 | int bi_list(BucketShard& bs, const std::string& filter_obj, const std::string& marker, uint32_t max, std::list<rgw_cls_bi_entry> *entries, bool *is_truncated); | |
1433 | int bi_list(const DoutPrefixProvider *dpp, rgw_bucket& bucket, const std::string& obj_name, const std::string& marker, uint32_t max, | |
1434 | std::list<rgw_cls_bi_entry> *entries, bool *is_truncated); | |
1435 | int bi_remove(const DoutPrefixProvider *dpp, BucketShard& bs); | |
1436 | ||
1437 | int cls_obj_usage_log_add(const DoutPrefixProvider *dpp, const std::string& oid, rgw_usage_log_info& info); | |
1438 | int cls_obj_usage_log_read(const DoutPrefixProvider *dpp, const std::string& oid, const std::string& user, const std::string& bucket, uint64_t start_epoch, | |
1439 | uint64_t end_epoch, uint32_t max_entries, std::string& read_iter, | |
1440 | std::map<rgw_user_bucket, rgw_usage_log_entry>& usage, bool *is_truncated); | |
1441 | int cls_obj_usage_log_trim(const DoutPrefixProvider *dpp, const std::string& oid, const std::string& user, const std::string& bucket, uint64_t start_epoch, | |
11fdf7f2 | 1442 | uint64_t end_epoch); |
20effc67 | 1443 | int cls_obj_usage_log_clear(const DoutPrefixProvider *dpp, std::string& oid); |
7c673cae | 1444 | |
20effc67 | 1445 | int get_target_shard_id(const rgw::bucket_index_normal_layout& layout, const std::string& obj_key, int *shard_id); |
9f95a23c | 1446 | |
20effc67 TL |
1447 | int lock_exclusive(const rgw_pool& pool, const std::string& oid, ceph::timespan& duration, rgw_zone_id& zone_id, std::string& owner_id); |
1448 | int unlock(const rgw_pool& pool, const std::string& oid, rgw_zone_id& zone_id, std::string& owner_id); | |
7c673cae | 1449 | |
b3b6e05e | 1450 | void update_gc_chain(const DoutPrefixProvider *dpp, rgw_obj& head_obj, RGWObjManifest& manifest, cls_rgw_obj_chain *chain); |
39ae355f | 1451 | std::tuple<int, std::optional<cls_rgw_obj_chain>> send_chain_to_gc(cls_rgw_obj_chain& chain, const std::string& tag); |
20effc67 TL |
1452 | void delete_objs_inline(const DoutPrefixProvider *dpp, cls_rgw_obj_chain& chain, const std::string& tag); |
1453 | int gc_operate(const DoutPrefixProvider *dpp, std::string& oid, librados::ObjectWriteOperation *op); | |
9f95a23c TL |
1454 | int gc_aio_operate(const std::string& oid, librados::AioCompletion *c, |
1455 | librados::ObjectWriteOperation *op); | |
20effc67 | 1456 | int gc_operate(const DoutPrefixProvider *dpp, std::string& oid, librados::ObjectReadOperation *op, bufferlist *pbl); |
7c673cae | 1457 | |
20effc67 | 1458 | int list_gc_objs(int *index, std::string& marker, uint32_t max, bool expired_only, std::list<cls_rgw_gc_obj_info>& result, bool *truncated, bool& processing_queue); |
11fdf7f2 | 1459 | int process_gc(bool expired_only); |
b3b6e05e TL |
1460 | bool process_expire_objects(const DoutPrefixProvider *dpp); |
1461 | int defer_gc(const DoutPrefixProvider *dpp, void *ctx, const RGWBucketInfo& bucket_info, const rgw_obj& obj, optional_yield y); | |
7c673cae | 1462 | |
20effc67 TL |
1463 | int process_lc(const std::unique_ptr<rgw::sal::Bucket>& optional_bucket); |
1464 | int list_lc_progress(std::string& marker, uint32_t max_entries, | |
1465 | std::vector<rgw::sal::Lifecycle::LCEntry>& progress_map, int& index); | |
f6b5b4d7 | 1466 | |
b3b6e05e | 1467 | int bucket_check_index(const DoutPrefixProvider *dpp, RGWBucketInfo& bucket_info, |
20effc67 TL |
1468 | std::map<RGWObjCategory, RGWStorageStats> *existing_stats, |
1469 | std::map<RGWObjCategory, RGWStorageStats> *calculated_stats); | |
b3b6e05e TL |
1470 | int bucket_rebuild_index(const DoutPrefixProvider *dpp, RGWBucketInfo& bucket_info); |
1471 | int bucket_set_reshard(const DoutPrefixProvider *dpp, const RGWBucketInfo& bucket_info, const cls_rgw_bucket_instance_entry& entry); | |
20effc67 TL |
1472 | int remove_objs_from_index(const DoutPrefixProvider *dpp, RGWBucketInfo& bucket_info, std::list<rgw_obj_index_key>& oid_list); |
1473 | int move_rados_obj(const DoutPrefixProvider *dpp, | |
b3b6e05e | 1474 | librados::IoCtx& src_ioctx, |
20effc67 | 1475 | const std::string& src_oid, const std::string& src_locator, |
7c673cae | 1476 | librados::IoCtx& dst_ioctx, |
20effc67 | 1477 | const std::string& dst_oid, const std::string& dst_locator); |
b3b6e05e TL |
1478 | int fix_head_obj_locator(const DoutPrefixProvider *dpp, const RGWBucketInfo& bucket_info, bool copy_obj, bool remove_bad, rgw_obj_key& key); |
1479 | int fix_tail_obj_locator(const DoutPrefixProvider *dpp, const RGWBucketInfo& bucket_info, rgw_obj_key& key, bool fix, bool *need_fix, optional_yield y); | |
7c673cae | 1480 | |
20effc67 | 1481 | int check_quota(const DoutPrefixProvider *dpp, const rgw_user& bucket_owner, rgw_bucket& bucket, |
f67539c2 TL |
1482 | RGWQuotaInfo& user_quota, RGWQuotaInfo& bucket_quota, uint64_t obj_size, |
1483 | optional_yield y, bool check_size_only = false); | |
7c673cae | 1484 | |
224ce89b | 1485 | int check_bucket_shards(const RGWBucketInfo& bucket_info, const rgw_bucket& bucket, |
b3b6e05e | 1486 | uint64_t num_objs, const DoutPrefixProvider *dpp); |
31f18b77 | 1487 | |
b3b6e05e | 1488 | int add_bucket_to_reshard(const DoutPrefixProvider *dpp, const RGWBucketInfo& bucket_info, uint32_t new_num_shards); |
31f18b77 | 1489 | |
7c673cae | 1490 | uint64_t instance_id(); |
3efd9988 | 1491 | |
7c673cae FG |
1492 | librados::Rados* get_rados_handle(); |
1493 | ||
20effc67 | 1494 | int delete_raw_obj_aio(const DoutPrefixProvider *dpp, const rgw_raw_obj& obj, std::list<librados::AioCompletion *>& handles); |
b3b6e05e | 1495 | int delete_obj_aio(const DoutPrefixProvider *dpp, const rgw_obj& obj, RGWBucketInfo& info, RGWObjState *astate, |
20effc67 | 1496 | std::list<librados::AioCompletion *>& handles, bool keep_index_consistent, |
9f95a23c | 1497 | optional_yield y); |
11fdf7f2 | 1498 | |
11fdf7f2 | 1499 | private: |
7c673cae FG |
1500 | /** |
1501 | * Check the actual on-disk state of the object specified | |
1502 | * by list_state, and fill in the time and size of object. | |
1503 | * Then append any changes to suggested_updates for | |
1504 | * the rgw class' dir_suggest_changes function. | |
1505 | * | |
1506 | * Note that this can maul list_state; don't use it afterwards. Also | |
1507 | * it expects object to already be filled in from list_state; it only | |
1508 | * sets the size and mtime. | |
1509 | * | |
1510 | * Returns 0 on success, -ENOENT if the object doesn't exist on disk, | |
1511 | * and -errno on other failures. (-ENOENT is not a failure, and it | |
1512 | * will encode that info as a suggested update.) | |
1513 | */ | |
20effc67 | 1514 | int check_disk_state(const DoutPrefixProvider *dpp, |
b3b6e05e | 1515 | librados::IoCtx io_ctx, |
7c673cae FG |
1516 | const RGWBucketInfo& bucket_info, |
1517 | rgw_bucket_dir_entry& list_state, | |
1518 | rgw_bucket_dir_entry& object, | |
9f95a23c TL |
1519 | bufferlist& suggested_updates, |
1520 | optional_yield y); | |
7c673cae FG |
1521 | |
1522 | /** | |
1523 | * Init pool iteration | |
31f18b77 | 1524 | * pool: pool to use for the ctx initialization |
7c673cae FG |
1525 | * ctx: context object to use for the iteration |
1526 | * Returns: 0 on success, -ERR# otherwise. | |
1527 | */ | |
b3b6e05e | 1528 | int pool_iterate_begin(const DoutPrefixProvider *dpp, const rgw_pool& pool, RGWPoolIterCtx& ctx); |
31f18b77 | 1529 | |
181888fb FG |
1530 | /** |
1531 | * Init pool iteration | |
1532 | * pool: pool to use | |
1533 | * cursor: position to start iteration | |
1534 | * ctx: context object to use for the iteration | |
1535 | * Returns: 0 on success, -ERR# otherwise. | |
1536 | */ | |
20effc67 | 1537 | int pool_iterate_begin(const DoutPrefixProvider *dpp, const rgw_pool& pool, const std::string& cursor, RGWPoolIterCtx& ctx); |
181888fb FG |
1538 | |
1539 | /** | |
1540 | * Get pool iteration position | |
1541 | * ctx: context object to use for the iteration | |
20effc67 | 1542 | * Returns: std::string representation of position |
181888fb | 1543 | */ |
20effc67 | 1544 | std::string pool_iterate_get_cursor(RGWPoolIterCtx& ctx); |
181888fb | 1545 | |
7c673cae FG |
1546 | /** |
1547 | * Iterate over pool return object names, use optional filter | |
1548 | * ctx: iteration context, initialized with pool_iterate_begin() | |
1549 | * num: max number of objects to return | |
1550 | * objs: a vector that the results will append into | |
1551 | * is_truncated: if not NULL, will hold true iff iteration is complete | |
1552 | * filter: if not NULL, will be used to filter returned objects | |
1553 | * Returns: 0 on success, -ERR# otherwise. | |
1554 | */ | |
20effc67 TL |
1555 | int pool_iterate(const DoutPrefixProvider *dpp, RGWPoolIterCtx& ctx, uint32_t num, |
1556 | std::vector<rgw_bucket_dir_entry>& objs, | |
7c673cae FG |
1557 | bool *is_truncated, RGWAccessListFilter *filter); |
1558 | ||
1559 | uint64_t next_bucket_id(); | |
11fdf7f2 | 1560 | |
9f95a23c TL |
1561 | /** |
1562 | * This is broken out to facilitate unit testing. | |
1563 | */ | |
1564 | static uint32_t calc_ordered_bucket_list_per_shard(uint32_t num_entries, | |
1565 | uint32_t num_shards); | |
11fdf7f2 TL |
1566 | }; |
1567 | ||
20effc67 TL |
1568 | |
1569 | struct get_obj_data { | |
1570 | RGWRados* rgwrados; | |
1571 | RGWGetDataCB* client_cb = nullptr; | |
1572 | rgw::Aio* aio; | |
1573 | uint64_t offset; // next offset to write to client | |
1574 | rgw::AioResultList completed; // completed read results, sorted by offset | |
1575 | optional_yield yield; | |
1576 | ||
1577 | get_obj_data(RGWRados* rgwrados, RGWGetDataCB* cb, rgw::Aio* aio, | |
1578 | uint64_t offset, optional_yield yield) | |
1579 | : rgwrados(rgwrados), client_cb(cb), aio(aio), offset(offset), yield(yield) {} | |
1580 | ~get_obj_data() { | |
1581 | if (rgwrados->get_use_datacache()) { | |
1582 | const std::lock_guard l(d3n_get_data.d3n_lock); | |
1583 | } | |
1584 | } | |
1585 | ||
1586 | D3nGetObjData d3n_get_data; | |
1587 | std::atomic_bool d3n_bypass_cache_write{false}; | |
1588 | ||
1589 | int flush(rgw::AioResultList&& results); | |
1590 | ||
1591 | void cancel() { | |
1592 | // wait for all completions to drain and ignore the results | |
1593 | aio->drain(); | |
1594 | } | |
1595 | ||
1596 | int drain() { | |
1597 | auto c = aio->wait(); | |
1598 | while (!c.empty()) { | |
1599 | int r = flush(std::move(c)); | |
1600 | if (r < 0) { | |
1601 | cancel(); | |
1602 | return r; | |
1603 | } | |
1604 | c = aio->wait(); | |
1605 | } | |
1606 | return flush(std::move(c)); | |
1607 | } | |
1608 | }; | |
1609 | ||
1610 | ||
7c673cae | 1611 | #endif |