1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab ft=cpp
4 #include "rgw_obj_manifest.h"
6 #include "services/svc_zone.h"
8 #include "rgw_bucket.h"
10 #define dout_context g_ceph_context
11 #define dout_subsys ceph_subsys_rgw
15 int RGWObjManifest::generator::create_next(uint64_t ofs
)
17 if (ofs
< last_ofs
) /* only going forward */
20 uint64_t max_head_size
= manifest
->get_max_head_size();
22 if (ofs
< max_head_size
) {
23 manifest
->set_head_size(ofs
);
26 if (ofs
>= max_head_size
) {
27 manifest
->set_head_size(max_head_size
);
28 cur_stripe
= (ofs
- max_head_size
) / rule
.stripe_max_size
;
29 cur_stripe_size
= rule
.stripe_max_size
;
31 if (cur_part_id
== 0 && max_head_size
> 0) {
37 manifest
->set_obj_size(ofs
);
39 manifest
->get_implicit_location(cur_part_id
, cur_stripe
, ofs
, NULL
, &cur_obj
);
44 int RGWObjManifest::append(const DoutPrefixProvider
*dpp
, RGWObjManifest
& m
, const RGWZoneGroup
& zonegroup
,
45 const RGWZoneParams
& zone_params
)
47 if (explicit_objs
|| m
.explicit_objs
) {
48 return append_explicit(dpp
, m
, zonegroup
, zone_params
);
56 string override_prefix
;
62 if (prefix
!= m
.prefix
) {
63 override_prefix
= m
.prefix
;
66 map
<uint64_t, RGWObjManifestRule
>::iterator miter
= m
.rules
.begin();
67 if (miter
== m
.rules
.end()) {
68 return append_explicit(dpp
, m
, zonegroup
, zone_params
);
71 for (; miter
!= m
.rules
.end(); ++miter
) {
72 map
<uint64_t, RGWObjManifestRule
>::reverse_iterator last_rule
= rules
.rbegin();
74 RGWObjManifestRule
& rule
= last_rule
->second
;
76 if (rule
.part_size
== 0) {
77 rule
.part_size
= obj_size
- rule
.start_ofs
;
80 RGWObjManifestRule
& next_rule
= miter
->second
;
81 if (!next_rule
.part_size
) {
82 next_rule
.part_size
= m
.obj_size
- next_rule
.start_ofs
;
85 string rule_prefix
= prefix
;
86 if (!rule
.override_prefix
.empty()) {
87 rule_prefix
= rule
.override_prefix
;
90 string next_rule_prefix
= m
.prefix
;
91 if (!next_rule
.override_prefix
.empty()) {
92 next_rule_prefix
= next_rule
.override_prefix
;
95 if (rule
.part_size
!= next_rule
.part_size
||
96 rule
.stripe_max_size
!= next_rule
.stripe_max_size
||
97 rule_prefix
!= next_rule_prefix
) {
98 if (next_rule_prefix
!= prefix
) {
99 append_rules(m
, miter
, &next_rule_prefix
);
101 append_rules(m
, miter
, NULL
);
106 uint64_t expected_part_num
= rule
.start_part_num
+ 1;
107 if (rule
.part_size
> 0) {
108 expected_part_num
= rule
.start_part_num
+ (obj_size
+ next_rule
.start_ofs
- rule
.start_ofs
) / rule
.part_size
;
111 if (expected_part_num
!= next_rule
.start_part_num
) {
112 append_rules(m
, miter
, NULL
);
117 set_obj_size(obj_size
+ m
.obj_size
);
122 void RGWObjManifest::append_rules(RGWObjManifest
& m
, map
<uint64_t, RGWObjManifestRule
>::iterator
& miter
,
123 string
*override_prefix
)
125 for (; miter
!= m
.rules
.end(); ++miter
) {
126 RGWObjManifestRule rule
= miter
->second
;
127 rule
.start_ofs
+= obj_size
;
129 rule
.override_prefix
= *override_prefix
;
130 rules
[rule
.start_ofs
] = rule
;
134 void RGWObjManifest::convert_to_explicit(const DoutPrefixProvider
*dpp
, const RGWZoneGroup
& zonegroup
, const RGWZoneParams
& zone_params
)
139 obj_iterator iter
= obj_begin(dpp
);
141 while (iter
!= obj_end(dpp
)) {
142 RGWObjManifestPart
& part
= objs
[iter
.get_stripe_ofs()];
143 const rgw_obj_select
& os
= iter
.get_location();
144 const rgw_raw_obj
& raw_loc
= os
.get_raw_obj(zonegroup
, zone_params
);
147 uint64_t ofs
= iter
.get_stripe_ofs();
152 RGWSI_Tier_RADOS::raw_obj_to_obj(tail_placement
.bucket
, raw_loc
, &part
.loc
);
155 uint64_t next_ofs
= iter
.get_stripe_ofs();
157 part
.size
= next_ofs
- ofs
;
160 explicit_objs
= true;
165 int RGWObjManifest::append_explicit(const DoutPrefixProvider
*dpp
, RGWObjManifest
& m
, const RGWZoneGroup
& zonegroup
, const RGWZoneParams
& zone_params
)
167 if (!explicit_objs
) {
168 convert_to_explicit(dpp
, zonegroup
, zone_params
);
170 if (!m
.explicit_objs
) {
171 m
.convert_to_explicit(dpp
, zonegroup
, zone_params
);
173 map
<uint64_t, RGWObjManifestPart
>::iterator iter
;
174 uint64_t base
= obj_size
;
175 for (iter
= m
.objs
.begin(); iter
!= m
.objs
.end(); ++iter
) {
176 RGWObjManifestPart
& part
= iter
->second
;
177 objs
[base
+ iter
->first
] = part
;
179 obj_size
+= m
.obj_size
;
184 bool RGWObjManifest::get_rule(uint64_t ofs
, RGWObjManifestRule
*rule
)
190 map
<uint64_t, RGWObjManifestRule
>::iterator iter
= rules
.upper_bound(ofs
);
191 if (iter
!= rules
.begin()) {
195 *rule
= iter
->second
;
200 int RGWObjManifest::generator::create_begin(CephContext
*cct
, RGWObjManifest
*_m
,
201 const rgw_placement_rule
& head_placement_rule
,
202 const rgw_placement_rule
*tail_placement_rule
,
203 const rgw_bucket
& _b
, const rgw_obj
& _obj
)
207 if (!tail_placement_rule
) {
208 manifest
->set_tail_placement(head_placement_rule
, _b
);
210 rgw_placement_rule new_tail_rule
= *tail_placement_rule
;
211 new_tail_rule
.inherit_from(head_placement_rule
);
212 manifest
->set_tail_placement(new_tail_rule
, _b
);
215 manifest
->set_head(head_placement_rule
, _obj
, 0);
218 if (manifest
->get_prefix().empty()) {
220 gen_rand_alphanumeric(cct
, buf
, sizeof(buf
) - 1);
222 string oid_prefix
= ".";
223 oid_prefix
.append(buf
);
224 oid_prefix
.append("_");
226 manifest
->set_prefix(oid_prefix
);
229 bool found
= manifest
->get_rule(0, &rule
);
231 derr
<< "ERROR: manifest->get_rule() could not find rule" << dendl
;
235 uint64_t head_size
= manifest
->get_head_size();
238 cur_stripe_size
= head_size
;
240 cur_stripe_size
= rule
.stripe_max_size
;
243 cur_part_id
= rule
.start_part_num
;
245 manifest
->get_implicit_location(cur_part_id
, cur_stripe
, 0, NULL
, &cur_obj
);
247 // Normal object which not generated through copy operation
248 manifest
->set_tail_instance(_obj
.key
.instance
);
253 void RGWObjManifestPart::generate_test_instances(std::list
<RGWObjManifestPart
*>& o
)
255 o
.push_back(new RGWObjManifestPart
);
257 RGWObjManifestPart
*p
= new RGWObjManifestPart
;
259 init_bucket(&b
, "tenant", "bucket", ".pool", ".index_pool", "marker_", "12");
261 p
->loc
= rgw_obj(b
, "object");
262 p
->loc_ofs
= 512 * 1024;
263 p
->size
= 128 * 1024;
267 void RGWObjManifest::generate_test_instances(std::list
<RGWObjManifest
*>& o
)
269 RGWObjManifest
*m
= new RGWObjManifest
;
270 map
<uint64_t, RGWObjManifestPart
> objs
;
271 uint64_t total_size
= 0;
272 for (int i
= 0; i
<10; i
++) {
273 RGWObjManifestPart p
;
275 init_bucket(&b
, "tenant", "bucket", ".pool", ".index_pool", "marker_", "12");
276 p
.loc
= rgw_obj(b
, "object");
279 total_size
+= p
.size
;
280 objs
[total_size
] = p
;
282 m
->set_explicit(total_size
, objs
);
284 o
.push_back(new RGWObjManifest
);
287 void RGWObjManifestPart::dump(Formatter
*f
) const
289 f
->open_object_section("loc");
292 f
->dump_unsigned("loc_ofs", loc_ofs
);
293 f
->dump_unsigned("size", size
);
296 void RGWObjManifest::obj_iterator::dump(Formatter
*f
) const
298 f
->dump_unsigned("part_ofs", part_ofs
);
299 f
->dump_unsigned("stripe_ofs", stripe_ofs
);
300 f
->dump_unsigned("ofs", ofs
);
301 f
->dump_unsigned("stripe_size", stripe_size
);
302 f
->dump_int("cur_part_id", cur_part_id
);
303 f
->dump_int("cur_stripe", cur_stripe
);
304 f
->dump_string("cur_override_prefix", cur_override_prefix
);
305 f
->dump_object("location", location
);
308 void RGWObjManifest::dump(Formatter
*f
) const
310 map
<uint64_t, RGWObjManifestPart
>::const_iterator iter
= objs
.begin();
311 f
->open_array_section("objs");
312 for (; iter
!= objs
.end(); ++iter
) {
313 f
->dump_unsigned("ofs", iter
->first
);
314 f
->open_object_section("part");
315 iter
->second
.dump(f
);
319 f
->dump_unsigned("obj_size", obj_size
);
320 ::encode_json("explicit_objs", explicit_objs
, f
);
321 ::encode_json("head_size", head_size
, f
);
322 ::encode_json("max_head_size", max_head_size
, f
);
323 ::encode_json("prefix", prefix
, f
);
324 ::encode_json("rules", rules
, f
);
325 ::encode_json("tail_instance", tail_instance
, f
);
326 ::encode_json("tail_placement", tail_placement
, f
);
327 ::encode_json("tier_type", tier_type
, f
);
329 if (tier_type
== "cloud-s3") {
330 ::encode_json("tier_config", tier_config
, f
);
333 // nullptr being passed into iterators since there
334 // is no cct and we aren't doing anything with these
335 // iterators that would write do the log
336 f
->dump_object("begin_iter", obj_begin(nullptr));
337 f
->dump_object("end_iter", obj_end(nullptr));
340 void RGWObjManifestRule::dump(Formatter
*f
) const
342 encode_json("start_part_num", start_part_num
, f
);
343 encode_json("start_ofs", start_ofs
, f
);
344 encode_json("part_size", part_size
, f
);
345 encode_json("stripe_max_size", stripe_max_size
, f
);
346 encode_json("override_prefix", override_prefix
, f
);
349 void rgw_obj_select::dump(Formatter
*f
) const
351 f
->dump_string("placement_rule", placement_rule
.to_str());
352 f
->dump_object("obj", obj
);
353 f
->dump_object("raw_obj", raw_obj
);
354 f
->dump_bool("is_raw", is_raw
);
357 void RGWObjTier::dump(Formatter
*f
) const
359 encode_json("name", name
, f
);
360 encode_json("tier_placement", tier_placement
, f
);
361 encode_json("is_multipart_upload", is_multipart_upload
, f
);
364 // returns true on success, false on failure
365 static bool rgw_get_obj_data_pool(const RGWZoneGroup
& zonegroup
, const RGWZoneParams
& zone_params
,
366 const rgw_placement_rule
& head_placement_rule
,
367 const rgw_obj
& obj
, rgw_pool
*pool
)
369 if (!zone_params
.get_head_data_pool(head_placement_rule
, obj
, pool
)) {
370 RGWZonePlacementInfo placement
;
371 if (!zone_params
.get_placement(zonegroup
.default_placement
.name
, &placement
)) {
375 if (!obj
.in_extra_data
) {
376 *pool
= placement
.get_data_pool(zonegroup
.default_placement
.storage_class
);
378 *pool
= placement
.get_data_extra_pool();
385 static bool rgw_obj_to_raw(const RGWZoneGroup
& zonegroup
, const RGWZoneParams
& zone_params
,
386 const rgw_placement_rule
& head_placement_rule
,
387 const rgw_obj
& obj
, rgw_raw_obj
*raw_obj
)
389 get_obj_bucket_and_oid_loc(obj
, raw_obj
->oid
, raw_obj
->loc
);
391 return rgw_get_obj_data_pool(zonegroup
, zone_params
, head_placement_rule
, obj
, &raw_obj
->pool
);
394 rgw_raw_obj
rgw_obj_select::get_raw_obj(const RGWZoneGroup
& zonegroup
, const RGWZoneParams
& zone_params
) const
398 rgw_obj_to_raw(zonegroup
, zone_params
, placement_rule
, obj
, &r
);
404 // returns true on success, false on failure
405 bool RGWRados::get_obj_data_pool(const rgw_placement_rule
& placement_rule
, const rgw_obj
& obj
, rgw_pool
*pool
)
407 return rgw_get_obj_data_pool(svc
.zone
->get_zonegroup(), svc
.zone
->get_zone_params(), placement_rule
, obj
, pool
);