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;
else
dest_obj.set_key(obj.object);
- /* FIXME: clone obj should be conditional, should check src object id-tag */
pair<string, bufferlist> 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) {
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
}
return false;
}
+
+ void clear() {
+ has_attrs = false;
+ exists = false;
+ size = 0;
+ mtime = 0;
+ obj_tag.clear();
+ shadow_obj.clear();
+ attrset.clear();
+ }
};
struct RGWRadosCtx {
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: