From: Yehuda Sadeh Date: Thu, 8 Jan 2015 20:48:47 +0000 (-0800) Subject: rgw: use gc for multipart abort X-Git-Tag: v0.92~4^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=8d52782a9cb9bdceed6e615fb1e25b6878b14239;p=ceph.git rgw: use gc for multipart abort Fixes: #10445 Instead of chewing through a potentially very large list of objects synchronously, leave it to the garbage collector. Reported-by: Aaron Bassett Signed-off-by: Yehuda Sadeh --- diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index 0319a56982da..4868fe90308e 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -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; diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index dbc2bc8e5f29..8712d3d3e49e 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -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 diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h index 838e9422775f..dfff36169136 100644 --- a/src/rgw/rgw_rados.h +++ b/src/rgw/rgw_rados.h @@ -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);