Skip to content

Commit 625e3ab

Browse files
committed
rgw/create_bucket: for swift:create_bucket(), should stop creating new bucket_instance_id object and bucket_index shard objects in rados and just update the bucket_instance_info
Signed-off-by: kchheda3 <[email protected]>
1 parent e61bfe0 commit 625e3ab

File tree

3 files changed

+89
-124
lines changed

3 files changed

+89
-124
lines changed

src/rgw/rgw_op.cc

Lines changed: 87 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -3687,6 +3687,84 @@ static int select_bucket_placement(const DoutPrefixProvider* dpp,
36873687
return 0;
36883688
}
36893689

3690+
int put_swift_bucket_metadata(const DoutPrefixProvider* dpp,
3691+
req_state* s,
3692+
RGWAccessControlPolicy& policy,
3693+
bool const has_policy,
3694+
uint32_t policy_rw_mask,
3695+
const RGWCORSConfiguration& cors_config,
3696+
bool const has_cors,
3697+
std::optional<std::string> swift_ver_location,
3698+
const std::set<std::string>& rmattr_names,
3699+
optional_yield y) {
3700+
std::map<std::string, ceph::bufferlist> attrs;
3701+
int op_ret = rgw_get_request_metadata(dpp, s->cct, s->info, attrs, false);
3702+
if (op_ret < 0) {
3703+
return op_ret;
3704+
}
3705+
3706+
return retry_raced_bucket_write(
3707+
dpp, s->bucket.get(),
3708+
[s, has_policy, policy_rw_mask, &policy, cors_config, has_cors, &attrs,
3709+
dpp, rmattr_names, swift_ver_location] {
3710+
/* Encode special metadata first as we're using std::map::emplace under
3711+
* the hood. This method will add the new items only if the map doesn't
3712+
* contain such keys yet. */
3713+
if (has_policy) {
3714+
if (s->dialect.compare("swift") == 0) {
3715+
rgw::swift::merge_policy(policy_rw_mask, s->bucket_acl, policy);
3716+
}
3717+
buffer::list bl;
3718+
policy.encode(bl);
3719+
attrs.emplace(RGW_ATTR_ACL, std::move(bl));
3720+
}
3721+
3722+
if (has_cors) {
3723+
buffer::list bl;
3724+
cors_config.encode(bl);
3725+
attrs.emplace(RGW_ATTR_CORS, std::move(bl));
3726+
}
3727+
3728+
/* It's supposed that following functions WILL NOT change any
3729+
* special attributes (like RGW_ATTR_ACL) if they are already
3730+
* present in attrs. */
3731+
prepare_add_del_attrs(s->bucket_attrs, rmattr_names, attrs);
3732+
populate_with_generic_attrs(s, attrs);
3733+
3734+
/* According to the Swift's behaviour and its container_quota
3735+
* WSGI middleware implementation: anyone with write permissions
3736+
* is able to set the bucket quota. This stays in contrast to
3737+
* account quotas that can be set only by clients holding
3738+
* reseller admin privileges. */
3739+
int ret = filter_out_quota_info(attrs, rmattr_names,
3740+
s->bucket->get_info().quota);
3741+
if (ret < 0) {
3742+
return ret;
3743+
}
3744+
3745+
if (swift_ver_location) {
3746+
s->bucket->get_info().swift_ver_location = *swift_ver_location;
3747+
s->bucket->get_info().swift_versioning =
3748+
(!swift_ver_location->empty());
3749+
}
3750+
3751+
/* Web site of Swift API. */
3752+
filter_out_website(attrs, rmattr_names,
3753+
s->bucket->get_info().website_conf);
3754+
s->bucket->get_info().has_website =
3755+
!s->bucket->get_info().website_conf.is_empty();
3756+
3757+
/* Setting attributes also stores the provided bucket info. Due
3758+
* to this fact, the new quota settings can be serialized with
3759+
* the same call. */
3760+
s->bucket->set_attrs(attrs);
3761+
constexpr bool exclusive = false; // overwrite
3762+
constexpr ceph::real_time no_set_mtime{};
3763+
return s->bucket->put_info(dpp, exclusive, no_set_mtime, s->yield);
3764+
},
3765+
y);
3766+
}
3767+
36903768
void RGWCreateBucket::execute(optional_yield y)
36913769
{
36923770
op_ret = get_params(y);
@@ -3833,6 +3911,12 @@ void RGWCreateBucket::execute(optional_yield y)
38333911
if (!need_metadata_upload()) {
38343912
op_ret = -ERR_BUCKET_EXISTS;
38353913
return;
3914+
} else {
3915+
// For swift, update the bucket metadata and do not call createbucket.
3916+
op_ret = put_swift_bucket_metadata(
3917+
this, s, policy, has_policy, policy_rw_mask, cors_config, has_cors,
3918+
createparams.swift_ver_location, rmattr_names, y);
3919+
return;
38363920
}
38373921
}
38383922

