]> git.proxmox.com Git - ceph.git/blame - ceph/src/rgw/rgw_rados.h
import ceph quincy 17.2.6
[ceph.git] / ceph / src / rgw / rgw_rados.h
CommitLineData
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
40struct D3nDataCache;
7c673cae
FG
41
42class RGWWatcher;
7c673cae
FG
43class ACLOwner;
44class RGWGC;
45class RGWMetaNotifier;
46class RGWDataNotifier;
47class RGWLC;
48class RGWObjectExpirer;
49class RGWMetaSyncProcessorThread;
50class RGWDataSyncProcessorThread;
51class RGWSyncLogTrimThread;
11fdf7f2 52class RGWSyncTraceManager;
7c673cae
FG
53struct RGWZoneGroup;
54struct RGWZoneParams;
31f18b77
FG
55class RGWReshard;
56class RGWReshardWait;
7c673cae 57
11fdf7f2 58class RGWSysObjectCtx;
20effc67 59struct 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 69static 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 80static 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
92int rgw_policy_from_attrset(const DoutPrefixProvider *dpp,
93 CephContext *cct,
94 std::map<std::string, bufferlist>& attrset,
95 RGWAccessControlPolicy *policy);
7c673cae 96
7c673cae
FG
97struct 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};
119WRITE_CLASS_ENCODER(RGWOLHInfo)
120
121struct 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};
140WRITE_CLASS_ENCODER(RGWOLHPendingInfo)
141
142struct 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
152struct RGWCloneRangeInfo {
153 rgw_obj src;
154 off_t src_ofs;
155 off_t dst_ofs;
156 uint64_t len;
157};
158
9f95a23c
TL
159class RGWFetchObjFilter {
160public:
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
172class RGWFetchObjFilter_Default : public RGWFetchObjFilter {
173protected:
174 rgw_placement_rule dest_rule;
175public:
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
187class 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;
193public:
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
214struct 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
252struct RGWPoolIterCtx {
253 librados::IoCtx io_ctx;
254 librados::NObjectIterator iter;
255};
256
257struct RGWListRawObjsCtx {
258 bool initialized;
259 RGWPoolIterCtx iter_ctx;
260
261 RGWListRawObjsCtx() : initialized(false) {}
262};
263
7c673cae 264struct 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};
299WRITE_CLASS_ENCODER(objexp_hint_entry)
300
7c673cae
FG
301class RGWMetaSyncStatusManager;
302class RGWDataSyncStatusManager;
7c673cae 303class RGWCoroutinesManagerRegistry;
7c673cae 304
7c673cae
FG
305class RGWGetDirHeader_CB;
306class RGWGetUserHeader_CB;
f67539c2 307namespace rgw { namespace sal {
20effc67
TL
308 class Store;
309 class RadosStore;
f67539c2
TL
310 class MPRadosSerializer;
311 class LCRadosSerializer;
312} }
7c673cae 313
7c673cae
FG
314class RGWAsyncRadosProcessor;
315
316template <class T>
317class RGWChainedCacheImpl;
318
319struct bucket_info_entry {
320 RGWBucketInfo info;
321 real_time mtime;
20effc67 322 std::map<std::string, bufferlist> attrs;
7c673cae
FG
323};
324
9f95a23c 325struct tombstone_entry;
7c673cae 326
9f95a23c
TL
327template <class K, class V>
328class lru_map;
329using tombstone_cache_t = lru_map<rgw_obj, tombstone_entry>;
7c673cae 330
31f18b77
FG
331class RGWIndexCompletionManager;
332
9f95a23c 333class 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);
418protected:
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 450public:
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 1325public:
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
1569struct 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