From: Daniel Gryniewicz Date: Thu, 19 Dec 2019 17:23:57 +0000 (-0500) Subject: Zipper Object X-Git-Tag: v16.1.0~1694^2~2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=99f7c4aa1286edfea6961b92bb44bb8fe22bd599;p=ceph.git Zipper Object This pass modifies RGW to use RGWObject and RGWRadosObject. Also improves RGWBucket usage. This converts many of the APIs to unique_ptr. Signed-off-by: Daniel Gryniewicz --- diff --git a/src/rgw/rgw_admin.cc b/src/rgw/rgw_admin.cc index 2bdc9726c871..c2ffe613a347 100644 --- a/src/rgw/rgw_admin.cc +++ b/src/rgw/rgw_admin.cc @@ -1342,28 +1342,19 @@ int set_user_quota(OPT opt_cmd, RGWUser& user, RGWUserAdminOpState& op_state, in return 0; } -int check_min_obj_stripe_size(rgw::sal::RGWRadosStore *store, RGWBucketInfo& bucket_info, rgw_obj& obj, uint64_t min_stripe_size, bool *need_rewrite) +int check_min_obj_stripe_size(rgw::sal::RGWRadosStore *store, RGWBucketInfo& bucket_info, rgw::sal::RGWObject* obj, uint64_t min_stripe_size, bool *need_rewrite) { - map attrs; - uint64_t obj_size; - RGWObjectCtx obj_ctx(store); - RGWRados::Object op_target(store->getRados(), bucket_info, obj_ctx, obj); - RGWRados::Object::Read read_op(&op_target); - - read_op.params.attrs = &attrs; - read_op.params.obj_size = &obj_size; - - int ret = read_op.prepare(null_yield); + int ret = obj->get_obj_attrs(&obj_ctx, null_yield); if (ret < 0) { lderr(store->ctx()) << "ERROR: failed to stat object, returned error: " << cpp_strerror(-ret) << dendl; return ret; } map::iterator iter; - iter = attrs.find(RGW_ATTR_MANIFEST); - if (iter == attrs.end()) { - *need_rewrite = (obj_size >= min_stripe_size); + iter = obj->get_attrs().find(RGW_ATTR_MANIFEST); + if (iter == obj->get_attrs().attrs.end()) { + *need_rewrite = (obj->get_obj_size() >= min_stripe_size); return 0; } @@ -6710,17 +6701,18 @@ next: return -ret; } - rgw_obj obj(bucket, object); - obj.key.set_instance(object_version); + rgw::sal::RGWRadosBucket rbucket(store, bucket); + rgw::sal::RGWRadosObject obj(store, object, &rbucket); + obj.set_instance(object_version); bool need_rewrite = true; if (min_rewrite_stripe_size > 0) { - ret = check_min_obj_stripe_size(store, bucket_info, obj, min_rewrite_stripe_size, &need_rewrite); + ret = check_min_obj_stripe_size(store, bucket_info, &obj, min_rewrite_stripe_size, &need_rewrite); if (ret < 0) { ldout(store->ctx(), 0) << "WARNING: check_min_obj_stripe_size failed, r=" << ret << dendl; } } if (need_rewrite) { - ret = store->getRados()->rewrite_obj(bucket_info, obj, dpp(), null_yield); + ret = store->getRados()->rewrite_obj(bucket_info, &obj, dpp(), null_yield); if (ret < 0) { cerr << "ERROR: object rewrite returned: " << cpp_strerror(-ret) << std::endl; return -ret; @@ -6838,11 +6830,12 @@ next: (end_epoch > 0 && end_epoch < (uint64_t)ut.sec())) { formatter->dump_string("status", "Skipped"); } else { - rgw_obj obj(bucket, key); + rgw::sal::RGWRadosBucket rbucket(store, bucket); + rgw::sal::RGWRadosObject obj(store, key, &rbucket); bool need_rewrite = true; if (min_rewrite_stripe_size > 0) { - r = check_min_obj_stripe_size(store, bucket_info, obj, min_rewrite_stripe_size, &need_rewrite); + r = check_min_obj_stripe_size(store, bucket_info, &obj, min_rewrite_stripe_size, &need_rewrite); if (r < 0) { ldout(store->ctx(), 0) << "WARNING: check_min_obj_stripe_size failed, r=" << r << dendl; } @@ -6850,7 +6843,7 @@ next: if (!need_rewrite) { formatter->dump_string("status", "Skipped"); } else { - r = store->getRados()->rewrite_obj(bucket_info, obj, dpp(), null_yield); + r = store->getRados()->rewrite_obj(bucket_info, &obj, dpp(), null_yield); if (r == 0) { formatter->dump_string("status", "Success"); } else { diff --git a/src/rgw/rgw_bucket.cc b/src/rgw/rgw_bucket.cc index 8b197b2db97a..1d59d1e3f4fe 100644 --- a/src/rgw/rgw_bucket.cc +++ b/src/rgw/rgw_bucket.cc @@ -276,13 +276,13 @@ void check_bad_user_bucket_mapping(rgw::sal::RGWRadosStore *store, const rgw_use return; } - map& buckets = user_buckets.get_buckets(); - for (map::iterator i = buckets.begin(); + map>& buckets = user_buckets.get_buckets(); + for (auto i = buckets.begin(); i != buckets.end(); ++i) { marker = i->first; - rgw::sal::RGWBucket* bucket = i->second; + auto& bucket = i->second; RGWBucketInfo bucket_info; real_time mtime; @@ -1511,10 +1511,10 @@ int RGWBucketAdminOp::limit_check(rgw::sal::RGWRadosStore *store, if (ret < 0) return ret; - map& m_buckets = buckets.get_buckets(); + map>& m_buckets = buckets.get_buckets(); for (const auto& iter : m_buckets) { - auto bucket = iter.second; + auto& bucket = iter.second; uint32_t num_shards = 1; uint64_t num_objects = 0; @@ -1618,7 +1618,6 @@ int RGWBucketAdminOp::info(rgw::sal::RGWRadosStore *store, constexpr bool no_need_stats = false; // set need_stats to false do { - buckets.clear(); ret = user.list_buckets(marker, empty_end_marker, max_entries, no_need_stats, buckets); if (ret < 0) { @@ -1626,7 +1625,7 @@ int RGWBucketAdminOp::info(rgw::sal::RGWRadosStore *store, } const std::string* marker_cursor = nullptr; - map& m = buckets.get_buckets(); + map>& m = buckets.get_buckets(); for (const auto& i : m) { const std::string& obj_name = i.first; diff --git a/src/rgw/rgw_common.cc b/src/rgw/rgw_common.cc index 9f62edb2bb4f..003f82c72845 100644 --- a/src/rgw/rgw_common.cc +++ b/src/rgw/rgw_common.cc @@ -1017,7 +1017,7 @@ struct perm_state_from_req_state : public perm_state_base { perm_state_from_req_state(req_state * const _s) : perm_state_base(_s->cct, _s->env, _s->auth.identity.get(), - _s->bucket_info, + _s->bucket->get_info(), _s->perm_mask, _s->defer_to_bucket_acls, _s->bucket_access_conf), @@ -1258,7 +1258,7 @@ bool verify_bucket_permission(const DoutPrefixProvider* dpp, struct req_state * return verify_bucket_permission(dpp, &ps, - s->bucket, + s->bucket->get_bi(), s->user_acl.get(), s->bucket_acl.get(), s->iam_policy, @@ -1272,14 +1272,14 @@ bool verify_bucket_permission(const DoutPrefixProvider* dpp, struct req_state * int verify_bucket_owner_or_policy(struct req_state* const s, const uint64_t op) { - auto usr_policy_res = eval_user_policies(s->iam_user_policies, s->env, boost::none, op, ARN(s->bucket)); + auto usr_policy_res = eval_user_policies(s->iam_user_policies, s->env, boost::none, op, ARN(s->bucket->get_bi())); if (usr_policy_res == Effect::Deny) { return -EACCES; } auto e = eval_or_pass(s->iam_policy, s->env, *s->auth.identity, - op, ARN(s->bucket)); + op, ARN(s->bucket->get_bi())); if (e == Effect::Deny) { return -EACCES; } @@ -1483,7 +1483,7 @@ bool verify_object_permission(const DoutPrefixProvider* dpp, struct req_state *s return verify_object_permission(dpp, &ps, - rgw_obj(s->bucket, s->object), + rgw_obj(s->bucket->get_bi(), s->object->get_key()), s->user_acl.get(), s->bucket_acl.get(), s->object_acl.get(), diff --git a/src/rgw/rgw_common.h b/src/rgw/rgw_common.h index d41aa6161361..ca2334d62ed0 100644 --- a/src/rgw/rgw_common.h +++ b/src/rgw/rgw_common.h @@ -45,6 +45,8 @@ namespace ceph { namespace rgw::sal { class RGWUser; + class RGWBucket; + class RGWObject; } using ceph::crypto::MD5; @@ -1618,11 +1620,11 @@ struct req_state : DoutPrefixProvider { string bucket_tenant; string bucket_name; - rgw_bucket bucket; - rgw_obj_key object; + std::unique_ptr bucket; + std::unique_ptr object; string src_tenant_name; string src_bucket_name; - rgw_obj_key src_object; + std::unique_ptr src_object; ACLOwner bucket_owner; ACLOwner owner; @@ -1634,8 +1636,6 @@ struct req_state : DoutPrefixProvider { string redirect; - RGWBucketInfo bucket_info; - obj_version bucket_ep_objv; real_time bucket_mtime; std::map bucket_attrs; bool bucket_exists{false}; @@ -1643,7 +1643,7 @@ struct req_state : DoutPrefixProvider { bool has_bad_meta{false}; - rgw::sal::RGWUser *user; + rgw::sal::RGWUser* user{nullptr}; struct { /* TODO(rzarzynski): switch out to the static_ptr for both members. */ diff --git a/src/rgw/rgw_cr_rados.cc b/src/rgw/rgw_cr_rados.cc index 390e5bd9ed74..faf0ee6a4dba 100644 --- a/src/rgw/rgw_cr_rados.cc +++ b/src/rgw/rgw_cr_rados.cc @@ -635,18 +635,19 @@ int RGWAsyncFetchRemoteObj::_send_request() snprintf(buf, sizeof(buf), ".%lld", (long long)store->getRados()->instance_id()); map attrs; - rgw_obj src_obj(src_bucket, key); - - rgw_obj dest_obj(dest_bucket_info.bucket, dest_key.value_or(key)); + rgw::sal::RGWRadosBucket bucket(store, src_bucket); + rgw::sal::RGWRadosObject src_obj(store, key, &bucket); + rgw::sal::RGWRadosBucket dest_bucket(store, dest_bucket_info); + rgw::sal::RGWRadosObject dest_obj(store, dest_key.value_or(key), &dest_bucket); std::optional bytes_transferred; int r = store->getRados()->fetch_remote_obj(obj_ctx, user_id.value_or(rgw_user()), NULL, /* req_info */ source_zone, - dest_obj, - src_obj, - dest_bucket_info, /* dest */ + &dest_obj, + &src_obj, + &dest_bucket, /* dest */ nullptr, /* source */ dest_placement_rule, NULL, /* real_time* src_mtime, */ @@ -694,13 +695,14 @@ int RGWAsyncStatRemoteObj::_send_request() char buf[16]; snprintf(buf, sizeof(buf), ".%lld", (long long)store->getRados()->instance_id()); - rgw_obj src_obj(src_bucket, key); + rgw::sal::RGWRadosBucket bucket(store, src_bucket); + rgw::sal::RGWRadosObject src_obj(store, key, &bucket); int r = store->getRados()->stat_remote_obj(obj_ctx, rgw_user(user_id), nullptr, /* req_info */ source_zone, - src_obj, + &src_obj, nullptr, /* source */ pmtime, /* real_time* src_mtime, */ psize, /* uint64_t * */ diff --git a/src/rgw/rgw_data_sync.cc b/src/rgw/rgw_data_sync.cc index deaf913559e5..5e5346b864cf 100644 --- a/src/rgw/rgw_data_sync.cc +++ b/src/rgw/rgw_data_sync.cc @@ -4935,14 +4935,14 @@ string RGWBucketPipeSyncStatusManager::status_oid(const rgw_zone_id& source_zone string RGWBucketPipeSyncStatusManager::obj_status_oid(const rgw_bucket_sync_pipe& sync_pipe, const rgw_zone_id& source_zone, - const rgw_obj& obj) + const rgw::sal::RGWObject* obj) { - string prefix = object_status_oid_prefix + "." + source_zone.id + ":" + obj.bucket.get_key(); + string prefix = object_status_oid_prefix + "." + source_zone.id + ":" + obj->get_bucket()->get_key(); if (sync_pipe.source_bucket_info.bucket != sync_pipe.dest_bucket_info.bucket) { prefix += string("/") + sync_pipe.dest_bucket_info.bucket.get_key(); } - return prefix + ":" + obj.key.name + ":" + obj.key.instance; + return prefix + ":" + obj->get_name() + ":" + obj->get_instance(); } class RGWCollectBucketSyncStatusCR : public RGWShardCollectCR { diff --git a/src/rgw/rgw_data_sync.h b/src/rgw/rgw_data_sync.h index 18d52b03197f..ec8e648cd51f 100644 --- a/src/rgw/rgw_data_sync.h +++ b/src/rgw/rgw_data_sync.h @@ -655,7 +655,7 @@ public: static string status_oid(const rgw_zone_id& source_zone, const rgw_bucket_sync_pair_info& bs); static string obj_status_oid(const rgw_bucket_sync_pipe& sync_pipe, - const rgw_zone_id& source_zone, const rgw_obj& obj); /* specific source obj sync status, + const rgw_zone_id& source_zone, const rgw::sal::RGWObject* obj); /* specific source obj sync status, can be used by sync modules */ // implements DoutPrefixProvider diff --git a/src/rgw/rgw_file.cc b/src/rgw/rgw_file.cc index 68fd775640c5..a7d8f8b91225 100644 --- a/src/rgw/rgw_file.cc +++ b/src/rgw/rgw_file.cc @@ -1371,7 +1371,7 @@ namespace rgw { /* start */ std::string object_name = relative_object_name(); f->write_req = - new RGWWriteRequest(fs->get_context(), &ruser, this, + new RGWWriteRequest(rgwlib.get_store(), &ruser, this, bucket_name(), object_name); rc = rgwlib.get_fe()->start_req(f->write_req); if (rc < 0) { @@ -1530,7 +1530,7 @@ namespace rgw { auto compression_type = get_store()->svc()->zone->get_zone_params().get_compression_type( - s->bucket_info.placement_rule); + s->bucket->get_placement_rule()); /* not obviously supportable */ ceph_assert(! dlo_manifest); @@ -1538,9 +1538,8 @@ namespace rgw { perfcounter->inc(l_rgw_put); op_ret = -EINVAL; - rgw_obj obj{s->bucket, s->object}; - if (s->object.empty()) { + if (s->object->empty()) { ldout(s->cct, 0) << __func__ << " called on empty object" << dendl; goto done; } @@ -1561,19 +1560,19 @@ namespace rgw { aio.emplace(s->cct->_conf->rgw_put_obj_min_window_size); - if (s->bucket_info.versioning_enabled()) { + if (s->bucket->versioning_enabled()) { if (!version_id.empty()) { - obj.key.set_instance(version_id); + s->object->set_instance(version_id); } else { - get_store()->getRados()->gen_rand_obj_instance_name(&obj); - version_id = obj.key.instance; + s->object->gen_rand_obj_instance_name(); + version_id = s->object->get_instance(); } } - processor.emplace(&*aio, get_store(), s->bucket_info, + processor.emplace(&*aio, get_store(), s->bucket.get(), &s->dest_placement, s->bucket_owner.get_id(), *static_cast(s->obj_ctx), - obj, olh_epoch, s->req_id, this, s->yield); + s->object->get_obj(), olh_epoch, s->req_id, this, s->yield); op_ret = processor->prepare(s->yield); if (op_ret < 0) { @@ -1611,8 +1610,9 @@ namespace rgw { return -EIO; } - op_ret = get_store()->getRados()->check_quota(s->bucket_owner.get_id(), s->bucket, - user_quota, bucket_quota, real_ofs, true); + op_ret = get_store()->getRados()->check_quota(s->bucket_owner.get_id(), + s->bucket->get_bi(), user_quota, bucket_quota, + real_ofs, true); /* max_size exceed */ if (op_ret < 0) return -EIO; @@ -1654,8 +1654,9 @@ namespace rgw { goto done; } - op_ret = get_store()->getRados()->check_quota(s->bucket_owner.get_id(), s->bucket, - user_quota, bucket_quota, s->obj_size, true); + op_ret = get_store()->getRados()->check_quota(s->bucket_owner.get_id(), + s->bucket->get_bi(), user_quota, bucket_quota, + s->obj_size, true); /* max_size exceed */ if (op_ret < 0) { goto done; diff --git a/src/rgw/rgw_file.h b/src/rgw/rgw_file.h index b8d44ec6424d..89d1ed25eef8 100644 --- a/src/rgw/rgw_file.h +++ b/src/rgw/rgw_file.h @@ -1317,7 +1317,7 @@ public: uint32_t d_count; bool rcb_eof; // caller forced early stop in readdir cycle - RGWListBucketsRequest(CephContext* _cct, rgw::sal::RGWUser *_user, + RGWListBucketsRequest(CephContext* _cct, rgw::sal::RGWUser* _user, RGWFileHandle* _rgw_fh, rgw_readdir_cb _rcb, void* _cb_arg, RGWFileHandle::readdir_offset& _offset) : RGWLibRequest(_cct, _user), rgw_fh(_rgw_fh), offset(_offset), @@ -1385,10 +1385,10 @@ public: void send_response_data(rgw::sal::RGWBucketList& buckets) override { if (!sent_data) return; - map& m = buckets.get_buckets(); + auto& m = buckets.get_buckets(); for (const auto& iter : m) { std::string_view marker{iter.first}; - rgw::sal::RGWBucket* ent = iter.second; + auto& ent = iter.second; if (! this->operator()(ent->get_name(), marker)) { /* caller cannot accept more */ lsubdout(cct, rgw, 5) << "ListBuckets rcb failed" @@ -1451,7 +1451,7 @@ public: uint32_t d_count; bool rcb_eof; // caller forced early stop in readdir cycle - RGWReaddirRequest(CephContext* _cct, rgw::sal::RGWUser *_user, + RGWReaddirRequest(CephContext* _cct, rgw::sal::RGWUser* _user, RGWFileHandle* _rgw_fh, rgw_readdir_cb _rcb, void* _cb_arg, RGWFileHandle::readdir_offset& _offset) : RGWLibRequest(_cct, _user), rgw_fh(_rgw_fh), offset(_offset), @@ -1682,7 +1682,7 @@ public: bool valid; bool has_children; - RGWRMdirCheck (CephContext* _cct, rgw::sal::RGWUser *_user, + RGWRMdirCheck (CephContext* _cct, rgw::sal::RGWUser* _user, const RGWFileHandle* _rgw_fh) : RGWLibRequest(_cct, _user), rgw_fh(_rgw_fh), valid(false), has_children(false) { @@ -1764,7 +1764,7 @@ class RGWCreateBucketRequest : public RGWLibRequest, public: const std::string& bucket_name; - RGWCreateBucketRequest(CephContext* _cct, rgw::sal::RGWUser *_user, + RGWCreateBucketRequest(CephContext* _cct, rgw::sal::RGWUser* _user, std::string& _bname) : RGWLibRequest(_cct, _user), bucket_name(_bname) { op = this; @@ -1833,7 +1833,7 @@ class RGWDeleteBucketRequest : public RGWLibRequest, public: const std::string& bucket_name; - RGWDeleteBucketRequest(CephContext* _cct, rgw::sal::RGWUser *_user, + RGWDeleteBucketRequest(CephContext* _cct, rgw::sal::RGWUser* _user, std::string& _bname) : RGWLibRequest(_cct, _user), bucket_name(_bname) { op = this; @@ -1889,7 +1889,7 @@ public: buffer::list& bl; /* XXX */ size_t bytes_written; - RGWPutObjRequest(CephContext* _cct, rgw::sal::RGWUser *_user, + RGWPutObjRequest(CephContext* _cct, rgw::sal::RGWUser* _user, const std::string& _bname, const std::string& _oname, buffer::list& _bl) : RGWLibRequest(_cct, _user), bucket_name(_bname), obj_name(_oname), @@ -1985,7 +1985,7 @@ public: size_t read_resid; /* initialize to len, <= sizeof(ulp_buffer) */ bool do_hexdump = false; - RGWReadRequest(CephContext* _cct, rgw::sal::RGWUser *_user, + RGWReadRequest(CephContext* _cct, rgw::sal::RGWUser* _user, RGWFileHandle* _rgw_fh, uint64_t off, uint64_t len, void *_ulp_buffer) : RGWLibRequest(_cct, _user), rgw_fh(_rgw_fh), ulp_buffer(_ulp_buffer), @@ -2080,7 +2080,7 @@ public: const std::string& bucket_name; const std::string& obj_name; - RGWDeleteObjRequest(CephContext* _cct, rgw::sal::RGWUser *_user, + RGWDeleteObjRequest(CephContext* _cct, rgw::sal::RGWUser* _user, const std::string& _bname, const std::string& _oname) : RGWLibRequest(_cct, _user), bucket_name(_bname), obj_name(_oname) { op = this; @@ -2135,7 +2135,7 @@ public: static constexpr uint32_t FLAG_NONE = 0x000; - RGWStatObjRequest(CephContext* _cct, rgw::sal::RGWUser *_user, + RGWStatObjRequest(CephContext* _cct, rgw::sal::RGWUser* _user, const std::string& _bname, const std::string& _oname, uint32_t _flags) : RGWLibRequest(_cct, _user), bucket_name(_bname), obj_name(_oname), @@ -2232,7 +2232,7 @@ public: std::map attrs; RGWLibFS::BucketStats& bs; - RGWStatBucketRequest(CephContext* _cct, rgw::sal::RGWUser *_user, + RGWStatBucketRequest(CephContext* _cct, rgw::sal::RGWUser* _user, const std::string& _path, RGWLibFS::BucketStats& _stats) : RGWLibRequest(_cct, _user), bs(_stats) { @@ -2287,7 +2287,7 @@ public: } void send_response() override { - bucket->get_creation_time() = get_state()->bucket_info.creation_time; + bucket->get_creation_time() = get_state()->bucket->get_info().creation_time; bs.size = bucket->get_size(); bs.size_rounded = bucket->get_size_rounded(); bs.creation_time = bucket->get_creation_time(); @@ -2311,7 +2311,7 @@ public: bool is_dir; bool exact_matched; - RGWStatLeafRequest(CephContext* _cct, rgw::sal::RGWUser *_user, + RGWStatLeafRequest(CephContext* _cct, rgw::sal::RGWUser* _user, RGWFileHandle* _rgw_fh, const std::string& _path) : RGWLibRequest(_cct, _user), rgw_fh(_rgw_fh), path(_path), matched(false), is_dir(false), exact_matched(false) { @@ -2429,16 +2429,16 @@ public: size_t bytes_written; bool eio; - RGWWriteRequest(CephContext* _cct, rgw::sal::RGWUser *_user, RGWFileHandle* _fh, + RGWWriteRequest(rgw::sal::RGWRadosStore* store, rgw::sal::RGWUser* _user, RGWFileHandle* _fh, const std::string& _bname, const std::string& _oname) - : RGWLibContinuedReq(_cct, _user), + : RGWLibContinuedReq(store->ctx(), _user), bucket_name(_bname), obj_name(_oname), rgw_fh(_fh), filter(nullptr), real_ofs(0), bytes_written(0), eio(false) { int ret = header_init(); if (ret == 0) { - ret = init_from_header(get_state()); + ret = init_from_header(store, get_state()); } op = this; } @@ -2526,7 +2526,7 @@ public: const std::string& src_name; const std::string& dst_name; - RGWCopyObjRequest(CephContext* _cct, rgw::sal::RGWUser *_user, + RGWCopyObjRequest(CephContext* _cct, rgw::sal::RGWUser* _user, RGWFileHandle* _src_parent, RGWFileHandle* _dst_parent, const std::string& _src_name, const std::string& _dst_name) : RGWLibRequest(_cct, _user), src_parent(_src_parent), @@ -2560,20 +2560,20 @@ public: src_bucket_name = src_parent->bucket_name(); // need s->src_bucket_name? - src_object.name = src_parent->format_child_name(src_name, false); + src_object->set_name(src_parent->format_child_name(src_name, false)); // need s->src_object? dest_bucket_name = dst_parent->bucket_name(); // need s->bucket.name? - dest_object = dst_parent->format_child_name(dst_name, false); + dest_obj_name = dst_parent->format_child_name(dst_name, false); // need s->object_name? - int rc = valid_s3_object_name(dest_object); + int rc = valid_s3_object_name(dest_obj_name); if (rc != 0) return rc; /* XXX and fixup key attr (could optimize w/string ref and - * dest_object) */ + * dest_obj_name) */ buffer::list ux_key; fh_key fhk = dst_parent->make_fhk(dst_name); rgw::encode(fhk, ux_key); @@ -2615,7 +2615,7 @@ public: const std::string& bucket_name; const std::string& obj_name; - RGWSetAttrsRequest(CephContext* _cct, rgw::sal::RGWUser *_user, + RGWSetAttrsRequest(CephContext* _cct, rgw::sal::RGWUser* _user, const std::string& _bname, const std::string& _oname) : RGWLibRequest(_cct, _user), bucket_name(_bname), obj_name(_oname) { op = this; @@ -2670,7 +2670,7 @@ class RGWGetClusterStatReq : public RGWLibRequest, public RGWGetClusterStat { public: struct rados_cluster_stat_t& stats_req; - RGWGetClusterStatReq(CephContext* _cct,rgw::sal::RGWUser *_user, + RGWGetClusterStatReq(CephContext* _cct,rgw::sal::RGWUser* _user, rados_cluster_stat_t& _stats): RGWLibRequest(_cct, _user), stats_req(_stats){ op = this; diff --git a/src/rgw/rgw_lc.cc b/src/rgw/rgw_lc.cc index b3ccc97a809d..5ef112daffd6 100644 --- a/src/rgw/rgw_lc.cc +++ b/src/rgw/rgw_lc.cc @@ -1262,8 +1262,10 @@ public: return -EINVAL; } + rgw::sal::RGWRadosBucket bucket(oc.store, oc.bucket_info); + rgw::sal::RGWRadosObject obj(oc.store, oc.obj.key, &bucket); int r = oc.store->getRados()->transition_obj( - oc.rctx, oc.bucket_info, oc.obj, target_placement, o.meta.mtime, + oc.rctx, &bucket, obj, target_placement, o.meta.mtime, o.versioned_epoch, oc.dpp, null_yield); if (r < 0) { ldpp_dout(oc.dpp, 0) << "ERROR: failed to transition obj " diff --git a/src/rgw/rgw_lib.h b/src/rgw/rgw_lib.h index 3117f3c34683..bf1af5875409 100644 --- a/src/rgw/rgw_lib.h +++ b/src/rgw/rgw_lib.h @@ -121,7 +121,8 @@ namespace rgw { RGWHandler_Lib() {} ~RGWHandler_Lib() override {} - static int init_from_header(struct req_state *s); + static int init_from_header(rgw::sal::RGWRadosStore *store, + struct req_state *s); }; /* RGWHandler_Lib */ class RGWLibRequest : public RGWRequest, @@ -173,7 +174,7 @@ namespace rgw { int ret = header_init(); if (ret == 0) { - ret = init_from_header(_s); + ret = init_from_header(rados_ctx->get_store(), _s); } return ret; } diff --git a/src/rgw/rgw_log.cc b/src/rgw/rgw_log.cc index 4955715c163c..976869a04d75 100644 --- a/src/rgw/rgw_log.cc +++ b/src/rgw/rgw_log.cc @@ -27,7 +27,7 @@ static void set_param_str(struct req_state *s, const char *name, string& str) } string render_log_object_name(const string& format, - struct tm *dt, string& bucket_id, + struct tm *dt, const string& bucket_id, const string& bucket_name) { string o; @@ -198,8 +198,10 @@ static void log_usage(struct req_state *s, const string& op_name) bucket_name = s->bucket_name; if (!bucket_name.empty()) { + bucket_name = s->bucket_name; user = s->bucket_owner.get_id(); - if (s->bucket_info.requester_pays) { + if (!rgw::sal::RGWBucket::empty(s->bucket.get()) && + s->bucket->get_info().requester_pays) { payer = s->user->get_id(); } } else { @@ -343,14 +345,14 @@ int rgw_log_op(RGWRados *store, RGWREST* const rest, struct req_state *s, ldout(s->cct, 5) << "nothing to log for operation" << dendl; return -EINVAL; } - if (s->err.ret == -ERR_NO_SUCH_BUCKET) { + if (s->err.ret == -ERR_NO_SUCH_BUCKET || rgw::sal::RGWBucket::empty(s->bucket.get())) { if (!s->cct->_conf->rgw_log_nonexistent_bucket) { - ldout(s->cct, 5) << "bucket " << s->bucket << " doesn't exist, not logging" << dendl; + ldout(s->cct, 5) << "bucket " << s->bucket_name << " doesn't exist, not logging" << dendl; return 0; } bucket_id = ""; } else { - bucket_id = s->bucket.bucket_id; + bucket_id = s->bucket->get_bucket_id(); } entry.bucket = rgw_make_bucket_entry_name(s->bucket_tenant, s->bucket_name); @@ -359,8 +361,8 @@ int rgw_log_op(RGWRados *store, RGWREST* const rest, struct req_state *s, return 0; } - if (!s->object.empty()) { - entry.obj = s->object; + if (!rgw::sal::RGWObject::empty(s->object.get())) { + entry.obj = s->object->get_key(); } else { entry.obj = rgw_obj_key("-"); } @@ -460,7 +462,7 @@ int rgw_log_op(RGWRados *store, RGWREST* const rest, struct req_state *s, if (s->cct->_conf->rgw_ops_log_rados) { string oid = render_log_object_name(s->cct->_conf->rgw_log_object_name, &bdt, - s->bucket.bucket_id, entry.bucket); + entry.bucket_id, entry.bucket); rgw_raw_obj obj(store->svc.zone->get_zone_params().log_pool, oid); diff --git a/src/rgw/rgw_multi.cc b/src/rgw/rgw_multi.cc index 2e4858c15006..3bb7b260b0c1 100644 --- a/src/rgw/rgw_multi.cc +++ b/src/rgw/rgw_multi.cc @@ -194,7 +194,7 @@ int list_multipart_parts(rgw::sal::RGWRadosStore *store, struct req_state *s, int *next_marker, bool *truncated, bool assume_unsorted) { - return list_multipart_parts(store, s->bucket_info, s->cct, upload_id, + return list_multipart_parts(store, s->bucket->get_info(), s->cct, upload_id, meta_oid, num_parts, marker, parts, next_marker, truncated, assume_unsorted); } diff --git a/src/rgw/rgw_notify.cc b/src/rgw/rgw_notify.cc index 25b5c533bfdf..05b576ad3cca 100644 --- a/src/rgw/rgw_notify.cc +++ b/src/rgw/rgw_notify.cc @@ -15,8 +15,7 @@ namespace rgw::notify { // populate record from request void populate_record_from_request(const req_state *s, - const rgw_obj_key& key, - uint64_t size, + const rgw::sal::RGWObject* obj, const ceph::real_time& mtime, const std::string& etag, EventType event_type, @@ -29,17 +28,17 @@ void populate_record_from_request(const req_state *s, // configurationId is filled from notification configuration record.bucket_name = s->bucket_name; record.bucket_ownerIdentity = s->bucket_owner.get_id().id; - record.bucket_arn = to_string(rgw::ARN(s->bucket)); - record.object_key = key.name; - record.object_size = size; + record.bucket_arn = to_string(rgw::ARN(s->bucket->get_bi())); + record.object_key = obj->get_name(); + record.object_size = obj->get_obj_size(); record.object_etag = etag; - record.object_versionId = key.instance; + record.object_versionId = obj->get_instance(); // use timestamp as per key sequence id (hex encoded) const utime_t ts(real_clock::now()); boost::algorithm::hex((const char*)&ts, (const char*)&ts + sizeof(utime_t), std::back_inserter(record.object_sequencer)); set_event_id(record.id, etag, ts); - record.bucket_id = s->bucket.bucket_id; + record.bucket_id = s->bucket->get_bucket_id(); // pass meta data record.x_meta_map = s->info.x_meta_map; // pass tags @@ -51,7 +50,7 @@ bool match(const rgw_pubsub_topic_filter& filter, const req_state* s, EventType if (!::match(filter.events, event)) { return false; } - if (!::match(filter.s3_filter.key_filter, s->object.name)) { + if (!::match(filter.s3_filter.key_filter, s->object->get_name())) { return false; } if (!::match(filter.s3_filter.metadata_filter, s->info.x_meta_map)) { @@ -64,14 +63,13 @@ bool match(const rgw_pubsub_topic_filter& filter, const req_state* s, EventType } int publish(const req_state* s, - const rgw_obj_key& key, - uint64_t size, + rgw::sal::RGWObject* obj, const ceph::real_time& mtime, const std::string& etag, EventType event_type, rgw::sal::RGWRadosStore* store) { RGWUserPubSub ps_user(store, s->user->get_id()); - RGWUserPubSub::Bucket ps_bucket(&ps_user, s->bucket); + RGWUserPubSub::Bucket ps_bucket(&ps_user, s->bucket->get_bi()); rgw_pubsub_bucket_topics bucket_topics; auto rc = ps_bucket.get_topics(&bucket_topics); if (rc < 0) { @@ -79,7 +77,7 @@ int publish(const req_state* s, return rc; } rgw_pubsub_s3_record record; - populate_record_from_request(s, key, size, mtime, etag, event_type, record); + populate_record_from_request(s, obj, mtime, etag, event_type, record); bool event_handled = false; bool event_should_be_handled = false; for (const auto& bucket_topic : bucket_topics.topics) { @@ -94,7 +92,7 @@ int publish(const req_state* s, record.opaque_data = topic_cfg.opaque_data; ldout(s->cct, 20) << "notification: '" << topic_filter.s3_id << "' on topic: '" << topic_cfg.dest.arn_topic << - "' and bucket: '" << s->bucket.name << + "' and bucket: '" << s->bucket->get_name() << "' (unique topic: '" << topic_cfg.name << "') apply to event of type: '" << to_string(event_type) << "'" << dendl; try { diff --git a/src/rgw/rgw_notify.h b/src/rgw/rgw_notify.h index 64c759141518..fa90af2de881 100644 --- a/src/rgw/rgw_notify.h +++ b/src/rgw/rgw_notify.h @@ -11,6 +11,7 @@ // forward declarations namespace rgw::sal { class RGWRadosStore; + class RGWObject; } class RGWRados; class req_state; @@ -20,8 +21,7 @@ namespace rgw::notify { // publish notification int publish(const req_state* s, - const rgw_obj_key& key, - uint64_t size, + rgw::sal::RGWObject* obj, const ceph::real_time& mtime, const std::string& etag, EventType event_type, diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index 0958f2871edb..94af5e077b15 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -223,9 +223,9 @@ int rgw_op_get_bucket_policy_from_attr(CephContext *cct, return ret; } else { ldout(cct, 0) << "WARNING: couldn't find acl header for bucket, generating default" << dendl; - rgw::sal::RGWRadosUser user(store); + rgw::sal::RGWRadosUser user(store, bucket_info.owner); /* object exists, but policy is broken */ - int r = user.get_by_id(bucket_info.owner, null_yield); + int r = user.load_by_id(null_yield); if (r < 0) return r; @@ -258,8 +258,8 @@ static int get_obj_policy_from_attr(CephContext *cct, } else if (ret == -ENODATA) { /* object exists, but policy is broken */ ldout(cct, 0) << "WARNING: couldn't find acl header for object, generating default" << dendl; - rgw::sal::RGWRadosUser user(store); - ret = user.get_by_id(bucket_info.owner, y); + rgw::sal::RGWRadosUser user(store, bucket_info.owner); + ret = user.load_by_id(y); if (ret < 0) return ret; @@ -329,7 +329,7 @@ vector get_iam_user_policy_from_attr(CephContext* cct, static int get_obj_attrs(rgw::sal::RGWRadosStore *store, struct req_state *s, const rgw_obj& obj, map& attrs, rgw_obj *target_obj = nullptr) { - RGWRados::Object op_target(store->getRados(), s->bucket_info, *static_cast(s->obj_ctx), obj); + RGWRados::Object op_target(store->getRados(), s->bucket->get_info(), *static_cast(s->obj_ctx), obj); RGWRados::Object::Read read_op(&op_target); read_op.params.attrs = &attrs; @@ -345,7 +345,7 @@ static int get_obj_head(rgw::sal::RGWRadosStore *store, struct req_state *s, { store->getRados()->set_prefetch_data(s->obj_ctx, obj); - RGWRados::Object op_target(store->getRados(), s->bucket_info, *static_cast(s->obj_ctx), obj); + RGWRados::Object op_target(store->getRados(), s->bucket->get_info(), *static_cast(s->obj_ctx), obj); RGWRados::Object::Read read_op(&op_target); read_op.params.attrs = attrs; @@ -441,29 +441,12 @@ static int get_multipart_info(rgw::sal::RGWRadosStore *store, struct req_state * bufferlist header; rgw_obj meta_obj; - meta_obj.init_ns(s->bucket, meta_oid, mp_ns); + meta_obj.init_ns(s->bucket->get_bi(), meta_oid, mp_ns); meta_obj.set_in_extra_data(true); return get_multipart_info(store, s, meta_obj, policy, attrs, upload_info); } -static int modify_obj_attr(rgw::sal::RGWRadosStore *store, struct req_state *s, const rgw_obj& obj, const char* attr_name, bufferlist& attr_val) -{ - map attrs; - RGWRados::Object op_target(store->getRados(), s->bucket_info, *static_cast(s->obj_ctx), obj); - RGWRados::Object::Read read_op(&op_target); - - read_op.params.attrs = &attrs; - - int r = read_op.prepare(s->yield); - if (r < 0) { - return r; - } - store->getRados()->set_atomic(s->obj_ctx, read_op.state.obj); - attrs[attr_name] = attr_val; - return store->getRados()->set_attrs(s->obj_ctx, s->bucket_info, read_op.state.obj, attrs, NULL, s->yield); -} - static int read_bucket_policy(rgw::sal::RGWRadosStore *store, struct req_state *s, RGWBucketInfo& bucket_info, @@ -562,7 +545,6 @@ static int read_obj_policy(rgw::sal::RGWRadosStore *store, int rgw_build_bucket_policies(rgw::sal::RGWRadosStore* store, struct req_state* s) { int ret = 0; - rgw_obj_key obj; auto obj_ctx = store->svc()->sysobj->init_obj_ctx(); string bi = s->info.args.get(RGW_SYS_PARAM_PREFIX "bucket-instance"); @@ -614,43 +596,33 @@ int rgw_build_bucket_policies(rgw::sal::RGWRadosStore* store, struct req_state* if (!s->bucket_name.empty()) { s->bucket_exists = true; - auto b = rgw_bucket(rgw_bucket_key(s->bucket_tenant, s->bucket_name, s->bucket_instance_id)); - - RGWObjVersionTracker ep_ot; - ret = store->ctl()->bucket->read_bucket_info(b, &s->bucket_info, - s->yield, - RGWBucketCtl::BucketInstance::GetParams() - .set_mtime(&s->bucket_mtime) - .set_attrs(&s->bucket_attrs), - &ep_ot); + ret = store->get_bucket(s->user, rgw_bucket(rgw_bucket_key(s->bucket_tenant, s->bucket_name, s->bucket_instance_id)), &s->bucket); if (ret < 0) { if (ret != -ENOENT) { - string bucket_log; - bucket_log = rgw_make_bucket_entry_name(s->bucket_tenant, s->bucket_name); - ldpp_dout(s, 0) << "NOTICE: couldn't get bucket from bucket_name (name=" - << bucket_log << ")" << dendl; - return ret; + string bucket_log; + bucket_log = rgw_make_bucket_entry_name(s->bucket_tenant, s->bucket_name); + ldpp_dout(s, 0) << "NOTICE: couldn't get bucket from bucket_name (name=" + << bucket_log << ")" << dendl; + return ret; } s->bucket_exists = false; - } - s->bucket_ep_objv = ep_ot.read_version; - s->bucket = s->bucket_info.bucket; - - if (s->bucket_exists) { - ret = read_bucket_policy(store, s, s->bucket_info, s->bucket_attrs, - s->bucket_acl.get(), s->bucket); - acct_acl_user = { - s->bucket_info.owner, - s->bucket_acl->get_owner().get_display_name(), - }; - } else { return -ERR_NO_SUCH_BUCKET; } + s->bucket_mtime = s->bucket->get_modification_time(); + s->bucket_attrs = s->bucket->get_attrs().attrs; + ret = read_bucket_policy(store, s, s->bucket->get_info(), + s->bucket->get_attrs().attrs, + s->bucket_acl.get(), s->bucket->get_bi()); + acct_acl_user = { + s->bucket->get_info().owner, + s->bucket_acl->get_owner().get_display_name(), + }; + s->bucket_owner = s->bucket_acl->get_owner(); RGWZoneGroup zonegroup; - int r = store->svc()->zone->get_zonegroup(s->bucket_info.zonegroup, zonegroup); + int r = store->svc()->zone->get_zonegroup(s->bucket->get_info().zonegroup, zonegroup); if (!r) { if (!zonegroup.endpoints.empty()) { s->zonegroup_endpoint = zonegroup.endpoints.front(); @@ -667,9 +639,9 @@ int rgw_build_bucket_policies(rgw::sal::RGWRadosStore* store, struct req_state* ret = r; } - if (s->bucket_exists && !store->svc()->zone->get_zonegroup().equals(s->bucket_info.zonegroup)) { + if (!store->svc()->zone->get_zonegroup().equals(s->bucket->get_info().zonegroup)) { ldpp_dout(s, 0) << "NOTICE: request for data in a different zonegroup (" - << s->bucket_info.zonegroup << " != " + << s->bucket->get_info().zonegroup << " != " << store->svc()->zone->get_zonegroup().get_id() << ")" << dendl; /* we now need to make sure that the operation actually requires copy source, that is * it's a copy operation @@ -680,26 +652,21 @@ int rgw_build_bucket_policies(rgw::sal::RGWRadosStore* store, struct req_state* /* If op is get bucket location, don't redirect */ } else if (!s->local_source || (s->op != OP_PUT && s->op != OP_COPY) || - s->object.empty()) { + rgw::sal::RGWObject::empty(s->object.get())) { return -ERR_PERMANENT_REDIRECT; } } - /* init dest placement -- only if bucket exists, otherwise request is either not relevant, or - * it's a create_bucket request, in which case the op will deal with the placement later */ - if (s->bucket_exists) { - s->dest_placement.storage_class = s->info.storage_class; - s->dest_placement.inherit_from(s->bucket_info.placement_rule); + /* init dest placement */ + s->dest_placement.storage_class = s->info.storage_class; + s->dest_placement.inherit_from(s->bucket->get_placement_rule()); - if (!store->svc()->zone->get_zone_params().valid_placement(s->dest_placement)) { - ldpp_dout(s, 0) << "NOTICE: invalid dest placement: " << s->dest_placement.to_str() << dendl; - return -EINVAL; - } + if (!store->svc()->zone->get_zone_params().valid_placement(s->dest_placement)) { + ldpp_dout(s, 0) << "NOTICE: invalid dest placement: " << s->dest_placement.to_str() << dendl; + return -EINVAL; } - if(s->bucket_exists) { - s->bucket_access_conf = get_public_access_conf_from_attr(s->bucket_attrs); - } + s->bucket_access_conf = get_public_access_conf_from_attr(s->bucket->get_attrs().attrs); } /* handle user ACL only for those APIs which support it */ @@ -777,20 +744,21 @@ int rgw_build_object_policies(rgw::sal::RGWRadosStore *store, struct req_state * { int ret = 0; - if (!s->object.empty()) { + if (!rgw::sal::RGWObject::empty(s->object.get())) { if (!s->bucket_exists) { return -ERR_NO_SUCH_BUCKET; } s->object_acl = std::make_unique(s->cct); - rgw_obj obj(s->bucket, s->object); + + s->object->set_bucket(s->bucket.get()); - store->getRados()->set_atomic(s->obj_ctx, obj); + s->object->set_atomic(s->obj_ctx); if (prefetch_data) { - store->getRados()->set_prefetch_data(s->obj_ctx, obj); + s->object->set_prefetch_data(s->obj_ctx); } - ret = read_obj_policy(store, s, s->bucket_info, s->bucket_attrs, - s->object_acl.get(), nullptr, s->iam_policy, s->bucket, - s->object); + ret = read_obj_policy(store, s, s->bucket->get_info(), s->bucket_attrs, + s->object_acl.get(), nullptr, s->iam_policy, s->bucket->get_bi(), + s->object->get_key()); } return ret; @@ -819,14 +787,14 @@ static int rgw_iam_add_tags_from_bl(struct req_state* s, bufferlist& bl){ return 0; } -static int rgw_iam_add_existing_objtags(rgw::sal::RGWRadosStore* store, struct req_state* s, rgw_obj& obj, std::uint64_t action){ - map attrs; - store->getRados()->set_atomic(s->obj_ctx, obj); - int op_ret = get_obj_attrs(store, s, obj, attrs); +static int rgw_iam_add_existing_objtags(rgw::sal::RGWRadosStore* store, struct req_state* s, std::uint64_t action) { + s->object->set_atomic(s->obj_ctx); + int op_ret = s->object->get_obj_attrs(s->obj_ctx, s->yield); if (op_ret < 0) return op_ret; - auto tags = attrs.find(RGW_ATTR_TAGS); - if (tags != attrs.end()){ + rgw::sal::RGWAttrs attrs = s->object->get_attrs(); + auto tags = attrs.attrs.find(RGW_ATTR_TAGS); + if (tags != attrs.attrs.end()){ return rgw_iam_add_tags_from_bl(s, tags->second); } return 0; @@ -941,7 +909,7 @@ template int retry_raced_bucket_write(RGWRados* g, req_state* s, const F& f) { auto r = f(); for (auto i = 0u; i < 15u && r == -ECANCELED; ++i) { - r = g->try_refresh_bucket_info(s->bucket_info, nullptr, + r = g->try_refresh_bucket_info(s->bucket->get_info(), nullptr, &s->bucket_attrs); if (r >= 0) { r = f(); @@ -954,30 +922,30 @@ int retry_raced_bucket_write(RGWRados* g, req_state* s, const F& f) { int RGWGetObj::verify_permission() { - obj = rgw_obj(s->bucket, s->object); - store->getRados()->set_atomic(s->obj_ctx, obj); + s->object->set_atomic(s->obj_ctx); + if (get_data) { - store->getRados()->set_prefetch_data(s->obj_ctx, obj); + s->object->set_prefetch_data(s->obj_ctx); } if (torrent.get_flag()) { - if (obj.key.instance.empty()) { + if (s->object->get_instance().empty()) { action = rgw::IAM::s3GetObjectTorrent; } else { action = rgw::IAM::s3GetObjectVersionTorrent; } } else { - if (obj.key.instance.empty()) { + if (s->object->get_instance().empty()) { action = rgw::IAM::s3GetObject; } else { action = rgw::IAM::s3GetObjectVersion; } if (s->iam_policy && s->iam_policy->has_partial_conditional(S3_EXISTING_OBJTAG)) - rgw_iam_add_existing_objtags(store, s, obj, action); + rgw_iam_add_existing_objtags(store, s, action); if (! s->iam_user_policies.empty()) { for (auto& user_policy : s->iam_user_policies) { if (user_policy.has_partial_conditional(S3_EXISTING_OBJTAG)) - rgw_iam_add_existing_objtags(store, s, obj, action); + rgw_iam_add_existing_objtags(store, s, action); } } } @@ -986,7 +954,7 @@ int RGWGetObj::verify_permission() return -EACCES; } - if (s->bucket_info.obj_lock_enabled()) { + if (s->bucket->get_info().obj_lock_enabled()) { get_retention = verify_object_permission(this, s, rgw::IAM::s3GetObjectRetention); get_legal_hold = verify_object_permission(this, s, rgw::IAM::s3GetObjectLegalHold); } @@ -1037,20 +1005,18 @@ int RGWOp::verify_op_mask() int RGWGetObjTags::verify_permission() { - auto iam_action = s->object.instance.empty()? + auto iam_action = s->object->get_instance().empty()? rgw::IAM::s3GetObjectTagging: rgw::IAM::s3GetObjectVersionTagging; // TODO since we are parsing the bl now anyway, we probably change // the send_response function to accept RGWObjTag instead of a bl if (s->iam_policy && s->iam_policy->has_partial_conditional(S3_EXISTING_OBJTAG)){ - rgw_obj obj = rgw_obj(s->bucket, s->object); - rgw_iam_add_existing_objtags(store, s, obj, iam_action); + rgw_iam_add_existing_objtags(store, s, iam_action); } if (! s->iam_user_policies.empty()) { for (auto& user_policy : s->iam_user_policies) { if (user_policy.has_partial_conditional(S3_EXISTING_OBJTAG)) { - rgw_obj obj = rgw_obj(s->bucket, s->object); - rgw_iam_add_existing_objtags(store, s, obj, iam_action); + rgw_iam_add_existing_objtags(store, s, iam_action); } } } @@ -1067,22 +1033,20 @@ void RGWGetObjTags::pre_exec() void RGWGetObjTags::execute() { - rgw_obj obj; - map attrs; + rgw::sal::RGWAttrs attrs; - obj = rgw_obj(s->bucket, s->object); + s->object->set_atomic(s->obj_ctx); - store->getRados()->set_atomic(s->obj_ctx, obj); - - op_ret = get_obj_attrs(store, s, obj, attrs); + op_ret = s->object->get_obj_attrs(s->obj_ctx, s->yield); if (op_ret < 0) { - ldpp_dout(this, 0) << "ERROR: failed to get obj attrs, obj=" << obj + ldpp_dout(this, 0) << "ERROR: failed to get obj attrs, obj=" << s->object << " ret=" << op_ret << dendl; return; } - auto tags = attrs.find(RGW_ATTR_TAGS); - if(tags != attrs.end()){ + attrs = s->object->get_attrs(); + auto tags = attrs.attrs.find(RGW_ATTR_TAGS); + if(tags != attrs.attrs.end()){ has_tags = true; tags_bl.append(tags->second); } @@ -1091,19 +1055,17 @@ void RGWGetObjTags::execute() int RGWPutObjTags::verify_permission() { - auto iam_action = s->object.instance.empty() ? + auto iam_action = s->object->get_instance().empty() ? rgw::IAM::s3PutObjectTagging: rgw::IAM::s3PutObjectVersionTagging; if(s->iam_policy && s->iam_policy->has_partial_conditional(S3_EXISTING_OBJTAG)){ - auto obj = rgw_obj(s->bucket, s->object); - rgw_iam_add_existing_objtags(store, s, obj, iam_action); + rgw_iam_add_existing_objtags(store, s, iam_action); } if (! s->iam_user_policies.empty()) { for (auto& user_policy : s->iam_user_policies) { if (user_policy.has_partial_conditional(S3_EXISTING_OBJTAG)) { - rgw_obj obj = rgw_obj(s->bucket, s->object); - rgw_iam_add_existing_objtags(store, s, obj, iam_action); + rgw_iam_add_existing_objtags(store, s, iam_action); } } } @@ -1118,15 +1080,13 @@ void RGWPutObjTags::execute() if (op_ret < 0) return; - if (s->object.empty()){ + if (rgw::sal::RGWObject::empty(s->object.get())){ op_ret= -EINVAL; // we only support tagging on existing objects return; } - rgw_obj obj; - obj = rgw_obj(s->bucket, s->object); - store->getRados()->set_atomic(s->obj_ctx, obj); - op_ret = modify_obj_attr(store, s, obj, RGW_ATTR_TAGS, tags_bl); + s->object->set_atomic(s->obj_ctx); + op_ret = s->object->modify_obj_attrs(s->obj_ctx, RGW_ATTR_TAGS, tags_bl, s->yield); if (op_ret == -ECANCELED){ op_ret = -ERR_TAG_CONFLICT; } @@ -1140,20 +1100,18 @@ void RGWDeleteObjTags::pre_exec() int RGWDeleteObjTags::verify_permission() { - if (!s->object.empty()) { - auto iam_action = s->object.instance.empty() ? + if (!rgw::sal::RGWObject::empty(s->object.get())) { + auto iam_action = s->object->get_instance().empty() ? rgw::IAM::s3DeleteObjectTagging: rgw::IAM::s3DeleteObjectVersionTagging; if (s->iam_policy && s->iam_policy->has_partial_conditional(S3_EXISTING_OBJTAG)){ - auto obj = rgw_obj(s->bucket, s->object); - rgw_iam_add_existing_objtags(store, s, obj, iam_action); + rgw_iam_add_existing_objtags(store, s, iam_action); } if (! s->iam_user_policies.empty()) { for (auto& user_policy : s->iam_user_policies) { if (user_policy.has_partial_conditional(S3_EXISTING_OBJTAG)) { - auto obj = rgw_obj(s->bucket, s->object); - rgw_iam_add_existing_objtags(store, s, obj, iam_action); + rgw_iam_add_existing_objtags(store, s, iam_action); } } } @@ -1165,17 +1123,10 @@ int RGWDeleteObjTags::verify_permission() void RGWDeleteObjTags::execute() { - if (s->object.empty()) + if (rgw::sal::RGWObject::empty(s->object.get())) return; - rgw_obj obj; - obj = rgw_obj(s->bucket, s->object); - store->getRados()->set_atomic(s->obj_ctx, obj); - map attrs; - map rmattr; - bufferlist bl; - rmattr[RGW_ATTR_TAGS] = bl; - op_ret = store->getRados()->set_attrs(s->obj_ctx, s->bucket_info, obj, attrs, &rmattr, s->yield); + op_ret = s->object->delete_obj_attrs(s->obj_ctx, RGW_ATTR_TAGS, s->yield); } int RGWGetBucketTags::verify_permission() @@ -1225,7 +1176,7 @@ void RGWPutBucketTags::execute() { op_ret = retry_raced_bucket_write(store->getRados(), s, [this] { map attrs = s->bucket_attrs; attrs[RGW_ATTR_TAGS] = tags_bl; - return store->ctl()->bucket->set_bucket_instance_attrs(s->bucket_info, attrs, &s->bucket_info.objv_tracker, s->yield); + return store->ctl()->bucket->set_bucket_instance_attrs(s->bucket->get_info(), attrs, &s->bucket->get_info().objv_tracker, s->yield); }); } @@ -1254,10 +1205,10 @@ void RGWDeleteBucketTags::execute() op_ret = retry_raced_bucket_write(store->getRados(), s, [this] { map attrs = s->bucket_attrs; attrs.erase(RGW_ATTR_TAGS); - op_ret = store->ctl()->bucket->set_bucket_instance_attrs(s->bucket_info, attrs, &s->bucket_info.objv_tracker, s->yield); + op_ret = store->ctl()->bucket->set_bucket_instance_attrs(s->bucket->get_info(), attrs, &s->bucket->get_info().objv_tracker, s->yield); if (op_ret < 0) { ldpp_dout(this, 0) << "RGWDeleteBucketTags() failed to remove RGW_ATTR_TAGS on bucket=" - << s->bucket.name + << s->bucket->get_name() << " returned err= " << op_ret << dendl; } return op_ret; @@ -1302,18 +1253,18 @@ void RGWPutBucketReplication::execute() { } op_ret = retry_raced_bucket_write(store->getRados(), s, [this] { - auto sync_policy = (s->bucket_info.sync_policy ? *s->bucket_info.sync_policy : rgw_sync_policy_info()); + auto sync_policy = (s->bucket->get_info().sync_policy ? *s->bucket->get_info().sync_policy : rgw_sync_policy_info()); for (auto& group : sync_policy_groups) { sync_policy.groups[group.id] = group; } - s->bucket_info.set_sync_policy(std::move(sync_policy)); + s->bucket->get_info().set_sync_policy(std::move(sync_policy)); - int ret = store->getRados()->put_bucket_instance_info(s->bucket_info, false, real_time(), + int ret = store->getRados()->put_bucket_instance_info(s->bucket->get_info(), false, real_time(), &s->bucket_attrs); if (ret < 0) { - ldpp_dout(this, 0) << "ERROR: put_bucket_instance_info (bucket=" << s->bucket_info.bucket.get_key() << ") returned ret=" << ret << dendl; + ldpp_dout(this, 0) << "ERROR: put_bucket_instance_info (bucket=" << s->bucket->get_info().bucket.get_key() << ") returned ret=" << ret << dendl; return ret; } @@ -1343,20 +1294,20 @@ void RGWDeleteBucketReplication::execute() } op_ret = retry_raced_bucket_write(store->getRados(), s, [this] { - if (!s->bucket_info.sync_policy) { + if (!s->bucket->get_info().sync_policy) { return 0; } - rgw_sync_policy_info sync_policy = *s->bucket_info.sync_policy; + rgw_sync_policy_info sync_policy = *s->bucket->get_info().sync_policy; update_sync_policy(&sync_policy); - s->bucket_info.set_sync_policy(std::move(sync_policy)); + s->bucket->get_info().set_sync_policy(std::move(sync_policy)); - int ret = store->getRados()->put_bucket_instance_info(s->bucket_info, false, real_time(), + int ret = store->getRados()->put_bucket_instance_info(s->bucket->get_info(), false, real_time(), &s->bucket_attrs); if (ret < 0) { - ldpp_dout(this, 0) << "ERROR: put_bucket_instance_info (bucket=" << s->bucket_info.bucket.get_key() << ") returned ret=" << ret << dendl; + ldpp_dout(this, 0) << "ERROR: put_bucket_instance_info (bucket=" << s->bucket->get_key() << ") returned ret=" << ret << dendl; return ret; } @@ -1395,24 +1346,24 @@ int RGWOp::init_quota() } /* only interested in object related ops */ - if (s->object.empty()) { + if (rgw::sal::RGWObject::empty(s->object.get())) { return 0; } - rgw::sal::RGWRadosUser owner_user(store); - rgw::sal::RGWUser *user; + rgw::sal::RGWRadosUser owner_user(store, s->bucket->get_info().owner); + rgw::sal::RGWUser* user; if (s->user->get_id() == s->bucket_owner.get_id()) { user = s->user; } else { - int r = owner_user.get_by_id(s->bucket_info.owner, s->yield); + int r = owner_user.load_by_id(s->yield); if (r < 0) return r; user = &owner_user; } - if (s->bucket_info.quota.enabled) { - bucket_quota = s->bucket_info.quota; + if (s->bucket->get_info().quota.enabled) { + bucket_quota = s->bucket->get_info().quota; } else if (user->get_info().bucket_quota.enabled) { bucket_quota = user->get_info().bucket_quota; } else { @@ -1616,7 +1567,7 @@ int RGWGetObj::read_user_manifest_part(rgw_bucket& bucket, obj_ctx.set_atomic(part); store->getRados()->set_prefetch_data(&obj_ctx, part); - RGWRados::Object op_target(store->getRados(), s->bucket_info, obj_ctx, part); + RGWRados::Object op_target(store->getRados(), s->bucket->get_info(), obj_ctx, part); RGWRados::Object::Read read_op(&op_target); if (!swift_slo) { @@ -1901,8 +1852,6 @@ int RGWGetObj::handle_user_manifest(const char *prefix) const std::string bucket_name = url_decode(prefix_view.substr(0, pos)); const std::string obj_prefix = url_decode(prefix_view.substr(pos + 1)); - rgw_bucket bucket; - RGWAccessControlPolicy _bucket_acl(s->cct); RGWAccessControlPolicy *bucket_acl; boost::optional _bucket_policy; @@ -1910,7 +1859,7 @@ int RGWGetObj::handle_user_manifest(const char *prefix) RGWBucketInfo bucket_info; RGWBucketInfo *pbucket_info; - if (bucket_name.compare(s->bucket.name) != 0) { + if (bucket_name.compare(s->bucket->get_name()) != 0) { map bucket_attrs; auto obj_ctx = store->svc()->sysobj->init_obj_ctx(); int r = store->getRados()->get_bucket_info(store->svc(), s->user->get_tenant(), @@ -1921,10 +1870,9 @@ int RGWGetObj::handle_user_manifest(const char *prefix) << bucket_name << dendl; return r; } - bucket = bucket_info.bucket; pbucket_info = &bucket_info; bucket_acl = &_bucket_acl; - r = read_bucket_policy(store, s, bucket_info, bucket_attrs, bucket_acl, bucket); + r = read_bucket_policy(store, s, bucket_info, bucket_attrs, bucket_acl, bucket_info.bucket); if (r < 0) { ldpp_dout(this, 0) << "failed to read bucket policy" << dendl; return r; @@ -1933,8 +1881,7 @@ int RGWGetObj::handle_user_manifest(const char *prefix) bucket_info.bucket.tenant); bucket_policy = &_bucket_policy; } else { - bucket = s->bucket; - pbucket_info = &s->bucket_info; + pbucket_info = &s->bucket->get_info(); bucket_acl = s->bucket_acl.get(); bucket_policy = &s->iam_policy; } @@ -1950,6 +1897,7 @@ int RGWGetObj::handle_user_manifest(const char *prefix) if (r < 0) { return r; } + s->object->set_obj_size(s->obj_size); r = RGWRados::Object::Read::range_to_ofs(s->obj_size, ofs, end); if (r < 0) { @@ -2034,7 +1982,7 @@ int RGWGetObj::handle_slo_manifest(bufferlist& bl) RGWAccessControlPolicy *bucket_acl; Policy* bucket_policy; - if (bucket_name.compare(s->bucket.name) != 0) { + if (bucket_name.compare(s->bucket->get_name()) != 0) { const auto& piter = policies.find(bucket_name); if (piter != policies.end()) { bucket_acl = piter->second.first; @@ -2071,7 +2019,7 @@ int RGWGetObj::handle_slo_manifest(bufferlist& bl) policies[bucket_name] = make_pair(bucket_acl, _bucket_policy); } } else { - bucket = s->bucket; + bucket = s->bucket->get_bi(); bucket_acl = s->bucket_acl.get(); bucket_policy = s->iam_policy.get_ptr(); } @@ -2099,6 +2047,7 @@ int RGWGetObj::handle_slo_manifest(bufferlist& bl) complete_etag(etag_sum, &lo_etag); s->obj_size = slo_info.total_size; + s->object->set_obj_size(slo_info.total_size); ldpp_dout(this, 20) << "s->obj_size=" << s->obj_size << dendl; int r = RGWRados::Object::Read::range_to_ofs(total_len, ofs, end); @@ -2126,7 +2075,7 @@ int RGWGetObj::get_data_cb(bufferlist& bl, off_t bl_ofs, off_t bl_len) /* garbage collection related handling */ utime_t start_time = ceph_clock_now(); if (start_time > gc_invalidate_time) { - int r = store->getRados()->defer_gc(s->obj_ctx, s->bucket_info, obj, s->yield); + int r = store->getRados()->defer_gc(s->obj_ctx, s->bucket->get_info(), s->object->get_obj(), s->yield); if (r < 0) { ldpp_dout(this, 0) << "WARNING: could not defer gc entry for obj" << dendl; } @@ -2210,7 +2159,7 @@ void RGWGetObj::execute() perfcounter->inc(l_rgw_get); - RGWRados::Object op_target(store->getRados(), s->bucket_info, *static_cast(s->obj_ctx), obj); + RGWRados::Object op_target(store->getRados(), s->bucket->get_info(), *static_cast(s->obj_ctx), s->object->get_obj()); RGWRados::Object::Read read_op(&op_target); op_ret = get_params(); @@ -2236,6 +2185,7 @@ void RGWGetObj::execute() if (op_ret < 0) goto done_err; version_id = read_op.state.obj.key.instance; + s->object->set_obj_size(s->obj_size); /* STAT ops don't need data, and do no i/o */ if (get_type() == RGW_OP_STAT_OBJ) { @@ -2256,6 +2206,7 @@ void RGWGetObj::execute() goto done_err; } torrent.init(s, store); + rgw_obj obj = s->object->get_obj(); op_ret = torrent.get_torrent_file(read_op, total_len, bl, obj); if (op_ret < 0) { @@ -2280,6 +2231,7 @@ void RGWGetObj::execute() } if (need_decompress) { s->obj_size = cs_info.orig_size; + s->object->set_obj_size(cs_info.orig_size); decompress.emplace(s->cct, &cs_info, partial_content, filter); filter = &*decompress; } @@ -2447,9 +2399,7 @@ void RGWListBuckets::execute() read_count = max_buckets; } - rgw::sal::RGWRadosUser user(store, s->user->get_id()); - - op_ret = user.list_buckets(marker, end_marker, read_count, should_get_stats(), buckets); + op_ret = s->user->list_buckets(marker, end_marker, read_count, should_get_stats(), buckets); if (op_ret < 0) { /* hmm.. something wrong here.. the user was authenticated, so it @@ -2467,7 +2417,7 @@ void RGWListBuckets::execute() decltype(policies_stats)::mapped_type()); } - std::map& m = buckets.get_buckets(); + std::map>& m = buckets.get_buckets(); for (const auto& kv : m) { const auto& bucket = kv.second; @@ -2495,7 +2445,7 @@ void RGWListBuckets::execute() if (read_count > 0 && !m.empty()) { - map::reverse_iterator riter = m.rbegin(); + auto riter = m.rbegin(); marker = riter->first; handle_listing_chunk(std::move(buckets)); @@ -2610,7 +2560,7 @@ void RGWStatAccount::execute() decltype(policies_stats)::mapped_type()); } - std::map& m = buckets.get_buckets(); + std::map>& m = buckets.get_buckets(); for (const auto& kv : m) { const auto& bucket = kv.second; lastmarker = &kv.first; @@ -2656,9 +2606,9 @@ void RGWGetBucketVersioning::execute() return; } - versioned = s->bucket_info.versioned(); - versioning_enabled = s->bucket_info.versioning_enabled(); - mfa_enabled = s->bucket_info.mfa_enabled(); + versioned = s->bucket->versioned(); + versioning_enabled = s->bucket->versioning_enabled(); + mfa_enabled = s->bucket->get_info().mfa_enabled(); } int RGWSetBucketVersioning::verify_permission() @@ -2682,12 +2632,12 @@ void RGWSetBucketVersioning::execute() return; } - if (s->bucket_info.obj_lock_enabled() && versioning_status != VersioningEnabled) { + if (s->bucket->get_info().obj_lock_enabled() && versioning_status != VersioningEnabled) { op_ret = -ERR_INVALID_BUCKET_STATE; return; } - bool cur_mfa_status = (s->bucket_info.flags & BUCKET_MFA_ENABLED) != 0; + bool cur_mfa_status = s->bucket->get_info().mfa_enabled(); mfa_set_status &= (mfa_status != cur_mfa_status); @@ -2701,9 +2651,9 @@ void RGWSetBucketVersioning::execute() bool req_versioning_status = false; //if requested versioning status is not the same as the one set for the bucket, return error if (versioning_status == VersioningEnabled) { - req_versioning_status = (s->bucket_info.flags & BUCKET_VERSIONS_SUSPENDED) != 0; + req_versioning_status = (s->bucket->get_info().flags & BUCKET_VERSIONS_SUSPENDED) != 0; } else if (versioning_status == VersioningSuspended) { - req_versioning_status = (s->bucket_info.flags & BUCKET_VERSIONS_SUSPENDED) == 0; + req_versioning_status = (s->bucket->get_info().flags & BUCKET_VERSIONS_SUSPENDED) == 0; } if (req_versioning_status && !s->mfa_verified) { op_ret = -ERR_MFA_REQUIRED; @@ -2724,24 +2674,24 @@ void RGWSetBucketVersioning::execute() op_ret = retry_raced_bucket_write(store->getRados(), s, [&] { if (mfa_set_status) { if (mfa_status) { - s->bucket_info.flags |= BUCKET_MFA_ENABLED; + s->bucket->get_info().flags |= BUCKET_MFA_ENABLED; } else { - s->bucket_info.flags &= ~BUCKET_MFA_ENABLED; + s->bucket->get_info().flags &= ~BUCKET_MFA_ENABLED; } } if (versioning_status == VersioningEnabled) { - s->bucket_info.flags |= BUCKET_VERSIONED; - s->bucket_info.flags &= ~BUCKET_VERSIONS_SUSPENDED; + s->bucket->get_info().flags |= BUCKET_VERSIONED; + s->bucket->get_info().flags &= ~BUCKET_VERSIONS_SUSPENDED; modified = true; } else if (versioning_status == VersioningSuspended) { - s->bucket_info.flags |= (BUCKET_VERSIONED | BUCKET_VERSIONS_SUSPENDED); + s->bucket->get_info().flags |= (BUCKET_VERSIONED | BUCKET_VERSIONS_SUSPENDED); modified = true; } else { return op_ret; } - return store->getRados()->put_bucket_instance_info(s->bucket_info, false, real_time(), - &s->bucket_attrs); + s->bucket->set_attrs(rgw::sal::RGWAttrs(s->bucket_attrs)); + return s->bucket->put_instance_info(false, real_time()); }); if (!modified) { @@ -2749,7 +2699,7 @@ void RGWSetBucketVersioning::execute() } if (op_ret < 0) { - ldpp_dout(this, 0) << "NOTICE: put_bucket_info on bucket=" << s->bucket.name + ldpp_dout(this, 0) << "NOTICE: put_bucket_info on bucket=" << s->bucket->get_name() << " returned err=" << op_ret << dendl; return; } @@ -2767,7 +2717,7 @@ void RGWGetBucketWebsite::pre_exec() void RGWGetBucketWebsite::execute() { - if (!s->bucket_info.has_website) { + if (!s->bucket->get_info().has_website) { op_ret = -ERR_NO_SUCH_WEBSITE_CONFIGURATION; } } @@ -2798,15 +2748,15 @@ void RGWSetBucketWebsite::execute() } op_ret = retry_raced_bucket_write(store->getRados(), s, [this] { - s->bucket_info.has_website = true; - s->bucket_info.website_conf = website_conf; - op_ret = store->getRados()->put_bucket_instance_info(s->bucket_info, false, + s->bucket->get_info().has_website = true; + s->bucket->get_info().website_conf = website_conf; + op_ret = store->getRados()->put_bucket_instance_info(s->bucket->get_info(), false, real_time(), &s->bucket_attrs); return op_ret; }); if (op_ret < 0) { - ldpp_dout(this, 0) << "NOTICE: put_bucket_info on bucket=" << s->bucket.name + ldpp_dout(this, 0) << "NOTICE: put_bucket_info on bucket=" << s->bucket->get_name() << " returned err=" << op_ret << dendl; return; } @@ -2829,20 +2779,20 @@ void RGWDeleteBucketWebsite::execute() bufferlist in_data; op_ret = forward_request_to_master(s, nullptr, store, in_data, nullptr); if (op_ret < 0) { - ldpp_dout(this, 0) << "NOTICE: forward_to_master failed on bucket=" << s->bucket.name + ldpp_dout(this, 0) << "NOTICE: forward_to_master failed on bucket=" << s->bucket->get_name() << "returned err=" << op_ret << dendl; return; } } op_ret = retry_raced_bucket_write(store->getRados(), s, [this] { - s->bucket_info.has_website = false; - s->bucket_info.website_conf = RGWBucketWebsiteConf(); - op_ret = store->getRados()->put_bucket_instance_info(s->bucket_info, false, + s->bucket->get_info().has_website = false; + s->bucket->get_info().website_conf = RGWBucketWebsiteConf(); + op_ret = store->getRados()->put_bucket_instance_info(s->bucket->get_info(), false, real_time(), &s->bucket_attrs); return op_ret; }); if (op_ret < 0) { - ldpp_dout(this, 0) << "NOTICE: put_bucket_info on bucket=" << s->bucket.name + ldpp_dout(this, 0) << "NOTICE: put_bucket_info on bucket=" << s->bucket->get_name() << " returned err=" << op_ret << dendl; return; } @@ -2870,8 +2820,10 @@ void RGWStatBucket::execute() return; } - rgw::sal::RGWRadosUser user(store, s->user->get_id()); - bucket = new rgw::sal::RGWRadosBucket(store, user, s->bucket); + op_ret = store->get_bucket(s->user, s->bucket->get_bi(), &bucket); + if (op_ret) { + return; + } op_ret = bucket->update_container_stats(); } @@ -2931,10 +2883,10 @@ void RGWListBucket::execute() } if (need_container_stats()) { - op_ret = bucket->update_container_stats(); + op_ret = s->bucket->update_container_stats(); } - RGWRados::Bucket target(store->getRados(), s->bucket_info); + RGWRados::Bucket target(store->getRados(), s->bucket->get_info()); if (shard_id >= 0) { target.set_shard_id(shard_id); } @@ -3208,13 +3160,11 @@ static void filter_out_website(std::map& add_attr void RGWCreateBucket::execute() { - RGWAccessControlPolicy old_policy(s->cct); buffer::list aclbl; buffer::list corsbl; bool existed; string bucket_name = rgw_make_bucket_entry_name(s->bucket_tenant, s->bucket_name); rgw_raw_obj obj(store->svc()->zone->get_zone_params().domain_root, bucket_name); - obj_version objv, *pobjv = NULL; op_ret = get_params(); if (op_ret < 0) @@ -3253,56 +3203,18 @@ void RGWCreateBucket::execute() /* we need to make sure we read bucket info, it's not read before for this * specific request */ - s->bucket.tenant = s->bucket_tenant; - s->bucket.name = s->bucket_name; - rgw::sal::RGWBucket* bucket = NULL; - op_ret = store->get_bucket(*s->user, s->bucket, &bucket); + op_ret = store->get_bucket(s->user, s->bucket_tenant, s->bucket_name, &s->bucket); if (op_ret < 0 && op_ret != -ENOENT) return; s->bucket_exists = (op_ret != -ENOENT); - s->bucket_owner.set_id(s->user->get_id()); - s->bucket_owner.set_name(s->user->get_display_name()); if (s->bucket_exists) { - s->bucket_info = bucket->get_info(); - s->bucket_attrs = bucket->get_attrs(); - delete bucket; - int r = rgw_op_get_bucket_policy_from_attr(s->cct, store, s->bucket_info, - s->bucket_attrs, &old_policy); - if (r >= 0) { - if (old_policy.get_owner().get_id().compare(s->user->get_id()) != 0) { - op_ret = -EEXIST; - return; - } - } + /* Initialize info from req_state */ + info = s->bucket->get_info(); } - RGWBucketInfo master_info; - rgw_bucket *pmaster_bucket; - uint32_t *pmaster_num_shards; - real_time creation_time; - - if (!store->svc()->zone->is_meta_master()) { - JSONParser jp; - op_ret = forward_request_to_master(s, NULL, store, in_data, &jp); - if (op_ret < 0) { - return; - } - - 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(this, 20) << "parsed: objv.tag=" << objv.tag << " objv.ver=" << objv.ver << dendl; - ldpp_dout(this, 20) << "got creation time: << " << master_info.creation_time << dendl; - pmaster_bucket= &master_info.bucket; - creation_time = master_info.creation_time; - pmaster_num_shards = &master_info.layout.current_index.layout.normal.num_shards; - pobjv = &objv; - obj_lock_enabled = master_info.obj_lock_enabled(); - } else { - pmaster_bucket = NULL; - pmaster_num_shards = NULL; - } + s->bucket_owner.set_id(s->user->get_id()); /* XXX dang use s->bucket->owner */ + s->bucket_owner.set_name(s->user->get_display_name()); string zonegroup_id; @@ -3315,21 +3227,6 @@ void RGWCreateBucket::execute() zonegroup_id = store->svc()->zone->get_zonegroup().get_id(); } - if (s->bucket_exists) { - rgw_placement_rule selected_placement_rule; - rgw_bucket bucket; - bucket.tenant = s->bucket_tenant; - bucket.name = s->bucket_name; - op_ret = store->svc()->zone->select_bucket_placement(s->user->get_info(), - zonegroup_id, - placement_rule, - &selected_placement_rule, nullptr); - if (selected_placement_rule != s->bucket_info.placement_rule) { - op_ret = -EEXIST; - 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. */ @@ -3361,31 +3258,32 @@ void RGWCreateBucket::execute() } /* 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(); + filter_out_website(attrs, rmattr_names, info.website_conf); + info.has_website = !info.website_conf.is_empty(); } - s->bucket.tenant = s->bucket_tenant; /* ignored if bucket exists */ - s->bucket.name = s->bucket_name; + rgw_bucket tmp_bucket; + tmp_bucket.tenant = s->bucket_tenant; /* ignored if bucket exists */ + tmp_bucket.name = s->bucket_name; /* Handle updates of the metadata for Swift's object versioning. */ if (swift_ver_location) { - s->bucket_info.swift_ver_location = *swift_ver_location; - s->bucket_info.swift_versioning = (! swift_ver_location->empty()); - } - if (obj_lock_enabled) { - info.flags = BUCKET_VERSIONED | BUCKET_OBJ_LOCK_ENABLED; + info.swift_ver_location = *swift_ver_location; + info.swift_versioning = (! swift_ver_location->empty()); } + /* We're replacing bucket with the newly created one */ + ldpp_dout(this, 10) << "user=" << s->user << " bucket=" << tmp_bucket << dendl; + op_ret = store->create_bucket(*s->user, tmp_bucket, zonegroup_id, + placement_rule, + info.swift_ver_location, + pquota_info, attrs, info, ep_objv, + true, obj_lock_enabled, &s->bucket_exists, s->info, + &s->bucket); - op_ret = store->getRados()->create_bucket(s->user->get_info(), s->bucket, zonegroup_id, - placement_rule, s->bucket_info.swift_ver_location, - pquota_info, attrs, - info, pobjv, &ep_objv, creation_time, - pmaster_bucket, pmaster_num_shards, true); /* 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 << dendl; + ldpp_dout(this, 20) << "rgw_create_bucket returned ret=" << op_ret << " bucket=" << s->bucket.get() << dendl; if (op_ret && op_ret != -EEXIST) return; @@ -3399,18 +3297,17 @@ void RGWCreateBucket::execute() * If all is ok then update the user's list of buckets. * Otherwise inform client about a name conflict. */ - if (info.owner.compare(s->user->get_id()) != 0) { + if (s->bucket->get_info().owner.compare(s->user->get_id()) != 0) { op_ret = -EEXIST; return; } - s->bucket = info.bucket; } - op_ret = store->ctl()->bucket->link_bucket(s->user->get_id(), s->bucket, - info.creation_time, s->yield, false); + op_ret = store->ctl()->bucket->link_bucket(s->user->get_id(), s->bucket->get_bi(), + s->bucket->get_creation_time(), s->yield, false); if (op_ret && !existed && op_ret != -EEXIST) { /* if it exists (or previously existed), don't remove it! */ - op_ret = store->ctl()->bucket->unlink_bucket(s->user->get_id(), s->bucket, s->yield); + op_ret = store->ctl()->bucket->unlink_bucket(s->user->get_id(), s->bucket->get_bi(), s->yield); if (op_ret < 0) { ldpp_dout(this, 0) << "WARNING: failed to unlink bucket: ret=" << op_ret << dendl; @@ -3426,20 +3323,17 @@ void RGWCreateBucket::execute() * changed in the meantime, we have to refresh. */ short tries = 0; do { - RGWBucketInfo binfo; map battrs; - op_ret = store->getRados()->get_bucket_info(store->svc(), s->bucket_tenant, s->bucket_name, - binfo, nullptr, s->yield, &battrs); + op_ret = s->bucket->get_bucket_info(s->yield); if (op_ret < 0) { return; - } else if (binfo.owner.compare(s->user->get_id()) != 0) { + } else if (!s->bucket->is_owner(s->user)) { /* 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; + s->bucket_attrs = s->bucket->get_attrs().attrs; } attrs.clear(); @@ -3450,24 +3344,24 @@ void RGWCreateBucket::execute() } 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_info.quota); + op_ret = filter_out_quota_info(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_info.swift_ver_location = *swift_ver_location; - s->bucket_info.swift_versioning = (! swift_ver_location->empty()); + s->bucket->get_info().swift_ver_location = *swift_ver_location; + s->bucket->get_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(); + filter_out_website(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 = store->ctl()->bucket->set_bucket_instance_attrs(s->bucket_info, attrs, - &s->bucket_info.objv_tracker, + op_ret = store->ctl()->bucket->set_bucket_instance_attrs(s->bucket->get_info(), attrs, + &s->bucket->get_info().objv_tracker, s->yield); } while (op_ret == -ECANCELED && tries++ < 20); @@ -3505,7 +3399,7 @@ void RGWDeleteBucket::execute() return; } RGWObjVersionTracker ot; - ot.read_version = s->bucket_ep_objv; + ot.read_version = s->bucket->get_version(); if (s->system_request) { string tag = s->info.args.get(RGW_SYS_PARAM_PREFIX "tag"); @@ -3524,12 +3418,12 @@ void RGWDeleteBucket::execute() } } - op_ret = store->ctl()->bucket->sync_user_stats(s->user->get_id(), s->bucket_info); + op_ret = s->bucket->sync_user_stats(); if ( op_ret < 0) { ldpp_dout(this, 1) << "WARNING: failed to sync user stats before bucket delete: op_ret= " << op_ret << dendl; } - - op_ret = store->getRados()->check_bucket_empty(s->bucket_info, s->yield); + + op_ret = s->bucket->check_empty(s->yield); if (op_ret < 0) { return; } @@ -3563,29 +3457,14 @@ void RGWDeleteBucket::execute() } } - op_ret = abort_bucket_multiparts(store, s->cct, s->bucket_info, prefix, delimiter); - - if (op_ret < 0) { - return; - } - - op_ret = store->getRados()->delete_bucket(s->bucket_info, ot, s->yield, false); + op_ret = s->bucket->remove_bucket(false, prefix, delimiter, s->yield); - if (op_ret == -ECANCELED) { - // lost a race, either with mdlog sync or another delete bucket operation. - // in either case, we've already called ctl.bucket->unlink_bucket() - op_ret = 0; - return; - } - - if (op_ret == 0) { - op_ret = store->ctl()->bucket->unlink_bucket(s->bucket_info.owner, - s->bucket, s->yield, false); - if (op_ret < 0) { - ldpp_dout(this, 0) << "WARNING: failed to unlink bucket: ret=" << op_ret - << dendl; - } + if (op_ret < 0 && op_ret == -ECANCELED) { + // lost a race, either with mdlog sync or another delete bucket operation. + // in either case, we've already called ctl.bucket->unlink_bucket() + op_ret = 0; } + return; } int RGWPutObj::verify_permission() @@ -3683,10 +3562,13 @@ int RGWPutObj::verify_permission() rgw_add_to_iam_environment(s->env, s3_kms_attr, kms_header->second); } + /* Object needs a bucket from this point */ + s->object->set_bucket(s->bucket.get()); + auto usr_policy_res = eval_user_policies(s->iam_user_policies, s->env, boost::none, rgw::IAM::s3PutObject, - rgw_obj(s->bucket, s->object)); + s->object->get_obj()); if (usr_policy_res == Effect::Deny) return -EACCES; @@ -3694,7 +3576,7 @@ int RGWPutObj::verify_permission() if (s->iam_policy) { e = s->iam_policy->eval(s->env, *s->auth.identity, rgw::IAM::s3PutObject, - rgw_obj(s->bucket, s->object)); + s->object->get_obj()); } if (e == Effect::Allow) { return 0; @@ -3855,7 +3737,7 @@ void RGWPutObj::execute() }); op_ret = -EINVAL; - if (s->object.empty()) { + if (rgw::sal::RGWObject::empty(s->object.get())) { return; } @@ -3864,6 +3746,8 @@ void RGWPutObj::execute() return; } + /* Object needs a bucket from this point */ + s->object->set_bucket(s->bucket.get()); op_ret = get_system_versioning_params(s, &olh_epoch, &version_id); if (op_ret < 0) { @@ -3890,7 +3774,7 @@ void RGWPutObj::execute() if (!chunked_upload) { /* with chunked upload we don't know how big is the upload. we also check sizes at the end anyway */ - op_ret = store->getRados()->check_quota(s->bucket_owner.get_id(), s->bucket, + op_ret = store->getRados()->check_quota(s->bucket_owner.get_id(), s->bucket->get_bi(), user_quota, bucket_quota, s->content_length); if (op_ret < 0) { ldpp_dout(this, 20) << "check_quota() returned ret=" << op_ret << dendl; @@ -3905,14 +3789,13 @@ void RGWPutObj::execute() const bool multipart = !multipart_upload_id.empty(); auto& obj_ctx = *static_cast(s->obj_ctx); - rgw_obj obj{s->bucket, s->object}; /* Handle object versioning of Swift API. */ if (! multipart) { op_ret = store->getRados()->swift_versioning_copy(obj_ctx, s->bucket_owner.get_id(), - s->bucket_info, - obj, + s->bucket.get(), + s->object.get(), this, s->yield); if (op_ret < 0) { @@ -3933,7 +3816,7 @@ void RGWPutObj::execute() multipart_upload_info upload_info; if (multipart) { - RGWMPObj mp(s->object.name, multipart_upload_id); + RGWMPObj mp(s->object->get_name(), multipart_upload_id); op_ret = get_multipart_info(store, s, mp.get_meta(), nullptr, nullptr, &upload_info); if (op_ret < 0) { @@ -3947,32 +3830,33 @@ void RGWPutObj::execute() pdest_placement = &upload_info.dest_placement; ldpp_dout(this, 20) << "dest_placement for part=" << upload_info.dest_placement << dendl; processor.emplace( - &*aio, store, s->bucket_info, pdest_placement, - s->owner.get_id(), obj_ctx, obj, + &*aio, store, s->bucket.get(), pdest_placement, + s->owner.get_id(), obj_ctx, s->object->get_obj(), multipart_upload_id, multipart_part_num, multipart_part_str, this, s->yield); } else if(append) { - if (s->bucket_info.versioned()) { + if (s->bucket->versioned()) { op_ret = -ERR_INVALID_BUCKET_STATE; return; } pdest_placement = &s->dest_placement; processor.emplace( - &*aio, store, s->bucket_info, pdest_placement, s->bucket_owner.get_id(),obj_ctx, obj, + &*aio, store, s->bucket.get(), pdest_placement, s->bucket_owner.get_id(), + obj_ctx, s->object->get_obj(), s->req_id, position, &cur_accounted_size, this, s->yield); } else { - if (s->bucket_info.versioning_enabled()) { + if (s->bucket->versioning_enabled()) { if (!version_id.empty()) { - obj.key.set_instance(version_id); + s->object->set_instance(version_id); } else { - store->getRados()->gen_rand_obj_instance_name(&obj); - version_id = obj.key.instance; + s->object->gen_rand_obj_instance_name(); + version_id = s->object->get_instance(); } } pdest_placement = &s->dest_placement; processor.emplace( - &*aio, store, s->bucket_info, pdest_placement, - s->bucket_owner.get_id(), obj_ctx, obj, olh_epoch, + &*aio, store, s->bucket.get(), pdest_placement, + s->bucket_owner.get_id(), obj_ctx, s->object->get_obj(), olh_epoch, s->req_id, this, s->yield); } @@ -3984,12 +3868,11 @@ void RGWPutObj::execute() } if ((! copy_source.empty()) && !copy_source_range) { - rgw_obj_key obj_key(copy_source_object_name, copy_source_version_id); - rgw_obj obj(copy_source_bucket_info.bucket, obj_key.name); + rgw::sal::RGWRadosObject obj(store, rgw_obj_key(copy_source_object_name, copy_source_version_id)); + rgw::sal::RGWRadosBucket bucket(store, copy_source_bucket_info); RGWObjState *astate; - op_ret = store->getRados()->get_obj_state(&obj_ctx, copy_source_bucket_info, obj, - &astate, true, s->yield, false); + op_ret = obj.get_obj_state(&obj_ctx, bucket, &astate, s->yield); if (op_ret < 0) { ldpp_dout(this, 0) << "ERROR: get copy source obj state returned with error" << op_ret << dendl; return; @@ -4085,6 +3968,7 @@ void RGWPutObj::execute() return; } s->obj_size = ofs; + s->object->set_obj_size(ofs); perfcounter->inc(l_rgw_put_b, s->obj_size); @@ -4093,7 +3977,7 @@ void RGWPutObj::execute() return; } - op_ret = store->getRados()->check_quota(s->bucket_owner.get_id(), s->bucket, + op_ret = store->getRados()->check_quota(s->bucket_owner.get_id(), s->bucket->get_bi(), user_quota, bucket_quota, s->obj_size); if (op_ret < 0) { ldpp_dout(this, 20) << "second check_quota() returned op_ret=" << op_ret << dendl; @@ -4199,7 +4083,7 @@ void RGWPutObj::execute() } // send request to notification manager - const auto ret = rgw::notify::publish(s, obj.key, s->obj_size, mtime, etag, rgw::notify::ObjectCreatedPut, store); + const auto ret = rgw::notify::publish(s, s->object.get(), mtime, etag, rgw::notify::ObjectCreatedPut, store); if (ret < 0) { ldpp_dout(this, 5) << "WARNING: publishing notification failed, with error: " << ret << dendl; // TODO: we should have conf to make send a blocking coroutine and reply with error in case sending failed @@ -4239,7 +4123,7 @@ void RGWPostObj::execute() auto usr_policy_res = eval_user_policies(s->iam_user_policies, s->env, boost::none, rgw::IAM::s3PutObject, - rgw_obj(s->bucket, s->object)); + s->object->get_obj()); if (usr_policy_res == Effect::Deny) { op_ret = -EACCES; return; @@ -4249,7 +4133,7 @@ void RGWPostObj::execute() if (s->iam_policy) { e = s->iam_policy->eval(s->env, *s->auth.identity, rgw::IAM::s3PutObject, - rgw_obj(s->bucket, s->object)); + s->object->get_obj()); } if (e == Effect::Deny) { op_ret = -EACCES; @@ -4273,7 +4157,7 @@ void RGWPostObj::execute() int len = 0; op_ret = store->getRados()->check_quota(s->bucket_owner.get_id(), - s->bucket, + s->bucket->get_bi(), user_quota, bucket_quota, s->content_length); @@ -4296,20 +4180,21 @@ void RGWPostObj::execute() ldpp_dout(this, 15) << "supplied_md5=" << supplied_md5 << dendl; } - rgw_obj obj(s->bucket, get_current_filename()); - if (s->bucket_info.versioning_enabled()) { - store->getRados()->gen_rand_obj_instance_name(&obj); + std::unique_ptr obj = + s->bucket->get_object(rgw_obj_key(get_current_filename())); + if (s->bucket->versioning_enabled()) { + obj->gen_rand_obj_instance_name(); } auto aio = rgw::make_throttle(s->cct->_conf->rgw_put_obj_min_window_size, s->yield); using namespace rgw::putobj; - AtomicObjectProcessor processor(&*aio, store, s->bucket_info, + AtomicObjectProcessor processor(&*aio, store, s->bucket.get(), &s->dest_placement, s->bucket_owner.get_id(), *static_cast(s->obj_ctx), - obj, 0, s->req_id, this, s->yield); + obj->get_obj(), 0, s->req_id, this, s->yield); op_ret = processor.prepare(s->yield); if (op_ret < 0) { return; @@ -4377,9 +4262,10 @@ void RGWPostObj::execute() } s->obj_size = ofs; + s->object->set_obj_size(ofs); - op_ret = store->getRados()->check_quota(s->bucket_owner.get_id(), s->bucket, + op_ret = store->getRados()->check_quota(s->bucket_owner.get_id(), s->bucket->get_bi(), user_quota, bucket_quota, s->obj_size); if (op_ret < 0) { return; @@ -4428,7 +4314,7 @@ void RGWPostObj::execute() } } while (is_next_file_to_upload()); - const auto ret = rgw::notify::publish(s, s->object, ofs, ceph::real_clock::now(), etag, rgw::notify::ObjectCreatedPost, store); + const auto ret = rgw::notify::publish(s, s->object.get(), ceph::real_clock::now(), etag, rgw::notify::ObjectCreatedPost, store); if (ret < 0) { ldpp_dout(this, 5) << "WARNING: publishing notification failed, with error: " << ret << dendl; // TODO: we should have conf to make send a blocking coroutine and reply with error in case sending failed @@ -4600,7 +4486,7 @@ void RGWPutMetadataBucket::execute() } if (!placement_rule.empty() && - placement_rule != s->bucket_info.placement_rule) { + placement_rule != s->bucket->get_placement_rule()) { op_ret = -EEXIST; return; } @@ -4639,25 +4525,25 @@ void RGWPutMetadataBucket::execute() * 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); + op_ret = filter_out_quota_info(attrs, rmattr_names, s->bucket->get_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()); + s->bucket->get_info().swift_ver_location = *swift_ver_location; + s->bucket->get_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(); + filter_out_website(attrs, rmattr_names, s->bucket->get_info().website_conf); + s->bucket->get_info().has_website = !s->bucket->get_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 = store->ctl()->bucket->set_bucket_instance_attrs(s->bucket_info, attrs, - &s->bucket_info.objv_tracker, + op_ret = store->ctl()->bucket->set_bucket_instance_attrs(s->bucket->get_info(), attrs, + &s->bucket->get_info().objv_tracker, s->yield); return op_ret; }); @@ -4681,11 +4567,10 @@ void RGWPutMetadataObject::pre_exec() void RGWPutMetadataObject::execute() { - rgw_obj obj(s->bucket, s->object); rgw_obj target_obj; map attrs, orig_attrs, rmattrs; - store->getRados()->set_atomic(s->obj_ctx, obj); + s->object->set_atomic(s->obj_ctx); op_ret = get_params(); if (op_ret < 0) { @@ -4698,10 +4583,11 @@ void RGWPutMetadataObject::execute() } /* check if obj exists, read orig attrs */ - op_ret = get_obj_attrs(store, s, obj, orig_attrs, &target_obj); + op_ret = s->object->get_obj_attrs(s->obj_ctx, s->yield, &target_obj); if (op_ret < 0) { return; } + orig_attrs = s->object->get_attrs().attrs; /* Check whether the object has expired. Swift API documentation * stands that we should return 404 Not Found in such case. */ @@ -4723,7 +4609,7 @@ void RGWPutMetadataObject::execute() } } - op_ret = store->getRados()->set_attrs(s->obj_ctx, s->bucket_info, target_obj, + op_ret = store->getRados()->set_attrs(s->obj_ctx, s->bucket->get_info(), target_obj, attrs, &rmattrs, s->yield); } @@ -4765,7 +4651,7 @@ int RGWDeleteObj::handle_slo_manifest(bufferlist& bl) /* Request removal of the manifest object itself. */ RGWBulkDelete::acct_path_t path; path.bucket_name = s->bucket_name; - path.obj_key = s->object; + path.obj_key = s->object->get_key(); items.push_back(path); int ret = deleter->delete_chunk(items); @@ -4783,14 +4669,14 @@ int RGWDeleteObj::verify_permission() return op_ret; } if (s->iam_policy || ! s->iam_user_policies.empty()) { - if (s->bucket_info.obj_lock_enabled() && bypass_governance_mode) { + if (s->bucket->get_info().obj_lock_enabled() && bypass_governance_mode) { auto r = eval_user_policies(s->iam_user_policies, s->env, boost::none, - rgw::IAM::s3BypassGovernanceRetention, ARN(s->bucket, s->object.name)); + rgw::IAM::s3BypassGovernanceRetention, ARN(s->bucket->get_bi(), s->object->get_name())); if (r == Effect::Deny) { bypass_perm = false; } else if (r == Effect::Pass && s->iam_policy) { r = s->iam_policy->eval(s->env, *s->auth.identity, rgw::IAM::s3BypassGovernanceRetention, - ARN(s->bucket, s->object.name)); + ARN(s->bucket->get_bi(), s->object->get_name())); if (r == Effect::Deny) { bypass_perm = false; } @@ -4798,10 +4684,10 @@ int RGWDeleteObj::verify_permission() } auto usr_policy_res = eval_user_policies(s->iam_user_policies, s->env, boost::none, - s->object.instance.empty() ? + s->object->get_instance().empty() ? rgw::IAM::s3DeleteObject : rgw::IAM::s3DeleteObjectVersion, - ARN(s->bucket, s->object.name)); + ARN(s->bucket->get_bi(), s->object->get_name())); if (usr_policy_res == Effect::Deny) { return -EACCES; } @@ -4809,10 +4695,10 @@ int RGWDeleteObj::verify_permission() rgw::IAM::Effect r = Effect::Pass; if (s->iam_policy) { r = s->iam_policy->eval(s->env, *s->auth.identity, - s->object.instance.empty() ? + s->object->get_instance().empty() ? rgw::IAM::s3DeleteObject : rgw::IAM::s3DeleteObjectVersion, - ARN(s->bucket, s->object.name)); + ARN(s->bucket->get_bi(), s->object->get_name())); } if (r == Effect::Allow) return 0; @@ -4826,8 +4712,8 @@ int RGWDeleteObj::verify_permission() return -EACCES; } - if (s->bucket_info.mfa_enabled() && - !s->object.instance.empty() && + if (s->bucket->get_info().mfa_enabled() && + !s->object->get_instance().empty() && !s->mfa_verified) { ldpp_dout(this, 5) << "NOTICE: object delete request with a versioned object, mfa auth not provided" << dendl; return -ERR_MFA_REQUIRED; @@ -4847,40 +4733,38 @@ void RGWDeleteObj::execute() op_ret = -ERR_NO_SUCH_BUCKET; return; } + s->object->set_bucket(s->bucket.get()); - rgw_obj obj(s->bucket, s->object); - map attrs; - - bool check_obj_lock = obj.key.have_instance() && s->bucket_info.obj_lock_enabled(); + rgw::sal::RGWAttrs attrs; - if (!s->object.empty()) { - op_ret = get_obj_attrs(store, s, obj, attrs); + bool check_obj_lock = s->object->have_instance() && s->bucket->get_info().obj_lock_enabled(); - if (need_object_expiration() || multipart_delete) { - /* check if obj exists, read orig attrs */ - if (op_ret < 0) { + if (!rgw::sal::RGWObject::empty(s->object.get())) { + op_ret = s->object->get_obj_attrs(s->obj_ctx, s->yield); + if (op_ret < 0) { + if (need_object_expiration() || multipart_delete) { return; } - } - if (check_obj_lock) { - /* check if obj exists, read orig attrs */ - if (op_ret < 0) { - if (op_ret == -ENOENT) { - /* object maybe delete_marker, skip check_obj_lock*/ - check_obj_lock = false; - } else { - return; - } + if (check_obj_lock) { + /* check if obj exists, read orig attrs */ + if (op_ret == -ENOENT) { + /* object maybe delete_marker, skip check_obj_lock*/ + check_obj_lock = false; + } else { + return; + } } + } else { + attrs = s->object->get_attrs(); } // ignore return value from get_obj_attrs in all other cases op_ret = 0; if (check_obj_lock) { - auto aiter = attrs.find(RGW_ATTR_OBJECT_RETENTION); - if (aiter != attrs.end()) { + auto aiter = attrs.attrs.find(RGW_ATTR_OBJECT_RETENTION); + if (aiter != attrs.attrs.end()) { RGWObjectRetention obj_retention; try { decode(obj_retention, aiter->second); @@ -4896,8 +4780,8 @@ void RGWDeleteObj::execute() } } } - aiter = attrs.find(RGW_ATTR_OBJECT_LEGAL_HOLD); - if (aiter != attrs.end()) { + aiter = attrs.attrs.find(RGW_ATTR_OBJECT_LEGAL_HOLD); + if (aiter != attrs.attrs.end()) { RGWObjectLegalHold obj_legal_hold; try { decode(obj_legal_hold, aiter->second); @@ -4914,9 +4798,9 @@ void RGWDeleteObj::execute() } if (multipart_delete) { - const auto slo_attr = attrs.find(RGW_ATTR_SLO_MANIFEST); + const auto slo_attr = attrs.attrs.find(RGW_ATTR_SLO_MANIFEST); - if (slo_attr != attrs.end()) { + if (slo_attr != attrs.attrs.end()) { op_ret = handle_slo_manifest(slo_attr->second); if (op_ret < 0) { ldpp_dout(this, 0) << "ERROR: failed to handle slo manifest ret=" << op_ret << dendl; @@ -4929,11 +4813,13 @@ void RGWDeleteObj::execute() } RGWObjectCtx *obj_ctx = static_cast(s->obj_ctx); - obj_ctx->set_atomic(obj); + s->object->set_atomic(s->obj_ctx); bool ver_restored = false; op_ret = store->getRados()->swift_versioning_restore(*obj_ctx, s->bucket_owner.get_id(), - s->bucket_info, obj, ver_restored, this); + s->bucket.get(), + s->object.get(), + ver_restored, this); if (op_ret < 0) { return; } @@ -4942,7 +4828,7 @@ void RGWDeleteObj::execute() /* Swift's versioning mechanism hasn't found any previous version of * the object that could be restored. This means we should proceed * with the regular delete path. */ - RGWRados::Object del_target(store->getRados(), s->bucket_info, *obj_ctx, obj); + RGWRados::Object del_target(store->getRados(), s->bucket->get_info(), *obj_ctx, s->object->get_obj()); RGWRados::Object::Delete del_op(&del_target); op_ret = get_system_versioning_params(s, &del_op.params.olh_epoch, @@ -4952,7 +4838,7 @@ void RGWDeleteObj::execute() } del_op.params.bucket_owner = s->bucket_owner.get_id(); - del_op.params.versioning_status = s->bucket_info.versioning_status(); + del_op.params.versioning_status = s->bucket->get_info().versioning_status(); del_op.params.obj_owner = s->owner; del_op.params.unmod_since = unmod_since; del_op.params.high_precision_time = s->system_request; /* system request uses high precision time */ @@ -4965,7 +4851,7 @@ void RGWDeleteObj::execute() /* Check whether the object has expired. Swift API documentation * stands that we should return 404 Not Found in such case. */ - if (need_object_expiration() && object_is_expired(attrs)) { + if (need_object_expiration() && object_is_expired(attrs.attrs)) { op_ret = -ENOENT; return; } @@ -4981,25 +4867,25 @@ void RGWDeleteObj::execute() // cache the objects tags and metadata into the requests // so it could be used in the notification mechanism try { - populate_tags_in_request(s, attrs); + populate_tags_in_request(s, attrs.attrs); } catch (buffer::error& err) { ldpp_dout(this, 5) << "WARNING: failed to populate delete request with object tags: " << err.what() << dendl; } - populate_metadata_in_request(s, attrs); - const auto obj_state = obj_ctx->get_state(obj); - - const auto ret = rgw::notify::publish(s, s->object, obj_state->size , obj_state->mtime, attrs[RGW_ATTR_ETAG].to_str(), - delete_marker && s->object.instance.empty() ? rgw::notify::ObjectRemovedDeleteMarkerCreated : rgw::notify::ObjectRemovedDelete, - store); - if (ret < 0) { - ldpp_dout(this, 5) << "WARNING: publishing notification failed, with error: " << ret << dendl; - // TODO: we should have conf to make send a blocking coroutine and reply with error in case sending failed - // this should be global conf (probably returnign a different handler) - // so we don't need to read the configured values before we perform it - } + populate_metadata_in_request(s, attrs.attrs); } else { op_ret = -EINVAL; } + + s->object->set_obj_size(s->obj_size); + const auto ret = rgw::notify::publish(s, s->object.get(), ceph::real_clock::now(), attrs.attrs[RGW_ATTR_ETAG].to_str(), + delete_marker && s->object->get_instance().empty() ? rgw::notify::ObjectRemovedDeleteMarkerCreated : rgw::notify::ObjectRemovedDelete, + store); + if (ret < 0) { + ldpp_dout(this, 5) << "WARNING: publishing notification failed, with error: " << ret << dendl; + // TODO: we should have conf to make send a blocking coroutine and reply with error in case sending failed + // this should be global conf (probably returnign a different handler) + // so we don't need to read the configured values before we perform it + } } bool RGWCopyObj::parse_copy_location(const std::string_view& url_src, @@ -5056,15 +4942,9 @@ int RGWCopyObj::verify_permission() if (op_ret < 0) { return op_ret; } - map src_attrs; - if (s->bucket_instance_id.empty()) { - op_ret = store->getRados()->get_bucket_info(store->svc(), src_tenant_name, src_bucket_name, src_bucket_info, NULL, s->yield, &src_attrs); - } else { - /* will only happen in intra region sync where the source and dest bucket is the same */ - rgw_bucket b(rgw_bucket_key(src_tenant_name, src_bucket_name, s->bucket_instance_id)); - op_ret = store->getRados()->get_bucket_instance_info(*s->sysobj_ctx, b, src_bucket_info, NULL, &src_attrs, s->yield); - } + /* This is a bit of a hack; create an empty bucket, then load it below. */ + op_ret = store->get_bucket(s->user, RGWBucketInfo(), &src_bucket); if (op_ret < 0) { if (op_ret == -ENOENT) { op_ret = -ERR_NO_SUCH_BUCKET; @@ -5072,26 +4952,33 @@ int RGWCopyObj::verify_permission() return op_ret; } - src_bucket = src_bucket_info.bucket; + op_ret = src_bucket->load_by_name(src_tenant_name, src_bucket_name, s->bucket_instance_id, + s->sysobj_ctx, s->yield); + if (op_ret < 0) { + if (op_ret == -ENOENT) { + op_ret = -ERR_NO_SUCH_BUCKET; + } + return op_ret; + } + src_object->set_bucket(src_bucket.get()); /* get buckets info (source and dest) */ if (s->local_source && source_zone.empty()) { - rgw_obj src_obj(src_bucket, src_object); - store->getRados()->set_atomic(s->obj_ctx, src_obj); - store->getRados()->set_prefetch_data(s->obj_ctx, src_obj); + src_object->set_atomic(s->obj_ctx); + src_object->set_prefetch_data(s->obj_ctx); rgw_placement_rule src_placement; /* check source object permissions */ - op_ret = read_obj_policy(store, s, src_bucket_info, src_attrs, &src_acl, &src_placement.storage_class, - src_policy, src_bucket, src_object); + op_ret = read_obj_policy(store, s, src_bucket->get_info(), src_bucket->get_attrs().attrs, &src_acl, &src_placement.storage_class, + src_policy, src_bucket->get_bi(), src_object->get_key()); if (op_ret < 0) { return op_ret; } /* follow up on previous checks that required reading source object head */ if (need_to_check_storage_class) { - src_placement.inherit_from(src_bucket_info.placement_rule); + src_placement.inherit_from(src_bucket->get_placement_rule()); op_ret = check_storage_class(src_placement); if (op_ret < 0) { @@ -5103,10 +4990,10 @@ int RGWCopyObj::verify_permission() if (!s->auth.identity->is_admin_of(src_acl.get_owner().get_id())) { if (src_policy) { auto e = src_policy->eval(s->env, *s->auth.identity, - src_object.instance.empty() ? + src_object->get_instance().empty() ? rgw::IAM::s3GetObject : rgw::IAM::s3GetObjectVersion, - ARN(src_obj)); + ARN(src_object->get_obj())); if (e == Effect::Deny) { return -EACCES; } else if (e == Effect::Pass && @@ -5123,15 +5010,20 @@ int RGWCopyObj::verify_permission() } RGWAccessControlPolicy dest_bucket_policy(s->cct); - map dest_attrs; if (src_bucket_name.compare(dest_bucket_name) == 0) { /* will only happen if s->local_source or intra region sync */ - dest_bucket_info = src_bucket_info; - dest_attrs = src_attrs; + dest_bucket = src_bucket->clone(); } else { - op_ret = store->getRados()->get_bucket_info(store->svc(), dest_tenant_name, dest_bucket_name, - dest_bucket_info, nullptr, s->yield, &dest_attrs); + op_ret = store->get_bucket(s->user, RGWBucketInfo(), &dest_bucket); + if (op_ret < 0) { + if (op_ret == -ENOENT) { + op_ret = -ERR_NO_SUCH_BUCKET; + } + return op_ret; + } + op_ret = dest_bucket->load_by_name(dest_tenant_name, dest_bucket_name, std::string(), + s->sysobj_ctx, s->yield); if (op_ret < 0) { if (op_ret == -ENOENT) { op_ret = -ERR_NO_SUCH_BUCKET; @@ -5140,18 +5032,18 @@ int RGWCopyObj::verify_permission() } } - dest_bucket = dest_bucket_info.bucket; - - rgw_obj dest_obj(dest_bucket, dest_object); - store->getRados()->set_atomic(s->obj_ctx, dest_obj); + dest_object = store->get_object(rgw_obj_key(dest_obj_name)); + dest_object->set_bucket(dest_bucket.get()); + dest_object->set_atomic(s->obj_ctx); /* check dest bucket permissions */ - op_ret = read_bucket_policy(store, s, dest_bucket_info, dest_attrs, - &dest_bucket_policy, dest_bucket); + op_ret = read_bucket_policy(store, s, dest_bucket->get_info(), + dest_bucket->get_attrs().attrs, + &dest_bucket_policy, dest_bucket->get_bi()); if (op_ret < 0) { return op_ret; } - auto dest_iam_policy = get_iam_policy_from_attr(s->cct, store, dest_attrs, dest_bucket.tenant); + auto dest_iam_policy = get_iam_policy_from_attr(s->cct, store, dest_bucket->get_attrs().attrs, dest_bucket->get_tenant()); /* admin request overrides permission checks */ if (! s->auth.identity->is_admin_of(dest_policy.get_owner().get_id())){ if (dest_iam_policy != boost::none) { @@ -5162,7 +5054,7 @@ int RGWCopyObj::verify_permission() auto e = dest_iam_policy->eval(s->env, *s->auth.identity, rgw::IAM::s3PutObject, - ARN(dest_obj)); + ARN(dest_object->get_obj())); if (e == Effect::Deny) { return -EACCES; } else if (e == Effect::Pass && @@ -5248,34 +5140,29 @@ void RGWCopyObj::execute() if (init_common() < 0) return; - rgw_obj src_obj(src_bucket, src_object); - rgw_obj dst_obj(dest_bucket, dest_object); - RGWObjectCtx& obj_ctx = *static_cast(s->obj_ctx); if ( ! version_id.empty()) { - dst_obj.key.set_instance(version_id); - } else if (dest_bucket_info.versioning_enabled()) { - store->getRados()->gen_rand_obj_instance_name(&dst_obj); + dest_object->set_instance(version_id); + } else if (dest_bucket->versioning_enabled()) { + dest_object->gen_rand_obj_instance_name(); } - obj_ctx.set_atomic(src_obj); - obj_ctx.set_atomic(dst_obj); + src_object->set_atomic(&obj_ctx); + dest_object->set_atomic(&obj_ctx); encode_delete_at_attr(delete_at, attrs); if (!s->system_request) { // no quota enforcement for system requests // get src object size (cached in obj_ctx from verify_permission()) RGWObjState* astate = nullptr; - op_ret = store->getRados()->get_obj_state(s->obj_ctx, src_bucket_info, src_obj, - &astate, true, s->yield, false); + op_ret = src_object->get_obj_state(s->obj_ctx, *src_bucket, &astate, + s->yield, true); if (op_ret < 0) { return; } // enforce quota against the destination bucket owner - op_ret = store->getRados()->check_quota(dest_bucket_info.owner, - dest_bucket_info.bucket, - user_quota, bucket_quota, - astate->accounted_size); + op_ret = dest_bucket->check_quota(user_quota, bucket_quota, + astate->accounted_size); if (op_ret < 0) { return; } @@ -5286,9 +5173,9 @@ void RGWCopyObj::execute() /* Handle object versioning of Swift API. In case of copying to remote this * should fail gently (op_ret == 0) as the dst_obj will not exist here. */ op_ret = store->getRados()->swift_versioning_copy(obj_ctx, - dest_bucket_info.owner, - dest_bucket_info, - dst_obj, + dest_bucket->get_info().owner, + dest_bucket.get(), + dest_object.get(), this, s->yield); if (op_ret < 0) { @@ -5299,10 +5186,10 @@ void RGWCopyObj::execute() s->user->get_id(), &s->info, source_zone, - dst_obj, - src_obj, - dest_bucket_info, - src_bucket_info, + dest_object.get(), + src_object.get(), + dest_bucket.get(), + src_bucket.get(), s->dest_placement, &src_mtime, &mtime, @@ -5323,7 +5210,7 @@ void RGWCopyObj::execute() this, s->yield); - const auto ret = rgw::notify::publish(s, s->object, s->obj_size, mtime, etag, rgw::notify::ObjectCreatedCopy, store); + const auto ret = rgw::notify::publish(s, s->object.get(), mtime, etag, rgw::notify::ObjectCreatedCopy, store); if (ret < 0) { ldpp_dout(this, 5) << "WARNING: publishing notification failed, with error: " << ret << dendl; // TODO: we should have conf to make send a blocking coroutine and reply with error in case sending failed @@ -5335,20 +5222,18 @@ void RGWCopyObj::execute() int RGWGetACLs::verify_permission() { bool perm; - if (!s->object.empty()) { - auto iam_action = s->object.instance.empty() ? + if (!rgw::sal::RGWObject::empty(s->object.get())) { + auto iam_action = s->object->get_instance().empty() ? rgw::IAM::s3GetObjectAcl : rgw::IAM::s3GetObjectVersionAcl; if (s->iam_policy && s->iam_policy->has_partial_conditional(S3_EXISTING_OBJTAG)){ - rgw_obj obj = rgw_obj(s->bucket, s->object); - rgw_iam_add_existing_objtags(store, s, obj, iam_action); + rgw_iam_add_existing_objtags(store, s, iam_action); } if (! s->iam_user_policies.empty()) { for (auto& user_policy : s->iam_user_policies) { if (user_policy.has_partial_conditional(S3_EXISTING_OBJTAG)) { - rgw_obj obj = rgw_obj(s->bucket, s->object); - rgw_iam_add_existing_objtags(store, s, obj, iam_action); + rgw_iam_add_existing_objtags(store, s, iam_action); } } } @@ -5374,7 +5259,7 @@ void RGWGetACLs::execute() { stringstream ss; RGWAccessControlPolicy* const acl = \ - (!s->object.empty() ? s->object_acl.get() : s->bucket_acl.get()); + (!rgw::sal::RGWObject::empty(s->object.get()) ? s->object_acl.get() : s->bucket_acl.get()); RGWAccessControlPolicy_S3* const s3policy = \ static_cast(acl); s3policy->to_xml(ss); @@ -5390,10 +5275,9 @@ int RGWPutACLs::verify_permission() rgw_add_to_iam_environment(s->env, "s3:x-amz-acl", s->canned_acl); rgw_add_grant_to_iam_environment(s->env, s); - if (!s->object.empty()) { - auto iam_action = s->object.instance.empty() ? rgw::IAM::s3PutObjectAcl : rgw::IAM::s3PutObjectVersionAcl; - auto obj = rgw_obj(s->bucket, s->object); - op_ret = rgw_iam_add_existing_objtags(store, s, obj, iam_action); + if (!rgw::sal::RGWObject::empty(s->object.get())) { + auto iam_action = s->object->get_instance().empty() ? rgw::IAM::s3PutObjectAcl : rgw::IAM::s3PutObjectVersionAcl; + op_ret = rgw_iam_add_existing_objtags(store, s, iam_action); perm = verify_object_permission(this, s, iam_action); } else { perm = verify_bucket_permission(this, s, rgw::IAM::s3PutBucketAcl); @@ -5462,7 +5346,6 @@ void RGWPutACLs::execute() RGWACLXMLParser_S3 parser(s->cct); RGWAccessControlPolicy_S3 new_policy(s->cct); stringstream ss; - rgw_obj obj; op_ret = 0; /* XXX redundant? */ @@ -5473,7 +5356,7 @@ void RGWPutACLs::execute() RGWAccessControlPolicy* const existing_policy = \ - (s->object.empty() ? s->bucket_acl.get() : s->object_acl.get()); + (rgw::sal::RGWObject::empty(s->object.get()) ? s->bucket_acl.get() : s->object_acl.get()); owner = existing_policy->get_owner(); @@ -5537,7 +5420,7 @@ void RGWPutACLs::execute() } // forward bucket acl requests to meta master zone - if (s->object.empty() && !store->svc()->zone->is_meta_master()) { + if ((rgw::sal::RGWObject::empty(s->object.get())) && !store->svc()->zone->is_meta_master()) { bufferlist in_data; // include acl data unless it was generated from a canned_acl if (s->canned_acl.empty()) { @@ -5573,16 +5456,17 @@ void RGWPutACLs::execute() return; } new_policy.encode(bl); - if (!s->object.empty()) { - obj = rgw_obj(s->bucket, s->object); - store->getRados()->set_atomic(s->obj_ctx, obj); + map attrs; + + if (!rgw::sal::RGWObject::empty(s->object.get())) { + s->object->set_atomic(s->obj_ctx); //if instance is empty, we should modify the latest object - op_ret = modify_obj_attr(store, s, obj, RGW_ATTR_ACL, bl); + op_ret = s->object->modify_obj_attrs(s->obj_ctx, RGW_ATTR_ACL, bl, s->yield); } else { map attrs = s->bucket_attrs; attrs[RGW_ATTR_ACL] = bl; - op_ret = store->ctl()->bucket->set_bucket_instance_attrs(s->bucket_info, attrs, - &s->bucket_info.objv_tracker, + op_ret = store->ctl()->bucket->set_bucket_instance_attrs(s->bucket->get_info(), attrs, + &s->bucket->get_info().objv_tracker, s->yield); } if (op_ret == -ECANCELED) { @@ -5677,7 +5561,7 @@ void RGWPutLC::execute() } } - op_ret = store->getRados()->get_lc()->set_bucket_config(s->bucket_info, s->bucket_attrs, &new_config); + op_ret = store->getRados()->get_lc()->set_bucket_config(s->bucket->get_info(), s->bucket_attrs, &new_config); if (op_ret < 0) { return; } @@ -5695,7 +5579,7 @@ void RGWDeleteLC::execute() } } - op_ret = store->getRados()->get_lc()->remove_bucket_config(s->bucket_info, s->bucket_attrs); + op_ret = store->getRados()->get_lc()->remove_bucket_config(s->bucket->get_info(), s->bucket_attrs); if (op_ret < 0) { return; } @@ -5744,8 +5628,8 @@ void RGWPutCORS::execute() op_ret = retry_raced_bucket_write(store->getRados(), s, [this] { map attrs = s->bucket_attrs; attrs[RGW_ATTR_CORS] = cors_bl; - return store->ctl()->bucket->set_bucket_instance_attrs(s->bucket_info, attrs, - &s->bucket_info.objv_tracker, + return store->ctl()->bucket->set_bucket_instance_attrs(s->bucket->get_info(), attrs, + &s->bucket->get_info().objv_tracker, s->yield); }); } @@ -5780,11 +5664,11 @@ void RGWDeleteCORS::execute() map attrs = s->bucket_attrs; attrs.erase(RGW_ATTR_CORS); - op_ret = store->ctl()->bucket->set_bucket_instance_attrs(s->bucket_info, attrs, - &s->bucket_info.objv_tracker, + op_ret = store->ctl()->bucket->set_bucket_instance_attrs(s->bucket->get_info(), attrs, + &s->bucket->get_info().objv_tracker, s->yield); if (op_ret < 0) { - ldpp_dout(this, 0) << "RGWLC::RGWDeleteCORS() failed to set attrs on bucket=" << s->bucket.name + ldpp_dout(this, 0) << "RGWLC::RGWDeleteCORS() failed to set attrs on bucket=" << s->bucket->get_name() << " returned err=" << op_ret << dendl; } return op_ret; @@ -5857,7 +5741,7 @@ void RGWGetRequestPayment::pre_exec() void RGWGetRequestPayment::execute() { - requester_pays = s->bucket_info.requester_pays; + requester_pays = s->bucket->get_info().requester_pays; } int RGWSetRequestPayment::verify_permission() @@ -5886,11 +5770,11 @@ void RGWSetRequestPayment::execute() if (op_ret < 0) return; - s->bucket_info.requester_pays = requester_pays; - op_ret = store->getRados()->put_bucket_instance_info(s->bucket_info, false, real_time(), + s->bucket->get_info().requester_pays = requester_pays; + op_ret = store->getRados()->put_bucket_instance_info(s->bucket->get_info(), false, real_time(), &s->bucket_attrs); if (op_ret < 0) { - ldpp_dout(this, 0) << "NOTICE: put_bucket_info on bucket=" << s->bucket.name + ldpp_dout(this, 0) << "NOTICE: put_bucket_info on bucket=" << s->bucket->get_name() << " returned err=" << op_ret << dendl; return; } @@ -5902,7 +5786,7 @@ int RGWInitMultipart::verify_permission() auto usr_policy_res = eval_user_policies(s->iam_user_policies, s->env, boost::none, rgw::IAM::s3PutObject, - rgw_obj(s->bucket, s->object)); + s->object->get_obj()); if (usr_policy_res == Effect::Deny) { return -EACCES; } @@ -5911,7 +5795,7 @@ int RGWInitMultipart::verify_permission() if (s->iam_policy) { e = s->iam_policy->eval(s->env, *s->auth.identity, rgw::IAM::s3PutObject, - rgw_obj(s->bucket, s->object)); + s->object->get_obj()); } if (e == Effect::Allow) { return 0; @@ -5943,7 +5827,7 @@ void RGWInitMultipart::execute() if (get_params() < 0) return; - if (s->object.empty()) + if (rgw::sal::RGWObject::empty(s->object.get())) return; policy.encode(aclbl); @@ -5968,15 +5852,15 @@ void RGWInitMultipart::execute() upload_id.append(buf); string tmp_obj_name; - RGWMPObj mp(s->object.name, upload_id); + RGWMPObj mp(s->object->get_name(), upload_id); tmp_obj_name = mp.get_meta(); - obj.init_ns(s->bucket, tmp_obj_name, mp_ns); + obj.init_ns(s->bucket->get_bi(), tmp_obj_name, mp_ns); // the meta object will be indexed with 0 size, we c obj.set_in_extra_data(true); - obj.index_hash_source = s->object.name; + obj.index_hash_source = s->object->get_name(); - RGWRados::Object op_target(store->getRados(), s->bucket_info, *static_cast(s->obj_ctx), obj); + RGWRados::Object op_target(store->getRados(), s->bucket->get_info(), *static_cast(s->obj_ctx), obj); op_target.set_versioning_disabled(true); /* no versioning for multipart meta */ RGWRados::Object::Write obj_op(&op_target); @@ -5996,7 +5880,7 @@ void RGWInitMultipart::execute() op_ret = obj_op.write_meta(bl.length(), 0, attrs, s->yield); } while (op_ret == -EEXIST); - const auto ret = rgw::notify::publish(s, s->object, s->obj_size, ceph::real_clock::now(), attrs[RGW_ATTR_ETAG].to_str(), rgw::notify::ObjectCreatedPost, store); + const auto ret = rgw::notify::publish(s, s->object.get(), ceph::real_clock::now(), attrs[RGW_ATTR_ETAG].to_str(), rgw::notify::ObjectCreatedPost, store); if (ret < 0) { ldpp_dout(this, 5) << "WARNING: publishing notification failed, with error: " << ret << dendl; // TODO: we should have conf to make send a blocking coroutine and reply with error in case sending failed @@ -6011,7 +5895,7 @@ int RGWCompleteMultipart::verify_permission() auto usr_policy_res = eval_user_policies(s->iam_user_policies, s->env, boost::none, rgw::IAM::s3PutObject, - rgw_obj(s->bucket, s->object)); + s->object->get_obj()); if (usr_policy_res == Effect::Deny) { return -EACCES; } @@ -6020,7 +5904,7 @@ int RGWCompleteMultipart::verify_permission() if (s->iam_policy) { e = s->iam_policy->eval(s->env, *s->auth.identity, rgw::IAM::s3PutObject, - rgw_obj(s->bucket, s->object)); + s->object->get_obj()); } if (e == Effect::Allow) { return 0; @@ -6098,7 +5982,7 @@ void RGWCompleteMultipart::execute() return; } - mp.init(s->object.name, upload_id); + mp.init(s->object->get_name(), upload_id); meta_oid = mp.get_meta(); int total_parts = 0; @@ -6114,13 +5998,13 @@ void RGWCompleteMultipart::execute() list remove_objs; /* objects to be removed from index listing */ - bool versioned_object = s->bucket_info.versioning_enabled(); + bool versioned_object = s->bucket->versioning_enabled(); iter = parts->parts.begin(); - meta_obj.init_ns(s->bucket, meta_oid, mp_ns); + meta_obj.init_ns(s->bucket->get_bi(), meta_oid, mp_ns); meta_obj.set_in_extra_data(true); - meta_obj.index_hash_source = s->object.name; + meta_obj.index_hash_source = s->object->get_name(); /*take a cls lock on meta_obj to prevent racing completions (or retries) from deleting the parts*/ @@ -6130,8 +6014,8 @@ void RGWCompleteMultipart::execute() s->cct->_conf.get_val("rgw_mp_lock_max_time"); utime_t dur(max_lock_secs_mp, 0); - store->getRados()->obj_to_raw((s->bucket_info).placement_rule, meta_obj, &raw_obj); - store->getRados()->get_obj_data_pool((s->bucket_info).placement_rule, + store->getRados()->obj_to_raw((s->bucket->get_info()).placement_rule, meta_obj, &raw_obj); + store->getRados()->get_obj_data_pool((s->bucket->get_info()).placement_rule, meta_obj,&meta_pool); store->getRados()->open_pool_ctx(meta_pool, serializer.ioctx, true); @@ -6201,7 +6085,7 @@ void RGWCompleteMultipart::execute() /* update manifest for part */ string oid = mp.get_part(obj_iter->second.num); rgw_obj src_obj; - src_obj.init_ns(s->bucket, oid, mp_ns); + src_obj.init_ns(s->bucket->get_bi(), oid, mp_ns); if (obj_part.manifest.empty()) { ldpp_dout(this, 0) << "ERROR: empty manifest for object part: obj=" @@ -6270,7 +6154,7 @@ void RGWCompleteMultipart::execute() attrs[RGW_ATTR_COMPRESSION] = tmp; } - target_obj.init(s->bucket, s->object.name); + target_obj.init(s->bucket->get_bi(), s->object->get_name()); if (versioned_object) { if (!version_id.empty()) { target_obj.key.set_instance(version_id); @@ -6284,7 +6168,7 @@ void RGWCompleteMultipart::execute() obj_ctx.set_atomic(target_obj); - RGWRados::Object op_target(store->getRados(), s->bucket_info, *static_cast(s->obj_ctx), target_obj); + RGWRados::Object op_target(store->getRados(), s->bucket->get_info(), *static_cast(s->obj_ctx), target_obj); RGWRados::Object::Write obj_op(&op_target); obj_op.meta.manifest = &manifest; @@ -6302,16 +6186,16 @@ void RGWCompleteMultipart::execute() // remove the upload obj int r = store->getRados()->delete_obj(*static_cast(s->obj_ctx), - s->bucket_info, meta_obj, 0); + s->bucket->get_info(), meta_obj, 0); if (r >= 0) { /* serializer's exclusive lock is released */ serializer.clear_locked(); } else { ldpp_dout(this, 0) << "WARNING: failed to remove object " << meta_obj << dendl; } - - const auto ret = rgw::notify::publish(s, s->object, ofs, ceph::real_clock::now(), final_etag_str, rgw::notify::ObjectCreatedCompleteMultipartUpload, store); + s->object->set_obj_size(ofs); + const auto ret = rgw::notify::publish(s, s->object.get(), ceph::real_clock::now(), etag, rgw::notify::ObjectCreatedCompleteMultipartUpload, store); if (ret < 0) { ldpp_dout(this, 5) << "WARNING: publishing notification failed, with error: " << ret << dendl; // TODO: we should have conf to make send a blocking coroutine and reply with error in case sending failed @@ -6353,7 +6237,7 @@ int RGWAbortMultipart::verify_permission() auto usr_policy_res = eval_user_policies(s->iam_user_policies, s->env, boost::none, rgw::IAM::s3AbortMultipartUpload, - rgw_obj(s->bucket, s->object)); + s->object->get_obj()); if (usr_policy_res == Effect::Deny) { return -EACCES; } @@ -6362,7 +6246,7 @@ int RGWAbortMultipart::verify_permission() if (s->iam_policy) { e = s->iam_policy->eval(s->env, *s->auth.identity, rgw::IAM::s3AbortMultipartUpload, - rgw_obj(s->bucket, s->object)); + s->object->get_obj()); } if (e == Effect::Allow) { return 0; @@ -6393,10 +6277,10 @@ void RGWAbortMultipart::execute() rgw_obj meta_obj; RGWMPObj mp; - if (upload_id.empty() || s->object.empty()) + if (upload_id.empty() || rgw::sal::RGWObject::empty(s->object.get())) return; - mp.init(s->object.name, upload_id); + mp.init(s->object->get_name(), upload_id); meta_oid = mp.get_meta(); op_ret = get_multipart_info(store, s, meta_oid, nullptr, nullptr, nullptr); @@ -6404,7 +6288,7 @@ void RGWAbortMultipart::execute() return; RGWObjectCtx *obj_ctx = static_cast(s->obj_ctx); - op_ret = abort_multipart_upload(store, s->cct, obj_ctx, s->bucket_info, mp); + op_ret = abort_multipart_upload(store, s->cct, obj_ctx, s->bucket->get_info(), mp); } int RGWListMultipart::verify_permission() @@ -6429,7 +6313,7 @@ void RGWListMultipart::execute() if (op_ret < 0) return; - mp.init(s->object.name, upload_id); + mp.init(s->object->get_name(), upload_id); meta_oid = mp.get_meta(); op_ret = get_multipart_info(store, s, meta_oid, &policy, nullptr, nullptr); @@ -6478,7 +6362,7 @@ void RGWListBucketMultiparts::execute() } marker_meta = marker.get_meta(); - op_ret = list_bucket_multiparts(store, s->bucket_info, prefix, marker_meta, delimiter, + op_ret = list_bucket_multiparts(store, s->bucket->get_info(), prefix, marker_meta, delimiter, max_uploads, &objs, &common_prefixes, &is_truncated); if (op_ret < 0) { return; @@ -6514,10 +6398,10 @@ int RGWDeleteMultiObj::verify_permission() if (s->iam_policy || ! s->iam_user_policies.empty()) { auto usr_policy_res = eval_user_policies(s->iam_user_policies, s->env, boost::none, - s->object.instance.empty() ? + s->object->get_instance().empty() ? rgw::IAM::s3DeleteObject : rgw::IAM::s3DeleteObjectVersion, - ARN(s->bucket)); + ARN(s->bucket->get_bi())); if (usr_policy_res == Effect::Deny) { return -EACCES; } @@ -6525,10 +6409,10 @@ int RGWDeleteMultiObj::verify_permission() rgw::IAM::Effect r = Effect::Pass; if (s->iam_policy) { r = s->iam_policy->eval(s->env, *s->auth.identity, - s->object.instance.empty() ? + s->object->get_instance().empty() ? rgw::IAM::s3DeleteObject : rgw::IAM::s3DeleteObjectVersion, - ARN(s->bucket)); + ARN(s->bucket->get_bi())); } if (r == Effect::Allow) return 0; @@ -6599,7 +6483,7 @@ void RGWDeleteMultiObj::execute() if (multi_delete->is_quiet()) quiet = true; - if (s->bucket_info.mfa_enabled()) { + if (s->bucket->get_info().mfa_enabled()) { bool has_versioned = false; for (auto i : multi_delete->objects) { if (!i.instance.empty()) { @@ -6622,14 +6506,14 @@ void RGWDeleteMultiObj::execute() for (iter = multi_delete->objects.begin(); iter != multi_delete->objects.end(); ++iter) { - rgw_obj obj(bucket, *iter); + rgw::sal::RGWRadosObject obj(store, *iter, bucket); if (s->iam_policy || ! s->iam_user_policies.empty()) { auto usr_policy_res = eval_user_policies(s->iam_user_policies, s->env, boost::none, iter->instance.empty() ? rgw::IAM::s3DeleteObject : rgw::IAM::s3DeleteObjectVersion, - ARN(obj)); + ARN(obj.get_obj())); if (usr_policy_res == Effect::Deny) { send_partial_response(*iter, false, "", -EACCES); continue; @@ -6642,7 +6526,7 @@ void RGWDeleteMultiObj::execute() iter->instance.empty() ? rgw::IAM::s3DeleteObject : rgw::IAM::s3DeleteObjectVersion, - ARN(obj)); + ARN(obj.get_obj())); } if ((e == Effect::Deny) || (usr_policy_res == Effect::Pass && e == Effect::Pass && !acl_allowed)) { @@ -6651,13 +6535,13 @@ void RGWDeleteMultiObj::execute() } } - obj_ctx->set_atomic(obj); + obj.set_atomic(obj_ctx); - RGWRados::Object del_target(store->getRados(), s->bucket_info, *obj_ctx, obj); + RGWRados::Object del_target(store->getRados(), s->bucket->get_info(), *obj_ctx, obj.get_obj()); RGWRados::Object::Delete del_op(&del_target); del_op.params.bucket_owner = s->bucket_owner.get_id(); - del_op.params.versioning_status = s->bucket_info.versioning_status(); + del_op.params.versioning_status = s->bucket->get_info().versioning_status(); del_op.params.obj_owner = s->owner; op_ret = del_op.delete_obj(s->yield); @@ -6668,12 +6552,13 @@ void RGWDeleteMultiObj::execute() send_partial_response(*iter, del_op.result.delete_marker, del_op.result.version_id, op_ret); - const auto obj_state = obj_ctx->get_state(obj); + const auto obj_state = obj_ctx->get_state(obj.get_obj()); bufferlist etag_bl; const auto etag = obj_state->get_attr(RGW_ATTR_ETAG, etag_bl) ? etag_bl.to_str() : ""; + obj.set_obj_size(obj_state->size); - const auto ret = rgw::notify::publish(s, obj.key, obj_state->size, obj_state->mtime, etag, - del_op.result.delete_marker && s->object.instance.empty() ? rgw::notify::ObjectRemovedDeleteMarkerCreated : rgw::notify::ObjectRemovedDelete, + const auto ret = rgw::notify::publish(s, &obj, ceph::real_clock::now(), etag, + del_op.result.delete_marker && s->object->get_instance().empty() ? rgw::notify::ObjectRemovedDeleteMarkerCreated : rgw::notify::ObjectRemovedDelete, store); if (ret < 0) { ldpp_dout(this, 5) << "WARNING: publishing notification failed, with error: " << ret << dendl; @@ -6934,10 +6819,10 @@ RGWBulkUploadOp::handle_upload_path(struct req_state *s) std::string bucket_path, file_prefix; if (! s->init_state.url_bucket.empty()) { file_prefix = bucket_path = s->init_state.url_bucket + "/"; - if (! s->object.empty()) { - std::string& object_name = s->object.name; + if (!rgw::sal::RGWObject::empty(s->object.get())) { + const std::string& object_name = s->object->get_name(); - /* As rgw_obj_key::empty() already verified emptiness of s->object.name, + /* As rgw_obj_key::empty() already verified emptiness of s->object->get_name(), * we can safely examine its last element. */ if (object_name.back() == '/') { file_prefix.append(object_name); @@ -7009,10 +6894,7 @@ int RGWBulkUploadOp::handle_dir(const std::string_view path) /* we need to make sure we read bucket info, it's not read before for this * specific request */ - RGWBucketInfo binfo; - std::map battrs; - op_ret = store->getRados()->get_bucket_info(store->svc(), s->bucket_tenant, bucket_name, - binfo, nullptr, s->yield, &battrs); + op_ret = store->get_bucket(s->user, s->bucket_tenant, bucket_name, &s->bucket); if (op_ret < 0 && op_ret != -ENOENT) { return op_ret; } @@ -7020,8 +6902,8 @@ int RGWBulkUploadOp::handle_dir(const std::string_view path) if (bucket_exists) { RGWAccessControlPolicy old_policy(s->cct); - int r = rgw_op_get_bucket_policy_from_attr(s->cct, store, binfo, - battrs, &old_policy); + int r = rgw_op_get_bucket_policy_from_attr(s->cct, store, s->bucket->get_info(), + s->bucket->get_attrs().attrs, &old_policy); if (r >= 0) { if (old_policy.get_owner().get_id().compare(s->user->get_user()) != 0) { op_ret = -EEXIST; @@ -7062,7 +6944,7 @@ int RGWBulkUploadOp::handle_dir(const std::string_view path) pmaster_num_shards = nullptr; } - rgw_placement_rule placement_rule(binfo.placement_rule, s->info.storage_class); + rgw_placement_rule placement_rule(s->bucket->get_placement_rule(), s->info.storage_class); if (bucket_exists) { rgw_placement_rule selected_placement_rule; @@ -7074,7 +6956,7 @@ int RGWBulkUploadOp::handle_dir(const std::string_view path) placement_rule, &selected_placement_rule, nullptr); - if (selected_placement_rule != binfo.placement_rule) { + if (selected_placement_rule != s->bucket->get_placement_rule()) { op_ret = -EEXIST; ldpp_dout(this, 20) << "non-coherent placement rule" << dendl; return op_ret; @@ -7101,7 +6983,7 @@ int RGWBulkUploadOp::handle_dir(const std::string_view path) op_ret = store->getRados()->create_bucket(s->user->get_info(), bucket, store->svc()->zone->get_zonegroup().get_id(), - placement_rule, binfo.swift_ver_location, + placement_rule, s->bucket->get_info().swift_ver_location, pquota_info, attrs, out_info, pobjv, &ep_objv, creation_time, pmaster_bucket, pmaster_num_shards, true); @@ -7202,45 +7084,45 @@ int RGWBulkUploadOp::handle_file(const std::string_view path, std::tie(bucket_name, object) = *parse_path(path); auto& obj_ctx = *static_cast(s->obj_ctx); - RGWBucketInfo binfo; - std::map battrs; + std::unique_ptr bucket; ACLOwner bowner; - op_ret = store->getRados()->get_bucket_info(store->svc(), s->user->get_tenant(), - bucket_name, binfo, nullptr, s->yield, &battrs); + + op_ret = store->get_bucket(s->user, rgw_bucket(rgw_bucket_key(s->user->get_tenant(), bucket_name)), &bucket); if (op_ret == -ENOENT) { ldpp_dout(this, 20) << "non existent directory=" << bucket_name << dendl; } else if (op_ret < 0) { return op_ret; } - if (! handle_file_verify_permission(binfo, - rgw_obj(binfo.bucket, object), - battrs, bowner)) { + std::unique_ptr obj = bucket->get_object(object); + + if (! handle_file_verify_permission(bucket->get_info(), + obj->get_obj(), + bucket->get_attrs().attrs, bowner)) { ldpp_dout(this, 20) << "object creation unauthorized" << dendl; op_ret = -EACCES; return op_ret; } - op_ret = store->getRados()->check_quota(bowner.get_id(), binfo.bucket, + op_ret = store->getRados()->check_quota(s->user->get_id(), bucket->get_bi(), user_quota, bucket_quota, size); if (op_ret < 0) { return op_ret; } - rgw_obj obj(binfo.bucket, object); - if (s->bucket_info.versioning_enabled()) { - store->getRados()->gen_rand_obj_instance_name(&obj); + if (s->bucket->versioning_enabled()) { + obj->gen_rand_obj_instance_name(); } rgw_placement_rule dest_placement = s->dest_placement; - dest_placement.inherit_from(binfo.placement_rule); + dest_placement.inherit_from(bucket->get_placement_rule()); auto aio = rgw::make_throttle(s->cct->_conf->rgw_put_obj_min_window_size, s->yield); using namespace rgw::putobj; - AtomicObjectProcessor processor(&*aio, store, binfo, &s->dest_placement, bowner.get_id(), - obj_ctx, obj, 0, s->req_id, this, s->yield); + AtomicObjectProcessor processor(&*aio, store, bucket.get(), &s->dest_placement, bowner.get_id(), + obj_ctx, obj->get_obj(), 0, s->req_id, this, s->yield); op_ret = processor.prepare(s->yield); if (op_ret < 0) { @@ -7303,7 +7185,7 @@ int RGWBulkUploadOp::handle_file(const std::string_view path, return op_ret; } - op_ret = store->getRados()->check_quota(bowner.get_id(), binfo.bucket, + op_ret = store->getRados()->check_quota(bowner.get_id(), bucket->get_bi(), user_quota, bucket_quota, size); if (op_ret < 0) { ldpp_dout(this, 20) << "quota exceeded for path=" << path << dendl; @@ -7479,7 +7361,7 @@ int RGWSetAttrs::verify_permission() // This looks to be part of the RGW-NFS machinery and has no S3 or // Swift equivalent. bool perm; - if (!s->object.empty()) { + if (!rgw::sal::RGWObject::empty(s->object.get())) { perm = verify_object_permission_no_policy(this, s, RGW_PERM_WRITE); } else { perm = verify_bucket_permission_no_policy(this, s, RGW_PERM_WRITE); @@ -7501,17 +7383,15 @@ void RGWSetAttrs::execute() if (op_ret < 0) return; - rgw_obj obj(s->bucket, s->object); - - if (!s->object.empty()) { - store->getRados()->set_atomic(s->obj_ctx, obj); - op_ret = store->getRados()->set_attrs(s->obj_ctx, s->bucket_info, obj, attrs, nullptr, s->yield); + if (!rgw::sal::RGWObject::empty(s->object.get())) { + rgw::sal::RGWAttrs a(attrs); + op_ret = s->object->set_attrs(a); } else { for (auto& iter : attrs) { s->bucket_attrs[iter.first] = std::move(iter.second); } - op_ret = store->ctl()->bucket->set_bucket_instance_attrs(s->bucket_info, attrs, - &s->bucket_info.objv_tracker, + op_ret = store->ctl()->bucket->set_bucket_instance_attrs(s->bucket->get_info(), attrs, + &s->bucket->get_info().objv_tracker, s->yield); } } @@ -7523,11 +7403,10 @@ void RGWGetObjLayout::pre_exec() void RGWGetObjLayout::execute() { - rgw_obj obj(s->bucket, s->object); RGWRados::Object target(store->getRados(), - s->bucket_info, + s->bucket->get_info(), *static_cast(s->obj_ctx), - rgw_obj(s->bucket, s->object)); + s->object->get_obj()); RGWRados::Object::Read stat_op(&target); op_ret = stat_op.prepare(s->yield); @@ -7563,11 +7442,11 @@ void RGWConfigBucketMetaSearch::execute() return; } - s->bucket_info.mdsearch_config = mdsearch_config; + s->bucket->get_info().mdsearch_config = mdsearch_config; - op_ret = store->getRados()->put_bucket_instance_info(s->bucket_info, false, real_time(), &s->bucket_attrs); + op_ret = store->getRados()->put_bucket_instance_info(s->bucket->get_info(), false, real_time(), &s->bucket_attrs); if (op_ret < 0) { - ldpp_dout(this, 0) << "NOTICE: put_bucket_info on bucket=" << s->bucket.name + ldpp_dout(this, 0) << "NOTICE: put_bucket_info on bucket=" << s->bucket->get_name() << " returned err=" << op_ret << dendl; return; } @@ -7603,11 +7482,11 @@ void RGWDelBucketMetaSearch::pre_exec() void RGWDelBucketMetaSearch::execute() { - s->bucket_info.mdsearch_config.clear(); + s->bucket->get_info().mdsearch_config.clear(); - op_ret = store->getRados()->put_bucket_instance_info(s->bucket_info, false, real_time(), &s->bucket_attrs); + op_ret = store->getRados()->put_bucket_instance_info(s->bucket->get_info(), false, real_time(), &s->bucket_attrs); if (op_ret < 0) { - ldpp_dout(this, 0) << "NOTICE: put_bucket_info on bucket=" << s->bucket.name + ldpp_dout(this, 0) << "NOTICE: put_bucket_info on bucket=" << s->bucket->get_name() << " returned err=" << op_ret << dendl; return; } @@ -7742,8 +7621,8 @@ void RGWPutBucketPolicy::execute() op_ret = retry_raced_bucket_write(store->getRados(), s, [&p, this, &attrs] { attrs[RGW_ATTR_IAM_POLICY].clear(); attrs[RGW_ATTR_IAM_POLICY].append(p.text); - op_ret = store->ctl()->bucket->set_bucket_instance_attrs(s->bucket_info, attrs, - &s->bucket_info.objv_tracker, + op_ret = store->ctl()->bucket->set_bucket_instance_attrs(s->bucket->get_info(), attrs, + &s->bucket->get_info().objv_tracker, s->yield); return op_ret; }); @@ -7818,8 +7697,8 @@ void RGWDeleteBucketPolicy::execute() op_ret = retry_raced_bucket_write(store->getRados(), s, [this] { auto attrs = s->bucket_attrs; attrs.erase(RGW_ATTR_IAM_POLICY); - op_ret = store->ctl()->bucket->set_bucket_instance_attrs(s->bucket_info, attrs, - &s->bucket_info.objv_tracker, + op_ret = store->ctl()->bucket->set_bucket_instance_attrs(s->bucket->get_info(), attrs, + &s->bucket->get_info().objv_tracker, s->yield); return op_ret; }); @@ -7837,7 +7716,7 @@ int RGWPutBucketObjectLock::verify_permission() void RGWPutBucketObjectLock::execute() { - if (!s->bucket_info.obj_lock_enabled()) { + if (!s->bucket->get_info().obj_lock_enabled()) { ldpp_dout(this, 0) << "ERROR: object Lock configuration cannot be enabled on existing buckets" << dendl; op_ret = -ERR_INVALID_BUCKET_STATE; return; @@ -7880,8 +7759,8 @@ void RGWPutBucketObjectLock::execute() } op_ret = retry_raced_bucket_write(store->getRados(), s, [this] { - s->bucket_info.obj_lock = obj_lock; - op_ret = store->getRados()->put_bucket_instance_info(s->bucket_info, false, + s->bucket->get_info().obj_lock = obj_lock; + op_ret = store->getRados()->put_bucket_instance_info(s->bucket->get_info(), false, real_time(), &s->bucket_attrs); return op_ret; }); @@ -7900,7 +7779,7 @@ int RGWGetBucketObjectLock::verify_permission() void RGWGetBucketObjectLock::execute() { - if (!s->bucket_info.obj_lock_enabled()) { + if (!s->bucket->get_info().obj_lock_enabled()) { op_ret = -ERR_NO_SUCH_OBJECT_LOCK_CONFIGURATION; return; } @@ -7928,7 +7807,7 @@ void RGWPutObjRetention::pre_exec() void RGWPutObjRetention::execute() { - if (!s->bucket_info.obj_lock_enabled()) { + if (!s->bucket->get_info().obj_lock_enabled()) { ldpp_dout(this, 0) << "ERROR: object retention can't be set if bucket object lock not configured" << dendl; op_ret = -ERR_INVALID_REQUEST; return; @@ -7961,17 +7840,16 @@ void RGWPutObjRetention::execute() } bufferlist bl; obj_retention.encode(bl); - rgw_obj obj(s->bucket, s->object); //check old retention - map attrs; - op_ret = get_obj_attrs(store, s, obj, attrs); + op_ret = s->object->get_obj_attrs(s->obj_ctx, s->yield); if (op_ret < 0) { ldpp_dout(this, 0) << "ERROR: get obj attr error"<< dendl; return; } - auto aiter = attrs.find(RGW_ATTR_OBJECT_RETENTION); - if (aiter != attrs.end()) { + rgw::sal::RGWAttrs attrs = s->object->get_attrs(); + auto aiter = attrs.attrs.find(RGW_ATTR_OBJECT_RETENTION); + if (aiter != attrs.attrs.end()) { RGWObjectRetention old_obj_retention; try { decode(old_obj_retention, aiter->second); @@ -7988,7 +7866,7 @@ void RGWPutObjRetention::execute() } } - op_ret = modify_obj_attr(store, s, obj, RGW_ATTR_OBJECT_RETENTION, bl); + op_ret = s->object->modify_obj_attrs(s->obj_ctx, RGW_ATTR_OBJECT_RETENTION, bl, s->yield); return; } @@ -8008,21 +7886,20 @@ void RGWGetObjRetention::pre_exec() void RGWGetObjRetention::execute() { - if (!s->bucket_info.obj_lock_enabled()) { + if (!s->bucket->get_info().obj_lock_enabled()) { ldpp_dout(this, 0) << "ERROR: bucket object lock not configured" << dendl; op_ret = -ERR_INVALID_REQUEST; return; } - rgw_obj obj(s->bucket, s->object); - map attrs; - op_ret = get_obj_attrs(store, s, obj, attrs); + op_ret = s->object->get_obj_attrs(s->obj_ctx, s->yield); if (op_ret < 0) { - ldpp_dout(this, 0) << "ERROR: failed to get obj attrs, obj=" << obj + ldpp_dout(this, 0) << "ERROR: failed to get obj attrs, obj=" << s->object << " ret=" << op_ret << dendl; return; } - auto aiter = attrs.find(RGW_ATTR_OBJECT_RETENTION); - if (aiter == attrs.end()) { + rgw::sal::RGWAttrs attrs = s->object->get_attrs(); + auto aiter = attrs.attrs.find(RGW_ATTR_OBJECT_RETENTION); + if (aiter == attrs.attrs.end()) { op_ret = -ERR_NO_SUCH_OBJECT_LOCK_CONFIGURATION; return; } @@ -8052,7 +7929,7 @@ void RGWPutObjLegalHold::pre_exec() } void RGWPutObjLegalHold::execute() { - if (!s->bucket_info.obj_lock_enabled()) { + if (!s->bucket->get_info().obj_lock_enabled()) { ldpp_dout(this, 0) << "ERROR: object legal hold can't be set if bucket object lock not configured" << dendl; op_ret = -ERR_INVALID_REQUEST; return; @@ -8083,9 +7960,8 @@ void RGWPutObjLegalHold::execute() { } bufferlist bl; obj_legal_hold.encode(bl); - rgw_obj obj(s->bucket, s->object); //if instance is empty, we should modify the latest object - op_ret = modify_obj_attr(store, s, obj, RGW_ATTR_OBJECT_LEGAL_HOLD, bl); + op_ret = s->object->modify_obj_attrs(s->obj_ctx, RGW_ATTR_OBJECT_LEGAL_HOLD, bl, s->yield); return; } @@ -8104,12 +7980,12 @@ void RGWGetObjLegalHold::pre_exec() void RGWGetObjLegalHold::execute() { - if (!s->bucket_info.obj_lock_enabled()) { + if (!s->bucket->get_info().obj_lock_enabled()) { ldpp_dout(this, 0) << "ERROR: bucket object lock not configured" << dendl; op_ret = -ERR_INVALID_REQUEST; return; } - rgw_obj obj(s->bucket, s->object); + rgw_obj obj = s->object->get_obj(); map attrs; op_ret = get_obj_attrs(store, s, obj, attrs); if (op_ret < 0) { @@ -8210,7 +8086,7 @@ void RGWPutBucketPublicAccessBlock::execute() op_ret = retry_raced_bucket_write(store->getRados(), s, [this, &bl] { map attrs = s->bucket_attrs; attrs[RGW_ATTR_PUBLIC_ACCESS] = bl; - return store->ctl()->bucket->set_bucket_instance_attrs(s->bucket_info, attrs, &s->bucket_info.objv_tracker, s->yield); + return store->ctl()->bucket->set_bucket_instance_attrs(s->bucket->get_info(), attrs, &s->bucket->get_info().objv_tracker, s->yield); }); } @@ -8269,8 +8145,8 @@ void RGWDeleteBucketPublicAccessBlock::execute() op_ret = retry_raced_bucket_write(store->getRados(), s, [this] { auto attrs = s->bucket_attrs; attrs.erase(RGW_ATTR_PUBLIC_ACCESS); - op_ret = store->ctl()->bucket->set_bucket_instance_attrs(s->bucket_info, attrs, - &s->bucket_info.objv_tracker, + op_ret = store->ctl()->bucket->set_bucket_instance_attrs(s->bucket->get_info(), attrs, + &s->bucket->get_info().objv_tracker, s->yield); return op_ret; }); diff --git a/src/rgw/rgw_op.h b/src/rgw/rgw_op.h index c96bf3a42938..64611bdfd415 100644 --- a/src/rgw/rgw_op.h +++ b/src/rgw/rgw_op.h @@ -281,7 +281,6 @@ protected: bool range_parsed; bool skip_manifest; bool skip_decrypt{false}; - rgw_obj obj; utime_t gc_invalidate_time; bool is_slo; string lo_etag; @@ -825,7 +824,6 @@ public: class RGWListBucket : public RGWOp { protected: - rgw::sal::RGWBucket* bucket; string prefix; rgw_obj_key marker; rgw_obj_key next_marker; @@ -847,17 +845,15 @@ protected: int parse_max_keys(); public: - RGWListBucket() : bucket(nullptr), list_versions(false), max(0), + RGWListBucket() : list_versions(false), max(0), default_max(0), is_truncated(false), allow_unordered(false), shard_id(-1) {} - ~RGWListBucket() { delete bucket; } int verify_permission() override; void pre_exec() override; void execute() override; void init(rgw::sal::RGWRadosStore *store, struct req_state *s, RGWHandler *h) override { RGWOp::init(store, s, h); - bucket = new rgw::sal::RGWRadosBucket(store, *s->user, s->bucket); } virtual int get_params() = 0; void send_response() override = 0; @@ -987,12 +983,9 @@ public: class RGWStatBucket : public RGWOp { protected: - rgw::sal::RGWBucket* bucket; + std::unique_ptr bucket; public: - RGWStatBucket() : bucket(nullptr) {} - ~RGWStatBucket() override { delete bucket; } - int verify_permission() override; void pre_exec() override; void execute() override; @@ -1433,17 +1426,15 @@ protected: ceph::real_time *mod_ptr; ceph::real_time *unmod_ptr; map attrs; - string src_tenant_name, src_bucket_name; - rgw_bucket src_bucket; - rgw_obj_key src_object; - string dest_tenant_name, dest_bucket_name; - rgw_bucket dest_bucket; - string dest_object; + string src_tenant_name, src_bucket_name, src_obj_name; + std::unique_ptr src_bucket; + std::unique_ptr src_object; + string dest_tenant_name, dest_bucket_name, dest_obj_name; + std::unique_ptr dest_bucket; + std::unique_ptr dest_object; ceph::real_time src_mtime; ceph::real_time mtime; RGWRados::AttrsMod attrs_mod; - RGWBucketInfo src_bucket_info; - RGWBucketInfo dest_bucket_info; string source_zone; string etag; @@ -1927,7 +1918,7 @@ public: class RGWDeleteMultiObj : public RGWOp { protected: bufferlist data; - rgw_bucket bucket; + rgw::sal::RGWBucket* bucket; bool quiet; bool status_dumped; bool acl_allowed = false; diff --git a/src/rgw/rgw_opa.cc b/src/rgw/rgw_opa.cc index 96cc5841c1d0..4e5770300267 100644 --- a/src/rgw/rgw_opa.cc +++ b/src/rgw/rgw_opa.cc @@ -44,10 +44,10 @@ int rgw_opa_authorize(RGWOp *& op, jf.dump_string("decoded_uri", s->decoded_uri.c_str()); jf.dump_string("params", s->info.request_params.c_str()); jf.dump_string("request_uri_aws4", s->info.request_uri_aws4.c_str()); - jf.dump_string("object_name", s->object.name.c_str()); + jf.dump_string("object_name", s->object->get_name().c_str()); jf.dump_string("subuser", s->auth.identity->get_subuser().c_str()); jf.dump_object("user_info", s->user->get_info()); - jf.dump_object("bucket_info", s->bucket_info); + jf.dump_object("bucket_info", s->bucket->get_info()); jf.close_section(); jf.close_section(); diff --git a/src/rgw/rgw_os_lib.cc b/src/rgw/rgw_os_lib.cc index b4f8bb260f57..d9b58f24319d 100644 --- a/src/rgw/rgw_os_lib.cc +++ b/src/rgw/rgw_os_lib.cc @@ -11,7 +11,8 @@ namespace rgw { /* static */ - int RGWHandler_Lib::init_from_header(struct req_state *s) + int RGWHandler_Lib::init_from_header(rgw::sal::RGWRadosStore *store, + struct req_state *s) { string req; string first; @@ -51,10 +52,10 @@ namespace rgw { if (pos >= 0) { // XXX ugh, another copy string encoded_obj_str = req.substr(pos+1); - s->object = rgw_obj_key(encoded_obj_str, s->info.args.get("versionId")); + s->object = store->get_object(rgw_obj_key(encoded_obj_str, s->info.args.get("versionId"))); } } else { - s->object = rgw_obj_key(req_name, s->info.args.get("versionId")); + s->object = store->get_object(rgw_obj_key(req_name, s->info.args.get("versionId"))); } return 0; } /* init_from_header */ diff --git a/src/rgw/rgw_process.cc b/src/rgw/rgw_process.cc index e314e8b2fb9c..56560a660d72 100644 --- a/src/rgw/rgw_process.cc +++ b/src/rgw/rgw_process.cc @@ -185,7 +185,7 @@ int process_request(rgw::sal::RGWRadosStore* const store, RGWEnv& rgw_env = client_io->get_env(); - rgw::sal::RGWRadosUser user; + rgw::sal::RGWRadosUser user(store); struct req_state rstate(g_ceph_context, &rgw_env, &user, req->id); struct req_state *s = &rstate; diff --git a/src/rgw/rgw_putobj_processor.cc b/src/rgw/rgw_putobj_processor.cc index 94aab6778216..e3bc25ef09d3 100644 --- a/src/rgw/rgw_putobj_processor.cc +++ b/src/rgw/rgw_putobj_processor.cc @@ -126,7 +126,7 @@ RadosWriter::~RadosWriter() std::optional raw_head; if (!head_obj.empty()) { raw_head.emplace(); - store->getRados()->obj_to_raw(bucket_info.placement_rule, head_obj, &*raw_head); + store->getRados()->obj_to_raw(bucket->get_placement_rule(), head_obj, &*raw_head); } /** @@ -156,7 +156,7 @@ RadosWriter::~RadosWriter() if (need_to_remove_head) { ldpp_dout(dpp, 5) << "NOTE: we are going to process the head obj (" << *raw_head << ")" << dendl; - int r = store->getRados()->delete_obj(obj_ctx, bucket_info, head_obj, 0, 0); + int r = store->getRados()->delete_obj(obj_ctx, bucket->get_info(), head_obj, 0, 0); if (r < 0 && r != -ENOENT) { ldpp_dout(dpp, 0) << "WARNING: failed to remove obj (" << *raw_head << "), leaked" << dendl; } @@ -208,7 +208,7 @@ int AtomicObjectProcessor::prepare(optional_yield y) uint64_t alignment; rgw_pool head_pool; - if (!store->getRados()->get_obj_data_pool(bucket_info.placement_rule, head_obj, &head_pool)) { + if (!store->getRados()->get_obj_data_pool(bucket->get_placement_rule(), head_obj, &head_pool)) { return -EIO; } @@ -219,7 +219,7 @@ int AtomicObjectProcessor::prepare(optional_yield y) bool same_pool = true; - if (bucket_info.placement_rule != tail_placement_rule) { + if (bucket->get_placement_rule() != tail_placement_rule) { rgw_pool tail_pool; if (!store->getRados()->get_obj_data_pool(tail_placement_rule, head_obj, &tail_pool)) { return -EIO; @@ -250,7 +250,7 @@ int AtomicObjectProcessor::prepare(optional_yield y) manifest.set_trivial_rule(head_max_size, stripe_size); r = manifest_gen.create_begin(store->ctx(), &manifest, - bucket_info.placement_rule, + bucket->get_placement_rule(), &tail_placement_rule, head_obj.bucket, head_obj); if (r < 0) { @@ -295,10 +295,10 @@ int AtomicObjectProcessor::complete(size_t accounted_size, obj_ctx.set_atomic(head_obj); - RGWRados::Object op_target(store->getRados(), bucket_info, obj_ctx, head_obj); + RGWRados::Object op_target(store->getRados(), bucket->get_info(), obj_ctx, head_obj); /* some object types shouldn't be versioned, e.g., multipart parts */ - op_target.set_versioning_disabled(!bucket_info.versioning_enabled()); + op_target.set_versioning_disabled(!bucket->versioning_enabled()); RGWRados::Object::Write obj_op(&op_target); @@ -377,7 +377,7 @@ int MultipartObjectProcessor::prepare_head() manifest.set_multipart_part_rule(stripe_size, part_num); r = manifest_gen.create_begin(store->ctx(), &manifest, - bucket_info.placement_rule, + bucket->get_placement_rule(), &tail_placement_rule, target_obj.bucket, target_obj); if (r < 0) { @@ -429,7 +429,7 @@ int MultipartObjectProcessor::complete(size_t accounted_size, return r; } - RGWRados::Object op_target(store->getRados(), bucket_info, obj_ctx, head_obj); + RGWRados::Object op_target(store->getRados(), bucket->get_info(), obj_ctx, head_obj); op_target.set_versioning_disabled(true); RGWRados::Object::Write obj_op(&op_target); @@ -473,12 +473,12 @@ int MultipartObjectProcessor::complete(size_t accounted_size, encode(info, bl); rgw_obj meta_obj; - meta_obj.init_ns(bucket_info.bucket, mp.get_meta(), RGW_OBJ_NS_MULTIPART); + meta_obj.init_ns(bucket->get_bi(), mp.get_meta(), RGW_OBJ_NS_MULTIPART); meta_obj.set_in_extra_data(true); rgw_raw_obj raw_meta_obj; - store->getRados()->obj_to_raw(bucket_info.placement_rule, meta_obj, &raw_meta_obj); + store->getRados()->obj_to_raw(bucket->get_placement_rule(), meta_obj, &raw_meta_obj); auto obj_ctx = store->svc()->sysobj->init_obj_ctx(); auto sysobj = obj_ctx.get_obj(raw_meta_obj); @@ -513,7 +513,7 @@ int AppendObjectProcessor::process_first_chunk(bufferlist &&data, rgw::putobj::D int AppendObjectProcessor::prepare(optional_yield y) { RGWObjState *astate; - int r = store->getRados()->get_obj_state(&obj_ctx, bucket_info, head_obj, &astate, y); + int r = store->getRados()->get_obj_state(&obj_ctx, bucket->get_info(), head_obj, &astate, y); if (r < 0) { return r; } @@ -571,7 +571,7 @@ int AppendObjectProcessor::prepare(optional_yield y) } manifest.set_multipart_part_rule(store->ctx()->_conf->rgw_obj_stripe_size, cur_part_num); - r = manifest_gen.create_begin(store->ctx(), &manifest, bucket_info.placement_rule, &tail_placement_rule, head_obj.bucket, head_obj); + r = manifest_gen.create_begin(store->ctx(), &manifest, bucket->get_placement_rule(), &tail_placement_rule, head_obj.bucket, head_obj); if (r < 0) { return r; } @@ -614,7 +614,7 @@ int AppendObjectProcessor::complete(size_t accounted_size, const string &etag, c return r; } obj_ctx.set_atomic(head_obj); - RGWRados::Object op_target(store->getRados(), bucket_info, obj_ctx, head_obj); + RGWRados::Object op_target(store->getRados(), bucket->get_info(), obj_ctx, head_obj); //For Append obj, disable versioning op_target.set_versioning_disabled(true); RGWRados::Object::Write obj_op(&op_target); diff --git a/src/rgw/rgw_putobj_processor.h b/src/rgw/rgw_putobj_processor.h index 322652ed9a49..b60d5ccf4772 100644 --- a/src/rgw/rgw_putobj_processor.h +++ b/src/rgw/rgw_putobj_processor.h @@ -21,6 +21,7 @@ #include "rgw_rados.h" #include "services/svc_rados.h" #include "services/svc_tier_rados.h" +#include "rgw_sal.h" namespace rgw { @@ -80,7 +81,7 @@ using RawObjSet = std::set; class RadosWriter : public DataProcessor { Aio *const aio; rgw::sal::RGWRadosStore *const store; - const RGWBucketInfo& bucket_info; + rgw::sal::RGWBucket* bucket; RGWObjectCtx& obj_ctx; const rgw_obj head_obj; RGWSI_RADOS::Obj stripe_obj; // current stripe object @@ -90,10 +91,10 @@ class RadosWriter : public DataProcessor { public: RadosWriter(Aio *aio, rgw::sal::RGWRadosStore *store, - const RGWBucketInfo& bucket_info, + rgw::sal::RGWBucket* bucket, RGWObjectCtx& obj_ctx, const rgw_obj& head_obj, const DoutPrefixProvider *dpp, optional_yield y) - : aio(aio), store(store), bucket_info(bucket_info), + : aio(aio), store(store), bucket(bucket), obj_ctx(obj_ctx), head_obj(head_obj), dpp(dpp), y(y) {} ~RadosWriter(); @@ -120,7 +121,7 @@ class ManifestObjectProcessor : public HeadObjectProcessor, public StripeGenerator { protected: rgw::sal::RGWRadosStore *const store; - const RGWBucketInfo& bucket_info; + rgw::sal::RGWBucket* bucket; rgw_placement_rule tail_placement_rule; rgw_user owner; RGWObjectCtx& obj_ctx; @@ -138,16 +139,16 @@ class ManifestObjectProcessor : public HeadObjectProcessor, public: ManifestObjectProcessor(Aio *aio, rgw::sal::RGWRadosStore *store, - const RGWBucketInfo& bucket_info, + rgw::sal::RGWBucket* bucket, const rgw_placement_rule *ptail_placement_rule, const rgw_user& owner, RGWObjectCtx& obj_ctx, - const rgw_obj& head_obj, + rgw_obj& head_obj, const DoutPrefixProvider* dpp, optional_yield y) : HeadObjectProcessor(0), - store(store), bucket_info(bucket_info), + store(store), bucket(bucket), owner(owner), obj_ctx(obj_ctx), head_obj(head_obj), - writer(aio, store, bucket_info, obj_ctx, head_obj, dpp, y), + writer(aio, store, bucket, obj_ctx, head_obj, dpp, y), chunk(&writer, 0), stripe(&chunk, this, 0), dpp(dpp) { if (ptail_placement_rule) { tail_placement_rule = *ptail_placement_rule; @@ -178,14 +179,14 @@ class AtomicObjectProcessor : public ManifestObjectProcessor { int process_first_chunk(bufferlist&& data, DataProcessor **processor) override; public: AtomicObjectProcessor(Aio *aio, rgw::sal::RGWRadosStore *store, - const RGWBucketInfo& bucket_info, + rgw::sal::RGWBucket* bucket, const rgw_placement_rule *ptail_placement_rule, const rgw_user& owner, - RGWObjectCtx& obj_ctx, const rgw_obj& head_obj, + RGWObjectCtx& obj_ctx, rgw_obj head_obj, std::optional olh_epoch, const std::string& unique_tag, const DoutPrefixProvider *dpp, optional_yield y) - : ManifestObjectProcessor(aio, store, bucket_info, ptail_placement_rule, + : ManifestObjectProcessor(aio, store, bucket, ptail_placement_rule, owner, obj_ctx, head_obj, dpp, y), olh_epoch(olh_epoch), unique_tag(unique_tag) {} @@ -222,18 +223,18 @@ class MultipartObjectProcessor : public ManifestObjectProcessor { int prepare_head(); public: MultipartObjectProcessor(Aio *aio, rgw::sal::RGWRadosStore *store, - const RGWBucketInfo& bucket_info, + rgw::sal::RGWBucket* bucket, const rgw_placement_rule *ptail_placement_rule, const rgw_user& owner, RGWObjectCtx& obj_ctx, - const rgw_obj& head_obj, + rgw_obj head_obj, const std::string& upload_id, uint64_t part_num, const std::string& part_num_str, const DoutPrefixProvider *dpp, optional_yield y) - : ManifestObjectProcessor(aio, store, bucket_info, ptail_placement_rule, + : ManifestObjectProcessor(aio, store, bucket, ptail_placement_rule, owner, obj_ctx, head_obj, dpp, y), target_obj(head_obj), upload_id(upload_id), part_num(part_num), part_num_str(part_num_str), - mp(head_obj.key.name, upload_id) + mp(head_obj.key.name, upload_id) {} // prepare a multipart manifest @@ -264,13 +265,15 @@ class MultipartObjectProcessor : public ManifestObjectProcessor { int process_first_chunk(bufferlist&& data, DataProcessor **processor) override; public: - AppendObjectProcessor(Aio *aio, rgw::sal::RGWRadosStore *store, const RGWBucketInfo& bucket_info, + AppendObjectProcessor(Aio *aio, rgw::sal::RGWRadosStore *store, + rgw::sal::RGWBucket* bucket, const rgw_placement_rule *ptail_placement_rule, - const rgw_user& owner, RGWObjectCtx& obj_ctx,const rgw_obj& head_obj, + const rgw_user& owner, RGWObjectCtx& obj_ctx, + rgw_obj head_obj, const std::string& unique_tag, uint64_t position, uint64_t *cur_accounted_size, const DoutPrefixProvider *dpp, optional_yield y) - : ManifestObjectProcessor(aio, store, bucket_info, ptail_placement_rule, + : ManifestObjectProcessor(aio, store, bucket, ptail_placement_rule, owner, obj_ctx, head_obj, dpp, y), position(position), cur_size(0), cur_accounted_size(cur_accounted_size), unique_tag(unique_tag), cur_manifest(nullptr) diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index abbb5946254c..07bc831fccd8 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -2725,22 +2725,27 @@ int RGWRados::on_last_entry_in_listing(RGWBucketInfo& bucket_info, return 0; } +bool RGWRados::swift_versioning_enabled(rgw::sal::RGWBucket* bucket) const +{ + return bucket->get_info().has_swift_versioning() && + bucket->get_info().swift_ver_location.size(); +} int RGWRados::swift_versioning_copy(RGWObjectCtx& obj_ctx, const rgw_user& user, - RGWBucketInfo& bucket_info, - rgw_obj& obj, + rgw::sal::RGWBucket* bucket, + rgw::sal::RGWObject* obj, const DoutPrefixProvider *dpp, optional_yield y) { - if (! swift_versioning_enabled(bucket_info)) { + if (! swift_versioning_enabled(bucket)) { return 0; } - obj_ctx.set_atomic(obj); + obj->set_atomic(&obj_ctx); RGWObjState * state = nullptr; - int r = get_obj_state(&obj_ctx, bucket_info, obj, &state, false, y); + int r = get_obj_state(&obj_ctx, bucket->get_info(), obj->get_obj(), &state, false, y); if (r < 0) { return r; } @@ -2749,7 +2754,7 @@ int RGWRados::swift_versioning_copy(RGWObjectCtx& obj_ctx, return 0; } - const string& src_name = obj.get_oid(); + const string& src_name = obj->get_oid(); char buf[src_name.size() + 32]; struct timespec ts = ceph::real_clock::to_timespec(state->mtime); snprintf(buf, sizeof(buf), "%03x%s/%lld.%06ld", (int)src_name.size(), @@ -2757,7 +2762,7 @@ int RGWRados::swift_versioning_copy(RGWObjectCtx& obj_ctx, RGWBucketInfo dest_bucket_info; - r = get_bucket_info(&svc, bucket_info.bucket.tenant, bucket_info.swift_ver_location, dest_bucket_info, NULL, null_yield, NULL); + r = get_bucket_info(&svc, bucket->get_tenant(), bucket->get_info().swift_ver_location, dest_bucket_info, NULL, null_yield, NULL); if (r < 0) { ldout(cct, 10) << "failed to read dest bucket info: r=" << r << dendl; if (r == -ENOENT) { @@ -2766,17 +2771,18 @@ int RGWRados::swift_versioning_copy(RGWObjectCtx& obj_ctx, return r; } - if (dest_bucket_info.owner != bucket_info.owner) { + if (dest_bucket_info.owner != bucket->get_info().owner) { return -ERR_PRECONDITION_FAILED; } - rgw_obj dest_obj(dest_bucket_info.bucket, buf); + rgw::sal::RGWRadosBucket dest_bucket(store, dest_bucket_info); + rgw::sal::RGWRadosObject dest_obj(store, rgw_obj_key(buf), &dest_bucket); if (dest_bucket_info.versioning_enabled()){ - gen_rand_obj_instance_name(&dest_obj); + dest_obj.gen_rand_obj_instance_name(); } - obj_ctx.set_atomic(dest_obj); + dest_obj.set_atomic(&obj_ctx); rgw_zone_id no_zone; @@ -2784,11 +2790,11 @@ int RGWRados::swift_versioning_copy(RGWObjectCtx& obj_ctx, user, NULL, /* req_info *info */ no_zone, - dest_obj, + &dest_obj, obj, - dest_bucket_info, - bucket_info, - bucket_info.placement_rule, + &dest_bucket, + bucket, + bucket->get_placement_rule(), NULL, /* time_t *src_mtime */ NULL, /* time_t *mtime */ NULL, /* const time_t *mod_ptr */ @@ -2820,21 +2826,21 @@ int RGWRados::swift_versioning_copy(RGWObjectCtx& obj_ctx, int RGWRados::swift_versioning_restore(RGWObjectCtx& obj_ctx, const rgw_user& user, - RGWBucketInfo& bucket_info, - rgw_obj& obj, + rgw::sal::RGWBucket* bucket, + rgw::sal::RGWObject* obj, bool& restored, /* out */ const DoutPrefixProvider *dpp) { - if (! swift_versioning_enabled(bucket_info)) { + if (! swift_versioning_enabled(bucket)) { return 0; } /* Bucket info of the bucket that stores previous versions of our object. */ RGWBucketInfo archive_binfo; - int ret = get_bucket_info(&svc, bucket_info.bucket.tenant, - bucket_info.swift_ver_location, archive_binfo, - nullptr, null_yield, nullptr); + int ret = get_bucket_info(&svc, bucket->get_tenant(), + bucket->get_info().swift_ver_location, + archive_binfo, nullptr, null_yield, nullptr); if (ret < 0) { return ret; } @@ -2844,7 +2850,7 @@ int RGWRados::swift_versioning_restore(RGWObjectCtx& obj_ctx, * into consideration. For we can live with that. * * TODO: delegate this check to un upper layer and compare with ACLs. */ - if (bucket_info.owner != archive_binfo.owner) { + if (bucket->get_info().owner != archive_binfo.owner) { return -EPERM; } @@ -2865,24 +2871,25 @@ int RGWRados::swift_versioning_restore(RGWObjectCtx& obj_ctx, * irrelevant and may be safely skipped. */ std::map no_attrs; - rgw_obj archive_obj(archive_binfo.bucket, entry.key); + rgw::sal::RGWRadosBucket archive_bucket(store, archive_binfo); + rgw::sal::RGWRadosObject archive_obj(store, entry.key, &archive_bucket); - if (bucket_info.versioning_enabled()){ - gen_rand_obj_instance_name(&obj); + if (bucket->versioning_enabled()){ + obj->gen_rand_obj_instance_name(); } - obj_ctx.set_atomic(archive_obj); - obj_ctx.set_atomic(obj); + archive_obj.set_atomic(&obj_ctx); + obj->set_atomic(&obj_ctx); int ret = copy_obj(obj_ctx, user, nullptr, /* req_info *info */ no_zone, obj, /* dest obj */ - archive_obj, /* src obj */ - bucket_info, /* dest bucket info */ - archive_binfo, /* src bucket info */ - bucket_info.placement_rule, /* placement_rule */ + &archive_obj, /* src obj */ + bucket, /* dest bucket info */ + &archive_bucket, /* src bucket info */ + bucket->get_placement_rule(), /* placement_rule */ nullptr, /* time_t *src_mtime */ nullptr, /* time_t *mtime */ nullptr, /* const time_t *mod_ptr */ @@ -2914,13 +2921,13 @@ int RGWRados::swift_versioning_restore(RGWObjectCtx& obj_ctx, } /* Need to remove the archived copy. */ - ret = delete_obj(obj_ctx, archive_binfo, archive_obj, + ret = delete_obj(obj_ctx, archive_binfo, archive_obj.get_obj(), archive_binfo.versioning_status()); return ret; }; - const std::string& obj_name = obj.get_oid(); + const std::string& obj_name = obj->get_oid(); const auto prefix = boost::str(boost::format("%03x%s") % obj_name.size() % obj_name); @@ -3487,31 +3494,12 @@ static void set_copy_attrs(map& src_attrs, } } -int RGWRados::rewrite_obj(RGWBucketInfo& dest_bucket_info, const rgw_obj& obj, const DoutPrefixProvider *dpp, optional_yield y) +int RGWRados::rewrite_obj(RGWBucketInfo& dest_bucket_info, rgw::sal::RGWObject* obj, const DoutPrefixProvider *dpp, optional_yield y) { - map attrset; - - real_time mtime; - uint64_t obj_size; RGWObjectCtx rctx(this->store); + rgw::sal::RGWRadosBucket bucket(store, dest_bucket_info); - RGWRados::Object op_target(this, dest_bucket_info, rctx, obj); - RGWRados::Object::Read read_op(&op_target); - - read_op.params.attrs = &attrset; - read_op.params.lastmod = &mtime; - read_op.params.obj_size = &obj_size; - - int ret = read_op.prepare(y); - if (ret < 0) - return ret; - - attrset.erase(RGW_ATTR_ID_TAG); - attrset.erase(RGW_ATTR_TAIL_TAG); - - return copy_obj_data(rctx, dest_bucket_info, dest_bucket_info.placement_rule, - read_op, obj_size - 1, obj, NULL, mtime, attrset, - 0, real_time(), NULL, dpp, y); + return obj->copy_obj_data(rctx, &bucket, obj, 0, NULL, dpp, y); } struct obj_time_weight { @@ -3612,7 +3600,7 @@ int RGWRados::stat_remote_obj(RGWObjectCtx& obj_ctx, const rgw_user& user_id, req_info *info, const rgw_zone_id& source_zone, - rgw_obj& src_obj, + rgw::sal::RGWObject* src_obj, const RGWBucketInfo *src_bucket_info, real_time *src_mtime, uint64_t *psize, @@ -3749,10 +3737,10 @@ int RGWRados::fetch_remote_obj(RGWObjectCtx& obj_ctx, const rgw_user& user_id, req_info *info, const rgw_zone_id& source_zone, - const rgw_obj& dest_obj, - const rgw_obj& src_obj, - const RGWBucketInfo& dest_bucket_info, - const RGWBucketInfo *src_bucket_info, + rgw::sal::RGWObject* dest_obj, + rgw::sal::RGWObject* src_obj, + rgw::sal::RGWBucket* dest_bucket, + rgw::sal::RGWBucket* src_bucket, std::optional dest_placement_rule, real_time *src_mtime, real_time *mtime, @@ -3788,17 +3776,17 @@ int RGWRados::fetch_remote_obj(RGWObjectCtx& obj_ctx, rgw::BlockingAioThrottle aio(cct->_conf->rgw_put_obj_min_window_size); using namespace rgw::putobj; - AtomicObjectProcessor processor(&aio, this->store, dest_bucket_info, nullptr, user_id, - obj_ctx, dest_obj, olh_epoch, tag, dpp, null_yield); + AtomicObjectProcessor processor(&aio, this->store, dest_bucket, nullptr, user_id, + obj_ctx, dest_obj->get_obj(), olh_epoch, tag, dpp, null_yield); RGWRESTConn *conn; auto& zone_conn_map = svc.zone->get_zone_conn_map(); auto& zonegroup_conn_map = svc.zone->get_zonegroup_conn_map(); if (source_zone.empty()) { - if (!src_bucket_info || src_bucket_info->zonegroup.empty()) { + if (!src_bucket || src_bucket->get_info().zonegroup.empty()) { /* source is in the master zonegroup */ conn = svc.zone->get_master_conn(); } else { - map::iterator iter = zonegroup_conn_map.find(src_bucket_info->zonegroup); + map::iterator iter = zonegroup_conn_map.find(src_bucket->get_info().zonegroup); if (iter == zonegroup_conn_map.end()) { ldout(cct, 0) << "could not find zonegroup connection to zonegroup: " << source_zone << dendl; return -ENOENT; @@ -3829,8 +3817,8 @@ int RGWRados::fetch_remote_obj(RGWObjectCtx& obj_ctx, const rgw_placement_rule *ptail_rule; int ret = filter->filter(cct, - src_obj.key, - dest_bucket_info, + src_obj->get_key(), + dest_bucket->get_info(), dest_placement_rule, obj_attrs, &override_owner, @@ -3870,7 +3858,7 @@ int RGWRados::fetch_remote_obj(RGWObjectCtx& obj_ctx, if (copy_if_newer) { /* need to get mtime for destination */ - ret = get_obj_state(&obj_ctx, dest_bucket_info, dest_obj, &dest_state, false, null_yield); + ret = get_obj_state(&obj_ctx, dest_bucket->get_info(), dest_obj->get_obj(), &dest_state, false, null_yield); if (ret < 0) goto set_err_state; @@ -4035,8 +4023,8 @@ int RGWRados::fetch_remote_obj(RGWObjectCtx& obj_ctx, if (copy_if_newer && canceled) { ldout(cct, 20) << "raced with another write of obj: " << dest_obj << dendl; - obj_ctx.invalidate(dest_obj); /* object was overwritten */ - ret = get_obj_state(&obj_ctx, dest_bucket_info, dest_obj, &dest_state, false, null_yield); + obj_ctx.invalidate(dest_obj->get_obj()); /* object was overwritten */ + ret = get_obj_state(&obj_ctx, dest_bucket->get_info(), dest_obj->get_obj(), &dest_state, false, null_yield); if (ret < 0) { ldout(cct, 0) << "ERROR: " << __func__ << ": get_err_state() returned ret=" << ret << dendl; goto set_err_state; @@ -4070,7 +4058,7 @@ set_err_state: // for OP_LINK_OLH to call set_olh() with a real olh_epoch if (olh_epoch && *olh_epoch > 0) { constexpr bool log_data_change = true; - ret = set_olh(obj_ctx, dest_bucket_info, dest_obj, false, nullptr, + ret = set_olh(obj_ctx, dest_bucket->get_info(), dest_obj->get_obj(), false, nullptr, *olh_epoch, real_time(), false, null_yield, zones_trace, log_data_change); } else { // we already have the latest copy @@ -4085,7 +4073,7 @@ int RGWRados::copy_obj_to_remote_dest(RGWObjState *astate, map& src_attrs, RGWRados::Object::Read& read_op, const rgw_user& user_id, - rgw_obj& dest_obj, + rgw::sal::RGWObject* dest_obj, real_time *mtime) { string etag; @@ -4131,10 +4119,10 @@ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx, const rgw_user& user_id, req_info *info, const rgw_zone_id& source_zone, - rgw_obj& dest_obj, - rgw_obj& src_obj, - RGWBucketInfo& dest_bucket_info, - RGWBucketInfo& src_bucket_info, + rgw::sal::RGWObject* dest_obj, + rgw::sal::RGWObject* src_obj, + rgw::sal::RGWBucket* dest_bucket, + rgw::sal::RGWBucket* src_bucket, const rgw_placement_rule& dest_placement, real_time *src_mtime, real_time *mtime, @@ -4159,30 +4147,30 @@ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx, { int ret; uint64_t obj_size; - rgw_obj shadow_obj = dest_obj; + rgw_obj shadow_obj = dest_obj->get_obj(); string shadow_oid; bool remote_src; bool remote_dest; - append_rand_alpha(cct, dest_obj.get_oid(), shadow_oid, 32); - shadow_obj.init_ns(dest_obj.bucket, shadow_oid, shadow_ns); + append_rand_alpha(cct, dest_obj->get_oid(), shadow_oid, 32); + shadow_obj.init_ns(dest_obj->get_bucket()->get_bi(), shadow_oid, shadow_ns); auto& zonegroup = svc.zone->get_zonegroup(); - remote_dest = !zonegroup.equals(dest_bucket_info.zonegroup); - remote_src = !zonegroup.equals(src_bucket_info.zonegroup); + remote_dest = !zonegroup.equals(dest_bucket->get_info().zonegroup); + remote_src = !zonegroup.equals(src_bucket->get_info().zonegroup); if (remote_src && remote_dest) { ldpp_dout(dpp, 0) << "ERROR: can't copy object when both src and dest buckets are remote" << dendl; return -EINVAL; } - ldpp_dout(dpp, 5) << "Copy object " << src_obj.bucket << ":" << src_obj.get_oid() << " => " << dest_obj.bucket << ":" << dest_obj.get_oid() << dendl; + ldpp_dout(dpp, 5) << "Copy object " << src_obj->get_bucket() << ":" << src_obj->get_oid() << " => " << dest_obj->get_bucket() << ":" << dest_obj->get_oid() << dendl; if (remote_src || !source_zone.empty()) { return fetch_remote_obj(obj_ctx, user_id, info, source_zone, - dest_obj, src_obj, dest_bucket_info, &src_bucket_info, + dest_obj, src_obj, dest_bucket, src_bucket, dest_placement, src_mtime, mtime, mod_ptr, unmod_ptr, high_precision_time, if_match, if_nomatch, attrs_mod, copy_if_newer, attrs, category, @@ -4191,7 +4179,7 @@ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx, } map src_attrs; - RGWRados::Object src_op_target(this, src_bucket_info, obj_ctx, src_obj); + RGWRados::Object src_op_target(this, src_bucket->get_info(), obj_ctx, src_obj->get_obj()); RGWRados::Object::Read read_op(&src_op_target); read_op.conds.mod_ptr = mod_ptr; @@ -4231,7 +4219,7 @@ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx, RGWObjManifest manifest; RGWObjState *astate = NULL; - ret = get_obj_state(&obj_ctx, src_bucket_info, src_obj, &astate, y); + ret = get_obj_state(&obj_ctx, src_bucket->get_info(), src_obj->get_obj(), &astate, y); if (ret < 0) { return ret; } @@ -4244,9 +4232,9 @@ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx, } uint64_t max_chunk_size; - ret = get_max_chunk_size(dest_bucket_info.placement_rule, dest_obj, &max_chunk_size); + ret = get_max_chunk_size(dest_bucket->get_placement_rule(), dest_obj->get_obj(), &max_chunk_size); if (ret < 0) { - ldpp_dout(dpp, 0) << "ERROR: failed to get max_chunk_size() for bucket " << dest_obj.bucket << dendl; + ldpp_dout(dpp, 0) << "ERROR: failed to get max_chunk_size() for bucket " << dest_obj->get_bucket() << dendl; return ret; } @@ -4261,15 +4249,15 @@ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx, } if (!src_rule || src_rule->empty()) { - src_rule = &src_bucket_info.placement_rule; + src_rule = &src_bucket->get_placement_rule(); } - if (!get_obj_data_pool(*src_rule, src_obj, &src_pool)) { + if (!get_obj_data_pool(*src_rule, src_obj->get_obj(), &src_pool)) { ldpp_dout(dpp, 0) << "ERROR: failed to locate data pool for " << src_obj << dendl; return -EIO; } - if (!get_obj_data_pool(dest_placement, dest_obj, &dest_pool)) { + if (!get_obj_data_pool(dest_placement, dest_obj->get_obj(), &dest_pool)) { ldpp_dout(dpp, 0) << "ERROR: failed to locate data pool for " << dest_obj << dendl; return -EIO; } @@ -4307,7 +4295,7 @@ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx, if (copy_data) { /* refcounting tail wouldn't work here, just copy the data */ attrs.erase(RGW_ATTR_TAIL_TAG); - return copy_obj_data(obj_ctx, dest_bucket_info, dest_placement, read_op, obj_size - 1, dest_obj, + return copy_obj_data(obj_ctx, dest_bucket, dest_placement, read_op, obj_size - 1, dest_obj, mtime, real_time(), attrs, olh_epoch, delete_at, petag, dpp, y); } @@ -4329,7 +4317,7 @@ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx, RGWObjManifest *pmanifest; ldpp_dout(dpp, 20) << "dest_obj=" << dest_obj << " src_obj=" << src_obj << " copy_itself=" << (int)copy_itself << dendl; - RGWRados::Object dest_op_target(this, dest_bucket_info, obj_ctx, dest_obj); + RGWRados::Object dest_op_target(this, dest_bucket->get_info(), obj_ctx, dest_obj->get_obj()); RGWRados::Object::Write write_op(&dest_op_target); string tag; @@ -4347,7 +4335,7 @@ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx, manifest = *astate->manifest; const rgw_bucket_placement& tail_placement = manifest.get_tail_placement(); if (tail_placement.bucket.name.empty()) { - manifest.set_tail_placement(tail_placement.placement_rule, src_obj.bucket); + manifest.set_tail_placement(tail_placement.placement_rule, src_obj->get_bucket()->get_bi()); } string ref_tag; for (; miter != astate->manifest->obj_end(); ++miter) { @@ -4380,15 +4368,15 @@ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx, goto done_ret; } - pmanifest->set_head(dest_bucket_info.placement_rule, dest_obj, first_chunk.length()); + pmanifest->set_head(dest_bucket->get_placement_rule(), dest_obj->get_obj(), first_chunk.length()); } else { - pmanifest->set_head(dest_bucket_info.placement_rule, dest_obj, 0); + pmanifest->set_head(dest_bucket->get_placement_rule(), dest_obj->get_obj(), 0); } write_op.meta.data = &first_chunk; write_op.meta.manifest = pmanifest; write_op.meta.ptag = &tag; - write_op.meta.owner = dest_bucket_info.owner; + write_op.meta.owner = dest_bucket->get_info().owner; write_op.meta.mtime = mtime; write_op.meta.flags = PUT_OBJ_CREATE; write_op.meta.category = category; @@ -4426,10 +4414,10 @@ done_ret: int RGWRados::copy_obj_data(RGWObjectCtx& obj_ctx, - RGWBucketInfo& dest_bucket_info, + rgw::sal::RGWBucket* bucket, const rgw_placement_rule& dest_placement, RGWRados::Object::Read& read_op, off_t end, - const rgw_obj& dest_obj, + rgw::sal::RGWObject* dest_obj, real_time *mtime, real_time set_mtime, map& attrs, @@ -4446,9 +4434,9 @@ int RGWRados::copy_obj_data(RGWObjectCtx& obj_ctx, using namespace rgw::putobj; // do not change the null_yield in the initialization of this AtomicObjectProcessor // it causes crashes in the ragweed tests - AtomicObjectProcessor processor(&aio, this->store, dest_bucket_info, &dest_placement, - dest_bucket_info.owner, obj_ctx, - dest_obj, olh_epoch, tag, dpp, null_yield); + AtomicObjectProcessor processor(&aio, this->store, bucket, &dest_placement, + bucket->get_info().owner, obj_ctx, + dest_obj->get_obj(), olh_epoch, tag, dpp, null_yield); int ret = processor.prepare(y); if (ret < 0) return ret; @@ -4506,8 +4494,8 @@ int RGWRados::copy_obj_data(RGWObjectCtx& obj_ctx, } int RGWRados::transition_obj(RGWObjectCtx& obj_ctx, - RGWBucketInfo& bucket_info, - rgw_obj& obj, + rgw::sal::RGWBucket* bucket, + rgw::sal::RGWObject& obj, const rgw_placement_rule& placement_rule, const real_time& mtime, uint64_t olh_epoch, @@ -4518,9 +4506,8 @@ int RGWRados::transition_obj(RGWObjectCtx& obj_ctx, real_time read_mtime; uint64_t obj_size; - obj_ctx.set_atomic(obj); - - RGWRados::Object op_target(this, bucket_info, obj_ctx, obj); + obj.set_atomic(&obj_ctx); + RGWRados::Object op_target(this, bucket->get_info(), obj_ctx, obj.get_obj()); RGWRados::Object::Read read_op(&op_target); read_op.params.attrs = &attrs; @@ -4541,11 +4528,11 @@ int RGWRados::transition_obj(RGWObjectCtx& obj_ctx, attrs.erase(RGW_ATTR_TAIL_TAG); ret = copy_obj_data(obj_ctx, - bucket_info, + bucket, placement_rule, read_op, obj_size - 1, - obj, + &obj, nullptr /* pmtime */, mtime, attrs, @@ -8393,7 +8380,7 @@ int RGWRados::cls_bucket_list_ordered(RGWBucketInfo& bucket_info, }; // ShardTracker // add the next unique candidate, or return false if we reach the end - auto next_candidate = [] (ShardTracker& t, + auto next_candidate = [] (CephContext *cct, ShardTracker& t, std::map& candidates, size_t tracker_idx) { while (!t.at_end()) { @@ -8429,7 +8416,7 @@ int RGWRados::cls_bucket_list_ordered(RGWBucketInfo& bucket_info, // it's important that the values in the map refer to the index // into the results_trackers vector, which may not be the same // as the shard number (i.e., when not all shards are requested) - next_candidate(t, candidates, tracker_idx); + next_candidate(cct, t, candidates, tracker_idx); ++tracker_idx; } @@ -8489,7 +8476,7 @@ int RGWRados::cls_bucket_list_ordered(RGWBucketInfo& bucket_info, candidates.erase(candidates.begin()); tracker.advance(); - next_candidate(tracker, candidates, tracker_idx); + next_candidate(cct, tracker, candidates, tracker_idx); if (tracker.at_end() && tracker.is_truncated()) { // once we exhaust one shard that is truncated, we need to stop, diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h index afd06cc53b23..c12404c1090d 100644 --- a/src/rgw/rgw_rados.h +++ b/src/rgw/rgw_rados.h @@ -1051,28 +1051,25 @@ public: const std::string& obj_delim, std::function handler); - bool swift_versioning_enabled(const RGWBucketInfo& bucket_info) const { - return bucket_info.has_swift_versioning() && - bucket_info.swift_ver_location.size(); - } + bool swift_versioning_enabled(rgw::sal::RGWBucket* bucket) const; int swift_versioning_copy(RGWObjectCtx& obj_ctx, /* in/out */ const rgw_user& user, /* in */ - RGWBucketInfo& bucket_info, /* in */ - rgw_obj& obj, /* in */ + rgw::sal::RGWBucket* bucket, /* in */ + rgw::sal::RGWObject* obj, /* in */ const DoutPrefixProvider *dpp, /* in/out */ optional_yield y); /* in */ int swift_versioning_restore(RGWObjectCtx& obj_ctx, /* in/out */ const rgw_user& user, /* in */ - RGWBucketInfo& bucket_info, /* in */ - rgw_obj& obj, /* in */ + rgw::sal::RGWBucket* bucket, /* in */ + rgw::sal::RGWObject* obj, /* in */ bool& restored, /* out */ const DoutPrefixProvider *dpp); /* in/out */ int copy_obj_to_remote_dest(RGWObjState *astate, map& src_attrs, RGWRados::Object::Read& read_op, const rgw_user& user_id, - rgw_obj& dest_obj, + rgw::sal::RGWObject* dest_obj, ceph::real_time *mtime); enum AttrsMod { @@ -1081,13 +1078,13 @@ public: ATTRSMOD_MERGE = 2 }; - int rewrite_obj(RGWBucketInfo& dest_bucket_info, const rgw_obj& obj, const DoutPrefixProvider *dpp, optional_yield y); + int rewrite_obj(RGWBucketInfo& dest_bucket_info, rgw::sal::RGWObject* obj, const DoutPrefixProvider *dpp, optional_yield y); int stat_remote_obj(RGWObjectCtx& obj_ctx, const rgw_user& user_id, req_info *info, const rgw_zone_id& source_zone, - rgw_obj& src_obj, + rgw::sal::RGWObject* src_obj, const RGWBucketInfo *src_bucket_info, real_time *src_mtime, uint64_t *psize, @@ -1106,10 +1103,10 @@ public: const rgw_user& user_id, req_info *info, const rgw_zone_id& source_zone, - const rgw_obj& dest_obj, - const rgw_obj& src_obj, - const RGWBucketInfo& dest_bucket_info, - const RGWBucketInfo *src_bucket_info, + rgw::sal::RGWObject* dest_obj, + rgw::sal::RGWObject* src_obj, + rgw::sal::RGWBucket* dest_bucket, + rgw::sal::RGWBucket* src_bucket, std::optional dest_placement, ceph::real_time *src_mtime, ceph::real_time *mtime, @@ -1150,10 +1147,10 @@ public: const rgw_user& user_id, req_info *info, const rgw_zone_id& source_zone, - rgw_obj& dest_obj, - rgw_obj& src_obj, - RGWBucketInfo& dest_bucket_info, - RGWBucketInfo& src_bucket_info, + rgw::sal::RGWObject* dest_obj, + rgw::sal::RGWObject* src_obj, + rgw::sal::RGWBucket* dest_bucket, + rgw::sal::RGWBucket* src_bucket, const rgw_placement_rule& dest_placement, ceph::real_time *src_mtime, ceph::real_time *mtime, @@ -1177,10 +1174,10 @@ public: optional_yield y); int copy_obj_data(RGWObjectCtx& obj_ctx, - RGWBucketInfo& dest_bucket_info, + rgw::sal::RGWBucket* bucket, const rgw_placement_rule& dest_placement, RGWRados::Object::Read& read_op, off_t end, - const rgw_obj& dest_obj, + rgw::sal::RGWObject* dest_obj, ceph::real_time *mtime, ceph::real_time set_mtime, map& attrs, @@ -1191,8 +1188,8 @@ public: optional_yield y); int transition_obj(RGWObjectCtx& obj_ctx, - RGWBucketInfo& bucket_info, - rgw_obj& obj, + rgw::sal::RGWBucket* bucket, + rgw::sal::RGWObject& obj, const rgw_placement_rule& placement_rule, const real_time& mtime, uint64_t olh_epoch, @@ -1220,12 +1217,12 @@ public: /** Delete an object.*/ int delete_obj(RGWObjectCtx& obj_ctx, - const RGWBucketInfo& bucket_owner, - const rgw_obj& src_obj, - int versioning_status, - uint16_t bilog_flags = 0, - const ceph::real_time& expiration_time = ceph::real_time(), - rgw_zone_set *zones_trace = nullptr); + const RGWBucketInfo& bucket_owner, + const rgw_obj& src_obj, + int versioning_status, + uint16_t bilog_flags = 0, + const ceph::real_time& expiration_time = ceph::real_time(), + rgw_zone_set *zones_trace = nullptr); int delete_raw_obj(const rgw_raw_obj& obj); diff --git a/src/rgw/rgw_rest.cc b/src/rgw/rgw_rest.cc index 19ed78eeb671..55bc28ba05db 100644 --- a/src/rgw/rgw_rest.cc +++ b/src/rgw/rgw_rest.cc @@ -566,9 +566,9 @@ void end_header(struct req_state* s, RGWOp* op, const char *content_type, dump_trans_id(s); - if ((!s->is_err()) && - (s->bucket_info.owner != s->user->get_id()) && - (s->bucket_info.requester_pays)) { + if ((!s->is_err()) && s->bucket && + (s->bucket->get_info().owner != s->user->get_id()) && + (s->bucket->get_info().requester_pays)) { dump_header(s, "x-amz-request-charged", "requester"); } @@ -1022,7 +1022,7 @@ int RGWPutObj_ObjStore::get_params() { return ret; } - torrent.set_info_name((s->object).name); + torrent.set_info_name(s->object->get_name()); } /* end gettorrent */ supplied_md5_b64 = s->info.env->get("HTTP_CONTENT_MD5"); @@ -1626,7 +1626,7 @@ int RGWDeleteMultiObj_ObjStore::get_params() } // everything is probably fine, set the bucket - bucket = s->bucket; + bucket = s->bucket.get(); const auto max_size = s->cct->_conf->rgw_max_put_param_size; std::tie(op_ret, data) = rgw_rest_read_all_input(s, max_size, false); @@ -2294,7 +2294,7 @@ RGWHandler_REST* RGWREST::get_handler( *pmgr = m; } - RGWHandler_REST* handler = m->get_handler(s, auth_registry, frontend_prefix); + RGWHandler_REST* handler = m->get_handler(store, s, auth_registry, frontend_prefix); if (! handler) { *init_error = -ERR_METHOD_NOT_ALLOWED; return NULL; diff --git a/src/rgw/rgw_rest.h b/src/rgw/rgw_rest.h index 928f8bd82265..754d3ca7dc46 100644 --- a/src/rgw/rgw_rest.h +++ b/src/rgw/rgw_rest.h @@ -639,6 +639,7 @@ public: } virtual RGWHandler_REST* get_handler( + rgw::sal::RGWRadosStore *store, struct req_state* const s, const rgw::auth::StrategyRegistry& auth_registry, const std::string& frontend_prefix diff --git a/src/rgw/rgw_rest_bucket.h b/src/rgw/rgw_rest_bucket.h index d516ea5c54aa..0a7de160c1ef 100644 --- a/src/rgw/rgw_rest_bucket.h +++ b/src/rgw/rgw_rest_bucket.h @@ -27,7 +27,8 @@ public: RGWRESTMgr_Bucket() = default; ~RGWRESTMgr_Bucket() override = default; - RGWHandler_REST* get_handler(struct req_state*, + RGWHandler_REST* get_handler(rgw::sal::RGWRadosStore *store, + struct req_state*, const rgw::auth::StrategyRegistry& auth_registry, const std::string&) override { return new RGWHandler_Bucket(auth_registry); diff --git a/src/rgw/rgw_rest_client.cc b/src/rgw/rgw_rest_client.cc index c9e9729a9f32..4ad08d8acfb3 100644 --- a/src/rgw/rgw_rest_client.cc +++ b/src/rgw/rgw_rest_client.cc @@ -557,17 +557,17 @@ int RGWRESTGenerateHTTPHeaders::sign(RGWAccessKey& key) return 0; } -void RGWRESTStreamS3PutObj::send_init(rgw_obj& obj) +void RGWRESTStreamS3PutObj::send_init(rgw::sal::RGWObject* obj) { string resource_str; string resource; string new_url = url; if (host_style == VirtualStyle) { - resource_str = obj.get_oid(); - new_url = obj.bucket.name + "." + new_url; + resource_str = obj->get_oid(); + new_url = obj->get_bucket()->get_name() + "." + new_url; } else { - resource_str = obj.bucket.name + "/" + obj.get_oid(); + resource_str = obj->get_bucket()->get_name() + "/" + obj->get_oid(); } //do not encode slash in object key name @@ -617,7 +617,7 @@ int RGWRESTStreamS3PutObj::send_ready(RGWAccessKey& key, bool send) return 0; } -int RGWRESTStreamS3PutObj::put_obj_init(RGWAccessKey& key, rgw_obj& obj, uint64_t obj_size, map& attrs, bool send) +int RGWRESTStreamS3PutObj::put_obj_init(RGWAccessKey& key, rgw::sal::RGWObject* obj, uint64_t obj_size, map& attrs, bool send) { send_init(obj); return send_ready(key, attrs, send); diff --git a/src/rgw/rgw_rest_client.h b/src/rgw/rgw_rest_client.h index 1e11e3ae2ae1..2628806ce135 100644 --- a/src/rgw/rgw_rest_client.h +++ b/src/rgw/rgw_rest_client.h @@ -211,13 +211,13 @@ public: out_cb(NULL), new_info(cct, &new_env), headers_gen(_cct, &new_env, &new_info) {} ~RGWRESTStreamS3PutObj() override; - void send_init(rgw_obj& obj); + void send_init(rgw::sal::RGWObject* obj); int send_ready(RGWAccessKey& key, map& rgw_attrs, bool send); int send_ready(RGWAccessKey& key, const map& http_attrs, RGWAccessControlPolicy& policy, bool send); int send_ready(RGWAccessKey& key, bool send); - int put_obj_init(RGWAccessKey& key, rgw_obj& obj, uint64_t obj_size, map& attrs, bool send); + int put_obj_init(RGWAccessKey& key, rgw::sal::RGWObject* obj, uint64_t obj_size, map& attrs, bool send); RGWGetDataCB *get_out_cb() { return out_cb; } }; diff --git a/src/rgw/rgw_rest_config.h b/src/rgw/rgw_rest_config.h index 99c773646963..3fb3e871f4d2 100644 --- a/src/rgw/rgw_rest_config.h +++ b/src/rgw/rgw_rest_config.h @@ -77,7 +77,8 @@ public: RGWRESTMgr_Config() = default; ~RGWRESTMgr_Config() override = default; - RGWHandler_REST* get_handler(struct req_state*, + RGWHandler_REST* get_handler(rgw::sal::RGWRadosStore *, + struct req_state*, const rgw::auth::StrategyRegistry& auth_registry, const std::string&) override { return new RGWHandler_Config(auth_registry); diff --git a/src/rgw/rgw_rest_conn.cc b/src/rgw/rgw_rest_conn.cc index a0fafe90f955..7d70cdb39937 100644 --- a/src/rgw/rgw_rest_conn.cc +++ b/src/rgw/rgw_rest_conn.cc @@ -4,6 +4,7 @@ #include "rgw_rados.h" #include "rgw_zone.h" #include "rgw_rest_conn.h" +#include "rgw_sal.h" #include "services/svc_zone.h" @@ -116,7 +117,7 @@ public: explicit StreamObjData(rgw_obj& _obj) : obj(_obj) {} }; -int RGWRESTConn::put_obj_send_init(rgw_obj& obj, const rgw_http_param_pair *extra_params, RGWRESTStreamS3PutObj **req) +int RGWRESTConn::put_obj_send_init(rgw::sal::RGWObject* obj, const rgw_http_param_pair *extra_params, RGWRESTStreamS3PutObj **req) { string url; int ret = get_url(url); @@ -137,7 +138,7 @@ int RGWRESTConn::put_obj_send_init(rgw_obj& obj, const rgw_http_param_pair *extr return 0; } -int RGWRESTConn::put_obj_async(const rgw_user& uid, rgw_obj& obj, uint64_t obj_size, +int RGWRESTConn::put_obj_async(const rgw_user& uid, rgw::sal::RGWObject* obj, uint64_t obj_size, map& attrs, bool send, RGWRESTStreamS3PutObj **req) { @@ -190,7 +191,7 @@ static void set_header(T val, map& headers, const string& header } -int RGWRESTConn::get_obj(const rgw_user& uid, req_info *info /* optional */, const rgw_obj& obj, +int RGWRESTConn::get_obj(const rgw_user& uid, req_info *info /* optional */, const rgw::sal::RGWObject* obj, const real_time *mod_ptr, const real_time *unmod_ptr, uint32_t mod_zone_id, uint64_t mod_pg_ver, bool prepend_metadata, bool get_op, bool rgwx_stat, @@ -211,7 +212,7 @@ int RGWRESTConn::get_obj(const rgw_user& uid, req_info *info /* optional */, con return get_obj(obj, params, send, req); } -int RGWRESTConn::get_obj(const rgw_obj& obj, const get_obj_params& in_params, bool send, RGWRESTStreamRWRequest **req) +int RGWRESTConn::get_obj(const rgw::sal::RGWObject* obj, const get_obj_params& in_params, bool send, RGWRESTStreamRWRequest **req) { string url; int ret = get_url(url); @@ -232,8 +233,8 @@ int RGWRESTConn::get_obj(const rgw_obj& obj, const get_obj_params& in_params, bo if (in_params.skip_decrypt) { params.push_back(param_pair_t(RGW_SYS_PARAM_PREFIX "skip-decrypt", "")); } - if (!obj.key.instance.empty()) { - const string& instance = obj.key.instance; + if (!obj->get_instance().empty()) { + const string& instance = obj->get_instance(); params.push_back(param_pair_t("versionId", instance)); } if (in_params.get_op) { @@ -274,7 +275,7 @@ int RGWRESTConn::get_obj(const rgw_obj& obj, const get_obj_params& in_params, bo set_header(buf, extra_headers, "RANGE"); } - int r = (*req)->send_prepare(key, extra_headers, obj); + int r = (*req)->send_prepare(key, extra_headers, obj->get_obj()); if (r < 0) { goto done_err; } diff --git a/src/rgw/rgw_rest_conn.h b/src/rgw/rgw_rest_conn.h index 5cbd3579a087..186f63eca9cd 100644 --- a/src/rgw/rgw_rest_conn.h +++ b/src/rgw/rgw_rest_conn.h @@ -113,8 +113,8 @@ public: /* async requests */ - int put_obj_send_init(rgw_obj& obj, const rgw_http_param_pair *extra_params, RGWRESTStreamS3PutObj **req); - int put_obj_async(const rgw_user& uid, rgw_obj& obj, uint64_t obj_size, + int put_obj_send_init(rgw::sal::RGWObject* obj, const rgw_http_param_pair *extra_params, RGWRESTStreamS3PutObj **req); + int put_obj_async(const rgw_user& uid, rgw::sal::RGWObject* obj, uint64_t obj_size, map& attrs, bool send, RGWRESTStreamS3PutObj **req); int complete_request(RGWRESTStreamS3PutObj *req, string& etag, ceph::real_time *mtime); @@ -143,9 +143,9 @@ public: uint64_t range_end{0}; }; - int get_obj(const rgw_obj& obj, const get_obj_params& params, bool send, RGWRESTStreamRWRequest **req); + int get_obj(const rgw::sal::RGWObject* obj, const get_obj_params& params, bool send, RGWRESTStreamRWRequest **req); - int get_obj(const rgw_user& uid, req_info *info /* optional */, const rgw_obj& obj, + int get_obj(const rgw_user& uid, req_info *info /* optional */, const rgw::sal::RGWObject* obj, const ceph::real_time *mod_ptr, const ceph::real_time *unmod_ptr, uint32_t mod_zone_id, uint64_t mod_pg_ver, bool prepend_metadata, bool get_op, bool rgwx_stat, bool sync_manifest, diff --git a/src/rgw/rgw_rest_iam.cc b/src/rgw/rgw_rest_iam.cc index 4f56d6334a0d..a6cce4f7191a 100644 --- a/src/rgw/rgw_rest_iam.cc +++ b/src/rgw/rgw_rest_iam.cc @@ -144,9 +144,10 @@ int RGWHandler_REST_IAM::init_from_header(struct req_state* s, } RGWHandler_REST* -RGWRESTMgr_IAM::get_handler(struct req_state* const s, - const rgw::auth::StrategyRegistry& auth_registry, - const std::string& frontend_prefix) +RGWRESTMgr_IAM::get_handler(rgw::sal::RGWRadosStore *store, + struct req_state* const s, + const rgw::auth::StrategyRegistry& auth_registry, + const std::string& frontend_prefix) { return new RGWHandler_REST_IAM(auth_registry); } diff --git a/src/rgw/rgw_rest_iam.h b/src/rgw/rgw_rest_iam.h index 30e0304c37a0..1c6a0e89d322 100644 --- a/src/rgw/rgw_rest_iam.h +++ b/src/rgw/rgw_rest_iam.h @@ -39,7 +39,8 @@ public: return this; } - RGWHandler_REST* get_handler(struct req_state*, + RGWHandler_REST* get_handler(rgw::sal::RGWRadosStore *store, + struct req_state*, const rgw::auth::StrategyRegistry&, const std::string&) override; }; diff --git a/src/rgw/rgw_rest_log.h b/src/rgw/rgw_rest_log.h index fa2897802bca..62d0ba8334dd 100644 --- a/src/rgw/rgw_rest_log.h +++ b/src/rgw/rgw_rest_log.h @@ -298,7 +298,8 @@ public: RGWRESTMgr_Log() = default; ~RGWRESTMgr_Log() override = default; - RGWHandler_REST* get_handler(struct req_state* const, + RGWHandler_REST* get_handler(rgw::sal::RGWRadosStore *store, + struct req_state* const, const rgw::auth::StrategyRegistry& auth_registry, const std::string& frontend_prefixs) override { return new RGWHandler_Log(auth_registry); diff --git a/src/rgw/rgw_rest_metadata.h b/src/rgw/rgw_rest_metadata.h index faabe288e59c..78aabb63fa8d 100644 --- a/src/rgw/rgw_rest_metadata.h +++ b/src/rgw/rgw_rest_metadata.h @@ -95,7 +95,8 @@ public: RGWRESTMgr_Metadata() = default; ~RGWRESTMgr_Metadata() override = default; - RGWHandler_REST* get_handler(struct req_state* const s, + RGWHandler_REST* get_handler(rgw::sal::RGWRadosStore *store, + struct req_state* const s, const rgw::auth::StrategyRegistry& auth_registry, const std::string& frontend_prefix) override { return new RGWHandler_Metadata(auth_registry); diff --git a/src/rgw/rgw_rest_realm.cc b/src/rgw/rgw_rest_realm.cc index 423f9cbf4887..9a14d8d5ff06 100644 --- a/src/rgw/rgw_rest_realm.cc +++ b/src/rgw/rgw_rest_realm.cc @@ -246,7 +246,8 @@ class RGWHandler_Period : public RGWHandler_Auth_S3 { class RGWRESTMgr_Period : public RGWRESTMgr { public: - RGWHandler_REST* get_handler(struct req_state*, + RGWHandler_REST* get_handler(rgw::sal::RGWRadosStore *store, + struct req_state*, const rgw::auth::StrategyRegistry& auth_registry, const std::string&) override { return new RGWHandler_Period(auth_registry); @@ -362,7 +363,8 @@ RGWRESTMgr_Realm::RGWRESTMgr_Realm() } RGWHandler_REST* -RGWRESTMgr_Realm::get_handler(struct req_state*, +RGWRESTMgr_Realm::get_handler(rgw::sal::RGWRadosStore *store, + struct req_state*, const rgw::auth::StrategyRegistry& auth_registry, const std::string&) { diff --git a/src/rgw/rgw_rest_realm.h b/src/rgw/rgw_rest_realm.h index fd4401d9649d..84ee86b48ad9 100644 --- a/src/rgw/rgw_rest_realm.h +++ b/src/rgw/rgw_rest_realm.h @@ -9,7 +9,8 @@ class RGWRESTMgr_Realm : public RGWRESTMgr { public: RGWRESTMgr_Realm(); - RGWHandler_REST* get_handler(struct req_state*, + RGWHandler_REST* get_handler(rgw::sal::RGWRadosStore *store, + struct req_state*, const rgw::auth::StrategyRegistry& auth_registry, const std::string&) override; }; diff --git a/src/rgw/rgw_rest_s3.cc b/src/rgw/rgw_rest_s3.cc index 90c4903b8d8b..3615f781af26 100644 --- a/src/rgw/rgw_rest_s3.cc +++ b/src/rgw/rgw_rest_s3.cc @@ -105,7 +105,7 @@ static inline std::string get_s3_expiration_header( const ceph::real_time& mtime) { return rgw::lc::s3_expiration_header( - s, s->object, s->tagset, mtime, s->bucket_attrs); + s, s->object->get_key(), s->tagset, mtime, s->bucket_attrs); } static inline bool get_s3_multipart_abort_header( @@ -113,7 +113,7 @@ static inline bool get_s3_multipart_abort_header( ceph::real_time& date, std::string& rule_id) { return rgw::lc::s3_multipart_abort_header( - s, s->object, mtime, s->bucket_attrs, date, rule_id); + s, s->object->get_key(), mtime, s->bucket_attrs, date, rule_id); } struct response_attr_param { @@ -1161,8 +1161,8 @@ void RGWGetBucketReplication_ObjStore_S3::send_response_data() ReplicationConfiguration conf; - if (s->bucket_info.sync_policy) { - auto policy = s->bucket_info.sync_policy; + if (s->bucket->get_info().sync_policy) { + auto policy = s->bucket->get_info().sync_policy; auto iter = policy->groups.find(enabled_group_id); if (iter != policy->groups.end()) { @@ -1273,12 +1273,11 @@ void RGWListBuckets_ObjStore_S3::send_response_data(rgw::sal::RGWBucketList& buc if (!sent_data) return; - map& m = buckets.get_buckets(); - map::iterator iter; + auto& m = buckets.get_buckets(); - for (iter = m.begin(); iter != m.end(); ++iter) { - rgw::sal::RGWBucket* obj = iter->second; - dump_bucket(s, *obj); + for (auto iter = m.begin(); iter != m.end(); ++iter) { + auto& bucket = iter->second; + dump_bucket(s, *bucket); } rgw_flush_formatter(s, s->formatter); } @@ -1884,12 +1883,12 @@ void RGWGetBucketLocation_ObjStore_S3::send_response() RGWZoneGroup zonegroup; string api_name; - int ret = store->svc()->zone->get_zonegroup(s->bucket_info.zonegroup, zonegroup); + int ret = store->svc()->zone->get_zonegroup(s->bucket->get_info().zonegroup, zonegroup); if (ret >= 0) { api_name = zonegroup.api_name; } else { - if (s->bucket_info.zonegroup != "default") { - api_name = s->bucket_info.zonegroup; + if (s->bucket->get_info().zonegroup != "default") { + api_name = s->bucket->get_info().zonegroup; } } @@ -2126,7 +2125,7 @@ void RGWGetBucketWebsite_ObjStore_S3::send_response() return; } - RGWBucketWebsiteConf& conf = s->bucket_info.website_conf; + RGWBucketWebsiteConf& conf = s->bucket->get_info().website_conf; s->formatter->open_object_section_in_ns("WebsiteConfiguration", XMLNS_AWS_S3); conf.dump_xml(s->formatter); @@ -2143,7 +2142,7 @@ static void dump_bucket_metadata(struct req_state *s, rgw::sal::RGWBucket* bucke void RGWStatBucket_ObjStore_S3::send_response() { if (op_ret >= 0) { - dump_bucket_metadata(s, bucket); + dump_bucket_metadata(s, bucket.get()); } set_req_state_err(s, op_ret); @@ -2491,7 +2490,7 @@ int RGWPutObj_ObjStore_S3::get_params() } obj_legal_hold = new RGWObjectLegalHold(obj_legal_hold_str); } - if (!s->bucket_info.obj_lock_enabled() && (obj_retention || obj_legal_hold)) { + if (!s->bucket->get_info().obj_lock_enabled() && (obj_retention || obj_legal_hold)) { ldpp_dout(this, 0) << "ERROR: object retention or legal hold can't be set if bucket object lock not configured" << dendl; ret = -ERR_INVALID_REQUEST; return ret; @@ -2604,7 +2603,7 @@ void RGWPutObj_ObjStore_S3::send_response() static inline int get_obj_attrs(rgw::sal::RGWRadosStore *store, struct req_state *s, rgw_obj& obj, map& attrs) { - RGWRados::Object op_target(store->getRados(), s->bucket_info, *static_cast(s->obj_ctx), obj); + RGWRados::Object op_target(store->getRados(), s->bucket->get_info(), *static_cast(s->obj_ctx), obj); RGWRados::Object::Read read_op(&op_target); read_op.params.attrs = &attrs; @@ -2660,9 +2659,9 @@ int RGWPutObj_ObjStore_S3::get_encrypt_filter( { int res = 0; if (!multipart_upload_id.empty()) { - RGWMPObj mp(s->object.name, multipart_upload_id); + RGWMPObj mp(s->object->get_name(), multipart_upload_id); rgw_obj obj; - obj.init_ns(s->bucket, mp.get_meta(), RGW_OBJ_NS_MULTIPART); + obj.init_ns(s->bucket->get_bi(), mp.get_meta(), RGW_OBJ_NS_MULTIPART); obj.set_in_extra_data(true); map xattrs; res = get_obj_attrs(store, s, obj, xattrs); @@ -2687,8 +2686,9 @@ int RGWPutObj_ObjStore_S3::get_encrypt_filter( return res; } -void RGWPostObj_ObjStore_S3::rebuild_key(string& key) +void RGWPostObj_ObjStore_S3::rebuild_key(rgw::sal::RGWObject* obj) { + string key = obj->get_name(); static string var = "${filename}"; int pos = key.find(var); if (pos < 0) @@ -2698,12 +2698,12 @@ void RGWPostObj_ObjStore_S3::rebuild_key(string& key) new_key.append(filename); new_key.append(key.substr(pos + var.size())); - key = new_key; + obj->set_key(new_key); } std::string RGWPostObj_ObjStore_S3::get_current_filename() const { - return s->object.name; + return s->object->get_name(); } std::string RGWPostObj_ObjStore_S3::get_current_content_type() const @@ -2720,9 +2720,9 @@ int RGWPostObj_ObjStore_S3::get_params() map_qs_metadata(s); - ldpp_dout(this, 20) << "adding bucket to policy env: " << s->bucket.name + ldpp_dout(this, 20) << "adding bucket to policy env: " << s->bucket->get_name() << dendl; - env.add_var("bucket", s->bucket.name); + env.add_var("bucket", s->bucket->get_name()); bool done; do { @@ -2780,16 +2780,16 @@ int RGWPostObj_ObjStore_S3::get_params() return -EINVAL; } - s->object = rgw_obj_key(object_str); + s->object = store->get_object(rgw_obj_key(object_str)); - rebuild_key(s->object.name); + rebuild_key(s->object.get()); - if (s->object.empty()) { + if (rgw::sal::RGWObject::empty(s->object.get())) { err_msg = "Empty object name"; return -EINVAL; } - env.add_var("key", s->object.name); + env.add_var("key", s->object->get_name()); part_str(parts, "Content-Type", &content_type); @@ -3111,7 +3111,7 @@ void RGWPostObj_ObjStore_S3::send_response() url_encode(s->bucket_tenant, tenant); /* surely overkill, but cheap */ url_encode(s->bucket_name, bucket); - url_encode(s->object.name, key); + url_encode(s->object->get_name(), key); url_encode(etag_str, etag_url); if (!s->bucket_tenant.empty()) { @@ -3180,16 +3180,16 @@ done: base_uri.c_str(), url_encode(s->bucket_tenant).c_str(), url_encode(s->bucket_name).c_str(), - url_encode(s->object.name).c_str()); + url_encode(s->object->get_name()).c_str()); s->formatter->dump_string("Tenant", s->bucket_tenant); } else { s->formatter->dump_format("Location", "%s/%s/%s", base_uri.c_str(), url_encode(s->bucket_name).c_str(), - url_encode(s->object.name).c_str()); + url_encode(s->object->get_name()).c_str()); } s->formatter->dump_string("Bucket", s->bucket_name); - s->formatter->dump_string("Key", s->object.name); + s->formatter->dump_string("Key", s->object->get_name()); s->formatter->dump_string("ETag", etag); s->formatter->close_section(); } @@ -3287,10 +3287,10 @@ int RGWCopyObj_ObjStore_S3::get_params() src_tenant_name = s->src_tenant_name; src_bucket_name = s->src_bucket_name; - src_object = s->src_object; - dest_tenant_name = s->bucket.tenant; - dest_bucket_name = s->bucket.name; - dest_object = s->object.name; + src_object = s->src_object->clone(); + dest_tenant_name = s->bucket->get_tenant(); + dest_bucket_name = s->bucket->get_name(); + dest_obj_name = s->object->get_name(); if (s->system_request) { source_zone = s->info.args.get(RGW_SYS_PARAM_PREFIX "source-zone"); @@ -3317,8 +3317,8 @@ int RGWCopyObj_ObjStore_S3::get_params() if (source_zone.empty() && (dest_tenant_name.compare(src_tenant_name) == 0) && (dest_bucket_name.compare(src_bucket_name) == 0) && - (dest_object.compare(src_object.name) == 0) && - src_object.instance.empty() && + (dest_obj_name.compare(src_object->get_name()) == 0) && + src_object->get_instance().empty() && (attrs_mod != RGWRados::ATTRSMOD_REPLACE)) { need_to_check_storage_class = true; } @@ -3417,7 +3417,7 @@ int RGWPutACLs_ObjStore_S3::get_policy_from_state(rgw::sal::RGWRadosStore *store RGWAccessControlPolicy_S3 s3policy(s->cct); // bucket-* canned acls do not apply to bucket - if (s->object.empty()) { + if (rgw::sal::RGWObject::empty(s->object.get())) { if (s->canned_acl.find("bucket") != string::npos) s->canned_acl.clear(); } @@ -3750,7 +3750,7 @@ void RGWInitMultipart_ObjStore_S3::send_response() if (!s->bucket_tenant.empty()) s->formatter->dump_string("Tenant", s->bucket_tenant); s->formatter->dump_string("Bucket", s->bucket_name); - s->formatter->dump_string("Key", s->object.name); + s->formatter->dump_string("Key", s->object->get_name()); s->formatter->dump_string("UploadId", upload_id); s->formatter->close_section(); rgw_flush_formatter_and_reset(s, s->formatter); @@ -3792,18 +3792,18 @@ void RGWCompleteMultipart_ObjStore_S3::send_response() base_uri.c_str(), s->bucket_tenant.c_str(), s->bucket_name.c_str(), - s->object.name.c_str() + s->object->get_name().c_str() ); s->formatter->dump_string("Tenant", s->bucket_tenant); } else { s->formatter->dump_format("Location", "%s/%s/%s", base_uri.c_str(), s->bucket_name.c_str(), - s->object.name.c_str() + s->object->get_name().c_str() ); } s->formatter->dump_string("Bucket", s->bucket_name); - s->formatter->dump_string("Key", s->object.name); + s->formatter->dump_string("Key", s->object->get_name()); s->formatter->dump_string("ETag", etag); s->formatter->close_section(); rgw_flush_formatter_and_reset(s, s->formatter); @@ -3845,7 +3845,7 @@ void RGWListMultipart_ObjStore_S3::send_response() if (!s->bucket_tenant.empty()) s->formatter->dump_string("Tenant", s->bucket_tenant); s->formatter->dump_string("Bucket", s->bucket_name); - s->formatter->dump_string("Key", s->object.name); + s->formatter->dump_string("Key", s->object->get_name()); s->formatter->dump_string("UploadId", upload_id); s->formatter->dump_string("StorageClass", "STANDARD"); s->formatter->dump_int("PartNumberMarker", marker); @@ -4138,7 +4138,7 @@ void RGWGetBucketMetaSearch_ObjStore_S3::send_response() Formatter *f = s->formatter; f->open_array_section("GetBucketMetaSearchResult"); - for (auto& e : s->bucket_info.mdsearch_config) { + for (auto& e : s->bucket->get_info().mdsearch_config) { f->open_object_section("Entry"); string k = string("x-amz-meta-") + e.first; f->dump_string("Key", k.c_str()); @@ -4189,7 +4189,7 @@ void RGWGetBucketObjectLock_ObjStore_S3::send_response() if (op_ret) { return; } - encode_xml("ObjectLockConfiguration", s->bucket_info.obj_lock, s->formatter); + encode_xml("ObjectLockConfiguration", s->bucket->get_info().obj_lock, s->formatter); rgw_flush_formatter_and_reset(s, s->formatter); } @@ -4613,9 +4613,10 @@ RGWOp *RGWHandler_REST_Obj_S3::op_options() return new RGWOptionsCORS_ObjStore_S3; } -int RGWHandler_REST_S3::init_from_header(struct req_state* s, - int default_formatter, - bool configurable_format) +int RGWHandler_REST_S3::init_from_header(rgw::sal::RGWRadosStore *store, + struct req_state* s, + int default_formatter, + bool configurable_format) { string req; string first; @@ -4668,10 +4669,18 @@ int RGWHandler_REST_S3::init_from_header(struct req_state* s, s->init_state.url_bucket = first; if (pos >= 0) { string encoded_obj_str = req.substr(pos+1); - s->object = rgw_obj_key(encoded_obj_str, s->info.args.get("versionId")); + if (s->bucket) { + s->object = s->bucket->get_object(rgw_obj_key(encoded_obj_str, s->info.args.get("versionId"))); + } else { + s->object = store->get_object(rgw_obj_key(encoded_obj_str, s->info.args.get("versionId"))); + } } } else { - s->object = rgw_obj_key(req_name, s->info.args.get("versionId")); + if (s->bucket) { + s->object = s->bucket->get_object(rgw_obj_key(req_name, s->info.args.get("versionId"))); + } else { + s->object = store->get_object(rgw_obj_key(req_name, s->info.args.get("versionId"))); + } } return 0; } @@ -4713,15 +4722,15 @@ int RGWHandler_REST_S3::postauth_init() rgw_parse_url_bucket(t->url_bucket, s->user->get_tenant(), s->bucket_tenant, s->bucket_name); - dout(10) << "s->object=" << (!s->object.empty() ? s->object : rgw_obj_key("")) + dout(10) << "s->object=" << s->object << " s->bucket=" << rgw_make_bucket_entry_name(s->bucket_tenant, s->bucket_name) << dendl; int ret; ret = rgw_validate_tenant_name(s->bucket_tenant); if (ret) return ret; - if (!s->bucket_name.empty()) { - ret = validate_object_name(s->object.name); + if (!s->bucket_name.empty() && !rgw::sal::RGWObject::empty(s->object.get())) { + ret = validate_object_name(s->object->get_name()); if (ret) return ret; } @@ -4753,7 +4762,7 @@ int RGWHandler_REST_S3::init(rgw::sal::RGWRadosStore *store, struct req_state *s if (ret) return ret; if (!s->bucket_name.empty()) { - ret = validate_object_name(s->object.name); + ret = validate_object_name(s->object->get_name()); if (ret) return ret; } @@ -4768,14 +4777,16 @@ int RGWHandler_REST_S3::init(rgw::sal::RGWRadosStore *store, struct req_state *s if (copy_source && (! s->info.env->get("HTTP_X_AMZ_COPY_SOURCE_RANGE")) && (! s->info.args.exists("uploadId"))) { + rgw_obj_key key; ret = RGWCopyObj::parse_copy_location(copy_source, s->init_state.src_bucket, - s->src_object); + key); if (!ret) { ldpp_dout(s, 0) << "failed to parse copy location" << dendl; return -EINVAL; // XXX why not -ERR_INVALID_BUCKET_NAME or -ERR_BAD_URL? } + s->src_object = store->get_object(key); } const char *sc = s->info.env->get("HTTP_X_AMZ_STORAGE_CLASS"); @@ -4874,21 +4885,21 @@ int RGW_Auth_S3::authorize(const DoutPrefixProvider *dpp, int RGWHandler_Auth_S3::init(rgw::sal::RGWRadosStore *store, struct req_state *state, rgw::io::BasicClient *cio) { - int ret = RGWHandler_REST_S3::init_from_header(state, RGW_FORMAT_JSON, - true); + int ret = RGWHandler_REST_S3::init_from_header(store, state, RGW_FORMAT_JSON, true); if (ret < 0) return ret; return RGWHandler_REST::init(store, state, cio); } -RGWHandler_REST* RGWRESTMgr_S3::get_handler(struct req_state* const s, +RGWHandler_REST* RGWRESTMgr_S3::get_handler(rgw::sal::RGWRadosStore *store, + struct req_state* const s, const rgw::auth::StrategyRegistry& auth_registry, const std::string& frontend_prefix) { bool is_s3website = enable_s3website && (s->prot_flags & RGW_REST_WEBSITE); int ret = - RGWHandler_REST_S3::init_from_header(s, + RGWHandler_REST_S3::init_from_header(store, s, is_s3website ? RGW_FORMAT_HTML : RGW_FORMAT_XML, true); if (ret < 0) @@ -4899,7 +4910,7 @@ RGWHandler_REST* RGWRESTMgr_S3::get_handler(struct req_state* const s, if (is_s3website) { if (s->init_state.url_bucket.empty()) { handler = new RGWHandler_REST_Service_S3Website(auth_registry); - } else if (s->object.empty()) { + } else if (rgw::sal::RGWObject::empty(s->object.get())) { handler = new RGWHandler_REST_Bucket_S3Website(auth_registry); } else { handler = new RGWHandler_REST_Obj_S3Website(auth_registry); @@ -4907,7 +4918,7 @@ RGWHandler_REST* RGWRESTMgr_S3::get_handler(struct req_state* const s, } else { if (s->init_state.url_bucket.empty()) { handler = new RGWHandler_REST_Service_S3(auth_registry, enable_sts, enable_iam, enable_pubsub); - } else if (s->object.empty()) { + } else if (rgw::sal::RGWObject::empty(s->object.get())) { handler = new RGWHandler_REST_Bucket_S3(auth_registry, enable_pubsub); } else { handler = new RGWHandler_REST_Obj_S3(auth_registry); @@ -4920,7 +4931,7 @@ RGWHandler_REST* RGWRESTMgr_S3::get_handler(struct req_state* const s, } bool RGWHandler_REST_S3Website::web_dir() const { - std::string subdir_name = url_decode(s->object.name); + std::string subdir_name = url_decode(s->object->get_name()); if (subdir_name.empty()) { return false; @@ -4928,14 +4939,14 @@ bool RGWHandler_REST_S3Website::web_dir() const { subdir_name.pop_back(); } - rgw_obj obj(s->bucket, subdir_name); + rgw_obj obj(s->bucket->get_bi(), subdir_name); RGWObjectCtx& obj_ctx = *static_cast(s->obj_ctx); obj_ctx.set_atomic(obj); obj_ctx.set_prefetch_data(obj); RGWObjState* state = nullptr; - if (store->getRados()->get_obj_state(&obj_ctx, s->bucket_info, obj, &state, false, s->yield) < 0) { + if (store->getRados()->get_obj_state(&obj_ctx, s->bucket->get_info(), obj, &state, false, s->yield) < 0) { return false; } if (! state->exists) { @@ -4950,7 +4961,11 @@ int RGWHandler_REST_S3Website::init(rgw::sal::RGWRadosStore *store, req_state *s // save the original object name before retarget() replaces it with the // result of get_effective_key(). the error_handler() needs the original // object name for redirect handling - original_object_name = s->object.name; + if (!rgw::sal::RGWObject::empty(s->object.get())) { + original_object_name = s->object->get_name(); + } else { + original_object_name = ""; + } return RGWHandler_REST_S3::init(store, s, cio); } @@ -4962,39 +4977,40 @@ int RGWHandler_REST_S3Website::retarget(RGWOp* op, RGWOp** new_op) { if (!(s->prot_flags & RGW_REST_WEBSITE)) return 0; - int ret = store->getRados()->get_bucket_info(store->svc(), s->bucket_tenant, - s->bucket_name, s->bucket_info, NULL, - s->yield, &s->bucket_attrs); + int ret = store->get_bucket(nullptr, s->bucket_tenant, s->bucket_name, &s->bucket); if (ret < 0) { // TODO-FUTURE: if the bucket does not exist, maybe expose it here? return -ERR_NO_SUCH_BUCKET; } - if (!s->bucket_info.has_website) { + + s->bucket_attrs = s->bucket->get_attrs().attrs; + + if (!s->bucket->get_info().has_website) { // TODO-FUTURE: if the bucket has no WebsiteConfig, expose it here return -ERR_NO_SUCH_WEBSITE_CONFIGURATION; } rgw_obj_key new_obj; - bool get_res = s->bucket_info.website_conf.get_effective_key(s->object.name, &new_obj.name, web_dir()); + bool get_res = s->bucket->get_info().website_conf.get_effective_key(s->object->get_name(), &new_obj.name, web_dir()); if (!get_res) { s->err.message = "The IndexDocument Suffix is not configurated or not well formed!"; ldpp_dout(s, 5) << s->err.message << dendl; return -EINVAL; } - ldpp_dout(s, 10) << "retarget get_effective_key " << s->object << " -> " + ldpp_dout(s, 10) << "retarget get_effective_key " << s->object->get_key() << " -> " << new_obj << dendl; RGWBWRoutingRule rrule; bool should_redirect = - s->bucket_info.website_conf.should_redirect(new_obj.name, 0, &rrule); + s->bucket->get_info().website_conf.should_redirect(new_obj.name, 0, &rrule); if (should_redirect) { const string& hostname = s->info.env->get("HTTP_HOST", ""); const string& protocol = (s->info.env->get("SERVER_PORT_SECURE") ? "https" : "http"); int redirect_code = 0; - rrule.apply_rule(protocol, hostname, s->object.name, &s->redirect, + rrule.apply_rule(protocol, hostname, s->object->get_name(), &s->redirect, &redirect_code); // APply a custom HTTP response code if (redirect_code > 0) @@ -5010,7 +5026,7 @@ int RGWHandler_REST_S3Website::retarget(RGWOp* op, RGWOp** new_op) { * operation. Or remove this comment if it's not applicable anymore */ - s->object = new_obj; + s->object = store->get_object(new_obj); return 0; } @@ -5039,7 +5055,7 @@ int RGWHandler_REST_S3Website::serve_errordoc(int http_ret, const string& errord getop->if_unmod = NULL; getop->if_match = NULL; getop->if_nomatch = NULL; - s->object = errordoc_key; + s->object = store->get_object(errordoc_key); ret = init_permissions(getop.get()); if (ret < 0) { @@ -5109,7 +5125,7 @@ int RGWHandler_REST_S3Website::error_handler(int err_no, RGWBWRoutingRule rrule; bool should_redirect = - s->bucket_info.website_conf.should_redirect(original_object_name, + s->bucket->get_info().website_conf.should_redirect(original_object_name, http_error_code, &rrule); if (should_redirect) { @@ -5129,12 +5145,12 @@ int RGWHandler_REST_S3Website::error_handler(int err_no, } else if (err_no == -ERR_WEBSITE_REDIRECT) { // Do nothing here, this redirect will be handled in abort_early's ERR_WEBSITE_REDIRECT block // Do NOT fire the ErrorDoc handler - } else if (!s->bucket_info.website_conf.error_doc.empty()) { + } else if (!s->bucket->get_info().website_conf.error_doc.empty()) { /* This serves an entire page! On success, it will return zero, and no further content should be sent to the socket On failure, we need the double-error handler */ - new_err_no = RGWHandler_REST_S3Website::serve_errordoc(http_error_code, s->bucket_info.website_conf.error_doc); + new_err_no = RGWHandler_REST_S3Website::serve_errordoc(http_error_code, s->bucket->get_info().website_conf.error_doc); if (new_err_no && new_err_no != -1) { err_no = new_err_no; } diff --git a/src/rgw/rgw_rest_s3.h b/src/rgw/rgw_rest_s3.h index 1993f647e800..1e03134f6c5c 100644 --- a/src/rgw/rgw_rest_s3.h +++ b/src/rgw/rgw_rest_s3.h @@ -297,7 +297,7 @@ class RGWPostObj_ObjStore_S3 : public RGWPostObj_ObjStore { int get_policy(); int get_tags(); - void rebuild_key(string& key); + void rebuild_key(rgw::sal::RGWObject* obj); std::string get_current_filename() const override; std::string get_current_content_type() const override; @@ -625,7 +625,7 @@ class RGWHandler_REST_S3 : public RGWHandler_REST { protected: const rgw::auth::StrategyRegistry& auth_registry; public: - static int init_from_header(struct req_state *s, int default_formatter, bool configurable_format); + static int init_from_header(rgw::sal::RGWRadosStore *store, struct req_state *s, int default_formatter, bool configurable_format); explicit RGWHandler_REST_S3(const rgw::auth::StrategyRegistry& auth_registry) : RGWHandler_REST(), @@ -765,7 +765,8 @@ public: ~RGWRESTMgr_S3() override = default; - RGWHandler_REST *get_handler(struct req_state* s, + RGWHandler_REST *get_handler(rgw::sal::RGWRadosStore *store, + struct req_state* s, const rgw::auth::StrategyRegistry& auth_registry, const std::string& frontend_prefix) override; }; diff --git a/src/rgw/rgw_rest_sts.cc b/src/rgw/rgw_rest_sts.cc index 7ef6455cd323..0e5c7b76d92d 100644 --- a/src/rgw/rgw_rest_sts.cc +++ b/src/rgw/rgw_rest_sts.cc @@ -670,9 +670,10 @@ int RGWHandler_REST_STS::init_from_header(struct req_state* s, } RGWHandler_REST* -RGWRESTMgr_STS::get_handler(struct req_state* const s, - const rgw::auth::StrategyRegistry& auth_registry, - const std::string& frontend_prefix) +RGWRESTMgr_STS::get_handler(rgw::sal::RGWRadosStore *store, + struct req_state* const s, + const rgw::auth::StrategyRegistry& auth_registry, + const std::string& frontend_prefix) { return new RGWHandler_REST_STS(auth_registry); } diff --git a/src/rgw/rgw_rest_sts.h b/src/rgw/rgw_rest_sts.h index d7227fe5af6c..4845010d650d 100644 --- a/src/rgw/rgw_rest_sts.h +++ b/src/rgw/rgw_rest_sts.h @@ -205,7 +205,8 @@ public: return this; } - RGWHandler_REST* get_handler(struct req_state*, + RGWHandler_REST* get_handler(rgw::sal::RGWRadosStore *store, + struct req_state*, const rgw::auth::StrategyRegistry&, const std::string&) override; }; diff --git a/src/rgw/rgw_rest_swift.cc b/src/rgw/rgw_rest_swift.cc index 7b01b57dc02b..eb39090e4761 100644 --- a/src/rgw/rgw_rest_swift.cc +++ b/src/rgw/rgw_rest_swift.cc @@ -212,7 +212,7 @@ void RGWListBuckets_ObjStore_SWIFT::send_response_data(rgw::sal::RGWBucketList& * in applying the filter earlier as we really need to go through all * entries regardless of it (the headers like X-Account-Container-Count * aren't affected by specifying prefix). */ - const std::map& m = buckets.get_buckets(); + const auto& m = buckets.get_buckets(); for (auto iter = m.lower_bound(prefix); iter != m.end() && boost::algorithm::starts_with(iter->first, prefix); ++iter) { @@ -247,7 +247,7 @@ void RGWListBuckets_ObjStore_SWIFT::send_response_data_reversed(rgw::sal::RGWBuc * in applying the filter earlier as we really need to go through all * entries regardless of it (the headers like X-Account-Container-Count * aren't affected by specifying prefix). */ - std::map& m = buckets.get_buckets(); + auto& m = buckets.get_buckets(); auto iter = m.rbegin(); for (/* initialized above */; @@ -349,12 +349,12 @@ void RGWListBucket_ObjStore_SWIFT::send_response() map::iterator pref_iter = common_prefixes.begin(); dump_start(s); - dump_container_metadata(s, bucket, bucket_quota, - s->bucket_info.website_conf); + dump_container_metadata(s, s->bucket.get(), bucket_quota, + s->bucket->get_info().website_conf); s->formatter->open_array_section_with_attrs("container", FormatterAttrs("name", - s->bucket.name.c_str(), + s->bucket->get_name().c_str(), NULL)); while (iter != objs.end() || pref_iter != common_prefixes.end()) { @@ -454,13 +454,13 @@ static void dump_container_metadata(struct req_state *s, const RGWBucketWebsiteConf& ws_conf) { /* Adding X-Timestamp to keep align with Swift API */ - dump_header(s, "X-Timestamp", utime_t(s->bucket_info.creation_time)); + dump_header(s, "X-Timestamp", utime_t(s->bucket->get_info().creation_time)); dump_header(s, "X-Container-Object-Count", bucket->get_count()); dump_header(s, "X-Container-Bytes-Used", bucket->get_size()); dump_header(s, "X-Container-Bytes-Used-Actual", bucket->get_size_rounded()); - if (s->object.empty()) { + if (rgw::sal::RGWObject::empty(s->object.get())) { auto swift_policy = \ static_cast(s->bucket_acl.get()); std::string read_acl, write_acl; @@ -472,10 +472,10 @@ static void dump_container_metadata(struct req_state *s, if (write_acl.size()) { dump_header(s, "X-Container-Write", write_acl); } - if (!s->bucket_info.placement_rule.name.empty()) { - dump_header(s, "X-Storage-Policy", s->bucket_info.placement_rule.name); + if (!s->bucket->get_placement_rule().name.empty()) { + dump_header(s, "X-Storage-Policy", s->bucket->get_placement_rule().name); } - dump_header(s, "X-Storage-Class", s->bucket_info.placement_rule.get_storage_class()); + dump_header(s, "X-Storage-Class", s->bucket->get_placement_rule().get_storage_class()); /* Dump user-defined metadata items and generic attrs. */ const size_t PREFIX_LEN = sizeof(RGW_ATTR_META_PREFIX) - 1; @@ -497,9 +497,9 @@ static void dump_container_metadata(struct req_state *s, } /* Dump container versioning info. */ - if (! s->bucket_info.swift_ver_location.empty()) { + if (! s->bucket->get_info().swift_ver_location.empty()) { dump_header(s, "X-Versions-Location", - url_encode(s->bucket_info.swift_ver_location)); + url_encode(s->bucket->get_info().swift_ver_location)); } /* Dump quota headers. */ @@ -571,8 +571,8 @@ void RGWStatBucket_ObjStore_SWIFT::send_response() { if (op_ret >= 0) { op_ret = STATUS_NO_CONTENT; - dump_container_metadata(s, bucket, bucket_quota, - s->bucket_info.website_conf); + dump_container_metadata(s, bucket.get(), bucket_quota, + s->bucket->get_info().website_conf); } set_req_state_err(s, op_ret); @@ -845,7 +845,7 @@ int RGWPutObj_ObjStore_SWIFT::update_slo_segment_size(rgw_slo_entry& entry) { rgw_bucket bucket; - if (bucket_name.compare(s->bucket.name) != 0) { + if (bucket_name.compare(s->bucket->get_name()) != 0) { RGWBucketInfo bucket_info; map bucket_attrs; r = store->getRados()->get_bucket_info(store->svc(), s->user->get_id().tenant, @@ -858,7 +858,7 @@ int RGWPutObj_ObjStore_SWIFT::update_slo_segment_size(rgw_slo_entry& entry) { } bucket = bucket_info.bucket; } else { - bucket = s->bucket; + bucket = s->bucket->get_bi(); } /* fetch the stored size of the seg (or error if not valid) */ @@ -869,7 +869,7 @@ int RGWPutObj_ObjStore_SWIFT::update_slo_segment_size(rgw_slo_entry& entry) { RGWObjectCtx obj_ctx(store); obj_ctx.set_atomic(slo_seg); - RGWRados::Object op_target(store->getRados(), s->bucket_info, obj_ctx, slo_seg); + RGWRados::Object op_target(store->getRados(), s->bucket->get_info(), obj_ctx, slo_seg); RGWRados::Object::Read read_op(&op_target); bool compressed; @@ -929,7 +929,7 @@ int RGWPutObj_ObjStore_SWIFT::get_params() if (!s->generic_attrs.count(RGW_ATTR_CONTENT_TYPE)) { ldpp_dout(this, 5) << "content type wasn't provided, trying to guess" << dendl; - const char *suffix = strrchr(s->object.name.c_str(), '.'); + const char *suffix = strrchr(s->object->get_name().c_str(), '.'); if (suffix) { suffix++; if (*suffix) { @@ -1292,7 +1292,7 @@ void RGWDeleteObj_ObjStore_SWIFT::send_response() } else { RGWBulkDelete::acct_path_t path; path.bucket_name = s->bucket_name; - path.obj_key = s->object; + path.obj_key = s->object->get_key(); RGWBulkDelete::fail_desc_t fail_desc; fail_desc.err = op_ret; @@ -1389,10 +1389,10 @@ int RGWCopyObj_ObjStore_SWIFT::get_params() src_tenant_name = s->src_tenant_name; src_bucket_name = s->src_bucket_name; - src_object = s->src_object; + src_object = s->src_object->clone(); dest_tenant_name = s->bucket_tenant; dest_bucket_name = s->bucket_name; - dest_object = s->object.name; + dest_obj_name = s->object->get_name(); const char * const fresh_meta = s->info.env->get("HTTP_X_FRESH_METADATA"); if (fresh_meta && strcasecmp(fresh_meta, "TRUE") == 0) { @@ -1435,8 +1435,8 @@ void RGWCopyObj_ObjStore_SWIFT::send_partial_response(off_t ofs) void RGWCopyObj_ObjStore_SWIFT::dump_copy_info() { /* Dump X-Copied-From. */ - dump_header(s, "X-Copied-From", url_encode(src_bucket.name) + - "/" + url_encode(src_object.name)); + dump_header(s, "X-Copied-From", url_encode(src_bucket->get_name()) + + "/" + url_encode(src_object->get_name())); /* Dump X-Copied-From-Account. */ /* XXX tenant */ @@ -1979,8 +1979,8 @@ void RGWFormPost::init(rgw::sal::RGWRadosStore* const store, req_state* const s, RGWHandler* const dialect_handler) { - prefix = std::move(s->object.name); - s->object = rgw_obj_key(); + prefix = std::move(s->object->get_name()); + s->object->set_key(rgw_obj_key()); return RGWPostObj_ObjStore::init(store, s, dialect_handler); } @@ -2371,7 +2371,11 @@ int RGWSwiftWebsiteHandler::serve_errordoc(const int http_ret, } } get_errpage_op(store, handler, s, http_ret); - s->object = std::to_string(http_ret) + error_doc; + if (!rgw::sal::RGWBucket::empty(s->bucket.get())) { + s->object = s->bucket->get_object(rgw_obj_key(std::to_string(http_ret) + error_doc)); + } else { + s->object = store->get_object(rgw_obj_key(std::to_string(http_ret) + error_doc)); + } RGWOp* newop = &get_errpage_op; RGWRequest req(0); @@ -2381,7 +2385,7 @@ int RGWSwiftWebsiteHandler::serve_errordoc(const int http_ret, int RGWSwiftWebsiteHandler::error_handler(const int err_no, std::string* const error_content) { - const auto& ws_conf = s->bucket_info.website_conf; + const auto& ws_conf = s->bucket->get_info().website_conf; if (can_be_website_req() && ! ws_conf.error_doc.empty()) { set_req_state_err(s, err_no); @@ -2459,11 +2463,11 @@ RGWOp* RGWSwiftWebsiteHandler::get_ws_redirect_op() RGWOp* RGWSwiftWebsiteHandler::get_ws_index_op() { /* Retarget to get obj on requested index file. */ - if (! s->object.empty()) { - s->object = s->object.name + - s->bucket_info.website_conf.get_index_doc(); + if (! s->object->empty()) { + s->object->set_name(s->object->get_name() + + s->bucket->get_info().website_conf.get_index_doc()); } else { - s->object = s->bucket_info.website_conf.get_index_doc(); + s->object->set_name(s->bucket->get_info().website_conf.get_index_doc()); } auto getop = new RGWGetObj_ObjStore_SWIFT; @@ -2488,8 +2492,8 @@ RGWOp* RGWSwiftWebsiteHandler::get_ws_listing_op() /* Generate the header now. */ set_req_state_err(s, op_ret); dump_errno(s); - dump_container_metadata(s, bucket, bucket_quota, - s->bucket_info.website_conf); + dump_container_metadata(s, s->bucket.get(), bucket_quota, + s->bucket->get_info().website_conf); end_header(s, this, "text/html"); if (op_ret < 0) { return; @@ -2501,7 +2505,7 @@ RGWOp* RGWSwiftWebsiteHandler::get_ws_listing_op() std::stringstream ss; RGWSwiftWebsiteListingFormatter htmler(ss, prefix); - const auto& ws_conf = s->bucket_info.website_conf; + const auto& ws_conf = s->bucket->get_info().website_conf; htmler.generate_header(s->decoded_uri, ws_conf.listing_css_doc); @@ -2533,15 +2537,15 @@ RGWOp* RGWSwiftWebsiteHandler::get_ws_listing_op() } }; - std::string prefix = std::move(s->object.name); - s->object = rgw_obj_key(); + std::string prefix = std::move(s->object->get_name()); + s->object->set_key(rgw_obj_key()); return new RGWWebsiteListing(std::move(prefix)); } bool RGWSwiftWebsiteHandler::is_web_dir() const { - std::string subdir_name = url_decode(s->object.name); + std::string subdir_name = url_decode(s->object->get_name()); /* Remove character from the subdir name if it is "/". */ if (subdir_name.empty()) { @@ -2550,15 +2554,15 @@ bool RGWSwiftWebsiteHandler::is_web_dir() const subdir_name.pop_back(); } - rgw_obj obj(s->bucket, std::move(subdir_name)); + rgw::sal::RGWRadosObject obj(store, rgw_obj_key(std::move(subdir_name)), s->bucket.get()); /* First, get attrset of the object we'll try to retrieve. */ RGWObjectCtx& obj_ctx = *static_cast(s->obj_ctx); - obj_ctx.set_atomic(obj); - obj_ctx.set_prefetch_data(obj); + obj.set_atomic(&obj_ctx); + obj.set_prefetch_data(&obj_ctx); RGWObjState* state = nullptr; - if (store->getRados()->get_obj_state(&obj_ctx, s->bucket_info, obj, &state, false, s->yield) < 0) { + if (obj.get_obj_state(&obj_ctx, *s->bucket, &state, s->yield, false)) { return false; } @@ -2572,7 +2576,7 @@ bool RGWSwiftWebsiteHandler::is_web_dir() const std::string content_type; get_contype_from_attrs(state->attrset, content_type); - const auto& ws_conf = s->bucket_info.website_conf; + const auto& ws_conf = s->bucket->get_info().website_conf; const std::string subdir_marker = ws_conf.subdir_marker.empty() ? "application/directory" : ws_conf.subdir_marker; @@ -2581,14 +2585,14 @@ bool RGWSwiftWebsiteHandler::is_web_dir() const bool RGWSwiftWebsiteHandler::is_index_present(const std::string& index) const { - rgw_obj obj(s->bucket, index); + rgw::sal::RGWRadosObject obj(store, rgw_obj_key(index), s->bucket.get()); RGWObjectCtx& obj_ctx = *static_cast(s->obj_ctx); - obj_ctx.set_atomic(obj); - obj_ctx.set_prefetch_data(obj); + obj.set_atomic(&obj_ctx); + obj.set_prefetch_data(&obj_ctx); RGWObjState* state = nullptr; - if (store->getRados()->get_obj_state(&obj_ctx, s->bucket_info, obj, &state, false, s->yield) < 0) { + if (obj.get_obj_state(&obj_ctx, *s->bucket, &state, s->yield, false)) { return false; } @@ -2605,8 +2609,8 @@ int RGWSwiftWebsiteHandler::retarget_bucket(RGWOp* op, RGWOp** new_op) /* In Swift static web content is served if the request is anonymous or * has X-Web-Mode HTTP header specified to true. */ if (can_be_website_req()) { - const auto& ws_conf = s->bucket_info.website_conf; - const auto& index = s->bucket_info.website_conf.get_index_doc(); + const auto& ws_conf = s->bucket->get_info().website_conf; + const auto& index = s->bucket->get_info().website_conf.get_index_doc(); if (s->decoded_uri.back() != '/') { op_override = get_ws_redirect_op(); @@ -2639,8 +2643,8 @@ int RGWSwiftWebsiteHandler::retarget_object(RGWOp* op, RGWOp** new_op) /* In Swift static web content is served if the request is anonymous or * has X-Web-Mode HTTP header specified to true. */ if (can_be_website_req() && is_web_dir()) { - const auto& ws_conf = s->bucket_info.website_conf; - const auto& index = s->bucket_info.website_conf.get_index_doc(); + const auto& ws_conf = s->bucket->get_info().website_conf; + const auto& index = s->bucket->get_info().website_conf.get_index_doc(); if (s->decoded_uri.back() != '/') { op_override = get_ws_redirect_op(); @@ -2796,8 +2800,13 @@ int RGWHandler_REST_SWIFT::postauth_init() s->bucket_tenant = s->user->get_tenant(); s->bucket_name = t->url_bucket; + if (!s->object) { + /* Need an object, even an empty one */ + s->object = store->get_object(rgw_obj_key()); + } + dout(10) << "s->object=" << - (!s->object.empty() ? s->object : rgw_obj_key("")) + (!s->object->empty() ? s->object->get_key() : rgw_obj_key("")) << " s->bucket=" << rgw_make_bucket_entry_name(s->bucket_tenant, s->bucket_name) << dendl; @@ -2809,7 +2818,7 @@ int RGWHandler_REST_SWIFT::postauth_init() ret = validate_bucket_name(s->bucket_name); if (ret) return ret; - ret = validate_object_name(s->object.name); + ret = validate_object_name(s->object->get_name()); if (ret) return ret; @@ -2825,7 +2834,7 @@ int RGWHandler_REST_SWIFT::postauth_init() if (ret < 0) { return ret; } - ret = validate_object_name(s->src_object.name); + ret = validate_object_name(s->src_object->get_name()); if (ret < 0) { return ret; } @@ -2890,7 +2899,8 @@ static void next_tok(string& str, string& tok, char delim) } } -int RGWHandler_REST_SWIFT::init_from_header(struct req_state* const s, +int RGWHandler_REST_SWIFT::init_from_header(rgw::sal::RGWRadosStore* store, + struct req_state* const s, const std::string& frontend_prefix) { string req; @@ -3007,9 +3017,9 @@ int RGWHandler_REST_SWIFT::init_from_header(struct req_state* const s, s->init_state.url_bucket = first; if (req.size()) { - s->object = - rgw_obj_key(req, s->info.env->get("HTTP_X_OBJECT_VERSION_ID", "")); /* rgw swift extension */ - s->info.effective_uri.append("/" + s->object.name); + s->object = store->get_object( + rgw_obj_key(req, s->info.env->get("HTTP_X_OBJECT_VERSION_ID", ""))); /* rgw swift extension */ + s->info.effective_uri.append("/" + s->object->get_name()); } return 0; @@ -3024,10 +3034,13 @@ int RGWHandler_REST_SWIFT::init(rgw::sal::RGWRadosStore* store, struct req_state std::string copy_source = s->info.env->get("HTTP_X_COPY_FROM", ""); if (! copy_source.empty()) { - bool result = RGWCopyObj::parse_copy_location(copy_source, t->src_bucket, - s->src_object); + rgw_obj_key key; + bool result = RGWCopyObj::parse_copy_location(copy_source, t->src_bucket, key); if (!result) return -ERR_BAD_URL; + s->src_object = store->get_object(key); + if (!s->src_object) + return -ERR_BAD_URL; } if (s->op == OP_COPY) { @@ -3043,13 +3056,13 @@ int RGWHandler_REST_SWIFT::init(rgw::sal::RGWRadosStore* store, struct req_state if (!result) return -ERR_BAD_URL; - std::string dest_object = dest_obj_key.name; + std::string dest_object_name = dest_obj_key.name; /* convert COPY operation into PUT */ t->src_bucket = t->url_bucket; - s->src_object = s->object; + s->src_object = s->object->clone(); t->url_bucket = dest_bucket_name; - s->object = rgw_obj_key(dest_object); + s->object->set_name(dest_object_name); s->op = OP_PUT; } @@ -3059,11 +3072,12 @@ int RGWHandler_REST_SWIFT::init(rgw::sal::RGWRadosStore* store, struct req_state } RGWHandler_REST* -RGWRESTMgr_SWIFT::get_handler(struct req_state* const s, +RGWRESTMgr_SWIFT::get_handler(rgw::sal::RGWRadosStore* store, + struct req_state* const s, const rgw::auth::StrategyRegistry& auth_registry, const std::string& frontend_prefix) { - int ret = RGWHandler_REST_SWIFT::init_from_header(s, frontend_prefix); + int ret = RGWHandler_REST_SWIFT::init_from_header(store, s, frontend_prefix); if (ret < 0) { ldpp_dout(s, 10) << "init_from_header returned err=" << ret << dendl; return nullptr; @@ -3075,7 +3089,7 @@ RGWRESTMgr_SWIFT::get_handler(struct req_state* const s, return new RGWHandler_REST_Service_SWIFT(auth_strategy); } - if (s->object.empty()) { + if (rgw::sal::RGWObject::empty(s->object.get())) { return new RGWHandler_REST_Bucket_SWIFT(auth_strategy); } @@ -3083,6 +3097,7 @@ RGWRESTMgr_SWIFT::get_handler(struct req_state* const s, } RGWHandler_REST* RGWRESTMgr_SWIFT_Info::get_handler( + rgw::sal::RGWRadosStore* store, struct req_state* const s, const rgw::auth::StrategyRegistry& auth_registry, const std::string& frontend_prefix) diff --git a/src/rgw/rgw_rest_swift.h b/src/rgw/rgw_rest_swift.h index cf8b224313fb..1ed664d02a3c 100644 --- a/src/rgw/rgw_rest_swift.h +++ b/src/rgw/rgw_rest_swift.h @@ -384,7 +384,7 @@ protected: return false; } - static int init_from_header(struct req_state* s, + static int init_from_header(rgw::sal::RGWRadosStore* store, struct req_state* s, const std::string& frontend_prefix); public: explicit RGWHandler_REST_SWIFT(const rgw::auth::Strategy& auth_strategy) @@ -500,7 +500,8 @@ public: RGWRESTMgr_SWIFT() = default; ~RGWRESTMgr_SWIFT() override = default; - RGWHandler_REST *get_handler(struct req_state *s, + RGWHandler_REST *get_handler(rgw::sal::RGWRadosStore *store, + struct req_state *s, const rgw::auth::StrategyRegistry& auth_registry, const std::string& frontend_prefix) override; }; @@ -571,7 +572,8 @@ public: RGWRESTMgr_SWIFT_CrossDomain() = default; ~RGWRESTMgr_SWIFT_CrossDomain() override = default; - RGWHandler_REST* get_handler(struct req_state* const s, + RGWHandler_REST* get_handler(rgw::sal::RGWRadosStore *store, + struct req_state* const s, const rgw::auth::StrategyRegistry&, const std::string&) override { s->prot_flags |= RGW_REST_SWIFT; @@ -627,7 +629,8 @@ public: RGWRESTMgr_SWIFT_HealthCheck() = default; ~RGWRESTMgr_SWIFT_HealthCheck() override = default; - RGWHandler_REST* get_handler(struct req_state* const s, + RGWHandler_REST* get_handler(rgw::sal::RGWRadosStore *store, + struct req_state* const s, const rgw::auth::StrategyRegistry&, const std::string&) override { s->prot_flags |= RGW_REST_SWIFT; @@ -673,7 +676,8 @@ public: RGWRESTMgr_SWIFT_Info() = default; ~RGWRESTMgr_SWIFT_Info() override = default; - RGWHandler_REST *get_handler(struct req_state* s, + RGWHandler_REST *get_handler(rgw::sal::RGWRadosStore *store, + struct req_state* s, const rgw::auth::StrategyRegistry& auth_registry, const std::string& frontend_prefix) override; }; diff --git a/src/rgw/rgw_rest_usage.h b/src/rgw/rgw_rest_usage.h index 6bffad69dd46..741ca87ca4a9 100644 --- a/src/rgw/rgw_rest_usage.h +++ b/src/rgw/rgw_rest_usage.h @@ -25,7 +25,8 @@ public: RGWRESTMgr_Usage() = default; ~RGWRESTMgr_Usage() override = default; - RGWHandler_REST* get_handler(struct req_state*, + RGWHandler_REST* get_handler(rgw::sal::RGWRadosStore* store, + struct req_state*, const rgw::auth::StrategyRegistry& auth_registry, const std::string&) override { return new RGWHandler_Usage(auth_registry); diff --git a/src/rgw/rgw_rest_user.h b/src/rgw/rgw_rest_user.h index 062797594960..a8b86101e47b 100644 --- a/src/rgw/rgw_rest_user.h +++ b/src/rgw/rgw_rest_user.h @@ -27,7 +27,8 @@ public: RGWRESTMgr_User() = default; ~RGWRESTMgr_User() override = default; - RGWHandler_REST *get_handler(struct req_state*, + RGWHandler_REST *get_handler(rgw::sal::RGWRadosStore *store, + struct req_state*, const rgw::auth::StrategyRegistry& auth_registry, const std::string&) override { return new RGWHandler_User(auth_registry); diff --git a/src/rgw/rgw_sal.cc b/src/rgw/rgw_sal.cc index 22cb33fa216b..8b9d95edc285 100644 --- a/src/rgw/rgw_sal.cc +++ b/src/rgw/rgw_sal.cc @@ -19,11 +19,19 @@ #include #include +#include "common/Clock.h" #include "common/errno.h" #include "rgw_sal.h" #include "rgw_bucket.h" #include "rgw_multi.h" +#include "rgw_acl_s3.h" + +/* Stuff for RGWRadosStore. Move to separate file when store split out */ +#include "rgw_zone.h" +#include "rgw_rest_conn.h" +#include "services/svc_sys_obj.h" +#include "services/svc_zone.h" #define dout_subsys ceph_subsys_rgw @@ -36,6 +44,7 @@ int RGWRadosUser::list_buckets(const string& marker, const string& end_marker, bool is_truncated = false; int ret; + buckets.clear(); ret = store->ctl()->user->list_buckets(info.user_id, marker, end_marker, max, need_stats, &ulist, &is_truncated); if (ret < 0) @@ -43,43 +52,36 @@ int RGWRadosUser::list_buckets(const string& marker, const string& end_marker, buckets.set_truncated(is_truncated); for (const auto& ent : ulist.get_buckets()) { - RGWRadosBucket *rb = new RGWRadosBucket(this->store, *this, ent.second); - buckets.add(rb); + buckets.add(std::unique_ptr(new RGWRadosBucket(this->store, ent.second, this))); } return 0; } -RGWBucketList::~RGWBucketList() -{ - for (auto itr = buckets.begin(); itr != buckets.end(); itr++) { - delete itr->second; - } - buckets.clear(); -} - -RGWBucket* RGWRadosUser::add_bucket(rgw_bucket& bucket, +RGWBucket* RGWRadosUser::create_bucket(rgw_bucket& bucket, ceph::real_time creation_time) { return NULL; } -int RGWRadosUser::get_by_id(rgw_user id, optional_yield y) +int RGWRadosUser::load_by_id(optional_yield y) { - return store->ctl()->user->get_info_by_uid(id, &info, y); + return store->ctl()->user->get_info_by_uid(info.user_id, &info, y); } -RGWObject *RGWRadosBucket::create_object(const rgw_obj_key &key) +std::unique_ptr RGWRadosStore::get_object(const rgw_obj_key& k) { - if (!object) { - object = new RGWRadosObject(store, key); - } + return std::unique_ptr(new RGWRadosObject(this, k)); +} - return object; +/* Placeholder */ +RGWObject *RGWRadosBucket::create_object(const rgw_obj_key &key) +{ + return nullptr; } -int RGWRadosBucket::remove_bucket(bool delete_children, optional_yield y) +int RGWRadosBucket::remove_bucket(bool delete_children, std::string prefix, std::string delimiter, optional_yield y) { int ret; map stats; @@ -111,22 +113,21 @@ int RGWRadosBucket::remove_bucket(bool delete_children, optional_yield y) return ret; if (!objs.empty() && !delete_children) { - lderr(store->ctx()) << "ERROR: could not remove non-empty bucket " << ent.bucket.name << dendl; + lderr(store->ctx()) << "ERROR: could not remove non-empty bucket " << info.bucket.name << + dendl; return -ENOTEMPTY; } for (const auto& obj : objs) { rgw_obj_key key(obj.key); /* xxx dang */ - ret = rgw_remove_object(store, info, ent.bucket, key); + ret = rgw_remove_object(store, info, info.bucket, key); if (ret < 0 && ret != -ENOENT) { - return ret; + return ret; } } } while(is_truncated); - string prefix, delimiter; - ret = abort_bucket_multiparts(store, store->ctx(), info, prefix, delimiter); if (ret < 0) { return ret; @@ -144,11 +145,11 @@ int RGWRadosBucket::remove_bucket(bool delete_children, optional_yield y) ret = store->getRados()->delete_bucket(info, objv_tracker, null_yield, !delete_children); if (ret < 0) { lderr(store->ctx()) << "ERROR: could not remove bucket " << - ent.bucket.name << dendl; + info.bucket.name << dendl; return ret; } - ret = store->ctl()->bucket->unlink_bucket(info.owner, ent.bucket, null_yield, false); + ret = store->ctl()->bucket->unlink_bucket(info.owner, info.bucket, null_yield, false); if (ret < 0) { lderr(store->ctx()) << "ERROR: unable to remove user bucket information" << dendl; } @@ -158,8 +159,34 @@ int RGWRadosBucket::remove_bucket(bool delete_children, optional_yield y) int RGWRadosBucket::get_bucket_info(optional_yield y) { - return store->getRados()->get_bucket_info(store->svc(), ent.bucket.tenant, ent.bucket.name, info, - NULL, y, &attrs); + auto obj_ctx = store->svc()->sysobj->init_obj_ctx(); + RGWSI_MetaBackend_CtxParams bectx_params = RGWSI_MetaBackend_CtxParams_SObj(&obj_ctx); + RGWObjVersionTracker ep_ot; + int ret = store->ctl()->bucket->read_bucket_info(info.bucket, &info, y, + RGWBucketCtl::BucketInstance::GetParams() + .set_mtime(&mtime) + .set_attrs(&attrs.attrs) + .set_bectx_params(bectx_params), + &ep_ot); + if (ret == 0) { + bucket_version = ep_ot.read_version; + ent.placement_rule = info.placement_rule; + } + return ret; +} + +int RGWRadosBucket::load_by_name(const std::string& tenant, const std::string& bucket_name, const std::string bucket_instance_id, RGWSysObjectCtx *rctx, optional_yield y) +{ + info.bucket.tenant = tenant; + info.bucket.name = bucket_name; + info.bucket.bucket_id = bucket_instance_id; + ent.bucket = info.bucket; + + if (bucket_instance_id.empty()) { + return get_bucket_info(y); + } + + return store->getRados()->get_bucket_instance_info(*rctx, info.bucket, info, NULL, &attrs.attrs, y); } int RGWRadosBucket::get_bucket_stats(RGWBucketInfo& bucket_info, int shard_id, @@ -172,12 +199,14 @@ int RGWRadosBucket::get_bucket_stats(RGWBucketInfo& bucket_info, int shard_id, int RGWRadosBucket::read_bucket_stats(optional_yield y) { - return store->ctl()->bucket->read_bucket_stats(ent.bucket, &ent, y); + int ret = store->ctl()->bucket->read_bucket_stats(info.bucket, &ent, y); + info.placement_rule = ent.placement_rule; + return ret; } int RGWRadosBucket::sync_user_stats() { - return store->ctl()->bucket->sync_user_stats(user.info.user_id, info, &ent); + return store->ctl()->bucket->sync_user_stats(owner->get_id(), info, &ent); } int RGWRadosBucket::update_container_stats(void) @@ -185,34 +214,36 @@ int RGWRadosBucket::update_container_stats(void) int ret; map m; - m[ent.bucket.name] = ent; + m[info.bucket.name] = ent; ret = store->getRados()->update_containers_stats(m); if (!ret) return -EEXIST; if (ret < 0) return ret; - map::iterator iter = m.find(ent.bucket.name); + map::iterator iter = m.find(info.bucket.name); if (iter == m.end()) return -EINVAL; ent.count = iter->second.count; ent.size = iter->second.size; ent.size_rounded = iter->second.size_rounded; + ent.creation_time = iter->second.creation_time; ent.placement_rule = std::move(iter->second.placement_rule); + info.placement_rule = ent.placement_rule; return 0; } int RGWRadosBucket::check_bucket_shards(void) { - return store->getRados()->check_bucket_shards(info, ent.bucket, get_count()); + return store->getRados()->check_bucket_shards(info, info.bucket, get_count()); } int RGWRadosBucket::link(RGWUser* new_user, optional_yield y) { RGWBucketEntryPoint ep; - ep.bucket = ent.bucket; + ep.bucket = info.bucket; ep.owner = new_user->get_user(); ep.creation_time = get_creation_time(); ep.linked = true; @@ -236,13 +267,29 @@ int RGWRadosBucket::chown(RGWUser* new_user, RGWUser* old_user, optional_yield y old_user->get_display_name(), obj_marker, y); } -bool RGWRadosBucket::is_owner(RGWUser* user) +int RGWRadosBucket::put_instance_info(bool exclusive, ceph::real_time _mtime) { - get_bucket_info(null_yield); + mtime = _mtime; + return store->getRados()->put_bucket_instance_info(info, exclusive, mtime, &attrs.attrs); +} +/* Make sure to call get_bucket_info() if you need it first */ +bool RGWRadosBucket::is_owner(RGWUser* user) +{ return (info.owner.compare(user->get_user()) == 0); } +int RGWRadosBucket::check_empty(optional_yield y) +{ + return store->getRados()->check_bucket_empty(info, y); +} + +int RGWRadosBucket::check_quota(RGWQuotaInfo& user_quota, RGWQuotaInfo& bucket_quota, uint64_t obj_size) +{ + return store->getRados()->check_quota(owner->get_user(), get_bi(), + user_quota, bucket_quota, obj_size); +} + int RGWRadosBucket::set_acl(RGWAccessControlPolicy &acl, optional_yield y) { bufferlist aclbl; @@ -250,12 +297,17 @@ int RGWRadosBucket::set_acl(RGWAccessControlPolicy &acl, optional_yield y) acls = acl; acl.encode(aclbl); - return store->ctl()->bucket->set_acl(acl.get_owner(), ent.bucket, info, aclbl, null_yield); + return store->ctl()->bucket->set_acl(acl.get_owner(), info.bucket, info, aclbl, null_yield); } -RGWUser *RGWRadosStore::get_user(const rgw_user &u) +std::unique_ptr RGWRadosBucket::get_object(const rgw_obj_key& k) { - return new RGWRadosUser(this, u); + return std::unique_ptr(new RGWRadosObject(this->store, k, this)); +} + +std::unique_ptr RGWRadosStore::get_user(const rgw_user &u) +{ + return std::unique_ptr(new RGWRadosUser(this, u)); } //RGWBucket *RGWRadosStore::create_bucket(RGWUser &u, const rgw_bucket &b) @@ -267,32 +319,322 @@ RGWUser *RGWRadosStore::get_user(const rgw_user &u) //return bucket; //} // -void RGWRadosStore::finalize(void) { +void RGWRadosStore::finalize(void) +{ if (rados) rados->finalize(); } -int RGWRadosStore::get_bucket(RGWUser& u, const rgw_bucket& b, RGWBucket** bucket) +int RGWRadosObject::get_obj_state(RGWObjectCtx *rctx, RGWBucket& bucket, RGWObjState **state, optional_yield y, bool follow_olh) { - int ret; - RGWBucket* bp; + rgw_obj obj(bucket.get_bi(), key.name); + + return store->getRados()->get_obj_state(rctx, bucket.get_info(), obj, state, follow_olh, y); +} + +int RGWRadosObject::read_attrs(RGWRados::Object::Read &read_op, optional_yield y, rgw_obj *target_obj) +{ + read_op.params.attrs = &attrs.attrs; + read_op.params.target_obj = target_obj; + read_op.params.obj_size = &obj_size; + read_op.params.lastmod = &mtime; + + return read_op.prepare(y); +} + +int RGWRadosObject::get_obj_attrs(RGWObjectCtx *rctx, optional_yield y, rgw_obj *target_obj) +{ + RGWRados::Object op_target(store->getRados(), bucket->get_info(), *rctx, get_obj()); + RGWRados::Object::Read read_op(&op_target); - *bucket = nullptr; + return read_attrs(read_op, y, target_obj); +} - bp = new RGWRadosBucket(this, u, b); - if (!bp) { - return -ENOMEM; +int RGWRadosObject::modify_obj_attrs(RGWObjectCtx *rctx, const char *attr_name, bufferlist& attr_val, optional_yield y) +{ + rgw_obj target_obj; + int r = get_obj_attrs(rctx, y, &target_obj); + if (r < 0) { + return r; } + set_atomic(rctx); + attrs.attrs[attr_name] = attr_val; + return store->getRados()->set_attrs(rctx, bucket->get_info(), target_obj, attrs.attrs, NULL, y); +} + +int RGWRadosObject::copy_obj_data(RGWObjectCtx& rctx, RGWBucket* dest_bucket, + RGWObject* dest_obj, + uint16_t olh_epoch, + std::string* petag, + const DoutPrefixProvider *dpp, + optional_yield y) +{ + map attrset; + RGWRados::Object op_target(store->getRados(), dest_bucket->get_info(), rctx, get_obj()); + RGWRados::Object::Read read_op(&op_target); + + int ret = read_attrs(read_op, y); + if (ret < 0) + return ret; + + attrset = attrs.attrs; + + attrset.erase(RGW_ATTR_ID_TAG); + attrset.erase(RGW_ATTR_TAIL_TAG); + + return store->getRados()->copy_obj_data(rctx, dest_bucket, + dest_bucket->get_info().placement_rule, read_op, + obj_size - 1, dest_obj, NULL, mtime, attrset, 0, real_time(), NULL, + dpp, y); +} + +int RGWRadosObject::delete_obj_attrs(RGWObjectCtx *rctx, const char *attr_name, optional_yield y) +{ + map attrs; + map rmattr; + bufferlist bl; + + set_atomic(rctx); + rmattr[attr_name] = bl; + rgw_obj obj = get_obj(); + return store->getRados()->set_attrs(rctx, bucket->get_info(), obj, attrs, &rmattr, y); +} + +void RGWRadosObject::set_atomic(RGWObjectCtx *rctx) const +{ + rgw_obj obj = get_obj(); + store->getRados()->set_atomic(rctx, obj); +} + +void RGWRadosObject::set_prefetch_data(RGWObjectCtx *rctx) +{ + rgw_obj obj = get_obj(); + store->getRados()->set_prefetch_data(rctx, obj); +} + +void RGWRadosObject::gen_rand_obj_instance_name() +{ + store->getRados()->gen_rand_obj_instance_name(&key); +} + +int RGWRadosStore::get_bucket(RGWUser* u, const rgw_bucket& b, std::unique_ptr* bucket) +{ + int ret; + RGWBucket* bp; + + bp = new RGWRadosBucket(this, b, u); ret = bp->get_bucket_info(null_yield); if (ret < 0) { delete bp; return ret; } - *bucket = bp; + bucket->reset(bp); + return 0; +} + +int RGWRadosStore::get_bucket(RGWUser* u, const RGWBucketInfo& i, std::unique_ptr* bucket) +{ + RGWBucket* bp; + + bp = new RGWRadosBucket(this, i, u); + /* Don't need to fetch the bucket info, use the provided one */ + + bucket->reset(bp); + return 0; +} + +int RGWRadosStore::get_bucket(RGWUser* u, const std::string& tenant, const std::string&name, std::unique_ptr* bucket) +{ + rgw_bucket b; + + b.tenant = tenant; + b.name = name; + + return get_bucket(u, b, bucket); +} + +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__ << " 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(RGWRadosStore *store, + RGWUser& user, + map& bucket_attrs, + RGWAccessControlPolicy *policy) +{ + map::iterator aiter = bucket_attrs.find(RGW_ATTR_ACL); + + if (aiter != bucket_attrs.end()) { + int ret = decode_policy(store->ctx(), aiter->second, policy); + if (ret < 0) + return ret; + } else { + ldout(store->ctx(), 0) << "WARNING: couldn't find acl header for bucket, generating default" << dendl; + /* object exists, but policy is broken */ + int r = user.load_by_id(null_yield); + if (r < 0) + return r; + + policy->create_default(user.get_user(), user.get_display_name()); + } + return 0; +} + +int RGWRadosStore::forward_request_to_master(RGWUser* user, obj_version *objv, + bufferlist& in_data, + JSONParser *jp, req_info& info) +{ + if (!svc()->zone->get_master_conn()) { + ldout(ctx(), 0) << "rest connection is invalid" << dendl; + return -EINVAL; + } + ldout(ctx(), 0) << "sending request to master zonegroup" << dendl; + bufferlist response; + string uid_str = user->get_id().to_str(); +#define MAX_REST_RESPONSE (128 * 1024) // we expect a very small response + int ret = svc()->zone->get_master_conn()->forward(rgw_user(uid_str), info, + objv, MAX_REST_RESPONSE, + &in_data, &response); + if (ret < 0) + return ret; + + ldout(ctx(), 20) << "response: " << response.c_str() << dendl; + if (jp && !jp->parse(response.c_str(), response.length())) { + ldout(ctx(), 0) << "failed parsing response from master zonegroup" << dendl; + return -EINVAL; + } + return 0; } + +int RGWRadosStore::create_bucket(RGWUser& u, const rgw_bucket& b, + const string& zonegroup_id, + const rgw_placement_rule& placement_rule, + const string& swift_ver_location, + const RGWQuotaInfo * pquota_info, + map& attrs, + RGWBucketInfo& info, + obj_version& ep_objv, + bool exclusive, + bool obj_lock_enabled, + bool *existed, + req_info& req_info, + std::unique_ptr* bucket_out) +{ + int ret; + bufferlist in_data; + RGWBucketInfo master_info; + rgw_bucket *pmaster_bucket; + uint32_t *pmaster_num_shards; + real_time creation_time; + RGWAccessControlPolicy old_policy(ctx()); + std::unique_ptr bucket; + obj_version objv, *pobjv = NULL; + + /* If it exists, look it up; otherwise create it */ + ret = get_bucket(&u, b, &bucket); + if (ret < 0 && ret != -ENOENT) + return ret; + + if (ret != -ENOENT) { + *existed = true; + int r = rgw_op_get_bucket_policy_from_attr(this, u, bucket->get_attrs().attrs, + &old_policy); + if (r >= 0) { + if (old_policy.get_owner().get_id().compare(u.get_id()) != 0) { + bucket_out->swap(bucket); + ret = -EEXIST; + return ret; + } + } + } else { + bucket = std::unique_ptr(new RGWRadosBucket(this, b, &u)); + *existed = false; + bucket->set_attrs(attrs); + } + + if (!svc()->zone->is_meta_master()) { + JSONParser jp; + ret = forward_request_to_master(&u, NULL, in_data, &jp, req_info); + 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(this, 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(this, 20) << "got creation time: << " << std::put_time(std::localtime(&ctime), "%F %T") << dendl; + pmaster_bucket= &master_info.bucket; + creation_time = master_info.creation_time; + pmaster_num_shards = &master_info.layout.current_index.layout.normal.num_shards; + pobjv = &objv; + if (master_info.obj_lock_enabled()) { + info.flags = BUCKET_VERSIONED | BUCKET_OBJ_LOCK_ENABLED; + } + } else { + pmaster_bucket = NULL; + pmaster_num_shards = NULL; + if (obj_lock_enabled) + info.flags = BUCKET_VERSIONED | BUCKET_OBJ_LOCK_ENABLED; + } + + std::string zid = zonegroup_id; + if (zid.empty()) { + zid = svc()->zone->get_zonegroup().get_id(); + } + + if (*existed) { + rgw_placement_rule selected_placement_rule; + ret = svc()->zone->select_bucket_placement(u.get_info(), + zid, placement_rule, + &selected_placement_rule, nullptr); + if (selected_placement_rule != info.placement_rule) { + ret = -EEXIST; + bucket_out->swap(bucket); + return ret; + } + } else { + + ret = getRados()->create_bucket(u.get_info(), bucket->get_bi(), + zid, placement_rule, swift_ver_location, + pquota_info, attrs, + info, pobjv, &ep_objv, creation_time, + pmaster_bucket, pmaster_num_shards, exclusive); + if (ret == -EEXIST) { + *existed = true; + } else if (ret != 0) { + return ret; + } + } + + bucket->set_version(ep_objv); + bucket->get_info() = info; + + bucket_out->swap(bucket); + + return ret; +} + } // namespace rgw::sal rgw::sal::RGWRadosStore *RGWStoreManager::init_storage_provider(CephContext *cct, bool use_gc_thread, bool use_lc_thread, bool quota_threads, bool run_sync_thread, bool run_reshard_thread, bool use_cache) diff --git a/src/rgw/rgw_sal.h b/src/rgw/rgw_sal.h index 542844d03924..7b27b3c3d462 100644 --- a/src/rgw/rgw_sal.h +++ b/src/rgw/rgw_sal.h @@ -27,16 +27,44 @@ class RGWBucket; class RGWObject; class RGWBucketList; -typedef std::map RGWAttrs; +struct RGWAttrs { + std::map attrs; -class RGWStore { + RGWAttrs() {} + RGWAttrs(const std::map&& _a) : attrs(std::move(_a)) {} + RGWAttrs(const std::map& _a) : attrs(_a) {} + + void emplace(std::string&& key, buffer::list&& bl) { + attrs.emplace(std::move(key), std::move(bl)); /* key and bl are r-value refs */ + } + std::map::iterator find(const std::string& key) { + return attrs.find(key); + } +}; + +class RGWStore : public DoutPrefixProvider { public: RGWStore() {} virtual ~RGWStore() = default; - virtual RGWUser* get_user(const rgw_user& u) = 0; - virtual int get_bucket(RGWUser& u, const rgw_bucket& b, RGWBucket** bucket) = 0; - //virtual RGWBucket* create_bucket(RGWUser& u, const rgw_bucket& b) = 0; + virtual std::unique_ptr get_user(const rgw_user& u) = 0; + virtual std::unique_ptr get_object(const rgw_obj_key& k) = 0; + virtual int get_bucket(RGWUser* u, const rgw_bucket& b, std::unique_ptr* bucket) = 0; + virtual int get_bucket(RGWUser* u, const RGWBucketInfo& i, std::unique_ptr* bucket) = 0; + virtual int get_bucket(RGWUser* u, const std::string& tenant, const std::string&name, std::unique_ptr* bucket) = 0; + virtual int create_bucket(RGWUser& u, const rgw_bucket& b, + const string& zonegroup_id, + const rgw_placement_rule& placement_rule, + const string& swift_ver_location, + const RGWQuotaInfo * pquota_info, + map& attrs, + RGWBucketInfo& info, + obj_version& ep_objv, + bool exclusive, + bool obj_lock_enabled, + bool *existed, + req_info& req_info, + std::unique_ptr* bucket) = 0; virtual RGWBucketList* list_buckets(void) = 0; virtual void finalize(void)=0; @@ -56,7 +84,7 @@ class RGWUser { virtual int list_buckets(const string& marker, const string& end_marker, uint64_t max, bool need_stats, RGWBucketList& buckets) = 0; - virtual RGWBucket* add_bucket(rgw_bucket& bucket, ceph::real_time creation_time) = 0; + virtual RGWBucket* create_bucket(rgw_bucket& bucket, ceph::real_time creation_time) = 0; friend class RGWBucket; virtual std::string& get_display_name() { return info.display_name; } @@ -66,8 +94,10 @@ class RGWUser { int32_t get_max_buckets() const { return info.max_buckets; } const RGWUserCaps& get_caps() const { return info.caps; } + /* Placeholders */ + virtual int load_by_id(optional_yield y) = 0; - /* xxx dang temporary; will be removed when User is complete */ + /* dang temporary; will be removed when User is complete */ rgw_user& get_user() { return info.user_id; } RGWUserInfo& get_info() { return info; } }; @@ -76,21 +106,34 @@ class RGWBucket { protected: RGWBucketEnt ent; RGWBucketInfo info; - RGWUser *owner; + RGWUser* owner; RGWAttrs attrs; + obj_version bucket_version; + ceph::real_time mtime; public: - RGWBucket() : ent(), owner(nullptr), attrs() {} - RGWBucket(const rgw_bucket& _b) : ent(), attrs() { ent.bucket = _b; } - RGWBucket(const RGWBucketEnt& _e) : ent(_e), attrs() {} + RGWBucket() : ent(), info(), owner(nullptr), attrs(), bucket_version() {} + RGWBucket(const rgw_bucket& _b) : + ent(), info(), owner(nullptr), attrs(), bucket_version() { ent.bucket = _b; info.bucket = _b; } + RGWBucket(const RGWBucketEnt& _e) : + ent(_e), info(), owner(nullptr), attrs(), bucket_version() { info.bucket = ent.bucket; info.placement_rule = ent.placement_rule; } + RGWBucket(const RGWBucketInfo& _i) : + ent(), info(_i), owner(nullptr), attrs(), bucket_version() {ent.bucket = info.bucket; ent.placement_rule = info.placement_rule; } + RGWBucket(const rgw_bucket& _b, RGWUser* _u) : + ent(), info(), owner(_u), attrs(), bucket_version() { ent.bucket = _b; info.bucket = _b; } + RGWBucket(const RGWBucketEnt& _e, RGWUser* _u) : + ent(_e), info(), owner(_u), attrs(), bucket_version() { info.bucket = ent.bucket; info.placement_rule = ent.placement_rule; } + RGWBucket(const RGWBucketInfo& _i, RGWUser* _u) : + ent(), info(_i), owner(_u), attrs(), bucket_version() { ent.bucket = info.bucket; ent.placement_rule = info.placement_rule;} virtual ~RGWBucket() = default; - virtual RGWObject* get_object(const rgw_obj_key& key) = 0; + virtual int load_by_name(const std::string& tenant, const std::string& bucket_name, const std::string bucket_instance_id, RGWSysObjectCtx *rctx, optional_yield y) = 0; + virtual std::unique_ptr get_object(const rgw_obj_key& key) = 0; virtual RGWBucketList* list(void) = 0; virtual RGWObject* create_object(const rgw_obj_key& key /* Attributes */) = 0; virtual RGWAttrs& get_attrs(void) { return attrs; } - virtual int set_attrs(RGWAttrs& a) { attrs = a; return 0; } - virtual int remove_bucket(bool delete_children, optional_yield y) = 0; + virtual int set_attrs(RGWAttrs a) { attrs = a; return 0; } + virtual int remove_bucket(bool delete_children, std::string prefix, std::string delimiter, optional_yield y) = 0; virtual RGWAccessControlPolicy& get_acl(void) = 0; virtual int set_acl(RGWAccessControlPolicy& acl, optional_yield y) = 0; virtual int get_bucket_info(optional_yield y) = 0; @@ -106,64 +149,110 @@ class RGWBucket { virtual int link(RGWUser* new_user, optional_yield y) = 0; virtual int unlink(RGWUser* new_user, optional_yield y) = 0; virtual int chown(RGWUser* new_user, RGWUser* old_user, optional_yield y) = 0; - virtual bool is_owner(RGWUser *user) = 0; - - const std::string& get_name() const { return ent.bucket.name; } - const std::string& get_tenant() const { return ent.bucket.tenant; } - const std::string& get_marker() const { return ent.bucket.marker; } - const std::string& get_bucket_id() const { return ent.bucket.bucket_id; } + virtual int put_instance_info(bool exclusive, ceph::real_time mtime) = 0; + virtual bool is_owner(RGWUser* user) = 0; + virtual int check_empty(optional_yield y) = 0; + virtual int check_quota(RGWQuotaInfo& user_quota, RGWQuotaInfo& bucket_quota, uint64_t obj_size) = 0; + + bool empty() const { return info.bucket.name.empty(); } + const std::string& get_name() const { return info.bucket.name; } + const std::string& get_tenant() const { return info.bucket.tenant; } + const std::string& get_marker() const { return info.bucket.marker; } + const std::string& get_bucket_id() const { return info.bucket.bucket_id; } size_t get_size() const { return ent.size; } size_t get_size_rounded() const { return ent.size_rounded; } uint64_t get_count() const { return ent.count; } - rgw_placement_rule get_placement_rule() const { return ent.placement_rule; } - ceph::real_time& get_creation_time() { return ent.creation_time; }; + rgw_placement_rule& get_placement_rule() { return info.placement_rule; } + ceph::real_time& get_creation_time() { return ent.creation_time; } + ceph::real_time& get_modification_time() { return mtime; } + obj_version& get_version() { return bucket_version; } + void set_version(obj_version &ver) { bucket_version = ver; } + std::string get_key() { return info.bucket.get_key(); } + bool versioned() { return info.versioned(); } + bool versioning_enabled() { return info.versioning_enabled(); } void convert(cls_user_bucket_entry *b) const { ent.convert(b); } + static bool empty(RGWBucket* b) { return (!b || b->empty()); } + virtual std::unique_ptr clone() = 0; + /* dang - This is temporary, until the API is completed */ - rgw_bucket& get_bi() { return ent.bucket; } + rgw_bucket& get_bi() { return info.bucket; } RGWBucketInfo& get_info() { return info; } friend inline ostream& operator<<(ostream& out, const RGWBucket& b) { - out << b.ent.bucket; + out << b.info.bucket; + return out; + } + + friend inline ostream& operator<<(ostream& out, const RGWBucket* b) { + if (!b) + out << ""; + else + out << b->info.bucket; + return out; + } + + friend inline ostream& operator<<(ostream& out, const std::unique_ptr& p) { + out << p.get(); return out; } friend class RGWBucketList; protected: - virtual void set_ent(RGWBucketEnt& _ent) { ent = _ent; } + virtual void set_ent(RGWBucketEnt& _ent) { ent = _ent; info.bucket = ent.bucket; info.placement_rule = ent.placement_rule; } }; + class RGWBucketList { - std::map buckets; + std::map> buckets; bool truncated; public: RGWBucketList() : buckets(), truncated(false) {} - RGWBucketList(RGWBucketList&&) = default; - RGWBucketList& operator=(const RGWBucketList&) = default; - ~RGWBucketList(); + RGWBucketList(RGWBucketList&& _bl) : + buckets(std::move(_bl.buckets)), + truncated(_bl.truncated) + { } + RGWBucketList& operator=(const RGWBucketList&) = delete; + RGWBucketList& operator=(RGWBucketList&& _bl) { + for (auto& ent : _bl.buckets) { + buckets.emplace(ent.first, std::move(ent.second)); + } + truncated = _bl.truncated; + return *this; + }; - map& get_buckets() { return buckets; } + map>& get_buckets() { return buckets; } bool is_truncated(void) const { return truncated; } void set_truncated(bool trunc) { truncated = trunc; } - void add(RGWBucket* bucket) { - buckets[bucket->ent.bucket.name] = bucket; + void add(std::unique_ptr bucket) { + buckets.emplace(bucket->info.bucket.name, std::move(bucket)); } size_t count() const { return buckets.size(); } - void clear() { buckets.clear(); truncated = false; } -}; // class RGWBucketList + void clear(void) { + buckets.clear(); + truncated = false; + } +}; class RGWObject { protected: rgw_obj_key key; + RGWBucket* bucket; + std::string index_hash_source; + uint64_t obj_size; + ceph::real_time mtime; public: - RGWObject() : key() {} - RGWObject(const rgw_obj_key& _k) : key(_k) {} + RGWObject() : key(), bucket(nullptr), index_hash_source(), obj_size(), mtime() {} + RGWObject(const rgw_obj_key& _k) : key(_k), bucket(), index_hash_source(), obj_size(), mtime() {} + RGWObject(const rgw_obj_key& _k, RGWBucket* _b) : key(_k), bucket(_b), index_hash_source(), obj_size(), mtime() {} + RGWObject(const RGWObject& _o) = default; + virtual ~RGWObject() = default; virtual int read(off_t offset, off_t length, std::iostream& stream) = 0; @@ -173,6 +262,57 @@ class RGWObject { virtual int delete_object(void) = 0; virtual RGWAccessControlPolicy& get_acl(void) = 0; virtual int set_acl(const RGWAccessControlPolicy& acl) = 0; + virtual void set_atomic(RGWObjectCtx *rctx) const = 0; + virtual void set_prefetch_data(RGWObjectCtx *rctx) = 0; + + bool empty() const { return key.empty(); } + const std::string &get_name() const { return key.name; } + + virtual int get_obj_state(RGWObjectCtx *rctx, RGWBucket& bucket, RGWObjState **state, optional_yield y, bool follow_olh = false) = 0; + virtual int get_obj_attrs(RGWObjectCtx *rctx, optional_yield y, rgw_obj *target_obj = nullptr) = 0; + virtual int modify_obj_attrs(RGWObjectCtx *rctx, const char *attr_name, bufferlist& attr_val, optional_yield y) = 0; + virtual int delete_obj_attrs(RGWObjectCtx *rctx, const char *attr_name, optional_yield y) = 0; + virtual int copy_obj_data(RGWObjectCtx& rctx, RGWBucket* dest_bucket, RGWObject* dest_obj, uint16_t olh_epoch, std::string* petag, const DoutPrefixProvider *dpp, optional_yield y) = 0; + + ceph::real_time get_mtime(void) const { return mtime; } + uint64_t get_obj_size(void) const { return obj_size; } + RGWBucket* get_bucket(void) const { return bucket; } + void set_bucket(RGWBucket* b) { bucket = b; } + std::string get_hash_source(void) { return index_hash_source; } + void set_hash_source(std::string s) { index_hash_source = s; } + std::string get_oid(void) const { return key.get_oid(); } + + static bool empty(RGWObject* o) { return (!o || o->empty()); } + virtual std::unique_ptr clone() = 0; + + /* dang - Not sure if we want this, but it simplifies things a lot */ + void set_obj_size(uint64_t s) { obj_size = s; } + virtual void set_name(const string& n) { key = n; } + virtual void set_key(const rgw_obj_key& k) { key = k; } + virtual rgw_obj get_obj(void) const { return rgw_obj(bucket->get_bi(), key); } + virtual void gen_rand_obj_instance_name() = 0; + + /* dang - This is temporary, until the API is completed */ + rgw_obj_key& get_key() { return key; } + void set_instance(const std::string &i) { key.set_instance(i); } + const std::string &get_instance() const { return key.instance; } + bool have_instance(void) { return key.have_instance(); } + + friend inline ostream& operator<<(ostream& out, const RGWObject& o) { + out << o.key; + return out; + } + friend inline ostream& operator<<(ostream& out, const RGWObject* o) { + if (!o) + out << ""; + else + out << o->key; + return out; + } + friend inline ostream& operator<<(ostream& out, const std::unique_ptr& p) { + out << p.get(); + return out; + } }; @@ -190,10 +330,10 @@ class RGWRadosUser : public RGWUser { int list_buckets(const string& marker, const string& end_marker, uint64_t max, bool need_stats, RGWBucketList& buckets); - RGWBucket* add_bucket(rgw_bucket& bucket, ceph::real_time creation_time); + RGWBucket* create_bucket(rgw_bucket& bucket, ceph::real_time creation_time); /* Placeholders */ - int get_by_id(rgw_user id, optional_yield y); + virtual int load_by_id(optional_yield y); friend class RGWRadosBucket; }; @@ -206,7 +346,8 @@ class RGWRadosObject : public RGWObject { public: RGWRadosObject() - : attrs(), + : store(), + attrs(), acls() { } @@ -216,6 +357,13 @@ class RGWRadosObject : public RGWObject { attrs(), acls() { } + RGWRadosObject(RGWRadosStore *_st, const rgw_obj_key& _k, RGWBucket* _b) + : RGWObject(_k, _b), + store(_st), + attrs(), + acls() { + } + RGWRadosObject(const RGWRadosObject& _o) = default; int read(off_t offset, off_t length, std::iostream& stream) { return length; } int write(off_t offset, off_t length, std::iostream& stream) { return length; } @@ -224,45 +372,77 @@ class RGWRadosObject : public RGWObject { int delete_object(void) { return 0; } RGWAccessControlPolicy& get_acl(void) { return acls; } int set_acl(const RGWAccessControlPolicy& acl) { acls = acl; return 0; } + virtual void set_atomic(RGWObjectCtx *rctx) const; + virtual void set_prefetch_data(RGWObjectCtx *rctx); + + virtual int get_obj_state(RGWObjectCtx *rctx, RGWBucket& bucket, RGWObjState **state, optional_yield y, bool follow_olh = true); + virtual int get_obj_attrs(RGWObjectCtx *rctx, optional_yield y, rgw_obj *target_obj = nullptr); + virtual int modify_obj_attrs(RGWObjectCtx *rctx, const char *attr_name, bufferlist& attr_val, optional_yield y); + virtual int delete_obj_attrs(RGWObjectCtx *rctx, const char *attr_name, optional_yield y); + virtual int copy_obj_data(RGWObjectCtx& rctx, RGWBucket* dest_bucket, RGWObject* dest_obj, uint16_t olh_epoch, std::string* petag, const DoutPrefixProvider *dpp, optional_yield y); + virtual void gen_rand_obj_instance_name() override; + virtual std::unique_ptr clone() { + return std::unique_ptr(new RGWRadosObject(*this)); + } + + private: + int read_attrs(RGWRados::Object::Read &read_op, optional_yield y, rgw_obj *target_obj = nullptr); }; class RGWRadosBucket : public RGWBucket { private: RGWRadosStore *store; - RGWRadosObject *object; RGWAccessControlPolicy acls; - RGWRadosUser user; public: - RGWRadosBucket() - : store(nullptr), - object(nullptr), - acls(), - user() { + RGWRadosBucket(RGWRadosStore *_st) + : store(_st), + acls() { } - RGWRadosBucket(RGWRadosStore *_st, RGWUser& _u, const rgw_bucket& _b) + RGWRadosBucket(RGWRadosStore *_st, const rgw_bucket& _b) : RGWBucket(_b), store(_st), - object(nullptr), - acls(), - user(dynamic_cast(_u)) { + acls() { } - RGWRadosBucket(RGWRadosStore *_st, RGWUser& _u, const RGWBucketEnt& _e) + RGWRadosBucket(RGWRadosStore *_st, const RGWBucketEnt& _e) : RGWBucket(_e), store(_st), - object(nullptr), - acls(), - user(dynamic_cast(_u)) { + acls() { + } + + RGWRadosBucket(RGWRadosStore *_st, const RGWBucketInfo& _i) + : RGWBucket(_i), + store(_st), + acls() { + } + + RGWRadosBucket(RGWRadosStore *_st, const rgw_bucket& _b, RGWUser* _u) + : RGWBucket(_b, _u), + store(_st), + acls() { + } + + RGWRadosBucket(RGWRadosStore *_st, const RGWBucketEnt& _e, RGWUser* _u) + : RGWBucket(_e, _u), + store(_st), + acls() { + } + + RGWRadosBucket(RGWRadosStore *_st, const RGWBucketInfo& _i, RGWUser* _u) + : RGWBucket(_i, _u), + store(_st), + acls() { } ~RGWRadosBucket() { } - RGWObject* get_object(const rgw_obj_key& key) { return object; } + virtual int load_by_name(const std::string& tenant, const std::string& bucket_name, const std::string bucket_instance_id, RGWSysObjectCtx *rctx, optional_yield y) override; + virtual std::unique_ptr get_object(const rgw_obj_key& k) override; RGWBucketList* list(void) { return new RGWBucketList(); } RGWObject* create_object(const rgw_obj_key& key /* Attributes */) override; - virtual int remove_bucket(bool delete_children, optional_yield y) override; + virtual int remove_bucket(bool delete_children, std::string prefix, std::string delimiter, optional_yield y) override; RGWAccessControlPolicy& get_acl(void) { return acls; } virtual int set_acl(RGWAccessControlPolicy& acl, optional_yield y) override; virtual int get_bucket_info(optional_yield y) override; @@ -278,7 +458,15 @@ class RGWRadosBucket : public RGWBucket { virtual int link(RGWUser* new_user, optional_yield y) override; virtual int unlink(RGWUser* new_user, optional_yield y) override; virtual int chown(RGWUser* new_user, RGWUser* old_user, optional_yield y) override; - virtual bool is_owner(RGWUser *user) override; + virtual int put_instance_info(bool exclusive, ceph::real_time mtime) override; + virtual bool is_owner(RGWUser* user) override; + virtual int check_empty(optional_yield y) override; + virtual int check_quota(RGWQuotaInfo& user_quota, RGWQuotaInfo& bucket_quota, uint64_t obj_size) override; + virtual std::unique_ptr clone() { + return std::unique_ptr(new RGWRadosBucket(*this)); + } + + friend class RGWRadosStore; }; class RGWRadosStore : public RGWStore { @@ -294,9 +482,24 @@ class RGWRadosStore : public RGWStore { delete rados; } - virtual RGWUser* get_user(const rgw_user& u); - virtual int get_bucket(RGWUser& u, const rgw_bucket& b, RGWBucket** bucket) override; - //virtual RGWBucket* create_bucket(RGWUser& u, const rgw_bucket& b); + virtual std::unique_ptr get_user(const rgw_user& u); + virtual std::unique_ptr get_object(const rgw_obj_key& k) override; + virtual int get_bucket(RGWUser* u, const rgw_bucket& b, std::unique_ptr* bucket) override; + virtual int get_bucket(RGWUser* u, const RGWBucketInfo& i, std::unique_ptr* bucket) override; + virtual int get_bucket(RGWUser* u, const std::string& tenant, const std::string&name, std::unique_ptr* bucket) override; + virtual int create_bucket(RGWUser& u, const rgw_bucket& b, + const string& zonegroup_id, + const rgw_placement_rule& placement_rule, + const string& swift_ver_location, + const RGWQuotaInfo * pquota_info, + map& attrs, + RGWBucketInfo& info, + obj_version& ep_objv, + bool exclusive, + bool obj_lock_enabled, + bool *existed, + req_info& req_info, + std::unique_ptr* bucket); virtual RGWBucketList* list_buckets(void) { return new RGWBucketList(); } void setRados(RGWRados * st) { rados = st; } @@ -310,6 +513,16 @@ class RGWRadosStore : public RGWStore { void finalize(void) override; virtual CephContext *ctx(void) { return rados->ctx(); } + + // implements DoutPrefixProvider + std::ostream& gen_prefix(std::ostream& out) const { return out << "RGWRadosStore "; } + CephContext* get_cct() const override { return rados->ctx(); } + unsigned get_subsys() const override { return ceph_subsys_rgw; } + + private: + int forward_request_to_master(RGWUser* user, obj_version *objv, + bufferlist& in_data, JSONParser *jp, req_info& info); + }; } } // namespace rgw::sal diff --git a/src/rgw/rgw_swift_auth.cc b/src/rgw/rgw_swift_auth.cc index 44bb3efd9e30..242d24294ef6 100644 --- a/src/rgw/rgw_swift_auth.cc +++ b/src/rgw/rgw_swift_auth.cc @@ -48,7 +48,7 @@ void TempURLApplier::modify_request_state(const DoutPrefixProvider* dpp, req_sta s->content_disp.override = "attachment; filename=\"" + fenc + "\""; } else { std::string fenc; - url_encode(s->object.name, fenc); + url_encode(s->object->get_name(), fenc); s->content_disp.fallback = "attachment; filename=\"" + fenc + "\""; } @@ -74,7 +74,7 @@ void TempURLEngine::get_owner_info(const DoutPrefixProvider* dpp, const req_stat const string& bucket_name = s->init_state.url_bucket; /* TempURL requires that bucket and object names are specified. */ - if (bucket_name.empty() || s->object.empty()) { + if (bucket_name.empty() || s->object->empty()) { throw -EPERM; } @@ -351,7 +351,7 @@ TempURLEngine::authenticate(const DoutPrefixProvider* dpp, const req_state* cons /* Need to try each combination of keys, allowed path and methods. */ PrefixableSignatureHelper sig_helper { s->decoded_uri, - s->object.name, + s->object->get_name(), temp_url_prefix }; diff --git a/src/rgw/rgw_swift_auth.h b/src/rgw/rgw_swift_auth.h index 8cefbf1a4880..fda9d6c98333 100644 --- a/src/rgw/rgw_swift_auth.h +++ b/src/rgw/rgw_swift_auth.h @@ -337,7 +337,8 @@ public: return this; } - RGWHandler_REST* get_handler(struct req_state*, + RGWHandler_REST* get_handler(rgw::sal::RGWRadosStore *store, + struct req_state*, const rgw::auth::StrategyRegistry&, const std::string&) override { return new RGWHandler_SWIFT_Auth; diff --git a/src/rgw/rgw_sync_module_aws.cc b/src/rgw/rgw_sync_module_aws.cc index 845fb74a48f3..c837070c7e88 100644 --- a/src/rgw/rgw_sync_module_aws.cc +++ b/src/rgw/rgw_sync_module_aws.cc @@ -35,9 +35,9 @@ static string get_key_oid(const rgw_obj_key& key) return oid; } -static string obj_to_aws_path(const rgw_obj& obj) +static string obj_to_aws_path(rgw::sal::RGWObject* obj) { - string path = obj.bucket.name + "/" + get_key_oid(obj.key); + string path = obj->get_bucket()->get_name() + "/" + get_key_oid(obj->get_key()); return path; @@ -717,7 +717,7 @@ class RGWRESTStreamGetCRF : public RGWStreamReadHTTPResourceCRF { RGWDataSyncCtx *sc; RGWRESTConn *conn; - rgw_obj src_obj; + rgw::sal::RGWObject* src_obj; RGWRESTConn::get_obj_params req_params; rgw_sync_aws_src_obj_properties src_properties; @@ -727,9 +727,9 @@ public: RGWCoroutine *_caller, RGWDataSyncCtx *_sc, RGWRESTConn *_conn, - rgw_obj& _src_obj, + rgw::sal::RGWObject* _src_obj, const rgw_sync_aws_src_obj_properties& _src_properties) : RGWStreamReadHTTPResourceCRF(_cct, _env, _caller, - _sc->env->http_manager, _src_obj.key), + _sc->env->http_manager, _src_obj->get_key()), sc(_sc), conn(_conn), src_obj(_src_obj), src_properties(_src_properties) { } @@ -796,7 +796,7 @@ class RGWAWSStreamPutCRF : public RGWStreamWriteHTTPResourceCRF RGWDataSyncCtx *sc; rgw_sync_aws_src_obj_properties src_properties; std::shared_ptr target; - rgw_obj dest_obj; + rgw::sal::RGWObject* dest_obj; string etag; public: RGWAWSStreamPutCRF(CephContext *_cct, @@ -805,7 +805,7 @@ public: RGWDataSyncCtx *_sc, const rgw_sync_aws_src_obj_properties& _src_properties, std::shared_ptr& _target, - rgw_obj& _dest_obj) : RGWStreamWriteHTTPResourceCRF(_cct, _env, _caller, _sc->env->http_manager), + rgw::sal::RGWObject* _dest_obj) : RGWStreamWriteHTTPResourceCRF(_cct, _env, _caller, _sc->env->http_manager), sc(_sc), src_properties(_src_properties), target(_target), dest_obj(_dest_obj) { } @@ -993,8 +993,8 @@ class RGWAWSStreamObjToCloudPlainCR : public RGWCoroutine { RGWDataSyncCtx *sc; RGWRESTConn *source_conn; std::shared_ptr target; - rgw_obj src_obj; - rgw_obj dest_obj; + rgw::sal::RGWObject* src_obj; + rgw::sal::RGWObject* dest_obj; rgw_sync_aws_src_obj_properties src_properties; @@ -1004,10 +1004,10 @@ class RGWAWSStreamObjToCloudPlainCR : public RGWCoroutine { public: RGWAWSStreamObjToCloudPlainCR(RGWDataSyncCtx *_sc, RGWRESTConn *_source_conn, - const rgw_obj& _src_obj, + rgw::sal::RGWObject* _src_obj, const rgw_sync_aws_src_obj_properties& _src_properties, std::shared_ptr _target, - const rgw_obj& _dest_obj) : RGWCoroutine(_sc->cct), + rgw::sal::RGWObject* _dest_obj) : RGWCoroutine(_sc->cct), sc(_sc), source_conn(_source_conn), target(_target), @@ -1042,8 +1042,8 @@ class RGWAWSStreamObjToCloudMultipartPartCR : public RGWCoroutine { RGWDataSyncCtx *sc; RGWRESTConn *source_conn; std::shared_ptr target; - rgw_obj src_obj; - rgw_obj dest_obj; + rgw::sal::RGWObject* src_obj; + rgw::sal::RGWObject* dest_obj; rgw_sync_aws_src_obj_properties src_properties; @@ -1059,9 +1059,9 @@ class RGWAWSStreamObjToCloudMultipartPartCR : public RGWCoroutine { public: RGWAWSStreamObjToCloudMultipartPartCR(RGWDataSyncCtx *_sc, RGWRESTConn *_source_conn, - const rgw_obj& _src_obj, + rgw::sal::RGWObject* _src_obj, std::shared_ptr& _target, - const rgw_obj& _dest_obj, + rgw::sal::RGWObject* _dest_obj, const rgw_sync_aws_src_obj_properties& _src_properties, const string& _upload_id, const rgw_sync_aws_multipart_part_info& _part_info, @@ -1111,14 +1111,14 @@ public: class RGWAWSAbortMultipartCR : public RGWCoroutine { RGWDataSyncCtx *sc; RGWRESTConn *dest_conn; - rgw_obj dest_obj; + rgw::sal::RGWObject* dest_obj; string upload_id; public: RGWAWSAbortMultipartCR(RGWDataSyncCtx *_sc, RGWRESTConn *_dest_conn, - const rgw_obj& _dest_obj, + rgw::sal::RGWObject* _dest_obj, const string& _upload_id) : RGWCoroutine(_sc->cct), sc(_sc), dest_conn(_dest_conn), @@ -1150,7 +1150,7 @@ public: class RGWAWSInitMultipartCR : public RGWCoroutine { RGWDataSyncCtx *sc; RGWRESTConn *dest_conn; - rgw_obj dest_obj; + rgw::sal::RGWObject* dest_obj; uint64_t obj_size; map attrs; @@ -1174,7 +1174,7 @@ class RGWAWSInitMultipartCR : public RGWCoroutine { public: RGWAWSInitMultipartCR(RGWDataSyncCtx *_sc, RGWRESTConn *_dest_conn, - const rgw_obj& _dest_obj, + rgw::sal::RGWObject* _dest_obj, uint64_t _obj_size, const map& _attrs, string *_upload_id) : RGWCoroutine(_sc->cct), @@ -1240,7 +1240,7 @@ public: class RGWAWSCompleteMultipartCR : public RGWCoroutine { RGWDataSyncCtx *sc; RGWRESTConn *dest_conn; - rgw_obj dest_obj; + rgw::sal::RGWObject* dest_obj; bufferlist out_bl; @@ -1278,7 +1278,7 @@ class RGWAWSCompleteMultipartCR : public RGWCoroutine { public: RGWAWSCompleteMultipartCR(RGWDataSyncCtx *_sc, RGWRESTConn *_dest_conn, - const rgw_obj& _dest_obj, + rgw::sal::RGWObject* _dest_obj, string _upload_id, const map& _parts) : RGWCoroutine(_sc->cct), sc(_sc), @@ -1350,7 +1350,7 @@ public: class RGWAWSStreamAbortMultipartUploadCR : public RGWCoroutine { RGWDataSyncCtx *sc; RGWRESTConn *dest_conn; - const rgw_obj dest_obj; + rgw::sal::RGWObject* dest_obj; const rgw_raw_obj status_obj; string upload_id; @@ -1359,7 +1359,7 @@ public: RGWAWSStreamAbortMultipartUploadCR(RGWDataSyncCtx *_sc, RGWRESTConn *_dest_conn, - const rgw_obj& _dest_obj, + rgw::sal::RGWObject* _dest_obj, const rgw_raw_obj& _status_obj, const string& _upload_id) : RGWCoroutine(_sc->cct), sc(_sc), dest_conn(_dest_conn), @@ -1392,8 +1392,8 @@ class RGWAWSStreamObjToCloudMultipartCR : public RGWCoroutine { AWSSyncConfig& conf; RGWRESTConn *source_conn; std::shared_ptr target; - rgw_obj src_obj; - rgw_obj dest_obj; + rgw::sal::RGWObject* src_obj; + rgw::sal::RGWObject* dest_obj; uint64_t obj_size; string src_etag; @@ -1415,9 +1415,9 @@ public: rgw_bucket_sync_pipe& _sync_pipe, AWSSyncConfig& _conf, RGWRESTConn *_source_conn, - const rgw_obj& _src_obj, + rgw::sal::RGWObject* _src_obj, std::shared_ptr& _target, - const rgw_obj& _dest_obj, + rgw::sal::RGWObject* _dest_obj, uint64_t _obj_size, const rgw_sync_aws_src_obj_properties& _src_properties, const rgw_rest_obj& _rest_obj) : RGWCoroutine(_sc->cct), @@ -1658,13 +1658,15 @@ public: } yield { - rgw_obj src_obj(src_bucket, key); + rgw::sal::RGWRadosBucket bucket(sync_env->store, src_bucket); + rgw::sal::RGWRadosObject src_obj(sync_env->store, key, &bucket); /* init output */ rgw_bucket target_bucket; target_bucket.name = target_bucket_name; /* this is only possible because we only use bucket name for uri resolution */ - rgw_obj dest_obj(target_bucket, target_obj_name); + rgw::sal::RGWRadosBucket dest_bucket(sync_env->store, target_bucket); + rgw::sal::RGWRadosObject dest_obj(sync_env->store, rgw_obj_key(target_obj_name), &dest_bucket); rgw_sync_aws_src_obj_properties src_properties; @@ -1675,10 +1677,10 @@ public: src_properties.versioned_epoch = versioned_epoch; if (size < instance.conf.s3.multipart_sync_threshold) { - call(new RGWAWSStreamObjToCloudPlainCR(sc, source_conn, src_obj, + call(new RGWAWSStreamObjToCloudPlainCR(sc, source_conn, &src_obj, src_properties, target, - dest_obj)); + &dest_obj)); } else { rgw_rest_obj rest_obj; rest_obj.init(key); @@ -1686,8 +1688,8 @@ public: ldout(sc->cct, 0) << "ERROR: failed to decode rest obj out of headers=" << headers << ", attrs=" << attrs << dendl; return set_cr_error(-EINVAL); } - call(new RGWAWSStreamObjToCloudMultipartCR(sc, sync_pipe, instance.conf, source_conn, src_obj, - target, dest_obj, size, src_properties, rest_obj)); + call(new RGWAWSStreamObjToCloudMultipartCR(sc, sync_pipe, instance.conf, source_conn, &src_obj, + target, &dest_obj, size, src_properties, rest_obj)); } } if (retcode < 0) { diff --git a/src/rgw/rgw_sync_module_es_rest.cc b/src/rgw/rgw_sync_module_es_rest.cc index 1abeaeb83d5a..675e89196ab6 100644 --- a/src/rgw/rgw_sync_module_es_rest.cc +++ b/src/rgw/rgw_sync_module_es_rest.cc @@ -208,7 +208,7 @@ void RGWMetadataSearchOp::execute() es_query.set_restricted_fields(&restricted_fields); map custom_map; - for (auto& i : s->bucket_info.mdsearch_config) { + for (auto& i : s->bucket->get_info().mdsearch_config) { custom_map[i.first] = (ESEntityTypeMap::EntityType)i.second; } @@ -399,18 +399,19 @@ public: }; -RGWHandler_REST* RGWRESTMgr_MDSearch_S3::get_handler(struct req_state* const s, +RGWHandler_REST* RGWRESTMgr_MDSearch_S3::get_handler(rgw::sal::RGWRadosStore *store, + struct req_state* const s, const rgw::auth::StrategyRegistry& auth_registry, const std::string& frontend_prefix) { int ret = - RGWHandler_REST_S3::init_from_header(s, + RGWHandler_REST_S3::init_from_header(store, s, RGW_FORMAT_XML, true); if (ret < 0) { return nullptr; } - if (!s->object.empty()) { + if (!s->object->empty()) { return nullptr; } diff --git a/src/rgw/rgw_sync_module_es_rest.h b/src/rgw/rgw_sync_module_es_rest.h index 676cbba64e50..6e4a459499df 100644 --- a/src/rgw/rgw_sync_module_es_rest.h +++ b/src/rgw/rgw_sync_module_es_rest.h @@ -11,7 +11,8 @@ class RGWRESTMgr_MDSearch_S3 : public RGWRESTMgr { public: explicit RGWRESTMgr_MDSearch_S3() {} - RGWHandler_REST *get_handler(struct req_state* s, + RGWHandler_REST *get_handler(rgw::sal::RGWRadosStore *store, + struct req_state* s, const rgw::auth::StrategyRegistry& auth_registry, const std::string& frontend_prefix) override; }; diff --git a/src/rgw/rgw_sync_module_pubsub_rest.cc b/src/rgw/rgw_sync_module_pubsub_rest.cc index 9a77ea78627a..f2fff54cf765 100644 --- a/src/rgw/rgw_sync_module_pubsub_rest.cc +++ b/src/rgw/rgw_sync_module_pubsub_rest.cc @@ -23,7 +23,7 @@ class RGWPSCreateTopic_ObjStore : public RGWPSCreateTopicOp { public: int get_params() override { - topic_name = s->object.name; + topic_name = s->object->get_name(); opaque_data = s->info.args.get("OpaqueData"); dest.push_endpoint = s->info.args.get("push-endpoint"); @@ -87,7 +87,7 @@ public: class RGWPSGetTopic_ObjStore : public RGWPSGetTopicOp { public: int get_params() override { - topic_name = s->object.name; + topic_name = s->object->get_name(); return 0; } @@ -111,7 +111,7 @@ public: class RGWPSDeleteTopic_ObjStore : public RGWPSDeleteTopicOp { public: int get_params() override { - topic_name = s->object.name; + topic_name = s->object->get_name(); return 0; } }; @@ -135,19 +135,19 @@ protected: if (s->init_state.url_bucket.empty()) { return nullptr; } - if (s->object.empty()) { + if (s->object->empty()) { return new RGWPSListTopics_ObjStore(); } return new RGWPSGetTopic_ObjStore(); } RGWOp *op_put() override { - if (!s->object.empty()) { + if (!s->object->empty()) { return new RGWPSCreateTopic_ObjStore(); } return nullptr; } RGWOp *op_delete() override { - if (!s->object.empty()) { + if (!s->object->empty()) { return new RGWPSDeleteTopic_ObjStore(); } return nullptr; @@ -161,7 +161,7 @@ public: class RGWPSCreateSub_ObjStore : public RGWPSCreateSubOp { public: int get_params() override { - sub_name = s->object.name; + sub_name = s->object->get_name(); bool exists; topic_name = s->info.args.get("topic", &exists); @@ -190,7 +190,7 @@ public: class RGWPSGetSub_ObjStore : public RGWPSGetSubOp { public: int get_params() override { - sub_name = s->object.name; + sub_name = s->object->get_name(); return 0; } void send_response() override { @@ -213,7 +213,7 @@ public: class RGWPSDeleteSub_ObjStore : public RGWPSDeleteSubOp { public: int get_params() override { - sub_name = s->object.name; + sub_name = s->object->get_name(); topic_name = s->info.args.get("topic"); return 0; } @@ -225,7 +225,7 @@ public: explicit RGWPSAckSubEvent_ObjStore() {} int get_params() override { - sub_name = s->object.name; + sub_name = s->object->get_name(); bool exists; @@ -242,7 +242,7 @@ public: class RGWPSPullSubEvents_ObjStore : public RGWPSPullSubEventsOp { public: int get_params() override { - sub_name = s->object.name; + sub_name = s->object->get_name(); marker = s->info.args.get("marker"); const int ret = s->info.args.get_int("max-entries", &max_entries, RGWUserPubSub::Sub::DEFAULT_MAX_EVENTS); @@ -283,7 +283,7 @@ protected: return false; } RGWOp *op_get() override { - if (s->object.empty()) { + if (s->object->empty()) { return nullptr; } if (s->info.args.exists("events")) { @@ -292,13 +292,13 @@ protected: return new RGWPSGetSub_ObjStore(); } RGWOp *op_put() override { - if (!s->object.empty()) { + if (!s->object->empty()) { return new RGWPSCreateSub_ObjStore(); } return nullptr; } RGWOp *op_delete() override { - if (!s->object.empty()) { + if (!s->object->empty()) { return new RGWPSDeleteSub_ObjStore(); } return nullptr; @@ -363,7 +363,7 @@ private: ldout(s->cct, 1) << "invalid event type in list: " << events_str << dendl; return -EINVAL; } - return notif_bucket_path(s->object.name, bucket_name); + return notif_bucket_path(s->object->get_name(), bucket_name); } public: @@ -396,7 +396,7 @@ private: ldout(s->cct, 1) << "missing required param 'topic'" << dendl; return -EINVAL; } - return notif_bucket_path(s->object.name, bucket_name); + return notif_bucket_path(s->object->get_name(), bucket_name); } public: @@ -426,7 +426,7 @@ private: rgw_pubsub_bucket_topics result; int get_params() override { - return notif_bucket_path(s->object.name, bucket_name); + return notif_bucket_path(s->object->get_name(), bucket_name); } public: @@ -472,19 +472,19 @@ protected: return false; } RGWOp *op_get() override { - if (s->object.empty()) { + if (s->object->empty()) { return nullptr; } return new RGWPSListNotifs_ObjStore(); } RGWOp *op_put() override { - if (!s->object.empty()) { + if (!s->object->empty()) { return new RGWPSCreateNotif_ObjStore(); } return nullptr; } RGWOp *op_delete() override { - if (!s->object.empty()) { + if (!s->object->empty()) { return new RGWPSDeleteNotif_ObjStore(); } return nullptr; @@ -495,11 +495,12 @@ public: }; // factory for ceph specific PubSub REST handlers -RGWHandler_REST* RGWRESTMgr_PubSub::get_handler(struct req_state* const s, - const rgw::auth::StrategyRegistry& auth_registry, - const std::string& frontend_prefix) +RGWHandler_REST* RGWRESTMgr_PubSub::get_handler(rgw::sal::RGWRadosStore *store, + struct req_state* const s, + const rgw::auth::StrategyRegistry& auth_registry, + const std::string& frontend_prefix) { - if (RGWHandler_REST_S3::init_from_header(s, RGW_FORMAT_JSON, true) < 0) { + if (RGWHandler_REST_S3::init_from_header(store, s, RGW_FORMAT_JSON, true) < 0) { return nullptr; } diff --git a/src/rgw/rgw_sync_module_pubsub_rest.h b/src/rgw/rgw_sync_module_pubsub_rest.h index 4990dbbedd0d..c558ecd0c818 100644 --- a/src/rgw/rgw_sync_module_pubsub_rest.h +++ b/src/rgw/rgw_sync_module_pubsub_rest.h @@ -7,7 +7,8 @@ class RGWRESTMgr_PubSub : public RGWRESTMgr { public: - virtual RGWHandler_REST* get_handler(struct req_state* s, + virtual RGWHandler_REST* get_handler(rgw::sal::RGWRadosStore *store, + struct req_state* s, const rgw::auth::StrategyRegistry& auth_registry, const std::string& frontend_prefix) override; }; diff --git a/src/rgw/rgw_tools.cc b/src/rgw/rgw_tools.cc index af5e05cca64a..716a1086c816 100644 --- a/src/rgw/rgw_tools.cc +++ b/src/rgw/rgw_tools.cc @@ -500,15 +500,17 @@ int RGWDataAccess::Object::put(bufferlist& data, rgw::BlockingAioThrottle aio(store->ctx()->_conf->rgw_put_obj_min_window_size); RGWObjectCtx obj_ctx(store); - rgw_obj obj(bucket_info.bucket, key); + std::unique_ptr b; + store->get_bucket(NULL, bucket_info, &b); + std::unique_ptr obj = b->get_object(key); auto& owner = bucket->policy.get_owner(); string req_id = store->svc()->zone_utils->unique_id(store->getRados()->get_new_req_id()); using namespace rgw::putobj; - AtomicObjectProcessor processor(&aio, store, bucket_info, nullptr, - owner.get_id(), obj_ctx, obj, olh_epoch, + AtomicObjectProcessor processor(&aio, store, b.get(), nullptr, + owner.get_id(), obj_ctx, obj->get_obj(), olh_epoch, req_id, dpp, y); int ret = processor.prepare(y); diff --git a/src/rgw/rgw_torrent.cc b/src/rgw/rgw_torrent.cc index b4501aad1fe9..a9f65226779d 100644 --- a/src/rgw/rgw_torrent.cc +++ b/src/rgw/rgw_torrent.cc @@ -248,10 +248,10 @@ int seed::save_torrent_file() { int op_ret = 0; string key = RGW_OBJ_TORRENT; - rgw_obj obj(s->bucket, s->object.name); + rgw_obj obj(s->bucket->get_bi(), s->object->get_name()); rgw_raw_obj raw_obj; - store->getRados()->obj_to_raw(s->bucket_info.placement_rule, obj, &raw_obj); + store->getRados()->obj_to_raw(s->bucket->get_info().placement_rule, obj, &raw_obj); auto obj_ctx = store->svc()->sysobj->init_obj_ctx(); auto sysobj = obj_ctx.get_obj(raw_obj); diff --git a/src/rgw/rgw_user.cc b/src/rgw/rgw_user.cc index 887bdac6b379..d6a7aa74b982 100644 --- a/src/rgw/rgw_user.cc +++ b/src/rgw/rgw_user.cc @@ -64,13 +64,11 @@ int rgw_user_sync_all_stats(rgw::sal::RGWRadosStore *store, const rgw_user& user ldout(cct, 0) << "failed to read user buckets: ret=" << ret << dendl; return ret; } - map& buckets = user_buckets.get_buckets(); - for (map::iterator i = buckets.begin(); - i != buckets.end(); - ++i) { + auto& buckets = user_buckets.get_buckets(); + for (auto i = buckets.begin(); i != buckets.end(); ++i) { marker = i->first; - rgw::sal::RGWBucket* bucket = i->second; + auto& bucket = i->second; ret = bucket->get_bucket_info(null_yield); if (ret < 0) { @@ -114,11 +112,11 @@ int rgw_user_get_all_buckets_stats(rgw::sal::RGWRadosStore *store, const rgw_use ldout(cct, 0) << "failed to read user buckets: ret=" << ret << dendl; return ret; } - std::map& m = buckets.get_buckets(); + auto& m = buckets.get_buckets(); for (const auto& i : m) { marker = i.first; - rgw::sal::RGWBucket* bucket_ent = i.second; + auto& bucket_ent = i.second; ret = bucket_ent->read_bucket_stats(null_yield); if (ret < 0) { ldout(cct, 0) << "ERROR: could not get bucket stats: ret=" << ret << dendl; @@ -1644,11 +1642,10 @@ int RGWUser::execute_rename(RGWUserAdminOpState& op_state, std::string *err_msg) return ret; } - map& m = buckets.get_buckets(); - std::map::iterator it; + auto& m = buckets.get_buckets(); - for (it = m.begin(); it != m.end(); ++it) { - rgw::sal::RGWBucket* bucket = it->second; + for (auto it = m.begin(); it != m.end(); ++it) { + auto& bucket = it->second; marker = it->first; ret = bucket->get_bucket_info(null_yield); @@ -1884,15 +1881,15 @@ int RGWUser::execute_remove(RGWUserAdminOpState& op_state, std::string *err_msg, return ret; } - std::map& m = buckets.get_buckets(); + auto& m = buckets.get_buckets(); if (!m.empty() && !purge_data) { set_err_msg(err_msg, "must specify purge data to remove user with buckets"); return -EEXIST; // change to code that maps to 409: conflict } - std::map::iterator it; - for (it = m.begin(); it != m.end(); ++it) { - ret = it->second->remove_bucket(true, y); + std::string prefix, delimiter; + for (auto it = m.begin(); it != m.end(); ++it) { + ret = it->second->remove_bucket(true, prefix, delimiter, y); if (ret < 0) { set_err_msg(err_msg, "unable to delete user data"); return ret; @@ -2039,13 +2036,12 @@ int RGWUser::execute_modify(RGWUserAdminOpState& op_state, std::string *err_msg) return ret; } - std::map& m = buckets.get_buckets(); - std::map::iterator iter; + auto& m = buckets.get_buckets(); vector bucket_names; - for (iter = m.begin(); iter != m.end(); ++iter) { - rgw::sal::RGWBucket* obj = iter->second; - bucket_names.push_back(obj->get_bi()); + for (auto iter = m.begin(); iter != m.end(); ++iter) { + auto& bucket = iter->second; + bucket_names.push_back(bucket->get_bi()); marker = iter->first; }