@@ -3900,68 +3984,6 @@ void RGWCreateBucket::execute(optional_yield y)
39003984
/* continue if EEXIST and create_bucket will fail below. this way we can
39013985
* recover from a partial create by retrying it. */
39023986
ldpp_dout(this, 20) << "Bucket::create() returned ret=" << op_ret << " bucket=" << s->bucket << dendl;
3903-
3904-
if (op_ret < 0 && op_ret != -EEXIST && op_ret != -ERR_BUCKET_EXISTS)
3905-
return;
3906-
3907-
const bool existed = s->bucket_exists;
3908-
if (need_metadata_upload() && existed) {
3909-
/* OK, it looks we lost race with another request. As it's required to
3910-
* handle metadata fusion and upload, the whole operation becomes very
3911-
* similar in nature to PutMetadataBucket. However, as the attrs may
3912-
* changed in the meantime, we have to refresh. */
3913-
short tries = 0;
3914-
do {
3915-
map<string, bufferlist> battrs;
3916-
3917-
op_ret = s->bucket->load_bucket(this, y);
3918-
if (op_ret < 0) {
3919-
return;
3920-
} else if (!s->auth.identity->is_owner_of(s->bucket->get_owner())) {
3921-
/* New bucket doesn't belong to the account we're operating on. */
3922-
op_ret = -EEXIST;
3923-
return;
3924-
} else {
3925-
s->bucket_attrs = s->bucket->get_attrs();
3926-
}
3927-
3928-
createparams.attrs.clear();
3929-
3930-
op_ret = rgw_get_request_metadata(this, s->cct, s->info, createparams.attrs, false);
3931-
if (op_ret < 0) {
3932-
return;
3933-
}
3934-
prepare_add_del_attrs(s->bucket_attrs, rmattr_names, createparams.attrs);
3935-
populate_with_generic_attrs(s, createparams.attrs);
3936-
op_ret = filter_out_quota_info(createparams.attrs, rmattr_names,
3937-
s->bucket->get_info().quota);
3938-
if (op_ret < 0) {
3939-
return;
3940-
}
3941-
3942-
/* Handle updates of the metadata for Swift's object versioning. */
3943-
if (createparams.swift_ver_location) {
3944-
s->bucket->get_info().swift_ver_location = *createparams.swift_ver_location;
3945-
s->bucket->get_info().swift_versioning = !createparams.swift_ver_location->empty();
3946-
}
3947-
3948-
/* Web site of Swift API. */
3949-
filter_out_website(createparams.attrs, rmattr_names,
3950-
s->bucket->get_info().website_conf);
3951-
s->bucket->get_info().has_website = !s->bucket->get_info().website_conf.is_empty();
3952-
3953-
/* This will also set the quota on the bucket. */
3954-
s->bucket->set_attrs(std::move(createparams.attrs));
3955-
constexpr bool exclusive = false; // overwrite
3956-
constexpr ceph::real_time no_set_mtime{};
3957-
op_ret = s->bucket->put_info(this, exclusive, no_set_mtime, y);
3958-
} while (op_ret == -ECANCELED && tries++ < 20);
3959-
3960-
/* Restore the proper return code. */
3961-
if (op_ret >= 0) {
3962-
op_ret = -ERR_BUCKET_EXISTS;
3963-
}
3964-
} /* if (need_metadata_upload() && existed) */
39653987
} /* RGWCreateBucket::execute() */
39663988

