From: lu.shasha Date: Fri, 12 May 2017 02:03:02 +0000 (+0800) Subject: rgw: fix SLO/DLO range requests X-Git-Tag: v12.1.0~25^2 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=9eec1b4ef953d9fda70b75500701506b4c00b593;p=ceph-ci.git rgw: fix SLO/DLO range requests Sending any SLO/DLO range requests will retrun InvalidRange error. SLO/DLO should call range_to_ofs after got object size instead of read_op.prepare() to deal with negative offsets. Signed-off-by: Shasha Lu --- diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index 4a0fe93bc4b..9ff3d05a057 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -1038,7 +1038,7 @@ static int iterate_user_manifest_parts(CephContext * const cct, uint64_t cur_total_len = obj_ofs; uint64_t start_ofs = 0, end_ofs = ent.meta.size; - if (!found_start && cur_total_len + ent.meta.size > (uint64_t)ofs) { + if ((ptotal_len || cb) && !found_start && cur_total_len + ent.meta.size > (uint64_t)ofs) { start_ofs = ofs - obj_ofs; found_start = true; } @@ -1049,7 +1049,7 @@ static int iterate_user_manifest_parts(CephContext * const cct, ent.meta.etag.length()); } - if (!found_end && obj_ofs > (uint64_t)end) { + if ((ptotal_len || cb) && !found_end && obj_ofs > (uint64_t)end) { end_ofs = end - cur_total_len + 1; found_end = true; } @@ -1237,13 +1237,26 @@ int RGWGetObj::handle_user_manifest(const char *prefix) * - overall DLO's content size, * - md5 sum of overall DLO's content (for etag of Swift API). */ int r = iterate_user_manifest_parts(s->cct, store, ofs, end, - pbucket_info, obj_prefix, bucket_acl, *bucket_policy, - &total_len, &s->obj_size, &lo_etag, + pbucket_info, obj_prefix, bucket_acl, *bucket_policy, + nullptr, &s->obj_size, &lo_etag, nullptr /* cb */, nullptr /* cb arg */); if (r < 0) { return r; } + r = RGWRados::Object::Read::range_to_ofs(s->obj_size, ofs, end); + if (r < 0) { + return r; + } + + r = iterate_user_manifest_parts(s->cct, store, ofs, end, + pbucket_info, obj_prefix, bucket_acl, *bucket_policy, + &total_len, nullptr, nullptr, + nullptr, nullptr); + if (r < 0) { + return r; + } + if (!get_data) { bufferlist bl; send_response_data(bl, 0, 0); @@ -1251,7 +1264,7 @@ int RGWGetObj::handle_user_manifest(const char *prefix) } r = iterate_user_manifest_parts(s->cct, store, ofs, end, - pbucket_info, obj_prefix, bucket_acl, *bucket_policy, + pbucket_info, obj_prefix, bucket_acl, *bucket_policy, nullptr, nullptr, nullptr, get_obj_user_manifest_iterate_cb, (void *)this); if (r < 0) { @@ -1382,17 +1395,14 @@ int RGWGetObj::handle_slo_manifest(bufferlist& bl) s->obj_size = slo_info.total_size; ldout(s->cct, 20) << "s->obj_size=" << s->obj_size << dendl; - if (ofs < 0) { - ofs = total_len - std::min(-ofs, static_cast(total_len)); - } - - if (end < 0 || end >= static_cast(total_len)) { - end = total_len - 1; + int r = RGWRados::Object::Read::range_to_ofs(total_len, ofs, end); + if (r < 0) { + return r; } total_len = end - ofs + 1; - int r = iterate_slo_parts(s->cct, store, ofs, end, slo_parts, + r = iterate_slo_parts(s->cct, store, ofs, end, slo_parts, get_obj_user_manifest_iterate_cb, (void *)this); if (r < 0) { return r; @@ -1549,17 +1559,6 @@ void RGWGetObj::execute() decompress.emplace(s->cct, &cs_info, partial_content, filter); filter = &*decompress; } - // for range requests with obj size 0 - if (range_str && !(s->obj_size)) { - total_len = 0; - op_ret = -ERANGE; - goto done_err; - } - - op_ret = read_op.range_to_ofs(s->obj_size, ofs, end); - if (op_ret < 0) - goto done_err; - total_len = (ofs <= end ? end + 1 - ofs : 0); attr_iter = attrs.find(RGW_ATTR_USER_MANIFEST); if (attr_iter != attrs.end() && !skip_manifest) { @@ -1584,6 +1583,18 @@ void RGWGetObj::execute() return; } + // for range requests with obj size 0 + if (range_str && !(s->obj_size)) { + total_len = 0; + op_ret = -ERANGE; + goto done_err; + } + + op_ret = read_op.range_to_ofs(s->obj_size, ofs, end); + if (op_ret < 0) + goto done_err; + total_len = (ofs <= end ? end + 1 - ofs : 0); + /* Check whether the object has expired. Swift API documentation * stands that we should return 404 Not Found in such case. */ if (need_object_expiration() && object_is_expired(attrs)) {