1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab ft=cpp
8 #include <boost/container/flat_map.hpp>
9 #include <boost/container/flat_set.hpp>
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"
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"
34 #include "rgw_d3n_cacherequest.h"
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"
48 class RGWMetaNotifier
;
49 class RGWDataNotifier
;
51 class RGWObjectExpirer
;
52 class RGWMetaSyncProcessorThread
;
53 class RGWDataSyncProcessorThread
;
54 class RGWSyncLogTrimThread
;
55 class RGWSyncTraceManager
;
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)
68 static inline void prepend_bucket_marker(const rgw_bucket
& bucket
, const std::string
& orig_oid
, std::string
& oid
)
70 if (bucket
.marker
.empty() || orig_oid
.empty()) {
79 static inline void get_obj_bucket_and_oid_loc(const rgw_obj
& obj
, std::string
& oid
, std::string
& locator
)
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();
85 prepend_bucket_marker(bucket
, loc
, locator
);
95 RGWOLHInfo() : removed(false) {}
97 void encode(bufferlist
& bl
) const {
98 ENCODE_START(1, 1, bl
);
104 void decode(bufferlist::const_iterator
& bl
) {
110 static void generate_test_instances(std::list
<RGWOLHInfo
*>& o
);
111 void dump(Formatter
*f
) const;
113 WRITE_CLASS_ENCODER(RGWOLHInfo
)
115 struct RGWOLHPendingInfo
{
116 ceph::real_time time
;
118 RGWOLHPendingInfo() {}
120 void encode(bufferlist
& bl
) const {
121 ENCODE_START(1, 1, bl
);
126 void decode(bufferlist::const_iterator
& bl
) {
132 void dump(Formatter
*f
) const;
134 WRITE_CLASS_ENCODER(RGWOLHPendingInfo
)
136 struct RGWUsageBatch
{
137 std::map
<ceph::real_time
, rgw_usage_log_entry
> m
;
139 void insert(ceph::real_time
& t
, rgw_usage_log_entry
& entry
, bool *account
) {
140 bool exists
= m
.find(t
) != m
.end();
142 m
[t
].aggregate(entry
);
146 struct RGWCloneRangeInfo
{
153 class RGWFetchObjFilter
{
155 virtual ~RGWFetchObjFilter() {}
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;
166 class RGWFetchObjFilter_Default
: public RGWFetchObjFilter
{
168 rgw_placement_rule dest_rule
;
170 RGWFetchObjFilter_Default() {}
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
;
181 struct RGWObjStateManifest
{
183 std::optional
<RGWObjManifest
> manifest
;
187 rgw::sal::Driver
* driver
;
188 ceph::shared_mutex lock
= ceph::make_shared_mutex("RGWObjectCtx");
190 std::map
<rgw_obj
, RGWObjStateManifest
> objs_state
;
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
;
199 rgw::sal::Driver
* get_driver() {
203 RGWObjStateManifest
*get_state(const rgw_obj
& obj
);
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
);
212 struct RGWRawObjState
{
214 bool has_attrs
{false};
217 ceph::real_time mtime
;
220 bool has_data
{false};
222 bool prefetch_data
{false};
225 /* important! don't forget to update copy constructor */
227 RGWObjVersionTracker objv_tracker
;
229 std::map
<std::string
, bufferlist
> attrset
;
231 RGWRawObjState(const RGWRawObjState
& rhs
) : obj (rhs
.obj
) {
232 has_attrs
= rhs
.has_attrs
;
237 if (rhs
.obj_tag
.length()) {
238 obj_tag
= rhs
.obj_tag
;
240 has_data
= rhs
.has_data
;
241 if (rhs
.data
.length()) {
244 prefetch_data
= rhs
.prefetch_data
;
246 objv_tracker
= rhs
.objv_tracker
;
250 struct RGWPoolIterCtx
{
251 librados::IoCtx io_ctx
;
252 librados::NObjectIterator iter
;
255 struct RGWListRawObjsCtx
{
257 RGWPoolIterCtx iter_ctx
;
259 RGWListRawObjsCtx() : initialized(false) {}
262 struct objexp_hint_entry
{
264 std::string bucket_name
;
265 std::string bucket_id
;
267 ceph::real_time exp_time
;
269 void encode(bufferlist
& bl
) const {
270 ENCODE_START(2, 1, bl
);
271 encode(bucket_name
, bl
);
272 encode(bucket_id
, bl
);
274 encode(exp_time
, bl
);
279 void decode(bufferlist::const_iterator
& bl
) {
280 // XXX Do we want DECODE_START_LEGACY_COMPAT_LEN(2, 1, 1, bl); ?
282 decode(bucket_name
, bl
);
283 decode(bucket_id
, bl
);
285 decode(exp_time
, bl
);
294 void dump(Formatter
*f
) const;
295 static void generate_test_instances(std::list
<objexp_hint_entry
*>& o
);
297 WRITE_CLASS_ENCODER(objexp_hint_entry
)
299 class RGWMetaSyncStatusManager
;
300 class RGWDataSyncStatusManager
;
301 class RGWCoroutinesManagerRegistry
;
303 class RGWGetDirHeader_CB
;
304 class RGWGetUserHeader_CB
;
305 namespace rgw
{ namespace sal
{
307 class MPRadosSerializer
;
308 class LCRadosSerializer
;
311 class RGWAsyncRadosProcessor
;
314 class RGWChainedCacheImpl
;
316 struct bucket_info_entry
{
319 std::map
<std::string
, bufferlist
> attrs
;
322 struct tombstone_entry
;
324 template <class K
, class V
>
326 using tombstone_cache_t
= lru_map
<rgw_obj
, tombstone_entry
>;
328 class RGWIndexCompletionManager
;
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
;
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
);
354 int open_pool_ctx(const DoutPrefixProvider
*dpp
, const rgw_pool
& pool
, librados::IoCtx
& io_ctx
,
355 bool mostly_omap
, bool bulk
);
358 ceph::mutex lock
= ceph::make_mutex("rados_timer_lock");
361 rgw::sal::RadosStore
* driver
= nullptr;
364 RGWObjectExpirer
*obj_expirer
;
368 bool run_sync_thread
;
369 bool run_reshard_thread
;
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
;
377 boost::optional
<rgw::BucketTrimManager
> bucket_trim
;
378 RGWSyncLogTrimThread
*sync_log_trimmer
{nullptr};
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");
383 librados::IoCtx root_pool_ctx
; // .rgw
385 ceph::mutex bucket_id_lock
{ceph::make_mutex("rados_bucket_id")};
387 // This field represents the number of bucket index object shards
388 uint32_t bucket_index_max_shards
;
390 std::string
get_cluster_fsid(const DoutPrefixProvider
*dpp
, optional_yield y
);
392 int get_obj_head_ref(const DoutPrefixProvider
*dpp
, const rgw_placement_rule
& target_placement_rule
, const rgw_obj
& obj
, rgw_rados_ref
*ref
);
393 int get_obj_head_ref(const DoutPrefixProvider
*dpp
, const RGWBucketInfo
& bucket_info
, const rgw_obj
& obj
, rgw_rados_ref
*ref
);
394 int get_system_obj_ref(const DoutPrefixProvider
*dpp
, const rgw_raw_obj
& obj
, rgw_rados_ref
*ref
);
395 uint64_t max_bucket_id
;
397 int clear_olh(const DoutPrefixProvider
*dpp
,
398 RGWObjectCtx
& obj_ctx
,
400 RGWBucketInfo
& bucket_info
,
402 const std::string
& tag
,
406 int get_olh_target_state(const DoutPrefixProvider
*dpp
, RGWObjectCtx
& rctx
,
407 RGWBucketInfo
& bucket_info
, const rgw_obj
& obj
,
408 RGWObjState
*olh_state
, RGWObjState
**target_state
,
409 RGWObjManifest
**target_manifest
, optional_yield y
);
410 int get_obj_state_impl(const DoutPrefixProvider
*dpp
, RGWObjectCtx
*rctx
, RGWBucketInfo
& bucket_info
, const rgw_obj
& obj
, RGWObjState
**state
, RGWObjManifest
** manifest
,
411 bool follow_olh
, optional_yield y
, bool assume_noent
= false);
412 int append_atomic_test(const DoutPrefixProvider
*dpp
, RGWObjectCtx
* rctx
, RGWBucketInfo
& bucket_info
, const rgw_obj
& obj
,
413 librados::ObjectOperation
& op
, RGWObjState
**state
,
414 RGWObjManifest
** pmanifest
, optional_yield y
);
416 int update_placement_map();
417 int store_bucket_info(RGWBucketInfo
& info
, std::map
<std::string
, bufferlist
> *pattrs
, RGWObjVersionTracker
*objv_tracker
, bool exclusive
);
419 void remove_rgw_head_obj(librados::ObjectWriteOperation
& op
);
420 void cls_obj_check_prefix_exist(librados::ObjectOperation
& op
, const std::string
& prefix
, bool fail_if_exist
);
421 void cls_obj_check_mtime(librados::ObjectOperation
& op
, const real_time
& mtime
, bool high_precision_time
, RGWCheckMTimeType type
);
425 librados::Rados rados
;
427 using RGWChainedCacheImpl_bucket_info_entry
= RGWChainedCacheImpl
<bucket_info_entry
>;
428 RGWChainedCacheImpl_bucket_info_entry
*binfo_cache
;
430 tombstone_cache_t
*obj_tombstone_cache
;
432 librados::IoCtx gc_pool_ctx
; // .rgw.gc
433 librados::IoCtx lc_pool_ctx
; // .rgw.lc
434 librados::IoCtx objexp_pool_ctx
;
435 librados::IoCtx reshard_pool_ctx
;
436 librados::IoCtx notif_pool_ctx
; // .rgw.notif
438 bool pools_initialized
;
440 RGWQuotaHandler
*quota_handler
;
442 RGWCoroutinesManagerRegistry
*cr_registry
;
444 RGWSyncModuleInstanceRef sync_module
;
445 bool writeable_zone
{false};
447 RGWIndexCompletionManager
*index_completion_manager
{nullptr};
449 bool use_cache
{false};
451 bool use_datacache
{false};
453 int get_obj_head_ioctx(const DoutPrefixProvider
*dpp
, const RGWBucketInfo
& bucket_info
, const rgw_obj
& obj
, librados::IoCtx
*ioctx
);
455 RGWRados(): timer(NULL
),
456 gc(NULL
), lc(NULL
), obj_expirer(NULL
), use_gc_thread(false), use_lc_thread(false), quota_threads(false),
457 run_sync_thread(false), run_reshard_thread(false), meta_notifier(NULL
),
458 data_notifier(NULL
), meta_sync_processor_thread(NULL
),
459 bucket_index_max_shards(0),
460 max_bucket_id(0), cct(NULL
),
461 binfo_cache(NULL
), obj_tombstone_cache(nullptr),
462 pools_initialized(false),
468 RGWRados
& set_use_cache(bool status
) {
473 RGWRados
& set_use_gc(bool status
) {
478 RGWRados
& set_use_datacache(bool status
) {
479 use_datacache
= status
;
483 bool get_use_datacache() {
484 return use_datacache
;
495 RGWRados
& set_run_gc_thread(bool _use_gc_thread
) {
496 use_gc_thread
= _use_gc_thread
;
500 RGWRados
& set_run_lc_thread(bool _use_lc_thread
) {
501 use_lc_thread
= _use_lc_thread
;
505 RGWRados
& set_run_quota_threads(bool _run_quota_threads
) {
506 quota_threads
= _run_quota_threads
;
510 RGWRados
& set_run_sync_thread(bool _run_sync_thread
) {
511 run_sync_thread
= _run_sync_thread
;
515 RGWRados
& set_run_reshard_thread(bool _run_reshard_thread
) {
516 run_reshard_thread
= _run_reshard_thread
;
520 librados::IoCtx
* get_lc_pool_ctx() {
524 librados::IoCtx
& get_notif_pool_ctx() {
525 return notif_pool_ctx
;
528 void set_context(CephContext
*_cct
) {
531 void set_store(rgw::sal::RadosStore
* _driver
) {
538 RGWCtl
*pctl
{nullptr};
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.
547 std::shared_ptr
<RGWReshardWait
> reshard_wait
;
549 virtual ~RGWRados() = default;
551 tombstone_cache_t
*get_tombstone_cache() {
552 return obj_tombstone_cache
;
554 const RGWSyncModuleInstanceRef
& get_sync_module() {
557 RGWSyncTraceManager
*get_sync_tracer() {
561 int get_required_alignment(const DoutPrefixProvider
*dpp
, const rgw_pool
& pool
, uint64_t *alignment
);
562 void get_max_aligned_size(uint64_t size
, uint64_t alignment
, uint64_t *max_size
);
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);
566 uint32_t get_max_bucket_shards() {
567 return RGWSI_BucketIndex_RADOS::shards_max();
571 int get_raw_obj_ref(const DoutPrefixProvider
*dpp
, const rgw_raw_obj
& obj
, rgw_rados_ref
*ref
);
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
,
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
,
580 std::string
list_raw_objs_get_cursor(RGWListRawObjsCtx
& ctx
);
582 CephContext
*ctx() { return cct
; }
583 /** do all necessary setup of the storage device */
584 int init_begin(CephContext
*_cct
, const DoutPrefixProvider
*dpp
) {
586 return init_begin(dpp
);
588 /** Initialize the RADOS instance and prepare to do other ops */
589 int init_svc(bool raw
, const DoutPrefixProvider
*dpp
);
590 int init_ctl(const DoutPrefixProvider
*dpp
);
591 virtual int init_rados();
592 int init_begin(const DoutPrefixProvider
*dpp
);
593 int init_complete(const DoutPrefixProvider
*dpp
);
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
);
600 int log_list_init(const DoutPrefixProvider
*dpp
, const std::string
& prefix
, RGWAccessHandle
*handle
);
601 int log_list_next(RGWAccessHandle handle
, std::string
*name
);
604 int log_remove(const DoutPrefixProvider
*dpp
, const std::string
& name
);
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
);
610 // log bandwidth info
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
,
614 rgw_usage_log_entry
>& usage
);
615 int trim_usage(const DoutPrefixProvider
*dpp
, const rgw_user
& user
, const std::string
& bucket_name
, uint64_t start_epoch
, uint64_t end_epoch
);
616 int clear_usage(const DoutPrefixProvider
*dpp
);
618 int create_pool(const DoutPrefixProvider
*dpp
, const rgw_pool
& pool
);
620 void create_bucket_id(std::string
*bucket_id
);
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
);
625 int create_bucket(const RGWUserInfo
& owner
, rgw_bucket
& bucket
,
626 const std::string
& zonegroup_id
,
627 const rgw_placement_rule
& placement_rule
,
628 const std::string
& swift_ver_location
,
629 const RGWQuotaInfo
* pquota_info
,
630 std::map
<std::string
,bufferlist
>& attrs
,
631 RGWBucketInfo
& bucket_info
,
633 obj_version
*pep_objv
,
634 ceph::real_time creation_time
,
635 rgw_bucket
*master_bucket
,
636 uint32_t *master_num_shards
,
638 const DoutPrefixProvider
*dpp
,
639 bool exclusive
= true);
641 RGWCoroutinesManagerRegistry
*get_cr_registry() { return cr_registry
; }
647 RGWSI_RADOS::Obj bucket_obj
;
649 explicit BucketShard(RGWRados
*_store
) : store(_store
), shard_id(-1) {}
650 int init(const rgw_bucket
& _bucket
, const rgw_obj
& obj
,
651 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
,
654 const RGWBucketInfo
& bucket_info
,
655 const rgw::bucket_index_layout_generation
& index
, int sid
);
657 friend std::ostream
& operator<<(std::ostream
& out
, const BucketShard
& bs
) {
658 out
<< "BucketShard:{ bucket=" << bs
.bucket
<<
659 ", shard_id=" << bs
.shard_id
<<
660 ", bucket_ojb=" << bs
.bucket_obj
<< "}";
667 RGWBucketInfo bucket_info
;
674 RGWObjManifest
*manifest
;
676 bool versioning_disabled
;
680 const rgw_placement_rule
*pmeta_placement_rule
;
683 int get_state(const DoutPrefixProvider
*dpp
, RGWObjState
**pstate
, RGWObjManifest
**pmanifest
, bool follow_olh
, optional_yield y
, bool assume_noent
= false);
684 void invalidate_state();
686 int prepare_atomic_modification(const DoutPrefixProvider
*dpp
, librados::ObjectWriteOperation
& op
, bool reset_obj
, const std::string
*ptag
,
687 const char *ifmatch
, const char *ifnomatch
, bool removal_op
, bool modify_tail
, optional_yield y
);
688 int complete_atomic_modification(const DoutPrefixProvider
*dpp
);
691 Object(RGWRados
*_store
, const RGWBucketInfo
& _bucket_info
, RGWObjectCtx
& _ctx
, const rgw_obj
& _obj
) : store(_store
), bucket_info(_bucket_info
),
692 ctx(_ctx
), obj(_obj
), bs(store
),
693 state(NULL
), manifest(nullptr), versioning_disabled(false),
694 bs_initialized(false),
695 pmeta_placement_rule(nullptr) {}
697 RGWRados
*get_store() { return store
; }
698 rgw_obj
& get_obj() { return obj
; }
699 RGWObjectCtx
& get_ctx() { return ctx
; }
700 RGWBucketInfo
& get_bucket_info() { return bucket_info
; }
701 //const std::string& get_instance() { return obj->get_instance(); }
702 //rgw::sal::Object* get_target() { return obj; }
703 int get_manifest(const DoutPrefixProvider
*dpp
, RGWObjManifest
**pmanifest
, optional_yield y
);
705 int get_bucket_shard(BucketShard
**pbs
, const DoutPrefixProvider
*dpp
) {
706 if (!bs_initialized
) {
708 bs
.init(bucket_info
.bucket
, obj
, nullptr /* no RGWBucketInfo */, dpp
);
712 bs_initialized
= true;
718 void set_versioning_disabled(bool status
) {
719 versioning_disabled
= status
;
722 bool versioning_enabled() {
723 return (!versioning_disabled
&& bucket_info
.versioning_enabled());
726 void set_meta_placement_rule(const rgw_placement_rule
*p
) {
727 pmeta_placement_rule
= p
;
730 const rgw_placement_rule
& get_meta_placement_rule() {
731 return pmeta_placement_rule
? *pmeta_placement_rule
: bucket_info
.placement_rule
;
735 RGWRados::Object
*source
;
738 std::map
<rgw_pool
, librados::IoCtx
> io_ctxs
;
740 librados::IoCtx
*cur_ioctx
{nullptr};
742 rgw_raw_obj head_obj
;
745 struct ConditionParams
{
746 const ceph::real_time
*mod_ptr
;
747 const ceph::real_time
*unmod_ptr
;
748 bool high_precision_time
;
749 uint32_t mod_zone_id
;
751 const char *if_match
;
752 const char *if_nomatch
;
755 mod_ptr(NULL
), unmod_ptr(NULL
), high_precision_time(false), mod_zone_id(0), mod_pg_ver(0),
756 if_match(NULL
), if_nomatch(NULL
) {}
760 ceph::real_time
*lastmod
;
762 std::map
<std::string
, bufferlist
> *attrs
;
765 Params() : lastmod(nullptr), obj_size(nullptr), attrs(nullptr),
766 target_obj(nullptr) {}
769 explicit Read(RGWRados::Object
*_source
) : source(_source
) {}
771 int prepare(optional_yield y
, const DoutPrefixProvider
*dpp
);
772 static int range_to_ofs(uint64_t obj_size
, int64_t &ofs
, int64_t &end
);
773 int read(int64_t ofs
, int64_t end
, bufferlist
& bl
, optional_yield y
, const DoutPrefixProvider
*dpp
);
774 int iterate(const DoutPrefixProvider
*dpp
, int64_t ofs
, int64_t end
, RGWGetDataCB
*cb
, optional_yield y
);
775 int get_attr(const DoutPrefixProvider
*dpp
, const char *name
, bufferlist
& dest
, optional_yield y
);
779 RGWRados::Object
*target
;
782 ceph::real_time
*mtime
;
783 std::map
<std::string
, bufferlist
>* rmattrs
;
784 const bufferlist
*data
;
785 RGWObjManifest
*manifest
;
786 const std::string
*ptag
;
787 std::list
<rgw_obj_index_key
> *remove_objs
;
788 ceph::real_time set_mtime
;
790 RGWObjCategory category
;
792 const char *if_match
;
793 const char *if_nomatch
;
794 std::optional
<uint64_t> olh_epoch
;
795 ceph::real_time delete_at
;
797 const std::string
*user_data
;
798 rgw_zone_set
*zones_trace
;
800 bool completeMultipart
;
803 MetaParams() : mtime(NULL
), rmattrs(NULL
), data(NULL
), manifest(NULL
), ptag(NULL
),
804 remove_objs(NULL
), category(RGWObjCategory::Main
), flags(0),
805 if_match(NULL
), if_nomatch(NULL
), canceled(false), user_data(nullptr), zones_trace(nullptr),
806 modify_tail(false), completeMultipart(false), appendable(false) {}
809 explicit Write(RGWRados::Object
*_target
) : target(_target
) {}
811 int _do_write_meta(const DoutPrefixProvider
*dpp
,
812 uint64_t size
, uint64_t accounted_size
,
813 std::map
<std::string
, bufferlist
>& attrs
,
814 bool modify_tail
, bool assume_noent
,
815 void *index_op
, optional_yield y
);
816 int write_meta(const DoutPrefixProvider
*dpp
, uint64_t size
, uint64_t accounted_size
,
817 std::map
<std::string
, bufferlist
>& attrs
, optional_yield y
);
818 int write_data(const char *data
, uint64_t ofs
, uint64_t len
, bool exclusive
);
819 const req_state
* get_req_state() {
820 return nullptr; /* XXX dang Only used by LTTng, and it handles null anyway */
825 RGWRados::Object
*target
;
827 struct DeleteParams
{
828 rgw_user bucket_owner
;
829 int versioning_status
; // versioning flags defined in enum RGWBucketFlags
830 ACLOwner obj_owner
; // needed for creation of deletion marker
832 std::string marker_version_id
;
833 uint32_t bilog_flags
;
834 std::list
<rgw_obj_index_key
> *remove_objs
;
835 ceph::real_time expiration_time
;
836 ceph::real_time unmod_since
;
837 ceph::real_time mtime
; /* for setting delete marker mtime */
838 bool high_precision_time
;
839 rgw_zone_set
*zones_trace
;
841 uint64_t parts_accounted_size
;
843 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) {}
846 struct DeleteResult
{
848 std::string version_id
;
850 DeleteResult() : delete_marker(false) {}
853 explicit Delete(RGWRados::Object
*_target
) : target(_target
) {}
855 int delete_obj(optional_yield y
, const DoutPrefixProvider
*dpp
);
859 RGWRados::Object
*source
;
863 std::optional
<RGWObjManifest
> manifest
;
865 struct timespec mtime
{};
866 std::map
<std::string
, bufferlist
> attrs
;
870 librados::IoCtx io_ctx
;
871 librados::AioCompletion
*completion
;
874 State() : completion(NULL
), ret(0) {}
878 explicit Stat(RGWRados::Object
*_source
) : source(_source
) {}
880 int stat_async(const DoutPrefixProvider
*dpp
);
881 int wait(const DoutPrefixProvider
*dpp
);
884 int finish(const DoutPrefixProvider
*dpp
);
890 RGWBucketInfo bucket_info
;
895 Bucket(RGWRados
*_store
, const RGWBucketInfo
& _bucket_info
) : store(_store
), bucket_info(_bucket_info
), bucket(bucket_info
.bucket
),
896 shard_id(RGW_NO_SHARD
) {}
897 RGWRados
*get_store() { return store
; }
898 rgw_bucket
& get_bucket() { return bucket
; }
899 RGWBucketInfo
& get_bucket_info() { return bucket_info
; }
901 int update_bucket_id(const std::string
& new_bucket_id
, const DoutPrefixProvider
*dpp
);
903 int get_shard_id() { return shard_id
; }
904 void set_shard_id(int id
) {
909 RGWRados::Bucket
*target
;
912 uint16_t bilog_flags
{0};
914 bool bs_initialized
{false};
916 bool prepared
{false};
917 rgw_zone_set
*zones_trace
{nullptr};
919 int init_bs(const DoutPrefixProvider
*dpp
) {
921 bs
.init(target
->get_bucket(), obj
, &target
->bucket_info
, dpp
);
925 bs_initialized
= true;
929 void invalidate_bs() {
930 bs_initialized
= false;
933 int guard_reshard(const DoutPrefixProvider
*dpp
, const rgw_obj
& obj_instance
, BucketShard
**pbs
, std::function
<int(BucketShard
*)> call
);
936 UpdateIndex(RGWRados::Bucket
*_target
, const rgw_obj
& _obj
) : target(_target
), obj(_obj
),
937 bs(target
->get_store()) {
938 blind
= (target
->get_bucket_info().layout
.current_index
.layout
.type
== rgw::BucketIndexType::Indexless
);
941 int get_bucket_shard(BucketShard
**pbs
, const DoutPrefixProvider
*dpp
) {
942 if (!bs_initialized
) {
943 int r
= init_bs(dpp
);
952 void set_bilog_flags(uint16_t flags
) {
956 void set_zones_trace(rgw_zone_set
*_zones_trace
) {
957 zones_trace
= _zones_trace
;
960 int prepare(const DoutPrefixProvider
*dpp
, RGWModifyOp
, const std::string
*write_tag
, optional_yield y
);
961 int complete(const DoutPrefixProvider
*dpp
, int64_t poolid
, uint64_t epoch
, uint64_t size
,
962 uint64_t accounted_size
, ceph::real_time
& ut
,
963 const std::string
& etag
, const std::string
& content_type
,
964 const std::string
& storage_class
,
965 bufferlist
*acl_bl
, RGWObjCategory category
,
966 std::list
<rgw_obj_index_key
> *remove_objs
,
968 const std::string
*user_data
= nullptr,
969 bool appendable
= false);
970 int complete_del(const DoutPrefixProvider
*dpp
,
971 int64_t poolid
, uint64_t epoch
,
972 ceph::real_time
& removed_mtime
, /* mtime of removed object */
973 std::list
<rgw_obj_index_key
> *remove_objs
,
975 int cancel(const DoutPrefixProvider
*dpp
,
976 std::list
<rgw_obj_index_key
> *remove_objs
,
979 const std::string
*get_optag() { return &optag
; }
981 bool is_prepared() { return prepared
; }
982 }; // class UpdateIndex
986 // absolute maximum number of objects that
987 // list_objects_(un)ordered can return
988 static constexpr int64_t bucket_list_objects_absolute_max
= 25000;
990 RGWRados::Bucket
*target
;
991 rgw_obj_key next_marker
;
993 int list_objects_ordered(const DoutPrefixProvider
*dpp
,
995 std::vector
<rgw_bucket_dir_entry
> *result
,
996 std::map
<std::string
, bool> *common_prefixes
,
999 int list_objects_unordered(const DoutPrefixProvider
*dpp
,
1001 std::vector
<rgw_bucket_dir_entry
> *result
,
1002 std::map
<std::string
, bool> *common_prefixes
,
1012 rgw_obj_key end_marker
;
1015 RGWAccessListFilter
* access_list_filter
;
1016 RGWBucketListNameFilter force_check_filter
;
1018 bool allow_unordered
;
1022 access_list_filter(nullptr),
1023 list_versions(false),
1024 allow_unordered(false)
1028 explicit List(RGWRados::Bucket
*_target
) : target(_target
) {}
1030 int list_objects(const DoutPrefixProvider
*dpp
, int64_t max
,
1031 std::vector
<rgw_bucket_dir_entry
> *result
,
1032 std::map
<std::string
, bool> *common_prefixes
,
1035 if (params
.allow_unordered
) {
1036 return list_objects_unordered(dpp
, max
, result
, common_prefixes
,
1039 return list_objects_ordered(dpp
, max
, result
, common_prefixes
,
1043 rgw_obj_key
& get_next_marker() {
1049 int on_last_entry_in_listing(const DoutPrefixProvider
*dpp
,
1050 RGWBucketInfo
& bucket_info
,
1051 const std::string
& obj_prefix
,
1052 const std::string
& obj_delim
,
1053 std::function
<int(const rgw_bucket_dir_entry
&)> handler
);
1055 bool swift_versioning_enabled(const RGWBucketInfo
& bucket_info
) const;
1057 int swift_versioning_copy(RGWObjectCtx
& obj_ctx
, /* in/out */
1058 const rgw_user
& user
, /* in */
1059 RGWBucketInfo
& bucket_info
, /* in */
1060 const rgw_obj
& obj
, /* in */
1061 const DoutPrefixProvider
*dpp
, /* in */
1062 optional_yield y
); /* in */
1063 int swift_versioning_restore(RGWObjectCtx
& obj_ctx
, /* in/out */
1064 const rgw_user
& user
, /* in */
1065 RGWBucketInfo
& bucket_info
, /* in */
1066 rgw_obj
& obj
, /* in/out */
1067 bool& restored
, /* out */
1068 const DoutPrefixProvider
*dpp
); /* in */
1069 int copy_obj_to_remote_dest(const DoutPrefixProvider
*dpp
,
1070 RGWObjState
*astate
,
1071 std::map
<std::string
, bufferlist
>& src_attrs
,
1072 RGWRados::Object::Read
& read_op
,
1073 const rgw_user
& user_id
,
1074 const rgw_obj
& dest_obj
,
1075 ceph::real_time
*mtime
);
1079 ATTRSMOD_REPLACE
= 1,
1083 D3nDataCache
* d3n_data_cache
{nullptr};
1085 int rewrite_obj(RGWBucketInfo
& dest_bucket_info
, const rgw_obj
& obj
, const DoutPrefixProvider
*dpp
, optional_yield y
);
1086 int reindex_obj(const RGWBucketInfo
& dest_bucket_info
,
1088 const DoutPrefixProvider
* dpp
,
1091 int stat_remote_obj(const DoutPrefixProvider
*dpp
,
1092 RGWObjectCtx
& obj_ctx
,
1093 const rgw_user
& user_id
,
1095 const rgw_zone_id
& source_zone
,
1096 const rgw_obj
& src_obj
,
1097 const RGWBucketInfo
*src_bucket_info
,
1098 real_time
*src_mtime
,
1100 const real_time
*mod_ptr
,
1101 const real_time
*unmod_ptr
,
1102 bool high_precision_time
,
1103 const char *if_match
,
1104 const char *if_nomatch
,
1105 std::map
<std::string
, bufferlist
> *pattrs
,
1106 std::map
<std::string
, std::string
> *pheaders
,
1107 std::string
*version_id
,
1109 std::string
*petag
);
1111 int fetch_remote_obj(RGWObjectCtx
& obj_ctx
,
1112 const rgw_user
& user_id
,
1114 const rgw_zone_id
& source_zone
,
1115 const rgw_obj
& dest_obj
,
1116 const rgw_obj
& src_obj
,
1117 RGWBucketInfo
& dest_bucket_info
,
1118 RGWBucketInfo
*src_bucket_info
,
1119 std::optional
<rgw_placement_rule
> dest_placement
,
1120 ceph::real_time
*src_mtime
,
1121 ceph::real_time
*mtime
,
1122 const ceph::real_time
*mod_ptr
,
1123 const ceph::real_time
*unmod_ptr
,
1124 bool high_precision_time
,
1125 const char *if_match
,
1126 const char *if_nomatch
,
1129 rgw::sal::Attrs
& attrs
,
1130 RGWObjCategory category
,
1131 std::optional
<uint64_t> olh_epoch
,
1132 ceph::real_time delete_at
,
1135 void (*progress_cb
)(off_t
, void *),
1136 void *progress_data
,
1137 const DoutPrefixProvider
*dpp
,
1138 RGWFetchObjFilter
*filter
,
1139 const rgw_zone_set_entry
& source_trace_entry
,
1140 rgw_zone_set
*zones_trace
= nullptr,
1141 std::optional
<uint64_t>* bytes_transferred
= 0);
1144 * dest_obj: the object to copy into
1145 * src_obj: the object to copy from
1146 * attrs: usage depends on attrs_mod parameter
1147 * attrs_mod: the modification mode of the attrs, may have the following values:
1148 * ATTRSMOD_NONE - the attributes of the source object will be
1149 * copied without modifications, attrs parameter is ignored;
1150 * ATTRSMOD_REPLACE - new object will have the attributes provided by attrs
1151 * parameter, source object attributes are not copied;
1152 * ATTRSMOD_MERGE - any conflicting meta keys on the source object's attributes
1153 * are overwritten by values contained in attrs parameter.
1154 * Returns: 0 on success, -ERR# otherwise.
1156 int copy_obj(RGWObjectCtx
& obj_ctx
,
1157 const rgw_user
& user_id
,
1159 const rgw_zone_id
& source_zone
,
1160 const rgw_obj
& dest_obj
,
1161 const rgw_obj
& src_obj
,
1162 RGWBucketInfo
& dest_bucket_info
,
1163 RGWBucketInfo
& src_bucket_info
,
1164 const rgw_placement_rule
& dest_placement
,
1165 ceph::real_time
*src_mtime
,
1166 ceph::real_time
*mtime
,
1167 const ceph::real_time
*mod_ptr
,
1168 const ceph::real_time
*unmod_ptr
,
1169 bool high_precision_time
,
1170 const char *if_match
,
1171 const char *if_nomatch
,
1174 std::map
<std::string
, bufferlist
>& attrs
,
1175 RGWObjCategory category
,
1177 ceph::real_time delete_at
,
1178 std::string
*version_id
,
1181 void (*progress_cb
)(off_t
, void *),
1182 void *progress_data
,
1183 const DoutPrefixProvider
*dpp
,
1186 int copy_obj_data(RGWObjectCtx
& obj_ctx
,
1187 RGWBucketInfo
& dest_bucket_info
,
1188 const rgw_placement_rule
& dest_placement
,
1189 RGWRados::Object::Read
& read_op
, off_t end
,
1190 const rgw_obj
& dest_obj
,
1191 ceph::real_time
*mtime
,
1192 ceph::real_time set_mtime
,
1193 std::map
<std::string
, bufferlist
>& attrs
,
1195 ceph::real_time delete_at
,
1197 const DoutPrefixProvider
*dpp
,
1200 int transition_obj(RGWObjectCtx
& obj_ctx
,
1201 RGWBucketInfo
& bucket_info
,
1203 const rgw_placement_rule
& placement_rule
,
1204 const real_time
& mtime
,
1206 const DoutPrefixProvider
*dpp
,
1209 int check_bucket_empty(const DoutPrefixProvider
*dpp
, RGWBucketInfo
& bucket_info
, optional_yield y
);
1213 * bucket: the name of the bucket to delete
1214 * Returns 0 on success, -ERR# otherwise.
1216 int delete_bucket(RGWBucketInfo
& bucket_info
, RGWObjVersionTracker
& objv_tracker
, optional_yield y
, const DoutPrefixProvider
*dpp
, bool check_empty
= true);
1218 void wakeup_meta_sync_shards(std::set
<int>& shard_ids
);
1220 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
);
1222 RGWMetaSyncStatusManager
* get_meta_sync_manager();
1223 RGWDataSyncStatusManager
* get_data_sync_manager(const rgw_zone_id
& source_zone
);
1225 int set_bucket_owner(rgw_bucket
& bucket
, ACLOwner
& owner
, const DoutPrefixProvider
*dpp
);
1226 int set_buckets_enabled(std::vector
<rgw_bucket
>& buckets
, bool enabled
, const DoutPrefixProvider
*dpp
);
1227 int bucket_suspended(const DoutPrefixProvider
*dpp
, rgw_bucket
& bucket
, bool *suspended
);
1229 /** Delete an object.*/
1230 int delete_obj(const DoutPrefixProvider
*dpp
,
1231 RGWObjectCtx
& obj_ctx
,
1232 const RGWBucketInfo
& bucket_info
,
1234 int versioning_status
, // versioning flags defined in enum RGWBucketFlags
1235 uint16_t bilog_flags
= 0,
1236 const ceph::real_time
& expiration_time
= ceph::real_time(),
1237 rgw_zone_set
*zones_trace
= nullptr);
1239 int delete_raw_obj(const DoutPrefixProvider
*dpp
, const rgw_raw_obj
& obj
);
1241 /** Remove an object from the bucket index */
1242 int delete_obj_index(const rgw_obj
& obj
, ceph::real_time mtime
,
1243 const DoutPrefixProvider
*dpp
, optional_yield y
);
1246 * Set an attr on an object.
1247 * bucket: name of the bucket holding the object
1248 * obj: name of the object to set the attr on
1249 * name: the attr to set
1250 * bl: the contents of the attr
1251 * Returns: 0 on success, -ERR# otherwise.
1253 int set_attr(const DoutPrefixProvider
*dpp
, RGWObjectCtx
* ctx
, RGWBucketInfo
& bucket_info
, const rgw_obj
& obj
, const char *name
, bufferlist
& bl
);
1255 int set_attrs(const DoutPrefixProvider
*dpp
, RGWObjectCtx
* ctx
, RGWBucketInfo
& bucket_info
, const rgw_obj
& obj
,
1256 std::map
<std::string
, bufferlist
>& attrs
,
1257 std::map
<std::string
, bufferlist
>* rmattrs
,
1259 ceph::real_time set_mtime
= ceph::real_clock::zero());
1261 int get_obj_state(const DoutPrefixProvider
*dpp
, RGWObjectCtx
*rctx
, RGWBucketInfo
& bucket_info
, const rgw_obj
& obj
, RGWObjState
**state
, RGWObjManifest
** manifest
,
1262 bool follow_olh
, optional_yield y
, bool assume_noent
= false);
1263 int get_obj_state(const DoutPrefixProvider
*dpp
, RGWObjectCtx
*rctx
, RGWBucketInfo
& bucket_info
, const rgw_obj
& obj
, RGWObjState
**state
, RGWObjManifest
** manifest
, optional_yield y
) {
1264 return get_obj_state(dpp
, rctx
, bucket_info
, obj
, state
, manifest
, true, y
);
1267 using iterate_obj_cb
= int (*)(const DoutPrefixProvider
*, const rgw_raw_obj
&, off_t
, off_t
,
1268 off_t
, bool, RGWObjState
*, void*);
1270 int iterate_obj(const DoutPrefixProvider
*dpp
, RGWObjectCtx
& ctx
, RGWBucketInfo
& bucket_info
,
1271 const rgw_obj
& obj
, off_t ofs
, off_t end
,
1272 uint64_t max_chunk_size
, iterate_obj_cb cb
, void *arg
,
1275 int append_atomic_test(const DoutPrefixProvider
*dpp
, const RGWObjState
* astate
, librados::ObjectOperation
& op
);
1277 virtual int get_obj_iterate_cb(const DoutPrefixProvider
*dpp
,
1278 const rgw_raw_obj
& read_obj
, off_t obj_ofs
,
1279 off_t read_ofs
, off_t len
, bool is_head_obj
,
1280 RGWObjState
*astate
, void *arg
);
1283 * a simple object read without keeping state
1286 int raw_obj_stat(const DoutPrefixProvider
*dpp
,
1287 rgw_raw_obj
& obj
, uint64_t *psize
, ceph::real_time
*pmtime
, uint64_t *epoch
,
1288 std::map
<std::string
, bufferlist
> *attrs
, bufferlist
*first_chunk
,
1289 RGWObjVersionTracker
*objv_tracker
, optional_yield y
);
1291 int obj_operate(const DoutPrefixProvider
*dpp
, const RGWBucketInfo
& bucket_info
, const rgw_obj
& obj
, librados::ObjectWriteOperation
*op
);
1292 int obj_operate(const DoutPrefixProvider
*dpp
, const RGWBucketInfo
& bucket_info
, const rgw_obj
& obj
, librados::ObjectReadOperation
*op
);
1294 int guard_reshard(const DoutPrefixProvider
*dpp
,
1296 const rgw_obj
& obj_instance
,
1297 RGWBucketInfo
& bucket_info
,
1298 std::function
<int(BucketShard
*)> call
);
1299 int block_while_resharding(RGWRados::BucketShard
*bs
,
1300 const rgw_obj
& obj_instance
,
1301 RGWBucketInfo
& bucket_info
,
1303 const DoutPrefixProvider
*dpp
);
1305 void bucket_index_guard_olh_op(const DoutPrefixProvider
*dpp
, RGWObjState
& olh_state
, librados::ObjectOperation
& op
);
1306 void olh_cancel_modification(const DoutPrefixProvider
*dpp
, const RGWBucketInfo
& bucket_info
, RGWObjState
& state
, const rgw_obj
& olh_obj
, const std::string
& op_tag
, optional_yield y
);
1307 int olh_init_modification(const DoutPrefixProvider
*dpp
, const RGWBucketInfo
& bucket_info
, RGWObjState
& state
, const rgw_obj
& olh_obj
, std::string
*op_tag
);
1308 int olh_init_modification_impl(const DoutPrefixProvider
*dpp
, const RGWBucketInfo
& bucket_info
, RGWObjState
& state
, const rgw_obj
& olh_obj
, std::string
*op_tag
);
1309 int bucket_index_link_olh(const DoutPrefixProvider
*dpp
,
1310 RGWBucketInfo
& bucket_info
, RGWObjState
& olh_state
,
1311 const rgw_obj
& obj_instance
, bool delete_marker
,
1312 const std::string
& op_tag
, struct rgw_bucket_dir_entry_meta
*meta
,
1314 ceph::real_time unmod_since
, bool high_precision_time
,
1316 rgw_zone_set
*zones_trace
= nullptr,
1317 bool log_data_change
= false);
1318 int bucket_index_unlink_instance(const DoutPrefixProvider
*dpp
,
1319 RGWBucketInfo
& bucket_info
,
1320 const rgw_obj
& obj_instance
,
1321 const std::string
& op_tag
, const std::string
& olh_tag
,
1322 uint64_t olh_epoch
, rgw_zone_set
*zones_trace
= nullptr);
1323 int bucket_index_read_olh_log(const DoutPrefixProvider
*dpp
,
1324 RGWBucketInfo
& bucket_info
, RGWObjState
& state
,
1325 const rgw_obj
& obj_instance
, uint64_t ver_marker
,
1326 std::map
<uint64_t, std::vector
<rgw_bucket_olh_log_entry
> > *log
, bool *is_truncated
);
1327 int bucket_index_trim_olh_log(const DoutPrefixProvider
*dpp
, RGWBucketInfo
& bucket_info
, RGWObjState
& obj_state
, const rgw_obj
& obj_instance
, uint64_t ver
);
1328 int bucket_index_clear_olh(const DoutPrefixProvider
*dpp
, RGWBucketInfo
& bucket_info
, const std::string
& olh_tag
, const rgw_obj
& obj_instance
);
1329 int apply_olh_log(const DoutPrefixProvider
*dpp
, RGWObjectCtx
& obj_ctx
, RGWObjState
& obj_state
, RGWBucketInfo
& bucket_info
, const rgw_obj
& obj
,
1330 bufferlist
& obj_tag
, std::map
<uint64_t, std::vector
<rgw_bucket_olh_log_entry
> >& log
,
1331 uint64_t *plast_ver
, rgw_zone_set
*zones_trace
= nullptr);
1332 int update_olh(const DoutPrefixProvider
*dpp
, RGWObjectCtx
& obj_ctx
, RGWObjState
*state
, RGWBucketInfo
& bucket_info
, const rgw_obj
& obj
, rgw_zone_set
*zones_trace
= nullptr);
1333 int clear_olh(const DoutPrefixProvider
*dpp
,
1334 RGWObjectCtx
& obj_ctx
,
1336 RGWBucketInfo
& bucket_info
,
1337 const std::string
& tag
,
1340 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
,
1341 uint64_t olh_epoch
, ceph::real_time unmod_since
, bool high_precision_time
,
1342 optional_yield y
, rgw_zone_set
*zones_trace
= nullptr, bool log_data_change
= false);
1343 int repair_olh(const DoutPrefixProvider
*dpp
, RGWObjState
* state
, const RGWBucketInfo
& bucket_info
,
1344 const rgw_obj
& obj
);
1345 int unlink_obj_instance(const DoutPrefixProvider
*dpp
, RGWObjectCtx
& obj_ctx
, RGWBucketInfo
& bucket_info
, const rgw_obj
& target_obj
,
1346 uint64_t olh_epoch
, optional_yield y
, rgw_zone_set
*zones_trace
= nullptr);
1348 void check_pending_olh_entries(const DoutPrefixProvider
*dpp
, std::map
<std::string
, bufferlist
>& pending_entries
, std::map
<std::string
, bufferlist
> *rm_pending_entries
);
1349 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
);
1350 int follow_olh(const DoutPrefixProvider
*dpp
, RGWBucketInfo
& bucket_info
, RGWObjectCtx
& ctx
, RGWObjState
*state
, const rgw_obj
& olh_obj
, rgw_obj
*target
);
1351 int get_olh(const DoutPrefixProvider
*dpp
, RGWBucketInfo
& bucket_info
, const rgw_obj
& obj
, RGWOLHInfo
*olh
);
1353 void gen_rand_obj_instance_name(rgw_obj_key
*target_key
);
1354 void gen_rand_obj_instance_name(rgw_obj
*target
);
1356 int update_containers_stats(std::map
<std::string
, RGWBucketEnt
>& m
, const DoutPrefixProvider
*dpp
);
1357 int append_async(const DoutPrefixProvider
*dpp
, rgw_raw_obj
& obj
, size_t size
, bufferlist
& bl
);
1360 void set_atomic(void *ctx
, const rgw_obj
& obj
) {
1361 RGWObjectCtx
*rctx
= static_cast<RGWObjectCtx
*>(ctx
);
1362 rctx
->set_atomic(obj
);
1364 void set_prefetch_data(void *ctx
, const rgw_obj
& obj
) {
1365 RGWObjectCtx
*rctx
= static_cast<RGWObjectCtx
*>(ctx
);
1366 rctx
->set_prefetch_data(obj
);
1368 void set_compressed(void *ctx
, const rgw_obj
& obj
) {
1369 RGWObjectCtx
*rctx
= static_cast<RGWObjectCtx
*>(ctx
);
1370 rctx
->set_compressed(obj
);
1372 int decode_policy(const DoutPrefixProvider
*dpp
, bufferlist
& bl
, ACLOwner
*owner
);
1373 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
,
1374 std::map
<RGWObjCategory
, RGWStorageStats
>& stats
, std::string
*max_marker
, bool* syncstopped
= NULL
);
1375 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
);
1377 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
);
1378 /* xxx dang obj_ctx -> svc */
1379 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
);
1380 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
);
1382 static void make_bucket_entry_name(const std::string
& tenant_name
, const std::string
& bucket_name
, std::string
& bucket_entry
);
1384 int get_bucket_info(RGWServices
*svc
,
1385 const std::string
& tenant_name
, const std::string
& bucket_name
,
1386 RGWBucketInfo
& info
,
1387 ceph::real_time
*pmtime
, optional_yield y
,
1388 const DoutPrefixProvider
*dpp
, std::map
<std::string
, bufferlist
> *pattrs
= NULL
);
1390 // Returns 0 on successful refresh. Returns error code if there was
1391 // an error or the version stored on the OSD is the same as that
1392 // presented in the BucketInfo structure.
1394 int try_refresh_bucket_info(RGWBucketInfo
& info
,
1395 ceph::real_time
*pmtime
,
1396 const DoutPrefixProvider
*dpp
,
1397 std::map
<std::string
, bufferlist
> *pattrs
= nullptr);
1399 int put_linked_bucket_info(RGWBucketInfo
& info
, bool exclusive
, ceph::real_time mtime
, obj_version
*pep_objv
,
1400 std::map
<std::string
, bufferlist
> *pattrs
, bool create_entry_point
,
1401 const DoutPrefixProvider
*dpp
, optional_yield y
);
1403 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);
1404 int cls_obj_complete_op(BucketShard
& bs
, const rgw_obj
& obj
, RGWModifyOp op
, std::string
& tag
, int64_t pool
, uint64_t epoch
,
1405 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);
1406 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
,
1407 RGWObjCategory category
, std::list
<rgw_obj_index_key
> *remove_objs
, uint16_t bilog_flags
, rgw_zone_set
*zones_trace
= nullptr);
1408 int cls_obj_complete_del(BucketShard
& bs
, std::string
& tag
, int64_t pool
, uint64_t epoch
, rgw_obj
& obj
,
1409 ceph::real_time
& removed_mtime
, std::list
<rgw_obj_index_key
> *remove_objs
, uint16_t bilog_flags
, rgw_zone_set
*zones_trace
= nullptr);
1410 int cls_obj_complete_cancel(BucketShard
& bs
, std::string
& tag
, rgw_obj
& obj
,
1411 std::list
<rgw_obj_index_key
> *remove_objs
,
1412 uint16_t bilog_flags
, rgw_zone_set
*zones_trace
= nullptr);
1413 int cls_obj_set_bucket_tag_timeout(const DoutPrefixProvider
*dpp
, RGWBucketInfo
& bucket_info
, uint64_t timeout
);
1416 boost::container::flat_map
<std::string
, rgw_bucket_dir_entry
>;
1418 int cls_bucket_list_ordered(const DoutPrefixProvider
*dpp
,
1419 RGWBucketInfo
& bucket_info
,
1420 const rgw::bucket_index_layout_generation
& idx_layout
,
1422 const rgw_obj_index_key
& start_after
,
1423 const std::string
& prefix
,
1424 const std::string
& delimiter
,
1425 const uint32_t num_entries
,
1426 const bool list_versions
,
1427 const uint16_t exp_factor
, // 0 means ignore
1431 rgw_obj_index_key
*last_entry
,
1433 RGWBucketListNameFilter force_check_filter
= {});
1434 int cls_bucket_list_unordered(const DoutPrefixProvider
*dpp
,
1435 RGWBucketInfo
& bucket_info
,
1436 const rgw::bucket_index_layout_generation
& idx_layout
,
1438 const rgw_obj_index_key
& start_after
,
1439 const std::string
& prefix
,
1440 uint32_t num_entries
,
1442 std::vector
<rgw_bucket_dir_entry
>& ent_list
,
1444 rgw_obj_index_key
*last_entry
,
1446 RGWBucketListNameFilter force_check_filter
= {});
1447 int cls_bucket_head(const DoutPrefixProvider
*dpp
,
1448 const RGWBucketInfo
& bucket_info
,
1449 const rgw::bucket_index_layout_generation
& idx_layout
,
1450 int shard_id
, std::vector
<rgw_bucket_dir_header
>& headers
,
1451 std::map
<int, std::string
> *bucket_instance_ids
= NULL
);
1452 int cls_bucket_head_async(const DoutPrefixProvider
*dpp
,
1453 const RGWBucketInfo
& bucket_info
,
1454 const rgw::bucket_index_layout_generation
& idx_layout
,
1455 int shard_id
, RGWGetDirHeader_CB
*ctx
, int *num_aio
);
1456 int bi_get_instance(const DoutPrefixProvider
*dpp
, const RGWBucketInfo
& bucket_info
, const rgw_obj
& obj
, rgw_bucket_dir_entry
*dirent
);
1457 int bi_get_olh(const DoutPrefixProvider
*dpp
, const RGWBucketInfo
& bucket_info
, const rgw_obj
& obj
, rgw_bucket_olh_entry
*olh
);
1458 int bi_get(const DoutPrefixProvider
*dpp
, const RGWBucketInfo
& bucket_info
, const rgw_obj
& obj
, BIIndexType index_type
, rgw_cls_bi_entry
*entry
);
1459 void bi_put(librados::ObjectWriteOperation
& op
, BucketShard
& bs
, rgw_cls_bi_entry
& entry
);
1460 int bi_put(BucketShard
& bs
, rgw_cls_bi_entry
& entry
);
1461 int bi_put(const DoutPrefixProvider
*dpp
, rgw_bucket
& bucket
, rgw_obj
& obj
, rgw_cls_bi_entry
& entry
);
1462 int bi_list(const DoutPrefixProvider
*dpp
,
1463 const RGWBucketInfo
& bucket_info
,
1465 const std::string
& filter_obj
,
1466 const std::string
& marker
,
1468 std::list
<rgw_cls_bi_entry
> *entries
,
1469 bool *is_truncated
);
1470 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
);
1471 int bi_list(const DoutPrefixProvider
*dpp
, rgw_bucket
& bucket
, const std::string
& obj_name
, const std::string
& marker
, uint32_t max
,
1472 std::list
<rgw_cls_bi_entry
> *entries
, bool *is_truncated
);
1473 int bi_remove(const DoutPrefixProvider
*dpp
, BucketShard
& bs
);
1475 int cls_obj_usage_log_add(const DoutPrefixProvider
*dpp
, const std::string
& oid
, rgw_usage_log_info
& info
);
1476 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
,
1477 uint64_t end_epoch
, uint32_t max_entries
, std::string
& read_iter
,
1478 std::map
<rgw_user_bucket
, rgw_usage_log_entry
>& usage
, bool *is_truncated
);
1479 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
,
1480 uint64_t end_epoch
);
1481 int cls_obj_usage_log_clear(const DoutPrefixProvider
*dpp
, std::string
& oid
);
1483 int get_target_shard_id(const rgw::bucket_index_normal_layout
& layout
, const std::string
& obj_key
, int *shard_id
);
1485 int lock_exclusive(const rgw_pool
& pool
, const std::string
& oid
, ceph::timespan
& duration
, rgw_zone_id
& zone_id
, std::string
& owner_id
);
1486 int unlock(const rgw_pool
& pool
, const std::string
& oid
, rgw_zone_id
& zone_id
, std::string
& owner_id
);
1488 void update_gc_chain(const DoutPrefixProvider
*dpp
, rgw_obj head_obj
, RGWObjManifest
& manifest
, cls_rgw_obj_chain
*chain
);
1489 std::tuple
<int, std::optional
<cls_rgw_obj_chain
>> send_chain_to_gc(cls_rgw_obj_chain
& chain
, const std::string
& tag
);
1490 void delete_objs_inline(const DoutPrefixProvider
*dpp
, cls_rgw_obj_chain
& chain
, const std::string
& tag
);
1491 int gc_operate(const DoutPrefixProvider
*dpp
, std::string
& oid
, librados::ObjectWriteOperation
*op
);
1492 int gc_aio_operate(const std::string
& oid
, librados::AioCompletion
*c
,
1493 librados::ObjectWriteOperation
*op
);
1494 int gc_operate(const DoutPrefixProvider
*dpp
, std::string
& oid
, librados::ObjectReadOperation
*op
, bufferlist
*pbl
);
1496 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
);
1497 int process_gc(bool expired_only
);
1498 bool process_expire_objects(const DoutPrefixProvider
*dpp
);
1499 int defer_gc(const DoutPrefixProvider
*dpp
, RGWObjectCtx
* ctx
, RGWBucketInfo
& bucket_info
, const rgw_obj
& obj
, optional_yield y
);
1501 int process_lc(const std::unique_ptr
<rgw::sal::Bucket
>& optional_bucket
);
1502 int list_lc_progress(std::string
& marker
, uint32_t max_entries
,
1503 std::vector
<std::unique_ptr
<rgw::sal::Lifecycle::LCEntry
>>& progress_map
,
1506 int bucket_check_index(const DoutPrefixProvider
*dpp
, RGWBucketInfo
& bucket_info
,
1507 std::map
<RGWObjCategory
, RGWStorageStats
> *existing_stats
,
1508 std::map
<RGWObjCategory
, RGWStorageStats
> *calculated_stats
);
1509 int bucket_rebuild_index(const DoutPrefixProvider
*dpp
, RGWBucketInfo
& bucket_info
);
1511 // Search the bucket for encrypted multipart uploads, and increase their mtime
1512 // slightly to generate a bilog entry to trigger a resync to repair any
1513 // corrupted replicas. See https://tracker.ceph.com/issues/46062
1514 int bucket_resync_encrypted_multipart(const DoutPrefixProvider
* dpp
,
1516 rgw::sal::RadosStore
* driver
,
1517 RGWBucketInfo
& bucket_info
,
1518 const std::string
& marker
,
1519 RGWFormatterFlusher
& flusher
);
1521 int bucket_set_reshard(const DoutPrefixProvider
*dpp
, const RGWBucketInfo
& bucket_info
, const cls_rgw_bucket_instance_entry
& entry
);
1522 int remove_objs_from_index(const DoutPrefixProvider
*dpp
,
1523 RGWBucketInfo
& bucket_info
,
1524 const std::list
<rgw_obj_index_key
>& oid_list
);
1525 int move_rados_obj(const DoutPrefixProvider
*dpp
,
1526 librados::IoCtx
& src_ioctx
,
1527 const std::string
& src_oid
, const std::string
& src_locator
,
1528 librados::IoCtx
& dst_ioctx
,
1529 const std::string
& dst_oid
, const std::string
& dst_locator
);
1530 int fix_head_obj_locator(const DoutPrefixProvider
*dpp
, const RGWBucketInfo
& bucket_info
, bool copy_obj
, bool remove_bad
, rgw_obj_key
& key
);
1531 int fix_tail_obj_locator(const DoutPrefixProvider
*dpp
, RGWBucketInfo
& bucket_info
,
1532 rgw_obj_key
& key
, bool fix
, bool *need_fix
, optional_yield y
);
1534 int check_quota(const DoutPrefixProvider
*dpp
, const rgw_user
& bucket_owner
, rgw_bucket
& bucket
,
1535 RGWQuota
& quota
, uint64_t obj_size
,
1536 optional_yield y
, bool check_size_only
= false);
1538 int check_bucket_shards(const RGWBucketInfo
& bucket_info
, const rgw_bucket
& bucket
,
1539 uint64_t num_objs
, const DoutPrefixProvider
*dpp
);
1541 int add_bucket_to_reshard(const DoutPrefixProvider
*dpp
, const RGWBucketInfo
& bucket_info
, uint32_t new_num_shards
);
1543 uint64_t instance_id();
1545 librados::Rados
* get_rados_handle();
1547 int delete_raw_obj_aio(const DoutPrefixProvider
*dpp
, const rgw_raw_obj
& obj
, std::list
<librados::AioCompletion
*>& handles
);
1548 int delete_obj_aio(const DoutPrefixProvider
*dpp
, const rgw_obj
& obj
, RGWBucketInfo
& info
, RGWObjState
*astate
,
1549 std::list
<librados::AioCompletion
*>& handles
, bool keep_index_consistent
,
1554 * Check the actual on-disk state of the object specified
1555 * by list_state, and fill in the time and size of object.
1556 * Then append any changes to suggested_updates for
1557 * the rgw class' dir_suggest_changes function.
1559 * Note that this can maul list_state; don't use it afterwards. Also
1560 * it expects object to already be filled in from list_state; it only
1561 * sets the size and mtime.
1563 * Returns 0 on success, -ENOENT if the object doesn't exist on disk,
1564 * and -errno on other failures. (-ENOENT is not a failure, and it
1565 * will encode that info as a suggested update.)
1567 int check_disk_state(const DoutPrefixProvider
*dpp
,
1568 librados::IoCtx io_ctx
,
1569 RGWBucketInfo
& bucket_info
,
1570 rgw_bucket_dir_entry
& list_state
,
1571 rgw_bucket_dir_entry
& object
,
1572 bufferlist
& suggested_updates
,
1576 * Init pool iteration
1577 * pool: pool to use for the ctx initialization
1578 * ctx: context object to use for the iteration
1579 * Returns: 0 on success, -ERR# otherwise.
1581 int pool_iterate_begin(const DoutPrefixProvider
*dpp
, const rgw_pool
& pool
, RGWPoolIterCtx
& ctx
);
1584 * Init pool iteration
1586 * cursor: position to start iteration
1587 * ctx: context object to use for the iteration
1588 * Returns: 0 on success, -ERR# otherwise.
1590 int pool_iterate_begin(const DoutPrefixProvider
*dpp
, const rgw_pool
& pool
, const std::string
& cursor
, RGWPoolIterCtx
& ctx
);
1593 * Get pool iteration position
1594 * ctx: context object to use for the iteration
1595 * Returns: std::string representation of position
1597 std::string
pool_iterate_get_cursor(RGWPoolIterCtx
& ctx
);
1600 * Iterate over pool return object names, use optional filter
1601 * ctx: iteration context, initialized with pool_iterate_begin()
1602 * num: max number of objects to return
1603 * objs: a vector that the results will append into
1604 * is_truncated: if not NULL, will hold true iff iteration is complete
1605 * filter: if not NULL, will be used to filter returned objects
1606 * Returns: 0 on success, -ERR# otherwise.
1608 int pool_iterate(const DoutPrefixProvider
*dpp
, RGWPoolIterCtx
& ctx
, uint32_t num
,
1609 std::vector
<rgw_bucket_dir_entry
>& objs
,
1610 bool *is_truncated
, RGWAccessListFilter
*filter
);
1612 uint64_t next_bucket_id();
1615 * This is broken out to facilitate unit testing.
1617 static uint32_t calc_ordered_bucket_list_per_shard(uint32_t num_entries
,
1618 uint32_t num_shards
);
1622 struct get_obj_data
{
1624 RGWGetDataCB
* client_cb
= nullptr;
1626 uint64_t offset
; // next offset to write to client
1627 rgw::AioResultList completed
; // completed read results, sorted by offset
1628 optional_yield yield
;
1630 get_obj_data(RGWRados
* rgwrados
, RGWGetDataCB
* cb
, rgw::Aio
* aio
,
1631 uint64_t offset
, optional_yield yield
)
1632 : rgwrados(rgwrados
), client_cb(cb
), aio(aio
), offset(offset
), yield(yield
) {}
1634 if (rgwrados
->get_use_datacache()) {
1635 const std::lock_guard
l(d3n_get_data
.d3n_lock
);
1639 D3nGetObjData d3n_get_data
;
1640 std::atomic_bool d3n_bypass_cache_write
{false};
1642 int flush(rgw::AioResultList
&& results
);
1645 // wait for all completions to drain and ignore the results
1650 auto c
= aio
->wait();
1651 while (!c
.empty()) {
1652 int r
= flush(std::move(c
));
1659 return flush(std::move(c
));