From: Adam C. Emerson Date: Fri, 17 Nov 2017 20:53:05 +0000 (-0500) Subject: rgw: Handle stale bucket info in RGWPutMetadataBucket X-Git-Tag: v12.2.3~205^2~9 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=fc271e4e3c44e520d8a530ebfc758a438c110737;p=ceph.git rgw: Handle stale bucket info in RGWPutMetadataBucket Signed-off-by: Adam C. Emerson (cherry picked from commit ebb86301b20098e15824f469001f6153b27965f5) Fixes: http://tracker.ceph.com/issues/22517 --- diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index 15bd3baa877b..213ce5ab7913 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -4058,55 +4058,61 @@ void RGWPutMetadataBucket::execute() return; } - /* Encode special metadata first as we're using std::map::emplace under - * the hood. This method will add the new items only if the map doesn't - * contain such keys yet. */ - if (has_policy) { - if (s->dialect.compare("swift") == 0) { - auto old_policy = \ - static_cast(s->bucket_acl.get()); - auto new_policy = static_cast(&policy); - new_policy->filter_merge(policy_rw_mask, old_policy); - policy = *new_policy; - } - buffer::list bl; - policy.encode(bl); - emplace_attr(RGW_ATTR_ACL, std::move(bl)); - } + op_ret = retry_raced_bucket_write(store, s, [this] { + /* Encode special metadata first as we're using std::map::emplace under + * the hood. This method will add the new items only if the map doesn't + * contain such keys yet. */ + if (has_policy) { + if (s->dialect.compare("swift") == 0) { + auto old_policy = \ + static_cast(s->bucket_acl.get()); + auto new_policy = static_cast(&policy); + new_policy->filter_merge(policy_rw_mask, old_policy); + policy = *new_policy; + } + buffer::list bl; + policy.encode(bl); + emplace_attr(RGW_ATTR_ACL, std::move(bl)); + } - if (has_cors) { - buffer::list bl; - cors_config.encode(bl); - emplace_attr(RGW_ATTR_CORS, std::move(bl)); - } + if (has_cors) { + buffer::list bl; + cors_config.encode(bl); + emplace_attr(RGW_ATTR_CORS, std::move(bl)); + } - /* It's supposed that following functions WILL NOT change any special - * attributes (like RGW_ATTR_ACL) if they are already present in attrs. */ - prepare_add_del_attrs(s->bucket_attrs, rmattr_names, attrs); - populate_with_generic_attrs(s, attrs); + /* It's supposed that following functions WILL NOT change any + * special attributes (like RGW_ATTR_ACL) if they are already + * present in attrs. */ + prepare_add_del_attrs(s->bucket_attrs, rmattr_names, attrs); + populate_with_generic_attrs(s, attrs); - /* According to the Swift's behaviour and its container_quota WSGI middleware - * implementation: anyone with write permissions is able to set the bucket - * quota. This stays in contrast to account quotas that can be set only by - * clients holding reseller admin privileges. */ - op_ret = filter_out_quota_info(attrs, rmattr_names, s->bucket_info.quota); - if (op_ret < 0) { - return; - } + /* According to the Swift's behaviour and its container_quota + * WSGI middleware implementation: anyone with write permissions + * is able to set the bucket quota. This stays in contrast to + * account quotas that can be set only by clients holding + * reseller admin privileges. */ + op_ret = filter_out_quota_info(attrs, rmattr_names, s->bucket_info.quota); + if (op_ret < 0) { + return op_ret; + } - if (swift_ver_location) { - s->bucket_info.swift_ver_location = *swift_ver_location; - s->bucket_info.swift_versioning = (! swift_ver_location->empty()); - } + if (swift_ver_location) { + s->bucket_info.swift_ver_location = *swift_ver_location; + s->bucket_info.swift_versioning = (!swift_ver_location->empty()); + } - /* Web site of Swift API. */ - filter_out_website(attrs, rmattr_names, s->bucket_info.website_conf); - s->bucket_info.has_website = !s->bucket_info.website_conf.is_empty(); + /* Web site of Swift API. */ + filter_out_website(attrs, rmattr_names, s->bucket_info.website_conf); + s->bucket_info.has_website = !s->bucket_info.website_conf.is_empty(); - /* Setting attributes also stores the provided bucket info. Due to this - * fact, the new quota settings can be serialized with the same call. */ - op_ret = rgw_bucket_set_attrs(store, s->bucket_info, attrs, - &s->bucket_info.objv_tracker); + /* Setting attributes also stores the provided bucket info. Due + * to this fact, the new quota settings can be serialized with + * the same call. */ + op_ret = rgw_bucket_set_attrs(store, s->bucket_info, attrs, + &s->bucket_info.objv_tracker); + return op_ret; + }); } int RGWPutMetadataObject::verify_permission()