]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
Zipper Object
authorDaniel Gryniewicz <dang@redhat.com>
Thu, 19 Dec 2019 17:23:57 +0000 (12:23 -0500)
committerDaniel Gryniewicz <dang@redhat.com>
Fri, 17 Jul 2020 16:05:49 +0000 (12:05 -0400)
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 <dang@redhat.com>
58 files changed:
src/rgw/rgw_admin.cc
src/rgw/rgw_bucket.cc
src/rgw/rgw_common.cc
src/rgw/rgw_common.h
src/rgw/rgw_cr_rados.cc
src/rgw/rgw_data_sync.cc
src/rgw/rgw_data_sync.h
src/rgw/rgw_file.cc
src/rgw/rgw_file.h
src/rgw/rgw_lc.cc
src/rgw/rgw_lib.h
src/rgw/rgw_log.cc
src/rgw/rgw_multi.cc
src/rgw/rgw_notify.cc
src/rgw/rgw_notify.h
src/rgw/rgw_op.cc
src/rgw/rgw_op.h
src/rgw/rgw_opa.cc
src/rgw/rgw_os_lib.cc
src/rgw/rgw_process.cc
src/rgw/rgw_putobj_processor.cc
src/rgw/rgw_putobj_processor.h
src/rgw/rgw_rados.cc
src/rgw/rgw_rados.h
src/rgw/rgw_rest.cc
src/rgw/rgw_rest.h
src/rgw/rgw_rest_bucket.h
src/rgw/rgw_rest_client.cc
src/rgw/rgw_rest_client.h
src/rgw/rgw_rest_config.h
src/rgw/rgw_rest_conn.cc
src/rgw/rgw_rest_conn.h
src/rgw/rgw_rest_iam.cc
src/rgw/rgw_rest_iam.h
src/rgw/rgw_rest_log.h
src/rgw/rgw_rest_metadata.h
src/rgw/rgw_rest_realm.cc
src/rgw/rgw_rest_realm.h
src/rgw/rgw_rest_s3.cc
src/rgw/rgw_rest_s3.h
src/rgw/rgw_rest_sts.cc
src/rgw/rgw_rest_sts.h
src/rgw/rgw_rest_swift.cc
src/rgw/rgw_rest_swift.h
src/rgw/rgw_rest_usage.h
src/rgw/rgw_rest_user.h
src/rgw/rgw_sal.cc
src/rgw/rgw_sal.h
src/rgw/rgw_swift_auth.cc
src/rgw/rgw_swift_auth.h
src/rgw/rgw_sync_module_aws.cc
src/rgw/rgw_sync_module_es_rest.cc
src/rgw/rgw_sync_module_es_rest.h
src/rgw/rgw_sync_module_pubsub_rest.cc
src/rgw/rgw_sync_module_pubsub_rest.h
src/rgw/rgw_tools.cc
src/rgw/rgw_torrent.cc
src/rgw/rgw_user.cc

