From: Marcus Watts Date: Wed, 24 Jul 2019 00:43:38 +0000 (-0400) Subject: Fix bucket versioning vs. swift metadata bug. X-Git-Tag: v13.2.7~107^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=ca6aa3d841759b39cbf491bd0e5678b27e55509a;p=ceph.git Fix bucket versioning vs. swift metadata bug. When a bucket and object was "versioned", it was not possible to set swift metadata on an existing object. In swift, it is possible to post metadata (stored as extended attributes with specific names) on objects without bumping the version on a versioned object. In ceph, objects in versioned buckets *may* be versioned. Versioned objects have a "olh" (object logical header) header which points to the versioned header which contains or points to the current actual data for the object. Pre-existing logic here correctly sets the attributes for non-versioned objects. For versioned ojbects it incorrectly stored those attributes in the olh rather than in the versioned header. The corrected logic here retains the target object name and stores the attributes in the correct header for both cases rather than in the olh for the versioned object. Fixes: https://tracker.ceph.com/issues/37531 Signed-off-by: Marcus Watts (cherry picked from commit 70d5e211a3ce97daf4f62f9b57958899e7b65f01) Conflicts: src/rgw/rgw_op.cc - function calls take slightly different argument sets in mimic --- diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index 5400a6247972..544f72f778ec 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -278,12 +278,13 @@ static boost::optional get_iam_policy_from_attr(CephContext* cct, } } -static int get_obj_attrs(RGWRados *store, struct req_state *s, rgw_obj& obj, map& attrs) +static int get_obj_attrs(RGWRados *store, struct req_state *s, rgw_obj& obj, map& attrs, rgw_obj *target_obj = nullptr) { RGWRados::Object op_target(store, s->bucket_info, *static_cast(s->obj_ctx), obj); RGWRados::Object::Read read_op(&op_target); read_op.params.attrs = &attrs; + read_op.params.target_obj = target_obj; return read_op.prepare(); } @@ -4255,6 +4256,7 @@ void RGWPutMetadataObject::pre_exec() void RGWPutMetadataObject::execute() { rgw_obj obj(s->bucket, s->object); + rgw_obj target_obj; map attrs, orig_attrs, rmattrs; store->set_atomic(s->obj_ctx, obj); @@ -4270,7 +4272,7 @@ void RGWPutMetadataObject::execute() } /* check if obj exists, read orig attrs */ - op_ret = get_obj_attrs(store, s, obj, orig_attrs); + op_ret = get_obj_attrs(store, s, obj, orig_attrs, &target_obj); if (op_ret < 0) { return; } @@ -4295,7 +4297,8 @@ void RGWPutMetadataObject::execute() } } - op_ret = store->set_attrs(s->obj_ctx, s->bucket_info, obj, attrs, &rmattrs); + op_ret = store->set_attrs(s->obj_ctx, s->bucket_info, target_obj, + attrs, &rmattrs); } int RGWDeleteObj::handle_slo_manifest(bufferlist& bl) diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index 32db310a0c96..4c12d65318af 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -10217,6 +10217,9 @@ int RGWRados::Object::Read::prepare() if (r < 0) { return r; } + if (params.target_obj) { + *params.target_obj = state.obj; + } if (params.attrs) { *params.attrs = astate->attrset; if (cct->_conf->subsys.should_gather()) { diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h index a2cd710a2ebb..444b04ef12f5 100644 --- a/src/rgw/rgw_rados.h +++ b/src/rgw/rgw_rados.h @@ -2828,8 +2828,10 @@ public: ceph::real_time *lastmod; uint64_t *obj_size; map *attrs; + rgw_obj *target_obj; - Params() : lastmod(NULL), obj_size(NULL), attrs(NULL) {} + Params() : lastmod(nullptr), obj_size(nullptr), attrs(nullptr), + target_obj(nullptr) {} } params; explicit Read(RGWRados::Object *_source) : source(_source) {}