int RGWPutObjProcessor_Plain::complete(string& etag, map<string, bufferlist>& attrs)
{
int r = rgwstore->put_obj_meta(s->obj_ctx, obj, data.length(), NULL, attrs,
- RGW_OBJ_CATEGORY_MAIN, false, NULL, &data, NULL);
+ RGW_OBJ_CATEGORY_MAIN, false, NULL, &data, NULL, NULL);
return r;
}
rgwstore->set_atomic(s->obj_ctx, head_obj);
int r = rgwstore->put_obj_meta(s->obj_ctx, head_obj, obj_len, NULL, attrs,
- RGW_OBJ_CATEGORY_MAIN, false, NULL, &first_chunk, &manifest);
+ RGW_OBJ_CATEGORY_MAIN, false, NULL, &first_chunk, &manifest, NULL);
return r;
}
int RGWPutObjProcessor_Multipart::complete(string& etag, map<string, bufferlist>& attrs)
{
- int r = rgwstore->put_obj_meta(s->obj_ctx, obj, s->obj_size, NULL, attrs, RGW_OBJ_CATEGORY_MAIN, false, NULL, NULL, NULL);
+ int r = rgwstore->put_obj_meta(s->obj_ctx, obj, s->obj_size, NULL, attrs, RGW_OBJ_CATEGORY_MAIN, false, NULL, NULL, NULL, NULL);
if (r < 0)
return r;
obj.init_ns(s->bucket, tmp_obj_name, mp_ns);
// the meta object will be indexed with 0 size, we c
- ret = rgwstore->put_obj_meta(s->obj_ctx, obj, 0, NULL, attrs, RGW_OBJ_CATEGORY_MULTIMETA, true, NULL, NULL, NULL);
+ ret = rgwstore->put_obj_meta(s->obj_ctx, obj, 0, NULL, attrs, RGW_OBJ_CATEGORY_MULTIMETA, true, NULL, NULL, NULL, NULL);
} while (ret == -EEXIST);
done:
send_response();
target_obj.init(s->bucket, s->object_str);
rgwstore->set_atomic(s->obj_ctx, target_obj);
- ret = rgwstore->put_obj_meta(s->obj_ctx, target_obj, 0, NULL, attrs, RGW_OBJ_CATEGORY_MAIN, false, NULL, NULL, NULL);
+ ret = rgwstore->put_obj_meta(s->obj_ctx, target_obj, 0, NULL, attrs, RGW_OBJ_CATEGORY_MAIN, false, NULL, NULL, NULL, NULL);
if (ret < 0)
goto done;
rgwstore->set_atomic(s->obj_ctx, target_obj);
ret = rgwstore->put_obj_meta(s->obj_ctx, target_obj, ofs, NULL, attrs,
- RGW_OBJ_CATEGORY_MAIN, false, NULL, NULL, &manifest);
+ RGW_OBJ_CATEGORY_MAIN, false, NULL, NULL, &manifest, NULL);
if (ret < 0)
goto done;
#include "cls/rgw/cls_rgw_types.h"
#include "cls/rgw/cls_rgw_client.h"
+#include "cls/refcount/cls_refcount_client.h"
#include "rgw_tools.h"
* Returns: 0 on success, -ERR# otherwise.
*/
int RGWRados::put_obj_meta(void *ctx, rgw_obj& obj, uint64_t size,
- time_t *mtime, map<string, bufferlist>& attrs, RGWObjCategory category, bool exclusive,
+ time_t *mtime, map<string, bufferlist>& attrs,
+ RGWObjCategory category, bool exclusive,
map<string, bufferlist>* rmattrs,
const bufferlist *data,
- RGWObjManifest *manifest)
+ RGWObjManifest *manifest,
+ const string *ptag)
{
rgw_bucket bucket;
std::string oid, key;
RGWObjState *state = NULL;
if (!exclusive) {
- r = prepare_atomic_for_write(rctx, obj, op, &state, true);
+ r = prepare_atomic_for_write(rctx, obj, op, &state, true, ptag);
if (r < 0)
return r;
} else {
if (!op.size())
return 0;
- string tag;
+ string index_tag;
uint64_t epoch;
utime_t ut;
- r = prepare_update_index(NULL, bucket, obj, tag);
+ r = prepare_update_index(NULL, bucket, obj, index_tag);
if (r < 0)
return r;
}
ut = ceph_clock_now(cct);
- r = complete_update_index(bucket, obj.object, tag, epoch, size,
+ r = complete_update_index(bucket, obj.object, index_tag, epoch, size,
ut, etag, content_type, &acl_bl, category);
if (r < 0)
goto done_cancel;
return 0;
done_cancel:
- int ret = complete_update_index_cancel(bucket, obj.object, tag);
+ int ret = complete_update_index_cancel(bucket, obj.object, index_tag);
if (ret < 0) {
ldout(cct, 0) << "ERROR: complete_update_index_cancel() returned ret=" << ret << dendl;
}
bufferlist first_chunk;
+ string tag;
+ append_rand_alpha(cct, tag, tag, 32);
+
for (; miter != astate->manifest.objs.end(); ++miter) {
RGWObjManifestPart& part = miter->second;
ObjectWriteOperation op;
manifest.objs[miter->first] = part;
- cls_rgw_refcount_get(op);
+ cls_refcount_get(op, tag, true);
get_obj_bucket_and_oid_key(part.loc, bucket, oid, key);
io_ctx.locator_set_key(key);
manifest.obj_size = total_len;
- ret = rgwstore->put_obj_meta(ctx, dest_obj, end + 1, NULL, attrs, category, false, NULL, &first_chunk, &manifest);
+ ret = rgwstore->put_obj_meta(ctx, dest_obj, end + 1, NULL, attrset, category, false, NULL, &first_chunk, &manifest, &tag);
if (mtime)
obj_stat(ctx, dest_obj, NULL, mtime, NULL, NULL);
/* rollback reference */
for (riter = ref_objs.begin(); riter != ref_objs.end(); ++riter) {
ObjectWriteOperation op;
- cls_rgw_refcount_put(op);
+ cls_refcount_put(op, tag, true);
get_obj_bucket_and_oid_key(*riter, bucket, oid, key);
io_ctx.locator_set_key(key);
}
manifest.obj_size = ofs;
- ret = rgwstore->put_obj_meta(ctx, dest_obj, end + 1, NULL, attrs, category, false, NULL, &first_chunk, &manifest);
+ ret = rgwstore->put_obj_meta(ctx, dest_obj, end + 1, NULL, attrs, category, false, NULL, &first_chunk, &manifest, NULL);
if (mtime)
obj_stat(ctx, dest_obj, NULL, mtime, NULL, NULL);
return ret;
done_err:
- rgwstore->delete_obj(ctx, shadow_obj, false);
+ rgwstore->delete_obj(ctx, shadow_obj);
finish_get_obj(&handle);
return r;
}
} while (is_truncated);
rgw_obj obj(rgw_root_bucket, bucket.name);
- r = delete_obj(NULL, obj, true);
+ r = delete_obj(NULL, obj);
if (r < 0)
return r;
ObjectWriteOperation op;
- cls_refcount_put(op);
+ op.remove();
string oid = dir_oid_prefix;
oid.append(bucket.marker);
librados::AioCompletion *completion = rados->aio_create_completion(NULL, NULL, NULL);
* obj: name of the object to delete
* Returns: 0 on success, -ERR# otherwise.
*/
-int RGWRados::delete_obj_impl(void *ctx, rgw_obj& obj, bool sync)
+int RGWRados::delete_obj_impl(void *ctx, rgw_obj& obj)
{
rgw_bucket bucket;
std::string oid, key;
ObjectWriteOperation op;
RGWObjState *state;
- r = prepare_atomic_for_write(rctx, obj, op, &state, false);
+ r = prepare_atomic_for_write(rctx, obj, op, &state, false, NULL);
if (r < 0)
return r;
bool ret_not_existed = (state && !state->exists);
string tag;
- cls_refcount_put(op);
- if (sync) {
- r = prepare_update_index(state, bucket, obj, tag);
- if (r < 0)
- return r;
- r = io_ctx.operate(oid, &op);
- bool removed = (r >= 0);
+ r = prepare_update_index(state, bucket, obj, tag);
+ if (r < 0)
+ return r;
+ cls_refcount_put(op, tag, true);
+ r = io_ctx.operate(oid, &op);
+ bool removed = (r >= 0);
- if ((r >= 0 || r == -ENOENT) && bucket.marker.size()) {
- uint64_t epoch = io_ctx.get_last_version();
- r = complete_update_index_del(bucket, obj.object, tag, epoch);
- } else {
- int ret = complete_update_index_cancel(bucket, obj.object, tag);
- if (ret < 0) {
- ldout(cct, 0) << "ERROR: complete_update_index_cancel returned ret=" << ret << dendl;
- }
+ if ((r >= 0 || r == -ENOENT) && bucket.marker.size()) {
+ uint64_t epoch = io_ctx.get_last_version();
+ r = complete_update_index_del(bucket, obj.object, tag, epoch);
+ } else {
+ int ret = complete_update_index_cancel(bucket, obj.object, tag);
+ if (ret < 0) {
+ ldout(cct, 0) << "ERROR: complete_update_index_cancel returned ret=" << ret << dendl;
}
- if (removed) {
- int ret = complete_atomic_overwrite(rctx, state, obj);
- if (ret < 0) {
- ldout(cct, 0) << "ERROR: complete_atomic_removal returned ret=" << ret << dendl;
- }
- /* other than that, no need to propagate error */
+ }
+ if (removed) {
+ int ret = complete_atomic_overwrite(rctx, state, obj);
+ if (ret < 0) {
+ ldout(cct, 0) << "ERROR: complete_atomic_removal returned ret=" << ret << dendl;
}
- } else {
- librados::AioCompletion *completion = rados->aio_create_completion(NULL, NULL, NULL);
- r = io_ctx.aio_operate(oid, completion, &op);
- completion->release();
+ /* other than that, no need to propagate error */
}
atomic_write_finish(state, r);
return 0;
}
-int RGWRados::delete_obj(void *ctx, rgw_obj& obj, bool sync)
+int RGWRados::delete_obj(void *ctx, rgw_obj& obj)
{
int r;
- r = delete_obj_impl(ctx, obj, sync);
+ r = delete_obj_impl(ctx, obj);
if (r == -ECANCELED)
r = 0;
int RGWRados::prepare_atomic_for_write_impl(RGWRadosCtx *rctx, rgw_obj& obj,
ObjectWriteOperation& op, RGWObjState **pstate,
- bool reset_obj)
+ bool reset_obj, const string *ptag)
{
int r = get_obj_state(rctx, obj, pstate);
if (r < 0)
}
string tag;
- append_rand_alpha(cct, tag, tag, 32);
+ if (ptag) {
+ tag = *ptag;
+ } else {
+ append_rand_alpha(cct, tag, tag, 32);
+ }
bufferlist bl;
bl.append(tag.c_str(), tag.size() + 1);
+ ldout(cct, 0) << "setting object tag=" << tag << dendl;
+
op.setxattr(RGW_ATTR_ID_TAG, bl);
string shadow = obj.object;
int RGWRados::prepare_atomic_for_write(RGWRadosCtx *rctx, rgw_obj& obj,
ObjectWriteOperation& op, RGWObjState **pstate,
- bool reset_obj)
+ bool reset_obj, const string *ptag)
{
if (!rctx) {
*pstate = NULL;
}
int r;
- r = prepare_atomic_for_write_impl(rctx, obj, op, pstate, reset_obj);
+ r = prepare_atomic_for_write_impl(rctx, obj, op, pstate, reset_obj, ptag);
return r;
}
}
}
RGWObjState *state;
- r = prepare_atomic_for_write(rctx, dst_obj, op, &state, true);
+ r = prepare_atomic_for_write(rctx, dst_obj, op, &state, true, NULL);
if (r < 0)
return r;
complete = false;
break;
}
- r = rgwstore->delete_obj(NULL, entry.obj, false);
+ r = rgwstore->delete_obj(NULL, entry.obj);
if (r < 0 && r != -ENOENT) {
cerr << "failed to remove obj: " << entry.obj << std::endl;
complete = false;
if (r < 0)
return r;
ObjectWriteOperation op;
- cls_refcount_put(op);
op.remove();
string oid = dir_oid_prefix;
oid.append(entry.obj.bucket.marker);
rgw_obj obj(bucket, oid);
cout << "completed intent log: " << obj << (purge ? ", purging it" : "") << std::endl;
if (purge) {
- r = delete_obj(NULL, obj, false);
+ r = delete_obj(NULL, obj);
if (r < 0)
cerr << "failed to remove obj: " << obj << std::endl;
}
librados::ObjectOperation& op, RGWObjState **state);
int prepare_atomic_for_write_impl(RGWRadosCtx *rctx, rgw_obj& obj,
librados::ObjectWriteOperation& op, RGWObjState **pstate,
- bool reset_obj);
+ bool reset_obj, const string *ptag);
int prepare_atomic_for_write(RGWRadosCtx *rctx, rgw_obj& obj,
librados::ObjectWriteOperation& op, RGWObjState **pstate,
- bool reset_obj);
+ bool reset_obj, const string *ptag);
void atomic_write_finish(RGWObjState *state, int r) {
if (state && r == -ECANCELED) {
v.push_back(info);
return clone_objs(ctx, dst_obj, v, attrs, category, pmtime, true, false);
}
- int delete_obj_impl(void *ctx, rgw_obj& src_obj, bool sync);
+ int delete_obj_impl(void *ctx, rgw_obj& src_obj);
int complete_atomic_overwrite(RGWRadosCtx *rctx, RGWObjState *state, rgw_obj& obj);
int update_placement_map();
virtual int put_obj_meta(void *ctx, rgw_obj& obj, uint64_t size, time_t *mtime,
map<std::string, bufferlist>& attrs, RGWObjCategory category, bool exclusive,
map<std::string, bufferlist>* rmattrs, const bufferlist *data,
- RGWObjManifest *manifest);
+ RGWObjManifest *manifest, const string *ptag);
virtual int put_obj_data(void *ctx, rgw_obj& obj, const char *data,
off_t ofs, size_t len, bool exclusive);
virtual int aio_put_obj_data(void *ctx, rgw_obj& obj, bufferlist& bl,
time_t *mtime, map<std::string, bufferlist>& attrs) {
bufferlist bl;
bl.append(data, len);
- int ret = put_obj_meta(ctx, obj, len, mtime, attrs, RGW_OBJ_CATEGORY_NONE, exclusive, NULL, &bl, NULL);
+ int ret = put_obj_meta(ctx, obj, len, mtime, attrs, RGW_OBJ_CATEGORY_NONE, exclusive, NULL, &bl, NULL, NULL);
return ret;
}
virtual int aio_wait(void *handle);
virtual int bucket_suspended(rgw_bucket& bucket, bool *suspended);
/** Delete an object.*/
- virtual int delete_obj(void *ctx, rgw_obj& src_obj, bool sync = true);
+ virtual int delete_obj(void *ctx, rgw_obj& src_obj);
/**
* Get the attributes for an object.