log_entry.delete_marker = delete_marker;
}
+static string escape_str(const string& s)
+{
+ int len = escape_json_attr_len(s.c_str(), s.size());
+ char escaped[len];
+ escape_json_attr(s.c_str(), s.size(), escaped);
+ return string(escaped);
+}
+
/*
* write object instance entry, and if needed also the list entry
*/
static int write_obj_entries(cls_method_context_t hctx, struct rgw_bucket_dir_entry& instance_entry, const string& instance_idx)
{
- CLS_LOG(20, "write_entry() instance=%s idx=%s flags=%d", instance_entry.key.instance.c_str(), instance_idx.c_str(), instance_entry.flags);
+ CLS_LOG(20, "write_entry() instance=%s idx=%s flags=%d", escape_str(instance_entry.key.instance).c_str(), instance_idx.c_str(), instance_entry.flags);
/* write the instance entry */
int ret = write_entry(hctx, instance_entry, instance_idx);
if (ret < 0) {
- CLS_LOG(0, "ERROR: write_entry() instance_key=%s ret=%d", instance_idx.c_str(), ret);
+ CLS_LOG(0, "ERROR: write_entry() instance_key=%s ret=%d", escape_str(instance_idx).c_str(), ret);
return ret;
}
string instance_list_idx;
get_list_index_key(instance_entry, &instance_list_idx);
if (instance_idx != instance_list_idx) {
- CLS_LOG(20, "write_entry() idx=%s flags=%d", instance_list_idx.c_str(), instance_entry.flags);
+ CLS_LOG(20, "write_entry() idx=%s flags=%d", escape_str(instance_list_idx).c_str(), instance_entry.flags);
/* write a new list entry for the object instance */
ret = write_entry(hctx, instance_entry, instance_list_idx);
if (ret < 0) {
string list_idx;
/* this instance has a previous list entry, remove that entry */
get_list_index_key(instance_entry, &list_idx);
+ CLS_LOG(20, "unlink_list_entry() list_idx=%s", escape_str(list_idx).c_str());
int ret = cls_cxx_map_remove_key(hctx, list_idx);
if (ret < 0) {
CLS_LOG(0, "ERROR: cls_cxx_map_remove_key() list_idx=%s ret=%d", list_idx.c_str(), ret);
int set_current(uint64_t epoch) {
if (instance_entry.ver.epoch > 0) {
+ CLS_LOG(20, "%s(): instance_entry.ver.epoch=%d epoch=%d", __func__, (int)instance_entry.ver.epoch, (int)epoch);
/* this instance has a previous list entry, remove that entry */
int ret = unlink_list_entry();
if (ret < 0) {
}
}
+ entry.key = key;
entry.flags = RGW_BUCKET_DIRENT_FLAG_VER_MARKER;
ret = write_entry(hctx, entry, key.name);
if (ret < 0) {
BIOLHEntry olh(hctx, op.key);
/* read instance entry */
- if (!op.delete_marker) {
- int ret = obj.init();
- if (ret < 0) {
- return ret;
- }
- } else {
- /* a deletion marker, need to initialize it, there's no instance entry for it yet */
+ int ret = obj.init();
+ if (ret == -ENOENT && op.delete_marker) {
+ ret = 0;
+ }
+ if (ret < 0) {
+ return ret;
+ }
+
+ if (op.delete_marker) {
+ /* a deletion marker, need to initialize entry as such */
obj.init_as_delete_marker();
}
/* read olh */
bool olh_found;
- int ret = olh.init(&olh_found);
+ ret = olh.init(&olh_found);
if (ret < 0) {
return ret;
}
return -EINVAL;
}
- BIVerObjEntry obj(hctx, op.key);
- BIOLHEntry olh(hctx, op.key);
+ cls_rgw_obj_key dest_key = op.key;
+ if (dest_key.instance == "null") {
+ dest_key.instance.clear();
+ }
+
+ BIVerObjEntry obj(hctx, dest_key);
+ BIOLHEntry olh(hctx, dest_key);
int ret = obj.init();
if (ret == -ENOENT) {
return ret;
}
- if (olh.get_entry().key == op.key) {
+ if (olh.get_entry().key == dest_key) {
/* this is the current head, need to update! */
cls_rgw_obj_key next_key;
bool found;
return -EIO;
}
+ CLS_LOG(20, "%s(): entry.idx=%s e.key.name=%s", __func__, escape_str(entry.idx).c_str(), escape_str(e.key.name).c_str());
+
if (e.key.name != name) {
return count;
}
return count;
}
-static string escape_str(const string& s)
-{
- int len = escape_json_attr_len(s.c_str(), s.size());
- char escaped[len];
- escape_json_attr(s.c_str(), s.size(), escaped);
- return string(escaped);
-}
-
static int list_instance_entries(cls_method_context_t hctx, const string& name, const string& marker, uint32_t max,
list<rgw_cls_bi_entry> *entries)
{
void decode_json(JSONObj *obj);
bool versioned() { return (flags & BUCKET_VERSIONED) != 0; }
- bool versioning_enabled() { return (flags & (BUCKET_VERSIONED | BUCKET_VERSIONS_SUSPENDED)) == BUCKET_VERSIONED; }
+ int versioning_status() { return flags & (BUCKET_VERSIONED | BUCKET_VERSIONS_SUSPENDED); }
+ bool versioning_enabled() { return versioning_status() == BUCKET_VERSIONED; }
RGWBucketInfo() : flags(0), creation_time(0), has_instance_obj(false) {}
};
loc.clear();
}
+ bool have_instance() {
+ return !instance.empty() && instance != "null";
+ }
+
void set_obj(const string& o) {
object.reserve(128);
orig_obj = o;
- if (ns.empty() && instance.empty()) {
+ if (ns.empty() && !have_instance()) {
if (o.empty()) {
return;
}
} else {
object = "_";
object.append(ns);
- if (!instance.empty()) {
+ if (have_instance()) {
object.append(string(":") + instance);
}
object.append("_");
obj_ctx->set_atomic(obj);
- ret = store->delete_obj(*obj_ctx, s->bucket_owner.get_id(), obj, s->bucket_info.versioning_enabled());
+ ret = store->delete_obj(*obj_ctx, s->bucket_owner.get_id(), obj, s->bucket_info.versioning_status());
}
}
}
// remove the upload obj
- int r = store->delete_obj(*(RGWObjectCtx *)s->obj_ctx, s->bucket_owner.get_id(), meta_obj, false);
+ int r = store->delete_obj(*(RGWObjectCtx *)s->obj_ctx, s->bucket_owner.get_id(), meta_obj, 0);
if (r < 0) {
ldout(store->ctx(), 0) << "WARNING: failed to remove object " << meta_obj << dendl;
}
string oid = mp.get_part(obj_iter->second.num);
rgw_obj obj;
obj.init_ns(s->bucket, oid, mp_ns);
- ret = store->delete_obj(*obj_ctx, owner, obj, false);
+ ret = store->delete_obj(*obj_ctx, owner, obj, 0);
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(*obj_ctx, owner, loc, false);
+ ret = store->delete_obj(*obj_ctx, owner, loc, 0);
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(*obj_ctx, owner, meta_obj, false);
+ ret = store->delete_obj(*obj_ctx, owner, meta_obj, 0);
if (ret == -ENOENT) {
ret = -ERR_NO_SUCH_BUCKET;
}
rgw_obj obj(bucket,(*iter));
obj_ctx->set_atomic(obj);
- ret = store->delete_obj(*obj_ctx, s->bucket_owner.get_id(), obj, s->bucket_info.versioning_enabled());
+ ret = store->delete_obj(*obj_ctx, s->bucket_owner.get_id(), obj, s->bucket_info.versioning_status());
if (ret == -ENOENT) {
ret = 0;
}
RGWRados *store = target->get_store();
rgw_obj& obj = target->get_obj();
- if (params.use_versioning) {
+ if (params.versioning_status & BUCKET_VERSIONED) {
if (obj.get_instance().empty()) {
rgw_obj marker = obj;
- store->gen_rand_obj_instance_name(&marker);
+ if ((params.versioning_status & BUCKET_VERSIONS_SUSPENDED) == 0) {
+ store->gen_rand_obj_instance_name(&marker);
+ }
int r = store->set_olh(target->get_ctx(), params.bucket_owner, marker, true);
if (r < 0) {
if (r < 0)
return r;
- /* need to insert a delete marker? */
- if (params.use_versioning && obj.get_instance().empty()) {
- rgw_obj marker = obj;
- store->gen_rand_obj_instance_name(&marker);
-
- r = store->set_olh(target->get_ctx(), params.bucket_owner, marker, true);
- if (r < 0) {
- return r;
- }
- }
-
if (ret_not_existed)
return -ENOENT;
return 0;
}
-int RGWRados::delete_obj(RGWObjectCtx& obj_ctx, const string& bucket_owner, rgw_obj& obj, bool use_versioning)
+int RGWRados::delete_obj(RGWObjectCtx& obj_ctx, const string& bucket_owner, rgw_obj& obj, int versioning_status)
{
RGWRados::Object del_target(this, obj_ctx, obj);
RGWRados::Object::Delete del_op(&del_target);
del_op.params.bucket_owner = bucket_owner;
- del_op.params.use_versioning = use_versioning;
+ del_op.params.versioning_status = versioning_status;
return del_op.delete_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, 0);
if (ret < 0 && ret != -ENOENT) {
ldout(cct, 0) << "ERROR: delete_obj() returned " << ret << " obj_instance=" << obj_instance << dendl;
return ret;
struct DeleteParams {
string bucket_owner;
- bool use_versioning;
+ int versioning_status;
- DeleteParams() : use_versioning(false) {}
+ DeleteParams() : versioning_status(0) {}
} params;
Delete(RGWRados::Object *_target) : target(_target) {}
int bucket_suspended(rgw_bucket& bucket, bool *suspended);
/** Delete an object.*/
- virtual int delete_obj(RGWObjectCtx& obj_ctx, const string& bucket_owner, rgw_obj& src_obj, bool use_versioning);
+ virtual int delete_obj(RGWObjectCtx& obj_ctx, const string& bucket_owner, rgw_obj& src_obj, int versioning_status);
/* Delete a system object */
virtual int delete_system_obj(rgw_obj& src_obj, RGWObjVersionTracker *objv_tracker = NULL);