From: Yehuda Sadeh Date: Wed, 5 Nov 2014 21:28:02 +0000 (-0800) Subject: rgw: send back ETag on S3 object copy X-Git-Tag: v0.80.9~22^2~6 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=8682d1b15e097ececd927dfbd096dbb46403afca;p=ceph.git rgw: send back ETag on S3 object copy Fixes: #9479 Backport: firefly, giant We didn't send the etag back correctly. Original code assumed the etag resided in the attrs, but attrs only contained request attrs. Signed-off-by: Yehuda Sadeh (cherry picked from commit b1bfc3a7e0c9088f01f8ff770ae14f569fbc570d) Conflicts: src/rgw/rgw_rados.cc --- diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index 457791fac3101..0d4f2deaeb8f6 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -2208,6 +2208,7 @@ void RGWCopyObj::execute() replace_attrs, attrs, RGW_OBJ_CATEGORY_MAIN, &s->req_id, /* use req_id as tag */ + &etag, &s->err, copy_obj_progress_cb, (void *)this ); diff --git a/src/rgw/rgw_op.h b/src/rgw/rgw_op.h index b141ed5bd1bcd..f48ffdc15527c 100644 --- a/src/rgw/rgw_op.h +++ b/src/rgw/rgw_op.h @@ -490,6 +490,7 @@ protected: string source_zone; string client_id; string op_id; + string etag; off_t last_ofs; diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index 62d44aad66931..eb9bf99e0668b 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -3141,6 +3141,7 @@ int RGWRados::copy_obj(void *ctx, map& attrs, RGWObjCategory category, string *ptag, + string *petag, struct rgw_err *err, void (*progress_cb)(off_t, void *), void *progress_data) @@ -3237,6 +3238,10 @@ int RGWRados::copy_obj(void *ctx, if (ret < 0) goto set_err_state; + if (petag) { + *petag = etag; + } + { /* opening scope so that we can do goto, sorry */ bufferlist& extra_data_bl = processor.get_extra_data(); if (extra_data_bl.length()) { @@ -3302,6 +3307,10 @@ set_err_state: if (ret < 0) return ret; + if (petag) { + *petag = etag; + } + return 0; } @@ -3331,7 +3340,7 @@ set_err_state: } if (copy_data) { /* refcounting tail wouldn't work here, just copy the data */ - return copy_obj_data(ctx, dest_bucket_info.owner, &handle, end, dest_obj, src_obj, max_chunk_size, mtime, src_attrs, category, ptag, err); + return copy_obj_data(ctx, dest_bucket_info.owner, &handle, end, dest_obj, src_obj, max_chunk_size, mtime, src_attrs, category, ptag, petag, err); } RGWObjManifest::obj_iterator miter = astate->manifest.obj_begin(); @@ -3410,6 +3419,14 @@ set_err_state: if (mtime) obj_stat(ctx, dest_obj, NULL, mtime, NULL, NULL, NULL, NULL); + if (petag) { + map::iterator iter = src_attrs.find(RGW_ATTR_ETAG); + if (iter != src_attrs.end()) { + bufferlist& etagbl = iter->second; + *petag = string(etagbl.c_str(), etagbl.length()); + } + } + return 0; done_ret: @@ -3446,6 +3463,7 @@ int RGWRados::copy_obj_data(void *ctx, map& attrs, RGWObjCategory category, string *ptag, + string *petag, struct rgw_err *err) { bufferlist first_chunk; @@ -3492,6 +3510,9 @@ int RGWRados::copy_obj_data(void *ctx, if (iter != attrs.end()) { bufferlist& bl = iter->second; etag = string(bl.c_str(), bl.length()); + if (petag) { + *petag = etag; + } } ret = processor.complete(etag, NULL, 0, attrs); diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h index 9aefe1efee98e..ff161b837a76a 100644 --- a/src/rgw/rgw_rados.h +++ b/src/rgw/rgw_rados.h @@ -1566,6 +1566,7 @@ public: map& attrs, RGWObjCategory category, string *ptag, + string *petag, struct rgw_err *err, void (*progress_cb)(off_t, void *), void *progress_data); @@ -1580,6 +1581,7 @@ public: map& attrs, RGWObjCategory category, string *ptag, + string *petag, struct rgw_err *err); /** * Delete a bucket. diff --git a/src/rgw/rgw_rest_s3.cc b/src/rgw/rgw_rest_s3.cc index bc6305e8ce443..68b379fbb068e 100644 --- a/src/rgw/rgw_rest_s3.cc +++ b/src/rgw/rgw_rest_s3.cc @@ -1285,13 +1285,8 @@ void RGWCopyObj_ObjStore_S3::send_response() if (ret == 0) { dump_time(s, "LastModified", &mtime); - map::iterator iter = attrs.find(RGW_ATTR_ETAG); - if (iter != attrs.end()) { - bufferlist& bl = iter->second; - if (bl.length()) { - char *etag = bl.c_str(); - s->formatter->dump_string("ETag", etag); - } + if (!etag.empty()) { + s->formatter->dump_string("ETag", etag); } s->formatter->close_section(); rgw_flush_formatter_and_reset(s, s->formatter);