#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
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() {
}
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);
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) {
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;
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;
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);
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);
}
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);
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;
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);
{ 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" },
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
* 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;
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
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);
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);
/**
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);