summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYehuda Sadeh <yehuda@inktank.com>2013-06-22 22:47:48 -0700
committerYehuda Sadeh <yehuda@inktank.com>2013-06-23 01:15:56 -0700
commitc3260b276882beedb52f7c77c622a9b77537a63f (patch)
tree5503992c618ec1400bca43a78d068d78d7c67e49
parentc103031ec6b259c70e3e33609dbb292f5b04d3fe (diff)
downloadceph-c3260b276882beedb52f7c77c622a9b77537a63f.tar.gz
rgw: initial work to separate bucket name and instance
Bucket info now resides in an instance specific object. The old bucket info object now contains a pointer to the new instance. Signed-off-by: Yehuda Sadeh <yehuda@inktank.com>
-rw-r--r--src/rgw/rgw_bucket.cc10
-rw-r--r--src/rgw/rgw_bucket.h2
-rw-r--r--src/rgw/rgw_common.h36
-rw-r--r--src/rgw/rgw_json_enc.cc2
-rw-r--r--src/rgw/rgw_op.cc4
-rw-r--r--src/rgw/rgw_rados.cc84
-rw-r--r--src/rgw/rgw_rados.h3
7 files changed, 123 insertions, 18 deletions
diff --git a/src/rgw/rgw_bucket.cc b/src/rgw/rgw_bucket.cc
index 0325a60840c..d3f673f7488 100644
--- a/src/rgw/rgw_bucket.cc
+++ b/src/rgw/rgw_bucket.cc
@@ -177,12 +177,15 @@ done:
}
#endif
-int rgw_bucket_set_attrs(RGWRados *store, rgw_obj& obj,
+int rgw_bucket_set_attrs(RGWRados *store, rgw_bucket& bucket,
map<string, bufferlist>& attrs,
map<string, bufferlist>* rmattrs,
RGWObjVersionTracker *objv_tracker)
{
- return store->meta_mgr->set_attrs(bucket_meta_handler, obj.bucket.name,
+ string oid;
+ store->get_bucket_meta_oid(bucket, oid);
+ rgw_obj obj(store->zone.domain_root, oid);
+ return store->meta_mgr->set_attrs(bucket_meta_handler, oid,
obj, attrs, rmattrs, objv_tracker);
}
@@ -1363,7 +1366,8 @@ public:
bci.info.bucket.index_pool = old_bci.info.bucket.index_pool;
}
- ret = store->put_bucket_info(entry, bci.info, false, &objv_tracker, mtime, &bci.attrs);
+#warning need to take care of different routes here
+ ret = store->put_bucket_info(entry, bci.info, false, &objv_tracker, mtime, &bci.attrs, false);
if (ret < 0)
return ret;
diff --git a/src/rgw/rgw_bucket.h b/src/rgw/rgw_bucket.h
index a4c2fded5de..09ddc653f73 100644
--- a/src/rgw/rgw_bucket.h
+++ b/src/rgw/rgw_bucket.h
@@ -100,7 +100,7 @@ extern int rgw_remove_user_bucket_info(RGWRados *store, string user_id, rgw_buck
extern int rgw_remove_object(RGWRados *store, rgw_bucket& bucket, std::string& object);
extern int rgw_remove_bucket(RGWRados *store, rgw_bucket& bucket, bool delete_children);
-extern int rgw_bucket_set_attrs(RGWRados *store, rgw_obj& obj,
+extern int rgw_bucket_set_attrs(RGWRados *store, rgw_bucket& obj,
map<string, bufferlist>& attrs,
map<string, bufferlist>* rmattrs,
RGWObjVersionTracker *objv_tracker);
diff --git a/src/rgw/rgw_common.h b/src/rgw/rgw_common.h
index bafe10d46db..a3e3cf5472d 100644
--- a/src/rgw/rgw_common.h
+++ b/src/rgw/rgw_common.h
@@ -607,15 +607,17 @@ struct RGWBucketInfo
string region;
time_t creation_time;
string placement_rule;
+ bool has_instance_obj;
void encode(bufferlist& bl) const {
- ENCODE_START(7, 4, bl);
+ ENCODE_START(8, 4, bl);
::encode(bucket, bl);
::encode(owner, bl);
::encode(flags, bl);
::encode(region, bl);
::encode(creation_time, bl);
::encode(placement_rule, bl);
+ ::encode(has_instance_obj, bl);
ENCODE_FINISH(bl);
}
void decode(bufferlist::iterator& bl) {
@@ -631,6 +633,8 @@ struct RGWBucketInfo
::decode(creation_time, bl);
if (struct_v >= 7)
::decode(placement_rule, bl);
+ if (struct_v >= 8)
+ ::decode(has_instance_obj, bl);
DECODE_FINISH(bl);
}
void dump(Formatter *f) const;
@@ -638,10 +642,38 @@ struct RGWBucketInfo
void decode_json(JSONObj *obj);
- RGWBucketInfo() : flags(0), creation_time(0) {}
+ RGWBucketInfo() : flags(0), creation_time(0), has_instance_obj(false) {}
};
WRITE_CLASS_ENCODER(RGWBucketInfo)
+struct RGWBucketEntryPoint
+{
+ rgw_bucket bucket;
+
+ bool has_bucket_info;
+ RGWBucketInfo old_bucket_info;
+
+ void encode(bufferlist& bl) const {
+ ENCODE_START(8, 8, bl);
+ ::encode(bucket, bl);
+ ENCODE_FINISH(bl);
+ }
+ void decode(bufferlist::iterator& bl) {
+ bufferlist::iterator orig_iter = bl;
+ DECODE_START_LEGACY_COMPAT_LEN_32(8, 4, 4, bl);
+ if (struct_v < 8) {
+ /* ouch, old entry, contains the bucket info itself */
+ old_bucket_info.decode(orig_iter);
+ has_bucket_info = true;
+ return;
+ }
+ has_bucket_info = false;
+ ::decode(bucket, bl);
+ DECODE_FINISH(bl);
+ }
+};
+WRITE_CLASS_ENCODER(RGWBucketEntryPoint)
+
struct RGWBucketStats
{
RGWObjCategory category;
diff --git a/src/rgw/rgw_json_enc.cc b/src/rgw/rgw_json_enc.cc
index 8555d825df5..bfc09bd6bd6 100644
--- a/src/rgw/rgw_json_enc.cc
+++ b/src/rgw/rgw_json_enc.cc
@@ -444,6 +444,7 @@ void RGWBucketInfo::dump(Formatter *f) const
encode_json("flags", flags, f);
encode_json("region", region, f);
encode_json("placement_rule", region, f);
+ encode_json("has_instance_obj", has_instance_obj, f);
}
void RGWBucketInfo::decode_json(JSONObj *obj) {
@@ -453,6 +454,7 @@ void RGWBucketInfo::decode_json(JSONObj *obj) {
JSONDecoder::decode_json("flags", flags, obj);
JSONDecoder::decode_json("region", region, obj);
JSONDecoder::decode_json("placement_rule", region, obj);
+ JSONDecoder::decode_json("has_instance_obj", has_instance_obj, obj);
}
void RGWObjEnt::dump(Formatter *f) const
diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc
index 0ded08a94f4..0f009d2e190 100644
--- a/src/rgw/rgw_op.cc
+++ b/src/rgw/rgw_op.cc
@@ -1407,7 +1407,7 @@ void RGWPutMetadata::execute()
if (s->object) {
ret = store->set_attrs(s->obj_ctx, obj, attrs, &rmattrs, ptracker);
} else {
- ret = rgw_bucket_set_attrs(store, obj, attrs, &rmattrs, ptracker);
+ ret = rgw_bucket_set_attrs(store, obj.bucket, attrs, &rmattrs, ptracker);
}
}
@@ -1704,7 +1704,7 @@ void RGWPutACLs::execute()
if (s->object) {
ret = store->set_attrs(s->obj_ctx, obj, attrs, NULL, ptracker);
} else {
- ret = rgw_bucket_set_attrs(store, obj, attrs, NULL, ptracker);
+ ret = rgw_bucket_set_attrs(store, obj.bucket, attrs, NULL, ptracker);
}
}
diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc
index 3ccb083e71b..2562a3afeb3 100644
--- a/src/rgw/rgw_rados.cc
+++ b/src/rgw/rgw_rados.cc
@@ -1805,7 +1805,7 @@ int RGWRados::create_bucket(RGWUserInfo& owner, rgw_bucket& bucket,
time(&info.creation_time);
else
info.creation_time = creation_time;
- ret = put_bucket_info(bucket.name, info, exclusive, &objv_tracker, 0, &attrs);
+ ret = put_bucket_info(bucket.name, info, exclusive, &objv_tracker, 0, &attrs, true);
if (ret == -EEXIST) {
librados::IoCtx index_ctx; // context for new bucket
int r = open_bucket_index_ctx(bucket, index_ctx);
@@ -1813,7 +1813,8 @@ int RGWRados::create_bucket(RGWUserInfo& owner, rgw_bucket& bucket,
return r;
index_ctx.remove(dir_oid);
- /* we need this for this objv_tracker */
+ /* we need to updated objv_tracker, but we don't want the old cruft there */
+ objv_tracker = RGWObjVersionTracker();
r = get_bucket_info(NULL, bucket.name, info, &objv_tracker, NULL);
if (r < 0) {
if (r == -ENOENT) {
@@ -2838,7 +2839,7 @@ int RGWRados::set_bucket_owner(rgw_bucket& bucket, ACLOwner& owner)
info.owner = owner.get_id();
- r = put_bucket_info(bucket.name, info, false, &objv_tracker, 0, &attrs);
+ r = put_bucket_info(bucket.name, info, false, &objv_tracker, 0, &attrs, false);
if (r < 0) {
ldout(cct, 0) << "NOTICE: put_bucket_info on bucket=" << bucket.name << " returned err=" << r << dendl;
return r;
@@ -2876,7 +2877,7 @@ int RGWRados::set_buckets_enabled(vector<rgw_bucket>& buckets, bool enabled)
info.flags |= BUCKET_SUSPENDED;
}
- r = put_bucket_info(bucket.name, info, false, &objv_tracker, 0, &attrs);
+ r = put_bucket_info(bucket.name, info, false, &objv_tracker, 0, &attrs, false);
if (r < 0) {
ldout(cct, 0) << "NOTICE: put_bucket_info on bucket=" << bucket.name << " returned err=" << r << ", skipping bucket" << dendl;
ret = r;
@@ -4463,38 +4464,103 @@ int RGWRados::get_bucket_stats(rgw_bucket& bucket, uint64_t *bucket_ver, uint64_
return 0;
}
+void RGWRados::get_bucket_meta_oid(rgw_bucket& bucket, string& oid)
+{
+ oid = ".bucket.meta." + bucket.bucket_id;
+}
+
int RGWRados::get_bucket_info(void *ctx, string& bucket_name, RGWBucketInfo& info, RGWObjVersionTracker *objv_tracker,
time_t *pmtime, map<string, bufferlist> *pattrs)
{
bufferlist bl;
- int ret = rgw_get_system_obj(this, ctx, zone.domain_root, bucket_name, bl, objv_tracker, pmtime, pattrs);
+ RGWObjVersionTracker ot;
+ int ret = rgw_get_system_obj(this, ctx, zone.domain_root, bucket_name, bl, &ot, pmtime, pattrs);
if (ret < 0) {
info.bucket.name = bucket_name; /* only init this field */
return ret;
}
+ RGWBucketEntryPoint entry_point;
bufferlist::iterator iter = bl.begin();
try {
- ::decode(info, iter);
+ ::decode(entry_point, iter);
} catch (buffer::error& err) {
ldout(cct, 0) << "ERROR: could not decode buffer info, caught buffer::error" << dendl;
return -EIO;
}
- ldout(cct, 20) << "rgw_get_bucket_info: bucket=" << info.bucket << " owner " << info.owner << dendl;
+ if (entry_point.has_bucket_info) {
+ info = entry_point.old_bucket_info;
+ ldout(cct, 20) << "rgw_get_bucket_info: old bucket info, bucket=" << info.bucket << " owner " << info.owner << dendl;
+ return 0;
+ }
+
+ ldout(cct, 20) << "rgw_get_bucket_info: bucket instance: " << entry_point.bucket << dendl;
+
+ if (pattrs)
+ pattrs->clear();
+
+ /* read bucket instance info */
+
+ string oid;
+ get_bucket_meta_oid(entry_point.bucket, oid);
+
+ ldout(cct, 20) << "reading from " << zone.domain_root << ":" << oid << dendl;
+
+ bufferlist epbl;
+
+ ret = rgw_get_system_obj(this, ctx, zone.domain_root, oid, epbl, objv_tracker, pmtime, pattrs);
+ if (ret < 0) {
+ info.bucket.name = bucket_name; /* only init this field */
+ return ret;
+ }
+ iter = epbl.begin();
+ try {
+ ::decode(info, iter);
+ } catch (buffer::error& err) {
+ ldout(cct, 0) << "ERROR: could not decode buffer info, caught buffer::error" << dendl;
+ return -EIO;
+ }
return 0;
}
int RGWRados::put_bucket_info(string& bucket_name, RGWBucketInfo& info, bool exclusive, RGWObjVersionTracker *objv_tracker,
- time_t mtime, map<string, bufferlist> *pattrs)
+ time_t mtime, map<string, bufferlist> *pattrs, bool create_entry_point)
{
bufferlist bl;
::encode(info, bl);
- int ret = rgw_bucket_store_info(this, info.bucket.name, bl, exclusive, pattrs, objv_tracker, mtime);
+ bool create_head = !info.has_instance_obj || create_entry_point;
+
+ info.has_instance_obj = true;
+
+ string oid;
+ get_bucket_meta_oid(info.bucket, oid);
+ int ret = rgw_bucket_store_info(this, oid, bl, exclusive, pattrs, objv_tracker, mtime);
+ if (ret < 0) {
+ return ret;
+ }
+
+ if (!create_head)
+ return 0; /* done! */
+
+ RGWBucketEntryPoint entry_point;
+ entry_point.bucket = info.bucket;
+ bufferlist epbl;
+ ::encode(entry_point, epbl);
+ RGWObjVersionTracker ot;
+ ret = rgw_bucket_store_info(this, info.bucket.name, epbl, exclusive, pattrs, &ot, mtime);
+
+ if (exclusive && ret == -EEXIST) {
+ rgw_obj obj(zone.domain_root, oid);
+ int r = delete_obj(NULL, obj);
+ if (r < 0) {
+ ldout(cct, 0) << "ERROR: failed removing object " << obj << " when trying to clean up" << dendl;
+ }
+ }
return ret;
}
diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h
index 4a21ad00e02..ca15aa1c14a 100644
--- a/src/rgw/rgw_rados.h
+++ b/src/rgw/rgw_rados.h
@@ -1268,10 +1268,11 @@ public:
int decode_policy(bufferlist& bl, ACLOwner *owner);
int get_bucket_stats(rgw_bucket& bucket, uint64_t *bucket_ver, uint64_t *master_ver, map<RGWObjCategory, RGWBucketStats>& stats);
+ void get_bucket_meta_oid(rgw_bucket& bucket, string& oid);
virtual int get_bucket_info(void *ctx, string& bucket_name, RGWBucketInfo& info, RGWObjVersionTracker *objv_tracker,
time_t *pmtime, map<string, bufferlist> *pattrs = NULL);
virtual int put_bucket_info(string& bucket_name, RGWBucketInfo& info, bool exclusive, RGWObjVersionTracker *objv_tracker,
- time_t mtime, map<string, bufferlist> *pattrs);
+ time_t mtime, map<string, bufferlist> *pattrs, bool create_entry_point);
int cls_rgw_init_index(librados::IoCtx& io_ctx, librados::ObjectWriteOperation& op, string& oid);
int cls_obj_prepare_op(rgw_bucket& bucket, RGWModifyOp op, string& tag,