From 7f1392865367624b2738608e02284e2a1964202f Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Mon, 27 Oct 2014 17:09:57 -0700 Subject: [PATCH] rgw, cls_rgw: multiple changes related to obj removal Signed-off-by: Yehuda Sadeh --- src/cls/rgw/cls_rgw.cc | 57 ++++++++++++++++++++++++++---------------- src/rgw/rgw_common.h | 11 +++++--- src/rgw/rgw_op.cc | 12 ++++----- src/rgw/rgw_rados.cc | 23 ++++++----------- src/rgw/rgw_rados.h | 6 ++--- 5 files changed, 59 insertions(+), 50 deletions(-) diff --git a/src/cls/rgw/cls_rgw.cc b/src/cls/rgw/cls_rgw.cc index d57281286144e..787514fbf9f21 100644 --- a/src/cls/rgw/cls_rgw.cc +++ b/src/cls/rgw/cls_rgw.cc @@ -1013,23 +1013,31 @@ static void update_olh_log(struct rgw_bucket_olh_entry& olh_data_entry, OLHLogOp 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) { @@ -1078,6 +1086,7 @@ public: 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); @@ -1109,6 +1118,7 @@ public: 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) { @@ -1263,6 +1273,7 @@ static int convert_plain_entry_to_versioned(cls_method_context_t hctx, cls_rgw_o } } + entry.key = key; entry.flags = RGW_BUCKET_DIRENT_FLAG_VER_MARKER; ret = write_entry(hctx, entry, key.name); if (ret < 0) { @@ -1304,19 +1315,22 @@ static int rgw_bucket_link_olh(cls_method_context_t hctx, bufferlist *in, buffer 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; } @@ -1375,8 +1389,13 @@ static int rgw_bucket_unlink_instance(cls_method_context_t hctx, bufferlist *in, 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) { @@ -1393,7 +1412,7 @@ static int rgw_bucket_unlink_instance(cls_method_context_t hctx, bufferlist *in, 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; @@ -1799,6 +1818,8 @@ static int list_plain_entries(cls_method_context_t hctx, const string& name, con 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; } @@ -1812,14 +1833,6 @@ static int list_plain_entries(cls_method_context_t hctx, const string& name, con 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 *entries) { diff --git a/src/rgw/rgw_common.h b/src/rgw/rgw_common.h index 578526e417f59..a2c9b0a7d822a 100644 --- a/src/rgw/rgw_common.h +++ b/src/rgw/rgw_common.h @@ -785,7 +785,8 @@ struct RGWBucketInfo 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) {} }; @@ -1172,11 +1173,15 @@ public: 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; } @@ -1189,7 +1194,7 @@ public: } else { object = "_"; object.append(ns); - if (!instance.empty()) { + if (have_instance()) { object.append(string(":") + instance); } object.append("_"); diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index f1ac63d942775..670f20bc020fb 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -2111,7 +2111,7 @@ void RGWDeleteObj::execute() 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()); } } @@ -2972,7 +2972,7 @@ void RGWCompleteMultipart::execute() } // 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; } @@ -3032,7 +3032,7 @@ void RGWAbortMultipart::execute() 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 { @@ -3040,7 +3040,7 @@ void RGWAbortMultipart::execute() 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; } @@ -3051,7 +3051,7 @@ void RGWAbortMultipart::execute() // 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; } @@ -3213,7 +3213,7 @@ void RGWDeleteMultiObj::execute() 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; } diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index 89ee71386fd59..cbb800fb457ad 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -3922,10 +3922,12 @@ int RGWRados::Object::Delete::delete_obj() 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) { @@ -3998,17 +4000,6 @@ int RGWRados::Object::Delete::delete_obj() 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; @@ -4020,13 +4011,13 @@ int RGWRados::Object::Delete::delete_obj() 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(); } @@ -5668,7 +5659,7 @@ int RGWRados::apply_olh_log(RGWObjectCtx& obj_ctx, const string& bucket_owner, r 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; diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h index f57681643e3e7..f096475d91f99 100644 --- a/src/rgw/rgw_rados.h +++ b/src/rgw/rgw_rados.h @@ -1452,9 +1452,9 @@ public: 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) {} @@ -1602,7 +1602,7 @@ public: 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); -- 2.39.5