]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
Fix bucket versioning vs. swift metadata bug. 29961/head
authorMarcus Watts <mwatts@redhat.com>
Wed, 24 Jul 2019 00:43:38 +0000 (20:43 -0400)
committerNathan Cutler <ncutler@suse.com>
Wed, 28 Aug 2019 14:38:42 +0000 (16:38 +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
- in master, the store->set_attrs() method takes an argument, s->yield, that is
  not applicable to nautilus

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

index 645a29f99c8a89e665838f6e76ba6ac32700ba5f..c8bfa5867dd197c0e853b184d4a3a0fcad3a7cfb 100644 (file)
@@ -320,12 +320,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();
 }
@@ -4378,6 +4379,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);
@@ -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)
index bdea1249c96c83cde43e44dc2893e6d9cd00a018..bb24e5f9b4d4fc72a504fb2ab6f94ca4b4824652 100644 (file)
@@ -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<ceph_subsys_rgw, 20>()) {
index 78f28fa0749b1590f420889ce66779ea20c3da16..b5eaaa4ad49a92e3f990472046b2c8dd7a39dcfe 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) {}