r = ref.ioctx.operate(ref.oid, &op);
if (r == -ECANCELED) {
/* raced with another operation, we can regard it as removed */
+ state->clear();
r = 0;
}
bool removed = (r >= 0);
/* other than that, no need to propagate error */
}
- store->atomic_write_finish(state, r);
-
if (r < 0)
return r;
(!state->fake_tag);
if (!state->is_atomic) {
- ldout(store->ctx(), 20) << "prepare_atomic_for_write_impl: state is not atomic. state=" << (void *)state << dendl;
+ ldout(store->ctx(), 20) << "prepare_atomic_modification: state is not atomic. state=" << (void *)state << dendl;
if (reset_obj) {
op.create(false);
return 0;
}
-int RGWRados::prepare_atomic_for_write_impl(ObjectCtx *rctx, rgw_obj& obj,
- ObjectWriteOperation& op, RGWObjState **pstate,
- bool reset_obj, const string *ptag,
- const char *if_match, const char *if_nomatch)
-#warning remove me when done
-{
- int r = get_obj_state(rctx, obj, pstate, NULL, false);
- if (r < 0)
- return r;
-
- RGWObjState *state = *pstate;
-
- bool need_guard = (state->has_manifest || (state->obj_tag.length() != 0) ||
- if_match != NULL || if_nomatch != NULL) &&
- (!state->fake_tag);
-
- if (!state->is_atomic) {
- ldout(cct, 20) << "prepare_atomic_for_write_impl: state is not atomic. state=" << (void *)state << dendl;
-
- if (reset_obj) {
- op.create(false);
- remove_rgw_head_obj(op); // we're not dropping reference here, actually removing object
- }
-
- return 0;
- }
-
- if (need_guard) {
- /* first verify that the object wasn't replaced under */
- if (if_nomatch == NULL || strcmp(if_nomatch, "*") != 0) {
- op.cmpxattr(RGW_ATTR_ID_TAG, LIBRADOS_CMPXATTR_OP_EQ, state->obj_tag);
- // FIXME: need to add FAIL_NOTEXIST_OK for racing deletion
- }
-
- if (if_match) {
- if (strcmp(if_match, "*") == 0) {
- // test the object is existing
- if (!state->exists) {
- r = -ERR_PRECONDITION_FAILED;
- return r;
- }
- } else {
- bufferlist bl;
- if (!state->get_attr(RGW_ATTR_ETAG, bl) ||
- strncmp(if_match, bl.c_str(), bl.length()) != 0) {
- r = -ERR_PRECONDITION_FAILED;
- return r;
- }
- }
- }
-
- if (if_nomatch) {
- if (strcmp(if_nomatch, "*") == 0) {
- // test the object is NOT existing
- if (state->exists) {
- r = -ERR_PRECONDITION_FAILED;
- return r;
- }
- } else {
- bufferlist bl;
- if (!state->get_attr(RGW_ATTR_ETAG, bl) ||
- strncmp(if_nomatch, bl.c_str(), bl.length()) == 0) {
- r = -ERR_PRECONDITION_FAILED;
- return r;
- }
- }
- }
- }
-
- if (reset_obj) {
- if (state->exists) {
- op.create(false);
- remove_rgw_head_obj(op);
- } else {
- op.create(true);
- }
- }
-
- if (ptag) {
- state->write_tag = *ptag;
- } else {
- append_rand_alpha(cct, state->write_tag, state->write_tag, 32);
- }
- bufferlist bl;
- bl.append(state->write_tag.c_str(), state->write_tag.size() + 1);
-
- ldout(cct, 10) << "setting object write_tag=" << state->write_tag << dendl;
-
- op.setxattr(RGW_ATTR_ID_TAG, bl);
-
- return 0;
-}
-
-int RGWRados::prepare_atomic_for_write(ObjectCtx *rctx, rgw_obj& obj,
- ObjectWriteOperation& op, RGWObjState **pstate,
- bool reset_obj, const string *ptag,
- const char *if_match, const char *if_nomatch)
-{
- if (!rctx) {
- *pstate = NULL;
- return 0;
- }
-
- int r;
- r = prepare_atomic_for_write_impl(rctx, obj, op, pstate, reset_obj, ptag,
- if_match, if_nomatch);
-
- return r;
-}
-
/**
* Set an attr on an object.
* bucket: name of the bucket holding the object
int get_obj_state_impl(ObjectCtx *rctx, rgw_obj& obj, RGWObjState **state, RGWObjVersionTracker *objv_tracker, bool follow_olh);
int append_atomic_test(ObjectCtx *rctx, rgw_obj& obj,
librados::ObjectOperation& op, RGWObjState **state);
- int prepare_atomic_for_write_impl(ObjectCtx *rctx, rgw_obj& obj,
- librados::ObjectWriteOperation& op, RGWObjState **pstate,
- bool reset_obj, const string *ptag,
- const char *if_match = NULL,
- const char *if_nomatch = NULL);
- int prepare_atomic_for_write(ObjectCtx *rctx, rgw_obj& obj,
- librados::ObjectWriteOperation& op, RGWObjState **pstate,
- bool reset_obj, const string *ptag,
- const char *if_match = NULL,
- const char *if_nomatch = NULL);
-
- void atomic_write_finish(RGWObjState *state, int r) {
- if (state && r == -ECANCELED) {
- state->clear();
- }
- }
-
- int complete_atomic_overwrite(ObjectCtx *rctx, RGWObjState *state, rgw_obj& obj);
int update_placement_map();
int store_bucket_info(RGWBucketInfo& info, map<string, bufferlist> *pattrs, RGWObjVersionTracker *objv_tracker, bool exclusive);