From: Marcus Watts Date: Wed, 24 Jul 2019 00:43:38 +0000 (-0400) Subject: Fix bucket versioning vs. swift metadata bug. X-Git-Tag: v14.2.5~90^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=9cc43d75d12a0183ff6484cea2b7f065c3c5c72c;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 - in master, the store->set_attrs() method takes an argument, s->yield, that is not applicable to nautilus --- diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index 645a29f99c8a..c8bfa5867dd1 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -320,12 +320,13 @@ vector get_iam_user_policy_from_attr(CephContext* cct, return policies; } -static int get_obj_attrs(RGWRados *store, struct req_state *s, const rgw_obj& obj, map& attrs) +static int get_obj_attrs(RGWRados *store, struct req_state *s, const 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(); } @@ -4378,6 +4379,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); @@ -4393,7 +4395,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; } @@ -4418,7 +4420,7 @@ 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 bdea1249c96c..bb24e5f9b4d4 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -6305,6 +6305,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 78f28fa0749b..b5eaaa4ad49a 100644 --- a/src/rgw/rgw_rados.h +++ b/src/rgw/rgw_rados.h @@ -1567,8 +1567,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) {}