From 22a9b519282dbd71e91c49f7ffa6b0027620fdcd Mon Sep 17 00:00:00 2001 From: Radoslaw Zarzynski Date: Wed, 9 Mar 2016 17:12:37 +0100 Subject: [PATCH] rgw: add support for metadata upload during PUT on Swift container. Signed-off-by: Radoslaw Zarzynski --- src/rgw/rgw_op.cc | 48 ++++++++++++++++++++++++++++++++++++++- src/rgw/rgw_op.h | 3 +++ src/rgw/rgw_rest_swift.cc | 2 ++ src/rgw/rgw_rest_swift.h | 2 ++ 4 files changed, 54 insertions(+), 1 deletion(-) diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index b1e943fdbd0..6475f4bbdcd 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -1970,8 +1970,13 @@ void RGWCreateBucket::execute() } } - policy.encode(aclbl); + if (need_metadata_upload()) { + rgw_get_request_metadata(s->cct, s->info, attrs, false); + prepare_add_del_attrs(s->bucket_attrs, rmattr_names, attrs, rmattrs); + populate_with_generic_attrs(s, attrs); + } + policy.encode(aclbl); attrs[RGW_ATTR_ACL] = aclbl; if (has_cors) { @@ -2020,6 +2025,47 @@ void RGWCreateBucket::execute() } else if (op_ret == -EEXIST || (op_ret == 0 && existed)) { op_ret = -ERR_BUCKET_EXISTS; } + + if (need_metadata_upload() && existed) { + /* OK, it looks we lost race with another request. As it's required to + * handle metadata fusion and upload, the whole operation becomes very + * similar in nature to PutMetadataBucket. However, as the attrs may + * changed in the meantime, we have to refresh. */ + short tries = 0; + do { + RGWObjectCtx& obj_ctx = *static_cast(s->obj_ctx); + RGWBucketInfo binfo; + map battrs; + + op_ret = store->get_bucket_info(obj_ctx, s->bucket_tenant, s->bucket_name, + binfo, nullptr, &battrs); + if (op_ret < 0) { + return; + } else if (binfo.owner.compare(s->user->user_id) != 0) { + /* New bucket doesn't belong to the account we're operating on. */ + op_ret = -EEXIST; + return; + } else { + s->bucket_info = binfo; + s->bucket_attrs = battrs; + } + + attrs.clear(); + rmattrs.clear(); + + rgw_get_request_metadata(s->cct, s->info, attrs, false); + prepare_add_del_attrs(s->bucket_attrs, rmattr_names, attrs, rmattrs); + populate_with_generic_attrs(s, attrs); + + op_ret = rgw_bucket_set_attrs(store, s->bucket_info, attrs, + &s->bucket_info.objv_tracker); + } while (op_ret == -ECANCELED && tries++ < 20); + + /* Restore the proper return code. */ + if (op_ret >= 0) { + op_ret = -ERR_BUCKET_EXISTS; + } + } } int RGWDeleteBucket::verify_permission() diff --git a/src/rgw/rgw_op.h b/src/rgw/rgw_op.h index 9849b431d3c..61004aee281 100644 --- a/src/rgw/rgw_op.h +++ b/src/rgw/rgw_op.h @@ -538,9 +538,12 @@ protected: bool has_cors; RGWCORSConfiguration cors_config; string swift_ver_location; + set rmattr_names; bufferlist in_data; + virtual bool need_metadata_upload() const { return false; } + public: RGWCreateBucket() : has_cors(false) {} diff --git a/src/rgw/rgw_rest_swift.cc b/src/rgw/rgw_rest_swift.cc index 0b993114f4b..76e01e4999a 100644 --- a/src/rgw/rgw_rest_swift.cc +++ b/src/rgw/rgw_rest_swift.cc @@ -517,6 +517,8 @@ int RGWCreateBucket_ObjStore_SWIFT::get_params() } location_constraint = store->get_zonegroup().api_name; + get_rmattrs_from_headers(s, CONT_PUT_ATTR_PREFIX, + CONT_REMOVE_ATTR_PREFIX, rmattr_names); placement_rule = s->info.env->get("HTTP_X_STORAGE_POLICY", ""); if (s->cct->_conf->rgw_swift_versioning_enabled) { diff --git a/src/rgw/rgw_rest_swift.h b/src/rgw/rgw_rest_swift.h index 5c45d26950e..bbef15bf9b4 100644 --- a/src/rgw/rgw_rest_swift.h +++ b/src/rgw/rgw_rest_swift.h @@ -71,6 +71,8 @@ public: }; class RGWCreateBucket_ObjStore_SWIFT : public RGWCreateBucket_ObjStore { +protected: + bool need_metadata_upload() const override { return true; } public: RGWCreateBucket_ObjStore_SWIFT() {} ~RGWCreateBucket_ObjStore_SWIFT() {} -- 2.47.3