info.dst_ofs = dst_ofs;
info.len = size;
v.push_back(info);
- return clone_objs(ctx, dst_obj, v, attrs, category, pmtime, true);
+ return clone_objs(ctx, dst_obj, v, attrs, category, pmtime, true, false);
}
virtual int clone_objs(void *ctx, rgw_obj& dst_obj,
map<string, bufferlist> attrs,
string& category,
time_t *pmtime,
- bool truncate_dest) { return -ENOTSUP; }
+ bool truncate_dest,
+ bool exclusive) { return -ENOTSUP; }
/**
* a simple object read without keeping state
*/
ofs += obj_iter->second.size;
}
- ret = rgwstore->clone_objs(s->obj_ctx, target_obj, ranges, attrs, rgw_obj_category_main, NULL, true);
+ ret = rgwstore->clone_objs(s->obj_ctx, target_obj, ranges, attrs, rgw_obj_category_main, NULL, true, false);
if (ret < 0)
goto done;
dest_obj.set_key(obj.object);
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);
+ RGW_LOG(0) << "cloning: dest_obj=" << dest_obj << " size=" << state->size << " tag=" << state->obj_tag.c_str() << dendl;
+ r = clone_obj_cond(NULL, dest_obj, 0, obj, 0, state->size, state->attrset, shadow_category, &state->mtime, false, true, &cond);
+ if (r == -EEXIST)
+ r = 0;
if (r == -ECANCELED) {
/* we lost in a race here, original object was replaced, we assume it was cloned
as required */
string& category,
time_t *pmtime,
bool truncate_dest,
+ bool exclusive,
pair<string, bufferlist> *xattr_cond)
{
std::string& bucket = dst_obj.bucket;
io_ctx.locator_set_key(dst_obj.key);
ObjectWriteOperation op;
-
if (truncate_dest) {
op.remove();
op.set_op_flags(OP_FAILOK); // don't fail if object didn't exist
}
if (category.size())
- op.create(false, category);
+ op.create(exclusive, category);
else
- op.create(false);
+ op.create(exclusive);
map<string, bufferlist>::iterator iter;
string& category,
time_t *pmtime,
bool truncate_dest,
+ bool exclusive,
pair<string, bufferlist> *xattr_cond)
{
int r;
do {
- r = clone_objs_impl(ctx, dst_obj, ranges, attrs, category, pmtime, truncate_dest, xattr_cond);
+ r = clone_objs_impl(ctx, dst_obj, ranges, attrs, category, pmtime, truncate_dest, exclusive, xattr_cond);
} while (ctx && r == -ECANCELED);
return r;
}
string& category,
time_t *pmtime,
bool truncate_dest,
+ bool exclusive,
pair<string, bufferlist> *cmp_xattr);
int delete_obj_impl(void *ctx, std::string& id, rgw_obj& src_obj, bool sync);
public:
vector<RGWCloneRangeInfo>& ranges,
map<string, bufferlist> attrs,
string& category,
- time_t *pmtime, bool truncate_dest) {
- return clone_objs(ctx, dst_obj, ranges, attrs, category, pmtime, truncate_dest, NULL);
+ time_t *pmtime, bool truncate_dest, bool exclusive) {
+ return clone_objs(ctx, dst_obj, ranges, attrs, category, pmtime, truncate_dest, exclusive, NULL);
}
int clone_objs(void *ctx, rgw_obj& dst_obj,
string& category,
time_t *pmtime,
bool truncate_dest,
+ bool exclusive,
pair<string, bufferlist> *cmp_xattr);
int clone_obj_cond(void *ctx, rgw_obj& dst_obj, off_t dst_ofs,
uint64_t size, map<string, bufferlist> attrs,
string& category,
time_t *pmtime,
+ bool truncate_dest,
+ bool exclusive,
pair<string, bufferlist> *xattr_cond) {
RGWCloneRangeInfo info;
vector<RGWCloneRangeInfo> v;
info.dst_ofs = dst_ofs;
info.len = size;
v.push_back(info);
- return clone_objs(ctx, dst_obj, v, attrs, category, pmtime, true, xattr_cond);
+ return clone_objs(ctx, dst_obj, v, attrs, category, pmtime, truncate_dest, exclusive, xattr_cond);
}
/** Copy an object, with many extra options */