]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: convert plain object to versioned (with null version) when removing 8755/head
authorYehuda Sadeh <yehuda@redhat.com>
Wed, 23 Mar 2016 01:14:57 +0000 (18:14 -0700)
committerKarol Mroz <kmroz@suse.de>
Wed, 1 Jun 2016 20:03:52 +0000 (13:03 -0700)
Fixes #15243

When removing a plain null versioned object (was created prior to bucket versioning
enabled), need to convert the bucket index representation to a versioned one. This
is needed so that all the versioning mechanics play together.

Signed-off-by: Yehuda Sadeh <yehuda@redhat.com>
(cherry picked from commit c6334d430b17739fed2df2b4481ae395ef6568d9)

Conflicts:
        src/rgw/rgw_rados.cc
          - hammer is missing get_zone() API from which log_data can be
            obtained. Needed to fall back to zone_public_config
            structure in bucket_index_unlink_instance() definition.
          - olh_tag string parameter added to
            bucket_index_unlink_instance() definition.
        src/rgw/rgw_rados.h
          - olh_tag string parameter added to
            bucket_index_unlink_instance() declaration.

src/cls/rgw/cls_rgw.cc
src/cls/rgw/cls_rgw_client.cc
src/cls/rgw/cls_rgw_client.h
src/cls/rgw/cls_rgw_ops.h
src/rgw/rgw_rados.cc
src/rgw/rgw_rados.h

index 980884a9f099b678785f39e0f23e4af3b91eba00..a06b0d8342130684fd3c7b3b265353614dd77ab1 100644 (file)
@@ -1063,6 +1063,9 @@ public:
     initialized = true;
   }
 
