]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: use gc for multipart abort 3323/head
authorYehuda Sadeh <yehuda@redhat.com>
Thu, 8 Jan 2015 20:48:47 +0000 (12:48 -0800)
committerYehuda Sadeh <yehuda@redhat.com>
Thu, 8 Jan 2015 21:09:03 +0000 (13:09 -0800)
Fixes: #10445
Instead of chewing through a potentially very large list of objects
synchronously, leave it to the garbage collector.

Reported-by: Aaron Bassett <aaron@five3genomics.com>
Signed-off-by: Yehuda Sadeh <yehuda@redhat.com>
src/rgw/rgw_op.cc
src/rgw/rgw_rados.cc
src/rgw/rgw_rados.h

index 0319a56982da4500189f715bc8260ffedc7f9c76..4868fe90308ebd9f51a76511818124d0e6ad2769 100644 (file)
@@ -2873,6 +2873,11 @@ void RGWAbortMultipart::execute()
   int marker = 0;
   int max_parts = 1000;
 
+  meta_obj.init_ns(s->bucket, meta_oid, mp_ns);
+  meta_obj.set_in_extra_data(true);
+
+  cls_rgw_obj_chain chain;
+
   do {
     ret = list_multipart_parts(store, s, upload_id, meta_oid, max_parts, marker, obj_parts, &marker, &truncated);
     if (ret < 0)
@@ -2889,21 +2894,19 @@ void RGWAbortMultipart::execute()
         if (ret < 0 && ret != -ENOENT)
           return;
       } else {
-        RGWObjManifest& manifest = obj_part.manifest;
-        RGWObjManifest::obj_iterator oiter;
-        for (oiter = manifest.obj_begin(); oiter != manifest.obj_end(); ++oiter) {
-          rgw_obj loc = oiter.get_location();
-          ret = store->delete_obj(s->obj_ctx, owner, loc);
-          if (ret < 0 && ret != -ENOENT)
-            return;
-        }
+        store->update_gc_chain(meta_obj, obj_part.manifest, &chain);
       }
     }
   } while (truncated);
 
+  /* use upload id as tag */
+  ret = store->send_chain_to_gc(chain, upload_id , false);  // do it async
+  if (ret < 0) {
+    ldout(store->ctx(), 5) << "gc->send_chain() returned " << ret << dendl;
+    return;
+  }
+
   // 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(s->obj_ctx, owner, meta_obj);
   if (ret == -ENOENT) {
     ret = -ERR_NO_SUCH_BUCKET;
index dbc2bc8e5f2914740a4d80585a3fc2a1e253af12..8712d3d3e49ef28609b4cc629be84920e9c18c1f 100644 (file)
@@ -3726,22 +3726,32 @@ int RGWRados::bucket_suspended(rgw_bucket& bucket, bool *suspended)
   return 0;
 }
 
-int RGWRados::complete_atomic_overwrite(RGWRadosCtx *rctx, RGWObjState *state, rgw_obj& obj)
+void RGWRados::update_gc_chain(rgw_obj& head_obj, RGWObjManifest& manifest, cls_rgw_obj_chain *chain)
 {
-  if (!state || !state->has_manifest || state->keep_tail)
-    return 0;
-
-  cls_rgw_obj_chain chain;
   RGWObjManifest::obj_iterator iter;
-  for (iter = state->manifest.obj_begin(); iter != state->manifest.obj_end(); ++iter) {
+  for (iter = manifest.obj_begin(); iter != manifest.obj_end(); ++iter) {
     const rgw_obj& mobj = iter.get_location();
-    if (mobj == obj)
+    if (mobj == head_obj)
       continue;
     string oid, key;
     rgw_bucket bucket;
     get_obj_bucket_and_oid_key(mobj, bucket, oid, key);
-    chain.push_obj(bucket.data_pool, oid, key);
+    chain->push_obj(bucket.data_pool, oid, key);
   }
+}
+
+int RGWRados::send_chain_to_gc(cls_rgw_obj_chain& chain, const string& tag, bool sync)
+{
+  return gc->send_chain(chain, tag, sync);
+}
+
+int RGWRados::complete_atomic_overwrite(RGWRadosCtx *rctx, RGWObjState *state, rgw_obj& obj)
+{
+  if (!state || !state->has_manifest || state->keep_tail)
+    return 0;
+
+  cls_rgw_obj_chain chain;
+  update_gc_chain(obj, state->manifest, &chain);
 
   string tag = state->obj_tag.c_str();
   int ret = gc->send_chain(chain, tag, false);  // do it async
index 838e9422775f4bb9100b87c8aa69dca609c7b90a..dfff36169136c98393d500ff3c36f0a2e15342b1 100644 (file)
@@ -1340,6 +1340,7 @@ class RGWRados
     v.push_back(info);
     return clone_objs(ctx, dst_obj, v, attrs, category, pmtime, true, false);
   }
+
   int complete_atomic_overwrite(RGWRadosCtx *rctx, RGWObjState *state, rgw_obj& obj);
 
   int update_placement_map();
@@ -1894,6 +1895,8 @@ public:
   /// clean up/process any temporary objects older than given date[/time]
   int remove_temp_objects(string date, string time);
 
+  void update_gc_chain(rgw_obj& head_obj, RGWObjManifest& manifest, cls_rgw_obj_chain *chain);
+  int send_chain_to_gc(cls_rgw_obj_chain& chain, const string& tag, bool sync);
   int gc_operate(string& oid, librados::ObjectWriteOperation *op);
   int gc_aio_operate(string& oid, librados::ObjectWriteOperation *op);
   int gc_operate(string& oid, librados::ObjectReadOperation *op, bufferlist *pbl);