rgw_obj obj(bucket, key);
- int ret = store->delete_obj((void *)&rctx, bucket_owner, obj, use_versioning);
+ int ret = store->delete_obj(rctx, bucket_owner, obj, use_versioning);
return ret;
}
rgw_obj obj(bucket, oid);
- ret = store->delete_system_obj(NULL, obj, objv_tracker);
+ ret = store->delete_system_obj(obj, objv_tracker);
/* cascading ret into post_modify() */
ret = post_modify(handler, section, key, log_data, objv_tracker, ret);
ret = -EINVAL;
rgw_obj obj(s->bucket, s->object);
if (!s->object.empty()) {
- store->set_atomic(s->obj_ctx, obj);
- ret = store->delete_obj(s->obj_ctx, s->bucket_owner.get_id(), obj, s->bucket_info.versioning_enabled());
+ RGWRados::ObjectCtx *obj_ctx = (RGWRados::ObjectCtx *)s->obj_ctx;
+
+ obj_ctx->set_atomic(obj);
+
+ ret = store->delete_obj(*obj_ctx, s->bucket_owner.get_id(), obj, s->bucket_info.versioning_enabled());
}
}
}
// remove the upload obj
- store->delete_obj(&obj_ctx, s->bucket_owner.get_id(), meta_obj, false);
+ int r = store->delete_obj(*(RGWRados::ObjectCtx *)s->obj_ctx, s->bucket_owner.get_id(), meta_obj, false);
+ if (r < 0) {
+ ldout(store->ctx(), 0) << "WARNING: failed to remove object " << meta_obj << dendl;
+ }
}
int RGWAbortMultipart::verify_permission()
int marker = 0;
int max_parts = 1000;
+ RGWRados::ObjectCtx *obj_ctx = (RGWRados::ObjectCtx *)s->obj_ctx;
+
do {
ret = list_multipart_parts(store, s, upload_id, meta_oid, max_parts, marker, obj_parts, &marker, &truncated);
if (ret < 0)
string oid = mp.get_part(obj_iter->second.num);
rgw_obj obj;
obj.init_ns(s->bucket, oid, mp_ns);
- ret = store->delete_obj(s->obj_ctx, owner, obj, false);
+ ret = store->delete_obj(*obj_ctx, owner, obj, false);
if (ret < 0 && ret != -ENOENT)
return;
} else {
RGWObjManifest::obj_iterator oiter;
for (oiter = manifest.obj_begin(); oiter != manifest.obj_end(); ++oiter) {
rgw_obj loc = oiter.get_location();
- ret = store->delete_obj(s->obj_ctx, owner, loc, false);
+ ret = store->delete_obj(*obj_ctx, owner, loc, false);
if (ret < 0 && ret != -ENOENT)
return;
}
// and also remove the metadata obj
meta_obj.init_ns(s->bucket, meta_oid, mp_ns);
meta_obj.set_in_extra_data(true);
- ret = store->delete_obj(s->obj_ctx, owner, meta_obj, false);
+ ret = store->delete_obj(*obj_ctx, owner, meta_obj, false);
if (ret == -ENOENT) {
ret = -ERR_NO_SUCH_BUCKET;
}
RGWMultiDelXMLParser parser;
pair<string,int> result;
int num_processed = 0;
+ RGWRados::ObjectCtx *obj_ctx = (RGWRados::ObjectCtx *)s->obj_ctx;
ret = get_params();
if (ret < 0) {
++iter, num_processed++) {
rgw_obj obj(bucket,(*iter));
- store->set_atomic(s->obj_ctx, obj);
- ret = store->delete_obj(s->obj_ctx, s->bucket_owner.get_id(), obj, s->bucket_info.versioning_enabled());
+
+ obj_ctx->set_atomic(obj);
+ ret = store->delete_obj(*obj_ctx, s->bucket_owner.get_id(), obj, s->bucket_info.versioning_enabled());
if (ret == -ENOENT) {
ret = 0;
}
list<rgw_obj>::iterator iter;
for (iter = written_objs.begin(); iter != written_objs.end(); ++iter) {
rgw_obj& obj = *iter;
- int r = store->delete_obj(&obj_ctx, bucket_owner, obj, false);
+ int r = store->delete_obj(obj_ctx, bucket_owner, obj, false);
if (r < 0 && r != -ENOENT) {
ldout(store->ctx(), 0) << "WARNING: failed to remove obj (" << obj << "), leaked" << dendl;
}
* obj: name of the object to delete
* Returns: 0 on success, -ERR# otherwise.
*/
-int RGWRados::delete_obj_impl(void *ctx, const string& bucket_owner, rgw_obj& obj, bool use_versioning, RGWObjVersionTracker *objv_tracker)
+int RGWRados::Object::Delete::delete_obj()
{
+ RGWRados *store = target->get_store();
+ rgw_obj& obj = target->get_obj();
+
rgw_rados_ref ref;
rgw_bucket bucket;
- int r = get_obj_ref(obj, &ref, &bucket);
+ int r = store->get_obj_ref(obj, &ref, &bucket);
if (r < 0) {
return r;
}
- ObjectCtx *rctx = static_cast<ObjectCtx *>(ctx);
ObjectWriteOperation op;
+ r = target->prepare_atomic_modification(op, false, NULL);
+ if (r < 0)
+ return r;
+
RGWObjState *state;
- r = prepare_atomic_for_write(rctx, obj, op, &state, false, NULL);
+ r = target->get_state(&state);
if (r < 0)
return r;
- bool ret_not_existed = (state && !state->exists);
+ bool ret_not_existed = (!state->exists);
- RGWRados::Bucket bop(this, bucket);
+ RGWRados::Bucket bop(store, bucket);
RGWRados::Bucket::UpdateIndex index_op(&bop, obj, state);
string tag;
if (r < 0)
return r;
- if (objv_tracker) {
- objv_tracker->prepare_op_for_write(&op);
- }
-
- remove_rgw_head_obj(op);
+ store->remove_rgw_head_obj(op);
r = ref.ioctx.operate(ref.oid, &op);
+ if (r == -ECANCELED) {
+ /* raced with another operation, we can regard it as removed */
+ r = 0;
+ }
bool removed = (r >= 0);
int64_t poolid = ref.ioctx.get_id();
} else {
int ret = index_op.cancel();
if (ret < 0) {
- ldout(cct, 0) << "ERROR: index_op.cancel() returned ret=" << ret << dendl;
+ ldout(store->ctx(), 0) << "ERROR: index_op.cancel() returned ret=" << ret << dendl;
}
}
if (removed) {
- int ret = index_op.complete_atomic_modification();
+ int ret = target->complete_atomic_modification();
if (ret < 0) {
- ldout(cct, 0) << "ERROR: complete_atomic_removal returned ret=" << ret << dendl;
+ ldout(store->ctx(), 0) << "ERROR: complete_atomic_modification returned ret=" << ret << dendl;
}
/* other than that, no need to propagate error */
}
- atomic_write_finish(state, r);
+ store->atomic_write_finish(state, r);
if (r < 0)
return r;
/* need to insert a delete marker? */
- if (use_versioning && obj.get_instance().empty()) {
+ if (params.use_versioning && obj.get_instance().empty()) {
rgw_obj marker = obj;
- gen_rand_obj_instance_name(&marker);
+ store->gen_rand_obj_instance_name(&marker);
- r = set_olh(*rctx, bucket_owner, marker, true);
+ r = store->set_olh(target->get_ctx(), params.bucket_owner, marker, true);
if (r < 0) {
return r;
}
if (state) {
/* update quota cache */
- quota_handler->update_stats(bucket_owner, bucket, -1, 0, state->size);
+ store->quota_handler->update_stats(params.bucket_owner, bucket, -1, 0, state->size);
}
return 0;
}
-int RGWRados::delete_obj(void *ctx, const string& bucket_owner, rgw_obj& obj, bool use_versioning, RGWObjVersionTracker *objv_tracker)
+int RGWRados::delete_obj(RGWRados::ObjectCtx& obj_ctx, const string& bucket_owner, rgw_obj& obj, bool use_versioning)
{
- int r;
+ RGWRados::Object del_target(this, obj_ctx, obj);
+ RGWRados::Object::Delete del_op(&del_target);
- r = delete_obj_impl(ctx, bucket_owner, obj, use_versioning, objv_tracker);
- if (r == -ECANCELED)
- r = 0;
+ del_op.params.bucket_owner = bucket_owner;
+ del_op.params.use_versioning = use_versioning;
- return r;
+ return del_op.delete_obj();
}
-int RGWRados::delete_system_obj(void *ctx, rgw_obj& obj, RGWObjVersionTracker *objv_tracker)
+int RGWRados::delete_system_obj(rgw_obj& obj, RGWObjVersionTracker *objv_tracker)
{
- int r;
+ rgw_rados_ref ref;
+ rgw_bucket bucket;
+ int r = get_obj_ref(obj, &ref, &bucket);
+ if (r < 0) {
+ return r;
+ }
- string no_owner;
- r = delete_obj_impl(ctx, no_owner, obj, false, objv_tracker);
- if (r == -ECANCELED)
- r = 0;
+ ObjectWriteOperation op;
- return r;
+ if (objv_tracker) {
+ objv_tracker->prepare_op_for_write(&op);
+ }
+
+ remove_rgw_head_obj(op);
+ r = ref.ioctx.operate(ref.oid, &op);
+ if (r < 0)
+ return r;
+
+ return 0;
}
int RGWRados::delete_obj_index(rgw_obj& obj)
cls_rgw_obj_key& key = *liter;
rgw_obj obj_instance(bucket, key.name);
obj_instance.set_instance(key.instance);
- int ret = delete_obj(&obj_ctx, bucket_owner, obj_instance, false);
+ int ret = delete_obj(obj_ctx, bucket_owner, obj_instance, false);
if (ret < 0 && ret != -ENOENT) {
ldout(cct, 0) << "ERROR: delete_obj() returned " << ret << " obj_instance=" << obj_instance << dendl;
return ret;
}
struct rgw_intent_log_entry entry;
+ RGWRados::ObjectCtx obj_ctx(this);
try {
::decode(entry, iter);
} catch (buffer::error& err) {
complete = false;
break;
}
- r = delete_obj(NULL, no_owner, entry.obj, false);
+ r = delete_obj(obj_ctx, no_owner, entry.obj, false);
if (r < 0 && r != -ENOENT) {
cerr << "failed to remove obj: " << entry.obj << std::endl;
complete = false;
rgw_obj obj(bucket, oid);
cout << "completed intent log: " << obj << (purge ? ", purging it" : "") << std::endl;
if (purge) {
- r = delete_system_obj(NULL, obj);
+ r = delete_system_obj(obj);
if (r < 0)
cerr << "failed to remove obj: " << obj << std::endl;
}
void remove_rgw_head_obj(librados::ObjectWriteOperation& op);
protected:
- virtual int delete_obj_impl(void *ctx, const string& bucket_owner, rgw_obj& src_obj, bool use_versioning, RGWObjVersionTracker *objv_tracker);
-
CephContext *cct;
librados::Rados *rados;
librados::IoCtx gc_pool_ctx; // .rgw.gc
RGWRados *get_store() { return store; }
rgw_obj& get_obj() { return obj; }
+ RGWRados::ObjectCtx& get_ctx() { return ctx; }
struct Write {
RGWRados::Object *target;
int write_meta(uint64_t size, map<std::string, bufferlist>& attrs);
int write_data(const char *data, uint64_t ofs, uint64_t len, bool exclusive);
};
+
+ struct Delete {
+ RGWRados::Object *target;
+
+ struct DeleteParams {
+ string bucket_owner;
+ bool use_versioning;
+
+ DeleteParams() : use_versioning(false) {}
+ } params;
+
+ Delete(RGWRados::Object *_target) : target(_target) {}
+
+ int delete_obj();
+ };
};
class Bucket {
int bucket_suspended(rgw_bucket& bucket, bool *suspended);
/** Delete an object.*/
- virtual int delete_obj(void *ctx, const string& bucket_owner, rgw_obj& src_obj, bool use_versioning, RGWObjVersionTracker *objv_tracker = NULL);
- virtual int delete_system_obj(void *ctx, rgw_obj& src_obj, RGWObjVersionTracker *objv_tracker = NULL);
+ virtual int delete_obj(RGWRados::ObjectCtx& obj_ctx, const string& bucket_owner, rgw_obj& src_obj, bool use_versioning);
+
+ /* Delete a system object */
+ virtual int delete_system_obj(rgw_obj& src_obj, RGWObjVersionTracker *objv_tracker = NULL);
/** Remove an object from the bucket index */
int delete_obj_index(rgw_obj& obj);
int rgw_remove_key_index(RGWRados *store, RGWAccessKey& access_key)
{
rgw_obj obj(store->zone.user_keys_pool, access_key.id);
- int ret = store->delete_system_obj(NULL, obj);
+ int ret = store->delete_system_obj(obj);
return ret;
}
int rgw_remove_email_index(RGWRados *store, string& email)
{
rgw_obj obj(store->zone.user_email_pool, email);
- int ret = store->delete_system_obj(NULL, obj);
+ int ret = store->delete_system_obj(obj);
return ret;
}
int rgw_remove_swift_name_index(RGWRados *store, string& swift_name)
{
rgw_obj obj(store->zone.user_swift_pool, swift_name);
- int ret = store->delete_system_obj(NULL, obj);
+ int ret = store->delete_system_obj(obj);
return ret;
}
rgw_obj email_obj(store->zone.user_email_pool, info.user_email);
ldout(store->ctx(), 10) << "removing email index: " << info.user_email << dendl;
- ret = store->delete_system_obj(NULL, email_obj);
+ ret = store->delete_system_obj(email_obj);
if (ret < 0 && ret != -ENOENT) {
ldout(store->ctx(), 0) << "ERROR: could not remove " << info.user_id << ":" << email_obj << ", should be fixed (err=" << ret << ")" << dendl;
return ret;
rgw_get_buckets_obj(info.user_id, buckets_obj_id);
rgw_obj uid_bucks(store->zone.user_uid_pool, buckets_obj_id);
ldout(store->ctx(), 10) << "removing user buckets index" << dendl;
- ret = store->delete_system_obj(NULL, uid_bucks);
+ ret = store->delete_system_obj(uid_bucks);
if (ret < 0 && ret != -ENOENT) {
ldout(store->ctx(), 0) << "ERROR: could not remove " << info.user_id << ":" << uid_bucks << ", should be fixed (err=" << ret << ")" << dendl;
return ret;