1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #ifndef CEPH_RGWRADOS_H
5 #define CEPH_RGWRADOS_H
9 #include "include/rados/librados.hpp"
10 #include "include/Context.h"
11 #include "common/admin_socket.h"
12 #include "common/RefCountedObj.h"
13 #include "common/RWLock.h"
14 #include "common/ceph_time.h"
15 #include "common/lru_map.h"
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"
20 #include "cls/statelog/cls_statelog_types.h"
21 #include "cls/timeindex/cls_timeindex_types.h"
23 #include "rgw_metadata.h"
24 #include "rgw_meta_sync_status.h"
25 #include "rgw_period_puller.h"
26 #include "rgw_sync_module.h"
27 #include "rgw_sync_log_trim.h"
33 class RGWMetaNotifier
;
34 class RGWDataNotifier
;
36 class RGWObjectExpirer
;
37 class RGWMetaSyncProcessorThread
;
38 class RGWDataSyncProcessorThread
;
39 class RGWSyncLogTrimThread
;
46 /* flags for put_obj_meta() */
47 #define PUT_OBJ_CREATE 0x01
48 #define PUT_OBJ_EXCL 0x02
49 #define PUT_OBJ_CREATE_EXCL (PUT_OBJ_CREATE | PUT_OBJ_EXCL)
51 #define RGW_OBJ_NS_MULTIPART "multipart"
52 #define RGW_OBJ_NS_SHADOW "shadow"
54 #define RGW_BUCKET_INSTANCE_MD_PREFIX ".bucket.meta."
56 #define RGW_NO_SHARD -1
58 #define RGW_SHARDS_PRIME_0 7877
59 #define RGW_SHARDS_PRIME_1 65521
61 // only called by rgw_shard_id and rgw_bucket_shard_index
62 static inline int rgw_shards_mod(unsigned hval
, int max_shards
)
64 if (max_shards
<= RGW_SHARDS_PRIME_0
) {
65 return hval
% RGW_SHARDS_PRIME_0
% max_shards
;
67 return hval
% RGW_SHARDS_PRIME_1
% max_shards
;
70 // used for logging and tagging
71 static inline int rgw_shard_id(const string
& key
, int max_shards
)
73 return rgw_shards_mod(ceph_str_hash_linux(key
.c_str(), key
.size()),
77 // used for bucket indices
78 static inline uint32_t rgw_bucket_shard_index(const std::string
& key
,
80 uint32_t sid
= ceph_str_hash_linux(key
.c_str(), key
.size());
81 uint32_t sid2
= sid
^ ((sid
& 0xFF) << 24);
82 return rgw_shards_mod(sid2
, num_shards
);
85 static inline int rgw_shards_max()
87 return RGW_SHARDS_PRIME_1
;
90 static inline void prepend_bucket_marker(const rgw_bucket
& bucket
, const string
& orig_oid
, string
& oid
)
92 if (bucket
.marker
.empty() || orig_oid
.empty()) {
101 static inline void get_obj_bucket_and_oid_loc(const rgw_obj
& obj
, string
& oid
, string
& locator
)
103 const rgw_bucket
& bucket
= obj
.bucket
;
104 prepend_bucket_marker(bucket
, obj
.get_oid(), oid
);
105 const string
& loc
= obj
.key
.get_loc();
107 prepend_bucket_marker(bucket
, loc
, locator
);
113 int rgw_init_ioctx(librados::Rados
*rados
, const rgw_pool
& pool
, librados::IoCtx
& ioctx
, bool create
= false);
115 int rgw_policy_from_attrset(CephContext
*cct
, map
<string
, bufferlist
>& attrset
, RGWAccessControlPolicy
*policy
);
117 static inline bool rgw_raw_obj_to_obj(const rgw_bucket
& bucket
, const rgw_raw_obj
& raw_obj
, rgw_obj
*obj
)
119 ssize_t pos
= raw_obj
.oid
.find('_');
124 if (!rgw_obj_key::parse_raw_oid(raw_obj
.oid
.substr(pos
+ 1), &obj
->key
)) {
127 obj
->bucket
= bucket
;
132 struct rgw_bucket_placement
{
133 string placement_rule
;
136 void dump(Formatter
*f
) const;
139 class rgw_obj_select
{
140 string placement_rule
;
146 rgw_obj_select() : is_raw(false) {}
147 rgw_obj_select(const rgw_obj
& _obj
) : obj(_obj
), is_raw(false) {}
148 rgw_obj_select(const rgw_raw_obj
& _raw_obj
) : raw_obj(_raw_obj
), is_raw(true) {}
149 rgw_obj_select(const rgw_obj_select
& rhs
) {
150 placement_rule
= rhs
.placement_rule
;
153 raw_obj
= rhs
.raw_obj
;
159 rgw_raw_obj
get_raw_obj(const RGWZoneGroup
& zonegroup
, const RGWZoneParams
& zone_params
) const;
160 rgw_raw_obj
get_raw_obj(RGWRados
*store
) const;
162 rgw_obj_select
& operator=(const rgw_obj
& rhs
) {
168 rgw_obj_select
& operator=(const rgw_raw_obj
& rhs
) {
174 void set_placement_rule(const string
& rule
) {
175 placement_rule
= rule
;
179 struct compression_block
{
184 void encode(bufferlist
& bl
) const {
185 ENCODE_START(1, 1, bl
);
186 ::encode(old_ofs
, bl
);
187 ::encode(new_ofs
, bl
);
192 void decode(bufferlist::iterator
& bl
) {
194 ::decode(old_ofs
, bl
);
195 ::decode(new_ofs
, bl
);
200 WRITE_CLASS_ENCODER(compression_block
)
202 struct RGWCompressionInfo
{
203 string compression_type
;
205 vector
<compression_block
> blocks
;
207 RGWCompressionInfo() : compression_type("none"), orig_size(0) {}
208 RGWCompressionInfo(const RGWCompressionInfo
& cs_info
) : compression_type(cs_info
.compression_type
),
209 orig_size(cs_info
.orig_size
),
210 blocks(cs_info
.blocks
) {}
212 void encode(bufferlist
& bl
) const {
213 ENCODE_START(1, 1, bl
);
214 ::encode(compression_type
, bl
);
215 ::encode(orig_size
, bl
);
216 ::encode(blocks
, bl
);
220 void decode(bufferlist::iterator
& bl
) {
222 ::decode(compression_type
, bl
);
223 ::decode(orig_size
, bl
);
224 ::decode(blocks
, bl
);
228 WRITE_CLASS_ENCODER(RGWCompressionInfo
)
230 int rgw_compression_info_from_attrset(map
<string
, bufferlist
>& attrs
, bool& need_decompress
, RGWCompressionInfo
& cs_info
);
236 RGWOLHInfo() : removed(false) {}
238 void encode(bufferlist
& bl
) const {
239 ENCODE_START(1, 1, bl
);
240 ::encode(target
, bl
);
241 ::encode(removed
, bl
);
245 void decode(bufferlist::iterator
& bl
) {
247 ::decode(target
, bl
);
248 ::decode(removed
, bl
);
251 static void generate_test_instances(list
<RGWOLHInfo
*>& o
);
252 void dump(Formatter
*f
) const;
254 WRITE_CLASS_ENCODER(RGWOLHInfo
)
256 struct RGWOLHPendingInfo
{
257 ceph::real_time time
;
259 RGWOLHPendingInfo() {}
261 void encode(bufferlist
& bl
) const {
262 ENCODE_START(1, 1, bl
);
267 void decode(bufferlist::iterator
& bl
) {
273 void dump(Formatter
*f
) const;
275 WRITE_CLASS_ENCODER(RGWOLHPendingInfo
)
277 struct RGWUsageBatch
{
278 map
<ceph::real_time
, rgw_usage_log_entry
> m
;
280 void insert(ceph::real_time
& t
, rgw_usage_log_entry
& entry
, bool *account
) {
281 bool exists
= m
.find(t
) != m
.end();
283 m
[t
].aggregate(entry
);
287 struct RGWUsageIter
{
291 RGWUsageIter() : index(0) {}
296 uint64_t extra_data_len
;
298 virtual int handle_data(bufferlist
& bl
, off_t bl_ofs
, off_t bl_len
) = 0;
299 RGWGetDataCB() : extra_data_len(0) {}
300 virtual ~RGWGetDataCB() {}
301 virtual void set_extra_data_len(uint64_t len
) {
302 extra_data_len
= len
;
305 * Flushes any cached data. Used by RGWGetObjFilter.
306 * Return logic same as handle_data.
308 virtual int flush() {
312 * Allows to extend fetch range of RGW object. Used by RGWGetObjFilter.
314 virtual int fixup_range(off_t
& bl_ofs
, off_t
& bl_end
) {
319 class RGWAccessListFilter
{
321 virtual ~RGWAccessListFilter() {}
322 virtual bool filter(string
& name
, string
& key
) = 0;
325 struct RGWCloneRangeInfo
{
332 struct RGWObjManifestPart
{
333 rgw_obj loc
; /* the object where the data is located */
334 uint64_t loc_ofs
; /* the offset at that object where the data is located */
335 uint64_t size
; /* the part size */
337 RGWObjManifestPart() : loc_ofs(0), size(0) {}
339 void encode(bufferlist
& bl
) const {
340 ENCODE_START(2, 2, bl
);
342 ::encode(loc_ofs
, bl
);
347 void decode(bufferlist::iterator
& bl
) {
348 DECODE_START_LEGACY_COMPAT_LEN_32(2, 2, 2, bl
);
350 ::decode(loc_ofs
, bl
);
355 void dump(Formatter
*f
) const;
356 static void generate_test_instances(list
<RGWObjManifestPart
*>& o
);
358 WRITE_CLASS_ENCODER(RGWObjManifestPart
)
361 The manifest defines a set of rules for structuring the object parts.
362 There are a few terms to note:
363 - head: the head part of the object, which is the part that contains
364 the first chunk of data. An object might not have a head (as in the
365 case of multipart-part objects).
366 - stripe: data portion of a single rgw object that resides on a single
368 - part: a collection of stripes that make a contiguous part of an
369 object. A regular object will only have one part (although might have
370 many stripes), a multipart object might have many parts. Each part
371 has a fixed stripe size, although the last stripe of a part might
372 be smaller than that. Consecutive parts may be merged if their stripe
376 struct RGWObjManifestRule
{
377 uint32_t start_part_num
;
379 uint64_t part_size
; /* each part size, 0 if there's no part size, meaning it's unlimited */
380 uint64_t stripe_max_size
; /* underlying obj max size */
381 string override_prefix
;
383 RGWObjManifestRule() : start_part_num(0), start_ofs(0), part_size(0), stripe_max_size(0) {}
384 RGWObjManifestRule(uint32_t _start_part_num
, uint64_t _start_ofs
, uint64_t _part_size
, uint64_t _stripe_max_size
) :
385 start_part_num(_start_part_num
), start_ofs(_start_ofs
), part_size(_part_size
), stripe_max_size(_stripe_max_size
) {}
387 void encode(bufferlist
& bl
) const {
388 ENCODE_START(2, 1, bl
);
389 ::encode(start_part_num
, bl
);
390 ::encode(start_ofs
, bl
);
391 ::encode(part_size
, bl
);
392 ::encode(stripe_max_size
, bl
);
393 ::encode(override_prefix
, bl
);
397 void decode(bufferlist::iterator
& bl
) {
399 ::decode(start_part_num
, bl
);
400 ::decode(start_ofs
, bl
);
401 ::decode(part_size
, bl
);
402 ::decode(stripe_max_size
, bl
);
404 ::decode(override_prefix
, bl
);
407 void dump(Formatter
*f
) const;
409 WRITE_CLASS_ENCODER(RGWObjManifestRule
)
411 class RGWObjManifest
{
413 bool explicit_objs
; /* old manifest? */
414 map
<uint64_t, RGWObjManifestPart
> objs
;
420 string head_placement_rule
;
422 uint64_t max_head_size
;
424 rgw_bucket_placement tail_placement
; /* might be different than the original bucket,
425 as object might have been copied across pools */
426 map
<uint64_t, RGWObjManifestRule
> rules
;
428 string tail_instance
; /* tail object's instance */
430 void convert_to_explicit(const RGWZoneGroup
& zonegroup
, const RGWZoneParams
& zone_params
);
431 int append_explicit(RGWObjManifest
& m
, const RGWZoneGroup
& zonegroup
, const RGWZoneParams
& zone_params
);
432 void append_rules(RGWObjManifest
& m
, map
<uint64_t, RGWObjManifestRule
>::iterator
& iter
, string
*override_prefix
);
434 void update_iterators() {
436 end_iter
.seek(obj_size
);
440 RGWObjManifest() : explicit_objs(false), obj_size(0), head_size(0), max_head_size(0),
441 begin_iter(this), end_iter(this) {}
442 RGWObjManifest(const RGWObjManifest
& rhs
) {
445 RGWObjManifest
& operator=(const RGWObjManifest
& rhs
) {
446 explicit_objs
= rhs
.explicit_objs
;
448 obj_size
= rhs
.obj_size
;
450 head_size
= rhs
.head_size
;
451 max_head_size
= rhs
.max_head_size
;
453 tail_placement
= rhs
.tail_placement
;
455 tail_instance
= rhs
.tail_instance
;
457 begin_iter
.set_manifest(this);
458 end_iter
.set_manifest(this);
460 begin_iter
.seek(rhs
.begin_iter
.get_ofs());
461 end_iter
.seek(rhs
.end_iter
.get_ofs());
466 map
<uint64_t, RGWObjManifestPart
>& get_explicit_objs() {
471 void set_explicit(uint64_t _size
, map
<uint64_t, RGWObjManifestPart
>& _objs
) {
472 explicit_objs
= true;
477 void get_implicit_location(uint64_t cur_part_id
, uint64_t cur_stripe
, uint64_t ofs
, string
*override_prefix
, rgw_obj_select
*location
);
479 void set_trivial_rule(uint64_t tail_ofs
, uint64_t stripe_max_size
) {
480 RGWObjManifestRule
rule(0, tail_ofs
, 0, stripe_max_size
);
482 max_head_size
= tail_ofs
;
485 void set_multipart_part_rule(uint64_t stripe_max_size
, uint64_t part_num
) {
486 RGWObjManifestRule
rule(0, 0, 0, stripe_max_size
);
487 rule
.start_part_num
= part_num
;
492 void encode(bufferlist
& bl
) const {
493 ENCODE_START(7, 6, bl
);
494 ::encode(obj_size
, bl
);
496 ::encode(explicit_objs
, bl
);
498 ::encode(head_size
, bl
);
499 ::encode(max_head_size
, bl
);
500 ::encode(prefix
, bl
);
502 bool encode_tail_bucket
= !(tail_placement
.bucket
== obj
.bucket
);
503 ::encode(encode_tail_bucket
, bl
);
504 if (encode_tail_bucket
) {
505 ::encode(tail_placement
.bucket
, bl
);
507 bool encode_tail_instance
= (tail_instance
!= obj
.key
.instance
);
508 ::encode(encode_tail_instance
, bl
);
509 if (encode_tail_instance
) {
510 ::encode(tail_instance
, bl
);
512 ::encode(head_placement_rule
, bl
);
513 ::encode(tail_placement
.placement_rule
, bl
);
517 void decode(bufferlist::iterator
& bl
) {
518 DECODE_START_LEGACY_COMPAT_LEN_32(7, 2, 2, bl
);
519 ::decode(obj_size
, bl
);
522 ::decode(explicit_objs
, bl
);
524 ::decode(head_size
, bl
);
525 ::decode(max_head_size
, bl
);
526 ::decode(prefix
, bl
);
529 explicit_objs
= true;
531 map
<uint64_t, RGWObjManifestPart
>::iterator iter
= objs
.begin();
532 obj
= iter
->second
.loc
;
533 head_size
= iter
->second
.size
;
534 max_head_size
= head_size
;
538 if (explicit_objs
&& head_size
> 0 && !objs
.empty()) {
539 /* patch up manifest due to issue 16435:
540 * the first object in the explicit objs list might not be the one we need to access, use the
541 * head object instead if set. This would happen if we had an old object that was created
542 * when the explicit objs manifest was around, and it got copied.
544 rgw_obj
& obj_0
= objs
[0].loc
;
545 if (!obj_0
.get_oid().empty() && obj_0
.key
.ns
.empty()) {
547 objs
[0].size
= head_size
;
553 ::decode(tail_placement
.bucket
, bl
);
556 ::decode(need_to_decode
, bl
);
557 if (need_to_decode
) {
558 ::decode(tail_placement
.bucket
, bl
);
560 tail_placement
.bucket
= obj
.bucket
;
567 ::decode(tail_instance
, bl
);
570 ::decode(need_to_decode
, bl
);
571 if (need_to_decode
) {
572 ::decode(tail_instance
, bl
);
574 tail_instance
= obj
.key
.instance
;
577 } else { // old object created before 'tail_instance' field added to manifest
578 tail_instance
= obj
.key
.instance
;
582 ::decode(head_placement_rule
, bl
);
583 ::decode(tail_placement
.placement_rule
, bl
);
590 void dump(Formatter
*f
) const;
591 static void generate_test_instances(list
<RGWObjManifest
*>& o
);
593 int append(RGWObjManifest
& m
, RGWZoneGroup
& zonegroup
, RGWZoneParams
& zone_params
);
594 int append(RGWObjManifest
& m
, RGWRados
*store
);
596 bool get_rule(uint64_t ofs
, RGWObjManifestRule
*rule
);
601 return rules
.empty();
604 bool has_explicit_objs() {
605 return explicit_objs
;
610 if (objs
.size() == 1) {
611 map
<uint64_t, RGWObjManifestPart
>::iterator iter
= objs
.begin();
612 rgw_obj
& o
= iter
->second
.loc
;
615 return (objs
.size() >= 2);
617 return (obj_size
> head_size
);
620 void set_head(const string
& placement_rule
, const rgw_obj
& _o
, uint64_t _s
) {
621 head_placement_rule
= placement_rule
;
625 if (explicit_objs
&& head_size
> 0) {
627 objs
[0].size
= head_size
;
631 const rgw_obj
& get_obj() {
635 void set_tail_placement(const string
& placement_rule
, const rgw_bucket
& _b
) {
636 tail_placement
.placement_rule
= placement_rule
;
637 tail_placement
.bucket
= _b
;
640 const rgw_bucket_placement
& get_tail_placement() {
641 return tail_placement
;
644 const string
& get_head_placement_rule() {
645 return head_placement_rule
;
648 void set_prefix(const string
& _p
) {
652 const string
& get_prefix() {
656 void set_tail_instance(const string
& _ti
) {
660 const string
& get_tail_instance() {
661 return tail_instance
;
664 void set_head_size(uint64_t _s
) {
668 void set_obj_size(uint64_t s
) {
674 uint64_t get_obj_size() {
678 uint64_t get_head_size() {
682 void set_max_head_size(uint64_t s
) {
686 uint64_t get_max_head_size() {
687 return max_head_size
;
691 RGWObjManifest
*manifest
;
692 uint64_t part_ofs
; /* where current part starts */
693 uint64_t stripe_ofs
; /* where current stripe starts */
694 uint64_t ofs
; /* current position within the object */
695 uint64_t stripe_size
; /* current part size */
699 string cur_override_prefix
;
701 rgw_obj_select location
;
703 map
<uint64_t, RGWObjManifestRule
>::iterator rule_iter
;
704 map
<uint64_t, RGWObjManifestRule
>::iterator next_rule_iter
;
706 map
<uint64_t, RGWObjManifestPart
>::iterator explicit_iter
;
717 void update_explicit_pos();
722 void set_manifest(RGWObjManifest
*m
) {
727 obj_iterator() : manifest(NULL
) {
730 explicit obj_iterator(RGWObjManifest
*_m
) : manifest(_m
) {
732 if (!manifest
->empty()) {
736 obj_iterator(RGWObjManifest
*_m
, uint64_t _ofs
) : manifest(_m
) {
738 if (!manifest
->empty()) {
742 void seek(uint64_t ofs
);
745 bool operator==(const obj_iterator
& rhs
) {
746 return (ofs
== rhs
.ofs
);
748 bool operator!=(const obj_iterator
& rhs
) {
749 return (ofs
!= rhs
.ofs
);
751 const rgw_obj_select
& get_location() {
755 /* start of current stripe */
756 uint64_t get_stripe_ofs() {
757 if (manifest
->explicit_objs
) {
758 return explicit_iter
->first
;
763 /* current ofs relative to start of rgw object */
764 uint64_t get_ofs() const {
769 int get_cur_stripe() const {
773 /* current stripe size */
774 uint64_t get_stripe_size() {
775 if (manifest
->explicit_objs
) {
776 return explicit_iter
->second
.size
;
781 /* offset where data starts within current stripe */
782 uint64_t location_ofs() {
783 if (manifest
->explicit_objs
) {
784 return explicit_iter
->second
.loc_ofs
;
786 return 0; /* all stripes start at zero offset */
789 void update_location();
791 friend class RGWObjManifest
;
794 const obj_iterator
& obj_begin();
795 const obj_iterator
& obj_end();
796 obj_iterator
obj_find(uint64_t ofs
);
798 obj_iterator begin_iter
;
799 obj_iterator end_iter
;
802 * simple object generator. Using a simple single rule manifest.
805 RGWObjManifest
*manifest
;
807 uint64_t cur_part_ofs
;
810 uint64_t cur_stripe_size
;
815 rgw_obj_select cur_obj
;
817 RGWObjManifestRule rule
;
820 generator() : manifest(NULL
), last_ofs(0), cur_part_ofs(0), cur_part_id(0),
821 cur_stripe(0), cur_stripe_size(0) {}
822 int create_begin(CephContext
*cct
, RGWObjManifest
*manifest
, const string
& placement_rule
, rgw_bucket
& bucket
, rgw_obj
& obj
);
824 int create_next(uint64_t ofs
);
826 rgw_raw_obj
get_cur_obj(RGWZoneGroup
& zonegroup
, RGWZoneParams
& zone_params
) { return cur_obj
.get_raw_obj(zonegroup
, zone_params
); }
827 rgw_raw_obj
get_cur_obj(RGWRados
*store
) { return cur_obj
.get_raw_obj(store
); }
829 /* total max size of current stripe (including head obj) */
830 uint64_t cur_stripe_max_size() {
831 return cur_stripe_size
;
835 WRITE_CLASS_ENCODER(RGWObjManifest
)
837 struct RGWUploadPartInfo
{
840 uint64_t accounted_size
{0};
842 ceph::real_time modified
;
843 RGWObjManifest manifest
;
844 RGWCompressionInfo cs_info
;
846 RGWUploadPartInfo() : num(0), size(0) {}
848 void encode(bufferlist
& bl
) const {
849 ENCODE_START(4, 2, bl
);
853 ::encode(modified
, bl
);
854 ::encode(manifest
, bl
);
855 ::encode(cs_info
, bl
);
856 ::encode(accounted_size
, bl
);
859 void decode(bufferlist::iterator
& bl
) {
860 DECODE_START_LEGACY_COMPAT_LEN(4, 2, 2, bl
);
864 ::decode(modified
, bl
);
866 ::decode(manifest
, bl
);
868 ::decode(cs_info
, bl
);
869 ::decode(accounted_size
, bl
);
871 accounted_size
= size
;
875 void dump(Formatter
*f
) const;
876 static void generate_test_instances(list
<RGWUploadPartInfo
*>& o
);
878 WRITE_CLASS_ENCODER(RGWUploadPartInfo
)
885 uint64_t size
; //< size of raw object
886 uint64_t accounted_size
{0}; //< size before compression, encryption
887 ceph::real_time mtime
;
893 RGWObjManifest manifest
;
903 uint32_t zone_short_id
;
905 /* important! don't forget to update copy constructor */
907 RGWObjVersionTracker objv_tracker
;
909 map
<string
, bufferlist
> attrset
;
910 RGWObjState() : is_atomic(false), has_attrs(0), exists(false),
911 size(0), epoch(0), fake_tag(false), has_manifest(false),
912 has_data(false), prefetch_data(false), keep_tail(false), is_olh(false),
913 pg_ver(0), zone_short_id(0) {}
914 RGWObjState(const RGWObjState
& rhs
) : obj (rhs
.obj
) {
915 is_atomic
= rhs
.is_atomic
;
916 has_attrs
= rhs
.has_attrs
;
919 accounted_size
= rhs
.accounted_size
;
922 if (rhs
.obj_tag
.length()) {
923 obj_tag
= rhs
.obj_tag
;
925 if (rhs
.tail_tag
.length()) {
926 tail_tag
= rhs
.tail_tag
;
928 write_tag
= rhs
.write_tag
;
929 fake_tag
= rhs
.fake_tag
;
930 if (rhs
.has_manifest
) {
931 manifest
= rhs
.manifest
;
933 has_manifest
= rhs
.has_manifest
;
934 shadow_obj
= rhs
.shadow_obj
;
935 has_data
= rhs
.has_data
;
936 if (rhs
.data
.length()) {
939 prefetch_data
= rhs
.prefetch_data
;
940 keep_tail
= rhs
.keep_tail
;
942 objv_tracker
= rhs
.objv_tracker
;
946 bool get_attr(string name
, bufferlist
& dest
) {
947 map
<string
, bufferlist
>::iterator iter
= attrset
.find(name
);
948 if (iter
!= attrset
.end()) {
956 struct RGWRawObjState
{
958 bool has_attrs
{false};
961 ceph::real_time mtime
;
964 bool has_data
{false};
966 bool prefetch_data
{false};
969 /* important! don't forget to update copy constructor */
971 RGWObjVersionTracker objv_tracker
;
973 map
<string
, bufferlist
> attrset
;
975 RGWRawObjState(const RGWRawObjState
& rhs
) : obj (rhs
.obj
) {
976 has_attrs
= rhs
.has_attrs
;
981 if (rhs
.obj_tag
.length()) {
982 obj_tag
= rhs
.obj_tag
;
984 has_data
= rhs
.has_data
;
985 if (rhs
.data
.length()) {
988 prefetch_data
= rhs
.prefetch_data
;
990 objv_tracker
= rhs
.objv_tracker
;
994 struct RGWPoolIterCtx
{
995 librados::IoCtx io_ctx
;
996 librados::NObjectIterator iter
;
999 struct RGWListRawObjsCtx
{
1001 RGWPoolIterCtx iter_ctx
;
1003 RGWListRawObjsCtx() : initialized(false) {}
1006 struct RGWDefaultSystemMetaObjInfo
{
1009 void encode(bufferlist
& bl
) const {
1010 ENCODE_START(1, 1, bl
);
1011 ::encode(default_id
, bl
);
1015 void decode(bufferlist::iterator
& bl
) {
1016 DECODE_START(1, bl
);
1017 ::decode(default_id
, bl
);
1021 void dump(Formatter
*f
) const;
1022 void decode_json(JSONObj
*obj
);
1024 WRITE_CLASS_ENCODER(RGWDefaultSystemMetaObjInfo
)
1026 struct RGWNameToId
{
1029 void encode(bufferlist
& bl
) const {
1030 ENCODE_START(1, 1, bl
);
1031 ::encode(obj_id
, bl
);
1035 void decode(bufferlist::iterator
& bl
) {
1036 DECODE_START(1, bl
);
1037 ::decode(obj_id
, bl
);
1041 void dump(Formatter
*f
) const;
1042 void decode_json(JSONObj
*obj
);
1044 WRITE_CLASS_ENCODER(RGWNameToId
)
1046 class RGWSystemMetaObj
{
1054 int store_name(bool exclusive
);
1055 int store_info(bool exclusive
);
1056 int read_info(const string
& obj_id
, bool old_format
= false);
1057 int read_id(const string
& obj_name
, string
& obj_id
);
1058 int read_default(RGWDefaultSystemMetaObjInfo
& default_info
,
1060 /* read and use default id */
1061 int use_default(bool old_format
= false);
1064 RGWSystemMetaObj() : cct(NULL
), store(NULL
) {}
1065 RGWSystemMetaObj(const string
& _name
): name(_name
), cct(NULL
), store(NULL
) {}
1066 RGWSystemMetaObj(const string
& _id
, const string
& _name
) : id(_id
), name(_name
), cct(NULL
), store(NULL
) {}
1067 RGWSystemMetaObj(CephContext
*_cct
, RGWRados
*_store
): cct(_cct
), store(_store
){}
1068 RGWSystemMetaObj(const string
& _name
, CephContext
*_cct
, RGWRados
*_store
): name(_name
), cct(_cct
), store(_store
){}
1069 const string
& get_name() const { return name
; }
1070 const string
& get_id() const { return id
; }
1072 void set_name(const string
& _name
) { name
= _name
;}
1073 void set_id(const string
& _id
) { id
= _id
;}
1074 void clear_id() { id
.clear(); }
1076 virtual ~RGWSystemMetaObj() {}
1078 virtual void encode(bufferlist
& bl
) const {
1079 ENCODE_START(1, 1, bl
);
1085 virtual void decode(bufferlist::iterator
& bl
) {
1086 DECODE_START(1, bl
);
1092 void reinit_instance(CephContext
*_cct
, RGWRados
*_store
) {
1096 int init(CephContext
*_cct
, RGWRados
*_store
, bool setup_obj
= true, bool old_format
= false);
1097 virtual int read_default_id(string
& default_id
, bool old_format
= false);
1098 virtual int set_as_default(bool exclusive
= false);
1099 int delete_default();
1100 virtual int create(bool exclusive
= true);
1101 int delete_obj(bool old_format
= false);
1102 int rename(const string
& new_name
);
1103 int update() { return store_info(false);}
1104 int update_name() { return store_name(false);}
1106 int write(bool exclusive
);
1108 virtual rgw_pool
get_pool(CephContext
*cct
) = 0;
1109 virtual const string
get_default_oid(bool old_format
= false) = 0;
1110 virtual const string
& get_names_oid_prefix() = 0;
1111 virtual const string
& get_info_oid_prefix(bool old_format
= false) = 0;
1112 virtual const string
& get_predefined_name(CephContext
*cct
) = 0;
1114 void dump(Formatter
*f
) const;
1115 void decode_json(JSONObj
*obj
);
1117 WRITE_CLASS_ENCODER(RGWSystemMetaObj
)
1119 struct RGWZonePlacementInfo
{
1120 rgw_pool index_pool
;
1122 rgw_pool data_extra_pool
; /* if not set we should use data_pool */
1123 RGWBucketIndexType index_type
;
1124 std::string compression_type
;
1126 RGWZonePlacementInfo() : index_type(RGWBIType_Normal
) {}
1128 void encode(bufferlist
& bl
) const {
1129 ENCODE_START(6, 1, bl
);
1130 ::encode(index_pool
.to_str(), bl
);
1131 ::encode(data_pool
.to_str(), bl
);
1132 ::encode(data_extra_pool
.to_str(), bl
);
1133 ::encode((uint32_t)index_type
, bl
);
1134 ::encode(compression_type
, bl
);
1138 void decode(bufferlist::iterator
& bl
) {
1139 DECODE_START(6, bl
);
1140 string index_pool_str
;
1141 string data_pool_str
;
1142 ::decode(index_pool_str
, bl
);
1143 index_pool
= rgw_pool(index_pool_str
);
1144 ::decode(data_pool_str
, bl
);
1145 data_pool
= rgw_pool(data_pool_str
);
1146 if (struct_v
>= 4) {
1147 string data_extra_pool_str
;
1148 ::decode(data_extra_pool_str
, bl
);
1149 data_extra_pool
= rgw_pool(data_extra_pool_str
);
1151 if (struct_v
>= 5) {
1154 index_type
= (RGWBucketIndexType
)it
;
1156 if (struct_v
>= 6) {
1157 ::decode(compression_type
, bl
);
1161 const rgw_pool
& get_data_extra_pool() const {
1162 if (data_extra_pool
.empty()) {
1165 return data_extra_pool
;
1167 void dump(Formatter
*f
) const;
1168 void decode_json(JSONObj
*obj
);
1170 WRITE_CLASS_ENCODER(RGWZonePlacementInfo
)
1172 struct RGWZoneParams
: RGWSystemMetaObj
{
1173 rgw_pool domain_root
;
1174 rgw_pool metadata_heap
;
1175 rgw_pool control_pool
;
1179 rgw_pool intent_log_pool
;
1180 rgw_pool usage_log_pool
;
1182 rgw_pool user_keys_pool
;
1183 rgw_pool user_email_pool
;
1184 rgw_pool user_swift_pool
;
1185 rgw_pool user_uid_pool
;
1186 rgw_pool roles_pool
;
1187 rgw_pool reshard_pool
;
1189 RGWAccessKey system_key
;
1191 map
<string
, RGWZonePlacementInfo
> placement_pools
;
1195 map
<string
, string
, ltstr_nocase
> tier_config
;
1197 RGWZoneParams() : RGWSystemMetaObj() {}
1198 RGWZoneParams(const string
& name
) : RGWSystemMetaObj(name
){}
1199 RGWZoneParams(const string
& id
, const string
& name
) : RGWSystemMetaObj(id
, name
) {}
1200 RGWZoneParams(const string
& id
, const string
& name
, const string
& _realm_id
)
1201 : RGWSystemMetaObj(id
, name
), realm_id(_realm_id
) {}
1203 rgw_pool
get_pool(CephContext
*cct
);
1204 const string
get_default_oid(bool old_format
= false) override
;
1205 const string
& get_names_oid_prefix() override
;
1206 const string
& get_info_oid_prefix(bool old_format
= false) override
;
1207 const string
& get_predefined_name(CephContext
*cct
) override
;
1209 int init(CephContext
*_cct
, RGWRados
*_store
, bool setup_obj
= true,
1210 bool old_format
= false);
1211 using RGWSystemMetaObj::init
;
1212 int read_default_id(string
& default_id
, bool old_format
= false) override
;
1213 int set_as_default(bool exclusive
= false) override
;
1214 int create_default(bool old_format
= false);
1215 int create(bool exclusive
= true) override
;
1216 int fix_pool_names();
1218 const string
& get_compression_type(const string
& placement_rule
) const;
1220 void encode(bufferlist
& bl
) const override
{
1221 ENCODE_START(10, 1, bl
);
1222 ::encode(domain_root
, bl
);
1223 ::encode(control_pool
, bl
);
1224 ::encode(gc_pool
, bl
);
1225 ::encode(log_pool
, bl
);
1226 ::encode(intent_log_pool
, bl
);
1227 ::encode(usage_log_pool
, bl
);
1228 ::encode(user_keys_pool
, bl
);
1229 ::encode(user_email_pool
, bl
);
1230 ::encode(user_swift_pool
, bl
);
1231 ::encode(user_uid_pool
, bl
);
1232 RGWSystemMetaObj::encode(bl
);
1233 ::encode(system_key
, bl
);
1234 ::encode(placement_pools
, bl
);
1235 ::encode(metadata_heap
, bl
);
1236 ::encode(realm_id
, bl
);
1237 ::encode(lc_pool
, bl
);
1238 ::encode(tier_config
, bl
);
1239 ::encode(roles_pool
, bl
);
1240 ::encode(reshard_pool
, bl
);
1244 void decode(bufferlist::iterator
& bl
) override
{
1245 DECODE_START(10, bl
);
1246 ::decode(domain_root
, bl
);
1247 ::decode(control_pool
, bl
);
1248 ::decode(gc_pool
, bl
);
1249 ::decode(log_pool
, bl
);
1250 ::decode(intent_log_pool
, bl
);
1251 ::decode(usage_log_pool
, bl
);
1252 ::decode(user_keys_pool
, bl
);
1253 ::decode(user_email_pool
, bl
);
1254 ::decode(user_swift_pool
, bl
);
1255 ::decode(user_uid_pool
, bl
);
1256 if (struct_v
>= 6) {
1257 RGWSystemMetaObj::decode(bl
);
1258 } else if (struct_v
>= 2) {
1263 ::decode(system_key
, bl
);
1265 ::decode(placement_pools
, bl
);
1267 ::decode(metadata_heap
, bl
);
1268 if (struct_v
>= 6) {
1269 ::decode(realm_id
, bl
);
1271 if (struct_v
>= 7) {
1272 ::decode(lc_pool
, bl
);
1274 lc_pool
= log_pool
.name
+ ":lc";
1276 if (struct_v
>= 8) {
1277 ::decode(tier_config
, bl
);
1279 if (struct_v
>= 9) {
1280 ::decode(roles_pool
, bl
);
1282 roles_pool
= name
+ ".rgw.meta:roles";
1284 if (struct_v
>= 10) {
1285 ::decode(reshard_pool
, bl
);
1287 reshard_pool
= log_pool
.name
+ ":reshard";
1291 void dump(Formatter
*f
) const;
1292 void decode_json(JSONObj
*obj
);
1293 static void generate_test_instances(list
<RGWZoneParams
*>& o
);
1295 bool get_placement(const string
& placement_id
, RGWZonePlacementInfo
*placement
) const {
1296 auto iter
= placement_pools
.find(placement_id
);
1297 if (iter
== placement_pools
.end()) {
1300 *placement
= iter
->second
;
1305 * return data pool of the head object
1307 bool get_head_data_pool(const string
& placement_id
, const rgw_obj
& obj
, rgw_pool
*pool
) const {
1308 const rgw_data_placement_target
& explicit_placement
= obj
.bucket
.explicit_placement
;
1309 if (!explicit_placement
.data_pool
.empty()) {
1310 if (!obj
.in_extra_data
) {
1311 *pool
= explicit_placement
.data_pool
;
1313 *pool
= explicit_placement
.get_data_extra_pool();
1317 if (placement_id
.empty()) {
1320 auto iter
= placement_pools
.find(placement_id
);
1321 if (iter
== placement_pools
.end()) {
1324 if (!obj
.in_extra_data
) {
1325 *pool
= iter
->second
.data_pool
;
1327 *pool
= iter
->second
.get_data_extra_pool();
1332 WRITE_CLASS_ENCODER(RGWZoneParams
)
1337 list
<string
> endpoints
;
1344 * Represents the number of shards for the bucket index object, a value of zero
1345 * indicates there is no sharding. By default (no sharding, the name of the object
1346 * is '.dir.{marker}', with sharding, the name is '.dir.{marker}.{sharding_id}',
1347 * sharding_id is zero-based value. It is not recommended to set a too large value
1348 * (e.g. thousand) as it increases the cost for bucket listing.
1350 uint32_t bucket_index_max_shards
;
1353 set
<string
> sync_from
; /* list of zones to sync from */
1355 RGWZone() : log_meta(false), log_data(false), read_only(false), bucket_index_max_shards(0),
1356 sync_from_all(true) {}
1358 void encode(bufferlist
& bl
) const {
1359 ENCODE_START(6, 1, bl
);
1361 ::encode(endpoints
, bl
);
1362 ::encode(log_meta
, bl
);
1363 ::encode(log_data
, bl
);
1364 ::encode(bucket_index_max_shards
, bl
);
1366 ::encode(read_only
, bl
);
1367 ::encode(tier_type
, bl
);
1368 ::encode(sync_from_all
, bl
);
1369 ::encode(sync_from
, bl
);
1373 void decode(bufferlist::iterator
& bl
) {
1374 DECODE_START(6, bl
);
1379 ::decode(endpoints
, bl
);
1380 if (struct_v
>= 2) {
1381 ::decode(log_meta
, bl
);
1382 ::decode(log_data
, bl
);
1384 if (struct_v
>= 3) {
1385 ::decode(bucket_index_max_shards
, bl
);
1387 if (struct_v
>= 4) {
1389 ::decode(read_only
, bl
);
1391 if (struct_v
>= 5) {
1392 ::decode(tier_type
, bl
);
1394 if (struct_v
>= 6) {
1395 ::decode(sync_from_all
, bl
);
1396 ::decode(sync_from
, bl
);
1400 void dump(Formatter
*f
) const;
1401 void decode_json(JSONObj
*obj
);
1402 static void generate_test_instances(list
<RGWZone
*>& o
);
1404 bool is_read_only() { return read_only
; }
1406 bool syncs_from(const string
& zone_id
) const {
1407 return (sync_from_all
|| sync_from
.find(zone_id
) != sync_from
.end());
1410 WRITE_CLASS_ENCODER(RGWZone
)
1412 struct RGWDefaultZoneGroupInfo
{
1413 string default_zonegroup
;
1415 void encode(bufferlist
& bl
) const {
1416 ENCODE_START(1, 1, bl
);
1417 ::encode(default_zonegroup
, bl
);
1421 void decode(bufferlist::iterator
& bl
) {
1422 DECODE_START(1, bl
);
1423 ::decode(default_zonegroup
, bl
);
1426 void dump(Formatter
*f
) const;
1427 void decode_json(JSONObj
*obj
);
1428 //todo: implement ceph-dencoder
1430 WRITE_CLASS_ENCODER(RGWDefaultZoneGroupInfo
)
1432 struct RGWZoneGroupPlacementTarget
{
1436 bool user_permitted(list
<string
>& user_tags
) const {
1440 for (auto& rule
: user_tags
) {
1441 if (tags
.find(rule
) != tags
.end()) {
1448 void encode(bufferlist
& bl
) const {
1449 ENCODE_START(1, 1, bl
);
1455 void decode(bufferlist::iterator
& bl
) {
1456 DECODE_START(1, bl
);
1461 void dump(Formatter
*f
) const;
1462 void decode_json(JSONObj
*obj
);
1464 WRITE_CLASS_ENCODER(RGWZoneGroupPlacementTarget
)
1467 struct RGWZoneGroup
: public RGWSystemMetaObj
{
1469 list
<string
> endpoints
;
1473 map
<string
, RGWZone
> zones
;
1475 map
<string
, RGWZoneGroupPlacementTarget
> placement_targets
;
1476 string default_placement
;
1478 list
<string
> hostnames
;
1479 list
<string
> hostnames_s3website
;
1480 // TODO: Maybe convert hostnames to a map<string,list<string>> for
1481 // endpoint_type->hostnames
1483 20:05 < _robbat21irssi> maybe I do someting like: if (hostname_map.empty()) { populate all map keys from hostnames; };
1484 20:05 < _robbat21irssi> but that's a later compatability migration planning bit
1485 20:06 < yehudasa> more like if (!hostnames.empty()) {
1486 20:06 < yehudasa> for (list<string>::iterator iter = hostnames.begin(); iter != hostnames.end(); ++iter) {
1487 20:06 < yehudasa> hostname_map["s3"].append(iter->second);
1488 20:07 < yehudasa> hostname_map["s3website"].append(iter->second);
1489 20:07 < yehudasa> s/append/push_back/g
1490 20:08 < _robbat21irssi> inner loop over APIs
1491 20:08 < yehudasa> yeah, probably
1492 20:08 < _robbat21irssi> s3, s3website, swift, swith_auth, swift_website
1494 map
<string
, list
<string
> > api_hostname_map
;
1495 map
<string
, list
<string
> > api_endpoints_map
;
1499 RGWZoneGroup(): is_master(false){}
1500 RGWZoneGroup(const std::string
&id
, const std::string
&name
):RGWSystemMetaObj(id
, name
) {}
1501 RGWZoneGroup(const std::string
&_name
):RGWSystemMetaObj(_name
) {}
1502 RGWZoneGroup(const std::string
&_name
, bool _is_master
, CephContext
*cct
, RGWRados
* store
,
1503 const string
& _realm_id
, const list
<string
>& _endpoints
)
1504 : RGWSystemMetaObj(_name
, cct
, store
), endpoints(_endpoints
), is_master(_is_master
),
1505 realm_id(_realm_id
) {}
1507 bool is_master_zonegroup() const { return is_master
;}
1508 void update_master(bool _is_master
) {
1509 is_master
= _is_master
;
1510 post_process_params();
1512 void post_process_params();
1514 void encode(bufferlist
& bl
) const override
{
1515 ENCODE_START(4, 1, bl
);
1517 ::encode(api_name
, bl
);
1518 ::encode(is_master
, bl
);
1519 ::encode(endpoints
, bl
);
1520 ::encode(master_zone
, bl
);
1521 ::encode(zones
, bl
);
1522 ::encode(placement_targets
, bl
);
1523 ::encode(default_placement
, bl
);
1524 ::encode(hostnames
, bl
);
1525 ::encode(hostnames_s3website
, bl
);
1526 RGWSystemMetaObj::encode(bl
);
1527 ::encode(realm_id
, bl
);
1531 void decode(bufferlist::iterator
& bl
) override
{
1532 DECODE_START(4, bl
);
1534 ::decode(api_name
, bl
);
1535 ::decode(is_master
, bl
);
1536 ::decode(endpoints
, bl
);
1537 ::decode(master_zone
, bl
);
1538 ::decode(zones
, bl
);
1539 ::decode(placement_targets
, bl
);
1540 ::decode(default_placement
, bl
);
1541 if (struct_v
>= 2) {
1542 ::decode(hostnames
, bl
);
1544 if (struct_v
>= 3) {
1545 ::decode(hostnames_s3website
, bl
);
1547 if (struct_v
>= 4) {
1548 RGWSystemMetaObj::decode(bl
);
1549 ::decode(realm_id
, bl
);
1556 int read_default_id(string
& default_id
, bool old_format
= false) override
;
1557 int set_as_default(bool exclusive
= false) override
;
1558 int create_default(bool old_format
= false);
1559 int equals(const string
& other_zonegroup
) const;
1560 int add_zone(const RGWZoneParams
& zone_params
, bool *is_master
, bool *read_only
,
1561 const list
<string
>& endpoints
, const string
*ptier_type
,
1562 bool *psync_from_all
, list
<string
>& sync_from
, list
<string
>& sync_from_rm
);
1563 int remove_zone(const std::string
& zone_id
);
1564 int rename_zone(const RGWZoneParams
& zone_params
);
1565 rgw_pool
get_pool(CephContext
*cct
);
1566 const string
get_default_oid(bool old_region_format
= false) override
;
1567 const string
& get_info_oid_prefix(bool old_region_format
= false) override
;
1568 const string
& get_names_oid_prefix() override
;
1569 const string
& get_predefined_name(CephContext
*cct
) override
;
1571 void dump(Formatter
*f
) const;
1572 void decode_json(JSONObj
*obj
);
1573 static void generate_test_instances(list
<RGWZoneGroup
*>& o
);
1575 WRITE_CLASS_ENCODER(RGWZoneGroup
)
1580 map
<string
, RGWZoneGroup
> zonegroups
;
1581 map
<string
, RGWZoneGroup
> zonegroups_by_api
;
1582 map
<string
, uint32_t> short_zone_ids
;
1584 string master_zonegroup
;
1586 void encode(bufferlist
& bl
) const;
1587 void decode(bufferlist::iterator
& bl
);
1589 int update(const RGWZoneGroup
& zonegroup
, CephContext
*cct
);
1591 void dump(Formatter
*f
) const;
1592 void decode_json(JSONObj
*obj
);
1596 zonegroups_by_api
.clear();
1597 master_zonegroup
.clear();
1600 uint32_t get_zone_short_id(const string
& zone_id
) const;
1602 WRITE_CLASS_ENCODER(RGWPeriodMap
)
1604 struct RGWPeriodConfig
1606 RGWQuotaInfo bucket_quota
;
1607 RGWQuotaInfo user_quota
;
1609 void encode(bufferlist
& bl
) const {
1610 ENCODE_START(1, 1, bl
);
1611 ::encode(bucket_quota
, bl
);
1612 ::encode(user_quota
, bl
);
1616 void decode(bufferlist::iterator
& bl
) {
1617 DECODE_START(1, bl
);
1618 ::decode(bucket_quota
, bl
);
1619 ::decode(user_quota
, bl
);
1623 void dump(Formatter
*f
) const;
1624 void decode_json(JSONObj
*obj
);
1626 // the period config must be stored in a local object outside of the period,
1627 // so that it can be used in a default configuration where no realm/period
1629 int read(RGWRados
*store
, const std::string
& realm_id
);
1630 int write(RGWRados
*store
, const std::string
& realm_id
);
1632 static std::string
get_oid(const std::string
& realm_id
);
1633 static rgw_pool
get_pool(CephContext
*cct
);
1635 WRITE_CLASS_ENCODER(RGWPeriodConfig
)
1637 /* for backward comaptability */
1638 struct RGWRegionMap
{
1640 map
<string
, RGWZoneGroup
> regions
;
1642 string master_region
;
1644 RGWQuotaInfo bucket_quota
;
1645 RGWQuotaInfo user_quota
;
1647 void encode(bufferlist
& bl
) const;
1648 void decode(bufferlist::iterator
& bl
);
1650 void dump(Formatter
*f
) const;
1651 void decode_json(JSONObj
*obj
);
1653 WRITE_CLASS_ENCODER(RGWRegionMap
)
1655 struct RGWZoneGroupMap
{
1657 map
<string
, RGWZoneGroup
> zonegroups
;
1658 map
<string
, RGWZoneGroup
> zonegroups_by_api
;
1660 string master_zonegroup
;
1662 RGWQuotaInfo bucket_quota
;
1663 RGWQuotaInfo user_quota
;
1665 /* constract the map */
1666 int read(CephContext
*cct
, RGWRados
*store
);
1668 void encode(bufferlist
& bl
) const;
1669 void decode(bufferlist::iterator
& bl
);
1671 void dump(Formatter
*f
) const;
1672 void decode_json(JSONObj
*obj
);
1674 WRITE_CLASS_ENCODER(RGWZoneGroupMap
)
1678 struct objexp_hint_entry
{
1682 rgw_obj_key obj_key
;
1683 ceph::real_time exp_time
;
1685 void encode(bufferlist
& bl
) const {
1686 ENCODE_START(2, 1, bl
);
1687 ::encode(bucket_name
, bl
);
1688 ::encode(bucket_id
, bl
);
1689 ::encode(obj_key
, bl
);
1690 ::encode(exp_time
, bl
);
1691 ::encode(tenant
, bl
);
1695 void decode(bufferlist::iterator
& bl
) {
1696 // XXX Do we want DECODE_START_LEGACY_COMPAT_LEN(2, 1, 1, bl); ?
1697 DECODE_START(2, bl
);
1698 ::decode(bucket_name
, bl
);
1699 ::decode(bucket_id
, bl
);
1700 ::decode(obj_key
, bl
);
1701 ::decode(exp_time
, bl
);
1702 if (struct_v
>= 2) {
1703 ::decode(tenant
, bl
);
1710 WRITE_CLASS_ENCODER(objexp_hint_entry
)
1714 class RGWRealm
: public RGWSystemMetaObj
1716 string current_period
;
1717 epoch_t epoch
{0}; //< realm epoch, incremented for each new period
1719 int create_control(bool exclusive
);
1720 int delete_control();
1723 RGWRealm(const string
& _id
, const string
& _name
= "") : RGWSystemMetaObj(_id
, _name
) {}
1724 RGWRealm(CephContext
*_cct
, RGWRados
*_store
): RGWSystemMetaObj(_cct
, _store
) {}
1725 RGWRealm(const string
& _name
, CephContext
*_cct
, RGWRados
*_store
): RGWSystemMetaObj(_name
, _cct
, _store
){}
1727 void encode(bufferlist
& bl
) const override
{
1728 ENCODE_START(1, 1, bl
);
1729 RGWSystemMetaObj::encode(bl
);
1730 ::encode(current_period
, bl
);
1731 ::encode(epoch
, bl
);
1735 void decode(bufferlist::iterator
& bl
) override
{
1736 DECODE_START(1, bl
);
1737 RGWSystemMetaObj::decode(bl
);
1738 ::decode(current_period
, bl
);
1739 ::decode(epoch
, bl
);
1743 int create(bool exclusive
= true) override
;
1745 rgw_pool
get_pool(CephContext
*cct
);
1746 const string
get_default_oid(bool old_format
= false) override
;
1747 const string
& get_names_oid_prefix() override
;
1748 const string
& get_info_oid_prefix(bool old_format
= false) override
;
1749 const string
& get_predefined_name(CephContext
*cct
) override
;
1751 using RGWSystemMetaObj::read_id
; // expose as public for radosgw-admin
1753 void dump(Formatter
*f
) const;
1754 void decode_json(JSONObj
*obj
);
1756 const string
& get_current_period() const {
1757 return current_period
;
1759 int set_current_period(RGWPeriod
& period
);
1760 void clear_current_period_and_epoch() {
1761 current_period
.clear();
1764 epoch_t
get_epoch() const { return epoch
; }
1766 string
get_control_oid();
1767 /// send a notify on the realm control object
1768 int notify_zone(bufferlist
& bl
);
1769 /// notify the zone of a new period
1770 int notify_new_period(const RGWPeriod
& period
);
1772 WRITE_CLASS_ENCODER(RGWRealm
)
1774 struct RGWPeriodLatestEpochInfo
{
1777 void encode(bufferlist
& bl
) const {
1778 ENCODE_START(1, 1, bl
);
1779 ::encode(epoch
, bl
);
1783 void decode(bufferlist::iterator
& bl
) {
1784 DECODE_START(1, bl
);
1785 ::decode(epoch
, bl
);
1789 void dump(Formatter
*f
) const;
1790 void decode_json(JSONObj
*obj
);
1792 WRITE_CLASS_ENCODER(RGWPeriodLatestEpochInfo
)
1798 string predecessor_uuid
;
1799 std::vector
<std::string
> sync_status
;
1800 RGWPeriodMap period_map
;
1801 RGWPeriodConfig period_config
;
1802 string master_zonegroup
;
1807 epoch_t realm_epoch
{1}; //< realm epoch when period was made current
1813 int read_latest_epoch(RGWPeriodLatestEpochInfo
& epoch_info
,
1814 RGWObjVersionTracker
*objv
= nullptr);
1815 int use_latest_epoch();
1816 int use_current_period();
1818 const string
get_period_oid();
1819 const string
get_period_oid_prefix();
1821 // gather the metadata sync status for each shard; only for use on master zone
1822 int update_sync_status(const RGWPeriod
¤t_period
,
1823 std::ostream
& error_stream
, bool force_if_stale
);
1826 RGWPeriod() : epoch(0), cct(NULL
), store(NULL
) {}
1828 RGWPeriod(const string
& period_id
, epoch_t _epoch
= 0)
1829 : id(period_id
), epoch(_epoch
),
1830 cct(NULL
), store(NULL
) {}
1832 const string
& get_id() const { return id
; }
1833 epoch_t
get_epoch() const { return epoch
; }
1834 epoch_t
get_realm_epoch() const { return realm_epoch
; }
1835 const string
& get_predecessor() const { return predecessor_uuid
; }
1836 const string
& get_master_zone() const { return master_zone
; }
1837 const string
& get_master_zonegroup() const { return master_zonegroup
; }
1838 const string
& get_realm() const { return realm_id
; }
1839 const RGWPeriodMap
& get_map() const { return period_map
; }
1840 RGWPeriodConfig
& get_config() { return period_config
; }
1841 const RGWPeriodConfig
& get_config() const { return period_config
; }
1842 const std::vector
<std::string
>& get_sync_status() const { return sync_status
; }
1843 rgw_pool
get_pool(CephContext
*cct
);
1844 const string
& get_latest_epoch_oid();
1845 const string
& get_info_oid_prefix();
1847 void set_user_quota(RGWQuotaInfo
& user_quota
) {
1848 period_config
.user_quota
= user_quota
;
1851 void set_bucket_quota(RGWQuotaInfo
& bucket_quota
) {
1852 period_config
.bucket_quota
= bucket_quota
;
1855 void set_id(const string
& id
) {
1859 void set_epoch(epoch_t epoch
) { this->epoch
= epoch
; }
1860 void set_realm_epoch(epoch_t epoch
) { realm_epoch
= epoch
; }
1862 void set_predecessor(const string
& predecessor
)
1864 predecessor_uuid
= predecessor
;
1867 void set_realm_id(const string
& _realm_id
) {
1868 realm_id
= _realm_id
;
1873 int get_zonegroup(RGWZoneGroup
& zonegroup
,
1874 const string
& zonegroup_id
);
1876 bool is_single_zonegroup() const
1878 return (period_map
.zonegroups
.size() == 1);
1882 returns true if there are several zone groups with a least one zone
1884 bool is_multi_zonegroups_with_zones()
1887 for (const auto& zg
: period_map
.zonegroups
) {
1888 if (zg
.second
.zones
.size() > 0) {
1897 int get_latest_epoch(epoch_t
& epoch
);
1898 int set_latest_epoch(epoch_t epoch
, bool exclusive
= false,
1899 RGWObjVersionTracker
*objv
= nullptr);
1900 // update latest_epoch if the given epoch is higher, else return -EEXIST
1901 int update_latest_epoch(epoch_t epoch
);
1903 int init(CephContext
*_cct
, RGWRados
*_store
, const string
&period_realm_id
, const string
&period_realm_name
= "",
1904 bool setup_obj
= true);
1905 int init(CephContext
*_cct
, RGWRados
*_store
, bool setup_obj
= true);
1907 int create(bool exclusive
= true);
1909 int store_info(bool exclusive
);
1910 int add_zonegroup(const RGWZoneGroup
& zonegroup
);
1915 // commit a staging period; only for use on master zone
1916 int commit(RGWRealm
& realm
, const RGWPeriod
¤t_period
,
1917 std::ostream
& error_stream
, bool force_if_stale
= false);
1919 void encode(bufferlist
& bl
) const {
1920 ENCODE_START(1, 1, bl
);
1922 ::encode(epoch
, bl
);
1923 ::encode(realm_epoch
, bl
);
1924 ::encode(predecessor_uuid
, bl
);
1925 ::encode(sync_status
, bl
);
1926 ::encode(period_map
, bl
);
1927 ::encode(master_zone
, bl
);
1928 ::encode(master_zonegroup
, bl
);
1929 ::encode(period_config
, bl
);
1930 ::encode(realm_id
, bl
);
1931 ::encode(realm_name
, bl
);
1935 void decode(bufferlist::iterator
& bl
) {
1936 DECODE_START(1, bl
);
1938 ::decode(epoch
, bl
);
1939 ::decode(realm_epoch
, bl
);
1940 ::decode(predecessor_uuid
, bl
);
1941 ::decode(sync_status
, bl
);
1942 ::decode(period_map
, bl
);
1943 ::decode(master_zone
, bl
);
1944 ::decode(master_zonegroup
, bl
);
1945 ::decode(period_config
, bl
);
1946 ::decode(realm_id
, bl
);
1947 ::decode(realm_name
, bl
);
1950 void dump(Formatter
*f
) const;
1951 void decode_json(JSONObj
*obj
);
1953 static string
get_staging_id(const string
& realm_id
) {
1954 return realm_id
+ ":staging";
1957 WRITE_CLASS_ENCODER(RGWPeriod
)
1959 class RGWDataChangesLog
;
1960 class RGWMetaSyncStatusManager
;
1961 class RGWDataSyncStatusManager
;
1962 class RGWReplicaLogger
;
1963 class RGWCoroutinesManagerRegistry
;
1970 void oid_str(int shard
, string
& oid
);
1971 int get_shard_num(const string
& object
);
1972 string
get_oid(const string
& object
);
1973 int open_ioctx(librados::IoCtx
& ioctx
);
1983 list_state() : cur_shard(0), max_shard(0) {}
1987 virtual bool dump_entry_internal(const cls_statelog_entry
& entry
, Formatter
*f
) {
1992 RGWStateLog(RGWRados
*_store
, int _num_shards
, const string
& _module_name
) :
1993 store(_store
), num_shards(_num_shards
), module_name(_module_name
) {}
1994 virtual ~RGWStateLog() {}
1996 int store_entry(const string
& client_id
, const string
& op_id
, const string
& object
,
1997 uint32_t state
, bufferlist
*bl
, uint32_t *check_state
);
1999 int remove_entry(const string
& client_id
, const string
& op_id
, const string
& object
);
2001 void init_list_entries(const string
& client_id
, const string
& op_id
, const string
& object
,
2004 int list_entries(void *handle
, int max_entries
, list
<cls_statelog_entry
>& entries
, bool *done
);
2006 void finish_list_entries(void *handle
);
2008 virtual void dump_entry(const cls_statelog_entry
& entry
, Formatter
*f
);
2012 * state transitions:
2014 * unknown -> in-progress -> complete
2017 * user can try setting the 'abort' state, and it can only succeed if state is
2020 * state renewal cannot switch state (stays in the same state)
2022 * rgw can switch from in-progress to complete
2023 * rgw can switch from in-progress to error
2025 * rgw can switch from abort to cancelled
2029 class RGWOpState
: public RGWStateLog
{
2031 bool dump_entry_internal(const cls_statelog_entry
& entry
, Formatter
*f
) override
;
2035 OPSTATE_UNKNOWN
= 0,
2036 OPSTATE_IN_PROGRESS
= 1,
2037 OPSTATE_COMPLETE
= 2,
2040 OPSTATE_CANCELLED
= 5,
2043 explicit RGWOpState(RGWRados
*_store
);
2045 int state_from_str(const string
& s
, OpState
*state
);
2046 int set_state(const string
& client_id
, const string
& op_id
, const string
& object
, OpState state
);
2047 int renew_state(const string
& client_id
, const string
& op_id
, const string
& object
, OpState state
);
2050 class RGWOpStateSingleOp
2059 RGWOpState::OpState cur_state
;
2060 ceph::real_time last_update
;
2063 RGWOpStateSingleOp(RGWRados
*store
, const string
& cid
, const string
& oid
, const string
& obj
);
2065 int set_state(RGWOpState::OpState state
);
2069 class RGWGetBucketStats_CB
: public RefCountedObject
{
2072 map
<RGWObjCategory
, RGWStorageStats
> *stats
;
2074 explicit RGWGetBucketStats_CB(const rgw_bucket
& _bucket
) : bucket(_bucket
), stats(NULL
) {}
2075 ~RGWGetBucketStats_CB() override
{}
2076 virtual void handle_response(int r
) = 0;
2077 virtual void set_response(map
<RGWObjCategory
, RGWStorageStats
> *_stats
) {
2082 class RGWGetUserStats_CB
: public RefCountedObject
{
2085 RGWStorageStats stats
;
2087 explicit RGWGetUserStats_CB(const rgw_user
& _user
) : user(_user
) {}
2088 ~RGWGetUserStats_CB() override
{}
2089 virtual void handle_response(int r
) = 0;
2090 virtual void set_response(RGWStorageStats
& _stats
) {
2095 class RGWGetDirHeader_CB
;
2096 class RGWGetUserHeader_CB
;
2098 struct rgw_rados_ref
{
2102 librados::IoCtx ioctx
;
2105 class RGWChainedCache
{
2107 virtual ~RGWChainedCache() {}
2108 virtual void chain_cb(const string
& key
, void *data
) = 0;
2109 virtual void invalidate(const string
& key
) = 0;
2110 virtual void invalidate_all() = 0;
2113 RGWChainedCache
*cache
;
2117 Entry(RGWChainedCache
*_c
, const string
& _k
, void *_d
) : cache(_c
), key(_k
), data(_d
) {}
2121 template <class T
, class S
>
2122 class RGWObjectCtxImpl
{
2124 std::map
<T
, S
> objs_state
;
2128 RGWObjectCtxImpl(RGWRados
*_store
) : store(_store
), lock("RGWObjectCtxImpl") {}
2130 S
*get_state(const T
& obj
) {
2132 typename
std::map
<T
, S
>::iterator iter
;
2134 assert (!obj
.empty());
2135 iter
= objs_state
.find(obj
);
2136 if (iter
!= objs_state
.end()) {
2137 result
= &iter
->second
;
2142 result
= &objs_state
[obj
];
2148 void set_atomic(T
& obj
) {
2149 RWLock::WLocker
wl(lock
);
2150 assert (!obj
.empty());
2151 objs_state
[obj
].is_atomic
= true;
2153 void set_prefetch_data(T
& obj
) {
2154 RWLock::WLocker
wl(lock
);
2155 assert (!obj
.empty());
2156 objs_state
[obj
].prefetch_data
= true;
2158 void invalidate(T
& obj
) {
2159 RWLock::WLocker
wl(lock
);
2160 auto iter
= objs_state
.find(obj
);
2161 if (iter
== objs_state
.end()) {
2164 bool is_atomic
= iter
->second
.is_atomic
;
2165 bool prefetch_data
= iter
->second
.prefetch_data
;
2167 objs_state
.erase(iter
);
2169 if (is_atomic
|| prefetch_data
) {
2170 auto& s
= objs_state
[obj
];
2171 s
.is_atomic
= is_atomic
;
2172 s
.prefetch_data
= prefetch_data
;
2178 void RGWObjectCtxImpl
<rgw_obj
, RGWObjState
>::invalidate(rgw_obj
& obj
);
2181 void RGWObjectCtxImpl
<rgw_raw_obj
, RGWRawObjState
>::invalidate(rgw_raw_obj
& obj
);
2183 struct RGWObjectCtx
{
2187 RGWObjectCtxImpl
<rgw_obj
, RGWObjState
> obj
;
2188 RGWObjectCtxImpl
<rgw_raw_obj
, RGWRawObjState
> raw
;
2190 explicit RGWObjectCtx(RGWRados
*_store
) : store(_store
), user_ctx(NULL
), obj(store
), raw(store
) { }
2191 RGWObjectCtx(RGWRados
*_store
, void *_user_ctx
) : store(_store
), user_ctx(_user_ctx
), obj(store
), raw(store
) { }
2195 class RGWAsyncRadosProcessor
;
2198 class RGWChainedCacheImpl
;
2200 struct bucket_info_entry
{
2203 map
<string
, bufferlist
> attrs
;
2206 struct tombstone_entry
{
2207 ceph::real_time mtime
;
2208 uint32_t zone_short_id
;
2211 tombstone_entry() = default;
2212 tombstone_entry(const RGWObjState
& state
)
2213 : mtime(state
.mtime
), zone_short_id(state
.zone_short_id
),
2214 pg_ver(state
.pg_ver
) {}
2217 class RGWIndexCompletionManager
;
2219 class RGWRados
: public AdminSocketHook
2222 friend class RGWMetaNotifier
;
2223 friend class RGWDataNotifier
;
2225 friend class RGWObjectExpirer
;
2226 friend class RGWMetaSyncProcessorThread
;
2227 friend class RGWDataSyncProcessorThread
;
2228 friend class RGWStateLog
;
2229 friend class RGWReplicaLogger
;
2230 friend class RGWReshard
;
2231 friend class RGWBucketReshard
;
2232 friend class BucketIndexLockGuard
;
2233 friend class RGWCompleteMultipart
;
2235 static const char* admin_commands
[4][3];
2237 /** Open the pool used as root for this gateway */
2238 int open_root_pool_ctx();
2239 int open_gc_pool_ctx();
2240 int open_lc_pool_ctx();
2241 int open_objexp_pool_ctx();
2242 int open_reshard_pool_ctx();
2244 int open_pool_ctx(const rgw_pool
& pool
, librados::IoCtx
& io_ctx
);
2245 int open_bucket_index_ctx(const RGWBucketInfo
& bucket_info
, librados::IoCtx
& index_ctx
);
2246 int open_bucket_index(const RGWBucketInfo
& bucket_info
, librados::IoCtx
& index_ctx
, string
& bucket_oid
);
2247 int open_bucket_index_base(const RGWBucketInfo
& bucket_info
, librados::IoCtx
& index_ctx
,
2248 string
& bucket_oid_base
);
2249 int open_bucket_index_shard(const RGWBucketInfo
& bucket_info
, librados::IoCtx
& index_ctx
,
2250 const string
& obj_key
, string
*bucket_obj
, int *shard_id
);
2251 int open_bucket_index_shard(const RGWBucketInfo
& bucket_info
, librados::IoCtx
& index_ctx
,
2252 int shard_id
, string
*bucket_obj
);
2253 int open_bucket_index(const RGWBucketInfo
& bucket_info
, librados::IoCtx
& index_ctx
,
2254 map
<int, string
>& bucket_objs
, int shard_id
= -1, map
<int, string
> *bucket_instance_ids
= NULL
);
2255 template<typename T
>
2256 int open_bucket_index(const RGWBucketInfo
& bucket_info
, librados::IoCtx
& index_ctx
,
2257 map
<int, string
>& oids
, map
<int, T
>& bucket_objs
,
2258 int shard_id
= -1, map
<int, string
> *bucket_instance_ids
= NULL
);
2259 void build_bucket_index_marker(const string
& shard_id_str
, const string
& shard_marker
,
2262 void get_bucket_instance_ids(const RGWBucketInfo
& bucket_info
, int shard_id
, map
<int, string
> *result
);
2264 std::atomic
<int64_t> max_req_id
= { 0 };
2266 Mutex watchers_lock
;
2271 RGWObjectExpirer
*obj_expirer
;
2275 bool run_sync_thread
;
2276 bool run_reshard_thread
;
2278 RGWAsyncRadosProcessor
* async_rados
;
2280 RGWMetaNotifier
*meta_notifier
;
2281 RGWDataNotifier
*data_notifier
;
2282 RGWMetaSyncProcessorThread
*meta_sync_processor_thread
;
2283 map
<string
, RGWDataSyncProcessorThread
*> data_sync_processor_threads
;
2285 boost::optional
<rgw::BucketTrimManager
> bucket_trim
;
2286 RGWSyncLogTrimThread
*sync_log_trimmer
{nullptr};
2288 Mutex meta_sync_thread_lock
;
2289 Mutex data_sync_thread_lock
;
2292 RGWWatcher
**watchers
;
2293 std::set
<int> watchers_set
;
2294 librados::IoCtx root_pool_ctx
; // .rgw
2295 librados::IoCtx control_pool_ctx
; // .rgw.control
2296 bool watch_initialized
;
2298 friend class RGWWatcher
;
2300 Mutex bucket_id_lock
;
2302 // This field represents the number of bucket index object shards
2303 uint32_t bucket_index_max_shards
;
2305 int get_obj_head_ioctx(const RGWBucketInfo
& bucket_info
, const rgw_obj
& obj
, librados::IoCtx
*ioctx
);
2306 int get_obj_head_ref(const RGWBucketInfo
& bucket_info
, const rgw_obj
& obj
, rgw_rados_ref
*ref
);
2307 int get_system_obj_ref(const rgw_raw_obj
& obj
, rgw_rados_ref
*ref
);
2308 uint64_t max_bucket_id
;
2310 int get_olh_target_state(RGWObjectCtx
& rctx
, const RGWBucketInfo
& bucket_info
, const rgw_obj
& obj
,
2311 RGWObjState
*olh_state
, RGWObjState
**target_state
);
2312 int get_system_obj_state_impl(RGWObjectCtx
*rctx
, rgw_raw_obj
& obj
, RGWRawObjState
**state
, RGWObjVersionTracker
*objv_tracker
);
2313 int get_obj_state_impl(RGWObjectCtx
*rctx
, const RGWBucketInfo
& bucket_info
, const rgw_obj
& obj
, RGWObjState
**state
,
2314 bool follow_olh
, bool assume_noent
= false);
2315 int append_atomic_test(RGWObjectCtx
*rctx
, const RGWBucketInfo
& bucket_info
, const rgw_obj
& obj
,
2316 librados::ObjectOperation
& op
, RGWObjState
**state
);
2318 int update_placement_map();
2319 int store_bucket_info(RGWBucketInfo
& info
, map
<string
, bufferlist
> *pattrs
, RGWObjVersionTracker
*objv_tracker
, bool exclusive
);
2321 void remove_rgw_head_obj(librados::ObjectWriteOperation
& op
);
2322 void cls_obj_check_prefix_exist(librados::ObjectOperation
& op
, const string
& prefix
, bool fail_if_exist
);
2323 void cls_obj_check_mtime(librados::ObjectOperation
& op
, const real_time
& mtime
, bool high_precision_time
, RGWCheckMTimeType type
);
2327 std::vector
<librados::Rados
> rados
;
2328 uint32_t next_rados_handle
;
2330 std::map
<pthread_t
, int> rados_map
;
2332 using RGWChainedCacheImpl_bucket_info_entry
= RGWChainedCacheImpl
<bucket_info_entry
>;
2333 RGWChainedCacheImpl_bucket_info_entry
*binfo_cache
;
2335 using tombstone_cache_t
= lru_map
<rgw_obj
, tombstone_entry
>;
2336 tombstone_cache_t
*obj_tombstone_cache
;
2338 librados::IoCtx gc_pool_ctx
; // .rgw.gc
2339 librados::IoCtx lc_pool_ctx
; // .rgw.lc
2340 librados::IoCtx objexp_pool_ctx
;
2341 librados::IoCtx reshard_pool_ctx
;
2343 bool pools_initialized
;
2345 string trans_id_suffix
;
2347 RGWQuotaHandler
*quota_handler
;
2351 RGWCoroutinesManagerRegistry
*cr_registry
;
2353 RGWSyncModulesManager
*sync_modules_manager
{nullptr};
2354 RGWSyncModuleInstanceRef sync_module
;
2355 bool writeable_zone
{false};
2357 RGWZoneGroup zonegroup
;
2358 RGWZone zone_public_config
; /* external zone params, e.g., entrypoints, log flags, etc. */
2359 RGWZoneParams zone_params
; /* internal zone params, e.g., rados pools */
2360 uint32_t zone_short_id
;
2362 RGWPeriod current_period
;
2364 RGWIndexCompletionManager
*index_completion_manager
{nullptr};
2366 RGWRados() : lock("rados_timer_lock"), watchers_lock("watchers_lock"), timer(NULL
),
2367 gc(NULL
), lc(NULL
), obj_expirer(NULL
), use_gc_thread(false), use_lc_thread(false), quota_threads(false),
2368 run_sync_thread(false), run_reshard_thread(false), async_rados(nullptr), meta_notifier(NULL
),
2369 data_notifier(NULL
), meta_sync_processor_thread(NULL
),
2370 meta_sync_thread_lock("meta_sync_thread_lock"), data_sync_thread_lock("data_sync_thread_lock"),
2371 num_watchers(0), watchers(NULL
),
2372 watch_initialized(false),
2373 bucket_id_lock("rados_bucket_id"),
2374 bucket_index_max_shards(0),
2375 max_bucket_id(0), cct(NULL
),
2376 next_rados_handle(0),
2377 handle_lock("rados_handle_lock"),
2378 binfo_cache(NULL
), obj_tombstone_cache(nullptr),
2379 pools_initialized(false),
2380 quota_handler(NULL
),
2384 rest_master_conn(NULL
),
2385 meta_mgr(NULL
), data_log(NULL
), reshard(NULL
) {}
2387 uint64_t get_new_req_id() {
2388 return ++max_req_id
;
2391 librados::IoCtx
* get_lc_pool_ctx() {
2392 return &lc_pool_ctx
;
2394 void set_context(CephContext
*_cct
) {
2399 * AmazonS3 errors contain a HostId string, but is an opaque base64 blob; we
2400 * try to be more transparent. This has a wrapper so we can update it when zonegroup/zone are changed.
2402 void init_host_id() {
2403 /* uint64_t needs 16, two '-' separators and a trailing null */
2404 const string
& zone_name
= get_zone().name
;
2405 const string
& zonegroup_name
= zonegroup
.get_name();
2406 char charbuf
[16 + zone_name
.size() + zonegroup_name
.size() + 2 + 1];
2407 snprintf(charbuf
, sizeof(charbuf
), "%llx-%s-%s", (unsigned long long)instance_id(), zone_name
.c_str(), zonegroup_name
.c_str());
2416 RGWRESTConn
*rest_master_conn
;
2417 map
<string
, RGWRESTConn
*> zone_conn_map
;
2418 map
<string
, RGWRESTConn
*> zone_data_sync_from_map
;
2419 map
<string
, RGWRESTConn
*> zone_data_notify_to_map
;
2420 map
<string
, RGWRESTConn
*> zonegroup_conn_map
;
2422 map
<string
, string
> zone_id_by_name
;
2423 map
<string
, RGWZone
> zone_by_id
;
2425 RGWRESTConn
*get_zone_conn_by_id(const string
& id
) {
2426 auto citer
= zone_conn_map
.find(id
);
2427 if (citer
== zone_conn_map
.end()) {
2431 return citer
->second
;
2434 RGWRESTConn
*get_zone_conn_by_name(const string
& name
) {
2435 auto i
= zone_id_by_name
.find(name
);
2436 if (i
== zone_id_by_name
.end()) {
2440 return get_zone_conn_by_id(i
->second
);
2443 bool find_zone_id_by_name(const string
& name
, string
*id
) {
2444 auto i
= zone_id_by_name
.find(name
);
2445 if (i
== zone_id_by_name
.end()) {
2452 int get_zonegroup(const string
& id
, RGWZoneGroup
& zonegroup
) {
2454 if (id
== get_zonegroup().get_id()) {
2455 zonegroup
= get_zonegroup();
2456 } else if (!current_period
.get_id().empty()) {
2457 ret
= current_period
.get_zonegroup(zonegroup
, id
);
2462 RGWRealm
& get_realm() {
2466 RGWZoneParams
& get_zone_params() { return zone_params
; }
2467 RGWZoneGroup
& get_zonegroup() {
2470 RGWZone
& get_zone() {
2471 return zone_public_config
;
2474 bool zone_is_writeable() {
2475 return writeable_zone
&& !get_zone().is_read_only();
2478 uint32_t get_zone_short_id() const {
2479 return zone_short_id
;
2482 bool zone_syncs_from(RGWZone
& target_zone
, RGWZone
& source_zone
);
2484 const RGWQuotaInfo
& get_bucket_quota() {
2485 return current_period
.get_config().bucket_quota
;
2488 const RGWQuotaInfo
& get_user_quota() {
2489 return current_period
.get_config().user_quota
;
2492 const string
& get_current_period_id() {
2493 return current_period
.get_id();
2496 bool has_zonegroup_api(const std::string
& api
) const {
2497 if (!current_period
.get_id().empty()) {
2498 const auto& zonegroups_by_api
= current_period
.get_map().zonegroups_by_api
;
2499 if (zonegroups_by_api
.find(api
) != zonegroups_by_api
.end())
2505 // pulls missing periods for period_history
2506 std::unique_ptr
<RGWPeriodPuller
> period_puller
;
2507 // maintains a connected history of periods
2508 std::unique_ptr
<RGWPeriodHistory
> period_history
;
2510 RGWAsyncRadosProcessor
* get_async_rados() const { return async_rados
; };
2512 RGWMetadataManager
*meta_mgr
;
2514 RGWDataChangesLog
*data_log
;
2516 RGWReshard
*reshard
;
2517 std::shared_ptr
<RGWReshardWait
> reshard_wait
;
2519 virtual ~RGWRados() = default;
2521 tombstone_cache_t
*get_tombstone_cache() {
2522 return obj_tombstone_cache
;
2525 RGWSyncModulesManager
*get_sync_modules_manager() {
2526 return sync_modules_manager
;
2528 const RGWSyncModuleInstanceRef
& get_sync_module() {
2532 int get_required_alignment(const rgw_pool
& pool
, uint64_t *alignment
);
2533 int get_max_chunk_size(const rgw_pool
& pool
, uint64_t *max_chunk_size
);
2534 int get_max_chunk_size(const string
& placement_rule
, const rgw_obj
& obj
, uint64_t *max_chunk_size
);
2536 uint32_t get_max_bucket_shards() {
2537 return rgw_shards_max();
2541 int get_raw_obj_ref(const rgw_raw_obj
& obj
, rgw_rados_ref
*ref
);
2543 int list_raw_objects_init(const rgw_pool
& pool
, const string
& marker
, RGWListRawObjsCtx
*ctx
);
2544 int list_raw_objects_next(const string
& prefix_filter
, int max
,
2545 RGWListRawObjsCtx
& ctx
, list
<string
>& oids
,
2546 bool *is_truncated
);
2547 int list_raw_objects(const rgw_pool
& pool
, const string
& prefix_filter
, int max
,
2548 RGWListRawObjsCtx
& ctx
, list
<string
>& oids
,
2549 bool *is_truncated
);
2550 string
list_raw_objs_get_cursor(RGWListRawObjsCtx
& ctx
);
2552 int list_raw_prefixed_objs(const rgw_pool
& pool
, const string
& prefix
, list
<string
>& result
);
2553 int list_zonegroups(list
<string
>& zonegroups
);
2554 int list_regions(list
<string
>& regions
);
2555 int list_zones(list
<string
>& zones
);
2556 int list_realms(list
<string
>& realms
);
2557 int list_periods(list
<string
>& periods
);
2558 int list_periods(const string
& current_period
, list
<string
>& periods
);
2561 CephContext
*ctx() { return cct
; }
2562 /** do all necessary setup of the storage device */
2563 int initialize(CephContext
*_cct
, bool _use_gc_thread
, bool _use_lc_thread
, bool _quota_threads
, bool _run_sync_thread
, bool _run_reshard_thread
) {
2565 use_gc_thread
= _use_gc_thread
;
2566 use_lc_thread
= _use_lc_thread
;
2567 quota_threads
= _quota_threads
;
2568 run_sync_thread
= _run_sync_thread
;
2569 run_reshard_thread
= _run_reshard_thread
;
2570 return initialize();
2572 /** Initialize the RADOS instance and prepare to do other ops */
2573 virtual int init_rados();
2574 int init_zg_from_period(bool *initialized
);
2575 int init_zg_from_local(bool *creating_defaults
);
2576 int init_complete();
2577 int replace_region_with_zonegroup();
2578 int convert_regionmap();
2582 int register_to_service_map(const string
& daemon_type
, const map
<string
, string
>& meta
);
2584 void schedule_context(Context
*c
);
2586 /** set up a bucket listing. handle is filled in. */
2587 int list_buckets_init(RGWAccessHandle
*handle
);
2589 * get the next bucket in the listing. obj is filled in,
2590 * handle is updated.
2592 int list_buckets_next(rgw_bucket_dir_entry
& obj
, RGWAccessHandle
*handle
);
2595 int log_list_init(const string
& prefix
, RGWAccessHandle
*handle
);
2596 int log_list_next(RGWAccessHandle handle
, string
*name
);
2599 int log_remove(const string
& name
);
2602 int log_show_init(const string
& name
, RGWAccessHandle
*handle
);
2603 int log_show_next(RGWAccessHandle handle
, rgw_log_entry
*entry
);
2605 // log bandwidth info
2606 int log_usage(map
<rgw_user_bucket
, RGWUsageBatch
>& usage_info
);
2607 int read_usage(const rgw_user
& user
, uint64_t start_epoch
, uint64_t end_epoch
, uint32_t max_entries
,
2608 bool *is_truncated
, RGWUsageIter
& read_iter
, map
<rgw_user_bucket
, rgw_usage_log_entry
>& usage
);
2609 int trim_usage(rgw_user
& user
, uint64_t start_epoch
, uint64_t end_epoch
);
2611 int create_pool(const rgw_pool
& pool
);
2613 int init_bucket_index(RGWBucketInfo
& bucket_info
, int num_shards
);
2614 int select_bucket_placement(RGWUserInfo
& user_info
, const string
& zonegroup_id
, const string
& rule
,
2615 string
*pselected_rule_name
, RGWZonePlacementInfo
*rule_info
);
2616 int select_legacy_bucket_placement(RGWZonePlacementInfo
*rule_info
);
2617 int select_new_bucket_location(RGWUserInfo
& user_info
, const string
& zonegroup_id
, const string
& rule
,
2618 string
*pselected_rule_name
, RGWZonePlacementInfo
*rule_info
);
2619 int select_bucket_location_by_rule(const string
& location_rule
, RGWZonePlacementInfo
*rule_info
);
2620 void create_bucket_id(string
*bucket_id
);
2622 bool get_obj_data_pool(const string
& placement_rule
, const rgw_obj
& obj
, rgw_pool
*pool
);
2623 bool obj_to_raw(const string
& placement_rule
, const rgw_obj
& obj
, rgw_raw_obj
*raw_obj
);
2625 int create_bucket(RGWUserInfo
& owner
, rgw_bucket
& bucket
,
2626 const string
& zonegroup_id
,
2627 const string
& placement_rule
,
2628 const string
& swift_ver_location
,
2629 const RGWQuotaInfo
* pquota_info
,
2630 map
<std::string
,bufferlist
>& attrs
,
2631 RGWBucketInfo
& bucket_info
,
2633 obj_version
*pep_objv
,
2634 ceph::real_time creation_time
,
2635 rgw_bucket
*master_bucket
,
2636 uint32_t *master_num_shards
,
2637 bool exclusive
= true);
2638 int add_bucket_placement(const rgw_pool
& new_pool
);
2639 int remove_bucket_placement(const rgw_pool
& new_pool
);
2640 int list_placement_set(set
<rgw_pool
>& names
);
2641 int create_pools(vector
<rgw_pool
>& pools
, vector
<int>& retcodes
);
2643 RGWCoroutinesManagerRegistry
*get_cr_registry() { return cr_registry
; }
2645 class SystemObject
{
2653 int get_state(RGWRawObjState
**pstate
, RGWObjVersionTracker
*objv_tracker
);
2656 SystemObject(RGWRados
*_store
, RGWObjectCtx
& _ctx
, rgw_raw_obj
& _obj
) : store(_store
), ctx(_ctx
), obj(_obj
), state(NULL
) {}
2658 void invalidate_state();
2660 RGWRados
*get_store() { return store
; }
2661 rgw_raw_obj
& get_obj() { return obj
; }
2662 RGWObjectCtx
& get_ctx() { return ctx
; }
2665 RGWRados::SystemObject
*source
;
2667 struct GetObjState
{
2669 bool has_ref
{false};
2670 uint64_t last_ver
{0};
2674 int get_ref(RGWRados
*store
, rgw_raw_obj
& obj
, rgw_rados_ref
**pref
);
2678 ceph::real_time
*lastmod
;
2680 map
<string
, bufferlist
> *attrs
;
2682 StatParams() : lastmod(NULL
), obj_size(NULL
), attrs(NULL
) {}
2686 rgw_cache_entry_info
*cache_info
{nullptr};
2687 map
<string
, bufferlist
> *attrs
;
2689 ReadParams() : attrs(NULL
) {}
2692 explicit Read(RGWRados::SystemObject
*_source
) : source(_source
) {}
2694 int stat(RGWObjVersionTracker
*objv_tracker
);
2695 int read(int64_t ofs
, int64_t end
, bufferlist
& bl
, RGWObjVersionTracker
*objv_tracker
,
2696 boost::optional
<obj_version
> refresh_version
= boost::none
);
2697 int get_attr(const char *name
, bufferlist
& dest
);
2701 struct BucketShard
{
2705 librados::IoCtx index_ctx
;
2708 explicit BucketShard(RGWRados
*_store
) : store(_store
), shard_id(-1) {}
2709 int init(const rgw_bucket
& _bucket
, const rgw_obj
& obj
);
2710 int init(const rgw_bucket
& _bucket
, int sid
);
2711 int init(const RGWBucketInfo
& bucket_info
, int sid
);
2716 RGWBucketInfo bucket_info
;
2724 bool versioning_disabled
;
2726 bool bs_initialized
;
2729 int get_state(RGWObjState
**pstate
, bool follow_olh
, bool assume_noent
= false);
2730 void invalidate_state();
2732 int prepare_atomic_modification(librados::ObjectWriteOperation
& op
, bool reset_obj
, const string
*ptag
,
2733 const char *ifmatch
, const char *ifnomatch
, bool removal_op
, bool modify_tail
);
2734 int complete_atomic_modification();
2737 Object(RGWRados
*_store
, const RGWBucketInfo
& _bucket_info
, RGWObjectCtx
& _ctx
, const rgw_obj
& _obj
) : store(_store
), bucket_info(_bucket_info
),
2738 ctx(_ctx
), obj(_obj
), bs(store
),
2739 state(NULL
), versioning_disabled(false),
2740 bs_initialized(false) {}
2742 RGWRados
*get_store() { return store
; }
2743 rgw_obj
& get_obj() { return obj
; }
2744 RGWObjectCtx
& get_ctx() { return ctx
; }
2745 RGWBucketInfo
& get_bucket_info() { return bucket_info
; }
2746 int get_manifest(RGWObjManifest
**pmanifest
);
2748 int get_bucket_shard(BucketShard
**pbs
) {
2749 if (!bs_initialized
) {
2750 int r
= bs
.init(bucket_info
.bucket
, obj
);
2754 bs_initialized
= true;
2760 void set_versioning_disabled(bool status
) {
2761 versioning_disabled
= status
;
2764 bool versioning_enabled() {
2765 return (!versioning_disabled
&& bucket_info
.versioning_enabled());
2769 RGWRados::Object
*source
;
2771 struct GetObjState
{
2772 librados::IoCtx io_ctx
;
2774 rgw_raw_obj head_obj
;
2777 struct ConditionParams
{
2778 const ceph::real_time
*mod_ptr
;
2779 const ceph::real_time
*unmod_ptr
;
2780 bool high_precision_time
;
2781 uint32_t mod_zone_id
;
2782 uint64_t mod_pg_ver
;
2783 const char *if_match
;
2784 const char *if_nomatch
;
2787 mod_ptr(NULL
), unmod_ptr(NULL
), high_precision_time(false), mod_zone_id(0), mod_pg_ver(0),
2788 if_match(NULL
), if_nomatch(NULL
) {}
2792 ceph::real_time
*lastmod
;
2794 map
<string
, bufferlist
> *attrs
;
2796 Params() : lastmod(NULL
), obj_size(NULL
), attrs(NULL
) {}
2799 explicit Read(RGWRados::Object
*_source
) : source(_source
) {}
2802 static int range_to_ofs(uint64_t obj_size
, int64_t &ofs
, int64_t &end
);
2803 int read(int64_t ofs
, int64_t end
, bufferlist
& bl
);
2804 int iterate(int64_t ofs
, int64_t end
, RGWGetDataCB
*cb
);
2805 int get_attr(const char *name
, bufferlist
& dest
);
2809 RGWRados::Object
*target
;
2812 ceph::real_time
*mtime
;
2813 map
<std::string
, bufferlist
>* rmattrs
;
2814 const bufferlist
*data
;
2815 RGWObjManifest
*manifest
;
2817 list
<rgw_obj_index_key
> *remove_objs
;
2818 ceph::real_time set_mtime
;
2820 RGWObjCategory category
;
2822 const char *if_match
;
2823 const char *if_nomatch
;
2824 boost::optional
<uint64_t> olh_epoch
;
2825 ceph::real_time delete_at
;
2827 const string
*user_data
;
2828 rgw_zone_set
*zones_trace
;
2830 bool completeMultipart
;
2832 MetaParams() : mtime(NULL
), rmattrs(NULL
), data(NULL
), manifest(NULL
), ptag(NULL
),
2833 remove_objs(NULL
), category(RGW_OBJ_CATEGORY_MAIN
), flags(0),
2834 if_match(NULL
), if_nomatch(NULL
), canceled(false), user_data(nullptr), zones_trace(nullptr),
2835 modify_tail(false), completeMultipart(false) {}
2838 explicit Write(RGWRados::Object
*_target
) : target(_target
) {}
2840 int _do_write_meta(uint64_t size
, uint64_t accounted_size
,
2841 map
<std::string
, bufferlist
>& attrs
,
2842 bool modify_tail
, bool assume_noent
,
2844 int write_meta(uint64_t size
, uint64_t accounted_size
,
2845 map
<std::string
, bufferlist
>& attrs
);
2846 int write_data(const char *data
, uint64_t ofs
, uint64_t len
, bool exclusive
);
2850 RGWRados::Object
*target
;
2852 struct DeleteParams
{
2853 rgw_user bucket_owner
;
2854 int versioning_status
;
2855 ACLOwner obj_owner
; /* needed for creation of deletion marker */
2857 string marker_version_id
;
2858 uint32_t bilog_flags
;
2859 list
<rgw_obj_index_key
> *remove_objs
;
2860 ceph::real_time expiration_time
;
2861 ceph::real_time unmod_since
;
2862 ceph::real_time mtime
; /* for setting delete marker mtime */
2863 bool high_precision_time
;
2864 rgw_zone_set
*zones_trace
;
2866 DeleteParams() : versioning_status(0), olh_epoch(0), bilog_flags(0), remove_objs(NULL
), high_precision_time(false), zones_trace(nullptr) {}
2869 struct DeleteResult
{
2873 DeleteResult() : delete_marker(false) {}
2876 explicit Delete(RGWRados::Object
*_target
) : target(_target
) {}
2882 RGWRados::Object
*source
;
2886 RGWObjManifest manifest
;
2889 struct timespec mtime
;
2890 map
<string
, bufferlist
> attrs
;
2892 Result() : has_manifest(false), size(0) {}
2896 librados::IoCtx io_ctx
;
2897 librados::AioCompletion
*completion
;
2900 State() : completion(NULL
), ret(0) {}
2904 explicit Stat(RGWRados::Object
*_source
) : source(_source
) {}
2916 RGWBucketInfo bucket_info
;
2921 Bucket(RGWRados
*_store
, const RGWBucketInfo
& _bucket_info
) : store(_store
), bucket_info(_bucket_info
), bucket(bucket_info
.bucket
),
2922 shard_id(RGW_NO_SHARD
) {}
2923 RGWRados
*get_store() { return store
; }
2924 rgw_bucket
& get_bucket() { return bucket
; }
2925 RGWBucketInfo
& get_bucket_info() { return bucket_info
; }
2927 int update_bucket_id(const string
& new_bucket_id
);
2929 int get_shard_id() { return shard_id
; }
2930 void set_shard_id(int id
) {
2935 RGWRados::Bucket
*target
;
2938 uint16_t bilog_flags
{0};
2940 bool bs_initialized
{false};
2942 bool prepared
{false};
2943 rgw_zone_set
*zones_trace
{nullptr};
2946 int r
= bs
.init(target
->get_bucket(), obj
);
2950 bs_initialized
= true;
2954 void invalidate_bs() {
2955 bs_initialized
= false;
2958 int guard_reshard(BucketShard
**pbs
, std::function
<int(BucketShard
*)> call
);
2961 UpdateIndex(RGWRados::Bucket
*_target
, const rgw_obj
& _obj
) : target(_target
), obj(_obj
),
2962 bs(target
->get_store()) {
2963 blind
= (target
->get_bucket_info().index_type
== RGWBIType_Indexless
);
2966 int get_bucket_shard(BucketShard
**pbs
) {
2967 if (!bs_initialized
) {
2977 void set_bilog_flags(uint16_t flags
) {
2978 bilog_flags
= flags
;
2981 void set_zones_trace(rgw_zone_set
*_zones_trace
) {
2982 zones_trace
= _zones_trace
;
2985 int prepare(RGWModifyOp
, const string
*write_tag
);
2986 int complete(int64_t poolid
, uint64_t epoch
, uint64_t size
,
2987 uint64_t accounted_size
, ceph::real_time
& ut
,
2988 const string
& etag
, const string
& content_type
,
2989 bufferlist
*acl_bl
, RGWObjCategory category
,
2990 list
<rgw_obj_index_key
> *remove_objs
, const string
*user_data
= nullptr);
2991 int complete_del(int64_t poolid
, uint64_t epoch
,
2992 ceph::real_time
& removed_mtime
, /* mtime of removed object */
2993 list
<rgw_obj_index_key
> *remove_objs
);
2996 const string
*get_optag() { return &optag
; }
2998 bool is_prepared() { return prepared
; }
2999 }; // class UpdateIndex
3004 RGWRados::Bucket
*target
;
3005 rgw_obj_key next_marker
;
3007 int list_objects_ordered(int64_t max
,
3008 vector
<rgw_bucket_dir_entry
> *result
,
3009 map
<string
, bool> *common_prefixes
,
3010 bool *is_truncated
);
3011 int list_objects_unordered(int64_t max
,
3012 vector
<rgw_bucket_dir_entry
> *result
,
3013 map
<string
, bool> *common_prefixes
,
3014 bool *is_truncated
);
3022 rgw_obj_key end_marker
;
3025 RGWAccessListFilter
*filter
;
3027 bool allow_unordered
;
3032 list_versions(false),
3033 allow_unordered(false)
3037 explicit List(RGWRados::Bucket
*_target
) : target(_target
) {}
3039 int list_objects(int64_t max
,
3040 vector
<rgw_bucket_dir_entry
> *result
,
3041 map
<string
, bool> *common_prefixes
,
3042 bool *is_truncated
) {
3043 if (params
.allow_unordered
) {
3044 return list_objects_unordered(max
, result
, common_prefixes
,
3047 return list_objects_ordered(max
, result
, common_prefixes
,
3051 rgw_obj_key
& get_next_marker() {
3057 /** Write/overwrite an object to the bucket storage. */
3058 virtual int put_system_obj_impl(rgw_raw_obj
& obj
, uint64_t size
, ceph::real_time
*mtime
,
3059 map
<std::string
, bufferlist
>& attrs
, int flags
,
3061 RGWObjVersionTracker
*objv_tracker
,
3062 ceph::real_time set_mtime
/* 0 for don't set */);
3064 virtual int put_system_obj_data(void *ctx
, rgw_raw_obj
& obj
, bufferlist
& bl
,
3065 off_t ofs
, bool exclusive
,
3066 RGWObjVersionTracker
*objv_tracker
= nullptr);
3067 int aio_put_obj_data(void *ctx
, rgw_raw_obj
& obj
, bufferlist
& bl
,
3068 off_t ofs
, bool exclusive
, void **handle
);
3070 int put_system_obj(void *ctx
, rgw_raw_obj
& obj
, const char *data
, size_t len
, bool exclusive
,
3071 ceph::real_time
*mtime
, map
<std::string
, bufferlist
>& attrs
, RGWObjVersionTracker
*objv_tracker
,
3072 ceph::real_time set_mtime
) {
3074 bl
.append(data
, len
);
3075 int flags
= PUT_OBJ_CREATE
;
3077 flags
|= PUT_OBJ_EXCL
;
3079 return put_system_obj_impl(obj
, len
, mtime
, attrs
, flags
, bl
, objv_tracker
, set_mtime
);
3081 int aio_wait(void *handle
);
3082 bool aio_completed(void *handle
);
3084 int on_last_entry_in_listing(RGWBucketInfo
& bucket_info
,
3085 const std::string
& obj_prefix
,
3086 const std::string
& obj_delim
,
3087 std::function
<int(const rgw_bucket_dir_entry
&)> handler
);
3089 bool swift_versioning_enabled(const RGWBucketInfo
& bucket_info
) const {
3090 return bucket_info
.has_swift_versioning() &&
3091 bucket_info
.swift_ver_location
.size();
3094 int swift_versioning_copy(RGWObjectCtx
& obj_ctx
, /* in/out */
3095 const rgw_user
& user
, /* in */
3096 RGWBucketInfo
& bucket_info
, /* in */
3097 rgw_obj
& obj
); /* in */
3098 int swift_versioning_restore(RGWObjectCtx
& obj_ctx
, /* in/out */
3099 const rgw_user
& user
, /* in */
3100 RGWBucketInfo
& bucket_info
, /* in */
3101 rgw_obj
& obj
, /* in */
3102 bool& restored
); /* out */
3103 int copy_obj_to_remote_dest(RGWObjState
*astate
,
3104 map
<string
, bufferlist
>& src_attrs
,
3105 RGWRados::Object::Read
& read_op
,
3106 const rgw_user
& user_id
,
3108 ceph::real_time
*mtime
);
3112 ATTRSMOD_REPLACE
= 1,
3116 int rewrite_obj(RGWBucketInfo
& dest_bucket_info
, rgw_obj
& obj
);
3118 int stat_remote_obj(RGWObjectCtx
& obj_ctx
,
3119 const rgw_user
& user_id
,
3120 const string
& client_id
,
3122 const string
& source_zone
,
3124 RGWBucketInfo
& src_bucket_info
,
3125 real_time
*src_mtime
,
3127 const real_time
*mod_ptr
,
3128 const real_time
*unmod_ptr
,
3129 bool high_precision_time
,
3130 const char *if_match
,
3131 const char *if_nomatch
,
3132 map
<string
, bufferlist
> *pattrs
,
3137 int fetch_remote_obj(RGWObjectCtx
& obj_ctx
,
3138 const rgw_user
& user_id
,
3139 const string
& client_id
,
3140 const string
& op_id
,
3141 bool record_op_state
,
3143 const string
& source_zone
,
3146 RGWBucketInfo
& dest_bucket_info
,
3147 RGWBucketInfo
& src_bucket_info
,
3148 ceph::real_time
*src_mtime
,
3149 ceph::real_time
*mtime
,
3150 const ceph::real_time
*mod_ptr
,
3151 const ceph::real_time
*unmod_ptr
,
3152 bool high_precision_time
,
3153 const char *if_match
,
3154 const char *if_nomatch
,
3157 map
<string
, bufferlist
>& attrs
,
3158 RGWObjCategory category
,
3159 boost::optional
<uint64_t> olh_epoch
,
3160 ceph::real_time delete_at
,
3163 ceph::buffer::list
*petag
,
3164 void (*progress_cb
)(off_t
, void *),
3165 void *progress_data
,
3166 rgw_zone_set
*zones_trace
= nullptr);
3169 * dest_obj: the object to copy into
3170 * src_obj: the object to copy from
3171 * attrs: usage depends on attrs_mod parameter
3172 * attrs_mod: the modification mode of the attrs, may have the following values:
3173 * ATTRSMOD_NONE - the attributes of the source object will be
3174 * copied without modifications, attrs parameter is ignored;
3175 * ATTRSMOD_REPLACE - new object will have the attributes provided by attrs
3176 * parameter, source object attributes are not copied;
3177 * ATTRSMOD_MERGE - any conflicting meta keys on the source object's attributes
3178 * are overwritten by values contained in attrs parameter.
3179 * Returns: 0 on success, -ERR# otherwise.
3181 int copy_obj(RGWObjectCtx
& obj_ctx
,
3182 const rgw_user
& user_id
,
3183 const string
& client_id
,
3184 const string
& op_id
,
3186 const string
& source_zone
,
3189 RGWBucketInfo
& dest_bucket_info
,
3190 RGWBucketInfo
& src_bucket_info
,
3191 ceph::real_time
*src_mtime
,
3192 ceph::real_time
*mtime
,
3193 const ceph::real_time
*mod_ptr
,
3194 const ceph::real_time
*unmod_ptr
,
3195 bool high_precision_time
,
3196 const char *if_match
,
3197 const char *if_nomatch
,
3200 map
<std::string
, bufferlist
>& attrs
,
3201 RGWObjCategory category
,
3203 ceph::real_time delete_at
,
3206 ceph::buffer::list
*petag
,
3207 void (*progress_cb
)(off_t
, void *),
3208 void *progress_data
);
3210 int copy_obj_data(RGWObjectCtx
& obj_ctx
,
3211 RGWBucketInfo
& dest_bucket_info
,
3212 RGWRados::Object::Read
& read_op
, off_t end
,
3215 uint64_t max_chunk_size
,
3216 ceph::real_time
*mtime
,
3217 ceph::real_time set_mtime
,
3218 map
<string
, bufferlist
>& attrs
,
3219 RGWObjCategory category
,
3221 ceph::real_time delete_at
,
3224 ceph::buffer::list
*petag
);
3226 int check_bucket_empty(RGWBucketInfo
& bucket_info
);
3230 * bucket: the name of the bucket to delete
3231 * Returns 0 on success, -ERR# otherwise.
3233 int delete_bucket(RGWBucketInfo
& bucket_info
, RGWObjVersionTracker
& objv_tracker
, bool check_empty
= true);
3235 bool is_meta_master();
3238 * Check to see if the bucket metadata is synced
3240 bool is_syncing_bucket_meta(const rgw_bucket
& bucket
);
3241 void wakeup_meta_sync_shards(set
<int>& shard_ids
);
3242 void wakeup_data_sync_shards(const string
& source_zone
, map
<int, set
<string
> >& shard_ids
);
3244 RGWMetaSyncStatusManager
* get_meta_sync_manager();
3245 RGWDataSyncStatusManager
* get_data_sync_manager(const std::string
& source_zone
);
3247 int set_bucket_owner(rgw_bucket
& bucket
, ACLOwner
& owner
);
3248 int set_buckets_enabled(std::vector
<rgw_bucket
>& buckets
, bool enabled
);
3249 int bucket_suspended(rgw_bucket
& bucket
, bool *suspended
);
3251 /** Delete an object.*/
3252 int delete_obj(RGWObjectCtx
& obj_ctx
,
3253 const RGWBucketInfo
& bucket_owner
,
3254 const rgw_obj
& src_obj
,
3255 int versioning_status
,
3256 uint16_t bilog_flags
= 0,
3257 const ceph::real_time
& expiration_time
= ceph::real_time(),
3258 rgw_zone_set
*zones_trace
= nullptr);
3260 /** Delete a raw object.*/
3261 int delete_raw_obj(const rgw_raw_obj
& obj
);
3263 /* Delete a system object */
3264 virtual int delete_system_obj(rgw_raw_obj
& src_obj
, RGWObjVersionTracker
*objv_tracker
= NULL
);
3266 /** Remove an object from the bucket index */
3267 int delete_obj_index(const rgw_obj
& obj
);
3270 * Get an attribute for a system object.
3271 * obj: the object to get attr
3272 * name: name of the attr to retrieve
3273 * dest: bufferlist to store the result in
3274 * Returns: 0 on success, -ERR# otherwise.
3276 virtual int system_obj_get_attr(rgw_raw_obj
& obj
, const char *name
, bufferlist
& dest
);
3278 int system_obj_set_attr(void *ctx
, rgw_raw_obj
& obj
, const char *name
, bufferlist
& bl
,
3279 RGWObjVersionTracker
*objv_tracker
);
3280 virtual int system_obj_set_attrs(void *ctx
, rgw_raw_obj
& obj
,
3281 map
<string
, bufferlist
>& attrs
,
3282 map
<string
, bufferlist
>* rmattrs
,
3283 RGWObjVersionTracker
*objv_tracker
);
3286 * Set an attr on an object.
3287 * bucket: name of the bucket holding the object
3288 * obj: name of the object to set the attr on
3289 * name: the attr to set
3290 * bl: the contents of the attr
3291 * Returns: 0 on success, -ERR# otherwise.
3293 int set_attr(void *ctx
, const RGWBucketInfo
& bucket_info
, rgw_obj
& obj
, const char *name
, bufferlist
& bl
);
3295 int set_attrs(void *ctx
, const RGWBucketInfo
& bucket_info
, rgw_obj
& obj
,
3296 map
<string
, bufferlist
>& attrs
,
3297 map
<string
, bufferlist
>* rmattrs
);
3299 int get_system_obj_state(RGWObjectCtx
*rctx
, rgw_raw_obj
& obj
, RGWRawObjState
**state
, RGWObjVersionTracker
*objv_tracker
);
3300 int get_obj_state(RGWObjectCtx
*rctx
, const RGWBucketInfo
& bucket_info
, const rgw_obj
& obj
, RGWObjState
**state
,
3301 bool follow_olh
, bool assume_noent
= false);
3302 int get_obj_state(RGWObjectCtx
*rctx
, const RGWBucketInfo
& bucket_info
, const rgw_obj
& obj
, RGWObjState
**state
) {
3303 return get_obj_state(rctx
, bucket_info
, obj
, state
, true);
3306 virtual int stat_system_obj(RGWObjectCtx
& obj_ctx
,
3307 RGWRados::SystemObject::Read::GetObjState
& state
,
3309 map
<string
, bufferlist
> *attrs
,
3310 ceph::real_time
*lastmod
,
3312 RGWObjVersionTracker
*objv_tracker
);
3314 virtual int get_system_obj(RGWObjectCtx
& obj_ctx
, RGWRados::SystemObject::Read::GetObjState
& read_state
,
3315 RGWObjVersionTracker
*objv_tracker
, rgw_raw_obj
& obj
,
3316 bufferlist
& bl
, off_t ofs
, off_t end
,
3317 map
<string
, bufferlist
> *attrs
,
3318 rgw_cache_entry_info
*cache_info
,
3319 boost::optional
<obj_version
> refresh_version
=
3322 virtual void register_chained_cache(RGWChainedCache
*cache
) {}
3323 virtual bool chain_cache_entry(list
<rgw_cache_entry_info
*>& cache_info_entries
, RGWChainedCache::Entry
*chained_entry
) { return false; }
3325 int iterate_obj(RGWObjectCtx
& ctx
,
3326 const RGWBucketInfo
& bucket_info
, const rgw_obj
& obj
,
3327 off_t ofs
, off_t end
,
3328 uint64_t max_chunk_size
,
3329 int (*iterate_obj_cb
)(const RGWBucketInfo
& bucket_info
, const rgw_obj
& obj
, const rgw_raw_obj
&, off_t
, off_t
, off_t
, bool, RGWObjState
*, void *),
3332 int flush_read_list(struct get_obj_data
*d
);
3334 int get_obj_iterate_cb(RGWObjectCtx
*ctx
, RGWObjState
*astate
,
3335 const RGWBucketInfo
& bucket_info
, const rgw_obj
& obj
,
3336 const rgw_raw_obj
& read_obj
,
3337 off_t obj_ofs
, off_t read_ofs
, off_t len
,
3338 bool is_head_obj
, void *arg
);
3340 void get_obj_aio_completion_cb(librados::completion_t cb
, void *arg
);
3343 * a simple object read without keeping state
3346 virtual int raw_obj_stat(rgw_raw_obj
& obj
, uint64_t *psize
, ceph::real_time
*pmtime
, uint64_t *epoch
,
3347 map
<string
, bufferlist
> *attrs
, bufferlist
*first_chunk
,
3348 RGWObjVersionTracker
*objv_tracker
);
3350 int obj_operate(const RGWBucketInfo
& bucket_info
, const rgw_obj
& obj
, librados::ObjectWriteOperation
*op
);
3351 int obj_operate(const RGWBucketInfo
& bucket_info
, const rgw_obj
& obj
, librados::ObjectReadOperation
*op
);
3353 int guard_reshard(BucketShard
*bs
, const rgw_obj
& obj_instance
, std::function
<int(BucketShard
*)> call
);
3354 int block_while_resharding(RGWRados::BucketShard
*bs
, string
*new_bucket_id
);
3356 void bucket_index_guard_olh_op(RGWObjState
& olh_state
, librados::ObjectOperation
& op
);
3357 int olh_init_modification(const RGWBucketInfo
& bucket_info
, RGWObjState
& state
, const rgw_obj
& olh_obj
, string
*op_tag
);
3358 int olh_init_modification_impl(const RGWBucketInfo
& bucket_info
, RGWObjState
& state
, const rgw_obj
& olh_obj
, string
*op_tag
);
3359 int bucket_index_link_olh(const RGWBucketInfo
& bucket_info
, RGWObjState
& olh_state
,
3360 const rgw_obj
& obj_instance
, bool delete_marker
,
3361 const string
& op_tag
, struct rgw_bucket_dir_entry_meta
*meta
,
3363 ceph::real_time unmod_since
, bool high_precision_time
,
3364 rgw_zone_set
*zones_trace
= nullptr,
3365 bool log_data_change
= false);
3366 int bucket_index_unlink_instance(const RGWBucketInfo
& bucket_info
, const rgw_obj
& obj_instance
, const string
& op_tag
, const string
& olh_tag
, uint64_t olh_epoch
, rgw_zone_set
*zones_trace
= nullptr);
3367 int bucket_index_read_olh_log(const RGWBucketInfo
& bucket_info
, RGWObjState
& state
, const rgw_obj
& obj_instance
, uint64_t ver_marker
,
3368 map
<uint64_t, vector
<rgw_bucket_olh_log_entry
> > *log
, bool *is_truncated
);
3369 int bucket_index_trim_olh_log(const RGWBucketInfo
& bucket_info
, RGWObjState
& obj_state
, const rgw_obj
& obj_instance
, uint64_t ver
);
3370 int bucket_index_clear_olh(const RGWBucketInfo
& bucket_info
, RGWObjState
& state
, const rgw_obj
& obj_instance
);
3371 int apply_olh_log(RGWObjectCtx
& ctx
, RGWObjState
& obj_state
, const RGWBucketInfo
& bucket_info
, const rgw_obj
& obj
,
3372 bufferlist
& obj_tag
, map
<uint64_t, vector
<rgw_bucket_olh_log_entry
> >& log
,
3373 uint64_t *plast_ver
, rgw_zone_set
*zones_trace
= nullptr);
3374 int update_olh(RGWObjectCtx
& obj_ctx
, RGWObjState
*state
, const RGWBucketInfo
& bucket_info
, const rgw_obj
& obj
, rgw_zone_set
*zones_trace
= nullptr);
3375 int set_olh(RGWObjectCtx
& obj_ctx
, RGWBucketInfo
& bucket_info
, const rgw_obj
& target_obj
, bool delete_marker
, rgw_bucket_dir_entry_meta
*meta
,
3376 uint64_t olh_epoch
, ceph::real_time unmod_since
, bool high_precision_time
,
3377 rgw_zone_set
*zones_trace
= nullptr, bool log_data_change
= false);
3378 int unlink_obj_instance(RGWObjectCtx
& obj_ctx
, RGWBucketInfo
& bucket_info
, const rgw_obj
& target_obj
,
3379 uint64_t olh_epoch
, rgw_zone_set
*zones_trace
= nullptr);
3381 void check_pending_olh_entries(map
<string
, bufferlist
>& pending_entries
, map
<string
, bufferlist
> *rm_pending_entries
);
3382 int remove_olh_pending_entries(const RGWBucketInfo
& bucket_info
, RGWObjState
& state
, const rgw_obj
& olh_obj
, map
<string
, bufferlist
>& pending_attrs
);
3383 int follow_olh(const RGWBucketInfo
& bucket_info
, RGWObjectCtx
& ctx
, RGWObjState
*state
, const rgw_obj
& olh_obj
, rgw_obj
*target
);
3384 int get_olh(const RGWBucketInfo
& bucket_info
, const rgw_obj
& obj
, RGWOLHInfo
*olh
);
3386 void gen_rand_obj_instance_name(rgw_obj
*target
);
3388 int omap_get_vals(rgw_raw_obj
& obj
, bufferlist
& header
, const std::string
& marker
, uint64_t count
, std::map
<string
, bufferlist
>& m
);
3389 int omap_get_all(rgw_raw_obj
& obj
, bufferlist
& header
, std::map
<string
, bufferlist
>& m
);
3390 int omap_set(rgw_raw_obj
& obj
, const std::string
& key
, bufferlist
& bl
);
3391 int omap_set(rgw_raw_obj
& obj
, map
<std::string
, bufferlist
>& m
);
3392 int omap_del(rgw_raw_obj
& obj
, const std::string
& key
);
3393 int update_containers_stats(map
<string
, RGWBucketEnt
>& m
);
3394 int append_async(rgw_raw_obj
& obj
, size_t size
, bufferlist
& bl
);
3396 int watch(const string
& oid
, uint64_t *watch_handle
, librados::WatchCtx2
*ctx
);
3397 int unwatch(uint64_t watch_handle
);
3398 void add_watcher(int i
);
3399 void remove_watcher(int i
);
3400 virtual bool need_watch_notify() { return false; }
3402 void finalize_watch();
3403 int distribute(const string
& key
, bufferlist
& bl
);
3404 virtual int watch_cb(uint64_t notify_id
,
3406 uint64_t notifier_id
,
3407 bufferlist
& bl
) { return 0; }
3408 void pick_control_oid(const string
& key
, string
& notify_oid
);
3410 virtual void set_cache_enabled(bool state
) {}
3412 void set_atomic(void *ctx
, rgw_obj
& obj
) {
3413 RGWObjectCtx
*rctx
= static_cast<RGWObjectCtx
*>(ctx
);
3414 rctx
->obj
.set_atomic(obj
);
3416 void set_prefetch_data(void *ctx
, rgw_obj
& obj
) {
3417 RGWObjectCtx
*rctx
= static_cast<RGWObjectCtx
*>(ctx
);
3418 rctx
->obj
.set_prefetch_data(obj
);
3420 void set_prefetch_data(void *ctx
, rgw_raw_obj
& obj
) {
3421 RGWObjectCtx
*rctx
= static_cast<RGWObjectCtx
*>(ctx
);
3422 rctx
->raw
.set_prefetch_data(obj
);
3425 int decode_policy(bufferlist
& bl
, ACLOwner
*owner
);
3426 int get_bucket_stats(RGWBucketInfo
& bucket_info
, int shard_id
, string
*bucket_ver
, string
*master_ver
,
3427 map
<RGWObjCategory
, RGWStorageStats
>& stats
, string
*max_marker
, bool* syncstopped
= NULL
);
3428 int get_bucket_stats_async(RGWBucketInfo
& bucket_info
, int shard_id
, RGWGetBucketStats_CB
*cb
);
3429 int get_user_stats(const rgw_user
& user
, RGWStorageStats
& stats
);
3430 int get_user_stats_async(const rgw_user
& user
, RGWGetUserStats_CB
*cb
);
3431 void get_bucket_instance_obj(const rgw_bucket
& bucket
, rgw_raw_obj
& obj
);
3432 void get_bucket_meta_oid(const rgw_bucket
& bucket
, string
& oid
);
3434 int put_bucket_entrypoint_info(const string
& tenant_name
, const string
& bucket_name
, RGWBucketEntryPoint
& entry_point
,
3435 bool exclusive
, RGWObjVersionTracker
& objv_tracker
, ceph::real_time mtime
,
3436 map
<string
, bufferlist
> *pattrs
);
3437 int put_bucket_instance_info(RGWBucketInfo
& info
, bool exclusive
, ceph::real_time mtime
, map
<string
, bufferlist
> *pattrs
);
3438 int get_bucket_entrypoint_info(RGWObjectCtx
& obj_ctx
, const string
& tenant_name
, const string
& bucket_name
,
3439 RGWBucketEntryPoint
& entry_point
, RGWObjVersionTracker
*objv_tracker
,
3440 ceph::real_time
*pmtime
, map
<string
, bufferlist
> *pattrs
, rgw_cache_entry_info
*cache_info
= NULL
,
3441 boost::optional
<obj_version
> refresh_version
= boost::none
);
3442 int get_bucket_instance_info(RGWObjectCtx
& obj_ctx
, const string
& meta_key
, RGWBucketInfo
& info
, ceph::real_time
*pmtime
, map
<string
, bufferlist
> *pattrs
);
3443 int get_bucket_instance_info(RGWObjectCtx
& obj_ctx
, const rgw_bucket
& bucket
, RGWBucketInfo
& info
, ceph::real_time
*pmtime
, map
<string
, bufferlist
> *pattrs
);
3444 int get_bucket_instance_from_oid(RGWObjectCtx
& obj_ctx
, const string
& oid
, RGWBucketInfo
& info
, ceph::real_time
*pmtime
, map
<string
, bufferlist
> *pattrs
,
3445 rgw_cache_entry_info
*cache_info
= NULL
,
3446 boost::optional
<obj_version
> refresh_version
= boost::none
);
3448 int convert_old_bucket_info(RGWObjectCtx
& obj_ctx
, const string
& tenant_name
, const string
& bucket_name
);
3449 static void make_bucket_entry_name(const string
& tenant_name
, const string
& bucket_name
, string
& bucket_entry
);
3453 int _get_bucket_info(RGWObjectCtx
& obj_ctx
, const string
& tenant
,
3454 const string
& bucket_name
, RGWBucketInfo
& info
,
3456 map
<string
, bufferlist
> *pattrs
,
3457 boost::optional
<obj_version
> refresh_version
);
3460 bool call(std::string command
, cmdmap_t
& cmdmap
, std::string format
,
3461 bufferlist
& out
) override final
;
3463 // Should really be protected, but some older GCCs don't handle
3464 // access control properly with lambdas defined in member functions
3465 // of child classes.
3467 void cache_list_dump_helper(Formatter
* f
,
3468 const std::string
& name
,
3469 const ceph::real_time mtime
,
3470 const std::uint64_t size
) {
3471 f
->dump_string("name", name
);
3472 f
->dump_string("mtime", ceph::to_iso_8601(mtime
));
3473 f
->dump_unsigned("size", size
);
3478 // `call_list` must iterate over all cache entries and call
3479 // `cache_list_dump_helper` with the supplied Formatter on any that
3480 // include `filter` as a substring.
3482 virtual void call_list(const boost::optional
<std::string
>& filter
,
3484 // `call_inspect` must look up the requested target and, if found,
3485 // dump it to the supplied Formatter and return true. If not found,
3486 // it must return false.
3488 virtual bool call_inspect(const std::string
& target
, Formatter
* format
);
3490 // `call_erase` must erase the requested target and return true. If
3491 // the requested target does not exist, it should return false.
3492 virtual bool call_erase(const std::string
& target
);
3494 // `call_zap` must erase the cache.
3495 virtual void call_zap();
3498 int get_bucket_info(RGWObjectCtx
& obj_ctx
,
3499 const string
& tenant_name
, const string
& bucket_name
,
3500 RGWBucketInfo
& info
,
3501 ceph::real_time
*pmtime
, map
<string
, bufferlist
> *pattrs
= NULL
);
3503 // Returns true on successful refresh. Returns false if there was an
3504 // error or the version stored on the OSD is the same as that
3505 // presented in the BucketInfo structure.
3507 int try_refresh_bucket_info(RGWBucketInfo
& info
,
3508 ceph::real_time
*pmtime
,
3509 map
<string
, bufferlist
> *pattrs
= nullptr);
3511 int put_linked_bucket_info(RGWBucketInfo
& info
, bool exclusive
, ceph::real_time mtime
, obj_version
*pep_objv
,
3512 map
<string
, bufferlist
> *pattrs
, bool create_entry_point
);
3514 int cls_rgw_init_index(librados::IoCtx
& io_ctx
, librados::ObjectWriteOperation
& op
, string
& oid
);
3515 int cls_obj_prepare_op(BucketShard
& bs
, RGWModifyOp op
, string
& tag
, rgw_obj
& obj
, uint16_t bilog_flags
, rgw_zone_set
*zones_trace
= nullptr);
3516 int cls_obj_complete_op(BucketShard
& bs
, const rgw_obj
& obj
, RGWModifyOp op
, string
& tag
, int64_t pool
, uint64_t epoch
,
3517 rgw_bucket_dir_entry
& ent
, RGWObjCategory category
, list
<rgw_obj_index_key
> *remove_objs
, uint16_t bilog_flags
, rgw_zone_set
*zones_trace
= nullptr);
3518 int cls_obj_complete_add(BucketShard
& bs
, const rgw_obj
& obj
, string
& tag
, int64_t pool
, uint64_t epoch
, rgw_bucket_dir_entry
& ent
,
3519 RGWObjCategory category
, list
<rgw_obj_index_key
> *remove_objs
, uint16_t bilog_flags
, rgw_zone_set
*zones_trace
= nullptr);
3520 int cls_obj_complete_del(BucketShard
& bs
, string
& tag
, int64_t pool
, uint64_t epoch
, rgw_obj
& obj
,
3521 ceph::real_time
& removed_mtime
, list
<rgw_obj_index_key
> *remove_objs
, uint16_t bilog_flags
, rgw_zone_set
*zones_trace
= nullptr);
3522 int cls_obj_complete_cancel(BucketShard
& bs
, string
& tag
, rgw_obj
& obj
, uint16_t bilog_flags
, rgw_zone_set
*zones_trace
= nullptr);
3523 int cls_obj_set_bucket_tag_timeout(RGWBucketInfo
& bucket_info
, uint64_t timeout
);
3524 int cls_bucket_list_ordered(RGWBucketInfo
& bucket_info
, int shard_id
,
3525 rgw_obj_index_key
& start
, const string
& prefix
,
3526 uint32_t num_entries
, bool list_versions
,
3527 map
<string
, rgw_bucket_dir_entry
>& m
,
3529 rgw_obj_index_key
*last_entry
,
3530 bool (*force_check_filter
)(const string
& name
) = nullptr);
3531 int cls_bucket_list_unordered(RGWBucketInfo
& bucket_info
, int shard_id
,
3532 rgw_obj_index_key
& start
, const string
& prefix
,
3533 uint32_t num_entries
, bool list_versions
,
3534 vector
<rgw_bucket_dir_entry
>& ent_list
,
3535 bool *is_truncated
, rgw_obj_index_key
*last_entry
,
3536 bool (*force_check_filter
)(const string
& name
) = nullptr);
3537 int cls_bucket_head(const RGWBucketInfo
& bucket_info
, int shard_id
, map
<string
, struct rgw_bucket_dir_header
>& headers
, map
<int, string
> *bucket_instance_ids
= NULL
);
3538 int cls_bucket_head_async(const RGWBucketInfo
& bucket_info
, int shard_id
, RGWGetDirHeader_CB
*ctx
, int *num_aio
);
3539 int list_bi_log_entries(RGWBucketInfo
& bucket_info
, int shard_id
, string
& marker
, uint32_t max
, std::list
<rgw_bi_log_entry
>& result
, bool *truncated
);
3540 int trim_bi_log_entries(RGWBucketInfo
& bucket_info
, int shard_id
, string
& marker
, string
& end_marker
);
3541 int resync_bi_log_entries(RGWBucketInfo
& bucket_info
, int shard_id
);
3542 int stop_bi_log_entries(RGWBucketInfo
& bucket_info
, int shard_id
);
3543 int get_bi_log_status(RGWBucketInfo
& bucket_info
, int shard_id
, map
<int, string
>& max_marker
);
3545 int bi_get_instance(const RGWBucketInfo
& bucket_info
, rgw_obj
& obj
, rgw_bucket_dir_entry
*dirent
);
3546 int bi_get(rgw_bucket
& bucket
, rgw_obj
& obj
, BIIndexType index_type
, rgw_cls_bi_entry
*entry
);
3547 void bi_put(librados::ObjectWriteOperation
& op
, BucketShard
& bs
, rgw_cls_bi_entry
& entry
);
3548 int bi_put(BucketShard
& bs
, rgw_cls_bi_entry
& entry
);
3549 int bi_put(rgw_bucket
& bucket
, rgw_obj
& obj
, rgw_cls_bi_entry
& entry
);
3550 int bi_list(rgw_bucket
& bucket
, int shard_id
, const string
& filter_obj
, const string
& marker
, uint32_t max
, list
<rgw_cls_bi_entry
> *entries
, bool *is_truncated
);
3551 int bi_list(BucketShard
& bs
, const string
& filter_obj
, const string
& marker
, uint32_t max
, list
<rgw_cls_bi_entry
> *entries
, bool *is_truncated
);
3552 int bi_list(rgw_bucket
& bucket
, const string
& obj_name
, const string
& marker
, uint32_t max
,
3553 list
<rgw_cls_bi_entry
> *entries
, bool *is_truncated
);
3554 int bi_remove(BucketShard
& bs
);
3556 int cls_obj_usage_log_add(const string
& oid
, rgw_usage_log_info
& info
);
3557 int cls_obj_usage_log_read(string
& oid
, string
& user
, uint64_t start_epoch
, uint64_t end_epoch
, uint32_t max_entries
,
3558 string
& read_iter
, map
<rgw_user_bucket
, rgw_usage_log_entry
>& usage
, bool *is_truncated
);
3559 int cls_obj_usage_log_trim(string
& oid
, string
& user
, uint64_t start_epoch
, uint64_t end_epoch
);
3561 int key_to_shard_id(const string
& key
, int max_shards
);
3562 void shard_name(const string
& prefix
, unsigned max_shards
, const string
& key
, string
& name
, int *shard_id
);
3563 void shard_name(const string
& prefix
, unsigned max_shards
, const string
& section
, const string
& key
, string
& name
);
3564 void shard_name(const string
& prefix
, unsigned shard_id
, string
& name
);
3565 int get_target_shard_id(const RGWBucketInfo
& bucket_info
, const string
& obj_key
, int *shard_id
);
3566 void time_log_prepare_entry(cls_log_entry
& entry
, const ceph::real_time
& ut
, const string
& section
, const string
& key
, bufferlist
& bl
);
3567 int time_log_add_init(librados::IoCtx
& io_ctx
);
3568 int time_log_add(const string
& oid
, list
<cls_log_entry
>& entries
,
3569 librados::AioCompletion
*completion
, bool monotonic_inc
= true);
3570 int time_log_add(const string
& oid
, const ceph::real_time
& ut
, const string
& section
, const string
& key
, bufferlist
& bl
);
3571 int time_log_list(const string
& oid
, const ceph::real_time
& start_time
, const ceph::real_time
& end_time
,
3572 int max_entries
, list
<cls_log_entry
>& entries
,
3573 const string
& marker
, string
*out_marker
, bool *truncated
);
3574 int time_log_info(const string
& oid
, cls_log_header
*header
);
3575 int time_log_info_async(librados::IoCtx
& io_ctx
, const string
& oid
, cls_log_header
*header
, librados::AioCompletion
*completion
);
3576 int time_log_trim(const string
& oid
, const ceph::real_time
& start_time
, const ceph::real_time
& end_time
,
3577 const string
& from_marker
, const string
& to_marker
,
3578 librados::AioCompletion
*completion
= nullptr);
3580 string
objexp_hint_get_shardname(int shard_num
);
3581 int objexp_key_shard(const rgw_obj_index_key
& key
);
3582 void objexp_get_shard(int shard_num
,
3583 string
& shard
); /* out */
3584 int objexp_hint_add(const ceph::real_time
& delete_at
,
3585 const string
& tenant_name
,
3586 const string
& bucket_name
,
3587 const string
& bucket_id
,
3588 const rgw_obj_index_key
& obj_key
);
3589 int objexp_hint_list(const string
& oid
,
3590 const ceph::real_time
& start_time
,
3591 const ceph::real_time
& end_time
,
3592 const int max_entries
,
3593 const string
& marker
,
3594 list
<cls_timeindex_entry
>& entries
, /* out */
3595 string
*out_marker
, /* out */
3596 bool *truncated
); /* out */
3597 int objexp_hint_parse(cls_timeindex_entry
&ti_entry
,
3598 objexp_hint_entry
& hint_entry
); /* out */
3599 int objexp_hint_trim(const string
& oid
,
3600 const ceph::real_time
& start_time
,
3601 const ceph::real_time
& end_time
,
3602 const string
& from_marker
= std::string(),
3603 const string
& to_marker
= std::string());
3605 int lock_exclusive(rgw_pool
& pool
, const string
& oid
, ceph::timespan
& duration
, string
& zone_id
, string
& owner_id
);
3606 int unlock(rgw_pool
& pool
, const string
& oid
, string
& zone_id
, string
& owner_id
);
3608 void update_gc_chain(rgw_obj
& head_obj
, RGWObjManifest
& manifest
, cls_rgw_obj_chain
*chain
);
3609 int send_chain_to_gc(cls_rgw_obj_chain
& chain
, const string
& tag
, bool sync
);
3610 int gc_operate(string
& oid
, librados::ObjectWriteOperation
*op
);
3611 int gc_aio_operate(string
& oid
, librados::ObjectWriteOperation
*op
);
3612 int gc_operate(string
& oid
, librados::ObjectReadOperation
*op
, bufferlist
*pbl
);
3614 int list_gc_objs(int *index
, string
& marker
, uint32_t max
, bool expired_only
, std::list
<cls_rgw_gc_obj_info
>& result
, bool *truncated
);
3616 bool process_expire_objects();
3617 int defer_gc(void *ctx
, const RGWBucketInfo
& bucket_info
, const rgw_obj
& obj
);
3620 int list_lc_progress(const string
& marker
, uint32_t max_entries
, map
<string
, int> *progress_map
);
3622 int bucket_check_index(RGWBucketInfo
& bucket_info
,
3623 map
<RGWObjCategory
, RGWStorageStats
> *existing_stats
,
3624 map
<RGWObjCategory
, RGWStorageStats
> *calculated_stats
);
3625 int bucket_rebuild_index(RGWBucketInfo
& bucket_info
);
3626 int bucket_set_reshard(RGWBucketInfo
& bucket_info
, const cls_rgw_bucket_instance_entry
& entry
);
3627 int remove_objs_from_index(RGWBucketInfo
& bucket_info
, list
<rgw_obj_index_key
>& oid_list
);
3628 int move_rados_obj(librados::IoCtx
& src_ioctx
,
3629 const string
& src_oid
, const string
& src_locator
,
3630 librados::IoCtx
& dst_ioctx
,
3631 const string
& dst_oid
, const string
& dst_locator
);
3632 int fix_head_obj_locator(const RGWBucketInfo
& bucket_info
, bool copy_obj
, bool remove_bad
, rgw_obj_key
& key
);
3633 int fix_tail_obj_locator(const RGWBucketInfo
& bucket_info
, rgw_obj_key
& key
, bool fix
, bool *need_fix
);
3635 int cls_user_get_header(const string
& user_id
, cls_user_header
*header
);
3636 int cls_user_reset_stats(const string
& user_id
);
3637 int cls_user_get_header_async(const string
& user_id
, RGWGetUserHeader_CB
*ctx
);
3638 int cls_user_sync_bucket_stats(rgw_raw_obj
& user_obj
, const RGWBucketInfo
& bucket_info
);
3639 int cls_user_list_buckets(rgw_raw_obj
& obj
,
3640 const string
& in_marker
,
3641 const string
& end_marker
,
3643 list
<cls_user_bucket_entry
>& entries
,
3646 int cls_user_add_bucket(rgw_raw_obj
& obj
, const cls_user_bucket_entry
& entry
);
3647 int cls_user_update_buckets(rgw_raw_obj
& obj
, list
<cls_user_bucket_entry
>& entries
, bool add
);
3648 int cls_user_complete_stats_sync(rgw_raw_obj
& obj
);
3649 int complete_sync_user_stats(const rgw_user
& user_id
);
3650 int cls_user_add_bucket(rgw_raw_obj
& obj
, list
<cls_user_bucket_entry
>& entries
);
3651 int cls_user_remove_bucket(rgw_raw_obj
& obj
, const cls_user_bucket
& bucket
);
3652 int cls_user_get_bucket_stats(const rgw_bucket
& bucket
, cls_user_bucket_entry
& entry
);
3654 int check_quota(const rgw_user
& bucket_owner
, rgw_bucket
& bucket
,
3655 RGWQuotaInfo
& user_quota
, RGWQuotaInfo
& bucket_quota
, uint64_t obj_size
);
3657 int check_bucket_shards(const RGWBucketInfo
& bucket_info
, const rgw_bucket
& bucket
,
3658 RGWQuotaInfo
& bucket_quota
);
3660 int add_bucket_to_reshard(const RGWBucketInfo
& bucket_info
, uint32_t new_num_shards
);
3662 uint64_t instance_id();
3663 const string
& zone_name() {
3664 return get_zone_params().get_name();
3666 const string
& zone_id() {
3667 return get_zone_params().get_id();
3669 string
unique_id(uint64_t unique_num
) {
3671 snprintf(buf
, sizeof(buf
), ".%llu.%llu", (unsigned long long)instance_id(), (unsigned long long)unique_num
);
3672 string s
= get_zone_params().get_id() + buf
;
3676 void init_unique_trans_id_deps() {
3677 char buf
[16 + 2 + 1]; /* uint64_t needs 16, 2 hyphens add further 2 */
3679 snprintf(buf
, sizeof(buf
), "-%llx-", (unsigned long long)instance_id());
3680 url_encode(string(buf
) + get_zone_params().get_name(), trans_id_suffix
);
3683 /* In order to preserve compability with Swift API, transaction ID
3684 * should contain at least 32 characters satisfying following spec:
3685 * - first 21 chars must be in range [0-9a-f]. Swift uses this
3686 * space for storing fragment of UUID obtained through a call to
3687 * uuid4() function of Python's uuid module;
3688 * - char no. 22 must be a hyphen;
3689 * - at least 10 next characters constitute hex-formatted timestamp
3690 * padded with zeroes if necessary. All bytes must be in [0-9a-f]
3692 * - last, optional part of transaction ID is any url-encoded string
3693 * without restriction on length. */
3694 string
unique_trans_id(const uint64_t unique_num
) {
3695 char buf
[41]; /* 2 + 21 + 1 + 16 (timestamp can consume up to 16) + 1 */
3696 time_t timestamp
= time(NULL
);
3698 snprintf(buf
, sizeof(buf
), "tx%021llx-%010llx",
3699 (unsigned long long)unique_num
,
3700 (unsigned long long)timestamp
);
3702 return string(buf
) + trans_id_suffix
;
3705 void get_log_pool(rgw_pool
& pool
) {
3706 pool
= get_zone_params().log_pool
;
3709 bool need_to_log_data() {
3710 return get_zone().log_data
;
3713 bool need_to_log_metadata() {
3714 return is_meta_master() &&
3715 (get_zonegroup().zones
.size() > 1 || current_period
.is_multi_zonegroups_with_zones());
3718 bool can_reshard() const {
3719 return current_period
.get_id().empty() ||
3720 (zonegroup
.zones
.size() == 1 && current_period
.is_single_zonegroup());
3723 librados::Rados
* get_rados_handle();
3725 int delete_raw_obj_aio(const rgw_raw_obj
& obj
, list
<librados::AioCompletion
*>& handles
);
3726 int delete_obj_aio(const rgw_obj
& obj
, RGWBucketInfo
& info
, RGWObjState
*astate
,
3727 list
<librados::AioCompletion
*>& handles
, bool keep_index_consistent
);
3730 * This is a helper method, it generates a list of bucket index objects with the given
3731 * bucket base oid and number of shards.
3733 * bucket_oid_base [in] - base name of the bucket index object;
3734 * num_shards [in] - number of bucket index object shards.
3735 * bucket_objs [out] - filled by this method, a list of bucket index objects.
3737 void get_bucket_index_objects(const string
& bucket_oid_base
, uint32_t num_shards
,
3738 map
<int, string
>& bucket_objs
, int shard_id
= -1);
3741 * Get the bucket index object with the given base bucket index object and object key,
3742 * and the number of bucket index shards.
3744 * bucket_oid_base [in] - bucket object base name.
3745 * obj_key [in] - object key.
3746 * num_shards [in] - number of bucket index shards.
3747 * hash_type [in] - type of hash to find the shard ID.
3748 * bucket_obj [out] - the bucket index object for the given object.
3750 * Return 0 on success, a failure code otherwise.
3752 int get_bucket_index_object(const string
& bucket_oid_base
, const string
& obj_key
,
3753 uint32_t num_shards
, RGWBucketInfo::BIShardsHashType hash_type
, string
*bucket_obj
, int *shard
);
3755 void get_bucket_index_object(const string
& bucket_oid_base
, uint32_t num_shards
,
3756 int shard_id
, string
*bucket_obj
);
3759 * Check the actual on-disk state of the object specified
3760 * by list_state, and fill in the time and size of object.
3761 * Then append any changes to suggested_updates for
3762 * the rgw class' dir_suggest_changes function.
3764 * Note that this can maul list_state; don't use it afterwards. Also
3765 * it expects object to already be filled in from list_state; it only
3766 * sets the size and mtime.
3768 * Returns 0 on success, -ENOENT if the object doesn't exist on disk,
3769 * and -errno on other failures. (-ENOENT is not a failure, and it
3770 * will encode that info as a suggested update.)
3772 int check_disk_state(librados::IoCtx io_ctx
,
3773 const RGWBucketInfo
& bucket_info
,
3774 rgw_bucket_dir_entry
& list_state
,
3775 rgw_bucket_dir_entry
& object
,
3776 bufferlist
& suggested_updates
);
3779 * Init pool iteration
3780 * pool: pool to use for the ctx initialization
3781 * ctx: context object to use for the iteration
3782 * Returns: 0 on success, -ERR# otherwise.
3784 int pool_iterate_begin(const rgw_pool
& pool
, RGWPoolIterCtx
& ctx
);
3787 * Init pool iteration
3789 * cursor: position to start iteration
3790 * ctx: context object to use for the iteration
3791 * Returns: 0 on success, -ERR# otherwise.
3793 int pool_iterate_begin(const rgw_pool
& pool
, const string
& cursor
, RGWPoolIterCtx
& ctx
);
3796 * Get pool iteration position
3797 * ctx: context object to use for the iteration
3798 * Returns: string representation of position
3800 string
pool_iterate_get_cursor(RGWPoolIterCtx
& ctx
);
3803 * Iterate over pool return object names, use optional filter
3804 * ctx: iteration context, initialized with pool_iterate_begin()
3805 * num: max number of objects to return
3806 * objs: a vector that the results will append into
3807 * is_truncated: if not NULL, will hold true iff iteration is complete
3808 * filter: if not NULL, will be used to filter returned objects
3809 * Returns: 0 on success, -ERR# otherwise.
3811 int pool_iterate(RGWPoolIterCtx
& ctx
, uint32_t num
, vector
<rgw_bucket_dir_entry
>& objs
,
3812 bool *is_truncated
, RGWAccessListFilter
*filter
);
3814 uint64_t next_bucket_id();
3817 class RGWStoreManager
{
3819 RGWStoreManager() {}
3820 static RGWRados
*get_storage(CephContext
*cct
, bool use_gc_thread
, bool use_lc_thread
, bool quota_threads
,
3821 bool run_sync_thread
, bool run_reshard_thread
, bool use_cache
= true) {
3822 RGWRados
*store
= init_storage_provider(cct
, use_gc_thread
, use_lc_thread
, quota_threads
, run_sync_thread
,
3823 run_reshard_thread
, use_cache
);
3826 static RGWRados
*get_raw_storage(CephContext
*cct
) {
3827 RGWRados
*store
= init_raw_storage_provider(cct
);
3830 static RGWRados
*init_storage_provider(CephContext
*cct
, bool use_gc_thread
, bool use_lc_thread
, bool quota_threads
, bool run_sync_thread
, bool run_reshard_thread
, bool use_metadata_cache
);
3831 static RGWRados
*init_raw_storage_provider(CephContext
*cct
);
3832 static void close_storage(RGWRados
*store
);
3837 class RGWChainedCacheImpl
: public RGWChainedCache
{
3838 ceph::timespan expiry
;
3841 map
<string
, std::pair
<T
, ceph::coarse_mono_time
>> entries
;
3844 RGWChainedCacheImpl() : lock("RGWChainedCacheImpl::lock") {}
3846 void init(RGWRados
*store
) {
3847 store
->register_chained_cache(this);
3848 expiry
= std::chrono::seconds(store
->ctx()->_conf
->get_val
<uint64_t>(
3849 "rgw_cache_expiry_interval"));
3852 bool find(const string
& key
, T
*entry
) {
3853 RWLock::RLocker
rl(lock
);
3854 auto iter
= entries
.find(key
);
3855 if (iter
== entries
.end()) {
3858 if (expiry
.count() &&
3859 (ceph::coarse_mono_clock::now() - iter
->second
.second
) > expiry
) {
3863 *entry
= iter
->second
.first
;
3867 bool put(RGWRados
*store
, const string
& key
, T
*entry
, list
<rgw_cache_entry_info
*>& cache_info_entries
) {
3868 Entry
chain_entry(this, key
, entry
);
3870 /* we need the store cache to call us under its lock to maintain lock ordering */
3871 return store
->chain_cache_entry(cache_info_entries
, &chain_entry
);
3874 void chain_cb(const string
& key
, void *data
) override
{
3875 T
*entry
= static_cast<T
*>(data
);
3876 RWLock::WLocker
wl(lock
);
3877 entries
[key
].first
= *entry
;
3878 if (expiry
.count() > 0) {
3879 entries
[key
].second
= ceph::coarse_mono_clock::now();
3883 void invalidate(const string
& key
) override
{
3884 RWLock::WLocker
wl(lock
);
3888 void invalidate_all() override
{
3889 RWLock::WLocker
wl(lock
);
3892 }; /* RGWChainedCacheImpl */
3895 * Base of PUT operation.
3896 * Allow to create chained data transformers like compresors and encryptors.
3898 class RGWPutObjDataProcessor
3901 RGWPutObjDataProcessor(){}
3902 virtual ~RGWPutObjDataProcessor(){}
3903 virtual int handle_data(bufferlist
& bl
, off_t ofs
, void **phandle
, rgw_raw_obj
*pobj
, bool *again
) = 0;
3904 virtual int throttle_data(void *handle
, const rgw_raw_obj
& obj
, uint64_t size
, bool need_to_wait
) = 0;
3905 }; /* RGWPutObjDataProcessor */
3908 class RGWPutObjProcessor
: public RGWPutObjDataProcessor
3912 RGWObjectCtx
& obj_ctx
;
3914 RGWBucketInfo bucket_info
;
3917 virtual int do_complete(size_t accounted_size
, const string
& etag
,
3918 ceph::real_time
*mtime
, ceph::real_time set_mtime
,
3919 map
<string
, bufferlist
>& attrs
, ceph::real_time delete_at
,
3920 const char *if_match
, const char *if_nomatch
, const string
*user_data
,
3921 rgw_zone_set
* zones_trace
= nullptr) = 0;
3924 RGWPutObjProcessor(RGWObjectCtx
& _obj_ctx
, RGWBucketInfo
& _bi
) : store(NULL
),
3929 ~RGWPutObjProcessor() override
{}
3930 virtual int prepare(RGWRados
*_store
, string
*oid_rand
) {
3935 int complete(size_t accounted_size
, const string
& etag
,
3936 ceph::real_time
*mtime
, ceph::real_time set_mtime
,
3937 map
<string
, bufferlist
>& attrs
, ceph::real_time delete_at
,
3938 const char *if_match
= NULL
, const char *if_nomatch
= NULL
, const string
*user_data
= nullptr,
3939 rgw_zone_set
*zones_trace
= nullptr);
3943 bool is_canceled() { return canceled
; }
3944 }; /* RGWPutObjProcessor */
3946 struct put_obj_aio_info
{
3952 #define RGW_PUT_OBJ_MIN_WINDOW_SIZE_DEFAULT (16 * 1024 * 1024)
3954 class RGWPutObjProcessor_Aio
: public RGWPutObjProcessor
3956 list
<struct put_obj_aio_info
> pending
;
3957 uint64_t window_size
{RGW_PUT_OBJ_MIN_WINDOW_SIZE_DEFAULT
};
3958 uint64_t pending_size
{0};
3960 struct put_obj_aio_info
pop_pending();
3961 int wait_pending_front();
3962 bool pending_has_completed();
3964 rgw_raw_obj last_written_obj
;
3967 uint64_t obj_len
{0};
3969 set
<rgw_raw_obj
> written_objs
;
3972 void add_written_obj(const rgw_raw_obj
& obj
) {
3973 written_objs
.insert(obj
);
3976 int drain_pending();
3977 int handle_obj_data(rgw_raw_obj
& obj
, bufferlist
& bl
, off_t ofs
, off_t abs_ofs
, void **phandle
, bool exclusive
);
3980 int prepare(RGWRados
*store
, string
*oid_rand
) override
;
3981 int throttle_data(void *handle
, const rgw_raw_obj
& obj
, uint64_t size
, bool need_to_wait
) override
;
3983 RGWPutObjProcessor_Aio(RGWObjectCtx
& obj_ctx
, RGWBucketInfo
& bucket_info
) : RGWPutObjProcessor(obj_ctx
, bucket_info
) {}
3984 ~RGWPutObjProcessor_Aio() override
;
3985 }; /* RGWPutObjProcessor_Aio */
3987 class RGWPutObjProcessor_Atomic
: public RGWPutObjProcessor_Aio
3989 bufferlist first_chunk
;
3992 off_t next_part_ofs
;
3996 bufferlist pending_data_bl
;
3997 uint64_t max_chunk_size
;
3999 bool versioned_object
;
4000 boost::optional
<uint64_t> olh_epoch
;
4009 rgw_raw_obj cur_obj
;
4010 RGWObjManifest manifest
;
4011 RGWObjManifest::generator manifest_gen
;
4013 int write_data(bufferlist
& bl
, off_t ofs
, void **phandle
, rgw_raw_obj
*pobj
, bool exclusive
);
4014 int do_complete(size_t accounted_size
, const string
& etag
,
4015 ceph::real_time
*mtime
, ceph::real_time set_mtime
,
4016 map
<string
, bufferlist
>& attrs
, ceph::real_time delete_at
,
4017 const char *if_match
, const char *if_nomatch
, const string
*user_data
, rgw_zone_set
*zones_trace
) override
;
4019 int prepare_next_part(off_t ofs
);
4020 int complete_parts();
4021 int complete_writing_data();
4023 int prepare_init(RGWRados
*store
, string
*oid_rand
);
4026 ~RGWPutObjProcessor_Atomic() override
{}
4027 RGWPutObjProcessor_Atomic(RGWObjectCtx
& obj_ctx
, RGWBucketInfo
& bucket_info
,
4028 rgw_bucket
& _b
, const string
& _o
, uint64_t _p
, const string
& _t
, bool versioned
) :
4029 RGWPutObjProcessor_Aio(obj_ctx
, bucket_info
),
4036 versioned_object(versioned
),
4040 int prepare(RGWRados
*store
, string
*oid_rand
) override
;
4041 virtual bool immutable_head() { return false; }
4042 int handle_data(bufferlist
& bl
, off_t ofs
, void **phandle
, rgw_raw_obj
*pobj
, bool *again
) override
;
4044 void set_olh_epoch(uint64_t epoch
) {
4048 void set_version_id(const string
& vid
) {
4051 }; /* RGWPutObjProcessor_Atomic */
4053 #define MP_META_SUFFIX ".meta"
4062 RGWMPObj(const string
& _oid
, const string
& _upload_id
) {
4063 init(_oid
, _upload_id
, _upload_id
);
4065 void init(const string
& _oid
, const string
& _upload_id
) {
4066 init(_oid
, _upload_id
, _upload_id
);
4068 void init(const string
& _oid
, const string
& _upload_id
, const string
& part_unique_str
) {
4074 upload_id
= _upload_id
;
4076 meta
= prefix
+ upload_id
+ MP_META_SUFFIX
;
4077 prefix
.append(part_unique_str
);
4079 string
& get_meta() { return meta
; }
4080 string
get_part(int num
) {
4082 snprintf(buf
, 16, ".%d", num
);
4087 string
get_part(string
& part
) {
4093 string
& get_upload_id() {
4099 bool from_meta(string
& meta
) {
4100 int end_pos
= meta
.rfind('.'); // search for ".meta"
4103 int mid_pos
= meta
.rfind('.', end_pos
- 1); // <key>.<upload_id>
4106 oid
= meta
.substr(0, mid_pos
);
4107 upload_id
= meta
.substr(mid_pos
+ 1, end_pos
- mid_pos
- 1);
4108 init(oid
, upload_id
, upload_id
);
4119 class RGWPutObjProcessor_Multipart
: public RGWPutObjProcessor_Atomic
4127 int prepare(RGWRados
*store
, string
*oid_rand
);
4128 int do_complete(size_t accounted_size
, const string
& etag
,
4129 ceph::real_time
*mtime
, ceph::real_time set_mtime
,
4130 map
<string
, bufferlist
>& attrs
, ceph::real_time delete_at
,
4131 const char *if_match
, const char *if_nomatch
, const string
*user_data
,
4132 rgw_zone_set
*zones_trace
) override
;
4134 bool immutable_head() { return true; }
4135 RGWPutObjProcessor_Multipart(RGWObjectCtx
& obj_ctx
, RGWBucketInfo
& bucket_info
, uint64_t _p
, req_state
*_s
) :
4136 RGWPutObjProcessor_Atomic(obj_ctx
, bucket_info
, _s
->bucket
, _s
->object
.name
, _p
, _s
->req_id
, false), s(_s
) {}
4137 void get_mp(RGWMPObj
** _mp
);
4138 }; /* RGWPutObjProcessor_Multipart */