From c466fd7bc30841c2eeef48ecccfba85d25bedb5c Mon Sep 17 00:00:00 2001 From: Daniel Gryniewicz Date: Thu, 27 Oct 2022 11:47:52 -0400 Subject: [PATCH] RGW - Zipper - Chown rework Chown was not unlinking, and was partially leaving the ownership wrong. Fix this by reworking chown. Bucket::chown now just changes ownership of the bucket from it's previous owner to a new one. An Object::chown was added to change the ownership of an object. The chown admin API was modified to loop through all the objects in a bucket, changing the ownership, so that a normal Bucket::chown doesn't need to do that anymore. Fixes https://tracker.ceph.com/issues/57936 Signed-off-by: Daniel Gryniewicz --- src/rgw/driver/dbstore/common/dbstore.h | 2 +- src/rgw/driver/rados/rgw_bucket.cc | 111 +++--------------------- src/rgw/driver/rados/rgw_bucket.h | 19 +--- src/rgw/driver/rados/rgw_data_sync.cc | 1 - src/rgw/driver/rados/rgw_sal_rados.cc | 76 ++++++++++++++-- src/rgw/driver/rados/rgw_sal_rados.h | 3 +- src/rgw/driver/rados/rgw_user.cc | 3 +- src/rgw/rgw_admin.cc | 5 +- src/rgw/rgw_bucket.cc | 61 +++++++++++++ src/rgw/rgw_bucket.h | 36 ++++++++ src/rgw/rgw_rados.cc | 2 +- src/rgw/rgw_reshard.cc | 2 +- src/rgw/rgw_rest_bucket.cc | 2 +- src/rgw/rgw_sal.h | 7 +- src/rgw/rgw_sal_daos.cc | 10 ++- src/rgw/rgw_sal_daos.h | 7 +- src/rgw/rgw_sal_dbstore.cc | 11 ++- src/rgw/rgw_sal_dbstore.h | 3 +- src/rgw/rgw_sal_filter.cc | 11 ++- src/rgw/rgw_sal_filter.h | 7 +- src/rgw/rgw_sal_motr.cc | 9 +- src/rgw/rgw_sal_motr.h | 3 +- 22 files changed, 230 insertions(+), 161 deletions(-) create mode 100644 src/rgw/rgw_bucket.h diff --git a/src/rgw/driver/dbstore/common/dbstore.h b/src/rgw/driver/dbstore/common/dbstore.h index 70dbd851544ed..41aae8d8dfcae 100644 --- a/src/rgw/driver/dbstore/common/dbstore.h +++ b/src/rgw/driver/dbstore/common/dbstore.h @@ -15,7 +15,7 @@ #include #include "rgw_sal_store.h" #include "rgw_common.h" -#include "rgw_bucket.h" +#include "driver/rados/rgw_bucket.h" #include "global/global_context.h" #include "global/global_init.h" #include "common/ceph_context.h" diff --git a/src/rgw/driver/rados/rgw_bucket.cc b/src/rgw/driver/rados/rgw_bucket.cc index 7f600fe457e2b..c8cfd26d92623 100644 --- a/src/rgw/driver/rados/rgw_bucket.cc +++ b/src/rgw/driver/rados/rgw_bucket.cc @@ -81,7 +81,7 @@ static void dump_mulipart_index_results(list& objs_to_unlink, } } -void check_bad_user_bucket_mapping(rgw::sal::Driver* driver, rgw::sal::User* user, +void check_bad_user_bucket_mapping(rgw::sal::Driver* driver, rgw::sal::User& user, bool fix, optional_yield y, const DoutPrefixProvider *dpp) @@ -94,7 +94,7 @@ void check_bad_user_bucket_mapping(rgw::sal::Driver* driver, rgw::sal::User* use size_t max_entries = cct->_conf->rgw_list_buckets_max_chunk; do { - int ret = user->list_buckets(dpp, marker, string(), max_entries, false, user_buckets, y); + int ret = user.list_buckets(dpp, marker, string(), max_entries, false, user_buckets, y); if (ret < 0) { ldout(driver->ctx(), 0) << "failed to read user buckets: " << cpp_strerror(-ret) << dendl; @@ -110,7 +110,7 @@ void check_bad_user_bucket_mapping(rgw::sal::Driver* driver, rgw::sal::User* use auto& bucket = i->second; std::unique_ptr actual_bucket; - int r = driver->get_bucket(dpp, user, user->get_tenant(), bucket->get_name(), &actual_bucket, null_yield); + int r = driver->get_bucket(dpp, &user, user.get_tenant(), bucket->get_name(), &actual_bucket, null_yield); if (r < 0) { ldout(driver->ctx(), 0) << "could not get bucket info for bucket=" << bucket << dendl; continue; @@ -123,7 +123,7 @@ void check_bad_user_bucket_mapping(rgw::sal::Driver* driver, rgw::sal::User* use cout << "bucket info mismatch: expected " << actual_bucket << " got " << bucket << std::endl; if (fix) { cout << "fixing" << std::endl; - r = actual_bucket->chown(dpp, user, nullptr, null_yield); + r = actual_bucket->chown(dpp, user, null_yield); if (r < 0) { cerr << "failed to fix bucket: " << cpp_strerror(-r) << std::endl; } @@ -246,12 +246,12 @@ bool rgw_find_bucket_by_id(const DoutPrefixProvider *dpp, CephContext *cct, rgw: int RGWBucket::chown(RGWBucketAdminOpState& op_state, const string& marker, optional_yield y, const DoutPrefixProvider *dpp, std::string *err_msg) { - int ret = bucket->chown(dpp, user.get(), user.get(), y, &marker); - if (ret < 0) { - set_err_msg(err_msg, "Failed to change object ownership: " + cpp_strerror(-ret)); - } - - return ret; + /* User passed in by rgw_admin is the new user; get the current user and set it in + * the bucket */ + std::unique_ptr old_user = driver->get_user(bucket->get_info().owner); + bucket->set_owner(old_user.get()); + + return rgw_chown_bucket_and_objects(driver, bucket.get(), user.get(), marker, err_msg, dpp, y); } int RGWBucket::set_quota(RGWBucketAdminOpState& op_state, const DoutPrefixProvider *dpp, std::string *err_msg) @@ -2738,97 +2738,6 @@ int RGWBucketCtl::do_unlink_bucket(RGWSI_Bucket_EP_Ctx& ctx, return svc.bucket->store_bucket_entrypoint_info(ctx, meta_key, ep, false, real_time(), &attrs, &ot, y, dpp); } -// TODO: remove RGWRados dependency for bucket listing -int RGWBucketCtl::chown(rgw::sal::Driver* driver, rgw::sal::Bucket* bucket, - const rgw_user& user_id, const std::string& display_name, - const std::string& marker, optional_yield y, const DoutPrefixProvider *dpp) -{ - map common_prefixes; - - rgw::sal::Bucket::ListParams params; - rgw::sal::Bucket::ListResults results; - - params.list_versions = true; - params.allow_unordered = true; - params.marker = marker; - - int count = 0; - int max_entries = 1000; - - //Loop through objects and update object acls to point to bucket owner - - do { - RGWObjectCtx obj_ctx(driver); - results.objs.clear(); - int ret = bucket->list(dpp, params, max_entries, results, y); - if (ret < 0) { - ldpp_dout(dpp, 0) << "ERROR: list objects failed: " << cpp_strerror(-ret) << dendl; - return ret; - } - - params.marker = results.next_marker; - count += results.objs.size(); - - for (const auto& obj : results.objs) { - std::unique_ptr r_obj = bucket->get_object(obj.key); - - ret = r_obj->get_obj_attrs(y, dpp); - if (ret < 0){ - ldpp_dout(dpp, 0) << "ERROR: failed to read object " << obj.key.name << cpp_strerror(-ret) << dendl; - continue; - } - const auto& aiter = r_obj->get_attrs().find(RGW_ATTR_ACL); - if (aiter == r_obj->get_attrs().end()) { - ldpp_dout(dpp, 0) << "ERROR: no acls found for object " << obj.key.name << " .Continuing with next object." << dendl; - continue; - } else { - bufferlist& bl = aiter->second; - RGWAccessControlPolicy policy(driver->ctx()); - ACLOwner owner; - try { - decode(policy, bl); - owner = policy.get_owner(); - } catch (buffer::error& err) { - ldpp_dout(dpp, 0) << "ERROR: decode policy failed" << err.what() - << dendl; - return -EIO; - } - - //Get the ACL from the policy - RGWAccessControlList& acl = policy.get_acl(); - - //Remove grant that is set to old owner - acl.remove_canon_user_grant(owner.get_id()); - - //Create a grant and add grant - ACLGrant grant; - grant.set_canon(user_id, display_name, RGW_PERM_FULL_CONTROL); - acl.add_grant(&grant); - - //Update the ACL owner to the new user - owner.set_id(user_id); - owner.set_name(display_name); - policy.set_owner(owner); - - bl.clear(); - encode(policy, bl); - - r_obj->set_atomic(); - map attrs; - attrs[RGW_ATTR_ACL] = bl; - ret = r_obj->set_obj_attrs(dpp, &attrs, nullptr, y); - if (ret < 0) { - ldpp_dout(dpp, 0) << "ERROR: modify attr failed " << cpp_strerror(-ret) << dendl; - return ret; - } - } - } - cerr << count << " objects processed in " << bucket - << ". Next marker " << params.marker.name << std::endl; - } while(results.is_truncated); - return 0; -} - int RGWBucketCtl::read_bucket_stats(const rgw_bucket& bucket, RGWBucketEnt *result, optional_yield y, diff --git a/src/rgw/driver/rados/rgw_bucket.h b/src/rgw/driver/rados/rgw_bucket.h index 6d5c73ce97ac9..c6aafd3be1a8c 100644 --- a/src/rgw/driver/rados/rgw_bucket.h +++ b/src/rgw/driver/rados/rgw_bucket.h @@ -14,6 +14,7 @@ #include "rgw_common.h" #include "rgw_tools.h" #include "rgw_metadata.h" +#include "rgw/rgw_bucket.h" #include "rgw_string.h" #include "rgw_sal.h" @@ -38,18 +39,6 @@ class RGWBucketCtl; class RGWZone; struct RGWZoneParams; -extern void init_bucket(rgw_bucket *b, const char *t, const char *n, const char *dp, const char *ip, const char *m, const char *id); -extern int rgw_bucket_parse_bucket_key(CephContext *cct, const std::string& key, - rgw_bucket* bucket, int *shard_id); - -extern std::string rgw_make_bucket_entry_name(const std::string& tenant_name, - const std::string& bucket_name); - -[[nodiscard]] int rgw_parse_url_bucket(const std::string& bucket, - const std::string& auth_tenant, - std::string &tenant_name, - std::string &bucket_name); - // this is used as a filter to RGWRados::cls_bucket_list_ordered; it // conforms to the type RGWBucketListNameFilter extern bool rgw_bucket_object_check_filter(const std::string& oid); @@ -224,7 +213,7 @@ extern int rgw_object_get_attr(rgw::sal::Driver* driver, rgw::sal::Object* obj, const char* attr_name, bufferlist& out_bl, optional_yield y); -extern void check_bad_user_bucket_mapping(rgw::sal::Driver* driver, rgw::sal::User* user, bool fix, optional_yield y, const DoutPrefixProvider *dpp); +extern void check_bad_user_bucket_mapping(rgw::sal::Driver* driver, rgw::sal::User& user, bool fix, optional_yield y, const DoutPrefixProvider *dpp); struct RGWBucketAdminOpState { rgw_user uid; @@ -689,10 +678,6 @@ public: const DoutPrefixProvider *dpp, bool update_entrypoint = true); - int chown(rgw::sal::Driver* driver, rgw::sal::Bucket* bucket, - const rgw_user& user_id, const std::string& display_name, - const std::string& marker, optional_yield y, const DoutPrefixProvider *dpp); - int read_buckets_stats(std::map& m, optional_yield y, const DoutPrefixProvider *dpp); diff --git a/src/rgw/driver/rados/rgw_data_sync.cc b/src/rgw/driver/rados/rgw_data_sync.cc index 0655df91f4aca..65f4d6bb6bf41 100644 --- a/src/rgw/driver/rados/rgw_data_sync.cc +++ b/src/rgw/driver/rados/rgw_data_sync.cc @@ -31,7 +31,6 @@ #include "services/svc_zone.h" #include "services/svc_sync_modules.h" -#include "rgw_bucket.h" #include "include/common_fwd.h" #include "include/random.h" diff --git a/src/rgw/driver/rados/rgw_sal_rados.cc b/src/rgw/driver/rados/rgw_sal_rados.cc index 577569dd5d558..1e0f30cdaac68 100644 --- a/src/rgw/driver/rados/rgw_sal_rados.cc +++ b/src/rgw/driver/rados/rgw_sal_rados.cc @@ -29,6 +29,7 @@ #include "rgw_sal_rados.h" #include "rgw_bucket.h" #include "rgw_multi.h" +#include "rgw_acl.h" #include "rgw_acl_s3.h" #include "rgw_aio.h" #include "rgw_aio_throttle.h" @@ -746,23 +747,22 @@ int RadosBucket::unlink(const DoutPrefixProvider* dpp, User* new_user, optional_ return store->ctl()->bucket->unlink_bucket(new_user->get_id(), info.bucket, y, dpp, update_entrypoint); } -int RadosBucket::chown(const DoutPrefixProvider* dpp, User* new_user, User* old_user, optional_yield y, const std::string* marker) +int RadosBucket::chown(const DoutPrefixProvider* dpp, User& new_user, optional_yield y) { std::string obj_marker; + int r; - if (marker == nullptr) - marker = &obj_marker; + if (!owner) { + ldpp_dout(dpp, 0) << __func__ << " Cannot chown without an owner " << dendl; + return -EINVAL; + } - int r = this->link(dpp, new_user, y); + r = this->unlink(dpp, owner, y); if (r < 0) { return r; } - if (!old_user) { - return r; - } - return store->ctl()->bucket->chown(store, this, new_user->get_id(), - old_user->get_display_name(), *marker, y, dpp); + return this->link(dpp, &new_user, y); } int RadosBucket::put_info(const DoutPrefixProvider* dpp, bool exclusive, ceph::real_time _mtime) @@ -1799,6 +1799,64 @@ int RadosObject::omap_set_val_by_key(const DoutPrefixProvider *dpp, const std::s return sysobj.omap().set_must_exist(must_exist).set(dpp, key, val, y); } +int RadosObject::chown(User& new_user, const DoutPrefixProvider* dpp, optional_yield y) +{ + int r = get_obj_attrs(y, dpp); + if (r < 0) { + ldpp_dout(dpp, 0) << "ERROR: failed to read object attrs " << get_name() << cpp_strerror(-r) << dendl; + return r; + } + + const auto& aiter = get_attrs().find(RGW_ATTR_ACL); + if (aiter == get_attrs().end()) { + ldpp_dout(dpp, 0) << "ERROR: no acls found for object " << get_name() << dendl; + return -EINVAL; + } + + bufferlist& bl = aiter->second; + RGWAccessControlPolicy policy(store->ctx()); + ACLOwner owner; + auto bliter = bl.cbegin(); + try { + policy.decode(bliter); + owner = policy.get_owner(); + } catch (buffer::error& err) { + ldpp_dout(dpp, 0) << "ERROR: decode policy failed" << err.what() + << dendl; + return -EIO; + } + + //Get the ACL from the policy + RGWAccessControlList& acl = policy.get_acl(); + + //Remove grant that is set to old owner + acl.remove_canon_user_grant(owner.get_id()); + + //Create a grant and add grant + ACLGrant grant; + grant.set_canon(new_user.get_id(), new_user.get_display_name(), RGW_PERM_FULL_CONTROL); + acl.add_grant(&grant); + + //Update the ACL owner to the new user + owner.set_id(new_user.get_id()); + owner.set_name(new_user.get_display_name()); + policy.set_owner(owner); + + bl.clear(); + encode(policy, bl); + + set_atomic(); + map attrs; + attrs[RGW_ATTR_ACL] = bl; + r = set_obj_attrs(dpp, &attrs, nullptr, y); + if (r < 0) { + ldpp_dout(dpp, 0) << "ERROR: modify attr failed " << cpp_strerror(-r) << dendl; + return r; + } + + return 0; +} + std::unique_ptr RadosObject::get_serializer(const DoutPrefixProvider *dpp, const std::string& lock_name) { return std::make_unique(dpp, store, this, lock_name); diff --git a/src/rgw/driver/rados/rgw_sal_rados.h b/src/rgw/driver/rados/rgw_sal_rados.h index cfd611c6e2794..d0c9ab3c9605e 100644 --- a/src/rgw/driver/rados/rgw_sal_rados.h +++ b/src/rgw/driver/rados/rgw_sal_rados.h @@ -476,6 +476,7 @@ class RadosObject : public StoreObject { Attrs* vals) override; virtual int omap_set_val_by_key(const DoutPrefixProvider *dpp, const std::string& key, bufferlist& val, bool must_exist, optional_yield y) override; + virtual int chown(User& new_user, const DoutPrefixProvider* dpp, optional_yield y) override; /* Internal to RadosStore */ int get_max_chunk_size(const DoutPrefixProvider* dpp, @@ -574,7 +575,7 @@ class RadosBucket : public StoreBucket { virtual int sync_user_stats(const DoutPrefixProvider *dpp, optional_yield y) override; virtual int update_container_stats(const DoutPrefixProvider* dpp) override; virtual int check_bucket_shards(const DoutPrefixProvider* dpp) override; - virtual int chown(const DoutPrefixProvider* dpp, User* new_user, User* old_user, optional_yield y, const std::string* marker = nullptr) override; + virtual int chown(const DoutPrefixProvider* dpp, User& new_user, optional_yield y) override; virtual int put_info(const DoutPrefixProvider* dpp, bool exclusive, ceph::real_time mtime) override; virtual bool is_owner(User* user) override; virtual int check_empty(const DoutPrefixProvider* dpp, optional_yield y) override; diff --git a/src/rgw/driver/rados/rgw_user.cc b/src/rgw/driver/rados/rgw_user.cc index 628ff0c3c95a4..7aefcfd5ddaee 100644 --- a/src/rgw/driver/rados/rgw_user.cc +++ b/src/rgw/driver/rados/rgw_user.cc @@ -1580,7 +1580,8 @@ int RGWUser::execute_rename(const DoutPrefixProvider *dpp, RGWUserAdminOpState& return ret; } - ret = bucket->chown(dpp, new_user.get(), old_user.get(), y); + ret = rgw_chown_bucket_and_objects(driver, bucket.get(), new_user.get(), + std::string(), nullptr, dpp, y); if (ret < 0) { set_err_msg(err_msg, "failed to run bucket chown" + cpp_strerror(-ret)); return ret; diff --git a/src/rgw/rgw_admin.cc b/src/rgw/rgw_admin.cc index 7506808d88207..6d90080858cf3 100644 --- a/src/rgw/rgw_admin.cc +++ b/src/rgw/rgw_admin.cc @@ -35,7 +35,6 @@ extern "C" { #include "include/str_list.h" #include "rgw_user.h" -#include "rgw_bucket.h" #include "rgw_otp.h" #include "rgw_rados.h" #include "rgw_acl.h" @@ -72,6 +71,8 @@ extern "C" { #include "services/svc_user.h" #include "services/svc_zone.h" +#include "driver/rados/rgw_bucket.h" + #define dout_context g_ceph_context #define SECRET_KEY_LEN 40 @@ -8604,7 +8605,7 @@ next: } if (opt_cmd == OPT::USER_CHECK) { - check_bad_user_bucket_mapping(driver, user.get(), fix, null_yield, dpp()); + check_bad_user_bucket_mapping(driver, *user.get(), fix, null_yield, dpp()); } if (opt_cmd == OPT::USER_STATS) { diff --git a/src/rgw/rgw_bucket.cc b/src/rgw/rgw_bucket.cc index 528c6f4bd3d58..852469b7eac93 100644 --- a/src/rgw/rgw_bucket.cc +++ b/src/rgw/rgw_bucket.cc @@ -3,6 +3,8 @@ #include "rgw_bucket.h" +#include "common/errno.h" + #define dout_subsys ceph_subsys_rgw // stolen from src/cls/version/cls_version.cc @@ -10,6 +12,12 @@ using namespace std; +static void set_err_msg(std::string *sink, std::string msg) +{ + if (sink && !msg.empty()) + *sink = msg; +} + void init_bucket(rgw_bucket *b, const char *t, const char *n, const char *dp, const char *ip, const char *m, const char *id) { b->tenant = t; @@ -123,3 +131,56 @@ int rgw_parse_url_bucket(const string &bucket, const string& auth_tenant, return 0; } +int rgw_chown_bucket_and_objects(rgw::sal::Driver* driver, rgw::sal::Bucket* bucket, + rgw::sal::User* new_user, + const std::string& marker, std::string *err_msg, + const DoutPrefixProvider *dpp, optional_yield y) +{ + /* Chown on the bucket */ + int ret = bucket->chown(dpp, *new_user, y); + if (ret < 0) { + set_err_msg(err_msg, "Failed to change object ownership: " + cpp_strerror(-ret)); + } + + /* Now chown on all the objects in the bucket */ + map common_prefixes; + + rgw::sal::Bucket::ListParams params; + rgw::sal::Bucket::ListResults results; + + params.list_versions = true; + params.allow_unordered = true; + params.marker = marker; + + int count = 0; + int max_entries = 1000; + + //Loop through objects and update object acls to point to bucket owner + + do { + results.objs.clear(); + ret = bucket->list(dpp, params, max_entries, results, y); + if (ret < 0) { + ldpp_dout(dpp, 0) << "ERROR: list objects failed: " << cpp_strerror(-ret) << dendl; + return ret; + } + + params.marker = results.next_marker; + count += results.objs.size(); + + for (const auto& obj : results.objs) { + std::unique_ptr r_obj = bucket->get_object(obj.key); + + ret = r_obj->chown(*new_user, dpp, y); + if (ret < 0) { + ldpp_dout(dpp, 0) << "ERROR: chown failed on " << r_obj << " :" << cpp_strerror(-ret) << dendl; + return ret; + } + } + cerr << count << " objects processed in " << bucket + << ". Next marker " << params.marker.name << std::endl; + } while(results.is_truncated); + + return ret; +} + diff --git a/src/rgw/rgw_bucket.h b/src/rgw/rgw_bucket.h new file mode 100644 index 0000000000000..e62b46898d8c1 --- /dev/null +++ b/src/rgw/rgw_bucket.h @@ -0,0 +1,36 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab ft=cpp + +#pragma once + +#include +#include +#include + +#include +#include + +#include "include/types.h" +#include "rgw_common.h" +#include "rgw_sal.h" + +extern void init_bucket(rgw_bucket *b, const char *t, const char *n, const char *dp, const char *ip, const char *m, const char *id); + +extern int rgw_bucket_parse_bucket_key(CephContext *cct, const std::string& key, + rgw_bucket* bucket, int *shard_id); + +extern std::string rgw_make_bucket_entry_name(const std::string& tenant_name, + const std::string& bucket_name); + +[[nodiscard]] int rgw_parse_url_bucket(const std::string& bucket, + const std::string& auth_tenant, + std::string &tenant_name, + std::string &bucket_name); + +extern int rgw_chown_bucket_and_objects(rgw::sal::Driver* driver, + rgw::sal::Bucket* bucket, + rgw::sal::User* new_user, + const std::string& marker, + std::string *err_msg, + const DoutPrefixProvider *dpp, + optional_yield y); diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index 4f2820c6cb60a..c5e5d53a3df47 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -28,7 +28,7 @@ #include "rgw_acl.h" #include "rgw_acl_s3.h" /* for dumping s3policy in debug log */ #include "rgw_aio_throttle.h" -#include "rgw_bucket.h" +#include "driver/rados/rgw_bucket.h" #include "rgw_rest_conn.h" #include "rgw_cr_rados.h" #include "rgw_cr_rest.h" diff --git a/src/rgw/rgw_reshard.cc b/src/rgw/rgw_reshard.cc index fdef4dbe71272..b2dec7af1c86e 100644 --- a/src/rgw/rgw_reshard.cc +++ b/src/rgw/rgw_reshard.cc @@ -5,7 +5,7 @@ #include #include "rgw_zone.h" -#include "rgw_bucket.h" +#include "driver/rados/rgw_bucket.h" #include "rgw_reshard.h" #include "rgw_sal.h" #include "rgw_sal_rados.h" diff --git a/src/rgw/rgw_rest_bucket.cc b/src/rgw/rgw_rest_bucket.cc index bc3be370a6afd..ebe4e429cc983 100644 --- a/src/rgw/rgw_rest_bucket.cc +++ b/src/rgw/rgw_rest_bucket.cc @@ -2,7 +2,7 @@ // vim: ts=8 sw=2 smarttab ft=cpp #include "rgw_op.h" -#include "rgw_bucket.h" +#include "driver/rados/rgw_bucket.h" #include "rgw_rest_bucket.h" #include "rgw_sal.h" diff --git a/src/rgw/rgw_sal.h b/src/rgw/rgw_sal.h index 931e9ff505c57..5de11c2bc707c 100644 --- a/src/rgw/rgw_sal.h +++ b/src/rgw/rgw_sal.h @@ -676,8 +676,9 @@ class Bucket { virtual int update_container_stats(const DoutPrefixProvider* dpp) = 0; /** Check if this bucket needs resharding, and schedule it if it does */ virtual int check_bucket_shards(const DoutPrefixProvider* dpp) = 0; - /** Change the owner of this bucket in the backing store */ - virtual int chown(const DoutPrefixProvider* dpp, User* new_user, User* old_user, optional_yield y, const std::string* marker = nullptr) = 0; + /** Change the owner of this bucket in the backing store. Current owner must be set. Does not + * change ownership of the objects in the bucket. */ + virtual int chown(const DoutPrefixProvider* dpp, User& new_user, optional_yield y) = 0; /** Store the cached bucket info into the backing store */ virtual int put_info(const DoutPrefixProvider* dpp, bool exclusive, ceph::real_time mtime) = 0; /** Check to see if the given user is the owner of this bucket */ @@ -1084,6 +1085,8 @@ class Object { /** Get a single OMAP value matching the given key */ virtual int omap_set_val_by_key(const DoutPrefixProvider *dpp, const std::string& key, bufferlist& val, bool must_exist, optional_yield y) = 0; + /** Change the ownership of this object */ + virtual int chown(User& new_user, const DoutPrefixProvider* dpp, optional_yield y) = 0; /** Check to see if the given object pointer is uninitialized */ static bool empty(const Object* o) { return (!o || o->empty()); } diff --git a/src/rgw/rgw_sal_daos.cc b/src/rgw/rgw_sal_daos.cc index a350bc9b01a2c..eaa06f5e3d3da 100644 --- a/src/rgw/rgw_sal_daos.cc +++ b/src/rgw/rgw_sal_daos.cc @@ -517,10 +517,8 @@ int DaosBucket::check_bucket_shards(const DoutPrefixProvider* dpp) { return DAOS_NOT_IMPLEMENTED_LOG(dpp); } -int DaosBucket::chown(const DoutPrefixProvider* dpp, User* new_user, - User* old_user, optional_yield y, - const std::string* marker) { - /* XXX: Update policies of all the bucket->objects with new user */ +int DaosBucket::chown(const DoutPrefixProvider* dpp, User& new_user, + optional_yield y) { return DAOS_NOT_IMPLEMENTED_LOG(dpp); } @@ -1044,6 +1042,10 @@ int DaosObject::omap_set_val_by_key(const DoutPrefixProvider* dpp, return DAOS_NOT_IMPLEMENTED_LOG(dpp); } +int DaosObject::chown(User& new_user, const DoutPrefixProvider* dpp, optional_yield y) { + return 0; +} + std::unique_ptr DaosObject::get_serializer( const DoutPrefixProvider* dpp, const std::string& lock_name) { return std::make_unique(dpp, store, this, lock_name); diff --git a/src/rgw/rgw_sal_daos.h b/src/rgw/rgw_sal_daos.h index b9fba5cce8731..5e5f04fc9ba5c 100644 --- a/src/rgw/rgw_sal_daos.h +++ b/src/rgw/rgw_sal_daos.h @@ -316,9 +316,8 @@ class DaosBucket : public StoreBucket { optional_yield y) override; virtual int update_container_stats(const DoutPrefixProvider* dpp) override; virtual int check_bucket_shards(const DoutPrefixProvider* dpp) override; - virtual int chown(const DoutPrefixProvider* dpp, User* new_user, - User* old_user, optional_yield y, - const std::string* marker = nullptr) override; + virtual int chown(const DoutPrefixProvider* dpp, User& new_user, + optional_yield y) override; virtual int put_info(const DoutPrefixProvider* dpp, bool exclusive, ceph::real_time mtime) override; virtual bool is_owner(User* user) override; @@ -687,6 +686,8 @@ class DaosObject : public StoreObject { virtual int omap_set_val_by_key(const DoutPrefixProvider* dpp, const std::string& key, bufferlist& val, bool must_exist, optional_yield y) override; + virtual int chown(User& new_user, const DoutPrefixProvider* dpp, + optional_yield y) override; bool is_open() { return ds3o != nullptr; }; // Only lookup the object, do not create diff --git a/src/rgw/rgw_sal_dbstore.cc b/src/rgw/rgw_sal_dbstore.cc index a99a412d4dd50..aa6b24612c30d 100644 --- a/src/rgw/rgw_sal_dbstore.cc +++ b/src/rgw/rgw_sal_dbstore.cc @@ -321,13 +321,11 @@ namespace rgw::sal { return 0; } - int DBBucket::chown(const DoutPrefixProvider *dpp, User* new_user, User* old_user, optional_yield y, const std::string* marker) + int DBBucket::chown(const DoutPrefixProvider *dpp, User& new_user, optional_yield y) { int ret; - ret = store->getDB()->update_bucket(dpp, "owner", info, false, &(new_user->get_id()), nullptr, nullptr, nullptr); - - /* XXX: Update policies of all the bucket->objects with new user */ + ret = store->getDB()->update_bucket(dpp, "owner", info, false, &(new_user.get_id()), nullptr, nullptr, nullptr); return ret; } @@ -722,6 +720,11 @@ namespace rgw::sal { return op_target.obj_omap_set_val_by_key(dpp, key, val, must_exist); } + int DBObject::chown(User& new_user, const DoutPrefixProvider* dpp, optional_yield y) + { + return 0; + } + std::unique_ptr DBObject::get_serializer(const DoutPrefixProvider *dpp, const std::string& lock_name) { diff --git a/src/rgw/rgw_sal_dbstore.h b/src/rgw/rgw_sal_dbstore.h index c9c07d22ac545..20d60ee90c9f2 100644 --- a/src/rgw/rgw_sal_dbstore.h +++ b/src/rgw/rgw_sal_dbstore.h @@ -202,7 +202,7 @@ protected: virtual int sync_user_stats(const DoutPrefixProvider *dpp, optional_yield y) override; virtual int update_container_stats(const DoutPrefixProvider *dpp) override; virtual int check_bucket_shards(const DoutPrefixProvider *dpp) override; - virtual int chown(const DoutPrefixProvider *dpp, User* new_user, User* old_user, optional_yield y, const std::string* marker = nullptr) override; + virtual int chown(const DoutPrefixProvider *dpp, User& new_user, optional_yield y) override; virtual int put_info(const DoutPrefixProvider *dpp, bool exclusive, ceph::real_time mtime) override; virtual bool is_owner(User* user) override; virtual int check_empty(const DoutPrefixProvider *dpp, optional_yield y) override; @@ -646,6 +646,7 @@ protected: Attrs* vals) override; virtual int omap_set_val_by_key(const DoutPrefixProvider *dpp, const std::string& key, bufferlist& val, bool must_exist, optional_yield y) override; + virtual int chown(User& new_user, const DoutPrefixProvider* dpp, optional_yield y) override; private: int read_attrs(const DoutPrefixProvider* dpp, DB::Object::Read &read_op, optional_yield y, rgw_obj* target_obj = nullptr); }; diff --git a/src/rgw/rgw_sal_filter.cc b/src/rgw/rgw_sal_filter.cc index 9888f4bb2f383..d45d3068c7c2b 100644 --- a/src/rgw/rgw_sal_filter.cc +++ b/src/rgw/rgw_sal_filter.cc @@ -731,11 +731,9 @@ int FilterBucket::check_bucket_shards(const DoutPrefixProvider* dpp) return next->check_bucket_shards(dpp); } -int FilterBucket::chown(const DoutPrefixProvider* dpp, User* new_user, - User* old_user, optional_yield y, - const std::string* marker) +int FilterBucket::chown(const DoutPrefixProvider* dpp, User& new_user, optional_yield y) { - return next->chown(dpp, new_user, old_user, y, marker); + return next->chown(dpp, new_user, y); } int FilterBucket::put_info(const DoutPrefixProvider* dpp, bool exclusive, @@ -1055,6 +1053,11 @@ int FilterObject::omap_set_val_by_key(const DoutPrefixProvider *dpp, return next->omap_set_val_by_key(dpp, key, val, must_exist, y); } +int FilterObject::chown(User& new_user, const DoutPrefixProvider* dpp, optional_yield y) +{ + return next->chown(new_user, dpp, y); +} + int FilterObject::FilterReadOp::prepare(optional_yield y, const DoutPrefixProvider* dpp) { /* Copy params into next */ diff --git a/src/rgw/rgw_sal_filter.h b/src/rgw/rgw_sal_filter.h index 19929056007bf..b6b39d82ed0c2 100644 --- a/src/rgw/rgw_sal_filter.h +++ b/src/rgw/rgw_sal_filter.h @@ -433,9 +433,8 @@ public: virtual int sync_user_stats(const DoutPrefixProvider *dpp, optional_yield y) override; virtual int update_container_stats(const DoutPrefixProvider* dpp) override; virtual int check_bucket_shards(const DoutPrefixProvider* dpp) override; - virtual int chown(const DoutPrefixProvider* dpp, User* new_user, - User* old_user, optional_yield y, - const std::string* marker = nullptr) override; + virtual int chown(const DoutPrefixProvider* dpp, User& new_user, + optional_yield y) override; virtual int put_info(const DoutPrefixProvider* dpp, bool exclusive, ceph::real_time mtime) override; virtual bool is_owner(User* user) override; @@ -671,6 +670,8 @@ public: virtual int omap_set_val_by_key(const DoutPrefixProvider *dpp, const std::string& key, bufferlist& val, bool must_exist, optional_yield y) override; + virtual int chown(User& new_user, const DoutPrefixProvider* dpp, + optional_yield y) override; virtual std::unique_ptr clone() override { return std::make_unique(*this); diff --git a/src/rgw/rgw_sal_motr.cc b/src/rgw/rgw_sal_motr.cc index 6aa12fa369a36..fdbe14f1174bb 100644 --- a/src/rgw/rgw_sal_motr.cc +++ b/src/rgw/rgw_sal_motr.cc @@ -619,11 +619,9 @@ int MotrBucket::check_bucket_shards(const DoutPrefixProvider *dpp) return 0; } -int MotrBucket::chown(const DoutPrefixProvider *dpp, User* new_user, User* old_user, optional_yield y, const std::string* marker) +int MotrBucket::chown(const DoutPrefixProvider *dpp, User& new_user, optional_yield y) { // TODO: update bucket with new owner - - /* XXX: Update policies of all the bucket->objects with new user */ return 0; } @@ -1106,6 +1104,11 @@ int MotrObject::omap_set_val_by_key(const DoutPrefixProvider *dpp, const std::st return 0; } +int MotrObject::chown(User& new_user, const DoutPrefixProvider* dpp, optional_yield y) +{ + return 0; +} + std::unique_ptr MotrObject::get_serializer(const DoutPrefixProvider *dpp, const std::string& lock_name) { diff --git a/src/rgw/rgw_sal_motr.h b/src/rgw/rgw_sal_motr.h index 5b877b7b890e3..b48310607dbda 100644 --- a/src/rgw/rgw_sal_motr.h +++ b/src/rgw/rgw_sal_motr.h @@ -319,7 +319,7 @@ class MotrBucket : public StoreBucket { virtual int sync_user_stats(const DoutPrefixProvider *dpp, optional_yield y) override; virtual int update_container_stats(const DoutPrefixProvider *dpp) override; virtual int check_bucket_shards(const DoutPrefixProvider *dpp) override; - virtual int chown(const DoutPrefixProvider *dpp, User* new_user, User* old_user, optional_yield y, const std::string* marker = nullptr) override; + virtual int chown(const DoutPrefixProvider *dpp, User& new_user, optional_yield y) override; virtual int put_info(const DoutPrefixProvider *dpp, bool exclusive, ceph::real_time mtime) override; virtual bool is_owner(User* user) override; virtual int check_empty(const DoutPrefixProvider *dpp, optional_yield y) override; @@ -674,6 +674,7 @@ class MotrObject : public StoreObject { Attrs* vals) override; virtual int omap_set_val_by_key(const DoutPrefixProvider *dpp, const std::string& key, bufferlist& val, bool must_exist, optional_yield y) override; + virtual int chown(User& new_user, const DoutPrefixProvider* dpp, optional_yield y) override; private: //int read_attrs(const DoutPrefixProvider* dpp, Motr::Object::Read &read_op, optional_yield y, rgw_obj* target_obj = nullptr); -- 2.39.5