]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
Deleting tail/multipart objects inline when send chain to gc fails.
authorPritha Srivastava <prsrivas@redhat.com>
Wed, 18 Sep 2019 08:01:57 +0000 (13:31 +0530)
committerPritha Srivastava <prsrivas@redhat.com>
Sat, 19 Oct 2019 07:58:32 +0000 (13:28 +0530)
Signed-off-by: Pritha Srivastava <prsrivas@redhat.com>
src/rgw/rgw_multi.cc
src/rgw/rgw_rados.cc
src/rgw/rgw_rados.h

index 03138750d8ae8831eefde0d30a98a07c3dd576ab..7cc54c747ce2beea6d87c3fc670b9f67b7d715b1 100644 (file)
@@ -252,12 +252,15 @@ int abort_multipart_upload(rgw::sal::RGWRadosStore *store, CephContext *cct,
     }
   } while (truncated);
 
-  /* use upload id as tag and do it asynchronously */
+  /* use upload id as tag and do it synchronously */
   ret = store->getRados()->send_chain_to_gc(chain, mp_obj.get_upload_id());
-  // XXX: should detect ENOSPC and delete inline
   if (ret < 0) {
     ldout(cct, 5) << __func__ << ": gc->send_chain() returned " << ret << dendl;
-    return (ret == -ENOENT) ? -ERR_NO_SUCH_UPLOAD : ret;
+    if (ret == -ENOENT) {
+      return -ERR_NO_SUCH_UPLOAD;
+    }
+    //Delete objects inline if send chain to gc fails
+    store->getRados()->delete_objs_inline(chain, mp_obj.get_upload_id());
   }
 
   RGWRados::Object del_target(store->getRados(), bucket_info, *obj_ctx, meta_obj);
index d80ee75da8c16a4da252f45956ed81ceb5c24a40..fb8a562b52f0c13d126ad7b12bd54d6fc5997fc1 100644 (file)
@@ -4487,7 +4487,12 @@ int RGWRados::Object::complete_atomic_modification()
   }
 
   string tag = (state->tail_tag.length() > 0 ? state->tail_tag.to_str() : state->obj_tag.to_str());
-  return store->gc->send_chain(chain, tag);  // do it sync
+  auto ret = store->gc->send_chain(chain, tag); // do it synchronously
+  if (ret < 0) {
+    //Delete objects inline if send chain to gc fails
+    store->delete_objs_inline(chain, tag);
+  }
+  return 0;
 }
 
 void RGWRados::update_gc_chain(rgw_obj& head_obj, RGWObjManifest& manifest, cls_rgw_obj_chain *chain)
@@ -4509,6 +4514,37 @@ int RGWRados::send_chain_to_gc(cls_rgw_obj_chain& chain, const string& tag)
   return gc->send_chain(chain, tag);
 }
 
+void RGWRados::delete_objs_inline(cls_rgw_obj_chain& chain, const string& tag)
+{
+  string last_pool;
+  std::unique_ptr<IoCtx> ctx(new IoCtx);
+  int ret = 0;
+  for (auto liter = chain.objs.begin(); liter != chain.objs.end(); ++liter) {
+    cls_rgw_obj& obj = *liter;
+    if (obj.pool != last_pool) {
+      ctx.reset(new IoCtx);
+      ret = rgw_init_ioctx(get_rados_handle(), obj.pool, *ctx);
+      if (ret < 0) {
+        last_pool = "";
+        ldout(cct, 0) << "ERROR: failed to create ioctx pool=" <<
+        obj.pool << dendl;
+        continue;
+      }
+      last_pool = obj.pool;
+    }
+    ctx->locator_set_key(obj.loc);
+    const string& oid = obj.key.name; /* just stored raw oid there */
+    ldout(cct, 5) << "delete_objs_inline: removing " << obj.pool <<
+    ":" << obj.key.name << dendl;
+    ObjectWriteOperation op;
+    cls_refcount_put(op, tag, true);
+    ret = ctx->operate(oid, &op);
+    if (ret < 0) {
+      ldout(cct, 5) << "delete_objs_inline: refcount put returned error " << ret << dendl;
+    }
+  }
+}
+
 static void accumulate_raw_stats(const rgw_bucket_dir_header& header,
                                  map<RGWObjCategory, RGWStorageStats>& stats)
 {
index e7d3d83d0249bd40d0c43891de8d72e6b7dcdd47..3ddba16441afad00e99363e026b74870aff722b0 100644 (file)
@@ -1391,6 +1391,7 @@ public:
 
   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);
+  void delete_objs_inline(cls_rgw_obj_chain& chain, const string& tag);
   int gc_operate(string& oid, librados::ObjectWriteOperation *op);
   int gc_aio_operate(const std::string& oid, librados::AioCompletion *c,
                      librados::ObjectWriteOperation *op);