From e65eecb1fe7d74837a18a0d86e8e6b2f0e976348 Mon Sep 17 00:00:00 2001 From: Pritha Srivastava Date: Wed, 18 Sep 2019 13:31:57 +0530 Subject: [PATCH] Deleting tail/multipart objects inline when send chain to gc fails. Signed-off-by: Pritha Srivastava --- src/rgw/rgw_multi.cc | 9 ++++++--- src/rgw/rgw_rados.cc | 38 +++++++++++++++++++++++++++++++++++++- src/rgw/rgw_rados.h | 1 + 3 files changed, 44 insertions(+), 4 deletions(-) diff --git a/src/rgw/rgw_multi.cc b/src/rgw/rgw_multi.cc index 03138750d8a..7cc54c747ce 100644 --- a/src/rgw/rgw_multi.cc +++ b/src/rgw/rgw_multi.cc @@ -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); diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index d80ee75da8c..fb8a562b52f 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -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 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& stats) { diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h index e7d3d83d024..3ddba16441a 100644 --- a/src/rgw/rgw_rados.h +++ b/src/rgw/rgw_rados.h @@ -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); -- 2.39.5