From 8d25ec63e63eaaf49f683831054e0e586afc6480 Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Mon, 29 Sep 2014 15:10:02 -0700 Subject: [PATCH] rgw: bucket versioning status is tri-state disabled, enabled, suspended. Signed-off-by: Yehuda Sadeh --- src/rgw/rgw_common.h | 15 ++++++++------- src/rgw/rgw_json_enc.cc | 2 -- src/rgw/rgw_op.cc | 29 +++++++++++++++++++++++++---- src/rgw/rgw_op.h | 3 ++- src/rgw/rgw_rados.cc | 21 +++++++++++++-------- src/rgw/rgw_rados.h | 2 ++ src/rgw/rgw_rest_s3.cc | 7 ++++++- 7 files changed, 56 insertions(+), 23 deletions(-) diff --git a/src/rgw/rgw_common.h b/src/rgw/rgw_common.h index a2344c021a603..578526e417f59 100644 --- a/src/rgw/rgw_common.h +++ b/src/rgw/rgw_common.h @@ -727,6 +727,8 @@ struct RGWObjVersionTracker { enum RGWBucketFlags { BUCKET_SUSPENDED = 0x1, + BUCKET_VERSIONED = 0x2, + BUCKET_VERSIONS_SUSPENDED = 0x4, }; struct RGWBucketInfo @@ -741,10 +743,9 @@ struct RGWBucketInfo RGWObjVersionTracker objv_tracker; /* we don't need to serialize this, for runtime tracking */ obj_version ep_objv; /* entry point object version, for runtime tracking only */ RGWQuotaInfo quota; - bool versioning_enabled; void encode(bufferlist& bl) const { - ENCODE_START(10, 4, bl); + ENCODE_START(9, 4, bl); ::encode(bucket, bl); ::encode(owner, bl); ::encode(flags, bl); @@ -754,11 +755,10 @@ struct RGWBucketInfo ::encode(placement_rule, bl); ::encode(has_instance_obj, bl); ::encode(quota, bl); - ::encode(versioning_enabled, bl); ENCODE_FINISH(bl); } void decode(bufferlist::iterator& bl) { - DECODE_START_LEGACY_COMPAT_LEN_32(6, 4, 4, bl); + DECODE_START_LEGACY_COMPAT_LEN_32(9, 4, 4, bl); ::decode(bucket, bl); if (struct_v >= 2) ::decode(owner, bl); @@ -777,8 +777,6 @@ struct RGWBucketInfo ::decode(has_instance_obj, bl); if (struct_v >= 9) ::decode(quota, bl); - if (struct_v >= 10) - ::decode(versioning_enabled, bl); DECODE_FINISH(bl); } void dump(Formatter *f) const; @@ -786,7 +784,10 @@ struct RGWBucketInfo void decode_json(JSONObj *obj); - RGWBucketInfo() : flags(0), creation_time(0), has_instance_obj(false), versioning_enabled(false) {} + bool versioned() { return (flags & BUCKET_VERSIONED) != 0; } + bool versioning_enabled() { return (flags & (BUCKET_VERSIONED | BUCKET_VERSIONS_SUSPENDED)) == BUCKET_VERSIONED; } + + RGWBucketInfo() : flags(0), creation_time(0), has_instance_obj(false) {} }; WRITE_CLASS_ENCODER(RGWBucketInfo) diff --git a/src/rgw/rgw_json_enc.cc b/src/rgw/rgw_json_enc.cc index 3585c8ffe3737..9a21f26cb2c2a 100644 --- a/src/rgw/rgw_json_enc.cc +++ b/src/rgw/rgw_json_enc.cc @@ -552,7 +552,6 @@ void RGWBucketInfo::dump(Formatter *f) const encode_json("placement_rule", placement_rule, f); encode_json("has_instance_obj", has_instance_obj, f); encode_json("quota", quota, f); - encode_json("versioning_enabled", versioning_enabled, f); } void RGWBucketInfo::decode_json(JSONObj *obj) { @@ -564,7 +563,6 @@ void RGWBucketInfo::decode_json(JSONObj *obj) { JSONDecoder::decode_json("placement_rule", placement_rule, obj); JSONDecoder::decode_json("has_instance_obj", has_instance_obj, obj); JSONDecoder::decode_json("quota", quota, obj); - JSONDecoder::decode_json("versioning_enabled", versioning_enabled, obj); } void RGWObjEnt::dump(Formatter *f) const diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index 6cb7e86dfe4fa..a05ecec4e6494 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -1051,7 +1051,8 @@ void RGWGetBucketVersioning::pre_exec() void RGWGetBucketVersioning::execute() { - versioning_enabled = s->bucket_info.versioning_enabled; + versioned = s->bucket_info.versioned(); + versioning_enabled = s->bucket_info.versioning_enabled(); send_response(); } @@ -1077,7 +1078,15 @@ void RGWSetBucketVersioning::execute() if (ret < 0) goto done; - s->bucket_info.versioning_enabled = true; + if (enable_versioning) { + s->bucket_info.flags |= BUCKET_VERSIONED; + s->bucket_info.flags &= ~BUCKET_VERSIONS_SUSPENDED; + } else if (s->bucket_info.versioned()) { + s->bucket_info.flags |= BUCKET_VERSIONS_SUSPENDED; + } else { + ret = -EINVAL; + goto done; + } ret = store->put_bucket_instance_info(s->bucket_info, false, 0, &s->bucket_attrs); if (ret < 0) { @@ -1582,7 +1591,7 @@ RGWPutObjProcessor *RGWPutObj::select_processor(bool *is_multipart) const string& bucket_owner = s->bucket_owner.get_id(); if (!multipart) { - processor = new RGWPutObjProcessor_Atomic(bucket_owner, s->bucket, s->object.name, part_size, s->req_id, s->bucket_info.versioning_enabled); + processor = new RGWPutObjProcessor_Atomic(bucket_owner, s->bucket, s->object.name, part_size, s->req_id, s->bucket_info.versioning_enabled()); } else { processor = new RGWPutObjProcessor_Multipart(bucket_owner, part_size, s); } @@ -1829,7 +1838,7 @@ RGWPutObjProcessor *RGWPostObj::select_processor() uint64_t part_size = s->cct->_conf->rgw_obj_stripe_size; - processor = new RGWPutObjProcessor_Atomic(s->bucket_owner.get_id(), s->bucket, s->object.name, part_size, s->req_id, s->bucket_info.versioning_enabled); + processor = new RGWPutObjProcessor_Atomic(s->bucket_owner.get_id(), s->bucket, s->object.name, part_size, s->req_id, s->bucket_info.versioning_enabled()); return processor; } @@ -2788,6 +2797,8 @@ void RGWCompleteMultipart::execute() list remove_objs; /* objects to be removed from index listing */ + bool versioned_object = s->bucket_info.versioning_enabled(); + iter = parts->parts.begin(); meta_obj.init_ns(s->bucket, meta_oid, mp_ns); @@ -2873,6 +2884,9 @@ void RGWCompleteMultipart::execute() attrs[RGW_ATTR_ETAG] = etag_bl; target_obj.init(s->bucket, s->object.name); + if (versioned_object) { + store->gen_rand_obj_instance_name(&target_obj); + } store->set_atomic(s->obj_ctx, target_obj); @@ -2890,6 +2904,13 @@ void RGWCompleteMultipart::execute() if (ret < 0) return; + if (versioned_object) { + ret = store->set_olh(s->obj_ctx, s->bucket_owner.get_id(), target_obj, false); + if (ret < 0) { + return; + } + } + // remove the upload obj store->delete_obj(s->obj_ctx, s->bucket_owner.get_id(), meta_obj); } diff --git a/src/rgw/rgw_op.h b/src/rgw/rgw_op.h index 776f213fea511..9288667b3b4bb 100644 --- a/src/rgw/rgw_op.h +++ b/src/rgw/rgw_op.h @@ -292,9 +292,10 @@ public: class RGWGetBucketVersioning : public RGWOp { protected: + bool versioned; bool versioning_enabled; public: - RGWGetBucketVersioning() : versioning_enabled(false) {} + RGWGetBucketVersioning() : versioned(false), versioning_enabled(false) {} int verify_permission(); void pre_exec(); diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index 3423af3e8c78c..943054a0b88d2 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -1132,12 +1132,7 @@ int RGWPutObjProcessor_Atomic::prepare(RGWRados *store, void *obj_ctx, string *o head_obj.init(bucket, obj_str); if (versioned_object) { -#define OBJ_INSTANCE_LEN 32 - char buf[OBJ_INSTANCE_LEN + 1]; - - gen_rand_base64(store->ctx(), buf, OBJ_INSTANCE_LEN); - - head_obj.set_instance(buf); + store->gen_rand_obj_instance_name(&head_obj); } manifest.set_trivial_rule(max_chunk_size, store->ctx()->_conf->rgw_obj_stripe_size); @@ -3305,7 +3300,7 @@ int RGWRados::copy_obj(void *ctx, append_rand_alpha(cct, tag, tag, 32); RGWPutObjProcessor_Atomic processor(dest_bucket_info.owner, dest_obj.bucket, dest_obj.get_object(), - cct->_conf->rgw_obj_stripe_size, tag, dest_bucket_info.versioning_enabled); + cct->_conf->rgw_obj_stripe_size, tag, dest_bucket_info.versioning_enabled()); ret = processor.prepare(this, ctx, NULL); if (ret < 0) return ret; @@ -3589,7 +3584,7 @@ int RGWRados::copy_obj_data(void *ctx, append_rand_alpha(cct, tag, tag, 32); RGWPutObjProcessor_Atomic processor(dest_bucket_info.owner, dest_obj.bucket, dest_obj.get_object(), - cct->_conf->rgw_obj_stripe_size, tag, dest_bucket_info.versioning_enabled); + cct->_conf->rgw_obj_stripe_size, tag, dest_bucket_info.versioning_enabled()); int ret = processor.prepare(this, ctx, NULL); if (ret < 0) return ret; @@ -5597,6 +5592,16 @@ int RGWRados::set_olh(void *ctx, const string& bucket_owner, rgw_obj& target_obj return 0; } +void RGWRados::gen_rand_obj_instance_name(rgw_obj *target_obj) +{ +#define OBJ_INSTANCE_LEN 32 + char buf[OBJ_INSTANCE_LEN + 1]; + + gen_rand_base64(cct, buf, OBJ_INSTANCE_LEN); + + target_obj->set_instance(buf); +} + static void filter_attrset(map& unfiltered_attrset, const string& check_prefix, map *attrset) { diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h index edfb1a5825d34..70664c05412ab 100644 --- a/src/rgw/rgw_rados.h +++ b/src/rgw/rgw_rados.h @@ -1776,6 +1776,8 @@ public: int follow_olh(void *ctx, RGWObjState *state, rgw_obj& olh_obj, rgw_obj *target); int get_olh(rgw_obj& obj, RGWOLHInfo *olh); + void gen_rand_obj_instance_name(rgw_obj *target); + virtual bool supports_omap() { return true; } int omap_get_vals(rgw_obj& obj, bufferlist& header, const std::string& marker, uint64_t count, std::map& m); virtual int omap_get_all(rgw_obj& obj, bufferlist& header, std::map& m); diff --git a/src/rgw/rgw_rest_s3.cc b/src/rgw/rgw_rest_s3.cc index 1c3d9327b067f..804e7bb590b7c 100644 --- a/src/rgw/rgw_rest_s3.cc +++ b/src/rgw/rgw_rest_s3.cc @@ -383,7 +383,12 @@ void RGWGetBucketVersioning_ObjStore_S3::send_response() s->formatter->open_object_section_in_ns("VersioningConfiguration", "http://doc.s3.amazonaws.com/doc/2006-03-01/"); - const char *status = (versioning_enabled ? "Enabled" : "Suspended"); + const char *status; + if (!versioned) { + status = "Disabled"; + } else { + status = (versioning_enabled ? "Enabled" : "Suspended"); + } s->formatter->dump_string("Status", status); s->formatter->close_section(); rgw_flush_formatter_and_reset(s, s->formatter); -- 2.39.5