39673989
int RGWDeleteBucket::verify_permission(optional_yield y)
@@ -5316,71 +5338,15 @@ void RGWPutMetadataBucket::execute(optional_yield y)
53165338
if (op_ret < 0) {
53175339
return;
53185340
}
5319-
5320-
op_ret = rgw_get_request_metadata(this, s->cct, s->info, attrs, false);
5321-
if (op_ret < 0) {
5322-
return;
5323-
}
5324-
53255341
if (!placement_rule.empty() &&
53265342
placement_rule != s->bucket->get_placement_rule()) {
53275343
op_ret = -EEXIST;
53285344
return;
53295345
}
53305346

5331-
op_ret = retry_raced_bucket_write(this, s->bucket.get(), [this] {
5332-
/* Encode special metadata first as we're using std::map::emplace under
5333-
* the hood. This method will add the new items only if the map doesn't
5334-
* contain such keys yet. */
5335-
if (has_policy) {
5336-
if (s->dialect.compare("swift") == 0) {
5337-
rgw::swift::merge_policy(policy_rw_mask, s->bucket_acl, policy);
5338-
}
5339-
buffer::list bl;
5340-
policy.encode(bl);
5341-
emplace_attr(RGW_ATTR_ACL, std::move(bl));
5342-
}
5343-
5344-
if (has_cors) {
5345-
buffer::list bl;
5346-
cors_config.encode(bl);
5347-
emplace_attr(RGW_ATTR_CORS, std::move(bl));
5348-
}
5349-
5350-
/* It's supposed that following functions WILL NOT change any
5351-
* special attributes (like RGW_ATTR_ACL) if they are already
5352-
* present in attrs. */
5353-
prepare_add_del_attrs(s->bucket_attrs, rmattr_names, attrs);
5354-
populate_with_generic_attrs(s, attrs);
5355-
5356-
/* According to the Swift's behaviour and its container_quota
5357-
* WSGI middleware implementation: anyone with write permissions
5358-
* is able to set the bucket quota. This stays in contrast to
5359-
* account quotas that can be set only by clients holding
5360-
* reseller admin privileges. */
5361-
op_ret = filter_out_quota_info(attrs, rmattr_names, s->bucket->get_info().quota);
5362-
if (op_ret < 0) {
5363-
return op_ret;
5364-
}
5365-
5366-
if (swift_ver_location) {
5367-
s->bucket->get_info().swift_ver_location = *swift_ver_location;
5368-
s->bucket->get_info().swift_versioning = (!swift_ver_location->empty());
5369-
}
5370-
5371-
/* Web site of Swift API. */
5372-
filter_out_website(attrs, rmattr_names, s->bucket->get_info().website_conf);
5373-
s->bucket->get_info().has_website = !s->bucket->get_info().website_conf.is_empty();
5374-
5375-
/* Setting attributes also stores the provided bucket info. Due
5376-
* to this fact, the new quota settings can be serialized with
5377-
* the same call. */
5378-
s->bucket->set_attrs(attrs);
5379-
constexpr bool exclusive = false; // overwrite
5380-
constexpr ceph::real_time no_set_mtime{};
5381-
op_ret = s->bucket->put_info(this, exclusive, no_set_mtime, s->yield);
5382-
return op_ret;
5383-
}, y);
5347+
op_ret = put_swift_bucket_metadata(this, s, policy, has_policy,
5348+
policy_rw_mask, cors_config, has_cors,
5349+
swift_ver_location, rmattr_names, y);
53845350
}
53855351

53865352
int RGWPutMetadataObject::verify_permission(optional_yield y)

src/rgw/rgw_op.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1149,6 +1149,8 @@ class RGWCreateBucket : public RGWOp {
11491149
RGWAccessControlPolicy policy;
11501150
std::string location_constraint;
11511151
bool has_cors = false;
1152+
bool has_policy = false;
1153+
uint32_t policy_rw_mask = 0;
11521154
bool relaxed_region_enforcement = false;
11531155
RGWCORSConfiguration cors_config;
11541156
std::set<std::string> rmattr_names;

src/rgw/rgw_rest_swift.cc

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -811,9 +811,6 @@ static int get_swift_versioning_settings(
811811

812812
int RGWCreateBucket_ObjStore_SWIFT::get_params(optional_yield y)
813813
{
814-
bool has_policy;
815-
uint32_t policy_rw_mask = 0;
816-
817814
int r = get_swift_container_settings(s, driver, policy, &has_policy,
818815
&policy_rw_mask, &cors_config, &has_cors);
819816
if (r < 0) {

0 commit comments

Comments
 (0)