index 2bdc9726c871af6241f04934323b2c014b2cee78..c2ffe613a347a54bbdec181df0ee8a49fa1eb9c9 100644 (file)
@@ -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<string, bufferlist> 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<string, bufferlist>::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 {
index 8b197b2db97adbda233ab6c687885a455bd71d0d..1d59d1e3f4fef3ef36e19105a6622ced65907ac9 100644 (file)
@@ -276,13 +276,13 @@ void check_bad_user_bucket_mapping(rgw::sal::RGWRadosStore *store, const rgw_use
       return;
     }
 
-    map<string, rgw::sal::RGWBucket*>& buckets = user_buckets.get_buckets();
-    for (map<string, rgw::sal::RGWBucket*>::iterator i = buckets.begin();
+    map<string, std::unique_ptr<rgw::sal::RGWBucket>>& 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<string, rgw::sal::RGWBucket*>& m_buckets = buckets.get_buckets();
+      map<string, std::unique_ptr<rgw::sal::RGWBucket>>& 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<string, rgw::sal::RGWBucket*>& m = buckets.get_buckets();
+      map<string, std::unique_ptr<rgw::sal::RGWBucket>>& m = buckets.get_buckets();
 
       for (const auto& i : m) {
         const std::string& obj_name = i.first;
index 9f62edb2bb4f7f80120aca84f04f3fb3b6c859ed..003f82c728456dc6f15576e26d0b23760335a2e3 100644 (file)
@@ -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(),
index d41aa61613611e6f4d751d18d9f0de294be8263c..ca2334d62ed00fcccdf2817998445dab20865543 100644 (file)
@@ -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<rgw::sal::RGWBucket> bucket;
+  std::unique_ptr<rgw::sal::RGWObject> object;
   string src_tenant_name;
   string src_bucket_name;
-  rgw_obj_key src_object;
+  std::unique_ptr<rgw::sal::RGWObject> 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<std::string, ceph::bufferlist> 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. */
index 390e5bd9ed7479152ebcc622c24e6e9f60da17b5..faf0ee6a4dba8a54d81b7028c08601f504561651 100644 (file)
@@ -635,18 +635,19 @@ int RGWAsyncFetchRemoteObj::_send_request()
   snprintf(buf, sizeof(buf), ".%lld", (long long)store->getRados()->instance_id());
   map<string, bufferlist> 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<uint64_t> 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 * */
index deaf913559e5a5f2e5e8cb97e8c1e7964c85e61d..5e5346b864cff5b26344a7f94c2e515c16141f20 100644 (file)
@@ -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 {
index 18d52b03197f4815d3e750142953757ca71a9cd9..ec8e648cd51f50b884f98ece8be10604f983a2a1 100644 (file)
@@ -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
index 68fd775640c5fb90293e0c35faa6a6247d379e95..a7d8f8b912252d6aba6b9d0faffce19403e436d8 100644 (file)
@@ -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<RGWObjectCtx *>(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;
index b8d44ec6424d0b5adc24de32550b96715144281e..89d1ed25eef81d20fea142e52c74d9e8fcf40577 100644 (file)
@@ -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<string, rgw::sal::RGWBucket*>& 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<std::string, buffer::list> 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;
index b3ccc97a809dc42dc10295b94f426b6b89a8fac8..5ef112daffd6a6fd43afda13fe655afa913780df 100644 (file)
@@ -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 " 
index 3117f3c3468397b9fac248841b6523b59a366aba..bf1af58754099cca2b809fbaf270fc30a2ea9f6d 100644 (file)
@@ -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;
     }
index 4955715c163c69b7bb252fe2e9e264189aff374a..976869a04d7530b2f28b7952795f9562df93feb0 100644 (file)
@@ -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);
 
index 2e4858c1500699f07bf1a021df773ef460f71e1b..3bb7b260b0c16ce9a00d9a95d69cc25c91015638 100644 (file)
@@ -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);
 }
index 25b5c533bfdfd5e444a4c3da137bb5e0fb35f0cb..05b576ad3cca3ea004cd3ce176d7f0e9f8ccfae0 100644 (file)
@@ -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 {
index 64c759141518648f2667f291ad01b73f06ebaec3..fa90af2de8816eb459b97973721124d1df1935f7 100644 (file)
@@ -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,
index 0958f2871edb9c3fe8149fadf93bb12d203112ae..94af5e077b15ed6586fb46c52c48cece6f35fb9a 100644 (file)
@@ -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<Policy> 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<string, bufferlist>& attrs, rgw_obj *target_obj = nullptr)
 {
-  RGWRados::Object op_target(store->getRados(), s->bucket_info, *static_cast<RGWObjectCtx *>(s->obj_ctx), obj);
+  RGWRados::Object op_target(store->getRados(), s->bucket->get_info(), *static_cast<RGWObjectCtx *>(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<RGWObjectCtx *>(s->obj_ctx), obj);
+  RGWRados::Object op_target(store->getRados(), s->bucket->get_info(), *static_cast<RGWObjectCtx *>(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<string, bufferlist> attrs;
-  RGWRados::Object op_target(store->getRados(), s->bucket_info, *static_cast<RGWObjectCtx *>(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<RGWAccessControlPolicy>(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 <string, bufferlist> 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<typename F>
 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<string,bufferlist> 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 <string, bufferlist> attrs;
-  map <string, bufferlist> 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<string, bufferlist> 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<string, bufferlist> 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::RGWUseruser;
 
   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<Policy> _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<string, bufferlist> 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<RGWObjectCtx *>(s->obj_ctx), obj);
+  RGWRados::Object op_target(store->getRados(), s->bucket->get_info(), *static_cast<RGWObjectCtx *>(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<std::string, rgw::sal::RGWBucket*>& m = buckets.get_buckets();
+    std::map<std::string, std::unique_ptr<rgw::sal::RGWBucket>>& 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<string, rgw::sal::RGWBucket*>::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<std::string, rgw::sal::RGWBucket*>& m = buckets.get_buckets();
+      std::map<std::string, std::unique_ptr<rgw::sal::RGWBucket>>& 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<std::string, ceph::bufferlist>& 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<string, bufferlist> 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<RGWObjectCtx*>(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<MultipartObjectProcessor>(
-        &*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<AppendObjectProcessor>(
-            &*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<AtomicObjectProcessor>(
-        &*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<rgw::sal::RGWObject> 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<RGWObjectCtx*>(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<string, bufferlist> 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<string, bufferlist> 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<RGWObjectCtx *>(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<string, bufferlist> 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<string, bufferlist> 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<RGWObjectCtx *>(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<RGWAccessControlPolicy_S3*>(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<string, bufferlist> 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<string,bufferlist> 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<string, bufferlist> 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<string, bufferlist> 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<RGWObjectCtx *>(s->obj_ctx), obj);
+    RGWRados::Object op_target(store->getRados(), s->bucket->get_info(), *static_cast<RGWObjectCtx *>(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<rgw_obj_index_key> 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<int64_t>("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<RGWObjectCtx *>(s->obj_ctx), target_obj);
+  RGWRados::Object op_target(store->getRados(), s->bucket->get_info(), *static_cast<RGWObjectCtx *>(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<RGWObjectCtx *>(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<RGWObjectCtx *>(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<std::string, ceph::bufferlist> 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<RGWObjectCtx *>(s->obj_ctx);
-  RGWBucketInfo binfo;
-  std::map<std::string, ceph::bufferlist> battrs;
+  std::unique_ptr<rgw::sal::RGWBucket> 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<rgw::sal::RGWObject> 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<RGWObjectCtx *>(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<string, bufferlist> 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<string, bufferlist> 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<string, bufferlist> 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<string, bufferlist> 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;
     });
index c96bf3a42938de1bfa62db1310a9d8dfed325e8d..64611bdfd41564c5f53ed8a8a087b4f2cd54f0df 100644 (file)
@@ -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<rgw::sal::RGWBucket> 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<string, buffer::list> 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<rgw::sal::RGWBucket> src_bucket;
+  std::unique_ptr<rgw::sal::RGWObject> src_object;
+  string dest_tenant_name, dest_bucket_name, dest_obj_name;
+  std::unique_ptr<rgw::sal::RGWBucket> dest_bucket;
+  std::unique_ptr<rgw::sal::RGWObject> 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;
index 96cc5841c1d01bf63f16e0cc9e0dcd91efd060e5..4e5770300267f5c95da203eea6416eefc0a0527a 100644 (file)
@@ -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();
 
index b4f8bb260f575e7ca410f708657e0ae35fb6f94a..d9b58f24319dd83ce0ffb5dcdaf139e362395723 100644 (file)
@@ -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 */
index e314e8b2fb9c59dce3e024d47cfb372d83bfdb8c..56560a660d720367a67ecbdc6b12a20161b44d2a 100644 (file)
@@ -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;
index 94aab6778216d5c42f29886c4def8ac336e6edd2..e3bc25ef09d3cad5cf1534752fa8fba2b7ee6cd0 100644 (file)
@@ -126,7 +126,7 @@ RadosWriter::~RadosWriter()
   std::optional<rgw_raw_obj> 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);
index 322652ed9a49610a2ab5c004deafa9ab0905cfed..b60d5ccf4772b8451f1ceeb9f7faf662d54234fa 100644 (file)
@@ -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<rgw_raw_obj>;
 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<uint64_t> 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)
index abbb5946254cfd96a7cc78ccbe055178862ad6f3..07bc831fccd8ca2c5bff140b9287748eb12ea5ad 100644 (file)
@@ -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<std::string, ceph::bufferlist> 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<string, bufferlist>& 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<string, bufferlist> 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<rgw_placement_rule> 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<string, RGWRESTConn *>::iterator iter = zonegroup_conn_map.find(src_bucket_info->zonegroup);
+      map<string, RGWRESTConn *>::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<string, bufferlist>& 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<string, bufferlist> 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<string, bufferlist>& 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<std::string, size_t>& 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,
index afd06cc53b2313f35449dd112c2ce90109bf7174..c12404c1090d2c0772ff146bfc4868b0035c5183 100644 (file)
@@ -1051,28 +1051,25 @@ public:
                                const std::string& obj_delim,
                                std::function<int(const rgw_bucket_dir_entry&)> 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<string, bufferlist>& 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<rgw_placement_rule> 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<string, bufferlist>& 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);
 
index 19ed78eeb6718ded1c5a59873e29ed470d0cfaf1..55bc28ba05dbc4b6f30c56aaaaa04936cc67c881 100644 (file)
@@ -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;
index 928f8bd822650a92058b778611f0f0fd5f98392d..754d3ca7dc46a32d30b6b4691b623618cf1b359f 100644 (file)
@@ -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
index d516ea5c54aae084805dcff1e57299468afac26e..0a7de160c1ef999061efb34d872867754b56003c 100644 (file)
@@ -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);
index c9e9729a9f32a8bec256caf09bb584345b7dc306..4ad08d8acfb39c88b3ea0ec5fcd0f0d7df886ef6 100644 (file)
@@ -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<string, bufferlist>& attrs, bool send)
+int RGWRESTStreamS3PutObj::put_obj_init(RGWAccessKey& key, rgw::sal::RGWObject* obj, uint64_t obj_size, map<string, bufferlist>& attrs, bool send)
 {
   send_init(obj);
   return send_ready(key, attrs, send);
index 1e11e3ae2ae1aba506dcce60dfe2a202e83c319b..2628806ce135010d8a6b483b93f0caeec95c5ab4 100644 (file)
@@ -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<string, bufferlist>& rgw_attrs, bool send);
   int send_ready(RGWAccessKey& key, const map<string, string>& 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<string, bufferlist>& attrs, bool send);
+  int put_obj_init(RGWAccessKey& key, rgw::sal::RGWObject* obj, uint64_t obj_size, map<string, bufferlist>& attrs, bool send);
 
   RGWGetDataCB *get_out_cb() { return out_cb; }
 };
index 99c773646963f846e0a54e18b7a29e5c564c6d6f..3fb3e871f4d26adf6849f271a498f24ba0edb535 100644 (file)
@@ -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);
index a0fafe90f9555e22cbb4615238fe3ea571ea28d0..7d70cdb39937800252aaaabef2d78b2a06f4bc16 100644 (file)
@@ -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<string, bufferlist>& attrs, bool send,
                                RGWRESTStreamS3PutObj **req)
 {
@@ -190,7 +191,7 @@ static void set_header(T val, map<string, string>& 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;
   }
index 5cbd3579a087871a21d111d4488382badd85ff0f..186f63eca9cde95dc60d23783f416e88e09d36ca 100644 (file)
@@ -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<string, bufferlist>& 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,
index 4f56d6334a0d460f3792cb629aa9ea5e27a7331b..a6cce4f7191a4c357a744d2866348b2acf377de9 100644 (file)
@@ -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);
 }
index 30e0304c37a02e1452af6425102247e8d0ebe166..1c6a0e89d32294fceef008c3577231d7ff692681 100644 (file)
@@ -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;
 };
index fa2897802bca03128213b894fab627ca18978876..62d0ba8334dde04c807e0cb0c596e24f1d5dfafe 100644 (file)
@@ -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);
index faabe288e59c8bf3f11f71556673c256f2ae46b6..78aabb63fa8d5d6351e37ba58362c36eca4bb3dd 100644 (file)
@@ -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);
index 423f9cbf4887573b21a6136ffa09b01b4fb898e0..9a14d8d5ff063e3e248550ef57453b51ced19eb1 100644 (file)
@@ -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&)
 {
index fd4401d9649d0793ccb2b8e95c07828830deefc8..84ee86b48ad919222e4db5763dd5cdb95308eedc 100644 (file)
@@ -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;
 };
index 90c4903b8d8b026efbc0e140a98d3916585e050a..3615f781af266fcd06398d4499858aa37d02f4f7 100644 (file)
@@ -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<string, rgw::sal::RGWBucket*>& m = buckets.get_buckets();
-  map<string, rgw::sal::RGWBucket*>::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<string, bufferlist>& attrs)
 {
-  RGWRados::Object op_target(store->getRados(), s->bucket_info, *static_cast<RGWObjectCtx *>(s->obj_ctx), obj);
+  RGWRados::Object op_target(store->getRados(), s->bucket->get_info(), *static_cast<RGWObjectCtx *>(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<string, bufferlist> 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("<NULL>"))
+  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<RGWObjectCtx *>(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;
     }
index 1993f647e800a8bab863d1f034e19c32a220894f..1e03134f6c5cfc3c27827cbffb12c89a7aee7fa9 100644 (file)
@@ -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;
 };
index 7ef6455cd323f63a828ff34abc905f14373b24c8..0e5c7b76d92d17c27de03d195b5ad8f5eb6c1519 100644 (file)
@@ -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);
 }
index d7227fe5af6c63c1d497d7e85ba9923983cc0590..4845010d650daade6bf189ddde1234c4c5121821 100644 (file)
@@ -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;
 };
index 7b01b57dc02b691d03d74944522c48d6c926d546..eb39090e476199dcf06d347f8d6e154436ecf4a7 100644 (file)
@@ -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<std::string, rgw::sal::RGWBucket*>& 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<std::string, rgw::sal::RGWBucket*>& 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<string, bool>::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<RGWAccessControlPolicy_SWIFT*>(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<string, bufferlist> 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<RGWObjectCtx *>(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<RGWObjectCtx *>(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("<NULL>"))
+    (!s->object->empty() ? s->object->get_key() : rgw_obj_key("<NULL>"))
            << " 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)
index cf8b224313fbb65aa8c5763514958b11e1f72f52..1ed664d02a3c3caabf2481dab43b5a0704d652ad 100644 (file)
@@ -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;
 };
index 6bffad69dd46c595eff8faf1e1bb89b79f38ef61..741ca87ca4a964209c112912935448334adcb56a 100644 (file)
@@ -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);
index 0627975949600aae0181bc648d89836bf1f1d413..a8b86101e47b8ae8c409857de88d59004a3708af 100644 (file)
@@ -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);
index 22cb33fa216b71202dfe4bb7a0ef3b38c0ade83e..8b9d95edc285d683c294405db203a3503a2b75d6 100644 (file)
 #include <unistd.h>
 #include <sstream>
 
+#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<RGWBucket>(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<RGWObject> RGWRadosStore::get_object(const rgw_obj_key& k)
 {
-  if (!object) {
-    object = new RGWRadosObject(store, key);
-  }
+  return std::unique_ptr<RGWObject>(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<RGWObjCategory, RGWStorageStats> 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<std::string, RGWBucketEnt> 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<string, RGWBucketEnt>::iterator iter = m.find(ent.bucket.name);
+  map<string, RGWBucketEnt>::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<RGWObject> RGWRadosBucket::get_object(const rgw_obj_key& k)
 {
-  return new RGWRadosUser(this, u);
+  return std::unique_ptr<RGWObject>(new RGWRadosObject(this->store, k, this));
+}
+
+std::unique_ptr<RGWUser> RGWRadosStore::get_user(const rgw_user &u)
+{
+  return std::unique_ptr<RGWUser>(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<string, bufferlist> 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 <string, bufferlist> attrs;
+  map <string, bufferlist> 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<RGWBucket>* 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<RGWBucket>* 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<RGWBucket>* 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<ceph_subsys_rgw, 15>()) {
+    ldout(cct, 15) << __func__ << " Read AccessControlPolicy";
+    RGWAccessControlPolicy_S3 *s3policy = static_cast<RGWAccessControlPolicy_S3 *>(policy);
+    s3policy->to_xml(*_dout);
+    *_dout << dendl;
+  }
+  return 0;
+}
+
+static int rgw_op_get_bucket_policy_from_attr(RGWRadosStore *store,
+                                      RGWUser& user,
+                                      map<string, bufferlist>& bucket_attrs,
+                                      RGWAccessControlPolicy *policy)
+{
+  map<string, bufferlist>::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<std::string, bufferlist>& attrs,
+                                RGWBucketInfo& info,
+                                obj_version& ep_objv,
+                                bool exclusive,
+                                bool obj_lock_enabled,
+                                bool *existed,
+                                req_info& req_info,
+                                std::unique_ptr<RGWBucket>* 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<RGWBucket> 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<RGWBucket>(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)
index 542844d03924868770b2629e11559fafe7c25378..7b27b3c3d462902e6bbe54b63eed0421f6638811 100644 (file)
@@ -27,16 +27,44 @@ class RGWBucket;
 class RGWObject;
 class RGWBucketList;
 
-typedef std::map<std::string, ceph::bufferlist> RGWAttrs;
+struct RGWAttrs {
+  std::map<std::string, ceph::buffer::list> attrs;
 
-class RGWStore {
+  RGWAttrs() {}
+  RGWAttrs(const std::map<std::string, ceph::buffer::list>&& _a) : attrs(std::move(_a)) {}
+  RGWAttrs(const std::map<std::string, ceph::buffer::list>& _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<std::string, bufferlist>::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<RGWUser> get_user(const rgw_user& u) = 0;
+    virtual std::unique_ptr<RGWObject> get_object(const rgw_obj_key& k) = 0;
+    virtual int get_bucket(RGWUser* u, const rgw_bucket& b, std::unique_ptr<RGWBucket>* bucket) = 0;
+    virtual int get_bucket(RGWUser* u, const RGWBucketInfo& i, std::unique_ptr<RGWBucket>* bucket) = 0;
+    virtual int get_bucket(RGWUser* u, const std::string& tenant, const std::string&name, std::unique_ptr<RGWBucket>* 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<std::string, bufferlist>& attrs,
+                            RGWBucketInfo& info,
+                            obj_version& ep_objv,
+                           bool exclusive,
+                           bool obj_lock_enabled,
+                           bool *existed,
+                           req_info& req_info,
+                           std::unique_ptr<RGWBucket>* 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;
+    RGWUserowner;
     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<RGWObject> 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<RGWBucket> 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 << "<NULL>";
+      else
+       out << b->info.bucket;
+      return out;
+    }
+
+    friend inline ostream& operator<<(ostream& out, const std::unique_ptr<RGWBucket>& 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<std::string, RGWBucket*> buckets;
+  std::map<std::string, std::unique_ptr<RGWBucket>> 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<string, RGWBucket*>& get_buckets() { return buckets; }
+  map<string, std::unique_ptr<RGWBucket>>& 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<RGWBucket> 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<RGWObject> 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 << "<NULL>";
+      else
+       out << o->key;
+      return out;
+    }
+    friend inline ostream& operator<<(ostream& out, const std::unique_ptr<RGWObject>& 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<RGWObject> clone() {
+      return std::unique_ptr<RGWObject>(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<RGWRadosUser&>(_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<RGWRadosUser&>(_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<RGWObject> 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<RGWBucket> clone() {
+      return std::unique_ptr<RGWBucket>(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<RGWUser> get_user(const rgw_user& u);
+    virtual std::unique_ptr<RGWObject> get_object(const rgw_obj_key& k) override;
+    virtual int get_bucket(RGWUser* u, const rgw_bucket& b, std::unique_ptr<RGWBucket>* bucket) override;
+    virtual int get_bucket(RGWUser* u, const RGWBucketInfo& i, std::unique_ptr<RGWBucket>* bucket) override;
+    virtual int get_bucket(RGWUser* u, const std::string& tenant, const std::string&name, std::unique_ptr<RGWBucket>* 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<std::string, bufferlist>& attrs,
+                            RGWBucketInfo& info,
+                            obj_version& ep_objv,
+                           bool exclusive,
+                           bool obj_lock_enabled,
+                           bool *existed,
+                           req_info& req_info,
+                           std::unique_ptr<RGWBucket>* 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
index 44bb3efd9e306452112f6a8374b80987ef61430b..242d24294ef6480a3277d573ea2e0efc7ca1d310 100644 (file)
@@ -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
   };
 
index 8cefbf1a4880da8e4707e68cb4d1964b4e7b66bd..fda9d6c98333a305c3c3062ad92d5aa1afe07198 100644 (file)
@@ -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;
index 845fb74a48f3587440eb63a7915c517f0aa51db0..c837070c7e887f3e76d3dab6720204fc71109839 100644 (file)
@@ -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<AWSSyncConfig_Profile> 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<AWSSyncConfig_Profile>& _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<AWSSyncConfig_Profile> 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<AWSSyncConfig_Profile> _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<AWSSyncConfig_Profile> 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<AWSSyncConfig_Profile>& _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<string, string> 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<string, string>& _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<int, rgw_sync_aws_multipart_part_info>& _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<AWSSyncConfig_Profile> 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<AWSSyncConfig_Profile>& _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) {
index 1abeaeb83d5a9bf0f309dc2bfdc209b6314a252a..675e89196ab6d3bd39bc62fee1e37808afec5c11 100644 (file)
@@ -208,7 +208,7 @@ void RGWMetadataSearchOp::execute()
   es_query.set_restricted_fields(&restricted_fields);
 
   map<string, ESEntityTypeMap::EntityType> 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;
   }
 
index 676cbba64e506b5657d5f913a2827f99080d3b50..6e4a459499df83fad2dd20311d00d061088c17b8 100644 (file)
@@ -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;
 };
index 9a77ea78627a847b299f9342692b0b4773d44e93..f2fff54cf765ff5859789818691bfb81e637ebda 100644 (file)
@@ -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;
   }
  
index 4990dbbedd0dd66701fb183bf377e3a5732c1c06..c558ecd0c818667f3926ec51d521a21401eb6658 100644 (file)
@@ -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;
 };
index af5e05cca64af9218e5336acef0c6713f82139ee..716a1086c8167d7b664dfe6721f2e3e339617043 100644 (file)
@@ -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<rgw::sal::RGWBucket> b;
+  store->get_bucket(NULL, bucket_info, &b);
+  std::unique_ptr<rgw::sal::RGWObject> 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);
index b4501aad1fe9250c258e999cacc726ca95e5cebc..a9f65226779d764b08799f3c216c45dc79bd798a 100644 (file)
@@ -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);
index 887bdac6b37953c24c392966e22b0c5a5b550f4f..d6a7aa74b982964f9058dffcdfb47d917b4f233c 100644 (file)
@@ -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<string, rgw::sal::RGWBucket*>& buckets = user_buckets.get_buckets();
-    for (map<string, rgw::sal::RGWBucket*>::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<std::string, rgw::sal::RGWBucket*>& 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<std::string, rgw::sal::RGWBucket*>& m = buckets.get_buckets();
-    std::map<std::string, rgw::sal::RGWBucket*>::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<std::string, rgw::sal::RGWBucket*>& 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<std::string, rgw::sal::RGWBucket*>::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<std::string, rgw::sal::RGWBucket*>& m = buckets.get_buckets();
-      std::map<std::string, rgw::sal::RGWBucket*>::iterator iter;
+      auto& m = buckets.get_buckets();
 
       vector<rgw_bucket> 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;
       }