diff options
author | Yehuda Sadeh <yehuda@inktank.com> | 2013-06-24 23:43:50 -0700 |
---|---|---|
committer | Yehuda Sadeh <yehuda@inktank.com> | 2013-06-24 23:43:50 -0700 |
commit | 63e81afeb80481ea8ca6987744dce03b0005c7cc (patch) | |
tree | a71b07364cf5783dc4b59a41bb4d2caeccdde550 | |
parent | 7e41c1036de061e0d73cee8a6707d22bc16fb09f (diff) | |
download | ceph-63e81afeb80481ea8ca6987744dce03b0005c7cc.tar.gz |
rgw: multiple fixes related to metadata, bucket creation
Signed-off-by: Yehuda Sadeh <yehuda@inktank.com>
-rw-r--r-- | src/rgw/rgw_bucket.cc | 47 | ||||
-rw-r--r-- | src/rgw/rgw_bucket.h | 2 | ||||
-rw-r--r-- | src/rgw/rgw_common.h | 8 | ||||
-rw-r--r-- | src/rgw/rgw_json_enc.cc | 4 | ||||
-rw-r--r-- | src/rgw/rgw_metadata.cc | 30 | ||||
-rw-r--r-- | src/rgw/rgw_metadata.h | 3 | ||||
-rw-r--r-- | src/rgw/rgw_rados.cc | 38 | ||||
-rw-r--r-- | src/rgw/rgw_rados.h | 1 |
8 files changed, 81 insertions, 52 deletions
diff --git a/src/rgw/rgw_bucket.cc b/src/rgw/rgw_bucket.cc index 419f40b5c2d..05a15d26760 100644 --- a/src/rgw/rgw_bucket.cc +++ b/src/rgw/rgw_bucket.cc @@ -127,10 +127,14 @@ int rgw_bucket_store_info(RGWRados *store, string& bucket_name, bufferlist& bl, return store->meta_mgr->put_entry(bucket_meta_handler, bucket_name, bl, exclusive, objv_tracker, mtime, pattrs); } -int rgw_bucket_instance_store_info(RGWRados *store, string& oid, bufferlist& bl, bool exclusive, +int rgw_bucket_instance_store_info(RGWRados *store, string& entry, bufferlist& bl, bool exclusive, map<string, bufferlist> *pattrs, RGWObjVersionTracker *objv_tracker, time_t mtime) { - return store->meta_mgr->put_entry(bucket_instance_meta_handler, oid, bl, exclusive, objv_tracker, mtime, pattrs); + return store->meta_mgr->put_entry(bucket_instance_meta_handler, entry, bl, exclusive, objv_tracker, mtime, pattrs); +} + +int rgw_bucket_instance_remove_entry(RGWRados *store, string& entry, RGWObjVersionTracker *objv_tracker) { + return store->meta_mgr->remove_entry(bucket_instance_meta_handler, entry, objv_tracker); } #warning removed RGWBucket::create_bucket(), clean this up when ready @@ -1363,20 +1367,16 @@ public: time_t orig_mtime; - int ret = store->get_bucket_entrypoint_info(NULL, entry, be, &objv_tracker, &orig_mtime); + int ret = store->get_bucket_entrypoint_info(NULL, entry, old_be, &objv_tracker, &orig_mtime); if (ret < 0 && ret != -ENOENT) return ret; - ret = store->put_bucket_entrypoint_info(entry, old_be, false, mtime); + ret = store->put_bucket_entrypoint_info(entry, 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 + /* link bucket */ + ret = rgw_add_bucket(store, be.owner, be.bucket, be.creation_time); return 0; } @@ -1465,12 +1465,12 @@ class RGWBucketInstanceMetadataHandler : public RGWMetadataHandler { public: string get_type() { return "bucket.instance"; } - int get(RGWRados *store, string& entry, RGWMetadataObject **obj) { + int get(RGWRados *store, string& oid, RGWMetadataObject **obj) { RGWBucketCompleteInfo bci; time_t mtime; - int ret = store->get_bucket_instance_info(NULL, entry, bci.info, &mtime, &bci.attrs); + int ret = store->get_bucket_instance_info(NULL, oid, bci.info, &mtime, &bci.attrs); if (ret < 0) return ret; @@ -1481,7 +1481,7 @@ public: return 0; } - int put(RGWRados *store, string& entry, RGWObjVersionTracker& objv_tracker, time_t mtime, JSONObj *obj) { + int put(RGWRados *store, string& oid, RGWObjVersionTracker& objv_tracker, time_t mtime, JSONObj *obj) { RGWBucketCompleteInfo bci, old_bci; decode_json_obj(bci, obj); @@ -1489,14 +1489,14 @@ public: old_bci.info.objv_tracker = objv_tracker; - int ret = store->get_bucket_instance_info(NULL, entry, old_bci.info, &orig_mtime, &old_bci.attrs); + int ret = store->get_bucket_instance_info(NULL, oid, old_bci.info, &orig_mtime, &old_bci.attrs); if (ret < 0 && ret != -ENOENT) return ret; if (ret == -ENOENT || old_bci.info.bucket.bucket_id != bci.info.bucket.bucket_id) { /* a new bucket, we need to select a new bucket placement for it */ rgw_bucket bucket; - ret = store->set_bucket_location_by_rule(bci.info.placement_rule, entry, bucket); + ret = store->set_bucket_location_by_rule(bci.info.placement_rule, oid, bucket); if (ret < 0) { ldout(store->ctx(), 0) << "ERROR: select_bucket_placement() returned " << ret << dendl; return ret; @@ -1510,7 +1510,7 @@ public: bci.info.objv_tracker = old_bci.info.objv_tracker; } - ret = store->put_bucket_instance_info(entry, bci.info, false, mtime, &bci.attrs); + ret = store->put_bucket_instance_info(oid, bci.info, false, mtime, &bci.attrs); if (ret < 0) return ret; @@ -1529,18 +1529,17 @@ public: }; 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; - } + RGWBucketInfo info; - return store->delete_bucket(bucket, objv_tracker); + int ret = store->get_bucket_instance_info(NULL, entry, info, NULL, NULL); + if (ret < 0 && ret != -ENOENT) + return ret; + + return rgw_bucket_instance_remove_entry(store, entry, &info.objv_tracker); } void get_pool_and_oid(RGWRados *store, string& key, rgw_bucket& bucket, string& oid) { - oid = key; + oid = RGW_BUCKET_INSTANCE_MD_PREFIX + key; bucket = store->zone.domain_root; } diff --git a/src/rgw/rgw_bucket.h b/src/rgw/rgw_bucket.h index 3d8ea265396..2a87e9b097b 100644 --- a/src/rgw/rgw_bucket.h +++ b/src/rgw/rgw_bucket.h @@ -29,6 +29,8 @@ extern int rgw_bucket_instance_store_info(RGWRados *store, string& oid, bufferli map<string, bufferlist> *pattrs, RGWObjVersionTracker *objv_tracker, time_t mtime); +extern int rgw_bucket_instance_remove_entry(RGWRados *store, string& entry, RGWObjVersionTracker *objv_tracker); + extern int rgw_bucket_delete_bucket_obj(RGWRados *store, string& bucket_name, RGWObjVersionTracker& objv_tracker); /** diff --git a/src/rgw/rgw_common.h b/src/rgw/rgw_common.h index 179c4fe70c6..0fc35e00292 100644 --- a/src/rgw/rgw_common.h +++ b/src/rgw/rgw_common.h @@ -684,16 +684,19 @@ struct RGWBucketEntryPoint { rgw_bucket bucket; string owner; + time_t creation_time; bool has_bucket_info; RGWBucketInfo old_bucket_info; - RGWBucketEntryPoint() : has_bucket_info(false) {} + RGWBucketEntryPoint() : creation_time(0), has_bucket_info(false) {} void encode(bufferlist& bl) const { ENCODE_START(8, 8, bl); ::encode(bucket, bl); ::encode(owner, bl); + uint64_t ctime = (uint64_t)creation_time; + ::encode(ctime, bl); ENCODE_FINISH(bl); } void decode(bufferlist::iterator& bl) { @@ -708,6 +711,9 @@ struct RGWBucketEntryPoint has_bucket_info = false; ::decode(bucket, bl); ::decode(owner, bl); + uint64_t ctime; + ::decode(ctime, bl); + creation_time = (uint64_t)ctime; DECODE_FINISH(bl); } diff --git a/src/rgw/rgw_json_enc.cc b/src/rgw/rgw_json_enc.cc index 8ab6ff530e6..1be85d43607 100644 --- a/src/rgw/rgw_json_enc.cc +++ b/src/rgw/rgw_json_enc.cc @@ -439,6 +439,8 @@ void rgw_bucket::decode_json(JSONObj *obj) { void RGWBucketEntryPoint::dump(Formatter *f) const { encode_json("bucket", bucket, f); + encode_json("owner", owner, f); + encode_json("creation_time", creation_time, f); encode_json("has_bucket_info", has_bucket_info, f); if (has_bucket_info) { encode_json("old_bucket_info", old_bucket_info, f); @@ -447,6 +449,8 @@ void RGWBucketEntryPoint::dump(Formatter *f) const void RGWBucketEntryPoint::decode_json(JSONObj *obj) { JSONDecoder::decode_json("bucket", bucket, obj); + JSONDecoder::decode_json("owner", owner, obj); + JSONDecoder::decode_json("creation_time", creation_time, 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); diff --git a/src/rgw/rgw_metadata.cc b/src/rgw/rgw_metadata.cc index 6242806ef4d..99d06fda5c4 100644 --- a/src/rgw/rgw_metadata.cc +++ b/src/rgw/rgw_metadata.cc @@ -28,6 +28,9 @@ struct LogStatusDump { case MDLOG_STATUS_COMPLETE: s = "complete"; break; + case MDLOG_STATUS_ABORT: + s = "abort"; + break; default: s = "unknown"; break; @@ -499,17 +502,23 @@ int RGWMetadataManager::pre_modify(RGWMetadataHandler *handler, string& section, } int RGWMetadataManager::post_modify(string& section, string& key, RGWMetadataLogData& log_data, - RGWObjVersionTracker *objv_tracker) + RGWObjVersionTracker *objv_tracker, int ret) { - log_data.status = MDLOG_STATUS_COMPLETE; + if (ret >= 0) + log_data.status = MDLOG_STATUS_COMPLETE; + else + log_data.status = MDLOG_STATUS_ABORT; bufferlist logbl; ::encode(log_data, logbl); - int ret = md_log->add_entry(store, section, key, logbl); + int r = md_log->add_entry(store, section, key, logbl); if (ret < 0) return ret; + if (r < 0) + return r; + return 0; } @@ -530,10 +539,9 @@ int RGWMetadataManager::put_entry(RGWMetadataHandler *handler, string& key, buff ret = rgw_put_system_obj(store, bucket, oid, bl.c_str(), bl.length(), exclusive, objv_tracker, mtime, pattrs); - if (ret < 0) - return ret; + /* cascading ret into post_modify() */ - ret = post_modify(section, key, log_data, objv_tracker); + ret = post_modify(section, key, log_data, objv_tracker, ret); if (ret < 0) return ret; @@ -556,10 +564,9 @@ int RGWMetadataManager::remove_entry(RGWMetadataHandler *handler, string& key, R rgw_obj obj(bucket, oid); ret = store->delete_obj(NULL, obj); - if (ret < 0) - return ret; + /* cascading ret into post_modify() */ - ret = post_modify(section, key, log_data, objv_tracker); + ret = post_modify(section, key, log_data, objv_tracker, ret); if (ret < 0) return ret; @@ -578,10 +585,9 @@ int RGWMetadataManager::set_attrs(RGWMetadataHandler *handler, string& key, return ret; ret = store->set_attrs(NULL, obj, attrs, rmattrs, objv_tracker); - if (ret < 0) - return ret; + /* cascading ret into post_modify() */ - ret = post_modify(section, key, log_data, objv_tracker); + ret = post_modify(section, key, log_data, objv_tracker, ret); if (ret < 0) return ret; diff --git a/src/rgw/rgw_metadata.h b/src/rgw/rgw_metadata.h index ba12decdd41..6dd21d10a21 100644 --- a/src/rgw/rgw_metadata.h +++ b/src/rgw/rgw_metadata.h @@ -22,6 +22,7 @@ enum RGWMDLogStatus { MDLOG_STATUS_SETATTRS, MDLOG_STATUS_REMOVE, MDLOG_STATUS_COMPLETE, + MDLOG_STATUS_ABORT, }; class RGWMetadataObject { @@ -117,7 +118,7 @@ class RGWMetadataManager { RGWMetadataLogData& log_data, RGWObjVersionTracker *objv_tracker, RGWMDLogStatus op_type); int post_modify(string& section, string& key, RGWMetadataLogData& log_data, - RGWObjVersionTracker *objv_tracker); + RGWObjVersionTracker *objv_tracker, int ret); public: RGWMetadataManager(CephContext *_cct, RGWRados *_store); diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index e5cb6c8ecd4..e8638a8173a 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -1807,6 +1807,14 @@ int RGWRados::create_bucket(RGWUserInfo& owner, rgw_bucket& bucket, info.creation_time = creation_time; ret = put_bucket_info(bucket.name, info, exclusive, 0, &attrs, true); if (ret == -EEXIST) { + /* remove bucket meta instance */ + string entry; + get_bucket_instance_entry(bucket, entry); + r = rgw_bucket_instance_remove_entry(this, entry, &info.objv_tracker); + if (r < 0) + return r; + + /* remove bucket index */ librados::IoCtx index_ctx; // context for new bucket int r = open_bucket_index_ctx(bucket, index_ctx); if (r < 0) @@ -4460,9 +4468,16 @@ int RGWRados::get_bucket_stats(rgw_bucket& bucket, uint64_t *bucket_ver, uint64_ return 0; } +void RGWRados::get_bucket_instance_entry(rgw_bucket& bucket, string& entry) +{ + entry = bucket.name + ":" + bucket.bucket_id; +} + void RGWRados::get_bucket_meta_oid(rgw_bucket& bucket, string& oid) { - oid = RGW_BUCKET_INSTANCE_MD_PREFIX + bucket.name + ":" + bucket.bucket_id; + string entry; + get_bucket_instance_entry(bucket, entry); + oid = RGW_BUCKET_INSTANCE_MD_PREFIX + entry; } int RGWRados::get_bucket_instance_info(void *ctx, string& entry, RGWBucketInfo& info, @@ -4564,6 +4579,7 @@ int RGWRados::put_bucket_entrypoint_info(string& bucket_name, RGWBucketEntryPoin bufferlist epbl; ::encode(entry_point, epbl); RGWObjVersionTracker ot; + ot.generate_new_write_ver(cct); return rgw_bucket_store_info(this, bucket_name, epbl, exclusive, NULL, &ot, mtime); } @@ -4575,9 +4591,9 @@ int RGWRados::put_bucket_instance_info(string& bucket_name, RGWBucketInfo& info, ::encode(info, bl); - string oid; - get_bucket_meta_oid(info.bucket, oid); - return rgw_bucket_instance_store_info(this, oid, bl, exclusive, pattrs, &info.objv_tracker, mtime); + string key; + get_bucket_instance_entry(info.bucket, key); /* when we go through meta api, we don't use oid directly */ + return rgw_bucket_instance_store_info(this, key, bl, exclusive, pattrs, &info.objv_tracker, mtime); } int RGWRados::put_bucket_info(string& bucket_name, RGWBucketInfo& info, bool exclusive, @@ -4598,18 +4614,12 @@ int RGWRados::put_bucket_info(string& bucket_name, RGWBucketInfo& info, bool exc RGWBucketEntryPoint entry_point; entry_point.bucket = info.bucket; entry_point.owner = info.owner; + entry_point.creation_time = info.creation_time; 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) { - ldout(cct, 0) << "ERROR: failed removing object " << obj << " when trying to clean up" << dendl; - } - } + if (ret < 0) + return ret; - return ret; + return 0; } int RGWRados::omap_get_vals(rgw_obj& obj, bufferlist& header, const string& marker, uint64_t count, std::map<string, bufferlist>& m) diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h index e6298e73353..1e6f1de862f 100644 --- a/src/rgw/rgw_rados.h +++ b/src/rgw/rgw_rados.h @@ -1269,6 +1269,7 @@ 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_instance_entry(rgw_bucket& bucket, string& entry); 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); |