From fb7831c30169b4839f00672c577bf5a5913d985d Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Thu, 18 Aug 2011 23:35:25 -0700 Subject: [PATCH] rgw: reread obj meta on racing write operation --- src/rgw/rgw_rados.cc | 21 +++++++++++++++------ src/rgw/rgw_rados.h | 12 ++++++++++++ 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index 9d3f9e586fcef..f86322db69d3f 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -832,12 +832,9 @@ int RGWRados::append_atomic_test(RGWRadosCtx *rctx, rgw_obj& obj, librados::IoCt return 0; } -int RGWRados::prepare_atomic_for_write(RGWRadosCtx *rctx, rgw_obj& obj, librados::IoCtx& io_ctx, +int RGWRados::prepare_atomic_for_write_impl(RGWRadosCtx *rctx, rgw_obj& obj, librados::IoCtx& io_ctx, string& actual_obj, ObjectWriteOperation& op, RGWObjState **pstate) { - if (!rctx) - return 0; - int r = get_obj_state(rctx, obj, io_ctx, actual_obj, pstate); if (r < 0) return r; @@ -859,14 +856,14 @@ int RGWRados::prepare_atomic_for_write(RGWRadosCtx *rctx, rgw_obj& obj, librados else dest_obj.set_key(obj.object); - /* FIXME: clone obj should be conditional, should check src object id-tag */ pair cond(RGW_ATTR_ID_TAG, state->obj_tag); r = clone_obj_cond(NULL, dest_obj, 0, obj, 0, state->size, state->attrset, shadow_category, &state->mtime, &cond); if (r == -ECANCELED) { /* we lost in a race here, original object was replaced, we assume it was cloned as required */ RGW_LOG(0) << "clone_obj_cond was cancelled, lost in a race" << dendl; - r = 0; + state->clear(); + return r; } else { int ret = rctx->notify_intent(dest_obj, DEL_OBJ); if (ret < 0) { @@ -897,6 +894,18 @@ int RGWRados::prepare_atomic_for_write(RGWRadosCtx *rctx, rgw_obj& obj, librados return 0; } +int RGWRados::prepare_atomic_for_write(RGWRadosCtx *rctx, rgw_obj& obj, librados::IoCtx& io_ctx, + string& actual_obj, ObjectWriteOperation& op, RGWObjState **pstate) +{ + if (!rctx) + return 0; + + int r; + do { + r = prepare_atomic_for_write_impl(rctx, obj, io_ctx, actual_obj, op, pstate); + } while (r == -ECANCELED); +} + /** * Set an attr on an object. * bucket: name of the bucket holding the object diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h index 8e794ff9e6e67..847d2d1fab639 100644 --- a/src/rgw/rgw_rados.h +++ b/src/rgw/rgw_rados.h @@ -27,6 +27,16 @@ struct RGWObjState { } return false; } + + void clear() { + has_attrs = false; + exists = false; + size = 0; + mtime = 0; + obj_tag.clear(); + shadow_obj.clear(); + attrset.clear(); + } }; struct RGWRadosCtx { @@ -75,6 +85,8 @@ class RGWRados : public RGWAccess int get_obj_state(RGWRadosCtx *rctx, rgw_obj& obj, librados::IoCtx& io_ctx, string& actual_obj, RGWObjState **state); int append_atomic_test(RGWRadosCtx *rctx, rgw_obj& obj, librados::IoCtx& io_ctx, string& actual_obj, librados::ObjectOperation& op, RGWObjState **state); + int prepare_atomic_for_write_impl(RGWRadosCtx *rctx, rgw_obj& obj, librados::IoCtx& io_ctx, + string& actual_obj, librados::ObjectWriteOperation& op, RGWObjState **pstate); int prepare_atomic_for_write(RGWRadosCtx *rctx, rgw_obj& obj, librados::IoCtx& io_ctx, string& actual_obj, librados::ObjectWriteOperation& op, RGWObjState **pstate); public: -- 2.39.5