1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #ifndef CEPH_CLS_RGW_TYPES_H
5 #define CEPH_CLS_RGW_TYPES_H
7 #include <boost/container/flat_map.hpp>
8 #include "common/ceph_time.h"
9 #include "common/Formatter.h"
11 #include "rgw/rgw_basic_types.h"
13 #define CEPH_RGW_REMOVE 'r'
14 #define CEPH_RGW_UPDATE 'u'
15 #define CEPH_RGW_TAG_TIMEOUT 120
16 #define CEPH_RGW_DIR_SUGGEST_LOG_OP 0x80
17 #define CEPH_RGW_DIR_SUGGEST_OP_MASK 0x7f
24 using ceph::operator <<;
26 struct rgw_zone_set_entry
{
28 std::optional
<std::string
> location_key
;
30 bool operator<(const rgw_zone_set_entry
& e
) const {
37 return (location_key
< e
.location_key
);
40 rgw_zone_set_entry() {}
41 rgw_zone_set_entry(const string
& _zone
,
42 std::optional
<std::string
> _location_key
) : zone(_zone
),
43 location_key(_location_key
) {}
44 rgw_zone_set_entry(const string
& s
) {
48 void from_str(const string
& s
);
49 string
to_str() const;
51 void encode(bufferlist
&bl
) const;
52 void decode(bufferlist::const_iterator
&bl
);
54 void dump(Formatter
*f
) const;
55 void decode_json(JSONObj
*obj
);
57 WRITE_CLASS_ENCODER(rgw_zone_set_entry
)
60 std::set
<rgw_zone_set_entry
> entries
;
62 void encode(bufferlist
&bl
) const {
63 /* no ENCODE_START, ENCODE_END for backward compatibility */
64 ceph::encode(entries
, bl
);
66 void decode(bufferlist::const_iterator
&bl
) {
67 /* no DECODE_START, DECODE_END for backward compatibility */
68 ceph::decode(entries
, bl
);
71 void insert(const string
& zone
, std::optional
<string
> location_key
);
72 bool exists(const string
& zone
, std::optional
<string
> location_key
) const;
74 WRITE_CLASS_ENCODER(rgw_zone_set
)
76 /* backward compatibility, rgw_zone_set needs to encode/decode the same as std::set */
77 void encode_json(const char *name
, const rgw_zone_set
& zs
, ceph::Formatter
*f
);
78 void decode_json_obj(rgw_zone_set
& zs
, JSONObj
*obj
);
81 enum RGWPendingState
{
82 CLS_RGW_STATE_PENDING_MODIFY
= 0,
83 CLS_RGW_STATE_COMPLETE
= 1,
84 CLS_RGW_STATE_UNKNOWN
= 2,
90 CLS_RGW_OP_CANCEL
= 2,
91 CLS_RGW_OP_UNKNOWN
= 3,
92 CLS_RGW_OP_LINK_OLH
= 4,
93 CLS_RGW_OP_LINK_OLH_DM
= 5, /* creation of delete marker */
94 CLS_RGW_OP_UNLINK_INSTANCE
= 6,
95 CLS_RGW_OP_SYNCSTOP
= 7,
96 CLS_RGW_OP_RESYNC
= 8,
100 RGW_BILOG_FLAG_VERSIONED_OP
= 0x1,
103 enum RGWCheckMTimeType
{
104 CLS_RGW_CHECK_TIME_MTIME_EQ
= 0,
105 CLS_RGW_CHECK_TIME_MTIME_LT
= 1,
106 CLS_RGW_CHECK_TIME_MTIME_LE
= 2,
107 CLS_RGW_CHECK_TIME_MTIME_GT
= 3,
108 CLS_RGW_CHECK_TIME_MTIME_GE
= 4,
111 #define ROUND_BLOCK_SIZE 4096
113 static inline uint64_t cls_rgw_get_rounded_size(uint64_t size
) {
114 return (size
+ ROUND_BLOCK_SIZE
- 1) & ~(ROUND_BLOCK_SIZE
- 1);
118 * This takes a string that either wholly contains a delimiter or is a
119 * path that ends with a delimiter and appends a new character to the
120 * end such that when a we request bucket-index entries *after* this,
121 * we'll get the next object after the "subdirectory". This works
122 * because we append a '\xFF' charater, and no valid UTF-8 character
123 * can contain that byte, so no valid entries can be skipped.
125 static inline std::string
cls_rgw_after_delim(const std::string
& path
) {
126 // assert: ! path.empty()
127 return path
+ '\xFF';
130 struct rgw_bucket_pending_info
{
131 RGWPendingState state
;
132 ceph::real_time timestamp
;
135 rgw_bucket_pending_info() : state(CLS_RGW_STATE_PENDING_MODIFY
), op(0) {}
137 void encode(bufferlist
&bl
) const {
138 ENCODE_START(2, 2, bl
);
139 uint8_t s
= (uint8_t)state
;
141 encode(timestamp
, bl
);
145 void decode(bufferlist::const_iterator
&bl
) {
146 DECODE_START_LEGACY_COMPAT_LEN(2, 2, 2, bl
);
149 state
= (RGWPendingState
)s
;
150 decode(timestamp
, bl
);
154 void dump(Formatter
*f
) const;
155 void decode_json(JSONObj
*obj
);
156 static void generate_test_instances(list
<rgw_bucket_pending_info
*>& o
);
158 WRITE_CLASS_ENCODER(rgw_bucket_pending_info
)
161 // categories of objects stored in a bucket index (b-i) and used to
162 // differentiate their associated statistics (bucket stats, and in
163 // some cases user stats)
164 enum class RGWObjCategory
: uint8_t {
165 None
= 0, // b-i entries for delete markers; also used in
166 // testing and for default values in default
169 Main
= 1, // b-i entries for standard objs
171 Shadow
= 2, // presumfably intended for multipart shadow
172 // uploads; not currently used in the codebase
174 MultiMeta
= 3, // b-i entries for multipart upload metadata objs
178 struct rgw_bucket_dir_entry_meta
{
179 RGWObjCategory category
;
181 ceph::real_time mtime
;
184 string owner_display_name
;
186 uint64_t accounted_size
;
188 string storage_class
;
191 rgw_bucket_dir_entry_meta() :
192 category(RGWObjCategory::None
), size(0), accounted_size(0), appendable(false) { }
194 void encode(bufferlist
&bl
) const {
195 ENCODE_START(7, 3, bl
);
196 encode(category
, bl
);
201 encode(owner_display_name
, bl
);
202 encode(content_type
, bl
);
203 encode(accounted_size
, bl
);
204 encode(user_data
, bl
);
205 encode(storage_class
, bl
);
206 encode(appendable
, bl
);
210 void decode(bufferlist::const_iterator
&bl
) {
211 DECODE_START_LEGACY_COMPAT_LEN(6, 3, 3, bl
);
212 decode(category
, bl
);
217 decode(owner_display_name
, bl
);
219 decode(content_type
, bl
);
221 decode(accounted_size
, bl
);
223 accounted_size
= size
;
225 decode(user_data
, bl
);
227 decode(storage_class
, bl
);
229 decode(appendable
, bl
);
232 void dump(Formatter
*f
) const;
233 void decode_json(JSONObj
*obj
);
234 static void generate_test_instances(list
<rgw_bucket_dir_entry_meta
*>& o
);
236 WRITE_CLASS_ENCODER(rgw_bucket_dir_entry_meta
)
239 void encode_packed_val(T val
, bufferlist
& bl
)
242 if ((uint64_t)val
< 0x80) {
243 encode((uint8_t)val
, bl
);
245 unsigned char c
= 0x80;
247 if ((uint64_t)val
< 0x100) {
250 encode((uint8_t)val
, bl
);
251 } else if ((uint64_t)val
<= 0x10000) {
254 encode((uint16_t)val
, bl
);
255 } else if ((uint64_t)val
<= 0x1000000) {
258 encode((uint32_t)val
, bl
);
262 encode((uint64_t)val
, bl
);
268 void decode_packed_val(T
& val
, bufferlist::const_iterator
& bl
)
310 throw buffer::error();
314 struct rgw_bucket_entry_ver
{
318 rgw_bucket_entry_ver() : pool(-1), epoch(0) {}
320 void encode(bufferlist
&bl
) const {
321 ENCODE_START(1, 1, bl
);
322 encode_packed_val(pool
, bl
);
323 encode_packed_val(epoch
, bl
);
326 void decode(bufferlist::const_iterator
&bl
) {
328 decode_packed_val(pool
, bl
);
329 decode_packed_val(epoch
, bl
);
332 void dump(Formatter
*f
) const;
333 void decode_json(JSONObj
*obj
);
334 static void generate_test_instances(list
<rgw_bucket_entry_ver
*>& o
);
336 WRITE_CLASS_ENCODER(rgw_bucket_entry_ver
)
338 struct cls_rgw_obj_key
{
343 cls_rgw_obj_key(const string
&_name
) : name(_name
) {}
344 cls_rgw_obj_key(const string
& n
, const string
& i
) : name(n
), instance(i
) {}
346 void set(const string
& _name
) {
350 bool operator==(const cls_rgw_obj_key
& k
) const {
351 return (name
.compare(k
.name
) == 0) &&
352 (instance
.compare(k
.instance
) == 0);
354 bool operator<(const cls_rgw_obj_key
& k
) const {
355 int r
= name
.compare(k
.name
);
357 r
= instance
.compare(k
.instance
);
361 bool operator<=(const cls_rgw_obj_key
& k
) const {
367 void encode(bufferlist
&bl
) const {
368 ENCODE_START(1, 1, bl
);
370 encode(instance
, bl
);
373 void decode(bufferlist::const_iterator
&bl
) {
376 decode(instance
, bl
);
379 void dump(Formatter
*f
) const {
380 f
->dump_string("name", name
);
381 f
->dump_string("instance", instance
);
383 void decode_json(JSONObj
*obj
);
384 static void generate_test_instances(list
<cls_rgw_obj_key
*>& ls
) {
385 ls
.push_back(new cls_rgw_obj_key
);
386 ls
.push_back(new cls_rgw_obj_key
);
387 ls
.back()->name
= "name";
388 ls
.back()->instance
= "instance";
391 WRITE_CLASS_ENCODER(cls_rgw_obj_key
)
394 struct rgw_bucket_dir_entry
{
395 /* a versioned object instance */
396 static constexpr uint16_t FLAG_VER
= 0x1;
397 /* the last object instance of a versioned object */
398 static constexpr uint16_t FLAG_CURRENT
= 0x2;
400 static constexpr uint16_t FLAG_DELETE_MARKER
= 0x4;
401 /* object is versioned, a placeholder for the plain entry */
402 static constexpr uint16_t FLAG_VER_MARKER
= 0x8;
403 /* object is a proxy; it is not listed in the bucket index but is a
404 * prefix ending with a delimiter, perhaps common to multiple
405 * entries; it is only useful when a delimiter is used and
406 * represents a "subdirectory" (again, ending in a delimiter) that
407 * may contain one or more actual entries/objects */
408 static constexpr uint16_t FLAG_COMMON_PREFIX
= 0x8000;
411 rgw_bucket_entry_ver ver
;
414 rgw_bucket_dir_entry_meta meta
;
415 multimap
<string
, rgw_bucket_pending_info
> pending_map
;
419 uint64_t versioned_epoch
;
421 rgw_bucket_dir_entry() :
422 exists(false), index_ver(0), flags(0), versioned_epoch(0) {}
424 void encode(bufferlist
&bl
) const {
425 ENCODE_START(8, 3, bl
);
426 encode(key
.name
, bl
);
427 encode(ver
.epoch
, bl
);
430 encode(pending_map
, bl
);
433 encode_packed_val(index_ver
, bl
);
435 encode(key
.instance
, bl
);
437 encode(versioned_epoch
, bl
);
440 void decode(bufferlist::const_iterator
&bl
) {
441 DECODE_START_LEGACY_COMPAT_LEN(8, 3, 3, bl
);
442 decode(key
.name
, bl
);
443 decode(ver
.epoch
, bl
);
446 decode(pending_map
, bl
);
456 decode_packed_val(index_ver
, bl
);
460 decode(key
.instance
, bl
);
466 decode(versioned_epoch
, bl
);
471 bool is_current() const {
473 rgw_bucket_dir_entry::FLAG_VER
| rgw_bucket_dir_entry::FLAG_CURRENT
;
474 return (flags
& rgw_bucket_dir_entry::FLAG_VER
) == 0 ||
475 (flags
& test_flags
) == test_flags
;
477 bool is_delete_marker() const {
478 return (flags
& rgw_bucket_dir_entry::FLAG_DELETE_MARKER
) != 0;
480 bool is_visible() const {
481 return is_current() && !is_delete_marker();
483 bool is_valid() const {
484 return (flags
& rgw_bucket_dir_entry::FLAG_VER_MARKER
) == 0;
486 bool is_common_prefix() const {
487 return flags
& rgw_bucket_dir_entry::FLAG_COMMON_PREFIX
;
490 void dump(Formatter
*f
) const;
491 void decode_json(JSONObj
*obj
);
492 static void generate_test_instances(list
<rgw_bucket_dir_entry
*>& o
);
494 WRITE_CLASS_ENCODER(rgw_bucket_dir_entry
)
496 enum class BIIndexType
: uint8_t {
503 struct rgw_bucket_category_stats
;
505 struct rgw_cls_bi_entry
{
510 rgw_cls_bi_entry() : type(BIIndexType::Invalid
) {}
512 void encode(bufferlist
& bl
) const {
513 ENCODE_START(1, 1, bl
);
520 void decode(bufferlist::const_iterator
& bl
) {
524 type
= (BIIndexType
)c
;
530 void dump(Formatter
*f
) const;
531 void decode_json(JSONObj
*obj
, cls_rgw_obj_key
*effective_key
= NULL
);
533 bool get_info(cls_rgw_obj_key
*key
, RGWObjCategory
*category
,
534 rgw_bucket_category_stats
*accounted_stats
);
536 WRITE_CLASS_ENCODER(rgw_cls_bi_entry
)
539 CLS_RGW_OLH_OP_UNKNOWN
= 0,
540 CLS_RGW_OLH_OP_LINK_OLH
= 1,
541 CLS_RGW_OLH_OP_UNLINK_OLH
= 2, /* object does not exist */
542 CLS_RGW_OLH_OP_REMOVE_INSTANCE
= 3,
545 struct rgw_bucket_olh_log_entry
{
552 rgw_bucket_olh_log_entry() : epoch(0), op(CLS_RGW_OLH_OP_UNKNOWN
), delete_marker(false) {}
555 void encode(bufferlist
&bl
) const {
556 ENCODE_START(1, 1, bl
);
558 encode((__u8
)op
, bl
);
561 encode(delete_marker
, bl
);
564 void decode(bufferlist::const_iterator
&bl
) {
572 decode(delete_marker
, bl
);
575 static void generate_test_instances(list
<rgw_bucket_olh_log_entry
*>& o
);
576 void dump(Formatter
*f
) const;
577 void decode_json(JSONObj
*obj
);
579 WRITE_CLASS_ENCODER(rgw_bucket_olh_log_entry
)
581 struct rgw_bucket_olh_entry
{
585 map
<uint64_t, vector
<struct rgw_bucket_olh_log_entry
> > pending_log
;
588 bool pending_removal
;
590 rgw_bucket_olh_entry() : delete_marker(false), epoch(0), exists(false), pending_removal(false) {}
592 void encode(bufferlist
&bl
) const {
593 ENCODE_START(1, 1, bl
);
595 encode(delete_marker
, bl
);
597 encode(pending_log
, bl
);
600 encode(pending_removal
, bl
);
603 void decode(bufferlist::const_iterator
&bl
) {
606 decode(delete_marker
, bl
);
608 decode(pending_log
, bl
);
611 decode(pending_removal
, bl
);
614 void dump(Formatter
*f
) const;
615 void decode_json(JSONObj
*obj
);
617 WRITE_CLASS_ENCODER(rgw_bucket_olh_entry
)
619 struct rgw_bi_log_entry
{
623 ceph::real_time timestamp
;
624 rgw_bucket_entry_ver ver
;
626 RGWPendingState state
;
629 uint16_t bilog_flags
;
630 string owner
; /* only being set if it's a delete marker */
631 string owner_display_name
; /* only being set if it's a delete marker */
632 rgw_zone_set zones_trace
;
634 rgw_bi_log_entry() : op(CLS_RGW_OP_UNKNOWN
), state(CLS_RGW_STATE_PENDING_MODIFY
), index_ver(0), bilog_flags(0) {}
636 void encode(bufferlist
&bl
) const {
637 ENCODE_START(4, 1, bl
);
640 encode(timestamp
, bl
);
643 uint8_t c
= (uint8_t)op
;
647 encode_packed_val(index_ver
, bl
);
648 encode(instance
, bl
);
649 encode(bilog_flags
, bl
);
651 encode(owner_display_name
, bl
);
652 encode(zones_trace
, bl
);
655 void decode(bufferlist::const_iterator
&bl
) {
659 decode(timestamp
, bl
);
666 state
= (RGWPendingState
)c
;
667 decode_packed_val(index_ver
, bl
);
669 decode(instance
, bl
);
670 decode(bilog_flags
, bl
);
674 decode(owner_display_name
, bl
);
677 decode(zones_trace
, bl
);
681 void dump(Formatter
*f
) const;
682 void decode_json(JSONObj
*obj
);
683 static void generate_test_instances(list
<rgw_bi_log_entry
*>& o
);
685 bool is_versioned() {
686 return ((bilog_flags
& RGW_BILOG_FLAG_VERSIONED_OP
) != 0);
689 WRITE_CLASS_ENCODER(rgw_bi_log_entry
)
691 struct rgw_bucket_category_stats
{
693 uint64_t total_size_rounded
;
694 uint64_t num_entries
;
695 uint64_t actual_size
{0}; //< account for compression, encryption
697 rgw_bucket_category_stats() : total_size(0), total_size_rounded(0), num_entries(0) {}
699 void encode(bufferlist
&bl
) const {
700 ENCODE_START(3, 2, bl
);
701 encode(total_size
, bl
);
702 encode(total_size_rounded
, bl
);
703 encode(num_entries
, bl
);
704 encode(actual_size
, bl
);
707 void decode(bufferlist::const_iterator
&bl
) {
708 DECODE_START_LEGACY_COMPAT_LEN(3, 2, 2, bl
);
709 decode(total_size
, bl
);
710 decode(total_size_rounded
, bl
);
711 decode(num_entries
, bl
);
713 decode(actual_size
, bl
);
715 actual_size
= total_size
;
719 void dump(Formatter
*f
) const;
720 static void generate_test_instances(list
<rgw_bucket_category_stats
*>& o
);
722 WRITE_CLASS_ENCODER(rgw_bucket_category_stats
)
724 enum class cls_rgw_reshard_status
: uint8_t {
730 static inline std::string
to_string(const cls_rgw_reshard_status status
)
733 case cls_rgw_reshard_status::NOT_RESHARDING
:
734 return "not-resharding";
736 case cls_rgw_reshard_status::IN_PROGRESS
:
737 return "in-progress";
739 case cls_rgw_reshard_status::DONE
:
743 return "Unknown reshard status";
746 struct cls_rgw_bucket_instance_entry
{
747 using RESHARD_STATUS
= cls_rgw_reshard_status
;
749 cls_rgw_reshard_status reshard_status
{RESHARD_STATUS::NOT_RESHARDING
};
750 string new_bucket_instance_id
;
751 int32_t num_shards
{-1};
753 void encode(bufferlist
& bl
) const {
754 ENCODE_START(1, 1, bl
);
755 encode((uint8_t)reshard_status
, bl
);
756 encode(new_bucket_instance_id
, bl
);
757 encode(num_shards
, bl
);
761 void decode(bufferlist::const_iterator
& bl
) {
765 reshard_status
= (cls_rgw_reshard_status
)s
;
766 decode(new_bucket_instance_id
, bl
);
767 decode(num_shards
, bl
);
771 void dump(Formatter
*f
) const;
772 static void generate_test_instances(list
<cls_rgw_bucket_instance_entry
*>& o
);
775 reshard_status
= RESHARD_STATUS::NOT_RESHARDING
;
776 new_bucket_instance_id
.clear();
779 void set_status(const string
& new_instance_id
,
780 int32_t new_num_shards
,
781 cls_rgw_reshard_status s
) {
783 new_bucket_instance_id
= new_instance_id
;
784 num_shards
= new_num_shards
;
787 bool resharding() const {
788 return reshard_status
!= RESHARD_STATUS::NOT_RESHARDING
;
790 bool resharding_in_progress() const {
791 return reshard_status
== RESHARD_STATUS::IN_PROGRESS
;
794 WRITE_CLASS_ENCODER(cls_rgw_bucket_instance_entry
)
796 struct rgw_bucket_dir_header
{
797 map
<RGWObjCategory
, rgw_bucket_category_stats
> stats
;
798 uint64_t tag_timeout
;
802 cls_rgw_bucket_instance_entry new_instance
;
805 rgw_bucket_dir_header() : tag_timeout(0), ver(0), master_ver(0), syncstopped(false) {}
807 void encode(bufferlist
&bl
) const {
808 ENCODE_START(7, 2, bl
);
810 encode(tag_timeout
, bl
);
812 encode(master_ver
, bl
);
813 encode(max_marker
, bl
);
814 encode(new_instance
, bl
);
815 encode(syncstopped
,bl
);
818 void decode(bufferlist::const_iterator
&bl
) {
819 DECODE_START_LEGACY_COMPAT_LEN(6, 2, 2, bl
);
822 decode(tag_timeout
, bl
);
828 decode(master_ver
, bl
);
833 decode(max_marker
, bl
);
836 decode(new_instance
, bl
);
838 new_instance
= cls_rgw_bucket_instance_entry();
841 decode(syncstopped
,bl
);
845 void dump(Formatter
*f
) const;
846 static void generate_test_instances(list
<rgw_bucket_dir_header
*>& o
);
848 bool resharding() const {
849 return new_instance
.resharding();
851 bool resharding_in_progress() const {
852 return new_instance
.resharding_in_progress();
855 WRITE_CLASS_ENCODER(rgw_bucket_dir_header
)
857 struct rgw_bucket_dir
{
858 rgw_bucket_dir_header header
;
859 boost::container::flat_map
<string
, rgw_bucket_dir_entry
> m
;
861 void encode(bufferlist
&bl
) const {
862 ENCODE_START(2, 2, bl
);
867 void decode(bufferlist::const_iterator
&bl
) {
868 DECODE_START_LEGACY_COMPAT_LEN(2, 2, 2, bl
);
873 void dump(Formatter
*f
) const;
874 static void generate_test_instances(list
<rgw_bucket_dir
*>& o
);
876 WRITE_CLASS_ENCODER(rgw_bucket_dir
)
878 struct rgw_usage_data
{
880 uint64_t bytes_received
;
882 uint64_t successful_ops
;
884 rgw_usage_data() : bytes_sent(0), bytes_received(0), ops(0), successful_ops(0) {}
885 rgw_usage_data(uint64_t sent
, uint64_t received
) : bytes_sent(sent
), bytes_received(received
), ops(0), successful_ops(0) {}
887 void encode(bufferlist
& bl
) const {
888 ENCODE_START(1, 1, bl
);
889 encode(bytes_sent
, bl
);
890 encode(bytes_received
, bl
);
892 encode(successful_ops
, bl
);
896 void decode(bufferlist::const_iterator
& bl
) {
898 decode(bytes_sent
, bl
);
899 decode(bytes_received
, bl
);
901 decode(successful_ops
, bl
);
905 void aggregate(const rgw_usage_data
& usage
) {
906 bytes_sent
+= usage
.bytes_sent
;
907 bytes_received
+= usage
.bytes_received
;
909 successful_ops
+= usage
.successful_ops
;
912 WRITE_CLASS_ENCODER(rgw_usage_data
)
915 struct rgw_usage_log_entry
{
917 rgw_user payer
; /* if empty, same as owner */
920 rgw_usage_data total_usage
; /* this one is kept for backwards compatibility */
921 map
<string
, rgw_usage_data
> usage_map
;
923 rgw_usage_log_entry() : epoch(0) {}
924 rgw_usage_log_entry(string
& o
, string
& b
) : owner(o
), bucket(b
), epoch(0) {}
925 rgw_usage_log_entry(string
& o
, string
& p
, string
& b
) : owner(o
), payer(p
), bucket(b
), epoch(0) {}
927 void encode(bufferlist
& bl
) const {
928 ENCODE_START(3, 1, bl
);
929 encode(owner
.to_str(), bl
);
932 encode(total_usage
.bytes_sent
, bl
);
933 encode(total_usage
.bytes_received
, bl
);
934 encode(total_usage
.ops
, bl
);
935 encode(total_usage
.successful_ops
, bl
);
936 encode(usage_map
, bl
);
937 encode(payer
.to_str(), bl
);
942 void decode(bufferlist::const_iterator
& bl
) {
949 decode(total_usage
.bytes_sent
, bl
);
950 decode(total_usage
.bytes_received
, bl
);
951 decode(total_usage
.ops
, bl
);
952 decode(total_usage
.successful_ops
, bl
);
954 usage_map
[""] = total_usage
;
956 decode(usage_map
, bl
);
966 void aggregate(const rgw_usage_log_entry
& e
, map
<string
, bool> *categories
= NULL
) {
974 map
<string
, rgw_usage_data
>::const_iterator iter
;
975 for (iter
= e
.usage_map
.begin(); iter
!= e
.usage_map
.end(); ++iter
) {
976 if (!categories
|| !categories
->size() || categories
->count(iter
->first
)) {
977 add(iter
->first
, iter
->second
);
982 void sum(rgw_usage_data
& usage
, map
<string
, bool>& categories
) const {
983 usage
= rgw_usage_data();
984 for (map
<string
, rgw_usage_data
>::const_iterator iter
= usage_map
.begin(); iter
!= usage_map
.end(); ++iter
) {
985 if (!categories
.size() || categories
.count(iter
->first
)) {
986 usage
.aggregate(iter
->second
);
991 void add(const string
& category
, const rgw_usage_data
& data
) {
992 usage_map
[category
].aggregate(data
);
993 total_usage
.aggregate(data
);
996 void dump(Formatter
* f
) const;
997 static void generate_test_instances(list
<rgw_usage_log_entry
*>& o
);
1000 WRITE_CLASS_ENCODER(rgw_usage_log_entry
)
1002 struct rgw_usage_log_info
{
1003 vector
<rgw_usage_log_entry
> entries
;
1005 void encode(bufferlist
& bl
) const {
1006 ENCODE_START(1, 1, bl
);
1007 encode(entries
, bl
);
1011 void decode(bufferlist::const_iterator
& bl
) {
1012 DECODE_START(1, bl
);
1013 decode(entries
, bl
);
1017 rgw_usage_log_info() {}
1019 WRITE_CLASS_ENCODER(rgw_usage_log_info
)
1021 struct rgw_user_bucket
{
1025 rgw_user_bucket() {}
1026 rgw_user_bucket(const string
& u
, const string
& b
) : user(u
), bucket(b
) {}
1028 void encode(bufferlist
& bl
) const {
1029 ENCODE_START(1, 1, bl
);
1035 void decode(bufferlist::const_iterator
& bl
) {
1036 DECODE_START(1, bl
);
1042 bool operator<(const rgw_user_bucket
& ub2
) const {
1043 int comp
= user
.compare(ub2
.user
);
1047 return bucket
.compare(ub2
.bucket
) < 0;
1052 WRITE_CLASS_ENCODER(rgw_user_bucket
)
1054 enum cls_rgw_gc_op
{
1056 CLS_RGW_GC_DEL_BUCKET
,
1059 struct cls_rgw_obj
{
1061 cls_rgw_obj_key key
;
1065 cls_rgw_obj(string
& _p
, cls_rgw_obj_key
& _k
) : pool(_p
), key(_k
) {}
1067 void encode(bufferlist
& bl
) const {
1068 ENCODE_START(2, 1, bl
);
1070 encode(key
.name
, bl
);
1076 void decode(bufferlist::const_iterator
& bl
) {
1077 DECODE_START(2, bl
);
1079 decode(key
.name
, bl
);
1081 if (struct_v
>= 2) {
1087 void dump(Formatter
*f
) const {
1088 f
->dump_string("pool", pool
);
1089 f
->dump_string("oid", key
.name
);
1090 f
->dump_string("key", loc
);
1091 f
->dump_string("instance", key
.instance
);
1093 static void generate_test_instances(list
<cls_rgw_obj
*>& ls
) {
1094 ls
.push_back(new cls_rgw_obj
);
1095 ls
.push_back(new cls_rgw_obj
);
1096 ls
.back()->pool
= "mypool";
1097 ls
.back()->key
.name
= "myoid";
1098 ls
.back()->loc
= "mykey";
1101 WRITE_CLASS_ENCODER(cls_rgw_obj
)
1103 struct cls_rgw_obj_chain
{
1104 list
<cls_rgw_obj
> objs
;
1106 cls_rgw_obj_chain() {}
1108 void push_obj(const string
& pool
, const cls_rgw_obj_key
& key
, const string
& loc
) {
1113 objs
.push_back(obj
);
1116 void encode(bufferlist
& bl
) const {
1117 ENCODE_START(1, 1, bl
);
1122 void decode(bufferlist::const_iterator
& bl
) {
1123 DECODE_START(1, bl
);
1128 void dump(Formatter
*f
) const {
1129 f
->open_array_section("objs");
1130 for (list
<cls_rgw_obj
>::const_iterator p
= objs
.begin(); p
!= objs
.end(); ++p
) {
1131 f
->open_object_section("obj");
1137 static void generate_test_instances(list
<cls_rgw_obj_chain
*>& ls
) {
1138 ls
.push_back(new cls_rgw_obj_chain
);
1142 return objs
.empty();
1145 WRITE_CLASS_ENCODER(cls_rgw_obj_chain
)
1147 struct cls_rgw_gc_obj_info
1150 cls_rgw_obj_chain chain
;
1151 ceph::real_time time
;
1153 cls_rgw_gc_obj_info() {}
1155 void encode(bufferlist
& bl
) const {
1156 ENCODE_START(1, 1, bl
);
1163 void decode(bufferlist::const_iterator
& bl
) {
1164 DECODE_START(1, bl
);
1171 void dump(Formatter
*f
) const {
1172 f
->dump_string("tag", tag
);
1173 f
->open_object_section("chain");
1176 f
->dump_stream("time") << time
;
1178 static void generate_test_instances(list
<cls_rgw_gc_obj_info
*>& ls
) {
1179 ls
.push_back(new cls_rgw_gc_obj_info
);
1180 ls
.push_back(new cls_rgw_gc_obj_info
);
1181 ls
.back()->tag
= "footag";
1182 ceph_timespec ts
{init_le32(21), init_le32(32)};
1183 ls
.back()->time
= ceph::real_clock::from_ceph_timespec(ts
);
1186 WRITE_CLASS_ENCODER(cls_rgw_gc_obj_info
)
1188 struct cls_rgw_lc_obj_head
1190 time_t start_date
= 0;
1193 cls_rgw_lc_obj_head() {}
1195 void encode(bufferlist
& bl
) const {
1196 ENCODE_START(1, 1, bl
);
1197 uint64_t t
= start_date
;
1203 void decode(bufferlist::const_iterator
& bl
) {
1204 DECODE_START(1, bl
);
1207 start_date
= static_cast<time_t>(t
);
1212 void dump(Formatter
*f
) const;
1213 static void generate_test_instances(list
<cls_rgw_lc_obj_head
*>& ls
);
1215 WRITE_CLASS_ENCODER(cls_rgw_lc_obj_head
)
1217 struct cls_rgw_reshard_entry
1219 ceph::real_time time
;
1223 string new_instance_id
;
1224 uint32_t old_num_shards
{0};
1225 uint32_t new_num_shards
{0};
1227 cls_rgw_reshard_entry() {}
1229 void encode(bufferlist
& bl
) const {
1230 ENCODE_START(1, 1, bl
);
1233 encode(bucket_name
, bl
);
1234 encode(bucket_id
, bl
);
1235 encode(new_instance_id
, bl
);
1236 encode(old_num_shards
, bl
);
1237 encode(new_num_shards
, bl
);
1241 void decode(bufferlist::const_iterator
& bl
) {
1242 DECODE_START(1, bl
);
1245 decode(bucket_name
, bl
);
1246 decode(bucket_id
, bl
);
1247 decode(new_instance_id
, bl
);
1248 decode(old_num_shards
, bl
);
1249 decode(new_num_shards
, bl
);
1253 void dump(Formatter
*f
) const;
1254 static void generate_test_instances(list
<cls_rgw_reshard_entry
*>& o
);
1256 static void generate_key(const string
& tenant
, const string
& bucket_name
, string
*key
);
1257 void get_key(string
*key
) const;
1259 WRITE_CLASS_ENCODER(cls_rgw_reshard_entry
)