epoch = ref.ioctx.get_last_version();
poolid = ref.ioctx.get_id();
+ /* successfully modified object, update internal object state */
+ state->exists = true;
+ state->mtime = meta.set_mtime;
+ state->size = size;
+ state->has_attrs = true;
+ state->epoch = epoch;
+ state->attrset = attrs;
+
r = target->complete_atomic_modification();
if (r < 0) {
ldout(store->ctx(), 0) << "ERROR: complete_atomic_modification returned r=" << r << dendl;
return ret;
}
- return copy_obj_data(rctx, dest_bucket_info, read_op, end, obj, obj, max_chunk_size, NULL, mtime, attrset, RGW_OBJ_CATEGORY_MAIN, NULL, NULL, NULL);
+ return copy_obj_data(rctx, dest_bucket_info, read_op, end, obj, obj, max_chunk_size, NULL, mtime, attrset, RGW_OBJ_CATEGORY_MAIN, 0, NULL, NULL, NULL, NULL);
}
int RGWRados::fetch_remote_obj(RGWObjectCtx& obj_ctx,
bool replace_attrs,
map<string, bufferlist>& attrs,
RGWObjCategory category,
+ uint64_t olh_epoch,
+ string *version_id,
string *ptag,
string *petag,
struct rgw_err *err,
bool replace_attrs,
map<string, bufferlist>& attrs,
RGWObjCategory category,
+ uint64_t olh_epoch,
+ string *version_id,
string *ptag,
string *petag,
struct rgw_err *err,
if (remote_src || !source_zone.empty()) {
return fetch_remote_obj(obj_ctx, user_id, client_id, op_id, info, source_zone,
dest_obj, src_obj, dest_bucket_info, src_bucket_info, mtime, mod_ptr,
- unmod_ptr, if_match, if_nomatch, replace_attrs, attrs,
- category, ptag, petag, err, progress_cb, progress_data);
+ unmod_ptr, if_match, if_nomatch, replace_attrs, attrs, category,
+ olh_epoch, version_id, ptag, petag, err, progress_cb, progress_data);
}
map<string, bufferlist> src_attrs;
if (copy_data) { /* refcounting tail wouldn't work here, just copy the data */
return copy_obj_data(obj_ctx, dest_bucket_info, read_op, end, dest_obj, src_obj,
- max_chunk_size, mtime, 0, src_attrs, category, ptag, petag, err);
+ max_chunk_size, mtime, 0, src_attrs, category, olh_epoch,
+ version_id, ptag, petag, err);
}
RGWObjManifest::obj_iterator miter = astate->manifest.obj_begin();
return ret;
}
+ bool versioned_dest = dest_bucket_info.versioning_enabled();
+
+ if (version_id && !version_id->empty()) {
+ versioned_dest = true;
+ dest_obj.set_instance(*version_id);
+ } else if (versioned_dest) {
+ gen_rand_obj_instance_name(&dest_obj);
+ }
+
bufferlist first_chunk;
bool copy_itself = (dest_obj == src_obj);
RGWRados::Object dest_op_target(this, obj_ctx, dest_obj);
RGWRados::Object::Write write_op(&dest_op_target);
+ RGWObjState *dest_state = NULL;
+ ret = get_obj_state(&obj_ctx, dest_obj, &dest_state, NULL);
+ if (ret < 0)
+ return ret;
+
string tag;
if (ptag)
write_op.meta.mtime = mtime;
write_op.meta.flags = PUT_OBJ_CREATE;
write_op.meta.category = category;
+ write_op.meta.olh_epoch = olh_epoch;
ret = write_op.write_meta(end + 1, attrs);
if (ret < 0)
goto done_ret;
+ if (versioned_dest || dest_state->is_olh) {
+ ret = set_olh(obj_ctx, dest_bucket_info.owner, dest_obj, false, NULL, olh_epoch);
+ if (ret < 0) {
+ goto done_ret;
+ }
+ }
+
return 0;
done_ret:
time_t set_mtime,
map<string, bufferlist>& attrs,
RGWObjCategory category,
+ uint64_t olh_epoch,
+ string *version_id,
string *ptag,
string *petag,
struct rgw_err *err)
RGWPutObjProcessor_Atomic processor(obj_ctx,
dest_bucket_info.owner, dest_obj.bucket, dest_obj.get_object(),
cct->_conf->rgw_obj_stripe_size, tag, dest_bucket_info.versioning_enabled());
+ if (version_id) {
+ processor.set_version_id(*version_id);
+ }
+ processor.set_olh_epoch(olh_epoch);
int ret = processor.prepare(this, NULL);
if (ret < 0)
return ret;
{
int ret;
- do {
- ret = olh_init_modification_impl(state, obj, op_tag);
- } while (ret == -EEXIST);
+ ret = olh_init_modification_impl(state, obj, op_tag);
+ if (ret == -EEXIST) {
+ ret = -ECANCELED;
+ }
return ret;
}