]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: multiple fixes related to metadata, bucket creation
authorYehuda Sadeh <yehuda@inktank.com>
Tue, 25 Jun 2013 06:43:50 +0000 (23:43 -0700)
committerYehuda Sadeh <yehuda@inktank.com>
Tue, 25 Jun 2013 06:43:50 +0000 (23:43 -0700)
Signed-off-by: Yehuda Sadeh <yehuda@inktank.com>
src/rgw/rgw_bucket.cc
src/rgw/rgw_bucket.h
src/rgw/rgw_common.h
src/rgw/rgw_json_enc.cc
src/rgw/rgw_metadata.cc
src/rgw/rgw_metadata.h
src/rgw/rgw_rados.cc
src/rgw/rgw_rados.h

index 419f40b5c2d56e7d137d48c92cf76009a5fb79a8..05a15d26760b238a971b491a0f07b0da3c95cd22 100644 (file)
@@ -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;
   }
 
index 3d8ea26539643bc5396d1bd33b16114eb9929a25..2a87e9b097b357f07ce05afaffae23a522f4159f 100644 (file)
@@ -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);
 
 /**
index 179c4fe70c6f195672216611bac1fe05e5abcad4..0fc35e00292bd55b5cd9af24b646433e72522b11 100644 (file)
@@ -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);
   }
 
index 8ab6ff530e65c19be689701089157d010453c4be..1be85d43607487c91d49e67abe8e134f85e8f32f 100644 (file)
@@ -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);
index 6242806ef4d486b68f10d7682ce0035d21d8eb70..99d06fda5c4d6faa4343b19bc0ea39991c2db5a8 100644 (file)
@@ -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;
 
index ba12decdd41fad434da6100fe3eade2879a1ee72..6dd21d10a216e418e92d27f466d91e377be0b442 100644 (file)
@@ -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);
index e5cb6c8ecd47b610401022fc729e7c19f7831d3b..e8638a8173ab96dfaac5671693ae2a9968676080 100644 (file)
@@ -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)
index e6298e733531cbf5bbd191348ba91ca511e9de55..1e6f1de862ff231db1d5b451e632688b0be2b837 100644 (file)
@@ -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);