summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYehuda Sadeh <yehuda@inktank.com>2013-06-23 21:00:00 -0700
committerYehuda Sadeh <yehuda@inktank.com>2013-06-23 21:00:00 -0700
commit71869c4b9edc13bac3333ae86fd6280fded113db (patch)
tree66c9727b861298989896932196c2b1e13300ce9b
parent00973dfdcab54e51a7cfcf09990f31849239e2a7 (diff)
downloadceph-71869c4b9edc13bac3333ae86fd6280fded113db.tar.gz
rgw: create meta handler for bucket instance
Create utility functions for reading writing bucket entry point and bucket instance. Add a separate meta handler for bucket instance. Signed-off-by: Yehuda Sadeh <yehuda@inktank.com>
-rw-r--r--src/rgw/rgw_bucket.cc158
-rw-r--r--src/rgw/rgw_common.h3
-rw-r--r--src/rgw/rgw_json_enc.cc17
-rw-r--r--src/rgw/rgw_rados.cc113
-rw-r--r--src/rgw/rgw_rados.h7
5 files changed, 256 insertions, 42 deletions
diff --git a/src/rgw/rgw_bucket.cc b/src/rgw/rgw_bucket.cc
index fb92aa311d8..3bce4cd4c0b 100644
--- a/src/rgw/rgw_bucket.cc
+++ b/src/rgw/rgw_bucket.cc
@@ -24,6 +24,7 @@
using namespace std;
static RGWMetadataHandler *bucket_meta_handler = NULL;
+static RGWMetadataHandler *bucket_instance_meta_handler = NULL;
// define as static when RGWBucket implementation compete
void rgw_get_buckets_obj(string& user_id, string& buckets_obj_id)
@@ -1290,10 +1291,23 @@ struct RGWBucketCompleteInfo {
}
};
-class RGWBucketMetadataObject : public RGWMetadataObject {
+class RGWBucketEntryMetadataObject : public RGWMetadataObject {
+ RGWBucketEntryPoint ep;
+public:
+ RGWBucketEntryMetadataObject(RGWBucketEntryPoint& _ep, obj_version& v, time_t m) : ep(_ep) {
+ objv = v;
+ mtime = m;
+ }
+
+ void dump(Formatter *f) const {
+ ep.dump(f);
+ }
+};
+
+class RGWBucketInstanceMetadataObject : public RGWMetadataObject {
RGWBucketCompleteInfo info;
public:
- RGWBucketMetadataObject(RGWBucketCompleteInfo& i, obj_version& v, time_t m) : info(i) {
+ RGWBucketInstanceMetadataObject(RGWBucketCompleteInfo& i, obj_version& v, time_t m) : info(i) {
objv = v;
mtime = m;
}
@@ -1321,15 +1335,140 @@ public:
string get_type() { return "bucket"; }
int get(RGWRados *store, string& entry, RGWMetadataObject **obj) {
+ RGWObjVersionTracker ot;
+ RGWBucketEntryPoint be;
+
+ time_t mtime;
+
+ int ret = store->get_bucket_entrypoint_info(NULL, entry, be, &ot, &mtime);
+ if (ret < 0)
+ return ret;
+
+ RGWBucketEntryMetadataObject *mdo = new RGWBucketEntryMetadataObject(be, ot.read_version, mtime);
+
+ *obj = mdo;
+
+ return 0;
+ }
+
+ int put(RGWRados *store, string& entry, RGWObjVersionTracker& objv_tracker, time_t mtime, JSONObj *obj) {
+ RGWBucketEntryPoint be, old_be;
+ decode_json_obj(be, obj);
+
+ time_t orig_mtime;
+
+ int ret = store->get_bucket_entrypoint_info(NULL, entry, be, &objv_tracker, &orig_mtime);
+ if (ret < 0 && ret != -ENOENT)
+ return ret;
+
+ ret = store->put_bucket_entrypoint_info(entry, old_be, false, mtime);
+ if (ret < 0)
+ return ret;
+
+#warning need to link bucket here
+#if 0
+ ret = rgw_add_bucket(store, bci.info.owner, bci.info.bucket, bci.info.creation_time);
+ if (ret < 0)
+ return ret;
+#endif
+
+ return 0;
+ }
+
+ struct list_keys_info {
+ RGWRados *store;
+ RGWListRawObjsCtx ctx;
+ };
+
+ int remove(RGWRados *store, string& entry, RGWObjVersionTracker& objv_tracker) {
+ rgw_bucket bucket;
+ int r = init_bucket(store, entry, bucket, &objv_tracker);
+ if (r < 0) {
+ cerr << "could not init bucket=" << entry << std::endl;
+ return r;
+ }
+
+ return store->delete_bucket(bucket, objv_tracker);
+ }
+
+ void get_pool_and_oid(RGWRados *store, string& key, rgw_bucket& bucket, string& oid) {
+ oid = key;
+ bucket = store->zone.domain_root;
+ }
+
+ int list_keys_init(RGWRados *store, void **phandle)
+ {
+ list_keys_info *info = new list_keys_info;
+
+ info->store = store;
+
+ *phandle = (void *)info;
+
+ return 0;
+ }
+
+ int list_keys_next(void *handle, int max, list<string>& keys, bool *truncated) {
+ list_keys_info *info = (list_keys_info *)handle;
+
+ string no_filter;
+
+ keys.clear();
+
+ RGWRados *store = info->store;
+
+ list<string> unfiltered_keys;
+
+ int ret = store->list_raw_objects(store->zone.domain_root, no_filter,
+ max, info->ctx, unfiltered_keys, truncated);
+ if (ret < 0)
+ return ret;
+
+ // now filter out the system entries
+ list<string>::iterator iter;
+ for (iter = unfiltered_keys.begin(); iter != unfiltered_keys.end(); ++iter) {
+ string& k = *iter;
+
+ if (k[0] != '.') {
+ keys.push_back(k);
+ }
+ }
+
+ return 0;
+ }
+
+ void list_keys_complete(void *handle) {
+ list_keys_info *info = (list_keys_info *)handle;
+ delete info;
+ }
+};
+
+class RGWBucketInstanceMetadataHandler : public RGWMetadataHandler {
+
+ int init_bucket(RGWRados *store, string& bucket_name, rgw_bucket& bucket, RGWObjVersionTracker *objv_tracker) {
+ RGWBucketInfo bucket_info;
+ int r = store->get_bucket_info(NULL, bucket_name, bucket_info, NULL);
+ if (r < 0) {
+ cerr << "could not get bucket info for bucket=" << bucket_name << std::endl;
+ return r;
+ }
+ bucket = bucket_info.bucket;
+
+ return 0;
+ }
+
+public:
+ string get_type() { return "bucket.instance"; }
+
+ int get(RGWRados *store, string& entry, RGWMetadataObject **obj) {
RGWBucketCompleteInfo bci;
time_t mtime;
- int ret = store->get_bucket_info(NULL, entry, bci.info, &mtime, &bci.attrs);
+ int ret = store->get_bucket_instance_info(NULL, entry, bci.info, &mtime, &bci.attrs);
if (ret < 0)
return ret;
- RGWBucketMetadataObject *mdo = new RGWBucketMetadataObject(bci, bci.info.objv_tracker.read_version, mtime);
+ RGWBucketInstanceMetadataObject *mdo = new RGWBucketInstanceMetadataObject(bci, bci.info.objv_tracker.read_version, mtime);
*obj = mdo;
@@ -1344,7 +1483,7 @@ public:
old_bci.info.objv_tracker = objv_tracker;
- int ret = store->get_bucket_info(NULL, entry, old_bci.info, &orig_mtime, &old_bci.attrs);
+ int ret = store->get_bucket_instance_info(NULL, entry, old_bci.info, &orig_mtime, &old_bci.attrs);
if (ret < 0 && ret != -ENOENT)
return ret;
@@ -1365,8 +1504,7 @@ public:
bci.info.objv_tracker = old_bci.info.objv_tracker;
}
-#warning need to take care of different routes here
- ret = store->put_bucket_info(entry, bci.info, false, mtime, &bci.attrs, false);
+ ret = store->put_bucket_instance_info(entry, bci.info, false, mtime, &bci.attrs);
if (ret < 0)
return ret;
@@ -1376,10 +1514,6 @@ public:
if (ret < 0)
return ret;
- ret = rgw_add_bucket(store, bci.info.owner, bci.info.bucket, bci.info.creation_time);
- if (ret < 0)
- return ret;
-
return 0;
}
@@ -1454,4 +1588,6 @@ void rgw_bucket_init(RGWMetadataManager *mm)
{
bucket_meta_handler = new RGWBucketMetadataHandler;
mm->register_handler(bucket_meta_handler);
+ bucket_instance_meta_handler = new RGWBucketInstanceMetadataHandler;
+ mm->register_handler(bucket_instance_meta_handler);
}
diff --git a/src/rgw/rgw_common.h b/src/rgw/rgw_common.h
index 42aeecfbe4b..af70846f87c 100644
--- a/src/rgw/rgw_common.h
+++ b/src/rgw/rgw_common.h
@@ -707,6 +707,9 @@ struct RGWBucketEntryPoint
::decode(bucket, bl);
DECODE_FINISH(bl);
}
+
+ void dump(Formatter *f) const;
+ void decode_json(JSONObj *obj);
};
WRITE_CLASS_ENCODER(RGWBucketEntryPoint)
diff --git a/src/rgw/rgw_json_enc.cc b/src/rgw/rgw_json_enc.cc
index bfc09bd6bd6..8ab6ff530e6 100644
--- a/src/rgw/rgw_json_enc.cc
+++ b/src/rgw/rgw_json_enc.cc
@@ -436,6 +436,23 @@ void rgw_bucket::decode_json(JSONObj *obj) {
JSONDecoder::decode_json("bucket_id", bucket_id, obj);
}
+void RGWBucketEntryPoint::dump(Formatter *f) const
+{
+ encode_json("bucket", bucket, f);
+ encode_json("has_bucket_info", has_bucket_info, f);
+ if (has_bucket_info) {
+ encode_json("old_bucket_info", old_bucket_info, f);
+ }
+}
+
+void RGWBucketEntryPoint::decode_json(JSONObj *obj) {
+ JSONDecoder::decode_json("bucket", bucket, obj);
+ JSONDecoder::decode_json("has_bucket_info", has_bucket_info, obj);
+ if (has_bucket_info) {
+ JSONDecoder::decode_json("old_bucket_info", old_bucket_info, obj);
+ }
+}
+
void RGWBucketInfo::dump(Formatter *f) const
{
encode_json("bucket", bucket, f);
diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc
index bf1e16d32c7..2e490dea13c 100644
--- a/src/rgw/rgw_rados.cc
+++ b/src/rgw/rgw_rados.cc
@@ -4464,19 +4464,53 @@ 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,
- time_t *pmtime, map<string, bufferlist> *pattrs)
+int RGWRados::get_bucket_instance_info(void *ctx, string& name, RGWBucketInfo& info,
+ time_t *pmtime, map<string, bufferlist> *pattrs)
+{
+ /* entry in the format <bucket>/<bucket_id> */
+ int pos = name.find('/');
+ if (pos < 0) {
+ return -EINVAL;
+ }
+ string oid = ".bucket.meta." + name.substr(pos + 1);
+
+ return get_bucket_instance_from_oid(ctx, oid, info, pmtime, pattrs);
+}
+
+int RGWRados::get_bucket_instance_from_oid(void *ctx, string& oid, RGWBucketInfo& info,
+ time_t *pmtime, map<string, bufferlist> *pattrs)
+{
+ ldout(cct, 20) << "reading from " << zone.domain_root << ":" << oid << dendl;
+
+ bufferlist epbl;
+
+ int ret = rgw_get_system_obj(this, ctx, zone.domain_root, oid, epbl, &info.objv_tracker, pmtime, pattrs);
+ if (ret < 0) {
+ return ret;
+ }
+
+ bufferlist::iterator 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::get_bucket_entrypoint_info(void *ctx, string& bucket_name,
+ RGWBucketEntryPoint& entry_point,
+ RGWObjVersionTracker *objv_tracker,
+ time_t *pmtime)
{
bufferlist bl;
- RGWObjVersionTracker ot;
- int ret = rgw_get_system_obj(this, ctx, zone.domain_root, bucket_name, bl, &ot, pmtime, pattrs);
+ int ret = rgw_get_system_obj(this, ctx, zone.domain_root, bucket_name, bl, objv_tracker, pmtime, NULL);
if (ret < 0) {
- info.bucket.name = bucket_name; /* only init this field */
return ret;
}
- RGWBucketEntryPoint entry_point;
bufferlist::iterator iter = bl.begin();
try {
::decode(entry_point, iter);
@@ -4484,6 +4518,21 @@ int RGWRados::get_bucket_info(void *ctx, string& bucket_name, RGWBucketInfo& inf
ldout(cct, 0) << "ERROR: could not decode buffer info, caught buffer::error" << dendl;
return -EIO;
}
+ return 0;
+}
+
+int RGWRados::get_bucket_info(void *ctx, string& bucket_name, RGWBucketInfo& info,
+ time_t *pmtime, map<string, bufferlist> *pattrs)
+{
+ bufferlist bl;
+
+ RGWBucketEntryPoint entry_point;
+ time_t ep_mtime;
+ int ret = get_bucket_entrypoint_info(ctx, bucket_name, entry_point, NULL, &ep_mtime);
+ if (ret < 0) {
+ info.bucket.name = bucket_name; /* only init this field */
+ return ret;
+ }
if (entry_point.has_bucket_info) {
info = entry_point.old_bucket_info;
@@ -4501,40 +4550,44 @@ int RGWRados::get_bucket_info(void *ctx, string& bucket_name, RGWBucketInfo& inf
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, &info.objv_tracker, pmtime, pattrs);
+ ret = get_bucket_instance_from_oid(ctx, oid, info, pmtime, pattrs);
if (ret < 0) {
- info.bucket.name = bucket_name; /* only init this field */
+ info.bucket.name = bucket_name;
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,
- time_t mtime, map<string, bufferlist> *pattrs, bool create_entry_point)
+int RGWRados::put_bucket_entrypoint_info(string& bucket_name, RGWBucketEntryPoint& entry_point,
+ bool exclusive, time_t mtime)
{
- bufferlist bl;
-
- bool create_head = !info.has_instance_obj || create_entry_point;
+ bufferlist epbl;
+ ::encode(entry_point, epbl);
+ RGWObjVersionTracker ot;
+ return rgw_bucket_store_info(this, bucket_name, epbl, exclusive, NULL, &ot, mtime);
+}
+int RGWRados::put_bucket_instance_info(string& bucket_name, RGWBucketInfo& info, bool exclusive,
+ time_t mtime, map<string, bufferlist> *pattrs)
+{
info.has_instance_obj = true;
+ bufferlist bl;
::encode(info, bl);
string oid;
get_bucket_meta_oid(info.bucket, oid);
- int ret = rgw_bucket_store_info(this, oid, bl, exclusive, pattrs, &info.objv_tracker, mtime);
+ return rgw_bucket_store_info(this, oid, bl, exclusive, pattrs, &info.objv_tracker, mtime);
+}
+
+int RGWRados::put_bucket_info(string& bucket_name, RGWBucketInfo& info, bool exclusive,
+ time_t mtime, map<string, bufferlist> *pattrs, bool create_entry_point)
+{
+ bufferlist bl;
+
+ bool create_head = !info.has_instance_obj || create_entry_point;
+
+ int ret = put_bucket_instance_info(bucket_name, info, exclusive, mtime, pattrs);
if (ret < 0) {
return ret;
}
@@ -4544,12 +4597,10 @@ int RGWRados::put_bucket_info(string& bucket_name, RGWBucketInfo& info, bool exc
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);
-
+ ret = put_bucket_entrypoint_info(info.bucket.name, entry_point, exclusive, mtime);
if (exclusive && ret == -EEXIST) {
+ string oid;
+ get_bucket_meta_oid(info.bucket, oid);
rgw_obj obj(zone.domain_root, oid);
int r = delete_obj(NULL, obj);
if (r < 0) {
diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h
index 72583008587..990bb1372ce 100644
--- a/src/rgw/rgw_rados.h
+++ b/src/rgw/rgw_rados.h
@@ -1268,6 +1268,13 @@ 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);
+
+ int put_bucket_entrypoint_info(string& bucket_name, RGWBucketEntryPoint& entry_point, bool exclusive, time_t mtime);
+ int put_bucket_instance_info(string& bucket_name, RGWBucketInfo& info, bool exclusive, time_t mtime, map<string, bufferlist> *pattrs);
+ int get_bucket_entrypoint_info(void *ctx, string& bucket_name, RGWBucketEntryPoint& entry_point, RGWObjVersionTracker *objv_tracker, time_t *pmtime);
+ int get_bucket_instance_info(void *ctx, string& name, RGWBucketInfo& info, time_t *pmtime, map<string, bufferlist> *pattrs);
+ int get_bucket_instance_from_oid(void *ctx, string& oid, RGWBucketInfo& info, time_t *pmtime, map<string, bufferlist> *pattrs);
+
virtual int get_bucket_info(void *ctx, string& bucket_name, RGWBucketInfo& info,
time_t *pmtime, map<string, bufferlist> *pattrs = NULL);
virtual int put_bucket_info(string& bucket_name, RGWBucketInfo& info, bool exclusive,