~~~~~~~~~~~~~
If the bucket name is unique, within constraints and unused, the operation will succeed.
-If a bucket with the same name already exists and the user is the bucket owner, the operation will succeed.
+If a bucket with the same name already exists and the user is the
+bucket owner, the operation will succeed unless non-default option
+``rgw_bucket_eexist_override`` is `true`.
If the bucket name is already in use, the operation will fail.
+---------------+-----------------------+----------------------------------------------------------+
flags:
- startup
with_legacy: true
+- name: rgw_bucket_eexist_override
+ type: bool
+ level: advanced
+ desc: CreateBucket on an existing bucket of the same owner returns 409/EEXIST, regardless of region.
+ long_desc: Overrides the documented RGW behavior that treats multiple CreateBucket operations by the same
+ owner as idempotent
+ default: false
+ services:
+ - rgw
{ ERR_METHOD_NOT_ALLOWED, {405, "MethodNotAllowed" }},
{ ETIMEDOUT, {408, "RequestTimeout" }},
{ EEXIST, {409, "BucketAlreadyExists" }},
+ { ERR_BUCKET_EXISTS, {409, "BucketAlreadyExists" }},
{ ERR_USER_EXIST, {409, "UserAlreadyExists" }},
{ ERR_EMAIL_EXIST, {409, "EmailExists" }},
{ ERR_KEY_EXIST, {409, "KeyExists"}},
if (op_ret >= 0) {
op_ret = -ERR_BUCKET_EXISTS;
}
- }
-}
+ } /* if (need_metadata_upload() && existed) */
+} /* RGWCreateBucket::execute() */
int RGWDeleteBucket::verify_permission(optional_yield y)
{
void RGWCreateBucket_ObjStore_S3::send_response()
{
- if (op_ret == -ERR_BUCKET_EXISTS)
- op_ret = 0;
- if (op_ret)
+ if (op_ret == -ERR_BUCKET_EXISTS) {
+ const auto eexist_override = s->cct->_conf.get_val<bool>("rgw_bucket_eexist_override");
+ if (! eexist_override) [[likely]] {
+ op_ret = 0;
+ } else {
+ s->err.message = "The requested bucket name is not available. The bucket namespace is shared by all users of the system. Specify a different name and try again.";
+ }
+ }
+
+ if (op_ret) {
set_req_state_err(s, op_ret);
+ }
dump_errno(s);
end_header(s);