diff options
-rw-r--r-- | src/rgw/rgw_op.cc | 21 | ||||
-rw-r--r-- | src/rgw/rgw_rados.cc | 4 |
2 files changed, 24 insertions, 1 deletions
diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index 652d0fd9ccb..44e14ffcd98 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -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); diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index cb396bfadbc..552d8703c4e 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -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; |