From: Radoslaw Zarzynski Date: Tue, 23 Feb 2016 17:46:44 +0000 (+0100) Subject: rgw: culculate etag for DLOs of Swift API. X-Git-Tag: v10.1.0~232^2~5 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=c27d27924d126da864c4acd373230801a44ddebf;p=ceph.git rgw: culculate etag for DLOs of Swift API. Signed-off-by: Radoslaw Zarzynski --- diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index df884086ec02..f9b05bd39e57 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -702,6 +702,7 @@ static int iterate_user_manifest_parts(CephContext * const cct, RGWAccessControlPolicy * const bucket_policy, uint64_t * const ptotal_len, uint64_t * const pobj_size, + string * const pobj_sum, int (*cb)(rgw_bucket& bucket, const RGWObjEnt& ent, RGWAccessControlPolicy * const bucket_policy, @@ -724,16 +725,15 @@ static int iterate_user_manifest_parts(CephContext * const cct, list_op.params.prefix = obj_prefix; list_op.params.delim = delim; + MD5 etag_sum; do { #define MAX_LIST_OBJS 100 int r = list_op.list_objects(MAX_LIST_OBJS, &objs, NULL, &is_truncated); - if (r < 0) + if (r < 0) { return r; + } - vector::iterator viter; - - for (viter = objs.begin(); viter != objs.end(); ++viter) { - RGWObjEnt& ent = *viter; + for (RGWObjEnt& ent : objs) { uint64_t cur_total_len = obj_ofs; uint64_t start_ofs = 0, end_ofs = ent.size; @@ -743,6 +743,10 @@ static int iterate_user_manifest_parts(CephContext * const cct, } obj_ofs += ent.size; + if (pobj_sum) { + etag_sum.Update((const byte *)ent.etag.c_str(), + ent.etag.length()); + } if (!found_end && obj_ofs > (uint64_t)end) { end_ofs = end - cur_total_len + 1; @@ -774,6 +778,9 @@ static int iterate_user_manifest_parts(CephContext * const cct, if (pobj_size) { *pobj_size = obj_ofs; } + if (pobj_sum) { + complete_etag(etag_sum, pobj_sum); + } return 0; } @@ -917,10 +924,14 @@ int RGWGetObj::handle_user_manifest(const char *prefix) bucket_policy = s->bucket_acl; } - /* dry run to find out total length */ + /* dry run to find out: + * - total length (of the parts we are going to send to client), + * - 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, - bucket, obj_prefix, bucket_policy, &total_len, &s->obj_size, - NULL, NULL); + bucket, obj_prefix, bucket_policy, + &total_len, &s->obj_size, &lo_etag, + nullptr /* cb */, nullptr /* cb arg */); if (r < 0) { return r; } @@ -932,7 +943,8 @@ int RGWGetObj::handle_user_manifest(const char *prefix) } r = iterate_user_manifest_parts(s->cct, store, ofs, end, - bucket, obj_prefix, bucket_policy, NULL, NULL, + bucket, obj_prefix, bucket_policy, + nullptr, nullptr, nullptr, get_obj_user_manifest_iterate_cb, (void *)this); if (r < 0) { return r; diff --git a/src/rgw/rgw_op.h b/src/rgw/rgw_op.h index 398534d582bd..1f511b93bfd1 100644 --- a/src/rgw/rgw_op.h +++ b/src/rgw/rgw_op.h @@ -160,6 +160,7 @@ protected: rgw_obj obj; utime_t gc_invalidate_time; bool is_slo; + string lo_etag; int init_common(); public: diff --git a/src/rgw/rgw_rest_swift.cc b/src/rgw/rgw_rest_swift.cc index dda1f173a878..49aa79e62f73 100644 --- a/src/rgw/rgw_rest_swift.cc +++ b/src/rgw/rgw_rest_swift.cc @@ -1012,8 +1012,9 @@ int RGWGetObj_ObjStore_SWIFT::send_response_data_error() return send_response_data(bl, 0, 0); } -int RGWGetObj_ObjStore_SWIFT::send_response_data(bufferlist& bl, off_t bl_ofs, - off_t bl_len) +int RGWGetObj_ObjStore_SWIFT::send_response_data(bufferlist& bl, + const off_t bl_ofs, + const off_t bl_len) { string content_type; @@ -1041,12 +1042,16 @@ int RGWGetObj_ObjStore_SWIFT::send_response_data(bufferlist& bl, off_t bl_ofs, } if (! op_ret) { - map::iterator iter = attrs.find(RGW_ATTR_ETAG); - if (iter != attrs.end()) { - bufferlist& bl = iter->second; - if (bl.length()) { - char *etag = bl.c_str(); - dump_etag(s, etag); + if (!lo_etag.empty()) { + dump_etag(s, ("\"" + lo_etag + "\"").c_str()); + } else { + auto iter = attrs.find(RGW_ATTR_ETAG); + if (iter != attrs.end()) { + bufferlist& bl = iter->second; + if (bl.length()) { + char *etag = bl.c_str(); + dump_etag(s, etag); + } } }