]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
Fix bucket versioning vs. swift metadata bug. 29240/head
authorMarcus Watts <mwatts@redhat.com>
Wed, 24 Jul 2019 00:43:38 +0000 (20:43 -0400)
committerMarcus Watts <mwatts@redhat.com>
Wed, 24 Jul 2019 00:43:38 +0000 (20:43 -0400)
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 <mwatts@redhat.com>
src/rgw/rgw_op.cc
src/rgw/rgw_rados.cc
src/rgw/rgw_rados.h

index 32971653f7c023ff74b517f3c95bf6a109eabb3f..6d72e63e4bc39f1ea5ce96d6701e2ff10b314058 100644 (file)
@@ -321,12 +321,13 @@ vector<Policy> 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<string, bufferlist>& attrs)
+static int get_obj_attrs(RGWRados *store, struct req_state *s, const rgw_obj& obj, map<string, bufferlist>& attrs, rgw_obj *target_obj = nullptr)
 {
   RGWRados::Object op_target(store, s->bucket_info, *static_cast<RGWObjectCtx *>(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(s->yield);
 }
@@ -4497,6 +4498,7 @@ void RGWPutMetadataObject::pre_exec()
 void RGWPutMetadataObject::execute()
 {
   rgw_obj obj(s->bucket, s->object);
+  rgw_obj target_obj;
   map<string, bufferlist> attrs, orig_attrs, rmattrs;
 
   store->set_atomic(s->obj_ctx, obj);
@@ -4512,7 +4514,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;
   }
@@ -4537,7 +4539,8 @@ void RGWPutMetadataObject::execute()
     }
   }
 
-  op_ret = store->set_attrs(s->obj_ctx, s->bucket_info, obj, attrs, &rmattrs, s->yield);
+  op_ret = store->set_attrs(s->obj_ctx, s->bucket_info, target_obj,
+    attrs, &rmattrs, s->yield);
 }
 
 int RGWDeleteObj::handle_slo_manifest(bufferlist& bl)
index 556aeda9503f656a7d25b531b75283a1d0f87b39..6ad79a8667e73a3f78e77c353cfab822171883dd 100644 (file)
@@ -6351,6 +6351,9 @@ int RGWRados::Object::Read::prepare(optional_yield y)
   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<ceph_subsys_rgw, 20>()) {
index 235dfab0a0954cb4fed2d02fa03836a0b3fdf73b..24df1102870c46ab4b75583f88b63e361004ba10 100644 (file)
@@ -1567,8 +1567,10 @@ public:
         ceph::real_time *lastmod;
         uint64_t *obj_size;
         map<string, bufferlist> *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) {}