Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / cls / rgw / cls_rgw_types.h
1 #ifndef CEPH_CLS_RGW_TYPES_H
2 #define CEPH_CLS_RGW_TYPES_H
3
4 #include "common/ceph_time.h"
5 #include "common/Formatter.h"
6
7 #include "rgw/rgw_basic_types.h"
8
9 #define CEPH_RGW_REMOVE 'r'
10 #define CEPH_RGW_UPDATE 'u'
11 #define CEPH_RGW_TAG_TIMEOUT 120
12 #define CEPH_RGW_DIR_SUGGEST_LOG_OP  0x80
13 #define CEPH_RGW_DIR_SUGGEST_OP_MASK 0x7f
14
15 class JSONObj;
16
17 namespace ceph {
18   class Formatter;
19 }
20
21 using rgw_zone_set = std::set<std::string>;
22
23 enum RGWPendingState {
24   CLS_RGW_STATE_PENDING_MODIFY = 0,
25   CLS_RGW_STATE_COMPLETE       = 1,
26   CLS_RGW_STATE_UNKNOWN        = 2,
27 };
28
29 enum RGWModifyOp {
30   CLS_RGW_OP_ADD     = 0,
31   CLS_RGW_OP_DEL     = 1,
32   CLS_RGW_OP_CANCEL  = 2,
33   CLS_RGW_OP_UNKNOWN = 3,
34   CLS_RGW_OP_LINK_OLH        = 4,
35   CLS_RGW_OP_LINK_OLH_DM     = 5, /* creation of delete marker */
36   CLS_RGW_OP_UNLINK_INSTANCE = 6,
37   CLS_RGW_OP_SYNCSTOP        = 7,
38   CLS_RGW_OP_RESYNC          = 8,
39 };
40
41 enum RGWBILogFlags {
42   RGW_BILOG_FLAG_VERSIONED_OP = 0x1,
43 };
44
45 enum RGWCheckMTimeType {
46   CLS_RGW_CHECK_TIME_MTIME_EQ = 0,
47   CLS_RGW_CHECK_TIME_MTIME_LT = 1,
48   CLS_RGW_CHECK_TIME_MTIME_LE = 2,
49   CLS_RGW_CHECK_TIME_MTIME_GT = 3,
50   CLS_RGW_CHECK_TIME_MTIME_GE = 4,
51 };
52
53 #define ROUND_BLOCK_SIZE 4096
54
55 static inline uint64_t cls_rgw_get_rounded_size(uint64_t size)
56 {
57   return (size + ROUND_BLOCK_SIZE - 1) & ~(ROUND_BLOCK_SIZE - 1);
58 }
59
60 struct rgw_bucket_pending_info {
61   RGWPendingState state;
62   ceph::real_time timestamp;
63   uint8_t op;
64
65   rgw_bucket_pending_info() : state(CLS_RGW_STATE_PENDING_MODIFY), op(0) {}
66
67   void encode(bufferlist &bl) const {
68     ENCODE_START(2, 2, bl);
69     uint8_t s = (uint8_t)state;
70     ::encode(s, bl);
71     ::encode(timestamp, bl);
72     ::encode(op, bl);
73     ENCODE_FINISH(bl);
74   }
75   void decode(bufferlist::iterator &bl) {
76     DECODE_START_LEGACY_COMPAT_LEN(2, 2, 2, bl);
77     uint8_t s;
78     ::decode(s, bl);
79     state = (RGWPendingState)s;
80     ::decode(timestamp, bl);
81     ::decode(op, bl);
82     DECODE_FINISH(bl);
83   }
84   void dump(Formatter *f) const;
85   void decode_json(JSONObj *obj);
86   static void generate_test_instances(list<rgw_bucket_pending_info*>& o);
87 };
88 WRITE_CLASS_ENCODER(rgw_bucket_pending_info)
89
90 struct rgw_bucket_dir_entry_meta {
91   uint8_t category;
92   uint64_t size;
93   ceph::real_time mtime;
94   string etag;
95   string owner;
96   string owner_display_name;
97   string content_type;
98   uint64_t accounted_size;
99   string user_data;
100
101   rgw_bucket_dir_entry_meta() :
102   category(0), size(0), accounted_size(0) { }
103
104   void encode(bufferlist &bl) const {
105     ENCODE_START(5, 3, bl);
106     ::encode(category, bl);
107     ::encode(size, bl);
108     ::encode(mtime, bl);
109     ::encode(etag, bl);
110     ::encode(owner, bl);
111     ::encode(owner_display_name, bl);
112     ::encode(content_type, bl);
113     ::encode(accounted_size, bl);
114     ::encode(user_data, bl);
115     ENCODE_FINISH(bl);
116   }
117   void decode(bufferlist::iterator &bl) {
118     DECODE_START_LEGACY_COMPAT_LEN(5, 3, 3, bl);
119     ::decode(category, bl);
120     ::decode(size, bl);
121     ::decode(mtime, bl);
122     ::decode(etag, bl);
123     ::decode(owner, bl);
124     ::decode(owner_display_name, bl);
125     if (struct_v >= 2)
126       ::decode(content_type, bl);
127     if (struct_v >= 4)
128       ::decode(accounted_size, bl);
129     else
130       accounted_size = size;
131     if (struct_v >= 5)
132       ::decode(user_data, bl);
133     DECODE_FINISH(bl);
134   }
135   void dump(Formatter *f) const;
136   void decode_json(JSONObj *obj);
137   static void generate_test_instances(list<rgw_bucket_dir_entry_meta*>& o);
138 };
139 WRITE_CLASS_ENCODER(rgw_bucket_dir_entry_meta)
140
141 template<class T>
142 void encode_packed_val(T val, bufferlist& bl)
143 {
144   if ((uint64_t)val < 0x80) {
145     ::encode((uint8_t)val, bl);
146   } else {
147     unsigned char c = 0x80;
148
149     if ((uint64_t)val < 0x100) {
150       c |= 1;
151       ::encode(c, bl);
152       ::encode((uint8_t)val, bl);
153     } else if ((uint64_t)val <= 0x10000) {
154       c |= 2;
155       ::encode(c, bl);
156       ::encode((uint16_t)val, bl);
157     } else if ((uint64_t)val <= 0x1000000) {
158       c |= 4;
159       ::encode(c, bl);
160       ::encode((uint32_t)val, bl);
161     } else {
162       c |= 8;
163       ::encode(c, bl);
164       ::encode((uint64_t)val, bl);
165     }
166   }
167 }
168
169 template<class T>
170 void decode_packed_val(T& val, bufferlist::iterator& bl)
171 {
172   unsigned char c;
173   ::decode(c, bl);
174   if (c < 0x80) {
175     val = c;
176     return;
177   }
178
179   c &= ~0x80;
180
181   switch (c) {
182     case 1:
183       {
184         uint8_t v;
185         ::decode(v, bl);
186         val = v;
187       }
188       break;
189     case 2:
190       {
191         uint16_t v;
192         ::decode(v, bl);
193         val = v;
194       }
195       break;
196     case 4:
197       {
198         uint32_t v;
199         ::decode(v, bl);
200         val = v;
201       }
202       break;
203     case 8:
204       {
205         uint64_t v;
206         ::decode(v, bl);
207         val = v;
208       }
209       break;
210     default:
211       throw buffer::error();
212   }
213 }
214
215 struct rgw_bucket_entry_ver {
216   int64_t pool;
217   uint64_t epoch;
218
219   rgw_bucket_entry_ver() : pool(-1), epoch(0) {}
220
221   void encode(bufferlist &bl) const {
222     ENCODE_START(1, 1, bl);
223     ::encode_packed_val(pool, bl);
224     ::encode_packed_val(epoch, bl);
225     ENCODE_FINISH(bl);
226   }
227   void decode(bufferlist::iterator &bl) {
228     DECODE_START(1, bl);
229     ::decode_packed_val(pool, bl);
230     ::decode_packed_val(epoch, bl);
231     DECODE_FINISH(bl);
232   }
233   void dump(Formatter *f) const;
234   void decode_json(JSONObj *obj);
235   static void generate_test_instances(list<rgw_bucket_entry_ver*>& o);
236 };
237 WRITE_CLASS_ENCODER(rgw_bucket_entry_ver)
238
239 struct cls_rgw_obj_key {
240   string name;
241   string instance;
242
243   cls_rgw_obj_key() {}
244   cls_rgw_obj_key(const string &_name) : name(_name) {}
245   cls_rgw_obj_key(const string& n, const string& i) : name(n), instance(i) {}
246
247   void set(const string& _name) {
248     name = _name;
249   }
250
251   bool operator==(const cls_rgw_obj_key& k) const {
252     return (name.compare(k.name) == 0) &&
253            (instance.compare(k.instance) == 0);
254   }
255   bool operator<(const cls_rgw_obj_key& k) const {
256     int r = name.compare(k.name);
257     if (r == 0) {
258       r = instance.compare(k.instance);
259     }
260     return (r < 0);
261   }
262   bool operator<=(const cls_rgw_obj_key& k) const {
263     return !(k < *this);
264   }
265   bool empty() {
266     return name.empty();
267   }
268   void encode(bufferlist &bl) const {
269     ENCODE_START(1, 1, bl);
270     ::encode(name, bl);
271     ::encode(instance, bl);
272     ENCODE_FINISH(bl);
273   }
274   void decode(bufferlist::iterator &bl) {
275     DECODE_START(1, bl);
276     ::decode(name, bl);
277     ::decode(instance, bl);
278     DECODE_FINISH(bl);
279   }
280   void dump(Formatter *f) const {
281     f->dump_string("name", name);
282     f->dump_string("instance", instance);
283   }
284   void decode_json(JSONObj *obj);
285   static void generate_test_instances(list<cls_rgw_obj_key*>& ls) {
286     ls.push_back(new cls_rgw_obj_key);
287     ls.push_back(new cls_rgw_obj_key);
288     ls.back()->name = "name";
289     ls.back()->instance = "instance";
290   }
291 };
292 WRITE_CLASS_ENCODER(cls_rgw_obj_key)
293
294
295 #define RGW_BUCKET_DIRENT_FLAG_VER           0x1    /* a versioned object instance */
296 #define RGW_BUCKET_DIRENT_FLAG_CURRENT       0x2    /* the last object instance of a versioned object */
297 #define RGW_BUCKET_DIRENT_FLAG_DELETE_MARKER 0x4    /* delete marker */
298 #define RGW_BUCKET_DIRENT_FLAG_VER_MARKER    0x8    /* object is versioned, a placeholder for the plain entry */
299
300 struct rgw_bucket_dir_entry {
301   cls_rgw_obj_key key;
302   rgw_bucket_entry_ver ver;
303   std::string locator;
304   bool exists;
305   struct rgw_bucket_dir_entry_meta meta;
306   multimap<string, struct rgw_bucket_pending_info> pending_map;
307   uint64_t index_ver;
308   string tag;
309   uint16_t flags;
310   uint64_t versioned_epoch;
311
312   rgw_bucket_dir_entry() :
313     exists(false), index_ver(0), flags(0), versioned_epoch(0) {}
314
315   void encode(bufferlist &bl) const {
316     ENCODE_START(8, 3, bl);
317     ::encode(key.name, bl);
318     ::encode(ver.epoch, bl);
319     ::encode(exists, bl);
320     ::encode(meta, bl);
321     ::encode(pending_map, bl);
322     ::encode(locator, bl);
323     ::encode(ver, bl);
324     ::encode_packed_val(index_ver, bl);
325     ::encode(tag, bl);
326     ::encode(key.instance, bl);
327     ::encode(flags, bl);
328     ::encode(versioned_epoch, bl);
329     ENCODE_FINISH(bl);
330   }
331   void decode(bufferlist::iterator &bl) {
332     DECODE_START_LEGACY_COMPAT_LEN(8, 3, 3, bl);
333     ::decode(key.name, bl);
334     ::decode(ver.epoch, bl);
335     ::decode(exists, bl);
336     ::decode(meta, bl);
337     ::decode(pending_map, bl);
338     if (struct_v >= 2) {
339       ::decode(locator, bl);
340     }
341     if (struct_v >= 4) {
342       ::decode(ver, bl);
343     } else {
344       ver.pool = -1;
345     }
346     if (struct_v >= 5) {
347       ::decode_packed_val(index_ver, bl);
348       ::decode(tag, bl);
349     }
350     if (struct_v >= 6) {
351       ::decode(key.instance, bl);
352     }
353     if (struct_v >= 7) {
354       ::decode(flags, bl);
355     }
356     if (struct_v >= 8) {
357       ::decode(versioned_epoch, bl);
358     }
359     DECODE_FINISH(bl);
360   }
361
362   bool is_current() {
363     int test_flags = RGW_BUCKET_DIRENT_FLAG_VER | RGW_BUCKET_DIRENT_FLAG_CURRENT;
364     return (flags & RGW_BUCKET_DIRENT_FLAG_VER) == 0 ||
365            (flags & test_flags) == test_flags;
366   }
367   bool is_delete_marker() { return (flags & RGW_BUCKET_DIRENT_FLAG_DELETE_MARKER) != 0; }
368   bool is_visible() {
369     return is_current() && !is_delete_marker();
370   }
371   bool is_valid() { return (flags & RGW_BUCKET_DIRENT_FLAG_VER_MARKER) == 0; }
372
373   void dump(Formatter *f) const;
374   void decode_json(JSONObj *obj);
375   static void generate_test_instances(list<rgw_bucket_dir_entry*>& o);
376 };
377 WRITE_CLASS_ENCODER(rgw_bucket_dir_entry)
378
379 enum BIIndexType {
380   InvalidIdx    = 0,
381   PlainIdx      = 1,
382   InstanceIdx   = 2,
383   OLHIdx        = 3,
384 };
385
386 struct rgw_bucket_category_stats;
387
388 struct rgw_cls_bi_entry {
389   BIIndexType type;
390   string idx;
391   bufferlist data;
392
393   rgw_cls_bi_entry() : type(InvalidIdx) {}
394
395   void encode(bufferlist& bl) const {
396     ENCODE_START(1, 1, bl);
397     ::encode((uint8_t)type, bl);
398     ::encode(idx, bl);
399     ::encode(data, bl);
400     ENCODE_FINISH(bl);
401   }
402
403   void decode(bufferlist::iterator& bl) {
404     DECODE_START(1, bl);
405     uint8_t c;
406     ::decode(c, bl);
407     type = (BIIndexType)c;
408     ::decode(idx, bl);
409     ::decode(data, bl);
410     DECODE_FINISH(bl);
411   }
412
413   void dump(Formatter *f) const;
414   void decode_json(JSONObj *obj, cls_rgw_obj_key *effective_key = NULL);
415
416   bool get_info(cls_rgw_obj_key *key, uint8_t *category, rgw_bucket_category_stats *accounted_stats);
417 };
418 WRITE_CLASS_ENCODER(rgw_cls_bi_entry)
419
420 enum OLHLogOp {
421   CLS_RGW_OLH_OP_UNKNOWN         = 0,
422   CLS_RGW_OLH_OP_LINK_OLH        = 1,
423   CLS_RGW_OLH_OP_UNLINK_OLH      = 2, /* object does not exist */
424   CLS_RGW_OLH_OP_REMOVE_INSTANCE = 3,
425 };
426
427 struct rgw_bucket_olh_log_entry {
428   uint64_t epoch;
429   OLHLogOp op;
430   string op_tag;
431   cls_rgw_obj_key key;
432   bool delete_marker;
433
434   rgw_bucket_olh_log_entry() : epoch(0), op(CLS_RGW_OLH_OP_UNKNOWN), delete_marker(false) {}
435
436
437   void encode(bufferlist &bl) const {
438     ENCODE_START(1, 1, bl);
439     ::encode(epoch, bl);
440     ::encode((__u8)op, bl);
441     ::encode(op_tag, bl);
442     ::encode(key, bl);
443     ::encode(delete_marker, bl);
444     ENCODE_FINISH(bl);
445   }
446   void decode(bufferlist::iterator &bl) {
447     DECODE_START(1, bl);
448     ::decode(epoch, bl);
449     uint8_t c;
450     ::decode(c, bl);
451     op = (OLHLogOp)c;
452     ::decode(op_tag, bl);
453     ::decode(key, bl);
454     ::decode(delete_marker, bl);
455     DECODE_FINISH(bl);
456   }
457   static void generate_test_instances(list<rgw_bucket_olh_log_entry*>& o);
458   void dump(Formatter *f) const;
459   void decode_json(JSONObj *obj);
460 };
461 WRITE_CLASS_ENCODER(rgw_bucket_olh_log_entry)
462
463 struct rgw_bucket_olh_entry {
464   cls_rgw_obj_key key;
465   bool delete_marker;
466   uint64_t epoch;
467   map<uint64_t, vector<struct rgw_bucket_olh_log_entry> > pending_log;
468   string tag;
469   bool exists;
470   bool pending_removal;
471
472   rgw_bucket_olh_entry() : delete_marker(false), epoch(0), exists(false), pending_removal(false) {}
473
474   void encode(bufferlist &bl) const {
475     ENCODE_START(1, 1, bl);
476     ::encode(key, bl);
477     ::encode(delete_marker, bl);
478     ::encode(epoch, bl);
479     ::encode(pending_log, bl);
480     ::encode(tag, bl);
481     ::encode(exists, bl);
482     ::encode(pending_removal, bl);
483     ENCODE_FINISH(bl);
484   }
485   void decode(bufferlist::iterator &bl) {
486     DECODE_START(1, bl);
487     ::decode(key, bl);
488     ::decode(delete_marker, bl);
489     ::decode(epoch, bl);
490     ::decode(pending_log, bl);
491     ::decode(tag, bl);
492     ::decode(exists, bl);
493     ::decode(pending_removal, bl);
494     DECODE_FINISH(bl);
495   }
496   void dump(Formatter *f) const;
497   void decode_json(JSONObj *obj);
498 };
499 WRITE_CLASS_ENCODER(rgw_bucket_olh_entry)
500
501 struct rgw_bi_log_entry {
502   string id;
503   string object;
504   string instance;
505   ceph::real_time timestamp;
506   rgw_bucket_entry_ver ver;
507   RGWModifyOp op;
508   RGWPendingState state;
509   uint64_t index_ver;
510   string tag;
511   uint16_t bilog_flags;
512   string owner; /* only being set if it's a delete marker */
513   string owner_display_name; /* only being set if it's a delete marker */
514   rgw_zone_set zones_trace;
515
516   rgw_bi_log_entry() : op(CLS_RGW_OP_UNKNOWN), state(CLS_RGW_STATE_PENDING_MODIFY), index_ver(0), bilog_flags(0) {}
517
518   void encode(bufferlist &bl) const {
519     ENCODE_START(4, 1, bl);
520     ::encode(id, bl);
521     ::encode(object, bl);
522     ::encode(timestamp, bl);
523     ::encode(ver, bl);
524     ::encode(tag, bl);
525     uint8_t c = (uint8_t)op;
526     ::encode(c, bl);
527     c = (uint8_t)state;
528     ::encode(c, bl);
529     encode_packed_val(index_ver, bl);
530     ::encode(instance, bl);
531     ::encode(bilog_flags, bl);
532     ::encode(owner, bl);
533     ::encode(owner_display_name, bl);
534     ::encode(zones_trace, bl);
535     ENCODE_FINISH(bl);
536   }
537   void decode(bufferlist::iterator &bl) {
538     DECODE_START(4, bl);
539     ::decode(id, bl);
540     ::decode(object, bl);
541     ::decode(timestamp, bl);
542     ::decode(ver, bl);
543     ::decode(tag, bl);
544     uint8_t c;
545     ::decode(c, bl);
546     op = (RGWModifyOp)c;
547     ::decode(c, bl);
548     state = (RGWPendingState)c;
549     decode_packed_val(index_ver, bl);
550     if (struct_v >= 2) {
551       ::decode(instance, bl);
552       ::decode(bilog_flags, bl);
553     }
554     if (struct_v >= 3) {
555       ::decode(owner, bl);
556       ::decode(owner_display_name, bl);
557     }
558     if (struct_v >= 4) {
559       ::decode(zones_trace, bl);
560     }
561     DECODE_FINISH(bl);
562   }
563   void dump(Formatter *f) const;
564   void decode_json(JSONObj *obj);
565   static void generate_test_instances(list<rgw_bi_log_entry*>& o);
566
567   bool is_versioned() {
568     return ((bilog_flags & RGW_BILOG_FLAG_VERSIONED_OP) != 0);
569   }
570 };
571 WRITE_CLASS_ENCODER(rgw_bi_log_entry)
572
573 struct rgw_bucket_category_stats {
574   uint64_t total_size;
575   uint64_t total_size_rounded;
576   uint64_t num_entries;
577   uint64_t actual_size{0}; //< account for compression, encryption
578
579   rgw_bucket_category_stats() : total_size(0), total_size_rounded(0), num_entries(0) {}
580
581   void encode(bufferlist &bl) const {
582     ENCODE_START(3, 2, bl);
583     ::encode(total_size, bl);
584     ::encode(total_size_rounded, bl);
585     ::encode(num_entries, bl);
586     ::encode(actual_size, bl);
587     ENCODE_FINISH(bl);
588   }
589   void decode(bufferlist::iterator &bl) {
590     DECODE_START_LEGACY_COMPAT_LEN(3, 2, 2, bl);
591     ::decode(total_size, bl);
592     ::decode(total_size_rounded, bl);
593     ::decode(num_entries, bl);
594     if (struct_v >= 3) {
595       ::decode(actual_size, bl);
596     } else {
597       actual_size = total_size;
598     }
599     DECODE_FINISH(bl);
600   }
601   void dump(Formatter *f) const;
602   static void generate_test_instances(list<rgw_bucket_category_stats*>& o);
603 };
604 WRITE_CLASS_ENCODER(rgw_bucket_category_stats)
605
606 enum cls_rgw_reshard_status {
607   CLS_RGW_RESHARD_NONE        = 0,
608   CLS_RGW_RESHARD_IN_PROGRESS = 1,
609   CLS_RGW_RESHARD_DONE        = 2,
610 };
611
612 struct cls_rgw_bucket_instance_entry {
613   cls_rgw_reshard_status reshard_status{CLS_RGW_RESHARD_NONE};
614   string new_bucket_instance_id;
615   int32_t num_shards{-1};
616
617   void encode(bufferlist& bl) const {
618     ENCODE_START(1, 1, bl);
619     ::encode((uint8_t)reshard_status, bl);
620     ::encode(new_bucket_instance_id, bl);
621     ::encode(num_shards, bl);
622     ENCODE_FINISH(bl);
623   }
624
625   void decode(bufferlist::iterator& bl) {
626     DECODE_START(1, bl);
627     uint8_t s;
628     ::decode(s, bl);
629     reshard_status = (cls_rgw_reshard_status)s;
630     ::decode(new_bucket_instance_id, bl);
631     ::decode(num_shards, bl);
632     DECODE_FINISH(bl);
633   }
634
635   void dump(Formatter *f) const;
636   static void generate_test_instances(list<cls_rgw_bucket_instance_entry*>& o);
637
638   void clear() {
639     reshard_status = CLS_RGW_RESHARD_NONE;
640     new_bucket_instance_id.clear();
641   }
642
643   void set_status(const string& new_instance_id, int32_t new_num_shards, cls_rgw_reshard_status s) {
644     reshard_status = s;
645     new_bucket_instance_id = new_instance_id;
646     num_shards = new_num_shards;
647   }
648
649   bool resharding() const {
650     return reshard_status != CLS_RGW_RESHARD_NONE;
651   }
652   bool resharding_in_progress() const {
653     return reshard_status == CLS_RGW_RESHARD_IN_PROGRESS;
654   }
655 };
656 WRITE_CLASS_ENCODER(cls_rgw_bucket_instance_entry)
657
658 struct rgw_bucket_dir_header {
659   map<uint8_t, rgw_bucket_category_stats> stats;
660   uint64_t tag_timeout;
661   uint64_t ver;
662   uint64_t master_ver;
663   string max_marker;
664   cls_rgw_bucket_instance_entry new_instance;
665   bool syncstopped;
666
667   rgw_bucket_dir_header() : tag_timeout(0), ver(0), master_ver(0), syncstopped(false) {}
668
669   void encode(bufferlist &bl) const {
670     ENCODE_START(7, 2, bl);
671     ::encode(stats, bl);
672     ::encode(tag_timeout, bl);
673     ::encode(ver, bl);
674     ::encode(master_ver, bl);
675     ::encode(max_marker, bl);
676     ::encode(new_instance, bl);
677     ::encode(syncstopped,bl);
678     ENCODE_FINISH(bl);
679   }
680   void decode(bufferlist::iterator &bl) {
681     DECODE_START_LEGACY_COMPAT_LEN(6, 2, 2, bl);
682     ::decode(stats, bl);
683     if (struct_v > 2) {
684       ::decode(tag_timeout, bl);
685     } else {
686       tag_timeout = 0;
687     }
688     if (struct_v >= 4) {
689       ::decode(ver, bl);
690       ::decode(master_ver, bl);
691     } else {
692       ver = 0;
693     }
694     if (struct_v >= 5) {
695       ::decode(max_marker, bl);
696     }
697     if (struct_v >= 6) {
698       ::decode(new_instance, bl);
699     } else {
700       new_instance = cls_rgw_bucket_instance_entry();
701     }
702     if (struct_v >= 7) {
703       ::decode(syncstopped,bl);
704     }
705     DECODE_FINISH(bl);
706   }
707   void dump(Formatter *f) const;
708   static void generate_test_instances(list<rgw_bucket_dir_header*>& o);
709
710   bool resharding() const {
711     return new_instance.resharding();
712   }
713   bool resharding_in_progress() const {
714     return new_instance.resharding_in_progress();
715   }
716 };
717 WRITE_CLASS_ENCODER(rgw_bucket_dir_header)
718
719 struct rgw_bucket_dir {
720   struct rgw_bucket_dir_header header;
721   std::map<string, struct rgw_bucket_dir_entry> m;
722
723   void encode(bufferlist &bl) const {
724     ENCODE_START(2, 2, bl);
725     ::encode(header, bl);
726     ::encode(m, bl);
727     ENCODE_FINISH(bl);
728   }
729   void decode(bufferlist::iterator &bl) {
730     DECODE_START_LEGACY_COMPAT_LEN(2, 2, 2, bl);
731     ::decode(header, bl);
732     ::decode(m, bl);
733     DECODE_FINISH(bl);
734   }
735   void dump(Formatter *f) const;
736   static void generate_test_instances(list<rgw_bucket_dir*>& o);
737 };
738 WRITE_CLASS_ENCODER(rgw_bucket_dir)
739
740 struct rgw_usage_data {
741   uint64_t bytes_sent;
742   uint64_t bytes_received;
743   uint64_t ops;
744   uint64_t successful_ops;
745
746   rgw_usage_data() : bytes_sent(0), bytes_received(0), ops(0), successful_ops(0) {}
747   rgw_usage_data(uint64_t sent, uint64_t received) : bytes_sent(sent), bytes_received(received), ops(0), successful_ops(0) {}
748
749   void encode(bufferlist& bl) const {
750     ENCODE_START(1, 1, bl);
751     ::encode(bytes_sent, bl);
752     ::encode(bytes_received, bl);
753     ::encode(ops, bl);
754     ::encode(successful_ops, bl);
755     ENCODE_FINISH(bl);
756   }
757
758   void decode(bufferlist::iterator& bl) {
759     DECODE_START(1, bl);
760     ::decode(bytes_sent, bl);
761     ::decode(bytes_received, bl);
762     ::decode(ops, bl);
763     ::decode(successful_ops, bl);
764     DECODE_FINISH(bl);
765   }
766
767   void aggregate(const rgw_usage_data& usage) {
768     bytes_sent += usage.bytes_sent;
769     bytes_received += usage.bytes_received;
770     ops += usage.ops;
771     successful_ops += usage.successful_ops;
772   }
773 };
774 WRITE_CLASS_ENCODER(rgw_usage_data)
775
776
777 struct rgw_usage_log_entry {
778   rgw_user owner;
779   rgw_user payer; /* if empty, same as owner */
780   string bucket;
781   uint64_t epoch;
782   rgw_usage_data total_usage; /* this one is kept for backwards compatibility */
783   map<string, rgw_usage_data> usage_map;
784
785   rgw_usage_log_entry() : epoch(0) {}
786   rgw_usage_log_entry(string& o, string& b) : owner(o), bucket(b), epoch(0) {}
787   rgw_usage_log_entry(string& o, string& p, string& b) : owner(o), payer(p), bucket(b), epoch(0) {}
788
789   void encode(bufferlist& bl) const {
790     ENCODE_START(3, 1, bl);
791     ::encode(owner.to_str(), bl);
792     ::encode(bucket, bl);
793     ::encode(epoch, bl);
794     ::encode(total_usage.bytes_sent, bl);
795     ::encode(total_usage.bytes_received, bl);
796     ::encode(total_usage.ops, bl);
797     ::encode(total_usage.successful_ops, bl);
798     ::encode(usage_map, bl);
799     ::encode(payer.to_str(), bl);
800     ENCODE_FINISH(bl);
801   }
802
803
804    void decode(bufferlist::iterator& bl) {
805     DECODE_START(3, bl);
806     string s;
807     ::decode(s, bl);
808     owner.from_str(s);
809     ::decode(bucket, bl);
810     ::decode(epoch, bl);
811     ::decode(total_usage.bytes_sent, bl);
812     ::decode(total_usage.bytes_received, bl);
813     ::decode(total_usage.ops, bl);
814     ::decode(total_usage.successful_ops, bl);
815     if (struct_v < 2) {
816       usage_map[""] = total_usage;
817     } else {
818       ::decode(usage_map, bl);
819     }
820     if (struct_v >= 3) {
821       string p;
822       ::decode(p, bl);
823       payer.from_str(p);
824     }
825     DECODE_FINISH(bl);
826   }
827
828   void aggregate(const rgw_usage_log_entry& e, map<string, bool> *categories = NULL) {
829     if (owner.empty()) {
830       owner = e.owner;
831       bucket = e.bucket;
832       epoch = e.epoch;
833       payer = e.payer;
834     }
835
836     map<string, rgw_usage_data>::const_iterator iter;
837     for (iter = e.usage_map.begin(); iter != e.usage_map.end(); ++iter) {
838       if (!categories || !categories->size() || categories->count(iter->first)) {
839         add(iter->first, iter->second);
840       }
841     }
842   }
843
844   void sum(rgw_usage_data& usage, map<string, bool>& categories) const {
845     usage = rgw_usage_data();
846     for (map<string, rgw_usage_data>::const_iterator iter = usage_map.begin(); iter != usage_map.end(); ++iter) {
847       if (!categories.size() || categories.count(iter->first)) {
848         usage.aggregate(iter->second);
849       }
850     }
851   }
852
853   void add(const string& category, const rgw_usage_data& data) {
854     usage_map[category].aggregate(data);
855     total_usage.aggregate(data);
856   }
857 };
858 WRITE_CLASS_ENCODER(rgw_usage_log_entry)
859
860 struct rgw_usage_log_info {
861   vector<rgw_usage_log_entry> entries;
862
863   void encode(bufferlist& bl) const {
864     ENCODE_START(1, 1, bl);
865     ::encode(entries, bl);
866     ENCODE_FINISH(bl);
867   }
868
869   void decode(bufferlist::iterator& bl) {
870     DECODE_START(1, bl);
871     ::decode(entries, bl);
872     DECODE_FINISH(bl);
873   }
874
875   rgw_usage_log_info() {}
876 };
877 WRITE_CLASS_ENCODER(rgw_usage_log_info)
878
879 struct rgw_user_bucket {
880   string user;
881   string bucket;
882
883   rgw_user_bucket() {}
884   rgw_user_bucket(const string& u, const string& b) : user(u), bucket(b) {}
885
886   void encode(bufferlist& bl) const {
887     ENCODE_START(1, 1, bl);
888     ::encode(user, bl);
889     ::encode(bucket, bl);
890     ENCODE_FINISH(bl);
891   }
892
893   void decode(bufferlist::iterator& bl) {
894     DECODE_START(1, bl);
895     ::decode(user, bl);
896     ::decode(bucket, bl);
897     DECODE_FINISH(bl);
898   }
899
900   bool operator<(const rgw_user_bucket& ub2) const {
901     int comp = user.compare(ub2.user);
902     if (comp < 0)
903       return true;
904     else if (!comp)
905       return bucket.compare(ub2.bucket) < 0;
906
907     return false;
908   }
909 };
910 WRITE_CLASS_ENCODER(rgw_user_bucket)
911
912 enum cls_rgw_gc_op {
913   CLS_RGW_GC_DEL_OBJ,
914   CLS_RGW_GC_DEL_BUCKET,
915 };
916
917 struct cls_rgw_obj {
918   string pool;
919   cls_rgw_obj_key key;
920   string loc;
921
922   cls_rgw_obj() {}
923   cls_rgw_obj(string& _p, cls_rgw_obj_key& _k) : pool(_p), key(_k) {}
924
925   void encode(bufferlist& bl) const {
926     ENCODE_START(2, 1, bl);
927     ::encode(pool, bl);
928     ::encode(key.name, bl);
929     ::encode(loc, bl);
930     ::encode(key, bl);
931     ENCODE_FINISH(bl);
932   }
933
934   void decode(bufferlist::iterator& bl) {
935     DECODE_START(2, bl);
936     ::decode(pool, bl);
937     ::decode(key.name, bl);
938     ::decode(loc, bl);
939     if (struct_v >= 2) {
940       ::decode(key, bl);
941     }
942     DECODE_FINISH(bl);
943   }
944
945   void dump(Formatter *f) const {
946     f->dump_string("pool", pool);
947     f->dump_string("oid", key.name);
948     f->dump_string("key", loc);
949     f->dump_string("instance", key.instance);
950   }
951   static void generate_test_instances(list<cls_rgw_obj*>& ls) {
952     ls.push_back(new cls_rgw_obj);
953     ls.push_back(new cls_rgw_obj);
954     ls.back()->pool = "mypool";
955     ls.back()->key.name = "myoid";
956     ls.back()->loc = "mykey";
957   }
958 };
959 WRITE_CLASS_ENCODER(cls_rgw_obj)
960
961 struct cls_rgw_obj_chain {
962   list<cls_rgw_obj> objs;
963
964   cls_rgw_obj_chain() {}
965
966   void push_obj(const string& pool, const cls_rgw_obj_key& key, const string& loc) {
967     cls_rgw_obj obj;
968     obj.pool = pool;
969     obj.key = key;
970     obj.loc = loc;
971     objs.push_back(obj);
972   }
973
974   void encode(bufferlist& bl) const {
975     ENCODE_START(1, 1, bl);
976     ::encode(objs, bl);
977     ENCODE_FINISH(bl);
978   }
979
980   void decode(bufferlist::iterator& bl) {
981     DECODE_START(1, bl);
982     ::decode(objs, bl);
983     DECODE_FINISH(bl);
984   }
985
986   void dump(Formatter *f) const {
987     f->open_array_section("objs");
988     for (list<cls_rgw_obj>::const_iterator p = objs.begin(); p != objs.end(); ++p) {
989       f->open_object_section("obj");
990       p->dump(f);
991       f->close_section();
992     }
993     f->close_section();
994   }
995   static void generate_test_instances(list<cls_rgw_obj_chain*>& ls) {
996     ls.push_back(new cls_rgw_obj_chain);
997   }
998
999   bool empty() {
1000     return objs.empty();
1001   }
1002 };
1003 WRITE_CLASS_ENCODER(cls_rgw_obj_chain)
1004
1005 struct cls_rgw_gc_obj_info
1006 {
1007   string tag;
1008   cls_rgw_obj_chain chain;
1009   ceph::real_time time;
1010
1011   cls_rgw_gc_obj_info() {}
1012
1013   void encode(bufferlist& bl) const {
1014     ENCODE_START(1, 1, bl);
1015     ::encode(tag, bl);
1016     ::encode(chain, bl);
1017     ::encode(time, bl);
1018     ENCODE_FINISH(bl);
1019   }
1020
1021   void decode(bufferlist::iterator& bl) {
1022     DECODE_START(1, bl);
1023     ::decode(tag, bl);
1024     ::decode(chain, bl);
1025     ::decode(time, bl);
1026     DECODE_FINISH(bl);
1027   }
1028
1029   void dump(Formatter *f) const {
1030     f->dump_string("tag", tag);
1031     f->open_object_section("chain");
1032     chain.dump(f);
1033     f->close_section();
1034     f->dump_stream("time") << time;
1035   }
1036   static void generate_test_instances(list<cls_rgw_gc_obj_info*>& ls) {
1037     ls.push_back(new cls_rgw_gc_obj_info);
1038     ls.push_back(new cls_rgw_gc_obj_info);
1039     ls.back()->tag = "footag";
1040     ceph_timespec ts{21, 32};
1041     ls.back()->time = ceph::real_clock::from_ceph_timespec(ts);
1042   }
1043 };
1044 WRITE_CLASS_ENCODER(cls_rgw_gc_obj_info)
1045
1046 struct cls_rgw_lc_obj_head
1047 {
1048   time_t start_date;
1049   string marker;
1050
1051   cls_rgw_lc_obj_head() {}
1052
1053   void encode(bufferlist& bl) const {
1054     ENCODE_START(1, 1, bl);
1055     uint64_t t = start_date;
1056     ::encode(t, bl);
1057     ::encode(marker, bl);
1058     ENCODE_FINISH(bl);
1059   }
1060
1061   void decode(bufferlist::iterator& bl) {
1062     DECODE_START(1, bl);
1063     uint64_t t;
1064     ::decode(t, bl);
1065     start_date = static_cast<time_t>(t);
1066     ::decode(marker, bl);
1067     DECODE_FINISH(bl);
1068   }
1069
1070 };
1071 WRITE_CLASS_ENCODER(cls_rgw_lc_obj_head)
1072
1073 struct cls_rgw_reshard_entry
1074 {
1075   ceph::real_time time;
1076   string tenant;
1077   string bucket_name;
1078   string bucket_id;
1079   string new_instance_id;
1080   uint32_t old_num_shards{0};
1081   uint32_t new_num_shards{0};
1082
1083   cls_rgw_reshard_entry() {}
1084
1085   void encode(bufferlist& bl) const {
1086     ENCODE_START(1, 1, bl);
1087      ::encode(time, bl);
1088     ::encode(tenant, bl);
1089     ::encode(bucket_name, bl);
1090     ::encode(bucket_id, bl);
1091     ::encode(new_instance_id, bl);
1092     ::encode(old_num_shards, bl);
1093     ::encode(new_num_shards, bl);
1094     ENCODE_FINISH(bl);
1095   }
1096
1097   void decode(bufferlist::iterator& bl) {
1098     DECODE_START(1, bl);
1099     ::decode(time, bl);
1100     ::decode(tenant, bl);
1101     ::decode(bucket_name, bl);
1102     ::decode(bucket_id, bl);
1103     ::decode(new_instance_id, bl);
1104     ::decode(old_num_shards, bl);
1105     ::decode(new_num_shards, bl);
1106     DECODE_FINISH(bl);
1107   }
1108
1109   void dump(Formatter *f) const;
1110   static void generate_test_instances(list<cls_rgw_reshard_entry*>& o);
1111
1112   static void generate_key(const string& tenant, const string& bucket_name, string *key);
1113   void get_key(string *key) const;
1114 };
1115 WRITE_CLASS_ENCODER(cls_rgw_reshard_entry)
1116
1117 #endif