]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: bucket recreation should not clobber bucket info
authorYehuda Sadeh <yehuda@inktank.com>
Thu, 7 Feb 2013 00:43:48 +0000 (16:43 -0800)
committerYehuda Sadeh <yehuda@inktank.com>
Thu, 7 Feb 2013 21:25:28 +0000 (13:25 -0800)
Fixes: #4039
User's list of buckets is getting modified even if bucket already
exists. This fix removes the newly created directory object, and
makes sure that user info's data points at the correct bucket.

Signed-off-by: Yehuda Sadeh <yehuda@inktank.com>
Reviewed-by: Greg Farnum <greg@inktank.com>
src/rgw/rgw_op.cc
src/rgw/rgw_rados.cc

index 652d0fd9ccb9a1088a0837204fe0f162078ba955..44e14ffcd98ea56dc03d8e5f3cef2247926c0c76 100644 (file)
@@ -589,6 +589,27 @@ void RGWCreateBucket::execute()
 
   existed = (ret == -EEXIST);
 
+  if (existed) {
+    /* bucket already existed, might have raced with another bucket creation, or
+     * might be partial bucket creation that never completed. Read existing bucket
+     * info, verify that the reported bucket owner is the current user.
+     * If all is ok then update the user's list of buckets
+     */
+    RGWBucketInfo info;
+    map<string, bufferlist> attrs;
+    int r = rgwstore->get_bucket_info(NULL, s->bucket.name, info, &attrs);
+    if (r < 0) {
+      ldout(s->cct, 0) << "ERROR: get_bucket_info on bucket=" << s->bucket.name << " returned err=" << r << " after create_bucket returned -EEXIST" << dendl;
+      ret = r;
+      goto done;
+    }
+    if (info.owner.compare(s->user.user_id) != 0) {
+      ret = -ERR_BUCKET_EXISTS;
+      goto done;
+    }
+    s->bucket = info.bucket;
+  }
+
   ret = rgw_add_bucket(s->user.user_id, s->bucket);
   if (ret && !existed && ret != -EEXIST)   /* if it exists (or previously existed), don't remove it! */
     rgw_remove_user_bucket_info(s->user.user_id, s->bucket);
index cb396bfadbcd4b6c971ba8132e1aca82077d7e91..552d8703c4e5f4bf21da089aa480e4cb4720c178 100644 (file)
@@ -633,8 +633,10 @@ int RGWRados::create_bucket(string& owner, rgw_bucket& bucket,
     info.bucket = bucket;
     info.owner = owner;
     ret = store_bucket_info(info, &attrs, exclusive);
-    if (ret == -EEXIST)
+    if (ret == -EEXIST) {
+      io_ctx.remove(dir_oid);
       return ret;
+    }
   }
 
   return ret;