disabled, enabled, suspended.
Signed-off-by: Yehuda Sadeh <yehuda@redhat.com>
enum RGWBucketFlags {
BUCKET_SUSPENDED = 0x1,
+ BUCKET_VERSIONED = 0x2,
+ BUCKET_VERSIONS_SUSPENDED = 0x4,
};
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);
::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);
::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;
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)
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) {
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
void RGWGetBucketVersioning::execute()
{
- versioning_enabled = s->bucket_info.versioning_enabled;
+ versioned = s->bucket_info.versioned();
+ versioning_enabled = s->bucket_info.versioning_enabled();
send_response();
}
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) {
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);
}
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;
}
list<rgw_obj_key> 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);
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);
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);
}
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();
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);
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;
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;
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<string, bufferlist>& unfiltered_attrset, const string& check_prefix,
map<string, bufferlist> *attrset)
{
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<string, bufferlist>& m);
virtual int omap_get_all(rgw_obj& obj, bufferlist& header, std::map<string, bufferlist>& m);
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);