From: Yehuda Sadeh Date: Fri, 17 May 2013 20:07:24 +0000 (-0700) Subject: rgw: store region in bucket info X-Git-Tag: v0.67-rc1~128^2~112 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=0f4c67f1b5a4e6a870be56dfe268a018196d526f;p=ceph.git rgw: store region in bucket info only handle requests that come to buckets stored in correct region. Signed-off-by: Yehuda Sadeh --- diff --git a/src/rgw/rgw_common.h b/src/rgw/rgw_common.h index 465d58e9a57..1403f655e8f 100644 --- a/src/rgw/rgw_common.h +++ b/src/rgw/rgw_common.h @@ -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) { diff --git a/src/rgw/rgw_dencoder.cc b/src/rgw/rgw_dencoder.cc index 59675c315e0..b5c49425f89 100644 --- a/src/rgw/rgw_dencoder.cc +++ b/src/rgw/rgw_dencoder.cc @@ -13,7 +13,7 @@ void RGWObjManifestPart::generate_test_instances(std::list& 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& 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& o) void rgw_intent_log_entry::generate_test_instances(list& 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& o) void rgw_bucket::generate_test_instances(list& 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& o) void RGWBucketInfo::generate_test_instances(list& 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& o) void RGWBucketEnt::generate_test_instances(list& 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& o) void rgw_obj::generate_test_instances(list& 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); diff --git a/src/rgw/rgw_html_errors.h b/src/rgw/rgw_html_errors.h index cc586c1406b..16b06562956 100644 --- a/src/rgw/rgw_html_errors.h +++ b/src/rgw/rgw_html_errors.h @@ -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" }, diff --git a/src/rgw/rgw_json_enc.cc b/src/rgw/rgw_json_enc.cc index 0a0176c9fa2..03075458318 100644 --- a/src/rgw/rgw_json_enc.cc +++ b/src/rgw/rgw_json_enc.cc @@ -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 diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index 799971d1f19..d3b3e03c300 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -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); diff --git a/src/rgw/rgw_op.h b/src/rgw/rgw_op.h index d791d4d1754..e580e0b4895 100644 --- a/src/rgw/rgw_op.h +++ b/src/rgw/rgw_op.h @@ -27,7 +27,6 @@ struct req_state; class RGWHandler; void rgw_get_request_metadata(struct req_state *s, map& attrs); -int rgw_build_policies(RGWRados *store, struct req_state *s, bool only_bucket, bool prefetch_data); /** diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index d4a5488dcd0..f48923d2681 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -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);