]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
Fix bucket versioning vs. swift metadata bug. 30140/head
authorMarcus Watts <mwatts@redhat.com>
Wed, 24 Jul 2019 00:43:38 +0000 (20:43 -0400)
committerNathan Cutler <ncutler@suse.com>
Wed, 4 Sep 2019 13:09:00 +0000 (15:09 +0200)
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>
(cherry picked from commit 70d5e211a3ce97daf4f62f9b57958899e7b65f01)

Conflicts:
src/rgw/rgw_op.cc
- function calls take slightly different argument sets in mimic

src/rgw/rgw_op.cc
src/rgw/rgw_rados.cc
src/rgw/rgw_rados.h

index 5400a6247972d3a8fd0ee1788184dc0f7a30b09a..544f72f778ecca6ef0fecc044aedfe768823a461 100644 (file)
@@ -278,12 +278,13 @@ static boost::optional<Policy> get_iam_policy_from_attr(CephContext* cct,
   }
 }
 
-static int get_obj_attrs(RGWRados *store, struct req_state *s, rgw_obj& obj, map<string, bufferlist>& attrs)
+static int get_obj_attrs(RGWRados *store, struct req_state *s, 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();
 }
@@ -4255,6 +4256,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);
@@ -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)
index 32db310a0c96e4735610ef7a14c2c5c743844e8d..4c12d65318afe53cf78ec79a4ecc4d10902fa5e4 100644 (file)
@@ -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<ceph_subsys_rgw, 20>()) {
index a2cd710a2ebbed27bdb80cbf54ac463288d6bc71..444b04ef12f5646f7111b77e578dee02cd18da16 100644 (file)
@@ -2828,8 +2828,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) {}