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"
7 #include "services/svc_tier_rados.h"
9 #define dout_context g_ceph_context
10 #define dout_subsys ceph_subsys_rgw
12 int RGWObjManifest::generator::create_next(uint64_t ofs
)
14 if (ofs
< last_ofs
) /* only going forward */
17 uint64_t max_head_size
= manifest
->get_max_head_size();
19 if (ofs
< max_head_size
) {
20 manifest
->set_head_size(ofs
);
23 if (ofs
>= max_head_size
) {
24 manifest
->set_head_size(max_head_size
);
25 cur_stripe
= (ofs
- max_head_size
) / rule
.stripe_max_size
;
26 cur_stripe_size
= rule
.stripe_max_size
;
28 if (cur_part_id
== 0 && max_head_size
> 0) {
34 manifest
->set_obj_size(ofs
);
36 manifest
->get_implicit_location(cur_part_id
, cur_stripe
, ofs
, NULL
, &cur_obj
);
38 manifest
->update_iterators();
43 const RGWObjManifest::obj_iterator
& RGWObjManifest::obj_begin()
48 const RGWObjManifest::obj_iterator
& RGWObjManifest::obj_end()
53 RGWObjManifest::obj_iterator
RGWObjManifest::obj_find(uint64_t ofs
)
58 RGWObjManifest::obj_iterator
iter(this);
63 int RGWObjManifest::append(RGWObjManifest
& m
, const RGWZoneGroup
& zonegroup
,
64 const RGWZoneParams
& zone_params
)
66 if (explicit_objs
|| m
.explicit_objs
) {
67 return append_explicit(m
, zonegroup
, zone_params
);
75 string override_prefix
;
81 if (prefix
!= m
.prefix
) {
82 override_prefix
= m
.prefix
;
85 map
<uint64_t, RGWObjManifestRule
>::iterator miter
= m
.rules
.begin();
86 if (miter
== m
.rules
.end()) {
87 return append_explicit(m
, zonegroup
, zone_params
);
90 for (; miter
!= m
.rules
.end(); ++miter
) {
91 map
<uint64_t, RGWObjManifestRule
>::reverse_iterator last_rule
= rules
.rbegin();
93 RGWObjManifestRule
& rule
= last_rule
->second
;
95 if (rule
.part_size
== 0) {
96 rule
.part_size
= obj_size
- rule
.start_ofs
;
99 RGWObjManifestRule
& next_rule
= miter
->second
;
100 if (!next_rule
.part_size
) {
101 next_rule
.part_size
= m
.obj_size
- next_rule
.start_ofs
;
104 string rule_prefix
= prefix
;
105 if (!rule
.override_prefix
.empty()) {
106 rule_prefix
= rule
.override_prefix
;
109 string next_rule_prefix
= m
.prefix
;
110 if (!next_rule
.override_prefix
.empty()) {
111 next_rule_prefix
= next_rule
.override_prefix
;
114 if (rule
.part_size
!= next_rule
.part_size
||
115 rule
.stripe_max_size
!= next_rule
.stripe_max_size
||
116 rule_prefix
!= next_rule_prefix
) {
117 if (next_rule_prefix
!= prefix
) {
118 append_rules(m
, miter
, &next_rule_prefix
);
120 append_rules(m
, miter
, NULL
);
125 uint64_t expected_part_num
= rule
.start_part_num
+ 1;
126 if (rule
.part_size
> 0) {
127 expected_part_num
= rule
.start_part_num
+ (obj_size
+ next_rule
.start_ofs
- rule
.start_ofs
) / rule
.part_size
;
130 if (expected_part_num
!= next_rule
.start_part_num
) {
131 append_rules(m
, miter
, NULL
);
136 set_obj_size(obj_size
+ m
.obj_size
);
141 int RGWObjManifest::append(RGWObjManifest
& m
, RGWSI_Zone
*zone_svc
)
143 return append(m
, zone_svc
->get_zonegroup(), zone_svc
->get_zone_params());
146 void RGWObjManifest::append_rules(RGWObjManifest
& m
, map
<uint64_t, RGWObjManifestRule
>::iterator
& miter
,
147 string
*override_prefix
)
149 for (; miter
!= m
.rules
.end(); ++miter
) {
150 RGWObjManifestRule rule
= miter
->second
;
151 rule
.start_ofs
+= obj_size
;
153 rule
.override_prefix
= *override_prefix
;
154 rules
[rule
.start_ofs
] = rule
;
158 void RGWObjManifest::convert_to_explicit(const RGWZoneGroup
& zonegroup
, const RGWZoneParams
& zone_params
)
163 obj_iterator iter
= obj_begin();
165 while (iter
!= obj_end()) {
166 RGWObjManifestPart
& part
= objs
[iter
.get_stripe_ofs()];
167 const rgw_obj_select
& os
= iter
.get_location();
168 const rgw_raw_obj
& raw_loc
= os
.get_raw_obj(zonegroup
, zone_params
);
171 uint64_t ofs
= iter
.get_stripe_ofs();
176 RGWSI_Tier_RADOS::raw_obj_to_obj(tail_placement
.bucket
, raw_loc
, &part
.loc
);
179 uint64_t next_ofs
= iter
.get_stripe_ofs();
181 part
.size
= next_ofs
- ofs
;
184 explicit_objs
= true;
189 int RGWObjManifest::append_explicit(RGWObjManifest
& m
, const RGWZoneGroup
& zonegroup
, const RGWZoneParams
& zone_params
)
191 if (!explicit_objs
) {
192 convert_to_explicit(zonegroup
, zone_params
);
194 if (!m
.explicit_objs
) {
195 m
.convert_to_explicit(zonegroup
, zone_params
);
197 map
<uint64_t, RGWObjManifestPart
>::iterator iter
;
198 uint64_t base
= obj_size
;
199 for (iter
= m
.objs
.begin(); iter
!= m
.objs
.end(); ++iter
) {
200 RGWObjManifestPart
& part
= iter
->second
;
201 objs
[base
+ iter
->first
] = part
;
203 obj_size
+= m
.obj_size
;
208 bool RGWObjManifest::get_rule(uint64_t ofs
, RGWObjManifestRule
*rule
)
214 map
<uint64_t, RGWObjManifestRule
>::iterator iter
= rules
.upper_bound(ofs
);
215 if (iter
!= rules
.begin()) {
219 *rule
= iter
->second
;
224 void RGWObjManifest::obj_iterator::operator++()
226 if (manifest
->explicit_objs
) {
229 update_explicit_pos();
235 uint64_t obj_size
= manifest
->get_obj_size();
236 uint64_t head_size
= manifest
->get_head_size();
238 if (ofs
== obj_size
) {
242 if (manifest
->rules
.empty()) {
246 /* are we still pointing at the head? */
247 if (ofs
< head_size
) {
248 rule_iter
= manifest
->rules
.begin();
249 RGWObjManifestRule
*rule
= &rule_iter
->second
;
250 ofs
= std::min(head_size
, obj_size
);
253 stripe_size
= std::min(obj_size
- ofs
, rule
->stripe_max_size
);
254 if (rule
->part_size
> 0) {
255 stripe_size
= std::min(stripe_size
, rule
->part_size
);
261 RGWObjManifestRule
*rule
= &rule_iter
->second
;
263 stripe_ofs
+= rule
->stripe_max_size
;
265 dout(20) << "RGWObjManifest::operator++(): rule->part_size=" << rule
->part_size
<< " rules.size()=" << manifest
->rules
.size() << dendl
;
267 if (rule
->part_size
> 0) {
268 /* multi part, multi stripes object */
270 dout(20) << "RGWObjManifest::operator++(): stripe_ofs=" << stripe_ofs
<< " part_ofs=" << part_ofs
<< " rule->part_size=" << rule
->part_size
<< dendl
;
272 if (stripe_ofs
>= part_ofs
+ rule
->part_size
) {
273 /* moved to the next part */
275 part_ofs
+= rule
->part_size
;
276 stripe_ofs
= part_ofs
;
278 bool last_rule
= (next_rule_iter
== manifest
->rules
.end());
279 /* move to the next rule? */
280 if (!last_rule
&& stripe_ofs
>= next_rule_iter
->second
.start_ofs
) {
281 rule_iter
= next_rule_iter
;
282 last_rule
= (next_rule_iter
== manifest
->rules
.end());
286 cur_part_id
= rule_iter
->second
.start_part_num
;
291 rule
= &rule_iter
->second
;
294 stripe_size
= std::min(rule
->part_size
- (stripe_ofs
- part_ofs
), rule
->stripe_max_size
);
297 cur_override_prefix
= rule
->override_prefix
;
300 if (ofs
> obj_size
) {
306 dout(20) << "RGWObjManifest::operator++(): result: ofs=" << ofs
<< " stripe_ofs=" << stripe_ofs
<< " part_ofs=" << part_ofs
<< " rule->part_size=" << rule
->part_size
<< dendl
;
310 int RGWObjManifest::generator::create_begin(CephContext
*cct
, RGWObjManifest
*_m
,
311 const rgw_placement_rule
& head_placement_rule
,
312 const rgw_placement_rule
*tail_placement_rule
,
313 const rgw_bucket
& _b
, const rgw_obj
& _obj
)
317 if (!tail_placement_rule
) {
318 manifest
->set_tail_placement(head_placement_rule
, _b
);
320 rgw_placement_rule new_tail_rule
= *tail_placement_rule
;
321 new_tail_rule
.inherit_from(head_placement_rule
);
322 manifest
->set_tail_placement(new_tail_rule
, _b
);
325 manifest
->set_head(head_placement_rule
, _obj
, 0);
328 if (manifest
->get_prefix().empty()) {
330 gen_rand_alphanumeric(cct
, buf
, sizeof(buf
) - 1);
332 string oid_prefix
= ".";
333 oid_prefix
.append(buf
);
334 oid_prefix
.append("_");
336 manifest
->set_prefix(oid_prefix
);
339 bool found
= manifest
->get_rule(0, &rule
);
341 derr
<< "ERROR: manifest->get_rule() could not find rule" << dendl
;
345 uint64_t head_size
= manifest
->get_head_size();
348 cur_stripe_size
= head_size
;
350 cur_stripe_size
= rule
.stripe_max_size
;
353 cur_part_id
= rule
.start_part_num
;
355 manifest
->get_implicit_location(cur_part_id
, cur_stripe
, 0, NULL
, &cur_obj
);
357 // Normal object which not generated through copy operation
358 manifest
->set_tail_instance(_obj
.key
.instance
);
360 manifest
->update_iterators();