+  void set_epoch(uint64_t epoch) {
+    instance_entry.versioned_epoch = epoch;
+  }
 
   int unlink_list_entry() {
     string list_idx;
@@ -1540,12 +1543,27 @@ static int rgw_bucket_unlink_instance(cls_method_context_t hctx, bufferlist *in,
     return ret;
   }
 
-  ret = olh.init(NULL);
+  bool olh_found;
+  ret = olh.init(&olh_found);
   if (ret < 0) {
     CLS_LOG(0, "ERROR: olh.init() returned ret=%d", ret);
     return ret;
   }
 
+  if (!olh_found) {
+    bool instance_only = false;
+    cls_rgw_obj_key key(dest_key.name);
+    ret = convert_plain_entry_to_versioned(hctx, key, true, instance_only);
+    if (ret < 0) {
+      CLS_LOG(0, "ERROR: convert_plain_entry_to_versioned ret=%d", ret);
+      return ret;
+    }
+    olh.update(dest_key, false);
+    olh.set_tag(op.olh_tag);
+
+    obj.set_epoch(1);
+  }
+
   if (!olh.start_modify(op.olh_epoch)) {
     ret = obj.unlink_list_entry();
     if (ret < 0) {
index e6ac56b822c3601ba731fdbaa7e50982ec9632e6..49bb840c2f980bb92a3d8b123875617a3c5b88b3 100644 (file)
@@ -310,13 +310,14 @@ int cls_rgw_bucket_link_olh(librados::IoCtx& io_ctx, const string& oid, const cl
 
 int cls_rgw_bucket_unlink_instance(librados::IoCtx& io_ctx, const string& oid,
                                    const cls_rgw_obj_key& key, const string& op_tag,
-                                   uint64_t olh_epoch, bool log_op)
+                                  const string& olh_tag, uint64_t olh_epoch, bool log_op)
 {
   bufferlist in, out;
   struct rgw_cls_unlink_instance_op call;
   call.key = key;
   call.op_tag = op_tag;
   call.olh_epoch = olh_epoch;
+  call.olh_tag = olh_tag;
   call.log_op = log_op;
   ::encode(call, in);
   int r = io_ctx.exec(oid, "rgw", "bucket_unlink_instance", in, out);
index ecec679192ed3b007ef9ca1ea1751a5435c745bd..a3555e7944185904059bd2c6efe5f9760dc406b1 100644 (file)
@@ -329,7 +329,7 @@ int cls_rgw_bucket_link_olh(librados::IoCtx& io_ctx, const string& oid, const cl
                             bool delete_marker, const string& op_tag, struct rgw_bucket_dir_entry_meta *meta,
                             uint64_t olh_epoch, bool log_op);
 int cls_rgw_bucket_unlink_instance(librados::IoCtx& io_ctx, const string& oid, const cls_rgw_obj_key& key, const string& op_tag,
-                                   uint64_t olh_epoch, bool log_op);
+                                  const string& olh_tag, uint64_t olh_epoch, bool log_op);
 int cls_rgw_get_olh_log(librados::IoCtx& io_ctx, string& oid, librados::ObjectReadOperation& op, const cls_rgw_obj_key& olh, uint64_t ver_marker,
                         const string& olh_tag,
                         map<uint64_t, vector<struct rgw_bucket_olh_log_entry> > *log, bool *is_truncated);
index 0a0686fbccb16cb92082540ed7021a4ad1242532..dece239f3f39f3318a9a9e407b8163573d17c8b0 100644 (file)
@@ -204,26 +204,31 @@ struct rgw_cls_unlink_instance_op {
   uint64_t olh_epoch;
   bool log_op;
   uint16_t bilog_flags;
+  string olh_tag;
 
   rgw_cls_unlink_instance_op() : olh_epoch(0), log_op(false), bilog_flags(0) {}
 
   void encode(bufferlist& bl) const {
-    ENCODE_START(1, 1, bl);
+    ENCODE_START(2, 1, bl);
     ::encode(key, bl);
     ::encode(op_tag, bl);
     ::encode(olh_epoch, bl);
     ::encode(log_op, bl);
     ::encode(bilog_flags, bl);
+    ::encode(olh_tag, bl);
     ENCODE_FINISH(bl);
   }
 
   void decode(bufferlist::iterator& bl) {
-    DECODE_START(1, bl);
+    DECODE_START(2, bl);
     ::decode(key, bl);
     ::decode(op_tag, bl);
     ::decode(olh_epoch, bl);
     ::decode(log_op, bl);
     ::decode(bilog_flags, bl);
+    if (struct_v >= 2) {
+      ::decode(olh_tag, bl);
+    }
     DECODE_FINISH(bl);
   }
 
index 91f7ce1e0e28e5b506db5d36100b37e731e6335e..654e6278a9fc2069d93760b42cfb5a4dbfe654a5 100644 (file)
@@ -6479,7 +6479,7 @@ void RGWRados::bucket_index_guard_olh_op(RGWObjState& olh_state, ObjectOperation
   op.cmpxattr(RGW_ATTR_OLH_ID_TAG, CEPH_OSD_CMPXATTR_OP_EQ, olh_state.olh_tag);
 }
 
-int RGWRados::bucket_index_unlink_instance(rgw_obj& obj_instance, const string& op_tag, uint64_t olh_epoch)
+int RGWRados::bucket_index_unlink_instance(rgw_obj& obj_instance, const string& op_tag, const string& olh_tag, uint64_t olh_epoch)
 {
   rgw_rados_ref ref;
   rgw_bucket bucket;
@@ -6496,7 +6496,7 @@ int RGWRados::bucket_index_unlink_instance(rgw_obj& obj_instance, const string&
   }
 
   cls_rgw_obj_key key(obj_instance.get_index_key_name(), obj_instance.get_instance());
-  ret = cls_rgw_bucket_unlink_instance(bs.index_ctx, bs.bucket_obj, key, op_tag, olh_epoch, zone_public_config.log_data);
+  ret = cls_rgw_bucket_unlink_instance(bs.index_ctx, bs.bucket_obj, key, op_tag, olh_tag, olh_epoch, zone_public_config.log_data);
   if (ret < 0) {
     return ret;
   }
@@ -6837,7 +6837,9 @@ int RGWRados::unlink_obj_instance(RGWObjectCtx& obj_ctx, RGWBucketInfo& bucket_i
       return ret;
     }
 
-    ret = bucket_index_unlink_instance(target_obj, op_tag, olh_epoch);
+    string olh_tag(state->olh_tag.c_str(), state->olh_tag.length());
+
+    ret = bucket_index_unlink_instance(target_obj, op_tag, olh_tag, olh_epoch);
     if (ret < 0) {
       ldout(cct, 20) << "bucket_index_link_olh() target_obj=" << target_obj << " returned " << ret << dendl;
       if (ret == -ECANCELED) {
index 38d7c29f71a82302636e5c1f26b023125aa276e1..911ac387bfecb1dc2783f8f3126552804c735fe4 100644 (file)
@@ -1945,7 +1945,7 @@ public:
   int bucket_index_link_olh(RGWObjState& olh_state, rgw_obj& obj_instance, bool delete_marker,
                             const string& op_tag, struct rgw_bucket_dir_entry_meta *meta,
                             uint64_t olh_epoch);
-  int bucket_index_unlink_instance(rgw_obj& obj_instance, const string& op_tag, uint64_t olh_epoch);
+  int bucket_index_unlink_instance(rgw_obj& obj_instance, const string& op_tag, const string& olh_tag, uint64_t olh_epoch);
   int bucket_index_read_olh_log(RGWObjState& state, rgw_obj& obj_instance, uint64_t ver_marker,
                                 map<uint64_t, vector<rgw_bucket_olh_log_entry> > *log, bool *is_truncated);
   int bucket_index_trim_olh_log(RGWObjState& obj_state, rgw_obj& obj_instance, uint64_t ver);