]> git.proxmox.com Git - ceph.git/blob - ceph/src/rgw/rgw_obj_manifest.cc
import ceph quincy 17.2.6
[ceph.git] / ceph / src / rgw / rgw_obj_manifest.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab ft=cpp
3
4 #include "rgw_obj_manifest.h"
5
6 #include "services/svc_zone.h"
7 #include "services/svc_tier_rados.h"
8 #include "rgw_rados.h" // RGW_OBJ_NS_SHADOW and RGW_OBJ_NS_MULTIPART
9 #include "rgw_bucket.h"
10
11 #define dout_context g_ceph_context
12 #define dout_subsys ceph_subsys_rgw
13
14 using namespace std;
15
16 int RGWObjManifest::generator::create_next(uint64_t ofs)
17 {
18 if (ofs < last_ofs) /* only going forward */
19 return -EINVAL;
20
21 uint64_t max_head_size = manifest->get_max_head_size();
22
23 if (ofs < max_head_size) {
24 manifest->set_head_size(ofs);
25 }
26
27 if (ofs >= max_head_size) {
28 manifest->set_head_size(max_head_size);
29 cur_stripe = (ofs - max_head_size) / rule.stripe_max_size;
30 cur_stripe_size = rule.stripe_max_size;
31
32 if (cur_part_id == 0 && max_head_size > 0) {
33 cur_stripe++;
34 }
35 }
36
37 last_ofs = ofs;
38 manifest->set_obj_size(ofs);
39
40 manifest->get_implicit_location(cur_part_id, cur_stripe, ofs, NULL, &cur_obj);
41
42 return 0;
43 }
44
45 int RGWObjManifest::append(const DoutPrefixProvider *dpp, RGWObjManifest& m, const RGWZoneGroup& zonegroup,
46 const RGWZoneParams& zone_params)
47 {
48 if (explicit_objs || m.explicit_objs) {
49 return append_explicit(dpp, m, zonegroup, zone_params);
50 }
51
52 if (rules.empty()) {
53 *this = m;
54 return 0;
55 }
56
57 string override_prefix;
58
59 if (prefix.empty()) {
60 prefix = m.prefix;
61 }
62
63 if (prefix != m.prefix) {
64 override_prefix = m.prefix;
65 }
66
67 map<uint64_t, RGWObjManifestRule>::iterator miter = m.rules.begin();
68 if (miter == m.rules.end()) {
69 return append_explicit(dpp, m, zonegroup, zone_params);
70 }
71
72 for (; miter != m.rules.end(); ++miter) {
73 map<uint64_t, RGWObjManifestRule>::reverse_iterator last_rule = rules.rbegin();
74
75 RGWObjManifestRule& rule = last_rule->second;
76
77 if (rule.part_size == 0) {
78 rule.part_size = obj_size - rule.start_ofs;
79 }
80
81 RGWObjManifestRule& next_rule = miter->second;
82 if (!next_rule.part_size) {
83 next_rule.part_size = m.obj_size - next_rule.start_ofs;
84 }
85
86 string rule_prefix = prefix;
87 if (!rule.override_prefix.empty()) {
88 rule_prefix = rule.override_prefix;
89 }
90
91 string next_rule_prefix = m.prefix;
92 if (!next_rule.override_prefix.empty()) {
93 next_rule_prefix = next_rule.override_prefix;
94 }
95
96 if (rule.part_size != next_rule.part_size ||
97 rule.stripe_max_size != next_rule.stripe_max_size ||
98 rule_prefix != next_rule_prefix) {
99 if (next_rule_prefix != prefix) {
100 append_rules(m, miter, &next_rule_prefix);
101 } else {
102 append_rules(m, miter, NULL);
103 }
104 break;
105 }
106
107 uint64_t expected_part_num = rule.start_part_num + 1;
108 if (rule.part_size > 0) {
109 expected_part_num = rule.start_part_num + (obj_size + next_rule.start_ofs - rule.start_ofs) / rule.part_size;
110 }
111
112 if (expected_part_num != next_rule.start_part_num) {
113 append_rules(m, miter, NULL);
114 break;
115 }
116 }
117
118 set_obj_size(obj_size + m.obj_size);
119
120 return 0;
121 }
122
123 int RGWObjManifest::append(const DoutPrefixProvider *dpp, RGWObjManifest& m, rgw::sal::Zone* zone_svc)
124 {
125 return append(dpp, m, zone_svc->get_zonegroup(), zone_svc->get_params());
126 }
127
128 void RGWObjManifest::append_rules(RGWObjManifest& m, map<uint64_t, RGWObjManifestRule>::iterator& miter,
129 string *override_prefix)
130 {
131 for (; miter != m.rules.end(); ++miter) {
132 RGWObjManifestRule rule = miter->second;
133 rule.start_ofs += obj_size;
134 if (override_prefix)
135 rule.override_prefix = *override_prefix;
136 rules[rule.start_ofs] = rule;
137 }
138 }
139
140 void RGWObjManifest::convert_to_explicit(const DoutPrefixProvider *dpp, const RGWZoneGroup& zonegroup, const RGWZoneParams& zone_params)
141 {
142 if (explicit_objs) {
143 return;
144 }
145 obj_iterator iter = obj_begin(dpp);
146
147 while (iter != obj_end(dpp)) {
148 RGWObjManifestPart& part = objs[iter.get_stripe_ofs()];
149 const rgw_obj_select& os = iter.get_location();
150 const rgw_raw_obj& raw_loc = os.get_raw_obj(zonegroup, zone_params);
151 part.loc_ofs = 0;
152
153 uint64_t ofs = iter.get_stripe_ofs();
154
155 if (ofs == 0) {
156 part.loc = obj;
157 } else {
158 RGWSI_Tier_RADOS::raw_obj_to_obj(tail_placement.bucket, raw_loc, &part.loc);
159 }
160 ++iter;
161 uint64_t next_ofs = iter.get_stripe_ofs();
162
163 part.size = next_ofs - ofs;
164 }
165
166 explicit_objs = true;
167 rules.clear();
168 prefix.clear();
169 }
170
171 int RGWObjManifest::append_explicit(const DoutPrefixProvider *dpp, RGWObjManifest& m, const RGWZoneGroup& zonegroup, const RGWZoneParams& zone_params)
172 {
173 if (!explicit_objs) {
174 convert_to_explicit(dpp, zonegroup, zone_params);
175 }
176 if (!m.explicit_objs) {
177 m.convert_to_explicit(dpp, zonegroup, zone_params);
178 }
179 map<uint64_t, RGWObjManifestPart>::iterator iter;
180 uint64_t base = obj_size;
181 for (iter = m.objs.begin(); iter != m.objs.end(); ++iter) {
182 RGWObjManifestPart& part = iter->second;
183 objs[base + iter->first] = part;
184 }
185 obj_size += m.obj_size;
186
187 return 0;
188 }
189
190 bool RGWObjManifest::get_rule(uint64_t ofs, RGWObjManifestRule *rule)
191 {
192 if (rules.empty()) {
193 return false;
194 }
195
196 map<uint64_t, RGWObjManifestRule>::iterator iter = rules.upper_bound(ofs);
197 if (iter != rules.begin()) {
198 --iter;
199 }
200
201 *rule = iter->second;
202
203 return true;
204 }
205
206 void RGWObjManifest::obj_iterator::operator++()
207 {
208 if (manifest->explicit_objs) {
209 ++explicit_iter;
210
211 if (explicit_iter == manifest->objs.end()) {
212 ofs = manifest->obj_size;
213 stripe_size = 0;
214 return;
215 }
216
217 update_explicit_pos();
218
219 update_location();
220 return;
221 }
222
223 uint64_t obj_size = manifest->get_obj_size();
224 uint64_t head_size = manifest->get_head_size();
225
226 if (ofs == obj_size) {
227 return;
228 }
229
230 if (manifest->rules.empty()) {
231 return;
232 }
233
234 /* are we still pointing at the head? */
235 if (ofs < head_size) {
236 rule_iter = manifest->rules.begin();
237 const RGWObjManifestRule *rule = &rule_iter->second;
238 ofs = std::min(head_size, obj_size);
239 stripe_ofs = ofs;
240 cur_stripe = 1;
241 stripe_size = std::min(obj_size - ofs, rule->stripe_max_size);
242 if (rule->part_size > 0) {
243 stripe_size = std::min(stripe_size, rule->part_size);
244 }
245 update_location();
246 return;
247 }
248
249 const RGWObjManifestRule *rule = &rule_iter->second;
250
251 stripe_ofs += rule->stripe_max_size;
252 cur_stripe++;
253 ldpp_dout(dpp, 20) << "RGWObjManifest::operator++(): rule->part_size=" << rule->part_size << " rules.size()=" << manifest->rules.size() << dendl;
254
255 if (rule->part_size > 0) {
256 /* multi part, multi stripes object */
257
258 ldpp_dout(dpp, 20) << "RGWObjManifest::operator++(): stripe_ofs=" << stripe_ofs << " part_ofs=" << part_ofs << " rule->part_size=" << rule->part_size << dendl;
259
260 if (stripe_ofs >= part_ofs + rule->part_size) {
261 /* moved to the next part */
262 cur_stripe = 0;
263 part_ofs += rule->part_size;
264 stripe_ofs = part_ofs;
265
266 bool last_rule = (next_rule_iter == manifest->rules.end());
267 /* move to the next rule? */
268 if (!last_rule && stripe_ofs >= next_rule_iter->second.start_ofs) {
269 rule_iter = next_rule_iter;
270 last_rule = (next_rule_iter == manifest->rules.end());
271 if (!last_rule) {
272 ++next_rule_iter;
273 }
274 cur_part_id = rule_iter->second.start_part_num;
275 } else {
276 cur_part_id++;
277 }
278
279 rule = &rule_iter->second;
280 }
281
282 stripe_size = std::min(rule->part_size - (stripe_ofs - part_ofs), rule->stripe_max_size);
283 }
284
285 cur_override_prefix = rule->override_prefix;
286
287 ofs = stripe_ofs;
288 if (ofs > obj_size) {
289 ofs = obj_size;
290 stripe_ofs = ofs;
291 stripe_size = 0;
292 }
293
294 ldpp_dout(dpp, 20) << "RGWObjManifest::operator++(): result: ofs=" << ofs << " stripe_ofs=" << stripe_ofs << " part_ofs=" << part_ofs << " rule->part_size=" << rule->part_size << dendl;
295 update_location();
296 }
297
298 int RGWObjManifest::generator::create_begin(CephContext *cct, RGWObjManifest *_m,
299 const rgw_placement_rule& head_placement_rule,
300 const rgw_placement_rule *tail_placement_rule,
301 const rgw_bucket& _b, const rgw_obj& _obj)
302 {
303 manifest = _m;
304
305 if (!tail_placement_rule) {
306 manifest->set_tail_placement(head_placement_rule, _b);
307 } else {
308 rgw_placement_rule new_tail_rule = *tail_placement_rule;
309 new_tail_rule.inherit_from(head_placement_rule);
310 manifest->set_tail_placement(new_tail_rule, _b);
311 }
312
313 manifest->set_head(head_placement_rule, _obj, 0);
314 last_ofs = 0;
315
316 if (manifest->get_prefix().empty()) {
317 char buf[33];
318 gen_rand_alphanumeric(cct, buf, sizeof(buf) - 1);
319
320 string oid_prefix = ".";
321 oid_prefix.append(buf);
322 oid_prefix.append("_");
323
324 manifest->set_prefix(oid_prefix);
325 }
326
327 bool found = manifest->get_rule(0, &rule);
328 if (!found) {
329 derr << "ERROR: manifest->get_rule() could not find rule" << dendl;
330 return -EIO;
331 }
332
333 uint64_t head_size = manifest->get_head_size();
334
335 if (head_size > 0) {
336 cur_stripe_size = head_size;
337 } else {
338 cur_stripe_size = rule.stripe_max_size;
339 }
340
341 cur_part_id = rule.start_part_num;
342
343 manifest->get_implicit_location(cur_part_id, cur_stripe, 0, NULL, &cur_obj);
344
345 // Normal object which not generated through copy operation
346 manifest->set_tail_instance(_obj.key.instance);
347
348 return 0;
349 }
350
351 void RGWObjManifest::obj_iterator::seek(uint64_t o)
352 {
353 ofs = o;
354 if (manifest->explicit_objs) {
355 explicit_iter = manifest->objs.upper_bound(ofs);
356 if (explicit_iter != manifest->objs.begin()) {
357 --explicit_iter;
358 }
359 if (ofs < manifest->obj_size) {
360 update_explicit_pos();
361 } else {
362 ofs = manifest->obj_size;
363 }
364 update_location();
365 return;
366 }
367 if (o < manifest->get_head_size()) {
368 rule_iter = manifest->rules.begin();
369 stripe_ofs = 0;
370 stripe_size = manifest->get_head_size();
371 if (rule_iter != manifest->rules.end()) {
372 cur_part_id = rule_iter->second.start_part_num;
373 cur_override_prefix = rule_iter->second.override_prefix;
374 }
375 update_location();
376 return;
377 }
378
379 rule_iter = manifest->rules.upper_bound(ofs);
380 next_rule_iter = rule_iter;
381 if (rule_iter != manifest->rules.begin()) {
382 --rule_iter;
383 }
384
385 if (rule_iter == manifest->rules.end()) {
386 update_location();
387 return;
388 }
389
390 const RGWObjManifestRule& rule = rule_iter->second;
391
392 if (rule.part_size > 0) {
393 cur_part_id = rule.start_part_num + (ofs - rule.start_ofs) / rule.part_size;
394 } else {
395 cur_part_id = rule.start_part_num;
396 }
397 part_ofs = rule.start_ofs + (cur_part_id - rule.start_part_num) * rule.part_size;
398
399 if (rule.stripe_max_size > 0) {
400 cur_stripe = (ofs - part_ofs) / rule.stripe_max_size;
401
402 stripe_ofs = part_ofs + cur_stripe * rule.stripe_max_size;
403 if (!cur_part_id && manifest->get_head_size() > 0) {
404 cur_stripe++;
405 }
406 } else {
407 cur_stripe = 0;
408 stripe_ofs = part_ofs;
409 }
410
411 if (!rule.part_size) {
412 stripe_size = rule.stripe_max_size;
413 stripe_size = std::min(manifest->get_obj_size() - stripe_ofs, stripe_size);
414 } else {
415 uint64_t next = std::min(stripe_ofs + rule.stripe_max_size, part_ofs + rule.part_size);
416 stripe_size = next - stripe_ofs;
417 }
418
419 cur_override_prefix = rule.override_prefix;
420
421 update_location();
422 }
423
424 void RGWObjManifest::obj_iterator::update_location()
425 {
426 if (manifest->explicit_objs) {
427 if (manifest->empty()) {
428 location = rgw_obj_select{};
429 } else {
430 location = explicit_iter->second.loc;
431 }
432 return;
433 }
434
435 if (ofs < manifest->get_head_size()) {
436 location = manifest->get_obj();
437 location.set_placement_rule(manifest->get_head_placement_rule());
438 return;
439 }
440
441 manifest->get_implicit_location(cur_part_id, cur_stripe, ofs, &cur_override_prefix, &location);
442 }
443
444 void RGWObjManifest::obj_iterator::update_explicit_pos()
445 {
446 ofs = explicit_iter->first;
447 stripe_ofs = ofs;
448
449 auto next_iter = explicit_iter;
450 ++next_iter;
451 if (next_iter != manifest->objs.end()) {
452 stripe_size = next_iter->first - ofs;
453 } else {
454 stripe_size = manifest->obj_size - ofs;
455 }
456 }
457
458 void RGWObjManifest::get_implicit_location(uint64_t cur_part_id, uint64_t cur_stripe,
459 uint64_t ofs, string *override_prefix, rgw_obj_select *location) const
460 {
461 rgw_obj loc;
462
463 string& oid = loc.key.name;
464 string& ns = loc.key.ns;
465
466 if (!override_prefix || override_prefix->empty()) {
467 oid = prefix;
468 } else {
469 oid = *override_prefix;
470 }
471
472 if (!cur_part_id) {
473 if (ofs < max_head_size) {
474 location->set_placement_rule(head_placement_rule);
475 *location = obj;
476 return;
477 } else {
478 char buf[16];
479 snprintf(buf, sizeof(buf), "%d", (int)cur_stripe);
480 oid += buf;
481 ns = RGW_OBJ_NS_SHADOW;
482 }
483 } else {
484 char buf[32];
485 if (cur_stripe == 0) {
486 snprintf(buf, sizeof(buf), ".%d", (int)cur_part_id);
487 oid += buf;
488 ns= RGW_OBJ_NS_MULTIPART;
489 } else {
490 snprintf(buf, sizeof(buf), ".%d_%d", (int)cur_part_id, (int)cur_stripe);
491 oid += buf;
492 ns = RGW_OBJ_NS_SHADOW;
493 }
494 }
495
496 if (!tail_placement.bucket.name.empty()) {
497 loc.bucket = tail_placement.bucket;
498 } else {
499 loc.bucket = obj.bucket;
500 }
501
502 // Always overwrite instance with tail_instance
503 // to get the right shadow object location
504 loc.key.set_instance(tail_instance);
505
506 location->set_placement_rule(tail_placement.placement_rule);
507 *location = loc;
508 }
509
510 void RGWObjManifestPart::generate_test_instances(std::list<RGWObjManifestPart*>& o)
511 {
512 o.push_back(new RGWObjManifestPart);
513
514 RGWObjManifestPart *p = new RGWObjManifestPart;
515 rgw_bucket b;
516 init_bucket(&b, "tenant", "bucket", ".pool", ".index_pool", "marker_", "12");
517
518 p->loc = rgw_obj(b, "object");
519 p->loc_ofs = 512 * 1024;
520 p->size = 128 * 1024;
521 o.push_back(p);
522 }
523
524 void RGWObjManifest::generate_test_instances(std::list<RGWObjManifest*>& o)
525 {
526 RGWObjManifest *m = new RGWObjManifest;
527 map<uint64_t, RGWObjManifestPart> objs;
528 uint64_t total_size = 0;
529 for (int i = 0; i<10; i++) {
530 RGWObjManifestPart p;
531 rgw_bucket b;
532 init_bucket(&b, "tenant", "bucket", ".pool", ".index_pool", "marker_", "12");
533 p.loc = rgw_obj(b, "object");
534 p.loc_ofs = 0;
535 p.size = 512 * 1024;
536 total_size += p.size;
537 objs[total_size] = p;
538 }
539 m->set_explicit(total_size, objs);
540 o.push_back(m);
541 o.push_back(new RGWObjManifest);
542 }
543
544 void RGWObjManifestPart::dump(Formatter *f) const
545 {
546 f->open_object_section("loc");
547 loc.dump(f);
548 f->close_section();
549 f->dump_unsigned("loc_ofs", loc_ofs);
550 f->dump_unsigned("size", size);
551 }
552
553 void RGWObjManifest::obj_iterator::dump(Formatter *f) const
554 {
555 f->dump_unsigned("part_ofs", part_ofs);
556 f->dump_unsigned("stripe_ofs", stripe_ofs);
557 f->dump_unsigned("ofs", ofs);
558 f->dump_unsigned("stripe_size", stripe_size);
559 f->dump_int("cur_part_id", cur_part_id);
560 f->dump_int("cur_stripe", cur_stripe);
561 f->dump_string("cur_override_prefix", cur_override_prefix);
562 f->dump_object("location", location);
563 }
564
565 void RGWObjManifest::dump(Formatter *f) const
566 {
567 map<uint64_t, RGWObjManifestPart>::const_iterator iter = objs.begin();
568 f->open_array_section("objs");
569 for (; iter != objs.end(); ++iter) {
570 f->dump_unsigned("ofs", iter->first);
571 f->open_object_section("part");
572 iter->second.dump(f);
573 f->close_section();
574 }
575 f->close_section();
576 f->dump_unsigned("obj_size", obj_size);
577 ::encode_json("explicit_objs", explicit_objs, f);
578 ::encode_json("head_size", head_size, f);
579 ::encode_json("max_head_size", max_head_size, f);
580 ::encode_json("prefix", prefix, f);
581 ::encode_json("rules", rules, f);
582 ::encode_json("tail_instance", tail_instance, f);
583 ::encode_json("tail_placement", tail_placement, f);
584
585 // nullptr being passed into iterators since there
586 // is no cct and we aren't doing anything with these
587 // iterators that would write do the log
588 f->dump_object("begin_iter", obj_begin(nullptr));
589 f->dump_object("end_iter", obj_end(nullptr));
590 }
591
592 void RGWObjManifestRule::dump(Formatter *f) const
593 {
594 encode_json("start_part_num", start_part_num, f);
595 encode_json("start_ofs", start_ofs, f);
596 encode_json("part_size", part_size, f);
597 encode_json("stripe_max_size", stripe_max_size, f);
598 encode_json("override_prefix", override_prefix, f);
599 }
600
601 void rgw_obj_select::dump(Formatter *f) const
602 {
603 f->dump_string("placement_rule", placement_rule.to_str());
604 f->dump_object("obj", obj);
605 f->dump_object("raw_obj", raw_obj);
606 f->dump_bool("is_raw", is_raw);
607 }
608
609 void RGWObjTier::dump(Formatter *f) const
610 {
611 encode_json("name", name, f);
612 encode_json("tier_placement", tier_placement, f);
613 encode_json("is_multipart_upload", is_multipart_upload, f);
614 }