]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw, cls_rgw: multiple changes related to obj removal
authorYehuda Sadeh <yehuda@redhat.com>
Tue, 28 Oct 2014 00:09:57 +0000 (17:09 -0700)
committerYehuda Sadeh <yehuda@redhat.com>
Mon, 19 Jan 2015 23:57:48 +0000 (15:57 -0800)
Signed-off-by: Yehuda Sadeh <yehuda@redhat.com>
src/cls/rgw/cls_rgw.cc
src/rgw/rgw_common.h
src/rgw/rgw_op.cc
src/rgw/rgw_rados.cc
src/rgw/rgw_rados.h

index d57281286144e9fc1d02f07e81a42b5118bcb36d..787514fbf9f212fe35438f70a015fe1409c19c53 100644 (file)
@@ -1013,23 +1013,31 @@ static void update_olh_log(struct rgw_bucket_olh_entry& olh_data_entry, OLHLogOp
   log_entry.delete_marker = delete_marker;
 }
 
+static string escape_str(const string& s)
+{
+   int len = escape_json_attr_len(s.c_str(), s.size());
+   char escaped[len];
+   escape_json_attr(s.c_str(), s.size(), escaped);
+   return string(escaped);
+}
+
 /*
  * write object instance entry, and if needed also the list entry
  */
 static int write_obj_entries(cls_method_context_t hctx, struct rgw_bucket_dir_entry& instance_entry, const string& instance_idx)
 {
-  CLS_LOG(20, "write_entry() instance=%s idx=%s flags=%d", instance_entry.key.instance.c_str(), instance_idx.c_str(), instance_entry.flags);
+  CLS_LOG(20, "write_entry() instance=%s idx=%s flags=%d", escape_str(instance_entry.key.instance).c_str(), instance_idx.c_str(), instance_entry.flags);
   /* write the instance entry */
   int ret = write_entry(hctx, instance_entry, instance_idx);
   if (ret < 0) {
-    CLS_LOG(0, "ERROR: write_entry() instance_key=%s ret=%d", instance_idx.c_str(), ret);
+    CLS_LOG(0, "ERROR: write_entry() instance_key=%s ret=%d", escape_str(instance_idx).c_str(), ret);
     return ret;
   }
   string instance_list_idx;
   get_list_index_key(instance_entry, &instance_list_idx);
 
   if (instance_idx != instance_list_idx) {
-    CLS_LOG(20, "write_entry() idx=%s flags=%d", instance_list_idx.c_str(), instance_entry.flags);
+    CLS_LOG(20, "write_entry() idx=%s flags=%d", escape_str(instance_list_idx).c_str(), instance_entry.flags);
     /* write a new list entry for the object instance */
     ret = write_entry(hctx, instance_entry, instance_list_idx);
     if (ret < 0) {
@@ -1078,6 +1086,7 @@ public:
     string list_idx;
     /* this instance has a previous list entry, remove that entry */
     get_list_index_key(instance_entry, &list_idx);
+    CLS_LOG(20, "unlink_list_entry() list_idx=%s", escape_str(list_idx).c_str());
     int ret = cls_cxx_map_remove_key(hctx, list_idx);
     if (ret < 0) {
       CLS_LOG(0, "ERROR: cls_cxx_map_remove_key() list_idx=%s ret=%d", list_idx.c_str(), ret);
@@ -1109,6 +1118,7 @@ public:
 
   int set_current(uint64_t epoch) {
     if (instance_entry.ver.epoch > 0) {
+      CLS_LOG(20, "%s(): instance_entry.ver.epoch=%d epoch=%d", __func__, (int)instance_entry.ver.epoch, (int)epoch);
       /* this instance has a previous list entry, remove that entry */
       int ret = unlink_list_entry();
       if (ret < 0) {
@@ -1263,6 +1273,7 @@ static int convert_plain_entry_to_versioned(cls_method_context_t hctx, cls_rgw_o
     }
   }
 
+  entry.key = key;
   entry.flags = RGW_BUCKET_DIRENT_FLAG_VER_MARKER;
   ret = write_entry(hctx, entry, key.name);
   if (ret < 0) {
@@ -1304,19 +1315,22 @@ static int rgw_bucket_link_olh(cls_method_context_t hctx, bufferlist *in, buffer
   BIOLHEntry olh(hctx, op.key);
 
   /* read instance entry */
-  if (!op.delete_marker) {
-    int ret = obj.init();
-    if (ret < 0) {
-      return ret;
-    }
-  } else {
-    /* a deletion marker, need to initialize it, there's no instance entry for it yet */
+  int ret = obj.init();
+  if (ret == -ENOENT && op.delete_marker) {
+    ret = 0;
+  }
+  if (ret < 0) {
+    return ret;
+  }
+
+  if (op.delete_marker) {
+    /* a deletion marker, need to initialize entry as such */
     obj.init_as_delete_marker();
   }
 
   /* read olh */
   bool olh_found;
-  int ret = olh.init(&olh_found);
+  ret = olh.init(&olh_found);
   if (ret < 0) {
     return ret;
   }
@@ -1375,8 +1389,13 @@ static int rgw_bucket_unlink_instance(cls_method_context_t hctx, bufferlist *in,
     return -EINVAL;
   }
 
-  BIVerObjEntry obj(hctx, op.key);
-  BIOLHEntry olh(hctx, op.key);
+  cls_rgw_obj_key dest_key = op.key;
+  if (dest_key.instance == "null") {
+    dest_key.instance.clear();
+  }
+
+  BIVerObjEntry obj(hctx, dest_key);
+  BIOLHEntry olh(hctx, dest_key);
 
   int ret = obj.init();
   if (ret == -ENOENT) {
@@ -1393,7 +1412,7 @@ static int rgw_bucket_unlink_instance(cls_method_context_t hctx, bufferlist *in,
     return ret;
   }
 
-  if (olh.get_entry().key == op.key) {
+  if (olh.get_entry().key == dest_key) {
     /* this is the current head, need to update! */
     cls_rgw_obj_key next_key;
     bool found;
@@ -1799,6 +1818,8 @@ static int list_plain_entries(cls_method_context_t hctx, const string& name, con
         return -EIO;
       }
 
+      CLS_LOG(20, "%s(): entry.idx=%s e.key.name=%s", __func__, escape_str(entry.idx).c_str(), escape_str(e.key.name).c_str());
+
       if (e.key.name != name) {
         return count;
       }
@@ -1812,14 +1833,6 @@ static int list_plain_entries(cls_method_context_t hctx, const string& name, con
   return count;
 }
 
-static string escape_str(const string& s)
-{
-   int len = escape_json_attr_len(s.c_str(), s.size());
-   char escaped[len];
-   escape_json_attr(s.c_str(), s.size(), escaped);
-   return string(escaped);
-}
-
 static int list_instance_entries(cls_method_context_t hctx, const string& name, const string& marker, uint32_t max,
                                  list<rgw_cls_bi_entry> *entries)
 {
index 578526e417f59c37e0e842e65bcb83163607751e..a2c9b0a7d822aad2c3896e388317465ab54ea79c 100644 (file)
@@ -785,7 +785,8 @@ struct RGWBucketInfo
   void decode_json(JSONObj *obj);
 
   bool versioned() { return (flags & BUCKET_VERSIONED) != 0; }
-  bool versioning_enabled() { return (flags & (BUCKET_VERSIONED | BUCKET_VERSIONS_SUSPENDED)) == BUCKET_VERSIONED; }
+  int versioning_status() { return flags & (BUCKET_VERSIONED | BUCKET_VERSIONS_SUSPENDED); }
+  bool versioning_enabled() { return versioning_status() == BUCKET_VERSIONED; }
 
   RGWBucketInfo() : flags(0), creation_time(0), has_instance_obj(false) {}
 };
@@ -1172,11 +1173,15 @@ public:
     loc.clear();
   }
 
+  bool have_instance() {
+    return !instance.empty() && instance != "null";
+  }
+
   void set_obj(const string& o) {
     object.reserve(128);
 
     orig_obj = o;
-    if (ns.empty() && instance.empty()) {
+    if (ns.empty() && !have_instance()) {
       if (o.empty()) {
         return;
       }
@@ -1189,7 +1194,7 @@ public:
     } else {
       object = "_";
       object.append(ns);
-      if (!instance.empty()) {
+      if (have_instance()) {
         object.append(string(":") + instance);
       }
       object.append("_");
index f1ac63d942775f319c7b7324e3b3794b5eaa56ae..670f20bc020fb78c52918ea82b0e5984e55dd362 100644 (file)
@@ -2111,7 +2111,7 @@ void RGWDeleteObj::execute()
 
     obj_ctx->set_atomic(obj);
 
-    ret = store->delete_obj(*obj_ctx, s->bucket_owner.get_id(), obj, s->bucket_info.versioning_enabled());
+    ret = store->delete_obj(*obj_ctx, s->bucket_owner.get_id(), obj, s->bucket_info.versioning_status());
   }
 }
 
@@ -2972,7 +2972,7 @@ void RGWCompleteMultipart::execute()
   }
 
   // remove the upload obj
-  int r = store->delete_obj(*(RGWObjectCtx *)s->obj_ctx, s->bucket_owner.get_id(), meta_obj, false);
+  int r = store->delete_obj(*(RGWObjectCtx *)s->obj_ctx, s->bucket_owner.get_id(), meta_obj, 0);
   if (r < 0) {
     ldout(store->ctx(), 0) << "WARNING: failed to remove object " << meta_obj << dendl;
   }
@@ -3032,7 +3032,7 @@ void RGWAbortMultipart::execute()
         string oid = mp.get_part(obj_iter->second.num);
         rgw_obj obj;
         obj.init_ns(s->bucket, oid, mp_ns);
-        ret = store->delete_obj(*obj_ctx, owner, obj, false);
+        ret = store->delete_obj(*obj_ctx, owner, obj, 0);
         if (ret < 0 && ret != -ENOENT)
           return;
       } else {
@@ -3040,7 +3040,7 @@ void RGWAbortMultipart::execute()
         RGWObjManifest::obj_iterator oiter;
         for (oiter = manifest.obj_begin(); oiter != manifest.obj_end(); ++oiter) {
           rgw_obj loc = oiter.get_location();
-          ret = store->delete_obj(*obj_ctx, owner, loc, false);
+          ret = store->delete_obj(*obj_ctx, owner, loc, 0);
           if (ret < 0 && ret != -ENOENT)
             return;
         }
@@ -3051,7 +3051,7 @@ void RGWAbortMultipart::execute()
   // and also remove the metadata obj
   meta_obj.init_ns(s->bucket, meta_oid, mp_ns);
   meta_obj.set_in_extra_data(true);
-  ret = store->delete_obj(*obj_ctx, owner, meta_obj, false);
+  ret = store->delete_obj(*obj_ctx, owner, meta_obj, 0);
   if (ret == -ENOENT) {
     ret = -ERR_NO_SUCH_BUCKET;
   }
@@ -3213,7 +3213,7 @@ void RGWDeleteMultiObj::execute()
     rgw_obj obj(bucket,(*iter));
 
     obj_ctx->set_atomic(obj);
-    ret = store->delete_obj(*obj_ctx, s->bucket_owner.get_id(), obj, s->bucket_info.versioning_enabled());
+    ret = store->delete_obj(*obj_ctx, s->bucket_owner.get_id(), obj, s->bucket_info.versioning_status());
     if (ret == -ENOENT) {
       ret = 0;
     }
index 89ee71386fd59e42fb150a700d95f1480eb3b944..cbb800fb457ad39850ce3b8ae61f7ad3df5a908a 100644 (file)
@@ -3922,10 +3922,12 @@ int RGWRados::Object::Delete::delete_obj()
   RGWRados *store = target->get_store();
   rgw_obj& obj = target->get_obj();
 
-  if (params.use_versioning) {
+  if (params.versioning_status & BUCKET_VERSIONED) {
     if (obj.get_instance().empty()) {
       rgw_obj marker = obj;
-      store->gen_rand_obj_instance_name(&marker);
+      if ((params.versioning_status & BUCKET_VERSIONS_SUSPENDED) == 0) {
+        store->gen_rand_obj_instance_name(&marker);
+      }
 
       int r = store->set_olh(target->get_ctx(), params.bucket_owner, marker, true);
       if (r < 0) {
@@ -3998,17 +4000,6 @@ int RGWRados::Object::Delete::delete_obj()
   if (r < 0)
     return r;
 
-  /* need to insert a delete marker? */
-  if (params.use_versioning && obj.get_instance().empty()) {
-    rgw_obj marker = obj;
-    store->gen_rand_obj_instance_name(&marker);
-
-    r = store->set_olh(target->get_ctx(), params.bucket_owner, marker, true);
-    if (r < 0) {
-      return r;
-    }
-  }
-
   if (ret_not_existed)
     return -ENOENT;
 
@@ -4020,13 +4011,13 @@ int RGWRados::Object::Delete::delete_obj()
   return 0;
 }
 
-int RGWRados::delete_obj(RGWObjectCtx& obj_ctx, const string& bucket_owner, rgw_obj& obj, bool use_versioning)
+int RGWRados::delete_obj(RGWObjectCtx& obj_ctx, const string& bucket_owner, rgw_obj& obj, int versioning_status)
 {
   RGWRados::Object del_target(this, obj_ctx, obj);
   RGWRados::Object::Delete del_op(&del_target);
 
   del_op.params.bucket_owner = bucket_owner;
-  del_op.params.use_versioning = use_versioning;
+  del_op.params.versioning_status = versioning_status;
 
   return del_op.delete_obj();
 }
@@ -5668,7 +5659,7 @@ int RGWRados::apply_olh_log(RGWObjectCtx& obj_ctx, const string& bucket_owner, r
     cls_rgw_obj_key& key = *liter;
     rgw_obj obj_instance(bucket, key.name);
     obj_instance.set_instance(key.instance);
-    int ret = delete_obj(obj_ctx, bucket_owner, obj_instance, false);
+    int ret = delete_obj(obj_ctx, bucket_owner, obj_instance, 0);
     if (ret < 0 && ret != -ENOENT) {
       ldout(cct, 0) << "ERROR: delete_obj() returned " << ret << " obj_instance=" << obj_instance << dendl;
       return ret;
index f57681643e3e77c8329a137276bf70aa36821441..f096475d91f9947c885d75e16f1afe0c08fc2515 100644 (file)
@@ -1452,9 +1452,9 @@ public:
 
       struct DeleteParams {
         string bucket_owner;
-        bool use_versioning;
+        int versioning_status;
 
-        DeleteParams() : use_versioning(false) {}
+        DeleteParams() : versioning_status(0) {}
       } params;
       
       Delete(RGWRados::Object *_target) : target(_target) {}
@@ -1602,7 +1602,7 @@ public:
   int bucket_suspended(rgw_bucket& bucket, bool *suspended);
 
   /** Delete an object.*/
-  virtual int delete_obj(RGWObjectCtx& obj_ctx, const string& bucket_owner, rgw_obj& src_obj, bool use_versioning);
+  virtual int delete_obj(RGWObjectCtx& obj_ctx, const string& bucket_owner, rgw_obj& src_obj, int versioning_status);
 
   /* Delete a system object */
   virtual int delete_system_obj(rgw_obj& src_obj, RGWObjVersionTracker *objv_tracker = NULL);