From: Casey Bodley Date: Sat, 18 Mar 2023 15:48:38 +0000 (-0400) Subject: rgw/sal: move User::create_bucket() to Bucket::create() X-Git-Tag: v19.0.0~122^2~6 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=e2eb66a36175dbd7ee0cdc706b1965c978807416;p=ceph-ci.git rgw/sal: move User::create_bucket() to Bucket::create() the CreateBucket operation always has to deal with existing buckets, so we have to load the Bucket handle first anyway also moves the related placement and forward_request_to_master() logic out of sal entirely Signed-off-by: Casey Bodley --- diff --git a/src/rgw/driver/d4n/rgw_sal_d4n.cc b/src/rgw/driver/d4n/rgw_sal_d4n.cc index 93cd8f2d415..efeb281c3ce 100644 --- a/src/rgw/driver/d4n/rgw_sal_d4n.cc +++ b/src/rgw/driver/d4n/rgw_sal_d4n.cc @@ -59,33 +59,11 @@ std::unique_ptr D4NFilterBucket::get_object(const rgw_obj_key& k) return std::make_unique(std::move(o), this, filter); } -int D4NFilterUser::create_bucket(const DoutPrefixProvider* dpp, - const rgw_bucket& b, - const std::string& zonegroup_id, - const rgw_placement_rule& placement_rule, - const std::string& swift_ver_location, - const RGWQuotaInfo * pquota_info, - const RGWAccessControlPolicy& policy, - Attrs& attrs, - RGWBucketInfo& info, - obj_version& ep_objv, - bool exclusive, - bool obj_lock_enabled, - bool* existed, - req_info& req_info, - std::unique_ptr* bucket_out, - optional_yield y) +int D4NFilterBucket::create(const DoutPrefixProvider* dpp, + const CreateParams& params, + optional_yield y) { - std::unique_ptr nb; - int ret; - - ret = next->create_bucket(dpp, b, zonegroup_id, placement_rule, swift_ver_location, pquota_info, policy, attrs, info, ep_objv, exclusive, obj_lock_enabled, existed, req_info, &nb, y); - if (ret < 0) - return ret; - - Bucket* fb = new D4NFilterBucket(std::move(nb), this, filter); - bucket_out->reset(fb); - return 0; + return next->create(dpp, params, y); } int D4NFilterObject::copy_object(User* user, diff --git a/src/rgw/driver/d4n/rgw_sal_d4n.h b/src/rgw/driver/d4n/rgw_sal_d4n.h index 459e885fc24..a54371f6cc6 100644 --- a/src/rgw/driver/d4n/rgw_sal_d4n.h +++ b/src/rgw/driver/d4n/rgw_sal_d4n.h @@ -71,23 +71,6 @@ class D4NFilterUser : public FilterUser { FilterUser(std::move(_next)), filter(_filter) {} virtual ~D4NFilterUser() = default; - - virtual int create_bucket(const DoutPrefixProvider* dpp, - const rgw_bucket& b, - const std::string& zonegroup_id, - const rgw_placement_rule& placement_rule, - const std::string& swift_ver_location, - const RGWQuotaInfo* pquota_info, - const RGWAccessControlPolicy& policy, - Attrs& attrs, - RGWBucketInfo& info, - obj_version& ep_objv, - bool exclusive, - bool obj_lock_enabled, - bool* existed, - req_info& req_info, - std::unique_ptr* bucket, - optional_yield y) override; }; class D4NFilterBucket : public FilterBucket { @@ -101,6 +84,9 @@ class D4NFilterBucket : public FilterBucket { virtual ~D4NFilterBucket() = default; virtual std::unique_ptr get_object(const rgw_obj_key& key) override; + virtual int create(const DoutPrefixProvider* dpp, + const CreateParams& params, + optional_yield y) override; }; class D4NFilterObject : public FilterObject { diff --git a/src/rgw/driver/dbstore/common/dbstore.cc b/src/rgw/driver/dbstore/common/dbstore.cc index 54202862c8d..5a4ae021ead 100644 --- a/src/rgw/driver/dbstore/common/dbstore.cc +++ b/src/rgw/driver/dbstore/common/dbstore.cc @@ -474,20 +474,16 @@ out: } int DB::create_bucket(const DoutPrefixProvider *dpp, - const RGWUserInfo& owner, rgw_bucket& bucket, - const string& zonegroup_id, + const rgw_user& owner, const rgw_bucket& bucket, + const std::string& zonegroup_id, const rgw_placement_rule& placement_rule, - const string& swift_ver_location, - const RGWQuotaInfo * pquota_info, - map& attrs, - RGWBucketInfo& info, - obj_version *pobjv, + const std::map& attrs, + const std::optional& swift_ver_location, + const std::optional& quota, + std::optional creation_time, obj_version *pep_objv, - real_time creation_time, - rgw_bucket *pmaster_bucket, - uint32_t *pmaster_num_shards, - optional_yield y, - bool exclusive) + RGWBucketInfo& info, + optional_yield y) { /* * XXX: Simple creation for now. @@ -506,50 +502,48 @@ int DB::create_bucket(const DoutPrefixProvider *dpp, orig_info.bucket.name = bucket.name; ret = get_bucket_info(dpp, string("name"), "", orig_info, nullptr, nullptr, nullptr); - if (!ret && !orig_info.owner.id.empty() && exclusive) { + if (!ret && !orig_info.owner.id.empty()) { /* already exists. Return the old info */ - info = std::move(orig_info); return ret; } RGWObjVersionTracker& objv_tracker = info.objv_tracker; - objv_tracker.read_version.clear(); + objv_tracker.generate_new_write_ver(cct); - if (pobjv) { - objv_tracker.write_version = *pobjv; - } else { - objv_tracker.generate_new_write_ver(cct); - } params.op.bucket.bucket_version = objv_tracker.write_version; objv_tracker.read_version = params.op.bucket.bucket_version; - uint64_t bid = next_bucket_id(); - string s = getDBname() + "." + std::to_string(bid); - bucket.marker = bucket.bucket_id = s; - info.bucket = bucket; - info.owner = owner.user_id; + if (info.bucket.marker.empty()) { + uint64_t bid = next_bucket_id(); + string s = getDBname() + "." + std::to_string(bid); + info.bucket.marker = info.bucket.bucket_id = s; + } + + info.owner = owner; info.zonegroup = zonegroup_id; info.placement_rule = placement_rule; - info.swift_ver_location = swift_ver_location; - info.swift_versioning = (!swift_ver_location.empty()); + if (swift_ver_location) { + info.swift_ver_location = *swift_ver_location; + } + info.swift_versioning = swift_ver_location.has_value(); info.requester_pays = false; - if (real_clock::is_zero(creation_time)) { - info.creation_time = ceph::real_clock::now(); + if (creation_time) { + info.creation_time = *creation_time; } else { - info.creation_time = creation_time; + info.creation_time = ceph::real_clock::now(); } - if (pquota_info) { - info.quota = *pquota_info; + if (quota) { + info.quota = *quota; } params.op.bucket.info = info; params.op.bucket.bucket_attrs = attrs; params.op.bucket.mtime = ceph::real_time(); - params.op.user.uinfo.user_id.id = owner.user_id.id; + params.op.user.uinfo.user_id.id = owner.id; ret = ProcessOp(dpp, "InsertBucket", ¶ms); diff --git a/src/rgw/driver/dbstore/common/dbstore.h b/src/rgw/driver/dbstore/common/dbstore.h index b26cc116e82..79f312cb844 100644 --- a/src/rgw/driver/dbstore/common/dbstore.h +++ b/src/rgw/driver/dbstore/common/dbstore.h @@ -1595,20 +1595,16 @@ class DB { RGWBucketInfo& info, rgw::sal::Attrs* pattrs, ceph::real_time* pmtime, obj_version* pbucket_version); int create_bucket(const DoutPrefixProvider *dpp, - const RGWUserInfo& owner, rgw_bucket& bucket, + const rgw_user& owner, const rgw_bucket& bucket, const std::string& zonegroup_id, const rgw_placement_rule& placement_rule, - const std::string& swift_ver_location, - const RGWQuotaInfo * pquota_info, - std::map& attrs, - RGWBucketInfo& info, - obj_version *pobjv, + const std::map& attrs, + const std::optional& swift_ver_location, + const std::optional& quota, + std::optional creation_time, obj_version *pep_objv, - real_time creation_time, - rgw_bucket *pmaster_bucket, - uint32_t *pmaster_num_shards, - optional_yield y, - bool exclusive); + RGWBucketInfo& info, + optional_yield y); int next_bucket_id() { return ++max_bucket_id; }; diff --git a/src/rgw/driver/dbstore/tests/dbstore_tests.cc b/src/rgw/driver/dbstore/tests/dbstore_tests.cc index 27edb7b8573..14fe9c37e75 100644 --- a/src/rgw/driver/dbstore/tests/dbstore_tests.cc +++ b/src/rgw/driver/dbstore/tests/dbstore_tests.cc @@ -461,45 +461,37 @@ TEST_F(DBStoreTest, CreateBucket) { struct DBOpParams params = GlobalParams; int ret = -1; RGWBucketInfo info; - RGWUserInfo owner; + rgw_user owner; rgw_bucket bucket; obj_version objv; rgw_placement_rule rule; map attrs; - owner.user_id.id = "user_id1"; + owner.id = "user_id1"; bucket.name = "bucket1"; bucket.tenant = "tenant"; - objv.ver = 2; - objv.tag = "write_tag"; - rule.name = "rule1"; rule.storage_class = "sc1"; - ret = db->create_bucket(dpp, owner, bucket, "zid", rule, "swift_ver", NULL, - attrs, info, &objv, NULL, bucket_mtime, NULL, NULL, - null_yield, false); + ret = db->create_bucket(dpp, owner, bucket, "zid", rule, attrs, "swift_ver", + std::nullopt, bucket_mtime, nullptr, info, null_yield); ASSERT_EQ(ret, 0); bucket.name = "bucket2"; - ret = db->create_bucket(dpp, owner, bucket, "zid", rule, "swift_ver", NULL, - attrs, info, &objv, NULL, bucket_mtime, NULL, NULL, - null_yield, false); + ret = db->create_bucket(dpp, owner, bucket, "zid", rule, attrs, "swift_ver", + std::nullopt, bucket_mtime, nullptr, info, null_yield); ASSERT_EQ(ret, 0); bucket.name = "bucket3"; - ret = db->create_bucket(dpp, owner, bucket, "zid", rule, "swift_ver", NULL, - attrs, info, &objv, NULL, bucket_mtime, NULL, NULL, - null_yield, false); + ret = db->create_bucket(dpp, owner, bucket, "zid", rule, attrs, "swift_ver", + std::nullopt, bucket_mtime, nullptr, info, null_yield); ASSERT_EQ(ret, 0); bucket.name = "bucket4"; - ret = db->create_bucket(dpp, owner, bucket, "zid", rule, "swift_ver", NULL, - attrs, info, &objv, NULL, bucket_mtime, NULL, NULL, - null_yield, false); + ret = db->create_bucket(dpp, owner, bucket, "zid", rule, attrs, "swift_ver", + std::nullopt, bucket_mtime, nullptr, info, null_yield); ASSERT_EQ(ret, 0); bucket.name = "bucket5"; - ret = db->create_bucket(dpp, owner, bucket, "zid", rule, "swift_ver", NULL, - attrs, info, &objv, NULL, bucket_mtime, NULL, NULL, - null_yield, false); + ret = db->create_bucket(dpp, owner, bucket, "zid", rule, attrs, "swift_ver", + std::nullopt, bucket_mtime, nullptr, info, null_yield); ASSERT_EQ(ret, 0); } @@ -516,14 +508,14 @@ TEST_F(DBStoreTest, GetBucketQueryByName) { ASSERT_EQ(binfo.bucket.name, "bucket2"); ASSERT_EQ(binfo.bucket.tenant, "tenant"); ASSERT_EQ(binfo.owner.id, "user_id1"); - ASSERT_EQ(binfo.objv_tracker.read_version.ver, 2); - ASSERT_EQ(binfo.objv_tracker.read_version.tag, "write_tag"); + ASSERT_EQ(binfo.objv_tracker.read_version.ver, 1); + ASSERT_FALSE(binfo.objv_tracker.read_version.tag.empty()); ASSERT_EQ(binfo.zonegroup, "zid"); ASSERT_EQ(binfo.creation_time, bucket_mtime); ASSERT_EQ(binfo.placement_rule.name, "rule1"); ASSERT_EQ(binfo.placement_rule.storage_class, "sc1"); - ASSERT_EQ(objv.ver, 2); - ASSERT_EQ(objv.tag, "write_tag"); + ASSERT_EQ(objv.ver, 1); + ASSERT_FALSE(objv.tag.empty()); marker1 = binfo.bucket.marker; } @@ -575,7 +567,7 @@ TEST_F(DBStoreTest, BucketChown) { ret = db->update_bucket(dpp, "owner", info, false, &user, nullptr, &bucket_mtime, nullptr); ASSERT_EQ(ret, 0); - ASSERT_EQ(info.objv_tracker.read_version.ver, 3); + ASSERT_EQ(info.objv_tracker.read_version.ver, 2); } TEST_F(DBStoreTest, ListAllBuckets) { diff --git a/src/rgw/driver/posix/rgw_sal_posix.cc b/src/rgw/driver/posix/rgw_sal_posix.cc index 5204017274a..e4e640b0203 100644 --- a/src/rgw/driver/posix/rgw_sal_posix.cc +++ b/src/rgw/driver/posix/rgw_sal_posix.cc @@ -37,51 +37,6 @@ const std::string MP_OBJ_PART_PFX = "part-"; const std::string MP_OBJ_PART_FMT = "{:0>5}"; const std::string MP_OBJ_HEAD_NAME = MP_OBJ_PART_PFX + "00000"; -static int decode_policy(CephContext* cct, - bufferlist& bl, - RGWAccessControlPolicy* policy) -{ - auto iter = bl.cbegin(); - try { - policy->decode(iter); - } catch (buffer::error& err) { - ldout(cct, 0) << "ERROR: could not decode policy, caught buffer::error" << dendl; - return -EIO; - } - if (cct->_conf->subsys.should_gather()) { - ldout(cct, 15) << __func__ << " POSIX Read AccessControlPolicy"; - RGWAccessControlPolicy_S3* s3policy = static_cast(policy); - s3policy->to_xml(*_dout); - *_dout << dendl; - } - return 0; -} - -static int rgw_op_get_bucket_policy_from_attr(const DoutPrefixProvider* dpp, - POSIXDriver* driver, - User* user, - Attrs& bucket_attrs, - RGWAccessControlPolicy* policy, - optional_yield y) -{ - auto aiter = bucket_attrs.find(RGW_ATTR_ACL); - - if (aiter != bucket_attrs.end()) { - int ret = decode_policy(driver->ctx(), aiter->second, policy); - if (ret < 0) - return ret; - } else { - ldout(driver->ctx(), 0) << "WARNING: couldn't find acl header for bucket, generating default" << dendl; - /* object exists, but policy is broken */ - int r = user->load_user(dpp, y); - if (r < 0) - return r; - - policy->create_default(user->get_id(), user->get_display_name()); - } - return 0; -} - static inline bool get_attr(Attrs& attrs, const char* name, bufferlist& bl) { auto iter = attrs.find(name); @@ -566,74 +521,46 @@ int POSIXUser::list_buckets(const DoutPrefixProvider* dpp, const std::string& ma return 0; } -int POSIXUser::create_bucket(const DoutPrefixProvider* dpp, - const rgw_bucket& b, - const std::string& zonegroup_id, - const rgw_placement_rule& placement_rule, - const std::string& swift_ver_location, - const RGWQuotaInfo * pquota_info, - const RGWAccessControlPolicy& policy, - Attrs& attrs, - RGWBucketInfo& binfo, - obj_version& ep_objv, - bool exclusive, - bool obj_lock_enabled, - bool* existed, - req_info& req_info, - std::unique_ptr* bucket_out, - optional_yield y) -{ - /* Check for existence */ - { - std::unique_ptr bucket; +int POSIXBucket::create(const DoutPrefixProvider* dpp, + const CreateParams& params, + optional_yield y) +{ + ceph_assert(owner); + info.owner = owner->get_id(); - int ret = driver->load_bucket(dpp, this, b, &bucket, y); - if (ret >= 0) { - *existed = true; - // Bucket exists. Check owner comparison - if (bucket->get_info().owner.compare(this->get_id()) != 0) { - return -EEXIST; - } - // Don't allow changes to ACL policy - RGWAccessControlPolicy old_policy(driver->ctx()); - ret = rgw_op_get_bucket_policy_from_attr( - dpp, driver, this, bucket->get_attrs(), &old_policy, y); - if (ret >= 0 && old_policy != policy) { - bucket_out->swap(bucket); - return -EEXIST; - } - } else { - *existed = false; - } - } + info.bucket.marker = params.marker; + info.bucket.bucket_id = params.bucket_id; - binfo.bucket = b; - binfo.owner = get_id(); - binfo.zonegroup = zonegroup_id; - binfo.placement_rule = placement_rule; - binfo.swift_ver_location = swift_ver_location; - binfo.swift_versioning = (!swift_ver_location.empty()); - binfo.requester_pays = false; - binfo.creation_time = ceph::real_clock::now(); - if (pquota_info) { - binfo.quota = *pquota_info; + info.zonegroup = params.zonegroup_id; + info.placement_rule = params.placement_rule; + info.swift_versioning = params.swift_ver_location.has_value(); + if (params.swift_ver_location) { + info.swift_ver_location = *params.swift_ver_location; + } + if (params.obj_lock_enabled) { + info.flags |= BUCKET_VERSIONED | BUCKET_OBJ_LOCK_ENABLED; + } + info.requester_pays = false; + if (params.creation_time) { + info.creation_time = *params.creation_time; + } else { + info.creation_time = ceph::real_clock::now(); + } + if (params.quota) { + info.quota = *params.quota; } - POSIXBucket* fb = new POSIXBucket(driver, driver->get_root_fd(), binfo, this); - - int ret = fb->set_attrs(attrs); + int ret = set_attrs(attrs); if (ret < 0) { - delete fb; - return ret; + return ret; } - ret = fb->create(dpp, y, existed); + bool existed = false; + ret = create(dpp, y, &existed); if (ret < 0) { - delete fb; - return ret; + return ret; } - bucket_out->reset(fb); return 0; } @@ -1240,7 +1167,7 @@ int POSIXBucket::create(const DoutPrefixProvider* dpp, optional_yield y, bool* e } else if (existed != nullptr) { *existed = true; } - return ret; + return -ret; } return write_attrs(dpp, y); diff --git a/src/rgw/driver/posix/rgw_sal_posix.h b/src/rgw/driver/posix/rgw_sal_posix.h index e132f240812..c5360aa90f9 100644 --- a/src/rgw/driver/posix/rgw_sal_posix.h +++ b/src/rgw/driver/posix/rgw_sal_posix.h @@ -121,22 +121,6 @@ public: const std::string& marker, const std::string& end_marker, uint64_t max, bool need_stats, BucketList& buckets, optional_yield y) override; - virtual int create_bucket(const DoutPrefixProvider* dpp, - const rgw_bucket& b, - const std::string& zonegroup_id, - const rgw_placement_rule& placement_rule, - const std::string& swift_ver_location, - const RGWQuotaInfo* pquota_info, - const RGWAccessControlPolicy& policy, - Attrs& attrs, - RGWBucketInfo& info, - obj_version& ep_objv, - bool exclusive, - bool obj_lock_enabled, - bool* existed, - req_info& req_info, - std::unique_ptr* bucket, - optional_yield y) override; virtual Attrs& get_attrs() override { return next->get_attrs(); } virtual void set_attrs(Attrs& _attrs) override { next->set_attrs(_attrs); } virtual int read_attrs(const DoutPrefixProvider* dpp, optional_yield y) override; @@ -197,6 +181,9 @@ public: bool keep_index_consistent, optional_yield y, const DoutPrefixProvider *dpp) override; + virtual int create(const DoutPrefixProvider* dpp, + const CreateParams& params, + optional_yield y) override; virtual int load_bucket(const DoutPrefixProvider* dpp, optional_yield y) override; virtual RGWAccessControlPolicy& get_acl(void) override { return acls; } virtual int set_acl(const DoutPrefixProvider* dpp, RGWAccessControlPolicy& acl, diff --git a/src/rgw/driver/rados/rgw_rados.cc b/src/rgw/driver/rados/rgw_rados.cc index 1ec17637435..3632e66af59 100644 --- a/src/rgw/driver/rados/rgw_rados.cc +++ b/src/rgw/driver/rados/rgw_rados.cc @@ -2272,79 +2272,70 @@ void RGWRados::create_bucket_id(string *bucket_id) *bucket_id = buf; } -int RGWRados::create_bucket(const RGWUserInfo& owner, rgw_bucket& bucket, - const string& zonegroup_id, +int RGWRados::create_bucket(const DoutPrefixProvider* dpp, + optional_yield y, + const rgw_bucket& bucket, + const rgw_user& owner, + const std::string& zonegroup_id, const rgw_placement_rule& placement_rule, - const string& swift_ver_location, + const RGWZonePlacementInfo* zone_placement, + const std::map& attrs, bool obj_lock_enabled, - const RGWQuotaInfo * pquota_info, - map& attrs, - RGWBucketInfo& info, - obj_version *pobjv, - obj_version *pep_objv, - real_time creation_time, - const rgw_bucket* pmaster_bucket, - optional_yield y, - const DoutPrefixProvider *dpp, - bool exclusive) + const std::optional& swift_ver_location, + const std::optional& quota, + std::optional creation_time, + obj_version* pep_objv, + RGWBucketInfo& info) { -#define MAX_CREATE_RETRIES 20 /* need to bound retries */ - rgw_placement_rule selected_placement_rule; - RGWZonePlacementInfo rule_info; + int ret = 0; +#define MAX_CREATE_RETRIES 20 /* need to bound retries */ for (int i = 0; i < MAX_CREATE_RETRIES; i++) { - int ret = 0; - ret = svc.zone->select_bucket_placement(dpp, owner, zonegroup_id, placement_rule, - &selected_placement_rule, &rule_info, y); - if (ret < 0) - return ret; - - if (!pmaster_bucket) { - create_bucket_id(&bucket.marker); - bucket.bucket_id = bucket.marker; - } else { - bucket.marker = pmaster_bucket->marker; - bucket.bucket_id = pmaster_bucket->bucket_id; - } - RGWObjVersionTracker& objv_tracker = info.objv_tracker; - objv_tracker.read_version.clear(); + objv_tracker.generate_new_write_ver(cct); - if (pobjv) { - objv_tracker.write_version = *pobjv; + if (bucket.marker.empty()) { + create_bucket_id(&info.bucket.marker); + info.bucket.bucket_id = info.bucket.marker; } else { - objv_tracker.generate_new_write_ver(cct); + info.bucket = bucket; } - info.bucket = bucket; - info.owner = owner.user_id; + info.owner = owner; info.zonegroup = zonegroup_id; - info.placement_rule = selected_placement_rule; - info.swift_ver_location = swift_ver_location; - info.swift_versioning = (!swift_ver_location.empty()); + info.placement_rule = placement_rule; + info.swift_versioning = swift_ver_location.has_value(); + if (swift_ver_location) { + info.swift_ver_location = *swift_ver_location; + } if (obj_lock_enabled) { info.flags |= BUCKET_VERSIONED | BUCKET_OBJ_LOCK_ENABLED; } - init_default_bucket_layout(cct, info.layout, svc.zone->get_zone(), - rule_info.index_type); + if (zone_placement) { + init_default_bucket_layout(cct, info.layout, svc.zone->get_zone(), + zone_placement->index_type); + } info.requester_pays = false; - if (real_clock::is_zero(creation_time)) { - info.creation_time = ceph::real_clock::now(); + if (creation_time) { + info.creation_time = *creation_time; } else { - info.creation_time = creation_time; + info.creation_time = ceph::real_clock::now(); } - if (pquota_info) { - info.quota = *pquota_info; + if (quota) { + info.quota = *quota; } - int r = svc.bi->init_index(dpp, info, info.layout.current_index); - if (r < 0) { - return r; + if (zone_placement) { + ret = svc.bi->init_index(dpp, info, info.layout.current_index); + if (ret < 0) { + return ret; + } } + constexpr bool exclusive = true; ret = put_linked_bucket_info(info, exclusive, ceph::real_time(), pep_objv, &attrs, true, dpp, y); if (ret == -ECANCELED) { ret = -EEXIST; @@ -2352,7 +2343,7 @@ int RGWRados::create_bucket(const RGWUserInfo& owner, rgw_bucket& bucket, if (ret == -EEXIST) { /* we need to reread the info and return it, caller will have a use for it */ RGWBucketInfo orig_info; - r = get_bucket_info(&svc, bucket.tenant, bucket.name, orig_info, NULL, y, NULL); + int r = get_bucket_info(&svc, bucket.tenant, bucket.name, orig_info, NULL, y, NULL); if (r < 0) { if (r == -ENOENT) { continue; @@ -2363,10 +2354,12 @@ int RGWRados::create_bucket(const RGWUserInfo& owner, rgw_bucket& bucket, /* only remove it if it's a different bucket instance */ if (orig_info.bucket.bucket_id != bucket.bucket_id) { - int r = svc.bi->clean_index(dpp, info, info.layout.current_index); - if (r < 0) { - ldpp_dout(dpp, 0) << "WARNING: could not remove bucket index (r=" << r << ")" << dendl; - } + if (zone_placement) { + r = svc.bi->clean_index(dpp, info, info.layout.current_index); + if (r < 0) { + ldpp_dout(dpp, 0) << "WARNING: could not remove bucket index (r=" << r << ")" << dendl; + } + } r = ctl.bucket->remove_bucket_instance_info(info.bucket, info, y, dpp); if (r < 0) { ldpp_dout(dpp, 0) << "WARNING: " << __func__ << "(): failed to remove bucket instance info: bucket instance=" << info.bucket.get_key() << ": r=" << r << dendl; diff --git a/src/rgw/driver/rados/rgw_rados.h b/src/rgw/driver/rados/rgw_rados.h index 18e818c4e89..77a08c068a6 100644 --- a/src/rgw/driver/rados/rgw_rados.h +++ b/src/rgw/driver/rados/rgw_rados.h @@ -628,21 +628,20 @@ public: bool get_obj_data_pool(const rgw_placement_rule& placement_rule, const rgw_obj& obj, rgw_pool *pool); bool obj_to_raw(const rgw_placement_rule& placement_rule, const rgw_obj& obj, rgw_raw_obj *raw_obj); - int create_bucket(const RGWUserInfo& owner, rgw_bucket& bucket, - const std::string& zonegroup_id, - const rgw_placement_rule& placement_rule, - const std::string& swift_ver_location, - bool obj_lock_enabled, - const RGWQuotaInfo * pquota_info, - std::map& attrs, - RGWBucketInfo& bucket_info, - obj_version *pobjv, - obj_version *pep_objv, - ceph::real_time creation_time, - const rgw_bucket *master_bucket, - optional_yield y, - const DoutPrefixProvider *dpp, - bool exclusive = true); + int create_bucket(const DoutPrefixProvider* dpp, + optional_yield y, + const rgw_bucket& bucket, + const rgw_user& owner, + const std::string& zonegroup_id, + const rgw_placement_rule& placement_rule, + const RGWZonePlacementInfo* zone_placement, + const std::map& attrs, + bool obj_lock_enabled, + const std::optional& swift_ver_location, + const std::optional& quota, + std::optional creation_time, + obj_version* pep_objv, + RGWBucketInfo& info); RGWCoroutinesManagerRegistry *get_cr_registry() { return cr_registry; } diff --git a/src/rgw/driver/rados/rgw_sal_rados.cc b/src/rgw/driver/rados/rgw_sal_rados.cc index 328b4f82c8f..fd8964e83ba 100644 --- a/src/rgw/driver/rados/rgw_sal_rados.cc +++ b/src/rgw/driver/rados/rgw_sal_rados.cc @@ -120,120 +120,52 @@ int RadosUser::list_buckets(const DoutPrefixProvider* dpp, const std::string& ma return 0; } -int RadosUser::create_bucket(const DoutPrefixProvider* dpp, - const rgw_bucket& b, - const std::string& zonegroup_id, - const rgw_placement_rule& placement_rule, - const std::string& swift_ver_location, - const RGWQuotaInfo * pquota_info, - const RGWAccessControlPolicy& policy, - Attrs& attrs, - RGWBucketInfo& info, - obj_version& ep_objv, - bool exclusive, - bool obj_lock_enabled, - bool* existed, - req_info& req_info, - std::unique_ptr* bucket_out, - optional_yield y) -{ - int ret; - bufferlist in_data; - RGWBucketInfo master_info; - rgw_bucket* pmaster_bucket = nullptr; - real_time creation_time; - std::unique_ptr bucket; - obj_version objv,* pobjv = NULL; - - /* If it exists, look it up; otherwise create it */ - ret = store->load_bucket(dpp, this, b, &bucket, y); - if (ret < 0 && ret != -ENOENT) - return ret; - - if (ret != -ENOENT) { - *existed = true; - } else { - bucket = std::unique_ptr(new RadosBucket(store, b, this)); - *existed = false; - bucket->set_attrs(attrs); - } - - if (!store->svc()->zone->is_meta_master()) { - JSONParser jp; - ret = store->forward_request_to_master(dpp, this, NULL, in_data, &jp, req_info, y); - if (ret < 0) { - return ret; - } - - JSONDecoder::decode_json("entry_point_object_ver", ep_objv, &jp); - JSONDecoder::decode_json("object_ver", objv, &jp); - JSONDecoder::decode_json("bucket_info", master_info, &jp); - ldpp_dout(dpp, 20) << "parsed: objv.tag=" << objv.tag << " objv.ver=" << objv.ver << dendl; - std::time_t ctime = ceph::real_clock::to_time_t(master_info.creation_time); - ldpp_dout(dpp, 20) << "got creation time: << " << std::put_time(std::localtime(&ctime), "%F %T") << dendl; - pmaster_bucket= &master_info.bucket; - creation_time = master_info.creation_time; - pobjv = &objv; - obj_lock_enabled = master_info.obj_lock_enabled(); - } - - std::string zid = zonegroup_id; - if (zid.empty()) { - zid = store->svc()->zone->get_zonegroup().get_id(); - } - - if (*existed) { - rgw_placement_rule selected_placement_rule; - ret = store->svc()->zone->select_bucket_placement(dpp, this->get_info(), - zid, placement_rule, - &selected_placement_rule, nullptr, y); - if (selected_placement_rule != info.placement_rule) { - ret = -EEXIST; - bucket_out->swap(bucket); - return ret; - } - } else { - - ret = store->getRados()->create_bucket(this->get_info(), bucket->get_key(), - zid, placement_rule, swift_ver_location, - obj_lock_enabled, pquota_info, - attrs, info, pobjv, &ep_objv, creation_time, - pmaster_bucket, y, dpp, exclusive); - if (ret == -EEXIST) { - *existed = true; - /* 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. Otherwise inform - * client about a name conflict. - */ - if (info.owner.compare(this->get_id()) != 0) { - return -EEXIST; - } - ret = 0; - } else if (ret != 0) { - return ret; +int RadosBucket::create(const DoutPrefixProvider* dpp, + const CreateParams& params, + optional_yield y) +{ + ceph_assert(owner); + const rgw_user& owner_id = owner->get_id(); + + rgw_bucket key = get_key(); + key.marker = params.marker; + key.bucket_id = params.bucket_id; + + int ret = store->getRados()->create_bucket( + dpp, y, key, owner_id, params.zonegroup_id, + params.placement_rule, params.zone_placement, params.attrs, + params.obj_lock_enabled, params.swift_ver_location, + params.quota, params.creation_time, &bucket_version, info); + + bool existed = false; + if (ret == -EEXIST) { + existed = true; + /* 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. Otherwise inform + * client about a name conflict. + */ + if (info.owner != owner_id) { + return -ERR_BUCKET_EXISTS; } + ret = 0; + } else if (ret != 0) { + return ret; } - bucket->set_version(ep_objv); - bucket->get_info() = info; - - RadosBucket* rbucket = static_cast(bucket.get()); - ret = rbucket->link(dpp, this, y, false); - if (ret && !*existed && ret != -EEXIST) { + ret = link(dpp, owner, y, false); + if (ret && !existed && ret != -EEXIST) { /* if it exists (or previously existed), don't remove it! */ - ret = rbucket->unlink(dpp, this, y); + ret = unlink(dpp, owner, y); if (ret < 0) { ldpp_dout(dpp, 0) << "WARNING: failed to unlink bucket: ret=" << ret << dendl; } - } else if (ret == -EEXIST || (ret == 0 && *existed)) { + } else if (ret == -EEXIST || (ret == 0 && existed)) { ret = -ERR_BUCKET_EXISTS; } - bucket_out->swap(bucket); - return ret; } diff --git a/src/rgw/driver/rados/rgw_sal_rados.h b/src/rgw/driver/rados/rgw_sal_rados.h index 8c1926f3fbe..c8fa876260b 100644 --- a/src/rgw/driver/rados/rgw_sal_rados.h +++ b/src/rgw/driver/rados/rgw_sal_rados.h @@ -274,22 +274,6 @@ class RadosUser : public StoreUser { int list_buckets(const DoutPrefixProvider* dpp, const std::string& marker, const std::string& end_marker, uint64_t max, bool need_stats, BucketList& buckets, optional_yield y) override; - virtual int create_bucket(const DoutPrefixProvider* dpp, - const rgw_bucket& b, - const std::string& zonegroup_id, - const rgw_placement_rule& placement_rule, - const std::string& swift_ver_location, - const RGWQuotaInfo * pquota_info, - const RGWAccessControlPolicy& policy, - Attrs& attrs, - RGWBucketInfo& info, - obj_version& ep_objv, - bool exclusive, - bool obj_lock_enabled, - bool* existed, - req_info& req_info, - std::unique_ptr* bucket, - optional_yield y) override; virtual int read_attrs(const DoutPrefixProvider* dpp, optional_yield y) override; virtual int merge_and_store_attrs(const DoutPrefixProvider* dpp, Attrs& new_attrs, optional_yield y) override; virtual int read_stats(const DoutPrefixProvider *dpp, @@ -544,6 +528,8 @@ class RadosBucket : public StoreBucket { DoutPrefixProvider *dpp) override; virtual RGWAccessControlPolicy& get_acl(void) override { return acls; } virtual int set_acl(const DoutPrefixProvider* dpp, RGWAccessControlPolicy& acl, optional_yield y) override; + int create(const DoutPrefixProvider* dpp, const CreateParams& params, + optional_yield y) override; virtual int load_bucket(const DoutPrefixProvider* dpp, optional_yield y) override; virtual int read_stats(const DoutPrefixProvider *dpp, const bucket_index_layout_generation& idx_layout, diff --git a/src/rgw/driver/rados/rgw_zone.cc b/src/rgw/driver/rados/rgw_zone.cc index 8c237f6beda..a9cc179f06c 100644 --- a/src/rgw/driver/rados/rgw_zone.cc +++ b/src/rgw/driver/rados/rgw_zone.cc @@ -1094,6 +1094,27 @@ int delete_zone(const DoutPrefixProvider* dpp, optional_yield y, return writer.remove(dpp, y); } +auto find_zone_placement(const DoutPrefixProvider* dpp, + const RGWZoneParams& info, + const rgw_placement_rule& rule) + -> const RGWZonePlacementInfo* +{ + auto i = info.placement_pools.find(rule.name); + if (i == info.placement_pools.end()) { + ldpp_dout(dpp, 0) << "ERROR: This zone does not contain placement rule " + << rule.name << dendl; + return nullptr; + } + + const std::string& storage_class = rule.get_storage_class(); + if (!i->second.storage_class_exists(storage_class)) { + ldpp_dout(dpp, 5) << "ERROR: The zone placement for rule " << rule.name + << " does not contain storage class " << storage_class << dendl; + return nullptr; + } + + return &i->second; +} static int read_or_create_default_zone(const DoutPrefixProvider* dpp, optional_yield y, diff --git a/src/rgw/driver/rados/rgw_zone.h b/src/rgw/driver/rados/rgw_zone.h index 6d55fd52c57..b57b05ada85 100644 --- a/src/rgw/driver/rados/rgw_zone.h +++ b/src/rgw/driver/rados/rgw_zone.h @@ -943,6 +943,12 @@ int delete_zone(const DoutPrefixProvider* dpp, optional_yield y, sal::ConfigStore* cfgstore, const RGWZoneParams& info, sal::ZoneWriter& writer); +/// Return the zone placement corresponding to the given rule, or nullptr. +auto find_zone_placement(const DoutPrefixProvider* dpp, + const RGWZoneParams& info, + const rgw_placement_rule& rule) + -> const RGWZonePlacementInfo*; + /// Global state about the site configuration. Initialized once during /// startup and may be reinitialized by RGWRealmReloader, but is otherwise diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index 067a939d753..1bd1fd85ba0 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -487,6 +487,8 @@ int rgw_build_bucket_policies(const DoutPrefixProvider *dpp, rgw::sal::Driver* d s->bucket_acl = std::make_unique(s->cct); } + const RGWZoneGroup& zonegroup = s->penv.site->get_zonegroup(); + /* check if copy source is within the current domain */ if (!s->src_bucket_name.empty()) { std::unique_ptr src_bucket; @@ -494,8 +496,7 @@ int rgw_build_bucket_policies(const DoutPrefixProvider *dpp, rgw::sal::Driver* d rgw_bucket(s->src_tenant_name, s->src_bucket_name), &src_bucket, y); if (ret == 0) { - string& zonegroup = src_bucket->get_info().zonegroup; - s->local_source = driver->get_zone()->get_zonegroup().equals(zonegroup); + s->local_source = zonegroup.equals(src_bucket->get_info().zonegroup); } } @@ -543,20 +544,13 @@ int rgw_build_bucket_policies(const DoutPrefixProvider *dpp, rgw::sal::Driver* d s->bucket_owner = s->bucket_acl->get_owner(); - std::unique_ptr zonegroup; - int r = driver->get_zonegroup(s->bucket->get_info().zonegroup, &zonegroup); - if (!r) { - s->zonegroup_endpoint = zonegroup->get_endpoint(); - s->zonegroup_name = zonegroup->get_name(); - } - if (r < 0 && ret == 0) { - ret = r; - } + s->zonegroup_endpoint = rgw::get_zonegroup_endpoint(zonegroup); + s->zonegroup_name = zonegroup.get_name(); - if (!driver->get_zone()->get_zonegroup().equals(s->bucket->get_info().zonegroup)) { + if (!zonegroup.equals(s->bucket->get_info().zonegroup)) { ldpp_dout(dpp, 0) << "NOTICE: request for data in a different zonegroup (" << s->bucket->get_info().zonegroup << " != " - << driver->get_zone()->get_zonegroup().get_id() << ")" << dendl; + << zonegroup.get_id() << ")" << dendl; /* we now need to make sure that the operation actually requires copy source, that is * it's a copy operation */ @@ -3331,6 +3325,47 @@ static void filter_out_website(std::map& add_attr } } +static int select_bucket_placement(const DoutPrefixProvider* dpp, + const RGWZoneGroup& zonegroup, + const RGWUserInfo& user, + rgw_placement_rule& rule) +{ + std::string_view selected = "requested"; + + // select placement: requested rule > user default > zonegroup default + if (rule.name.empty()) { + selected = "user-default"; + rule.inherit_from(user.default_placement); + if (rule.name.empty()) { + selected = "zonegroup-default"; + rule.inherit_from(zonegroup.default_placement); + if (rule.name.empty()) { + ldpp_dout(dpp, 0) << "ERROR: misconfigured zonegroup " << zonegroup.id + << ", default placement should not be empty" << dendl; + return -ERR_ZONEGROUP_DEFAULT_PLACEMENT_MISCONFIGURATION; + } + } + } + + // look up the zonegroup placement target + auto target = zonegroup.placement_targets.find(rule.name); + if (target == zonegroup.placement_targets.end()) { + ldpp_dout(dpp, 0) << "could not find " << selected << " placement target " + << rule.name << " within zonegroup" << dendl; + return -ERR_INVALID_LOCATION_CONSTRAINT; + } + + // check the user's permission tags + if (!target->second.user_permitted(user.placement_tags)) { + ldpp_dout(dpp, 0) << "user not permitted to use placement rule " + << target->first << dendl; + return -EPERM; + } + + ldpp_dout(dpp, 20) << "using " << selected << " placement target " + << rule.name << dendl; + return 0; +} void RGWCreateBucket::execute(optional_yield y) { @@ -3338,149 +3373,181 @@ void RGWCreateBucket::execute(optional_yield y) if (op_ret < 0) return; - if (!relaxed_region_enforcement && - !location_constraint.empty() && - !driver->get_zone()->has_zonegroup_api(location_constraint)) { - ldpp_dout(this, 0) << "location constraint (" << location_constraint << ")" - << " can't be found." << dendl; + const rgw::SiteConfig& site = *s->penv.site; + const std::optional& period = site.get_period(); + const RGWZoneGroup& my_zonegroup = site.get_zonegroup(); + + if (s->system_request) { + // allow system requests to override the target zonegroup. for forwarded + // requests, we'll create the bucket for the originating zonegroup + createparams.zonegroup_id = s->info.args.get(RGW_SYS_PARAM_PREFIX "zonegroup"); + } + + const RGWZoneGroup* bucket_zonegroup = &my_zonegroup; + if (createparams.zonegroup_id.empty()) { + // default to the local zonegroup + createparams.zonegroup_id = my_zonegroup.id; + } else if (period) { + auto z = period->period_map.zonegroups.find(createparams.zonegroup_id); + if (z == period->period_map.zonegroups.end()) { + ldpp_dout(this, 0) << "could not find zonegroup " + << createparams.zonegroup_id << " in current period" << dendl; + op_ret = -ENOENT; + return; + } + bucket_zonegroup = &z->second; + } else if (createparams.zonegroup_id != my_zonegroup.id) { + ldpp_dout(this, 0) << "zonegroup does not match current zonegroup " + << createparams.zonegroup_id << dendl; + op_ret = -ENOENT; + return; + } + + // validate the LocationConstraint + if (!location_constraint.empty() && !relaxed_region_enforcement) { + // on the master zonegroup, allow any valid api_name. otherwise it has to + // match the bucket's zonegroup + if (period && my_zonegroup.is_master) { + if (!period->period_map.zonegroups_by_api.count(location_constraint)) { + ldpp_dout(this, 0) << "location constraint (" << location_constraint + << ") can't be found." << dendl; + op_ret = -ERR_INVALID_LOCATION_CONSTRAINT; + s->err.message = "The specified location-constraint is not valid"; + return; + } + } else if (bucket_zonegroup->api_name != location_constraint) { + ldpp_dout(this, 0) << "location constraint (" << location_constraint + << ") doesn't match zonegroup (" << bucket_zonegroup->api_name + << ')' << dendl; op_ret = -ERR_INVALID_LOCATION_CONSTRAINT; s->err.message = "The specified location-constraint is not valid"; return; + } } - if (!relaxed_region_enforcement && !driver->get_zone()->get_zonegroup().is_master_zonegroup() && !location_constraint.empty() && - driver->get_zone()->get_zonegroup().get_api_name() != location_constraint) { - ldpp_dout(this, 0) << "location constraint (" << location_constraint << ")" - << " doesn't match zonegroup" << " (" << driver->get_zone()->get_zonegroup().get_api_name() << ")" - << dendl; - op_ret = -ERR_INVALID_LOCATION_CONSTRAINT; - s->err.message = "The specified location-constraint is not valid"; + // select and validate the placement target + op_ret = select_bucket_placement(this, *bucket_zonegroup, s->user->get_info(), + createparams.placement_rule); + if (op_ret < 0) { return; } - std::set names; - driver->get_zone()->get_zonegroup().get_placement_target_names(names); - if (!placement_rule.name.empty() && - !names.count(placement_rule.name)) { - ldpp_dout(this, 0) << "placement target (" << placement_rule.name << ")" - << " doesn't exist in the placement targets of zonegroup" - << " (" << driver->get_zone()->get_zonegroup().get_api_name() << ")" << dendl; - op_ret = -ERR_INVALID_LOCATION_CONSTRAINT; - s->err.message = "The specified placement target does not exist"; - return; + if (bucket_zonegroup == &my_zonegroup) { + // look up the zone placement pool + createparams.zone_placement = rgw::find_zone_placement( + this, site.get_zone_params(), createparams.placement_rule); + if (!createparams.zone_placement) { + op_ret = -ERR_INVALID_LOCATION_CONSTRAINT; + return; + } } - /* we need to make sure we read bucket info, it's not read before for this - * specific request */ - { - std::unique_ptr tmp_bucket; - op_ret = driver->load_bucket(this, s->user.get(), - rgw_bucket(s->bucket_tenant, s->bucket_name), - &tmp_bucket, y); - if (op_ret < 0 && op_ret != -ENOENT) - return; - s->bucket_exists = (op_ret != -ENOENT); + // read the bucket info if it exists + op_ret = driver->load_bucket(this, s->user.get(), + rgw_bucket(s->bucket_tenant, s->bucket_name), + &s->bucket, y); + if (op_ret < 0 && op_ret != -ENOENT) + return; + s->bucket_exists = (op_ret != -ENOENT); + ceph_assert(s->bucket); // creates handle even on ENOENT - if (s->bucket_exists) { - if (!s->system_request && - driver->get_zone()->get_zonegroup().get_id() != - tmp_bucket->get_info().zonegroup) { - op_ret = -EEXIST; - return; - } - /* Initialize info from req_state */ - info = tmp_bucket->get_info(); + if (s->bucket_exists) { + const RGWBucketInfo& info = s->bucket->get_info(); - if (!swift_ver_location) { - swift_ver_location = info.swift_ver_location; - } - placement_rule.inherit_from(info.placement_rule); - - // don't allow changes to the acl policy - RGWAccessControlPolicy old_policy(get_cct()); - int r = rgw_op_get_bucket_policy_from_attr(this, s->cct, driver, info.owner, - tmp_bucket->get_attrs(), - &old_policy, y); - if (r >= 0 && old_policy != policy) { - s->err.message = "Cannot modify existing access control policy"; - op_ret = -EEXIST; - return; - } + if (!s->system_request && createparams.zonegroup_id != info.zonegroup) { + s->err.message = "Cannot modify existing bucket's zonegroup"; + op_ret = -EEXIST; + return; } - } - s->bucket_owner.set_id(s->user->get_id()); - s->bucket_owner.set_name(s->user->get_display_name()); + if (!createparams.swift_ver_location) { + createparams.swift_ver_location = info.swift_ver_location; + } - string zonegroup_id; + // don't allow changes to placement + if (createparams.placement_rule != info.placement_rule) { + s->err.message = "Cannot modify existing bucket's placement rule"; + op_ret = -EEXIST; + return; + } - if (s->system_request) { - zonegroup_id = s->info.args.get(RGW_SYS_PARAM_PREFIX "zonegroup"); - if (zonegroup_id.empty()) { - zonegroup_id = driver->get_zone()->get_zonegroup().get_id(); + // don't allow changes to the acl policy + RGWAccessControlPolicy old_policy(get_cct()); + int r = rgw_op_get_bucket_policy_from_attr(this, s->cct, driver, info.owner, + s->bucket->get_attrs(), + &old_policy, y); + if (r >= 0 && old_policy != policy) { + s->err.message = "Cannot modify existing access control policy"; + op_ret = -EEXIST; + return; } - } else { - zonegroup_id = driver->get_zone()->get_zonegroup().get_id(); } - /* 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. */ + s->bucket_owner.set_id(s->user->get_id()); + s->bucket_owner.set_name(s->user->get_display_name()); + buffer::list aclbl; policy.encode(aclbl); - emplace_attr(RGW_ATTR_ACL, std::move(aclbl)); + createparams.attrs[RGW_ATTR_ACL] = std::move(aclbl); if (has_cors) { buffer::list corsbl; cors_config.encode(corsbl); - emplace_attr(RGW_ATTR_CORS, std::move(corsbl)); + createparams.attrs[RGW_ATTR_CORS] = std::move(corsbl); } - RGWQuotaInfo quota_info; - const RGWQuotaInfo * pquota_info = nullptr; if (need_metadata_upload()) { /* It's supposed that following functions WILL NOT change any special * attributes (like RGW_ATTR_ACL) if they are already present in attrs. */ - op_ret = rgw_get_request_metadata(this, s->cct, s->info, attrs, false); + op_ret = rgw_get_request_metadata(this, s->cct, s->info, + createparams.attrs, false); if (op_ret < 0) { return; } - prepare_add_del_attrs(s->bucket_attrs, rmattr_names, attrs); - populate_with_generic_attrs(s, attrs); + prepare_add_del_attrs(s->bucket_attrs, rmattr_names, createparams.attrs); + populate_with_generic_attrs(s, createparams.attrs); - op_ret = filter_out_quota_info(attrs, rmattr_names, quota_info); + RGWQuotaInfo quota; + op_ret = filter_out_quota_info(createparams.attrs, rmattr_names, quota); if (op_ret < 0) { return; } - pquota_info = "a_info; + createparams.quota = quota; /* Web site of Swift API. */ - filter_out_website(attrs, rmattr_names, info.website_conf); + RGWBucketInfo& info = s->bucket->get_info(); + filter_out_website(createparams.attrs, rmattr_names, info.website_conf); info.has_website = !info.website_conf.is_empty(); } - rgw_bucket tmp_bucket; - tmp_bucket.tenant = s->bucket_tenant; /* ignored if bucket exists */ - tmp_bucket.name = s->bucket_name; + if (!driver->is_meta_master()) { + // apply bucket creation on the master zone first + bufferlist in_data; + JSONParser jp; + op_ret = driver->forward_request_to_master(this, s->user.get(), nullptr, + in_data, &jp, s->info, y); + if (op_ret < 0) { + return; + } + + RGWBucketInfo master_info; + JSONDecoder::decode_json("bucket_info", master_info, &jp); - /* Handle updates of the metadata for Swift's object versioning. */ - if (swift_ver_location) { - info.swift_ver_location = *swift_ver_location; - info.swift_versioning = (! swift_ver_location->empty()); + // update params with info from the master + createparams.marker = master_info.bucket.marker; + createparams.bucket_id = master_info.bucket.bucket_id; + createparams.zonegroup_id = master_info.zonegroup; + createparams.obj_lock_enabled = master_info.obj_lock_enabled(); + createparams.quota = master_info.quota; + createparams.creation_time = master_info.creation_time; } - /* We're replacing bucket with the newly created one */ - ldpp_dout(this, 10) << "user=" << s->user << " bucket=" << tmp_bucket << dendl; - op_ret = s->user->create_bucket(this, tmp_bucket, zonegroup_id, - placement_rule, - info.swift_ver_location, - pquota_info, policy, attrs, info, ep_objv, - true, obj_lock_enabled, &s->bucket_exists, s->info, - &s->bucket, y); + ldpp_dout(this, 10) << "user=" << s->user << " bucket=" << s->bucket << dendl; + op_ret = s->bucket->create(this, createparams, y); /* continue if EEXIST and create_bucket will fail below. this way we can * recover from a partial create by retrying it. */ - ldpp_dout(this, 20) << "rgw_create_bucket returned ret=" << op_ret << " bucket=" << s->bucket.get() << dendl; + ldpp_dout(this, 20) << "Bucket::create() returned ret=" << op_ret << " bucket=" << s->bucket << dendl; if (op_ret) return; @@ -3506,31 +3573,33 @@ void RGWCreateBucket::execute(optional_yield y) s->bucket_attrs = s->bucket->get_attrs(); } - attrs.clear(); + createparams.attrs.clear(); - op_ret = rgw_get_request_metadata(this, s->cct, s->info, attrs, false); + op_ret = rgw_get_request_metadata(this, s->cct, s->info, createparams.attrs, false); if (op_ret < 0) { return; } - prepare_add_del_attrs(s->bucket_attrs, rmattr_names, attrs); - populate_with_generic_attrs(s, attrs); - op_ret = filter_out_quota_info(attrs, rmattr_names, s->bucket->get_info().quota); + prepare_add_del_attrs(s->bucket_attrs, rmattr_names, createparams.attrs); + populate_with_generic_attrs(s, createparams.attrs); + op_ret = filter_out_quota_info(createparams.attrs, rmattr_names, + s->bucket->get_info().quota); if (op_ret < 0) { return; } /* Handle updates of the metadata for Swift's object versioning. */ - if (swift_ver_location) { - s->bucket->get_info().swift_ver_location = *swift_ver_location; - s->bucket->get_info().swift_versioning = (! swift_ver_location->empty()); + if (createparams.swift_ver_location) { + s->bucket->get_info().swift_ver_location = *createparams.swift_ver_location; + s->bucket->get_info().swift_versioning = !createparams.swift_ver_location->empty(); } /* Web site of Swift API. */ - filter_out_website(attrs, rmattr_names, s->bucket->get_info().website_conf); + filter_out_website(createparams.attrs, rmattr_names, + s->bucket->get_info().website_conf); s->bucket->get_info().has_website = !s->bucket->get_info().website_conf.is_empty(); /* This will also set the quota on the bucket. */ - op_ret = s->bucket->merge_and_store_attrs(this, attrs, y); + op_ret = s->bucket->merge_and_store_attrs(this, createparams.attrs, y); } while (op_ret == -ECANCELED && tries++ < 20); /* Restore the proper return code. */ @@ -7561,54 +7630,73 @@ int RGWBulkUploadOp::handle_dir(const std::string_view path, optional_yield y) { ldpp_dout(this, 20) << "got directory=" << path << dendl; - op_ret = handle_dir_verify_permission(y); - if (op_ret < 0) { - return op_ret; + int ret = handle_dir_verify_permission(y); + if (ret < 0) { + return ret; } std::string bucket_name; rgw_obj_key object_junk; std::tie(bucket_name, object_junk) = *parse_path(path); - /* we need to make sure we read bucket info, it's not read before for this - * specific request */ - std::unique_ptr bucket; - - /* Create metadata: ACLs. */ - std::map attrs; - RGWAccessControlPolicy policy; - policy.create_default(s->user->get_id(), s->user->get_display_name()); - ceph::bufferlist aclbl; - policy.encode(aclbl); - attrs.emplace(RGW_ATTR_ACL, std::move(aclbl)); - - obj_version objv, ep_objv; - bool bucket_exists; - RGWQuotaInfo quota_info; - const RGWQuotaInfo* pquota_info = nullptr; - RGWBucketInfo out_info; - string swift_ver_location; rgw_bucket new_bucket; - req_info info = s->info; new_bucket.tenant = s->bucket_tenant; /* ignored if bucket exists */ new_bucket.name = bucket_name; - rgw_placement_rule placement_rule; - placement_rule.storage_class = s->info.storage_class; - forward_req_info(this, s->cct, info, bucket_name); - - op_ret = s->user->create_bucket(this, new_bucket, - driver->get_zone()->get_zonegroup().get_id(), - placement_rule, swift_ver_location, - pquota_info, policy, attrs, - out_info, ep_objv, - true, false, &bucket_exists, - info, &bucket, y); - /* continue if EEXIST and create_bucket will fail below. this way we can - * recover from a partial create by retrying it. */ - ldpp_dout(this, 20) << "rgw_create_bucket returned ret=" << op_ret - << ", bucket=" << bucket << dendl; - return op_ret; + // load the bucket + std::unique_ptr bucket; + ret = driver->load_bucket(this, s->user.get(), new_bucket, &bucket, y); + + // return success if it exists + if (ret != -ENOENT) { + return ret; + } + ceph_assert(bucket); // creates handle even on ENOENT + + const auto& zonegroup = s->penv.site->get_zonegroup(); + + rgw::sal::Bucket::CreateParams createparams; + createparams.zonegroup_id = zonegroup.id; + createparams.placement_rule.storage_class = s->info.storage_class; + op_ret = select_bucket_placement(this, zonegroup, s->user->get_info(), + createparams.placement_rule); + createparams.zone_placement = rgw::find_zone_placement( + this, s->penv.site->get_zone_params(), createparams.placement_rule); + + { + // create a default acl + RGWAccessControlPolicy policy; + policy.create_default(s->user->get_id(), s->user->get_display_name()); + ceph::bufferlist aclbl; + policy.encode(aclbl); + createparams.attrs[RGW_ATTR_ACL] = std::move(aclbl); + } + + if (!driver->is_meta_master()) { + // apply bucket creation on the master zone first + bufferlist in_data; + JSONParser jp; + req_info req = s->info; + forward_req_info(this, s->cct, req, bucket_name); + + ret = driver->forward_request_to_master(this, s->user.get(), nullptr, + in_data, &jp, req, y); + if (ret < 0) { + return ret; + } + + RGWBucketInfo master_info; + JSONDecoder::decode_json("bucket_info", master_info, &jp); + + // update params with info from the master + createparams.marker = master_info.bucket.marker; + createparams.bucket_id = master_info.bucket.bucket_id; + createparams.obj_lock_enabled = master_info.obj_lock_enabled(); + createparams.quota = master_info.quota; + createparams.creation_time = master_info.creation_time; + } + + return bucket->create(this, createparams, y); } diff --git a/src/rgw/rgw_op.h b/src/rgw/rgw_op.h index e1189cb236d..21044046680 100644 --- a/src/rgw/rgw_op.h +++ b/src/rgw/rgw_op.h @@ -1076,31 +1076,21 @@ public: }; class RGWCreateBucket : public RGWOp { -protected: + protected: + rgw::sal::Bucket::CreateParams createparams; RGWAccessControlPolicy policy; std::string location_constraint; - rgw_placement_rule placement_rule; - RGWBucketInfo info; - obj_version ep_objv; - bool has_cors; - bool relaxed_region_enforcement; - bool obj_lock_enabled; + bool has_cors = false; + bool relaxed_region_enforcement = false; RGWCORSConfiguration cors_config; - boost::optional swift_ver_location; - std::map attrs; std::set rmattr_names; - bufferlist in_data; - virtual bool need_metadata_upload() const { return false; } -public: - RGWCreateBucket() : has_cors(false), relaxed_region_enforcement(false), obj_lock_enabled(false) {} - + public: void emplace_attr(std::string&& key, buffer::list&& bl) { - attrs.emplace(std::move(key), std::move(bl)); /* key and bl are r-value refs */ + createparams.attrs.emplace(std::move(key), std::move(bl)); /* key and bl are r-value refs */ } - int verify_permission(optional_yield y) override; void pre_exec() override; void execute(optional_yield y) override; @@ -1403,7 +1393,7 @@ protected: RGWAccessControlPolicy policy; RGWCORSConfiguration cors_config; rgw_placement_rule placement_rule; - boost::optional swift_ver_location; + std::optional swift_ver_location; public: RGWPutMetadataBucket() diff --git a/src/rgw/rgw_quota_types.h b/src/rgw/rgw_quota_types.h index f7d06657ed6..48d46dc62b4 100644 --- a/src/rgw/rgw_quota_types.h +++ b/src/rgw/rgw_quota_types.h @@ -28,8 +28,6 @@ static inline int64_t rgw_rounded_kb(int64_t bytes) class JSONObj; struct RGWQuotaInfo { - template friend class RGWQuotaCache; -public: int64_t max_size; int64_t max_objects; bool enabled; diff --git a/src/rgw/rgw_rest_s3.cc b/src/rgw/rgw_rest_s3.cc index 6c3a8c8adc1..971b63e85d7 100644 --- a/src/rgw/rgw_rest_s3.cc +++ b/src/rgw/rgw_rest_s3.cc @@ -2456,8 +2456,6 @@ int RGWCreateBucket_ObjStore_S3::get_params(optional_yield y) if ((op_ret < 0) && (op_ret != -ERR_LENGTH_REQUIRED)) return op_ret; - in_data.append(data); - if (data.length()) { RGWCreateBucketParser parser; @@ -2486,17 +2484,18 @@ int RGWCreateBucket_ObjStore_S3::get_params(optional_yield y) size_t pos = location_constraint.find(':'); if (pos != string::npos) { - placement_rule.init(location_constraint.substr(pos + 1), s->info.storage_class); + createparams.placement_rule.init(location_constraint.substr(pos + 1), + s->info.storage_class); location_constraint = location_constraint.substr(0, pos); } else { - placement_rule.storage_class = s->info.storage_class; + createparams.placement_rule.storage_class = s->info.storage_class; } auto iter = s->info.x_meta_map.find("x-amz-bucket-object-lock-enabled"); if (iter != s->info.x_meta_map.end()) { if (!boost::algorithm::iequals(iter->second, "true") && !boost::algorithm::iequals(iter->second, "false")) { return -EINVAL; } - obj_lock_enabled = boost::algorithm::iequals(iter->second, "true"); + createparams.obj_lock_enabled = boost::algorithm::iequals(iter->second, "true"); } return 0; } @@ -2516,6 +2515,8 @@ void RGWCreateBucket_ObjStore_S3::send_response() if (s->system_request) { JSONFormatter f; /* use json formatter for system requests output */ + const RGWBucketInfo& info = s->bucket->get_info(); + const obj_version& ep_objv = s->bucket->get_version(); f.open_object_section("info"); encode_json("entry_point_object_ver", ep_objv, &f); encode_json("object_ver", info.objv_tracker.read_version, &f); diff --git a/src/rgw/rgw_rest_swift.cc b/src/rgw/rgw_rest_swift.cc index 7ef73285583..b941d4bb099 100644 --- a/src/rgw/rgw_rest_swift.cc +++ b/src/rgw/rgw_rest_swift.cc @@ -682,14 +682,14 @@ static void get_rmattrs_from_headers(const req_state * const s, static int get_swift_versioning_settings( req_state * const s, - boost::optional& swift_ver_location) + std::optional& swift_ver_location) { /* Removing the Swift's versions location has lower priority than setting * a new one. That's the reason why we're handling it first. */ const std::string vlocdel = s->info.env->get("HTTP_X_REMOVE_VERSIONS_LOCATION", ""); if (vlocdel.size()) { - swift_ver_location = boost::in_place(std::string()); + swift_ver_location.emplace(); } if (s->info.env->exists("HTTP_X_VERSIONS_LOCATION")) { @@ -724,9 +724,10 @@ int RGWCreateBucket_ObjStore_SWIFT::get_params(optional_yield y) location_constraint = driver->get_zone()->get_zonegroup().get_api_name(); get_rmattrs_from_headers(s, CONT_PUT_ATTR_PREFIX, CONT_REMOVE_ATTR_PREFIX, rmattr_names); - placement_rule.init(s->info.env->get("HTTP_X_STORAGE_POLICY", ""), s->info.storage_class); + createparams.placement_rule.init(s->info.env->get("HTTP_X_STORAGE_POLICY", ""), + s->info.storage_class); - return get_swift_versioning_settings(s, swift_ver_location); + return get_swift_versioning_settings(s, createparams.swift_ver_location); } static inline int handle_metadata_errors(req_state* const s, const int op_ret) diff --git a/src/rgw/rgw_sal.h b/src/rgw/rgw_sal.h index d6994253288..d449535c398 100644 --- a/src/rgw/rgw_sal.h +++ b/src/rgw/rgw_sal.h @@ -39,6 +39,7 @@ typedef std::shared_ptr RGWSyncModuleInstanceRef; class RGWCompressionInfo; struct rgw_pubsub_topics; struct rgw_pubsub_bucket_topics; +class RGWZonePlacementInfo; using RGWBucketListNameFilter = std::function; @@ -487,23 +488,6 @@ class User { const std::string& marker, const std::string& end_marker, uint64_t max, bool need_stats, BucketList& buckets, optional_yield y) = 0; - /** Create a new bucket owned by this user. Creates in the backing store, not just the instantiation. */ - virtual int create_bucket(const DoutPrefixProvider* dpp, - const rgw_bucket& b, - const std::string& zonegroup_id, - const rgw_placement_rule& placement_rule, - const std::string& swift_ver_location, - const RGWQuotaInfo* pquota_info, - const RGWAccessControlPolicy& policy, - Attrs& attrs, - RGWBucketInfo& info, - obj_version& ep_objv, - bool exclusive, - bool obj_lock_enabled, - bool* existed, - req_info& req_info, - std::unique_ptr* bucket, - optional_yield y) = 0; /** Get the display name for this User */ virtual std::string& get_display_name() = 0; @@ -674,6 +658,27 @@ class Bucket { // XXXX hack virtual void set_owner(rgw::sal::User* _owner) = 0; + /// Input parameters for create(). + struct CreateParams { + std::string zonegroup_id; + rgw_placement_rule placement_rule; + // zone placement is optional on buckets created for another zonegroup + const RGWZonePlacementInfo* zone_placement; + RGWAccessControlPolicy policy; + Attrs attrs; + bool obj_lock_enabled = false; + std::string marker; + std::string bucket_id; + std::optional swift_ver_location; + std::optional quota; + std::optional creation_time; + }; + + /// Create this bucket in the backing store. + virtual int create(const DoutPrefixProvider* dpp, + const CreateParams& params, + optional_yield y) = 0; + /** Load this bucket from the backing store. Requires the key to be set, fills other fields. */ virtual int load_bucket(const DoutPrefixProvider* dpp, optional_yield y) = 0; /** Read the bucket stats from the backing Store, synchronous */ diff --git a/src/rgw/rgw_sal_dbstore.cc b/src/rgw/rgw_sal_dbstore.cc index 792fa457f89..c8046a65a00 100644 --- a/src/rgw/rgw_sal_dbstore.cc +++ b/src/rgw/rgw_sal_dbstore.cc @@ -58,90 +58,22 @@ namespace rgw::sal { return 0; } - int DBUser::create_bucket(const DoutPrefixProvider *dpp, - const rgw_bucket& b, - const string& zonegroup_id, - const rgw_placement_rule& placement_rule, - const string& swift_ver_location, - const RGWQuotaInfo * pquota_info, - const RGWAccessControlPolicy& policy, - Attrs& attrs, - RGWBucketInfo& info, - obj_version& ep_objv, - bool exclusive, - bool obj_lock_enabled, - bool *existed, - req_info& req_info, - std::unique_ptr* bucket_out, - optional_yield y) - { - int ret; - bufferlist in_data; - RGWBucketInfo master_info; - rgw_bucket *pmaster_bucket = nullptr; - real_time creation_time; - std::unique_ptr bucket; - obj_version objv, *pobjv = NULL; - - /* If it exists, look it up; otherwise create it */ - ret = store->load_bucket(dpp, this, b, &bucket, y); - if (ret < 0 && ret != -ENOENT) - return ret; - - if (ret != -ENOENT) { - *existed = true; - } else { - bucket = std::make_unique(store, b, this); - *existed = false; - bucket->set_attrs(attrs); - } - - /* - * XXX: If not master zone, fwd the request to master zone. - * For now DBStore has single zone. - */ - std::string zid = zonegroup_id; - /* if (zid.empty()) { - zid = svc()->zone->get_zonegroup().get_id(); - } */ - - // XXX: For now single default zone and STANDARD storage class - // supported. - rgw_placement_rule selected_placement_rule; - selected_placement_rule.name = "default"; - selected_placement_rule.storage_class = "STANDARD"; - - if (*existed) { - /* XXX: Handle this when zone is implemented - ret = svc()->zone->select_bucket_placement(this.get_info(), - zid, placement_rule, - &selected_placement_rule, nullptr, y); - if (selected_placement_rule != info.placement_rule) { - ret = -EEXIST; - bucket_out->swap(bucket); - return ret; - } */ - } else { - - /* XXX: We may not need to send all these params. Cleanup the unused ones */ - ret = store->getDB()->create_bucket(dpp, this->get_info(), bucket->get_key(), - zid, selected_placement_rule, swift_ver_location, pquota_info, - attrs, info, pobjv, &ep_objv, creation_time, - pmaster_bucket, nullptr, y, exclusive); - if (ret == -EEXIST) { - *existed = true; - ret = 0; - } else if (ret != 0) { - return ret; - } - } - - bucket->set_version(ep_objv); - bucket->get_info() = info; - - bucket_out->swap(bucket); - - return ret; + int DBBucket::create(const DoutPrefixProvider *dpp, + const CreateParams& params, + optional_yield y) + { + ceph_assert(owner); + const rgw_user& owner_id = owner->get_id(); + + rgw_bucket key = get_key(); + key.marker = params.marker; + key.bucket_id = params.bucket_id; + + /* XXX: We may not need to send all these params. Cleanup the unused ones */ + return store->getDB()->create_bucket(dpp, owner_id, key, + params.zonegroup_id, params.placement_rule, params.attrs, + params.swift_ver_location, params.quota, params.creation_time, + &bucket_version, info, y); } int DBUser::read_attrs(const DoutPrefixProvider* dpp, optional_yield y) diff --git a/src/rgw/rgw_sal_dbstore.h b/src/rgw/rgw_sal_dbstore.h index 41a0b89ea50..83f3ff96578 100644 --- a/src/rgw/rgw_sal_dbstore.h +++ b/src/rgw/rgw_sal_dbstore.h @@ -88,22 +88,6 @@ protected: } int list_buckets(const DoutPrefixProvider *dpp, const std::string& marker, const std::string& end_marker, uint64_t max, bool need_stats, BucketList& buckets, optional_yield y) override; - virtual int create_bucket(const DoutPrefixProvider* dpp, - const rgw_bucket& b, - const std::string& zonegroup_id, - const rgw_placement_rule& placement_rule, - const std::string& swift_ver_location, - const RGWQuotaInfo* pquota_info, - const RGWAccessControlPolicy& policy, - Attrs& attrs, - RGWBucketInfo& info, - obj_version& ep_objv, - bool exclusive, - bool obj_lock_enabled, - bool* existed, - req_info& req_info, - std::unique_ptr* bucket, - optional_yield y) override; virtual int read_attrs(const DoutPrefixProvider* dpp, optional_yield y) override; virtual int read_stats(const DoutPrefixProvider *dpp, optional_yield y, RGWStorageStats* stats, @@ -178,6 +162,9 @@ protected: DoutPrefixProvider *dpp) override; virtual RGWAccessControlPolicy& get_acl(void) override { return acls; } virtual int set_acl(const DoutPrefixProvider *dpp, RGWAccessControlPolicy& acl, optional_yield y) override; + int create(const DoutPrefixProvider* dpp, + const CreateParams& params, + optional_yield y) override; virtual int load_bucket(const DoutPrefixProvider *dpp, optional_yield y) override; virtual int read_stats(const DoutPrefixProvider *dpp, const bucket_index_layout_generation& idx_layout, diff --git a/src/rgw/rgw_sal_filter.cc b/src/rgw/rgw_sal_filter.cc index c70d9e372dc..01a11351367 100644 --- a/src/rgw/rgw_sal_filter.cc +++ b/src/rgw/rgw_sal_filter.cc @@ -508,35 +508,6 @@ int FilterUser::list_buckets(const DoutPrefixProvider* dpp, const std::string& m need_stats, buckets, y); } -int FilterUser::create_bucket(const DoutPrefixProvider* dpp, - const rgw_bucket& b, - const std::string& zonegroup_id, - const rgw_placement_rule& placement_rule, - const std::string& swift_ver_location, - const RGWQuotaInfo * pquota_info, - const RGWAccessControlPolicy& policy, - Attrs& attrs, - RGWBucketInfo& info, - obj_version& ep_objv, - bool exclusive, - bool obj_lock_enabled, - bool* existed, - req_info& req_info, - std::unique_ptr* bucket_out, - optional_yield y) -{ - std::unique_ptr nb; - int ret; - - ret = next->create_bucket(dpp, b, zonegroup_id, placement_rule, swift_ver_location, pquota_info, policy, attrs, info, ep_objv, exclusive, obj_lock_enabled, existed, req_info, &nb, y); - if (ret < 0) - return ret; - - Bucket* fb = new FilterBucket(std::move(nb), this); - bucket_out->reset(fb); - return 0; -} - int FilterUser::read_attrs(const DoutPrefixProvider* dpp, optional_yield y) { return next->read_attrs(dpp, y); @@ -636,6 +607,13 @@ int FilterBucket::set_acl(const DoutPrefixProvider* dpp, return next->set_acl(dpp, acl, y); } +int FilterBucket::create(const DoutPrefixProvider* dpp, + const CreateParams& params, + optional_yield y) +{ + return next->create(dpp, params, y); +} + int FilterBucket::load_bucket(const DoutPrefixProvider* dpp, optional_yield y) { return next->load_bucket(dpp, y); diff --git a/src/rgw/rgw_sal_filter.h b/src/rgw/rgw_sal_filter.h index b2aa1be399f..1711723bdd2 100644 --- a/src/rgw/rgw_sal_filter.h +++ b/src/rgw/rgw_sal_filter.h @@ -325,22 +325,6 @@ public: const std::string& marker, const std::string& end_marker, uint64_t max, bool need_stats, BucketList& buckets, optional_yield y) override; - virtual int create_bucket(const DoutPrefixProvider* dpp, - const rgw_bucket& b, - const std::string& zonegroup_id, - const rgw_placement_rule& placement_rule, - const std::string& swift_ver_location, - const RGWQuotaInfo* pquota_info, - const RGWAccessControlPolicy& policy, - Attrs& attrs, - RGWBucketInfo& info, - obj_version& ep_objv, - bool exclusive, - bool obj_lock_enabled, - bool* existed, - req_info& req_info, - std::unique_ptr* bucket, - optional_yield y) override; virtual std::string& get_display_name() override { return next->get_display_name(); } virtual const std::string& get_tenant() override { return next->get_tenant(); } @@ -419,6 +403,9 @@ public: optional_yield y) override; virtual void set_owner(rgw::sal::User* _owner) override { next->set_owner(_owner); } + virtual int create(const DoutPrefixProvider* dpp, + const CreateParams& params, + optional_yield y) override; virtual int load_bucket(const DoutPrefixProvider* dpp, optional_yield y) override; virtual int read_stats(const DoutPrefixProvider *dpp, const bucket_index_layout_generation& idx_layout, diff --git a/src/test/rgw/test_d4n_filter.cc b/src/test/rgw/test_d4n_filter.cc index 7ceb7092c64..2d39981806c 100644 --- a/src/test/rgw/test_d4n_filter.cc +++ b/src/test/rgw/test_d4n_filter.cc @@ -114,43 +114,17 @@ class D4NFilterFixture : public ::testing::Test { } int createBucket() { - rgw_bucket b; - string zonegroup_id = "test_id"; - rgw_placement_rule placement_rule; - string swift_ver_location = "test_location"; - const RGWAccessControlPolicy policy; - rgw::sal::Attrs attrs; RGWBucketInfo info; - obj_version ep_objv; - bool bucket_exists; - int ret; - - CephContext* cct = get_pointer(env->cct); - RGWProcessEnv penv; - RGWEnv rgw_env; - req_state s(cct->get(), penv, &rgw_env, 0); - req_info _req_info = s.info; - - b.name = "test_bucket"; - placement_rule.storage_class = "test_sc"; - - ret = testUser->create_bucket(dpp, b, - zonegroup_id, - placement_rule, - swift_ver_location, - nullptr, - policy, - attrs, - info, - ep_objv, - false, - false, - &bucket_exists, - _req_info, - &testBucket, - null_yield); - - return ret; + info.bucket.name = "test_bucket"; + + testBucket = driver->get_bucket(testUser.get(), info); + + rgw::sal::Bucket::CreateParams params; + params.zonegroup_id = "test_id"; + params.placement_rule.storage_class = "test_sc"; + params.swift_ver_location = "test_location"; + + return testBucket->create(dpp, params, null_yield); } int putObject(string name) { diff --git a/src/test/rgw/test_rgw_lua.cc b/src/test/rgw/test_rgw_lua.cc index 05f0d291961..8502ce81ef5 100644 --- a/src/test/rgw/test_rgw_lua.cc +++ b/src/test/rgw/test_rgw_lua.cc @@ -78,10 +78,6 @@ public: return 0; } - virtual int create_bucket(const DoutPrefixProvider* dpp, const rgw_bucket& b, const std::string& zonegroup_id, const rgw_placement_rule& placement_rule, const std::string& swift_ver_location, const RGWQuotaInfo* pquota_info, const RGWAccessControlPolicy& policy, sal::Attrs& attrs, RGWBucketInfo& info, obj_version& ep_objv, bool exclusive, bool obj_lock_enabled, bool* existed, req_info& req_info, std::unique_ptr* bucket, optional_yield y) override { - return 0; - } - virtual int read_attrs(const DoutPrefixProvider *dpp, optional_yield y) override { return 0; }