]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: store region in bucket info
authorYehuda Sadeh <yehuda@inktank.com>
Fri, 17 May 2013 20:07:24 +0000 (13:07 -0700)
committerYehuda Sadeh <yehuda@inktank.com>
Fri, 17 May 2013 20:07:24 +0000 (13:07 -0700)
only handle requests that come to buckets stored in correct
region.

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

index 465d58e9a57496befd76a9e934c242df9b8a137b..1403f655e8fb69bf756d72bbb836dd640a05df2d 100644 (file)
@@ -113,6 +113,7 @@ using ceph::crypto::MD5;
 #define ERR_INVALID_REQUEST      2021
 #define ERR_TOO_SMALL            2022
 #define ERR_NOT_FOUND            2023
+#define ERR_PERMANENT_REDIRECT   2024
 #define ERR_USER_SUSPENDED       2100
 #define ERR_INTERNAL_ERROR       2200
 
@@ -497,7 +498,7 @@ struct rgw_bucket {
     data_pool = index_pool = n;
     marker = "";
   }
-  rgw_bucket(const char *n, const char *dp, const char *ip, const char *m, const char *id) :
+  rgw_bucket(const char *n, const char *dp, const char *ip, const char *m, const char *id, const char *h) :
     name(n), data_pool(dp), index_pool(ip), marker(m), bucket_id(id) {}
 
   void clear() {
@@ -509,7 +510,7 @@ struct rgw_bucket {
   }
 
   void encode(bufferlist& bl) const {
-     ENCODE_START(5, 3, bl);
+     ENCODE_START(6, 3, bl);
     ::encode(name, bl);
     ::encode(data_pool, bl);
     ::encode(marker, bl);
@@ -518,7 +519,7 @@ struct rgw_bucket {
     ENCODE_FINISH(bl);
   }
   void decode(bufferlist::iterator& bl) {
-    DECODE_START_LEGACY_COMPAT_LEN(5, 3, 3, bl);
+    DECODE_START_LEGACY_COMPAT_LEN(6, 3, 3, bl);
     ::decode(name, bl);
     ::decode(data_pool, bl);
     if (struct_v >= 2) {
index 59675c315e00378142fd7816584eeee1e57f2097..b5c49425f89a2e62da42216edf8a89056f944fca 100644 (file)
@@ -13,7 +13,7 @@ void RGWObjManifestPart::generate_test_instances(std::list<RGWObjManifestPart*>&
   o.push_back(new RGWObjManifestPart);
 
   RGWObjManifestPart *p = new RGWObjManifestPart;
-  rgw_bucket b("bucket", ".pool", ".index_pool", "marker_", "12");
+  rgw_bucket b("bucket", ".pool", ".index_pool", "marker_", "12", "region");
   p->loc = rgw_obj(b, "object");
   p->loc_ofs = 512 * 1024;
   p->size = 128 * 1024;
@@ -25,7 +25,7 @@ void RGWObjManifest::generate_test_instances(std::list<RGWObjManifest*>& o)
   RGWObjManifest *m = new RGWObjManifest;
   for (int i = 0; i<10; i++) {
     RGWObjManifestPart p;
-    rgw_bucket b("bucket", ".pool", ".index_pool", "marker_", "12");
+    rgw_bucket b("bucket", ".pool", ".index_pool", "marker_", "12", "region");
     p.loc = rgw_obj(b, "object");
     p.loc_ofs = 0;
     p.size = 512 * 1024;
@@ -63,7 +63,7 @@ void rgw_log_entry::generate_test_instances(list<rgw_log_entry*>& o)
 void rgw_intent_log_entry::generate_test_instances(list<rgw_intent_log_entry*>& o)
 {
   rgw_intent_log_entry *e = new rgw_intent_log_entry;
-  rgw_bucket b("bucket", "pool", ".index_pool", "marker", "10");
+  rgw_bucket b("bucket", "pool", ".index_pool", "marker", "10", "region");
   e->obj = rgw_obj(b, "object");
   e->intent = DEL_OBJ;
   o.push_back(e);
@@ -254,7 +254,7 @@ void RGWUserInfo::generate_test_instances(list<RGWUserInfo*>& o)
 
 void rgw_bucket::generate_test_instances(list<rgw_bucket*>& o)
 {
-  rgw_bucket *b = new rgw_bucket("name", "pool", ".index_pool", "marker", "123");
+  rgw_bucket *b = new rgw_bucket("name", "pool", ".index_pool", "marker", "123", "region");
   o.push_back(b);
   o.push_back(new rgw_bucket);
 }
@@ -262,7 +262,7 @@ void rgw_bucket::generate_test_instances(list<rgw_bucket*>& o)
 void RGWBucketInfo::generate_test_instances(list<RGWBucketInfo*>& o)
 {
   RGWBucketInfo *i = new RGWBucketInfo;
-  i->bucket = rgw_bucket("bucket", "pool", ".index_pool", "marker", "10");
+  i->bucket = rgw_bucket("bucket", "pool", ".index_pool", "marker", "10", "region");
   i->owner = "owner";
   i->flags = BUCKET_SUSPENDED;
   o.push_back(i);
@@ -272,7 +272,7 @@ void RGWBucketInfo::generate_test_instances(list<RGWBucketInfo*>& o)
 void RGWBucketEnt::generate_test_instances(list<RGWBucketEnt*>& o)
 {
   RGWBucketEnt *e = new RGWBucketEnt;
-  e->bucket = rgw_bucket("bucket", "pool", ".index_pool", "marker", "10");
+  e->bucket = rgw_bucket("bucket", "pool", ".index_pool", "marker", "10", "region");
   e->size = 1024;
   e->size_rounded = 4096;
   e->count = 1;
@@ -292,7 +292,7 @@ void RGWUploadPartInfo::generate_test_instances(list<RGWUploadPartInfo*>& o)
 
 void rgw_obj::generate_test_instances(list<rgw_obj*>& o)
 {
-  rgw_bucket b = rgw_bucket("bucket", "pool", ".index_pool", "marker", "10");
+  rgw_bucket b = rgw_bucket("bucket", "pool", ".index_pool", "marker", "10", "region");
   rgw_obj *obj = new rgw_obj(b, "object");
   o.push_back(obj);
   o.push_back(new rgw_obj);
index cc586c1406b4fc1ac793e76051741c0842b9cbde..16b065629565562633be8628e5886ba817c25d5b 100644 (file)
@@ -15,6 +15,7 @@ const static struct rgw_html_errors RGW_HTML_ERRORS[] = {
     { STATUS_ACCEPTED, 202, "Accepted" },
     { STATUS_NO_CONTENT, 204, "NoContent" },
     { STATUS_PARTIAL_CONTENT, 206, "" },
+    { ERR_PERMANENT_REDIRECT, 301, "PermanentRedirect" },
     { STATUS_REDIRECT, 303, "" },
     { ERR_NOT_MODIFIED, 304, "NotModified" },
     { EINVAL, 400, "InvalidArgument" },
index 0a0176c9fa25ec8390dc221ffff2a53ee2e362bf..030754583182bea68869439aba818f294af2d198 100644 (file)
@@ -404,14 +404,14 @@ void RGWBucketInfo::dump(Formatter *f) const
   encode_json("bucket", bucket, f);
   encode_json("owner", owner, f);
   encode_json("flags", flags, f);
-  encode_json("region", flags, f);
+  encode_json("region", region, f);
 }
 
 void RGWBucketInfo::decode_json(JSONObj *obj) {
   JSONDecoder::decode_json("bucket", bucket, obj);
   JSONDecoder::decode_json("owner", owner, obj);
   JSONDecoder::decode_json("flags", flags, obj);
-  JSONDecoder::decode_json("region", flags, obj);
+  JSONDecoder::decode_json("region", region, obj);
 }
 
 void RGWObjEnt::dump(Formatter *f) const
index 799971d1f19b24146e1958137b8a88182a97765a..d3b3e03c300d8030c7a8a258ce219768a758988e 100644 (file)
@@ -287,7 +287,7 @@ static int read_policy(RGWRados *store, struct req_state *s, RGWBucketInfo& buck
  * only_bucket: If true, reads the bucket ACL rather than the object ACL.
  * Returns: 0 on success, -ERR# otherwise.
  */
-int rgw_build_policies(RGWRados *store, struct req_state *s, bool only_bucket, bool prefetch_data)
+static int rgw_build_policies(RGWRados *store, struct req_state *s, bool only_bucket, bool prefetch_data)
 {
   int ret = 0;
   string obj_str;
@@ -309,6 +309,13 @@ int rgw_build_policies(RGWRados *store, struct req_state *s, bool only_bucket, b
     ret = read_policy(store, s, bucket_info, s->bucket_acl, s->bucket, no_obj);
 
     s->bucket_owner = s->bucket_acl->get_owner();
+
+    string& region = bucket_info.region;
+    if ((region.empty() && !store->region.is_master) &&
+        (region != store->region.name)) {
+      ldout(s->cct, 0) << "NOTICE: request for data in a different region (" << region << " != " << store->region.name << ")" << dendl;
+      return -ERR_PERMANENT_REDIRECT;
+    }
   }
 
   /* we're passed only_bucket = true when we specifically need the bucket's
@@ -851,6 +858,14 @@ void RGWCreateBucket::execute()
   if (ret < 0)
     return;
 
+  if (!store->region.is_master) {
+    if (store->region.api_name != location_constraint) {
+      ldout(s->cct, 0) << "location constraint (" << location_constraint << ") doesn't match region" << dendl;
+      ret = -EINVAL;
+      return;
+    }
+  }
+
   s->bucket_owner.set_id(s->user.user_id);
   s->bucket_owner.set_name(s->user.display_name);
   r = get_policy_from_attr(s->cct, store, s->obj_ctx, &old_policy, obj, &s->objv_tracker);
index d791d4d1754112b42d4f2551bf8e1ea49dff2ba3..e580e0b4895635d3979eb0fbdab355f7db765c35 100644 (file)
@@ -27,7 +27,6 @@ struct req_state;
 class RGWHandler;
 
 void rgw_get_request_metadata(struct req_state *s, map<string, bufferlist>& attrs);
-int rgw_build_policies(RGWRados *store, struct req_state *s, bool only_bucket, bool prefetch_data);
 
 
 /**
index d4a5488dcd0458d3bb5f640c3e3d2dc92715b23e..f48923d26814a8b0af87367c877388f94110801a 100644 (file)
@@ -1360,6 +1360,7 @@ int RGWRados::create_bucket(string& owner, rgw_bucket& bucket,
   RGWBucketInfo info;
   info.bucket = bucket;
   info.owner = owner;
+  info.region = region.name;
   ret = put_bucket_info(bucket.name, info, exclusive, &objv_tracker, &attrs);
   if (ret == -EEXIST) {
     index_ctx.remove(dir_oid);