diff options
author | Yehuda Sadeh <yehuda@inktank.com> | 2013-06-22 22:47:48 -0700 |
---|---|---|
committer | Yehuda Sadeh <yehuda@inktank.com> | 2013-06-23 01:15:56 -0700 |
commit | c3260b276882beedb52f7c77c622a9b77537a63f (patch) | |
tree | 5503992c618ec1400bca43a78d068d78d7c67e49 | |
parent | c103031ec6b259c70e3e33609dbb292f5b04d3fe (diff) | |
download | ceph-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.cc | 10 | ||||
-rw-r--r-- | src/rgw/rgw_bucket.h | 2 | ||||
-rw-r--r-- | src/rgw/rgw_common.h | 36 | ||||
-rw-r--r-- | src/rgw/rgw_json_enc.cc | 2 | ||||
-rw-r--r-- | src/rgw/rgw_op.cc | 4 | ||||
-rw-r--r-- | src/rgw/rgw_rados.cc | 84 | ||||
-rw-r--r-- | src/rgw/rgw_rados.h | 3 |
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, |