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