From 93218aeab7615ced131f0f1af49f6cda41b4a661 Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Wed, 5 Sep 2012 12:56:43 -0700 Subject: [PATCH] rgw_rados: adjustments for refcount objclass Signed-off-by: Yehuda Sadeh --- src/rgw/rgw_gc.cc | 3 +- src/rgw/rgw_op.cc | 12 ++--- src/rgw/rgw_rados.cc | 107 ++++++++++++++++++++++--------------------- src/rgw/rgw_rados.h | 12 ++--- 4 files changed, 70 insertions(+), 64 deletions(-) diff --git a/src/rgw/rgw_gc.cc b/src/rgw/rgw_gc.cc index e2375d34865c1..2ec2b41abdf56 100644 --- a/src/rgw/rgw_gc.cc +++ b/src/rgw/rgw_gc.cc @@ -3,6 +3,7 @@ #include "rgw_gc.h" #include "include/rados/librados.hpp" #include "cls/rgw/cls_rgw_client.h" +#include "cls/refcount/cls_refcount_client.h" #include "cls/lock/cls_lock_client.h" #include "auth/Crypto.h" @@ -194,7 +195,7 @@ int RGWGC::process(int index, int max_secs) ctx->locator_set_key(obj.key); dout(0) << "gc::process: removing " << obj.pool << ":" << obj.oid << dendl; ObjectWriteOperation op; - cls_refcount_put(op); + cls_refcount_put(op, info.tag, true); ret = ctx->operate(obj.oid, &op); if (ret == -ENOENT) ret = 0; diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index 72b9d1606f4d2..1a8e58ce594ef 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -687,7 +687,7 @@ int RGWPutObjProcessor_Plain::handle_data(bufferlist& bl, off_t _ofs, void **pha int RGWPutObjProcessor_Plain::complete(string& etag, map& attrs) { int r = rgwstore->put_obj_meta(s->obj_ctx, obj, data.length(), NULL, attrs, - RGW_OBJ_CATEGORY_MAIN, false, NULL, &data, NULL); + RGW_OBJ_CATEGORY_MAIN, false, NULL, &data, NULL, NULL); return r; } @@ -850,7 +850,7 @@ int RGWPutObjProcessor_Atomic::complete(string& etag, map& a rgwstore->set_atomic(s->obj_ctx, head_obj); int r = rgwstore->put_obj_meta(s->obj_ctx, head_obj, obj_len, NULL, attrs, - RGW_OBJ_CATEGORY_MAIN, false, NULL, &first_chunk, &manifest); + RGW_OBJ_CATEGORY_MAIN, false, NULL, &first_chunk, &manifest, NULL); return r; } @@ -888,7 +888,7 @@ int RGWPutObjProcessor_Multipart::prepare(struct req_state *s) int RGWPutObjProcessor_Multipart::complete(string& etag, map& attrs) { - int r = rgwstore->put_obj_meta(s->obj_ctx, obj, s->obj_size, NULL, attrs, RGW_OBJ_CATEGORY_MAIN, false, NULL, NULL, NULL); + int r = rgwstore->put_obj_meta(s->obj_ctx, obj, s->obj_size, NULL, attrs, RGW_OBJ_CATEGORY_MAIN, false, NULL, NULL, NULL, NULL); if (r < 0) return r; @@ -1436,7 +1436,7 @@ void RGWInitMultipart::execute() obj.init_ns(s->bucket, tmp_obj_name, mp_ns); // the meta object will be indexed with 0 size, we c - ret = rgwstore->put_obj_meta(s->obj_ctx, obj, 0, NULL, attrs, RGW_OBJ_CATEGORY_MULTIMETA, true, NULL, NULL, NULL); + ret = rgwstore->put_obj_meta(s->obj_ctx, obj, 0, NULL, attrs, RGW_OBJ_CATEGORY_MULTIMETA, true, NULL, NULL, NULL, NULL); } while (ret == -EEXIST); done: send_response(); @@ -1603,7 +1603,7 @@ void RGWCompleteMultipart::execute() target_obj.init(s->bucket, s->object_str); rgwstore->set_atomic(s->obj_ctx, target_obj); - ret = rgwstore->put_obj_meta(s->obj_ctx, target_obj, 0, NULL, attrs, RGW_OBJ_CATEGORY_MAIN, false, NULL, NULL, NULL); + ret = rgwstore->put_obj_meta(s->obj_ctx, target_obj, 0, NULL, attrs, RGW_OBJ_CATEGORY_MAIN, false, NULL, NULL, NULL, NULL); if (ret < 0) goto done; @@ -1626,7 +1626,7 @@ void RGWCompleteMultipart::execute() rgwstore->set_atomic(s->obj_ctx, target_obj); ret = rgwstore->put_obj_meta(s->obj_ctx, target_obj, ofs, NULL, attrs, - RGW_OBJ_CATEGORY_MAIN, false, NULL, NULL, &manifest); + RGW_OBJ_CATEGORY_MAIN, false, NULL, NULL, &manifest, NULL); if (ret < 0) goto done; diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index c711004dc710f..e221d1f8676e4 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -10,6 +10,7 @@ #include "cls/rgw/cls_rgw_types.h" #include "cls/rgw/cls_rgw_client.h" +#include "cls/refcount/cls_refcount_client.h" #include "rgw_tools.h" @@ -927,10 +928,12 @@ int RGWRados::create_pools(vector& names, vector& retcodes, int aui * Returns: 0 on success, -ERR# otherwise. */ int RGWRados::put_obj_meta(void *ctx, rgw_obj& obj, uint64_t size, - time_t *mtime, map& attrs, RGWObjCategory category, bool exclusive, + time_t *mtime, map& attrs, + RGWObjCategory category, bool exclusive, map* rmattrs, const bufferlist *data, - RGWObjManifest *manifest) + RGWObjManifest *manifest, + const string *ptag) { rgw_bucket bucket; std::string oid, key; @@ -950,7 +953,7 @@ int RGWRados::put_obj_meta(void *ctx, rgw_obj& obj, uint64_t size, RGWObjState *state = NULL; if (!exclusive) { - r = prepare_atomic_for_write(rctx, obj, op, &state, true); + r = prepare_atomic_for_write(rctx, obj, op, &state, true, ptag); if (r < 0) return r; } else { @@ -1007,10 +1010,10 @@ int RGWRados::put_obj_meta(void *ctx, rgw_obj& obj, uint64_t size, if (!op.size()) return 0; - string tag; + string index_tag; uint64_t epoch; utime_t ut; - r = prepare_update_index(NULL, bucket, obj, tag); + r = prepare_update_index(NULL, bucket, obj, index_tag); if (r < 0) return r; @@ -1026,7 +1029,7 @@ int RGWRados::put_obj_meta(void *ctx, rgw_obj& obj, uint64_t size, } ut = ceph_clock_now(cct); - r = complete_update_index(bucket, obj.object, tag, epoch, size, + r = complete_update_index(bucket, obj.object, index_tag, epoch, size, ut, etag, content_type, &acl_bl, category); if (r < 0) goto done_cancel; @@ -1041,7 +1044,7 @@ int RGWRados::put_obj_meta(void *ctx, rgw_obj& obj, uint64_t size, return 0; done_cancel: - int ret = complete_update_index_cancel(bucket, obj.object, tag); + int ret = complete_update_index_cancel(bucket, obj.object, index_tag); if (ret < 0) { ldout(cct, 0) << "ERROR: complete_update_index_cancel() returned ret=" << ret << dendl; } @@ -1215,11 +1218,14 @@ int RGWRados::copy_obj(void *ctx, bufferlist first_chunk; + string tag; + append_rand_alpha(cct, tag, tag, 32); + for (; miter != astate->manifest.objs.end(); ++miter) { RGWObjManifestPart& part = miter->second; ObjectWriteOperation op; manifest.objs[miter->first] = part; - cls_rgw_refcount_get(op); + cls_refcount_get(op, tag, true); get_obj_bucket_and_oid_key(part.loc, bucket, oid, key); io_ctx.locator_set_key(key); @@ -1244,7 +1250,7 @@ int RGWRados::copy_obj(void *ctx, manifest.obj_size = total_len; - ret = rgwstore->put_obj_meta(ctx, dest_obj, end + 1, NULL, attrs, category, false, NULL, &first_chunk, &manifest); + ret = rgwstore->put_obj_meta(ctx, dest_obj, end + 1, NULL, attrset, category, false, NULL, &first_chunk, &manifest, &tag); if (mtime) obj_stat(ctx, dest_obj, NULL, mtime, NULL, NULL); @@ -1256,7 +1262,7 @@ done_ret: /* rollback reference */ for (riter = ref_objs.begin(); riter != ref_objs.end(); ++riter) { ObjectWriteOperation op; - cls_rgw_refcount_put(op); + cls_refcount_put(op, tag, true); get_obj_bucket_and_oid_key(*riter, bucket, oid, key); io_ctx.locator_set_key(key); @@ -1333,7 +1339,7 @@ int RGWRados::copy_obj_data(void *ctx, } manifest.obj_size = ofs; - ret = rgwstore->put_obj_meta(ctx, dest_obj, end + 1, NULL, attrs, category, false, NULL, &first_chunk, &manifest); + ret = rgwstore->put_obj_meta(ctx, dest_obj, end + 1, NULL, attrs, category, false, NULL, &first_chunk, &manifest, NULL); if (mtime) obj_stat(ctx, dest_obj, NULL, mtime, NULL, NULL); @@ -1341,7 +1347,7 @@ int RGWRados::copy_obj_data(void *ctx, return ret; done_err: - rgwstore->delete_obj(ctx, shadow_obj, false); + rgwstore->delete_obj(ctx, shadow_obj); finish_get_obj(&handle); return r; } @@ -1381,12 +1387,12 @@ int RGWRados::delete_bucket(rgw_bucket& bucket) } while (is_truncated); rgw_obj obj(rgw_root_bucket, bucket.name); - r = delete_obj(NULL, obj, true); + r = delete_obj(NULL, obj); if (r < 0) return r; ObjectWriteOperation op; - cls_refcount_put(op); + op.remove(); string oid = dir_oid_prefix; oid.append(bucket.marker); librados::AioCompletion *completion = rados->aio_create_completion(NULL, NULL, NULL); @@ -1509,7 +1515,7 @@ int RGWRados::defer_gc(void *ctx, rgw_obj& obj) * obj: name of the object to delete * Returns: 0 on success, -ERR# otherwise. */ -int RGWRados::delete_obj_impl(void *ctx, rgw_obj& obj, bool sync) +int RGWRados::delete_obj_impl(void *ctx, rgw_obj& obj) { rgw_bucket bucket; std::string oid, key; @@ -1525,41 +1531,35 @@ int RGWRados::delete_obj_impl(void *ctx, rgw_obj& obj, bool sync) ObjectWriteOperation op; RGWObjState *state; - r = prepare_atomic_for_write(rctx, obj, op, &state, false); + r = prepare_atomic_for_write(rctx, obj, op, &state, false, NULL); if (r < 0) return r; bool ret_not_existed = (state && !state->exists); string tag; - cls_refcount_put(op); - if (sync) { - r = prepare_update_index(state, bucket, obj, tag); - if (r < 0) - return r; - r = io_ctx.operate(oid, &op); - bool removed = (r >= 0); + r = prepare_update_index(state, bucket, obj, tag); + if (r < 0) + return r; + cls_refcount_put(op, tag, true); + r = io_ctx.operate(oid, &op); + bool removed = (r >= 0); - if ((r >= 0 || r == -ENOENT) && bucket.marker.size()) { - uint64_t epoch = io_ctx.get_last_version(); - r = complete_update_index_del(bucket, obj.object, tag, epoch); - } else { - int ret = complete_update_index_cancel(bucket, obj.object, tag); - if (ret < 0) { - ldout(cct, 0) << "ERROR: complete_update_index_cancel returned ret=" << ret << dendl; - } + if ((r >= 0 || r == -ENOENT) && bucket.marker.size()) { + uint64_t epoch = io_ctx.get_last_version(); + r = complete_update_index_del(bucket, obj.object, tag, epoch); + } else { + int ret = complete_update_index_cancel(bucket, obj.object, tag); + if (ret < 0) { + ldout(cct, 0) << "ERROR: complete_update_index_cancel returned ret=" << ret << dendl; } - if (removed) { - int ret = complete_atomic_overwrite(rctx, state, obj); - if (ret < 0) { - ldout(cct, 0) << "ERROR: complete_atomic_removal returned ret=" << ret << dendl; - } - /* other than that, no need to propagate error */ + } + if (removed) { + int ret = complete_atomic_overwrite(rctx, state, obj); + if (ret < 0) { + ldout(cct, 0) << "ERROR: complete_atomic_removal returned ret=" << ret << dendl; } - } else { - librados::AioCompletion *completion = rados->aio_create_completion(NULL, NULL, NULL); - r = io_ctx.aio_operate(oid, completion, &op); - completion->release(); + /* other than that, no need to propagate error */ } atomic_write_finish(state, r); @@ -1573,11 +1573,11 @@ int RGWRados::delete_obj_impl(void *ctx, rgw_obj& obj, bool sync) return 0; } -int RGWRados::delete_obj(void *ctx, rgw_obj& obj, bool sync) +int RGWRados::delete_obj(void *ctx, rgw_obj& obj) { int r; - r = delete_obj_impl(ctx, obj, sync); + r = delete_obj_impl(ctx, obj); if (r == -ECANCELED) r = 0; @@ -1752,7 +1752,7 @@ int RGWRados::append_atomic_test(RGWRadosCtx *rctx, rgw_obj& obj, int RGWRados::prepare_atomic_for_write_impl(RGWRadosCtx *rctx, rgw_obj& obj, ObjectWriteOperation& op, RGWObjState **pstate, - bool reset_obj) + bool reset_obj, const string *ptag) { int r = get_obj_state(rctx, obj, pstate); if (r < 0) @@ -1825,10 +1825,16 @@ int RGWRados::prepare_atomic_for_write_impl(RGWRadosCtx *rctx, rgw_obj& obj, } string tag; - append_rand_alpha(cct, tag, tag, 32); + if (ptag) { + tag = *ptag; + } else { + append_rand_alpha(cct, tag, tag, 32); + } bufferlist bl; bl.append(tag.c_str(), tag.size() + 1); + ldout(cct, 0) << "setting object tag=" << tag << dendl; + op.setxattr(RGW_ATTR_ID_TAG, bl); string shadow = obj.object; @@ -1844,7 +1850,7 @@ int RGWRados::prepare_atomic_for_write_impl(RGWRadosCtx *rctx, rgw_obj& obj, int RGWRados::prepare_atomic_for_write(RGWRadosCtx *rctx, rgw_obj& obj, ObjectWriteOperation& op, RGWObjState **pstate, - bool reset_obj) + bool reset_obj, const string *ptag) { if (!rctx) { *pstate = NULL; @@ -1852,7 +1858,7 @@ int RGWRados::prepare_atomic_for_write(RGWRadosCtx *rctx, rgw_obj& obj, } int r; - r = prepare_atomic_for_write_impl(rctx, obj, op, pstate, reset_obj); + r = prepare_atomic_for_write_impl(rctx, obj, op, pstate, reset_obj, ptag); return r; } @@ -2259,7 +2265,7 @@ int RGWRados::clone_objs_impl(void *ctx, rgw_obj& dst_obj, } } RGWObjState *state; - r = prepare_atomic_for_write(rctx, dst_obj, op, &state, true); + r = prepare_atomic_for_write(rctx, dst_obj, op, &state, true, NULL); if (r < 0) return r; @@ -3237,7 +3243,7 @@ int RGWRados::process_intent_log(rgw_bucket& bucket, string& oid, complete = false; break; } - r = rgwstore->delete_obj(NULL, entry.obj, false); + r = rgwstore->delete_obj(NULL, entry.obj); if (r < 0 && r != -ENOENT) { cerr << "failed to remove obj: " << entry.obj << std::endl; complete = false; @@ -3253,7 +3259,6 @@ int RGWRados::process_intent_log(rgw_bucket& bucket, string& oid, if (r < 0) return r; ObjectWriteOperation op; - cls_refcount_put(op); op.remove(); string oid = dir_oid_prefix; oid.append(entry.obj.bucket.marker); @@ -3275,7 +3280,7 @@ int RGWRados::process_intent_log(rgw_bucket& bucket, string& oid, rgw_obj obj(bucket, oid); cout << "completed intent log: " << obj << (purge ? ", purging it" : "") << std::endl; if (purge) { - r = delete_obj(NULL, obj, false); + r = delete_obj(NULL, obj); if (r < 0) cerr << "failed to remove obj: " << obj << std::endl; } diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h index 12443f248758c..d5ae86b79d240 100644 --- a/src/rgw/rgw_rados.h +++ b/src/rgw/rgw_rados.h @@ -247,10 +247,10 @@ class RGWRados librados::ObjectOperation& op, RGWObjState **state); int prepare_atomic_for_write_impl(RGWRadosCtx *rctx, rgw_obj& obj, librados::ObjectWriteOperation& op, RGWObjState **pstate, - bool reset_obj); + bool reset_obj, const string *ptag); int prepare_atomic_for_write(RGWRadosCtx *rctx, rgw_obj& obj, librados::ObjectWriteOperation& op, RGWObjState **pstate, - bool reset_obj); + bool reset_obj, const string *ptag); void atomic_write_finish(RGWObjState *state, int r) { if (state && r == -ECANCELED) { @@ -281,7 +281,7 @@ class RGWRados v.push_back(info); return clone_objs(ctx, dst_obj, v, attrs, category, pmtime, true, false); } - int delete_obj_impl(void *ctx, rgw_obj& src_obj, bool sync); + int delete_obj_impl(void *ctx, rgw_obj& src_obj); int complete_atomic_overwrite(RGWRadosCtx *rctx, RGWObjState *state, rgw_obj& obj); int update_placement_map(); @@ -375,7 +375,7 @@ public: virtual int put_obj_meta(void *ctx, rgw_obj& obj, uint64_t size, time_t *mtime, map& attrs, RGWObjCategory category, bool exclusive, map* rmattrs, const bufferlist *data, - RGWObjManifest *manifest); + RGWObjManifest *manifest, const string *ptag); virtual int put_obj_data(void *ctx, rgw_obj& obj, const char *data, off_t ofs, size_t len, bool exclusive); virtual int aio_put_obj_data(void *ctx, rgw_obj& obj, bufferlist& bl, @@ -385,7 +385,7 @@ public: time_t *mtime, map& attrs) { bufferlist bl; bl.append(data, len); - int ret = put_obj_meta(ctx, obj, len, mtime, attrs, RGW_OBJ_CATEGORY_NONE, exclusive, NULL, &bl, NULL); + int ret = put_obj_meta(ctx, obj, len, mtime, attrs, RGW_OBJ_CATEGORY_NONE, exclusive, NULL, &bl, NULL, NULL); return ret; } virtual int aio_wait(void *handle); @@ -463,7 +463,7 @@ public: virtual int bucket_suspended(rgw_bucket& bucket, bool *suspended); /** Delete an object.*/ - virtual int delete_obj(void *ctx, rgw_obj& src_obj, bool sync = true); + virtual int delete_obj(void *ctx, rgw_obj& src_obj); /** * Get the attributes for an object. -- 2.39.5