]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: bucket versioning status is tri-state
authorYehuda Sadeh <yehuda@redhat.com>
Mon, 29 Sep 2014 22:10:02 +0000 (15:10 -0700)
committerYehuda Sadeh <yehuda@redhat.com>
Fri, 16 Jan 2015 22:41:42 +0000 (14:41 -0800)
disabled, enabled, suspended.

Signed-off-by: Yehuda Sadeh <yehuda@redhat.com>
src/rgw/rgw_common.h
src/rgw/rgw_json_enc.cc
src/rgw/rgw_op.cc
src/rgw/rgw_op.h
src/rgw/rgw_rados.cc
src/rgw/rgw_rados.h
src/rgw/rgw_rest_s3.cc

index a2344c021a603ae81f911850a443b3f419c756d4..578526e417f59c37e0e842e65bcb83163607751e 100644 (file)
@@ -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)
 
index 3585c8ffe373789c4041ef1f83abc4a0ed69f1d4..9a21f26cb2c2af8517c77255d5534f013318c91c 100644 (file)
@@ -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
index 6cb7e86dfe4fa7fae78b6531feeaf3fe865e058e..a05ecec4e6494773af6357791246575771ac6ea6 100644 (file)
@@ -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<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);
@@ -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);
 }
index 776f213fea511d79a4537007cfad9c7ff6bb9c1d..9288667b3b4bb2535641709a518e3087b4bbf26f 100644 (file)
@@ -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();
index 3423af3e8c78c7fa3ea758086fb8eced147418fc..943054a0b88d27c49f4506fbfd50daba3f4f18eb 100644 (file)
@@ -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<string, bufferlist>& unfiltered_attrset, const string& check_prefix,
                            map<string, bufferlist> *attrset)
 {
index edfb1a5825d3403bbada03dde0a39831cc50786b..70664c05412ab9666f2211de8bb968b6dd8371ac 100644 (file)
@@ -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<string, bufferlist>& m);
   virtual int omap_get_all(rgw_obj& obj, bufferlist& header, std::map<string, bufferlist>& m);
index 1c3d9327b067f9b7a7c44ab317c5dc08129556b7..804e7bb590b7c1e9bf21e5bf5b470204865e35dd 100644 (file)
@@ -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);