]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: move placement rule out of rgw_bucket
authorYehuda Sadeh <yehuda@redhat.com>
Mon, 28 Nov 2016 16:27:41 +0000 (08:27 -0800)
committerYehuda Sadeh <yehuda@redhat.com>
Thu, 9 Mar 2017 17:18:54 +0000 (09:18 -0800)
Bucket's placement rule is in the bucket instance's info. Object's
placement rule is in the manifest

Signed-off-by: Yehuda Sadeh <yehuda@redhat.com>
13 files changed:
src/rgw/rgw_admin.cc
src/rgw/rgw_bucket.cc
src/rgw/rgw_common.h
src/rgw/rgw_cr_rados.cc
src/rgw/rgw_cr_rados.h
src/rgw/rgw_dencoder.cc
src/rgw/rgw_json_enc.cc
src/rgw/rgw_lc.cc
src/rgw/rgw_op.cc
src/rgw/rgw_rados.cc
src/rgw/rgw_rados.h
src/rgw/rgw_rest_swift.cc
src/rgw/rgw_torrent.cc

index 553b331d35c934e7bdda3f714751e22167728472..05783191980677b3bb3c8da8ab54cd299980d621 100644 (file)
@@ -1379,7 +1379,7 @@ int check_obj_locator_underscore(RGWBucketInfo& bucket_info, rgw_obj& obj, rgw_o
   string status = (needs_fixing ? "needs_fixing" : "ok");
 
   if ((needs_fixing || remove_bad) && fix) {
-    ret = store->fix_head_obj_locator(obj.bucket, needs_fixing, remove_bad, key);
+    ret = store->fix_head_obj_locator(bucket_info, needs_fixing, remove_bad, key);
     if (ret < 0) {
       cerr << "ERROR: fix_head_object_locator() returned ret=" << ret << std::endl;
       goto done;
@@ -1406,7 +1406,7 @@ int check_obj_tail_locator_underscore(RGWBucketInfo& bucket_info, rgw_obj& obj,
   bool needs_fixing;
   string status;
 
-  int ret = store->fix_tail_obj_locator(obj.bucket, key, fix, &needs_fixing);
+  int ret = store->fix_tail_obj_locator(bucket_info, key, fix, &needs_fixing);
   if (ret < 0) {
     cerr << "ERROR: fix_tail_object_locator_underscore() returned ret=" << ret << std::endl;
     status = "failed";
@@ -5147,9 +5147,15 @@ next:
   }
 
   if (opt_cmd == OPT_OLH_GET) {
+    RGWBucketInfo bucket_info;
+    int ret = init_bucket(tenant, bucket_name, bucket_id, bucket_info, bucket);
+    if (ret < 0) {
+      cerr << "ERROR: could not init bucket: " << cpp_strerror(-ret) << std::endl;
+      return -ret;
+    }
     RGWOLHInfo olh;
     rgw_obj obj(bucket, object);
-    int ret = store->get_olh(obj, &olh);
+    ret = store->get_olh(bucket_info, obj, &olh);
     if (ret < 0) {
       cerr << "ERROR: failed reading olh: " << cpp_strerror(-ret) << std::endl;
       return -ret;
@@ -5159,6 +5165,12 @@ next:
   }
 
   if (opt_cmd == OPT_OLH_READLOG) {
+    RGWBucketInfo bucket_info;
+    int ret = init_bucket(tenant, bucket_name, bucket_id, bucket_info, bucket);
+    if (ret < 0) {
+      cerr << "ERROR: could not init bucket: " << cpp_strerror(-ret) << std::endl;
+      return -ret;
+    }
     map<uint64_t, vector<rgw_bucket_olh_log_entry> > log;
     bool is_truncated;
 
@@ -5167,12 +5179,12 @@ next:
 
     RGWObjState *state;
 
-    int ret = store->get_obj_state(&rctx, obj, &state, false); /* don't follow olh */
+    ret = store->get_obj_state(&rctx, bucket_info, obj, &state, false); /* don't follow olh */
     if (ret < 0) {
       return -ret;
     }
 
-    ret = store->bucket_index_read_olh_log(*state, obj, 0, &log, &is_truncated);
+    ret = store->bucket_index_read_olh_log(bucket_info, *state, obj, 0, &log, &is_truncated);
     if (ret < 0) {
       cerr << "ERROR: failed reading olh: " << cpp_strerror(-ret) << std::endl;
       return -ret;
index e17be36438755c42bd3583241ed875309999bda0..da55fbfd6a87bdee5bf0237e4a8985a92e308b2c 100644 (file)
@@ -647,7 +647,7 @@ int rgw_remove_bucket_bypass_gc(RGWRados *store, rgw_bucket& bucket,
       RGWObjState *astate = NULL;
       rgw_obj obj(bucket, (*it).key);
 
-      ret = store->get_obj_state(&obj_ctx, obj, &astate, false);
+      ret = store->get_obj_state(&obj_ctx, info, obj, &astate, false);
       if (ret == -ENOENT) {
         dout(1) << "WARNING: cannot find obj state for obj " << obj.get_oid() << dendl;
         continue;
@@ -662,7 +662,7 @@ int rgw_remove_bucket_bypass_gc(RGWRados *store, rgw_bucket& bucket,
         RGWObjManifest::obj_iterator miter = manifest.obj_begin();
         rgw_obj head_obj = manifest.get_obj();
         rgw_raw_obj raw_head_obj;
-        store->obj_to_raw(head_obj, &raw_head_obj);
+        store->obj_to_raw(info.placement_rule, head_obj, &raw_head_obj);
 
 
         for (; miter != manifest.obj_end() && max_aio--; ++miter) {
index 5582e02c808d193ef95981546890b64ba22ef04d..4317de9ff54030e3e6c2cef941216352cc2fc224 100644 (file)
@@ -1826,7 +1826,6 @@ WRITE_CLASS_ENCODER(RGWBucketEnt)
 struct rgw_obj {
   rgw_bucket bucket;
   rgw_obj_key key;
-  std::string placement_id;
 
   bool in_extra_data{false}; /* in-memory only member, does not serialize */
 
@@ -1883,7 +1882,7 @@ struct rgw_obj {
     ::encode(key.ns, bl);
     ::encode(key.name, bl);
     ::encode(key.instance, bl);
-    ::encode(placement_id, bl);
+//    ::encode(placement_id, bl);
     ENCODE_FINISH(bl);
   }
   void decode(bufferlist::iterator& bl) {
@@ -1918,7 +1917,7 @@ struct rgw_obj {
       ::decode(key.ns, bl);
       ::decode(key.name, bl);
       ::decode(key.instance, bl);
-      ::decode(placement_id, bl);
+//      ::decode(placement_id, bl);
     }
     DECODE_FINISH(bl);
   }
index 2e3207777cb6d6338431989ddc38381bd8ca1cca..da9eda6e036ffa22403b24647db9807deae87a0a 100644 (file)
@@ -572,7 +572,7 @@ int RGWAsyncRemoveObj::_send_request()
 
   RGWObjState *state;
 
-  int ret = store->get_obj_state(&obj_ctx, obj, &state);
+  int ret = store->get_obj_state(&obj_ctx, bucket_info, obj, &state);
   if (ret < 0) {
     ldout(store->ctx(), 20) << __func__ << "(): get_obj_state() obj=" << obj << " returned ret=" << ret << dendl;
     return ret;
@@ -728,17 +728,17 @@ int RGWRadosTimelogTrimCR::request_complete()
 int RGWAsyncStatObj::_send_request()
 {
   rgw_raw_obj raw_obj;
-  store->obj_to_raw(obj, &raw_obj);
+  store->obj_to_raw(bucket_info.placement_rule, obj, &raw_obj);
   return store->raw_obj_stat(raw_obj, psize, pmtime, pepoch,
                              nullptr, nullptr, objv_tracker);
 }
 
 RGWStatObjCR::RGWStatObjCR(RGWAsyncRadosProcessor *async_rados, RGWRados *store,
-                           const rgw_obj& obj, uint64_t *psize,
+                           const RGWBucketInfo& _bucket_info, const rgw_obj& obj, uint64_t *psize,
                            real_time* pmtime, uint64_t *pepoch,
                            RGWObjVersionTracker *objv_tracker)
   : RGWSimpleCoroutine(store->ctx()), store(store), async_rados(async_rados),
-    obj(obj), psize(psize), pmtime(pmtime), pepoch(pepoch),
+    bucket_info(_bucket_info), obj(obj), psize(psize), pmtime(pmtime), pepoch(pepoch),
     objv_tracker(objv_tracker)
 {
 }
@@ -754,7 +754,7 @@ void RGWStatObjCR::request_cleanup()
 int RGWStatObjCR::send_request()
 {
   req = new RGWAsyncStatObj(this, stack->create_completion_notifier(),
-                            store, obj, psize, pmtime, pepoch, objv_tracker);
+                            store, bucket_info, obj, psize, pmtime, pepoch, objv_tracker);
   async_rados->queue(req);
   return 0;
 }
index a80ad5850ca28384eb358f36710322a4f86366b8..52e33717ee4a0a3daa4ddc33a6cd2a260160788a 100644 (file)
@@ -1091,6 +1091,7 @@ class RGWRadosTimelogTrimCR : public RGWSimpleCoroutine {
 
 class RGWAsyncStatObj : public RGWAsyncRadosRequest {
   RGWRados *store;
+  RGWBucketInfo bucket_info;
   rgw_obj obj;
   uint64_t *psize;
   real_time *pmtime;
@@ -1100,7 +1101,7 @@ protected:
   int _send_request() override;
 public:
   RGWAsyncStatObj(RGWCoroutine *caller, RGWAioCompletionNotifier *cn, RGWRados *store,
-                  const rgw_obj& obj, uint64_t *psize = nullptr,
+                  const RGWBucketInfo& _bucket_info, const rgw_obj& obj, uint64_t *psize = nullptr,
                   real_time *pmtime = nullptr, uint64_t *pepoch = nullptr,
                   RGWObjVersionTracker *objv_tracker = nullptr)
          : RGWAsyncRadosRequest(caller, cn), store(store), obj(obj), psize(psize),
@@ -1110,6 +1111,7 @@ public:
 class RGWStatObjCR : public RGWSimpleCoroutine {
   RGWRados *store;
   RGWAsyncRadosProcessor *async_rados;
+  RGWBucketInfo bucket_info;
   rgw_obj obj;
   uint64_t *psize;
   real_time *pmtime;
@@ -1118,7 +1120,7 @@ class RGWStatObjCR : public RGWSimpleCoroutine {
   RGWAsyncStatObj *req = nullptr;
  public:
   RGWStatObjCR(RGWAsyncRadosProcessor *async_rados, RGWRados *store,
-         const rgw_obj& obj, uint64_t *psize = nullptr,
+         const RGWBucketInfo& _bucket_info, const rgw_obj& obj, uint64_t *psize = nullptr,
          real_time* pmtime = nullptr, uint64_t *pepoch = nullptr,
          RGWObjVersionTracker *objv_tracker = nullptr);
   ~RGWStatObjCR() {
index cfeae47335e7d4f48a3fd6fe149b8571f261cb81..6ee42bfe163fe553aa2b6bac94e3eda33f3af9d3 100644 (file)
@@ -172,6 +172,7 @@ void RGWObjManifest::get_implicit_location(uint64_t cur_part_id, uint64_t cur_st
 
   if (!cur_part_id) {
     if (ofs < max_head_size) {
+      location->set_placement_rule(head_placement_rule);
       *location = obj;
       return;
     } else {
@@ -193,8 +194,8 @@ void RGWObjManifest::get_implicit_location(uint64_t cur_part_id, uint64_t cur_st
     }
   }
 
-  if (!tail_bucket.name.empty()) {
-    loc.bucket = tail_bucket;
+  if (!tail_placement.bucket.name.empty()) {
+    loc.bucket = tail_placement.bucket;
   } else {
     loc.bucket = obj.bucket;
   }
@@ -203,6 +204,7 @@ void RGWObjManifest::get_implicit_location(uint64_t cur_part_id, uint64_t cur_st
   // to get the right shadow object location
   loc.key.set_instance(tail_instance);
 
+  location->set_placement_rule(tail_placement.placement_rule);
   *location = loc;
 }
 
index 7c0b64ce229c9f5e04ffa0b5ae7ad701f00dc06f..84d3154b5e5adb0aafbf73cf1b85ab20ef383e42 100644 (file)
@@ -81,6 +81,12 @@ void RGWObjManifestRule::dump(Formatter *f) const
   encode_json("override_prefix", override_prefix, f);
 }
 
+void rgw_bucket_placement::dump(Formatter *f) const
+{
+  encode_json("bucket", bucket, f);
+  encode_json("placement_rule", placement_rule, f);
+}
+
 void RGWObjManifest::dump(Formatter *f) const
 {
   map<uint64_t, RGWObjManifestPart>::const_iterator iter = objs.begin();
@@ -97,9 +103,9 @@ void RGWObjManifest::dump(Formatter *f) const
   ::encode_json("head_size", head_size, f);
   ::encode_json("max_head_size", max_head_size, f);
   ::encode_json("prefix", prefix, f);
-  ::encode_json("tail_bucket", tail_bucket, f);
   ::encode_json("rules", rules, f);
   ::encode_json("tail_instance", tail_instance, f);
+  ::encode_json("tail_placement", tail_placement, f);
 }
 
 void rgw_log_entry::dump(Formatter *f) const
@@ -800,7 +806,6 @@ void rgw_obj::dump(Formatter *f) const
 {
   encode_json("bucket", bucket, f);
   encode_json("key", key, f);
-  encode_json("placement_id", placement_id, f);
 }
 
 void RGWDefaultSystemMetaObjInfo::dump(Formatter *f) const {
index 6bf7441d7fac455c4dbdf188ece2561c07b2964b..2be2d86b824feba9a6dd0e6d03ff34b34e045f0c 100644 (file)
@@ -339,7 +339,7 @@ int RGWLC::bucket_lc_process(string& shard_id)
             RGWObjectCtx rctx(store);
             rgw_obj obj(bucket_info.bucket, key);
             RGWObjState *state;
-            int ret = store->get_obj_state(&rctx, obj, &state, false);
+            int ret = store->get_obj_state(&rctx, bucket_info, obj, &state, false);
             if (ret < 0) {
               return ret;
             }
index 7a8a58b49087d04394a8dbfe32ab668a19fb2448..91bbf216ed36078f69b5c916f502ccc5ad794856 100644 (file)
@@ -282,7 +282,7 @@ static int modify_obj_attr(RGWRados *store, struct req_state *s, rgw_obj& obj, c
   }
   store->set_atomic(s->obj_ctx, read_op.state.obj);
   attrs[attr_name] = attr_val;
-  return store->set_attrs(s->obj_ctx, read_op.state.obj, attrs, NULL);
+  return store->set_attrs(s->obj_ctx, s->bucket_info, read_op.state.obj, attrs, NULL);
 }
 
 static int get_system_obj_attrs(RGWRados *store, struct req_state *s, rgw_raw_obj& obj, map<string, bufferlist>& attrs,
@@ -1291,7 +1291,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->defer_gc(s->obj_ctx, obj);
+    int r = store->defer_gc(s->obj_ctx, s->bucket_info, obj);
     if (r < 0) {
       dout(0) << "WARNING: could not defer gc entry for obj" << dendl;
     }
@@ -2651,7 +2651,7 @@ int RGWPutObjProcessor_Multipart::prepare(RGWRados *store, string *oid_rand)
 
   manifest.set_multipart_part_rule(store->ctx()->_conf->rgw_obj_stripe_size, num);
 
-  int r = manifest_gen.create_begin(store->ctx(), &manifest, bucket, target_obj);
+  int r = manifest_gen.create_begin(store->ctx(), &manifest, s->bucket_info.placement_rule, bucket, target_obj);
   if (r < 0) {
     return r;
   }
@@ -2740,7 +2740,7 @@ int RGWPutObjProcessor_Multipart::do_complete(size_t accounted_size,
 
   rgw_raw_obj raw_meta_obj;
 
-  store->obj_to_raw(meta_obj, &raw_meta_obj);
+  store->obj_to_raw(s->bucket_info.placement_rule, meta_obj, &raw_meta_obj);
 
   r = store->omap_set(raw_meta_obj, p, bl);
 
@@ -3627,7 +3627,7 @@ void RGWPutMetadataObject::execute()
     }
   }
 
-  op_ret = store->set_attrs(s->obj_ctx, obj, attrs, &rmattrs);
+  op_ret = store->set_attrs(s->obj_ctx, s->bucket_info, obj, attrs, &rmattrs);
 }
 
 int RGWDeleteObj::handle_slo_manifest(bufferlist& bl)
@@ -4673,7 +4673,7 @@ static int list_multipart_parts(RGWRados *store, struct req_state *s,
   obj.set_in_extra_data(true);
 
   rgw_raw_obj raw_obj;
-  store->obj_to_raw(obj, &raw_obj);
+  store->obj_to_raw(s->bucket_info.placement_rule, obj, &raw_obj);
 
   bool sorted_omap = is_v2_upload_id(upload_id) && !assume_unsorted;
 
@@ -5510,7 +5510,7 @@ void RGWSetAttrs::execute()
   store->set_atomic(s->obj_ctx, obj);
 
   if (!s->object.empty()) {
-    op_ret = store->set_attrs(s->obj_ctx, obj, attrs, nullptr);
+    op_ret = store->set_attrs(s->obj_ctx, s->bucket_info, obj, attrs, nullptr);
   } else {
     for (auto& iter : attrs) {
       s->bucket_attrs[iter.first] = std::move(iter.second);
index a4d86866bbe1d75dba8bbf520a329891e6b4d41a..964cff81f3d5686911e40aa3c379593d8a99d287 100644 (file)
@@ -120,9 +120,9 @@ static string RGW_DEFAULT_PERIOD_ROOT_POOL = "rgw.root";
 
 
 static bool rgw_get_obj_data_pool(const RGWZoneGroup& zonegroup, const RGWZoneParams& zone_params,
-                                  const rgw_obj& obj, rgw_pool *pool)
+                                  const string& placement_id, const rgw_obj& obj, rgw_pool *pool)
 {
-  if (!zone_params.get_data_pool(obj, pool)) {
+  if (!zone_params.get_head_data_pool(placement_id, obj, pool)) {
     RGWZonePlacementInfo placement;
     if (!zone_params.get_placement(zonegroup.default_placement, &placement)) {
       return false;
@@ -138,19 +138,19 @@ static bool rgw_get_obj_data_pool(const RGWZoneGroup& zonegroup, const RGWZonePa
   return true;
 }
 
-bool rgw_obj_to_raw(const RGWZoneGroup& zonegroup, const RGWZoneParams& zone_params,
-                    const rgw_obj& obj, rgw_raw_obj *raw_obj)
+static bool rgw_obj_to_raw(const RGWZoneGroup& zonegroup, const RGWZoneParams& zone_params,
+                           const string& placement_id, const rgw_obj& obj, rgw_raw_obj *raw_obj)
 {
   get_obj_bucket_and_oid_loc(obj, raw_obj->oid, raw_obj->loc);
 
-  return rgw_get_obj_data_pool(zonegroup, zone_params, obj, &raw_obj->pool);
+  return rgw_get_obj_data_pool(zonegroup, zone_params, placement_id, obj, &raw_obj->pool);
 }
 
 rgw_raw_obj rgw_obj_select::get_raw_obj(const RGWZoneGroup& zonegroup, const RGWZoneParams& zone_params) const
 {
   if (!is_raw) {
     rgw_raw_obj r;
-    rgw_obj_to_raw(zonegroup, zone_params, obj, &r);
+    rgw_obj_to_raw(zonegroup, zone_params, placement_rule, obj, &r);
     return r;
   }
   return raw_obj;
@@ -160,7 +160,7 @@ rgw_raw_obj rgw_obj_select::get_raw_obj(RGWRados *store) const
 {
   if (!is_raw) {
     rgw_raw_obj r;
-    store->obj_to_raw(obj, &r);
+    store->obj_to_raw(placement_rule, obj, &r);
     return r;
   }
   return raw_obj;
@@ -1987,12 +1987,12 @@ void RGWObjManifest::obj_iterator::operator++()
   update_location();
 }
 
-int RGWObjManifest::generator::create_begin(CephContext *cct, RGWObjManifest *_m, rgw_bucket& _b, rgw_obj& _obj)
+int RGWObjManifest::generator::create_begin(CephContext *cct, RGWObjManifest *_m, const string& placement_rule, rgw_bucket& _b, rgw_obj& _obj)
 {
   manifest = _m;
 
-  manifest->set_tail_bucket(_b);
-  manifest->set_head(_obj, 0);
+  manifest->set_tail_placement(placement_rule, _b);
+  manifest->set_head(placement_rule, _obj, 0);
   last_ofs = 0;
 
   if (manifest->get_prefix().empty()) {
@@ -2195,7 +2195,7 @@ void RGWObjManifest::convert_to_explicit(const RGWZoneGroup& zonegroup, const RG
     if (ofs == 0) {
       part.loc = obj;
     } else {
-      rgw_raw_obj_to_obj(tail_bucket, raw_loc, &part.loc);
+      rgw_raw_obj_to_obj(tail_placement.bucket, raw_loc, &part.loc);
     }
     ++iter;
     uint64_t next_ofs = iter.get_stripe_ofs();
@@ -2282,7 +2282,7 @@ RGWPutObjProcessor_Aio::~RGWPutObjProcessor_Aio()
   rgw_raw_obj raw_head;
 
   if (!head_obj.empty()) {
-    store->obj_to_raw(head_obj, &raw_head);
+    store->obj_to_raw(bucket_info.placement_rule, head_obj, &raw_head);
   }
 
   /** 
@@ -2485,7 +2485,7 @@ int RGWPutObjProcessor_Atomic::prepare_init(RGWRados *store, string *oid_rand)
 {
   RGWPutObjProcessor_Aio::prepare(store, oid_rand);
 
-  int r = store->get_max_chunk_size(head_obj, &max_chunk_size);
+  int r = store->get_max_chunk_size(bucket_info.placement_rule, head_obj, &max_chunk_size);
   if (r < 0) {
     return r;
   }
@@ -2510,7 +2510,7 @@ int RGWPutObjProcessor_Atomic::prepare(RGWRados *store, string *oid_rand)
 
   manifest.set_trivial_rule(max_chunk_size, store->ctx()->_conf->rgw_obj_stripe_size);
 
-  r = manifest_gen.create_begin(store->ctx(), &manifest, head_obj.bucket, head_obj);
+  r = manifest_gen.create_begin(store->ctx(), &manifest, bucket_info.placement_rule, head_obj.bucket, head_obj);
   if (r < 0) {
     return r;
   }
@@ -3206,10 +3206,10 @@ int RGWRados::get_max_chunk_size(const rgw_pool& pool, uint64_t *max_chunk_size)
   return 0;
 }
 
-int RGWRados::get_max_chunk_size(const rgw_obj& obj, uint64_t *max_chunk_size)
+int RGWRados::get_max_chunk_size(const string& placement_rule, const rgw_obj& obj, uint64_t *max_chunk_size)
 {
   rgw_pool pool;
-  if (!get_obj_data_pool(obj, &pool)) {
+  if (!get_obj_data_pool(placement_rule, obj, &pool)) {
     ldout(cct, 0) << "ERROR: failed to get data pool for object " << obj << dendl;
     return -EIO;
   }
@@ -5622,16 +5622,16 @@ read_omap:
   return 0;
 }
 
-bool RGWRados::get_obj_data_pool(const rgw_obj& obj, rgw_pool *pool)
+bool RGWRados::get_obj_data_pool(const string& placement_rule, const rgw_obj& obj, rgw_pool *pool)
 {
-  return rgw_get_obj_data_pool(zonegroup, zone_params, obj, pool);
+  return rgw_get_obj_data_pool(zonegroup, zone_params, placement_rule, obj, pool);
 }
 
-bool RGWRados::obj_to_raw(const rgw_obj& obj, rgw_raw_obj *raw_obj)
+bool RGWRados::obj_to_raw(const string& placement_rule, const rgw_obj& obj, rgw_raw_obj *raw_obj)
 {
   get_obj_bucket_and_oid_loc(obj, raw_obj->oid, raw_obj->loc);
 
-  return get_obj_data_pool(obj, &raw_obj->pool);
+  return get_obj_data_pool(placement_rule, obj, &raw_obj->pool);
 }
 
 int RGWRados::update_placement_map()
@@ -5735,13 +5735,13 @@ int RGWRados::create_pools(vector<string>& names, vector<int>& retcodes)
   return 0;
 }
 
-int RGWRados::get_obj_ioctx(const rgw_obj& obj, librados::IoCtx *ioctx)
+int RGWRados::get_obj_head_ioctx(const RGWBucketInfo& bucket_info, const rgw_obj& obj, librados::IoCtx *ioctx)
 {
   string oid, key;
   get_obj_bucket_and_oid_loc(obj, oid, key);
 
   rgw_pool pool;
-  if (!get_obj_data_pool(obj, &pool)) {
+  if (!get_obj_data_pool(bucket_info.placement_rule, obj, &pool)) {
     ldout(cct, 0) << "ERROR: cannot get data pool for obj=" << obj << ", probably misconfiguration" << dendl;
     return -EIO;
   }
@@ -5756,12 +5756,12 @@ int RGWRados::get_obj_ioctx(const rgw_obj& obj, librados::IoCtx *ioctx)
   return 0;
 }
 
-int RGWRados::get_obj_ref(const rgw_obj& obj, rgw_rados_ref *ref)
+int RGWRados::get_obj_head_ref(const RGWBucketInfo& bucket_info, const rgw_obj& obj, rgw_rados_ref *ref)
 {
   get_obj_bucket_and_oid_loc(obj, ref->oid, ref->key);
 
   rgw_pool pool;
-  if (!get_obj_data_pool(obj, &pool)) {
+  if (!get_obj_data_pool(bucket_info.placement_rule, obj, &pool)) {
     ldout(cct, 0) << "ERROR: cannot get data pool for obj=" << obj << ", probably misconfiguration" << dendl;
     return -EIO;
   }
@@ -5810,8 +5810,9 @@ int RGWRados::get_system_obj_ref(const rgw_raw_obj& obj, rgw_rados_ref *ref, rgw
  * fixes an issue where head objects were supposed to have a locator created, but ended
  * up without one
  */
-int RGWRados::fix_head_obj_locator(rgw_bucket& bucket, bool copy_obj, bool remove_bad, rgw_obj_key& key)
+int RGWRados::fix_head_obj_locator(const RGWBucketInfo& bucket_info, bool copy_obj, bool remove_bad, rgw_obj_key& key)
 {
+  const rgw_bucket& bucket = bucket_info.bucket;
   string oid;
   string locator;
 
@@ -5826,9 +5827,9 @@ int RGWRados::fix_head_obj_locator(rgw_bucket& bucket, bool copy_obj, bool remov
 
   librados::IoCtx ioctx;
 
-  int ret = get_obj_ioctx(obj, &ioctx);
+  int ret = get_obj_head_ioctx(bucket_info, obj, &ioctx);
   if (ret < 0) {
-    cerr << "ERROR: get_obj_ioctx() returned ret=" << ret << std::endl;
+    cerr << "ERROR: get_obj_head_ioctx() returned ret=" << ret << std::endl;
     return ret;
   }
   ioctx.locator_set_key(string()); /* override locator for this object, use empty locator */
@@ -5961,8 +5962,9 @@ done_err:
  * fixes an issue where head objects were supposed to have a locator created, but ended
  * up without one
  */
-int RGWRados::fix_tail_obj_locator(rgw_bucket& bucket, rgw_obj_key& key, bool fix, bool *need_fix)
+int RGWRados::fix_tail_obj_locator(const RGWBucketInfo& bucket_info, rgw_obj_key& key, bool fix, bool *need_fix)
 {
+  const rgw_bucket& bucket = bucket_info.bucket;
   rgw_obj obj(bucket, key);
 
   if (need_fix) {
@@ -5970,14 +5972,14 @@ int RGWRados::fix_tail_obj_locator(rgw_bucket& bucket, rgw_obj_key& key, bool fi
   }
 
   rgw_rados_ref ref;
-  int r = get_obj_ref(obj, &ref);
+  int r = get_obj_head_ref(bucket_info, obj, &ref);
   if (r < 0) {
     return r;
   }
 
   RGWObjState *astate = NULL;
   RGWObjectCtx rctx(this);
-  r = get_obj_state(&rctx, obj, &astate, false);
+  r = get_obj_state(&rctx, bucket_info, obj, &astate, false);
   if (r < 0)
     return r;
 
@@ -5990,7 +5992,7 @@ int RGWRados::fix_tail_obj_locator(rgw_bucket& bucket, rgw_obj_key& key, bool fi
       string oid;
       string locator;
 
-      rgw_raw_obj_to_obj(manifest.get_tail_bucket(), raw_loc, &loc);
+      rgw_raw_obj_to_obj(manifest.get_tail_placement().bucket, raw_loc, &loc);
 
       if (loc.key.ns.empty()) {
        /* continue, we're only interested in tail objects */
@@ -6140,7 +6142,7 @@ int RGWRados::swift_versioning_copy(RGWObjectCtx& obj_ctx,
   obj_ctx.obj.set_atomic(obj);
 
   RGWObjState * state = nullptr;
-  int r = get_obj_state(&obj_ctx, obj, &state, false);
+  int r = get_obj_state(&obj_ctx, bucket_info, obj, &state, false);
   if (r < 0) {
     return r;
   }
@@ -6357,7 +6359,7 @@ int RGWRados::Object::Write::_do_write_meta(uint64_t size, uint64_t accounted_si
     return -EIO;
   }
 
-  r = store->get_obj_ref(obj, &ref);
+  r = store->get_obj_head_ref(target->get_bucket_info(), obj, &ref);
   if (r < 0)
     return r;
 
@@ -6890,7 +6892,7 @@ int RGWRados::rewrite_obj(RGWBucketInfo& dest_bucket_info, rgw_obj& obj)
 
   uint64_t max_chunk_size;
 
-  ret = get_max_chunk_size(obj, &max_chunk_size);
+  ret = get_max_chunk_size(dest_bucket_info.placement_rule, obj, &max_chunk_size);
   if (ret < 0) {
     ldout(cct, 0) << "ERROR: failed to get max_chunk_size() for bucket " << obj.bucket << dendl;
     return ret;
@@ -7212,7 +7214,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_obj, &dest_state, false);
+    ret = get_obj_state(&obj_ctx, dest_bucket_info, dest_obj, &dest_state, false);
     if (ret < 0)
       goto set_err_state;
 
@@ -7314,7 +7316,7 @@ int RGWRados::fetch_remote_obj(RGWObjectCtx& obj_ctx,
     if (copy_if_newer && cb.is_canceled()) {
       ldout(cct, 20) << "raced with another write of obj: " << dest_obj << dendl;
       obj_ctx.obj.invalidate(dest_obj); /* object was overwritten */
-      ret = get_obj_state(&obj_ctx, dest_obj, &dest_state, false);
+      ret = get_obj_state(&obj_ctx, dest_bucket_info, dest_obj, &dest_state, false);
       if (ret < 0) {
         ldout(cct, 0) << "ERROR: " << __func__ << ": get_err_state() returned ret=" << ret << dendl;
         goto set_err_state;
@@ -7503,7 +7505,7 @@ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx,
   RGWObjManifest manifest;
   RGWObjState *astate = NULL;
 
-  ret = get_obj_state(&obj_ctx, src_obj, &astate);
+  ret = get_obj_state(&obj_ctx, src_bucket_info, src_obj, &astate);
   if (ret < 0) {
     return ret;
   }
@@ -7516,7 +7518,7 @@ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx,
   }
   uint64_t max_chunk_size;
 
-  ret = get_max_chunk_size(dest_obj, &max_chunk_size);
+  ret = get_max_chunk_size(dest_bucket_info.placement_rule, dest_obj, &max_chunk_size);
   if (ret < 0) {
     ldout(cct, 0) << "ERROR: failed to get max_chunk_size() for bucket " << dest_obj.bucket << dendl;
     return ret;
@@ -7524,11 +7526,11 @@ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx,
 
   rgw_pool src_pool;
   rgw_pool dest_pool;
-  if (!get_obj_data_pool(src_obj, &src_pool)) {
+  if (!get_obj_data_pool(src_bucket_info.placement_rule, src_obj, &src_pool)) {
     ldout(cct, 0) << "ERROR: failed to locate data pool for " << src_obj << dendl;
     return -EIO;
   }
-  if (!get_obj_data_pool(dest_obj, &dest_pool)) {
+  if (!get_obj_data_pool(dest_bucket_info.placement_rule, dest_obj, &dest_pool)) {
     ldout(cct, 0) << "ERROR: failed to locate data pool for " << dest_obj << dendl;
     return -EIO;
   }
@@ -7607,9 +7609,9 @@ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx,
 
   if (!copy_itself) {
     manifest = astate->manifest;
-    rgw_bucket& tail_bucket = manifest.get_tail_bucket();
-    if (tail_bucket.name.empty()) {
-      manifest.set_tail_bucket(src_obj.bucket);
+    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);
     }
     string oid, key;
     for (; miter != astate->manifest.obj_end(); ++miter) {
@@ -7639,9 +7641,9 @@ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx,
       goto done_ret;
     }
 
-    pmanifest->set_head(dest_obj, first_chunk.length());
+    pmanifest->set_head(dest_bucket_info.placement_rule, dest_obj, first_chunk.length());
   } else {
-    pmanifest->set_head(dest_obj, 0);
+    pmanifest->set_head(dest_bucket_info.placement_rule, dest_obj, 0);
   }
 
   write_op.meta.data = &first_chunk;
@@ -7961,7 +7963,7 @@ void RGWRados::update_gc_chain(rgw_obj& head_obj, RGWObjManifest& manifest, cls_
 {
   RGWObjManifest::obj_iterator iter;
   rgw_raw_obj raw_head;
-  obj_to_raw(head_obj, &raw_head);
+  obj_to_raw(manifest.get_head_placement_rule(), head_obj, &raw_head);
   for (iter = manifest.obj_begin(); iter != manifest.obj_end(); ++iter) {
     const rgw_raw_obj& mobj = iter.get_location().get_raw_obj(this);
     if (mobj == raw_head)
@@ -8134,7 +8136,7 @@ int RGWRados::bucket_rebuild_index(RGWBucketInfo& bucket_info)
 }
 
 
-int RGWRados::defer_gc(void *ctx, rgw_obj& obj)
+int RGWRados::defer_gc(void *ctx, const RGWBucketInfo& bucket_info, const rgw_obj& obj)
 {
   RGWObjectCtx *rctx = static_cast<RGWObjectCtx *>(ctx);
   std::string oid, key;
@@ -8144,7 +8146,7 @@ int RGWRados::defer_gc(void *ctx, rgw_obj& obj)
 
   RGWObjState *state = NULL;
 
-  int r = get_obj_state(rctx, obj, &state, false);
+  int r = get_obj_state(rctx, bucket_info, obj, &state, false);
   if (r < 0)
     return r;
 
@@ -8235,7 +8237,7 @@ int RGWRados::Object::Delete::delete_obj()
     } else {
       rgw_bucket_dir_entry dirent;
 
-      int r = store->bi_get_instance(obj, &dirent);
+      int r = store->bi_get_instance(target->get_bucket_info(), obj, &dirent);
       if (r < 0) {
         return r;
       }
@@ -8264,7 +8266,7 @@ int RGWRados::Object::Delete::delete_obj()
   }
 
   rgw_rados_ref ref;
-  int r = store->get_obj_ref(obj, &ref);
+  int r = store->get_obj_head_ref(target->get_bucket_info(), obj, &ref);
   if (r < 0) {
     return r;
   }
@@ -8380,7 +8382,7 @@ int RGWRados::Object::Delete::delete_obj()
 }
 
 int RGWRados::delete_obj(RGWObjectCtx& obj_ctx,
-                         RGWBucketInfo& bucket_info,
+                         const RGWBucketInfo& bucket_info,
                          const rgw_obj& obj,
                          int versioning_status,
                          uint16_t bilog_flags,
@@ -8511,17 +8513,17 @@ static bool has_olh_tag(map<string, bufferlist>& attrs)
   return (iter != attrs.end());
 }
 
-int RGWRados::get_olh_target_state(RGWObjectCtx& obj_ctx, const rgw_obj& obj, RGWObjState *olh_state,
-                                   RGWObjState **target_state)
+int RGWRados::get_olh_target_state(RGWObjectCtx& obj_ctx, const RGWBucketInfo& bucket_info, const rgw_obj& obj,
+                                   RGWObjState *olh_state, RGWObjState **target_state)
 {
   assert(olh_state->is_olh);
 
   rgw_obj target;
-  int r = RGWRados::follow_olh(obj_ctx, olh_state, obj, &target); /* might return -EAGAIN */
+  int r = RGWRados::follow_olh(bucket_info, obj_ctx, olh_state, obj, &target); /* might return -EAGAIN */
   if (r < 0) {
     return r;
   }
-  r = get_obj_state(&obj_ctx, target, target_state, false);
+  r = get_obj_state(&obj_ctx, bucket_info, target, target_state, false);
   if (r < 0) {
     return r;
   }
@@ -8574,7 +8576,8 @@ int RGWRados::get_system_obj_state(RGWObjectCtx *rctx, rgw_raw_obj& obj, RGWRawO
   return ret;
 }
 
-int RGWRados::get_obj_state_impl(RGWObjectCtx *rctx, const rgw_obj& obj, RGWObjState **state, bool follow_olh, bool assume_noent)
+int RGWRados::get_obj_state_impl(RGWObjectCtx *rctx, const RGWBucketInfo& bucket_info, const rgw_obj& obj,
+                                 RGWObjState **state, bool follow_olh, bool assume_noent)
 {
   bool need_follow_olh = follow_olh && obj.key.instance.empty();
 
@@ -8583,7 +8586,7 @@ int RGWRados::get_obj_state_impl(RGWObjectCtx *rctx, const rgw_obj& obj, RGWObjS
   *state = s;
   if (s->has_attrs) {
     if (s->is_olh && need_follow_olh) {
-      return get_olh_target_state(*rctx, obj, s, state);
+      return get_olh_target_state(*rctx, bucket_info, obj, s, state);
     }
     return 0;
   }
@@ -8591,7 +8594,7 @@ int RGWRados::get_obj_state_impl(RGWObjectCtx *rctx, const rgw_obj& obj, RGWObjS
   s->obj = obj;
 
   rgw_raw_obj raw_obj;
-  obj_to_raw(obj, &raw_obj);
+  obj_to_raw(bucket_info.placement_rule, obj, &raw_obj);
 
   int r = -ENOENT;
 
@@ -8650,7 +8653,7 @@ int RGWRados::get_obj_state_impl(RGWObjectCtx *rctx, const rgw_obj& obj, RGWObjS
     try {
       ::decode(s->manifest, miter);
       s->has_manifest = true;
-      s->manifest.set_head(obj, s->size); /* patch manifest to reflect the head we just read, some manifests might be
+      s->manifest.set_head(bucket_info.placement_rule, obj, s->size); /* patch manifest to reflect the head we just read, some manifests might be
                                              broken due to old bugs */
       s->size = s->manifest.get_obj_size();
     } catch (buffer::error& err) {
@@ -8717,19 +8720,20 @@ int RGWRados::get_obj_state_impl(RGWObjectCtx *rctx, const rgw_obj& obj, RGWObjS
     ldout(cct, 20) << __func__ << ": setting s->olh_tag to " << string(s->olh_tag.c_str(), s->olh_tag.length()) << dendl;
 
     if (need_follow_olh) {
-      return get_olh_target_state(*rctx, obj, s, state);
+      return get_olh_target_state(*rctx, bucket_info, obj, s, state);
     }
   }
 
   return 0;
 }
 
-int RGWRados::get_obj_state(RGWObjectCtx *rctx, const rgw_obj& obj, RGWObjState **state, bool follow_olh, bool assume_noent)
+int RGWRados::get_obj_state(RGWObjectCtx *rctx, const RGWBucketInfo& bucket_info, const rgw_obj& obj, RGWObjState **state,
+                            bool follow_olh, bool assume_noent)
 {
   int ret;
 
   do {
-    ret = get_obj_state_impl(rctx, obj, state, follow_olh, assume_noent);
+    ret = get_obj_state_impl(rctx, bucket_info, obj, state, follow_olh, assume_noent);
   } while (ret == -EAGAIN);
 
   return ret;
@@ -8785,7 +8789,7 @@ int RGWRados::Object::Stat::stat_async()
   string loc;
   get_obj_bucket_and_oid_loc(obj, oid, loc);
 
-  int r = store->get_obj_ioctx(obj, &state.io_ctx);
+  int r = store->get_obj_head_ioctx(source->get_bucket_info(), obj, &state.io_ctx);
   if (r < 0) {
     return r;
   }
@@ -8872,13 +8876,14 @@ int RGWRados::system_obj_get_attr(rgw_raw_obj& obj, const char *name, bufferlist
   return 0;
 }
 
-int RGWRados::append_atomic_test(RGWObjectCtx *rctx, const rgw_obj& obj,
-                            ObjectOperation& op, RGWObjState **pstate)
+int RGWRados::append_atomic_test(RGWObjectCtx *rctx,
+                                 const RGWBucketInfo& bucket_info, const rgw_obj& obj,
+                                 ObjectOperation& op, RGWObjState **pstate)
 {
   if (!rctx)
     return 0;
 
-  int r = get_obj_state(rctx, obj, pstate, false);
+  int r = get_obj_state(rctx, bucket_info, obj, pstate, false);
   if (r < 0)
     return r;
 
@@ -8899,7 +8904,7 @@ int RGWRados::append_atomic_test(RGWObjectCtx *rctx, const rgw_obj& obj,
 
 int RGWRados::Object::get_state(RGWObjState **pstate, bool follow_olh, bool assume_noent)
 {
-  return store->get_obj_state(&ctx, obj, pstate, follow_olh, assume_noent);
+  return store->get_obj_state(&ctx, bucket_info, obj, pstate, follow_olh, assume_noent);
 }
 
 void RGWRados::Object::invalidate_state()
@@ -9064,19 +9069,19 @@ int RGWRados::system_obj_set_attrs(void *ctx, rgw_raw_obj& obj,
  * bl: the contents of the attr
  * Returns: 0 on success, -ERR# otherwise.
  */
-int RGWRados::set_attr(void *ctx, rgw_obj& obj, const char *name, bufferlist& bl)
+int RGWRados::set_attr(void *ctx, const RGWBucketInfo& bucket_info, rgw_obj& obj, const char *name, bufferlist& bl)
 {
   map<string, bufferlist> attrs;
   attrs[name] = bl;
-  return set_attrs(ctx, obj, attrs, NULL);
+  return set_attrs(ctx, bucket_info, obj, attrs, NULL);
 }
 
-int RGWRados::set_attrs(void *ctx, rgw_obj& obj,
+int RGWRados::set_attrs(void *ctx, const RGWBucketInfo& bucket_info, rgw_obj& obj,
                         map<string, bufferlist>& attrs,
                         map<string, bufferlist>* rmattrs)
 {
   rgw_rados_ref ref;
-  int r = get_obj_ref(obj, &ref);
+  int r = get_obj_head_ref(bucket_info, obj, &ref);
   if (r < 0) {
     return r;
   }
@@ -9085,7 +9090,7 @@ int RGWRados::set_attrs(void *ctx, rgw_obj& obj,
   ObjectWriteOperation op;
   RGWObjState *state = NULL;
 
-  r = append_atomic_test(rctx, obj, op, &state);
+  r = append_atomic_test(rctx, bucket_info, obj, op, &state);
   if (r < 0)
     return r;
 
@@ -9128,13 +9133,6 @@ int RGWRados::set_attrs(void *ctx, rgw_obj& obj,
 
   RGWObjectCtx obj_ctx(this);
 
-  RGWBucketInfo bucket_info;
-  int ret = get_bucket_instance_info(obj_ctx, bucket, bucket_info, NULL, NULL);
-  if (ret < 0) {
-    ldout(cct, 0) << "ERROR: " << __func__ << "() get_bucket_instance_info(bucket=" << bucket << ") returned ret=" << ret << dendl;
-    return ret;
-  }
-
   bufferlist bl;
   RGWRados::Bucket bop(this, bucket_info);
   RGWRados::Bucket::UpdateIndex index_op(&bop, obj);
@@ -9232,10 +9230,12 @@ int RGWRados::Object::Read::prepare()
     return -ENOENT;
   }
 
+  const RGWBucketInfo& bucket_info = source->get_bucket_info();
+
   state.obj = astate->obj;
-  store->obj_to_raw(state.obj, &state.head_obj);
+  store->obj_to_raw(bucket_info.placement_rule, state.obj, &state.head_obj);
 
-  r = store->get_obj_ioctx(state.obj, &state.io_ctx);
+  r = store->get_obj_head_ioctx(bucket_info, state.obj, &state.io_ctx);
   if (r < 0) {
     return r;
   }
@@ -9561,7 +9561,7 @@ int RGWRados::Object::Read::read(int64_t ofs, int64_t end, bufferlist& bl)
 
   if (reading_from_head) {
     /* only when reading from the head object do we need to do the atomic test */
-    r = store->append_atomic_test(&source->get_ctx(), state.obj, op, &astate);
+    r = store->append_atomic_test(&source->get_ctx(), source->get_bucket_info(), state.obj, op, &astate);
     if (r < 0)
       return r;
 
@@ -9868,11 +9868,11 @@ struct get_obj_data : public RefCountedObject {
   }
 };
 
-static int _get_obj_iterate_cb(const rgw_obj& obj, const rgw_raw_obj& read_obj, off_t obj_ofs, off_t read_ofs, off_t len, bool is_head_obj, RGWObjState *astate, void *arg)
+static int _get_obj_iterate_cb(const RGWBucketInfo& bucket_info, const rgw_obj& obj, const rgw_raw_obj& read_obj, off_t obj_ofs, off_t read_ofs, off_t len, bool is_head_obj, RGWObjState *astate, void *arg)
 {
   struct get_obj_data *d = (struct get_obj_data *)arg;
 
-  return d->rados->get_obj_iterate_cb(d->ctx, astate, obj, read_obj, obj_ofs, read_ofs, len, is_head_obj, arg);
+  return d->rados->get_obj_iterate_cb(d->ctx, astate, bucket_info, obj, read_obj, obj_ofs, read_ofs, len, is_head_obj, arg);
 }
 
 static void _get_obj_aio_completion_cb(completion_t cb, void *arg)
@@ -9957,6 +9957,7 @@ int RGWRados::flush_read_list(struct get_obj_data *d)
 }
 
 int RGWRados::get_obj_iterate_cb(RGWObjectCtx *ctx, RGWObjState *astate,
+                         const RGWBucketInfo& bucket_info,
                          const rgw_obj& obj,
                         const rgw_raw_obj& read_obj,
                         off_t obj_ofs,
@@ -9974,7 +9975,7 @@ int RGWRados::get_obj_iterate_cb(RGWObjectCtx *ctx, RGWObjState *astate,
 
   if (is_head_obj) {
     /* only when reading from the head object do we need to do the atomic test */
-    r = append_atomic_test(rctx, obj, op, &astate);
+    r = append_atomic_test(rctx, bucket_info, obj, op, &astate);
     if (r < 0)
       return r;
 
@@ -10051,7 +10052,7 @@ int RGWRados::Object::Read::iterate(int64_t ofs, int64_t end, RGWGetDataCB *cb)
   data->io_ctx.dup(state.io_ctx);
   data->client_cb = cb;
 
-  int r = store->iterate_obj(obj_ctx, state.obj, ofs, end, cct->_conf->rgw_get_obj_max_req_size, _get_obj_iterate_cb, (void *)data);
+  int r = store->iterate_obj(obj_ctx, source->get_bucket_info(), state.obj, ofs, end, cct->_conf->rgw_get_obj_max_req_size, _get_obj_iterate_cb, (void *)data);
   if (r < 0) {
     data->cancel_all_io();
     goto done;
@@ -10077,10 +10078,13 @@ done:
   return r;
 }
 
-int RGWRados::iterate_obj(RGWObjectCtx& obj_ctx, rgw_obj& obj,
+int RGWRados::iterate_obj(RGWObjectCtx& obj_ctx,
+                          const RGWBucketInfo& bucket_info, const rgw_obj& obj,
                           off_t ofs, off_t end,
                          uint64_t max_chunk_size,
-                         int (*iterate_obj_cb)(const rgw_obj& obj, const rgw_raw_obj&, off_t, off_t, off_t, bool, RGWObjState *, void *),
+                         int (*iterate_obj_cb)(const RGWBucketInfo&, const rgw_obj& obj,
+                                                const rgw_raw_obj&, off_t, off_t, off_t, bool,
+                                                RGWObjState *, void *),
                          void *arg)
 {
   rgw_raw_obj head_obj;
@@ -10090,9 +10094,9 @@ int RGWRados::iterate_obj(RGWObjectCtx& obj_ctx, rgw_obj& obj,
   bool reading_from_head = true;
   RGWObjState *astate = NULL;
 
-  obj_to_raw(obj, &head_obj);
+  obj_to_raw(bucket_info.placement_rule, obj, &head_obj);
 
-  int r = get_obj_state(&obj_ctx, obj, &astate, false);
+  int r = get_obj_state(&obj_ctx, bucket_info, obj, &astate, false);
   if (r < 0) {
     return r;
   }
@@ -10122,7 +10126,7 @@ int RGWRados::iterate_obj(RGWObjectCtx& obj_ctx, rgw_obj& obj,
         }
 
         reading_from_head = (read_obj == head_obj);
-        r = iterate_obj_cb(obj, read_obj, ofs, read_ofs, read_len, reading_from_head, astate, arg);
+        r = iterate_obj_cb(bucket_info, obj, read_obj, ofs, read_ofs, read_len, reading_from_head, astate, arg);
        if (r < 0) {
          return r;
         }
@@ -10136,7 +10140,7 @@ int RGWRados::iterate_obj(RGWObjectCtx& obj_ctx, rgw_obj& obj,
       read_obj = head_obj;
       uint64_t read_len = min(len, max_chunk_size);
 
-      r = iterate_obj_cb(obj, read_obj, ofs, ofs, read_len, reading_from_head, astate, arg);
+      r = iterate_obj_cb(bucket_info, obj, read_obj, ofs, ofs, read_len, reading_from_head, astate, arg);
       if (r < 0) {
        return r;
       }
@@ -10149,10 +10153,10 @@ int RGWRados::iterate_obj(RGWObjectCtx& obj_ctx, rgw_obj& obj,
   return 0;
 }
 
-int RGWRados::obj_operate(const rgw_obj& obj, ObjectWriteOperation *op)
+int RGWRados::obj_operate(const RGWBucketInfo& bucket_info, const rgw_obj& obj, ObjectWriteOperation *op)
 {
   rgw_rados_ref ref;
-  int r = get_obj_ref(obj, &ref);
+  int r = get_obj_head_ref(bucket_info, obj, &ref);
   if (r < 0) {
     return r;
   }
@@ -10160,10 +10164,10 @@ int RGWRados::obj_operate(const rgw_obj& obj, ObjectWriteOperation *op)
   return ref.ioctx.operate(ref.oid, op);
 }
 
-int RGWRados::obj_operate(const rgw_obj& obj, ObjectReadOperation *op)
+int RGWRados::obj_operate(const RGWBucketInfo& bucket_info, const rgw_obj& obj, ObjectReadOperation *op)
 {
   rgw_rados_ref ref;
-  int r = get_obj_ref(obj, &ref);
+  int r = get_obj_head_ref(bucket_info, obj, &ref);
   if (r < 0) {
     return r;
   }
@@ -10173,7 +10177,7 @@ int RGWRados::obj_operate(const rgw_obj& obj, ObjectReadOperation *op)
   return ref.ioctx.operate(ref.oid, op, &outbl);
 }
 
-int RGWRados::olh_init_modification_impl(RGWObjState& state, const rgw_obj& olh_obj, string *op_tag)
+int RGWRados::olh_init_modification_impl(const RGWBucketInfo& bucket_info, RGWObjState& state, const rgw_obj& olh_obj, string *op_tag)
 {
   ObjectWriteOperation op;
 
@@ -10261,7 +10265,7 @@ int RGWRados::olh_init_modification_impl(RGWObjState& state, const rgw_obj& olh_
 
   op.setxattr(attr_name.c_str(), bl);
 
-  ret = obj_operate(olh_obj, &op);
+  ret = obj_operate(bucket_info, olh_obj, &op);
   if (ret < 0) {
     return ret;
   }
@@ -10272,11 +10276,11 @@ int RGWRados::olh_init_modification_impl(RGWObjState& state, const rgw_obj& olh_
   return 0;
 }
 
-int RGWRados::olh_init_modification(RGWObjState& state, const rgw_obj& obj, string *op_tag)
+int RGWRados::olh_init_modification(const RGWBucketInfo& bucket_info, RGWObjState& state, const rgw_obj& obj, string *op_tag)
 {
   int ret;
 
-  ret = olh_init_modification_impl(state, obj, op_tag);
+  ret = olh_init_modification_impl(bucket_info, state, obj, op_tag);
   if (ret == -EEXIST) {
     ret = -ECANCELED;
   }
@@ -10284,14 +10288,15 @@ int RGWRados::olh_init_modification(RGWObjState& state, const rgw_obj& obj, stri
   return ret;
 }
 
-int RGWRados::bucket_index_link_olh(RGWObjState& olh_state, const rgw_obj& obj_instance, bool delete_marker,
+int RGWRados::bucket_index_link_olh(const RGWBucketInfo& bucket_info, RGWObjState& olh_state, const rgw_obj& obj_instance,
+                                    bool delete_marker,
                                     const string& op_tag,
                                     struct rgw_bucket_dir_entry_meta *meta,
                                     uint64_t olh_epoch,
                                     real_time unmod_since, bool high_precision_time)
 {
   rgw_rados_ref ref;
-  int r = get_obj_ref(obj_instance, &ref);
+  int r = get_obj_head_ref(bucket_info, obj_instance, &ref);
   if (r < 0) {
     return r;
   }
@@ -10320,10 +10325,11 @@ void RGWRados::bucket_index_guard_olh_op(RGWObjState& olh_state, ObjectOperation
   op.cmpxattr(RGW_ATTR_OLH_ID_TAG, CEPH_OSD_CMPXATTR_OP_EQ, olh_state.olh_tag);
 }
 
-int RGWRados::bucket_index_unlink_instance(const rgw_obj& obj_instance, const string& op_tag, const string& olh_tag, uint64_t olh_epoch)
+int RGWRados::bucket_index_unlink_instance(const RGWBucketInfo& bucket_info, const rgw_obj& obj_instance,
+                                           const string& op_tag, const string& olh_tag, uint64_t olh_epoch)
 {
   rgw_rados_ref ref;
-  int r = get_obj_ref(obj_instance, &ref);
+  int r = get_obj_head_ref(bucket_info, obj_instance, &ref);
   if (r < 0) {
     return r;
   }
@@ -10344,12 +10350,13 @@ int RGWRados::bucket_index_unlink_instance(const rgw_obj& obj_instance, const st
   return 0;
 }
 
-int RGWRados::bucket_index_read_olh_log(RGWObjState& state, const rgw_obj& obj_instance, uint64_t ver_marker,
+int RGWRados::bucket_index_read_olh_log(const RGWBucketInfo& bucket_info, RGWObjState& state,
+                                        const rgw_obj& obj_instance, uint64_t ver_marker,
                                         map<uint64_t, vector<rgw_bucket_olh_log_entry> > *log,
                                         bool *is_truncated)
 {
   rgw_rados_ref ref;
-  int r = get_obj_ref(obj_instance, &ref);
+  int r = get_obj_head_ref(bucket_info, obj_instance, &ref);
   if (r < 0) {
     return r;
   }
@@ -10374,10 +10381,10 @@ int RGWRados::bucket_index_read_olh_log(RGWObjState& state, const rgw_obj& obj_i
   return 0;
 }
 
-int RGWRados::bucket_index_trim_olh_log(RGWObjState& state, const rgw_obj& obj_instance, uint64_t ver)
+int RGWRados::bucket_index_trim_olh_log(const RGWBucketInfo& bucket_info, RGWObjState& state, const rgw_obj& obj_instance, uint64_t ver)
 {
   rgw_rados_ref ref;
-  int r = get_obj_ref(obj_instance, &ref);
+  int r = get_obj_head_ref(bucket_info, obj_instance, &ref);
   if (r < 0) {
     return r;
   }
@@ -10404,10 +10411,10 @@ int RGWRados::bucket_index_trim_olh_log(RGWObjState& state, const rgw_obj& obj_i
   return 0;
 }
 
-int RGWRados::bucket_index_clear_olh(RGWObjState& state, const rgw_obj& obj_instance)
+int RGWRados::bucket_index_clear_olh(const RGWBucketInfo& bucket_info, RGWObjState& state, const rgw_obj& obj_instance)
 {
   rgw_rados_ref ref;
-  int r = get_obj_ref(obj_instance, &ref);
+  int r = get_obj_head_ref(bucket_info, obj_instance, &ref);
   if (r < 0) {
     return r;
   }
@@ -10432,7 +10439,7 @@ int RGWRados::bucket_index_clear_olh(RGWObjState& state, const rgw_obj& obj_inst
   return 0;
 }
 
-int RGWRados::apply_olh_log(RGWObjectCtx& obj_ctx, RGWObjState& state, RGWBucketInfo& bucket_info, const rgw_obj& obj,
+int RGWRados::apply_olh_log(RGWObjectCtx& obj_ctx, RGWObjState& state, const RGWBucketInfo& bucket_info, const rgw_obj& obj,
                             bufferlist& olh_tag, map<uint64_t, vector<rgw_bucket_olh_log_entry> >& log,
                             uint64_t *plast_ver)
 {
@@ -10489,7 +10496,7 @@ int RGWRados::apply_olh_log(RGWObjectCtx& obj_ctx, RGWObjState& state, RGWBucket
   }
 
   rgw_rados_ref ref;
-  int r = get_obj_ref(obj, &ref);
+  int r = get_obj_head_ref(bucket_info, obj, &ref);
   if (r < 0) {
     return r;
   }
@@ -10528,7 +10535,7 @@ int RGWRados::apply_olh_log(RGWObjectCtx& obj_ctx, RGWObjState& state, RGWBucket
     return r;
   }
 
-  r = bucket_index_trim_olh_log(state, obj, last_ver);
+  r = bucket_index_trim_olh_log(bucket_info, state, obj, last_ver);
   if (r < 0) {
     ldout(cct, 0) << "ERROR: could not trim olh log, r=" << r << dendl;
     return r;
@@ -10549,7 +10556,7 @@ int RGWRados::apply_olh_log(RGWObjectCtx& obj_ctx, RGWObjState& state, RGWBucket
       /* 
        * only clear if was successful, otherwise we might clobber pending operations on this object
        */
-      r = bucket_index_clear_olh(state, obj);
+      r = bucket_index_clear_olh(bucket_info, state, obj);
       if (r < 0) {
         ldout(cct, 0) << "ERROR: could not clear bucket index olh entries r=" << r << dendl;
         return r;
@@ -10563,14 +10570,14 @@ int RGWRados::apply_olh_log(RGWObjectCtx& obj_ctx, RGWObjState& state, RGWBucket
 /*
  * read olh log and apply it
  */
-int RGWRados::update_olh(RGWObjectCtx& obj_ctx, RGWObjState *state, RGWBucketInfo& bucket_info, const rgw_obj& obj)
+int RGWRados::update_olh(RGWObjectCtx& obj_ctx, RGWObjState *state, const RGWBucketInfo& bucket_info, const rgw_obj& obj)
 {
   map<uint64_t, vector<rgw_bucket_olh_log_entry> > log;
   bool is_truncated;
   uint64_t ver_marker = 0;
 
   do {
-    int ret = bucket_index_read_olh_log(*state, obj, ver_marker, &log, &is_truncated);
+    int ret = bucket_index_read_olh_log(bucket_info, *state, obj, ver_marker, &log, &is_truncated);
     if (ret < 0) {
       return ret;
     }
@@ -10602,12 +10609,12 @@ int RGWRados::set_olh(RGWObjectCtx& obj_ctx, RGWBucketInfo& bucket_info, const r
       obj_ctx.obj.invalidate(olh_obj);
     }
 
-    ret = get_obj_state(&obj_ctx, olh_obj, &state, false); /* don't follow olh */
+    ret = get_obj_state(&obj_ctx, bucket_info, olh_obj, &state, false); /* don't follow olh */
     if (ret < 0) {
       return ret;
     }
 
-    ret = olh_init_modification(*state, olh_obj, &op_tag);
+    ret = olh_init_modification(bucket_info, *state, olh_obj, &op_tag);
     if (ret < 0) {
       ldout(cct, 20) << "olh_init_modification() target_obj=" << target_obj << " delete_marker=" << (int)delete_marker << " returned " << ret << dendl;
       if (ret == -ECANCELED) {
@@ -10615,7 +10622,7 @@ int RGWRados::set_olh(RGWObjectCtx& obj_ctx, RGWBucketInfo& bucket_info, const r
       }
       return ret;
     }
-    ret = bucket_index_link_olh(*state, target_obj, delete_marker, op_tag, meta, olh_epoch, unmod_since, high_precision_time);
+    ret = bucket_index_link_olh(bucket_info, *state, target_obj, delete_marker, op_tag, meta, olh_epoch, unmod_since, high_precision_time);
     if (ret < 0) {
       ldout(cct, 20) << "bucket_index_link_olh() target_obj=" << target_obj << " delete_marker=" << (int)delete_marker << " returned " << ret << dendl;
       if (ret == -ECANCELED) {
@@ -10661,11 +10668,11 @@ int RGWRados::unlink_obj_instance(RGWObjectCtx& obj_ctx, RGWBucketInfo& bucket_i
       obj_ctx.obj.invalidate(olh_obj);
     }
 
-    ret = get_obj_state(&obj_ctx, olh_obj, &state, false); /* don't follow olh */
+    ret = get_obj_state(&obj_ctx, bucket_info, olh_obj, &state, false); /* don't follow olh */
     if (ret < 0)
       return ret;
 
-    ret = olh_init_modification(*state, olh_obj, &op_tag);
+    ret = olh_init_modification(bucket_info, *state, olh_obj, &op_tag);
     if (ret < 0) {
       ldout(cct, 20) << "olh_init_modification() target_obj=" << target_obj << " returned " << ret << dendl;
       if (ret == -ECANCELED) {
@@ -10676,9 +10683,9 @@ int RGWRados::unlink_obj_instance(RGWObjectCtx& obj_ctx, RGWBucketInfo& bucket_i
 
     string olh_tag(state->olh_tag.c_str(), state->olh_tag.length());
 
-    ret = bucket_index_unlink_instance(target_obj, op_tag, olh_tag, olh_epoch);
+    ret = bucket_index_unlink_instance(bucket_info, target_obj, op_tag, olh_tag, olh_epoch);
     if (ret < 0) {
-      ldout(cct, 20) << "bucket_index_link_olh() target_obj=" << target_obj << " returned " << ret << dendl;
+      ldout(cct, 20) << "bucket_index_unlink_instance() target_obj=" << target_obj << " returned " << ret << dendl;
       if (ret == -ECANCELED) {
         continue;
       }
@@ -10728,7 +10735,7 @@ static void filter_attrset(map<string, bufferlist>& unfiltered_attrset, const st
   }
 }
 
-int RGWRados::get_olh(const rgw_obj& obj, RGWOLHInfo *olh)
+int RGWRados::get_olh(const RGWBucketInfo& bucket_info, const rgw_obj& obj, RGWOLHInfo *olh)
 {
   map<string, bufferlist> unfiltered_attrset;
 
@@ -10736,7 +10743,7 @@ int RGWRados::get_olh(const rgw_obj& obj, RGWOLHInfo *olh)
   op.getxattrs(&unfiltered_attrset, NULL);
 
   bufferlist outbl;
-  int r = obj_operate(obj, &op);
+  int r = obj_operate(bucket_info, obj, &op);
 
   if (r < 0) {
     return r;
@@ -10792,7 +10799,7 @@ void RGWRados::check_pending_olh_entries(map<string, bufferlist>& pending_entrie
   }
 }
 
-int RGWRados::remove_olh_pending_entries(RGWObjState& state, const rgw_obj& olh_obj, map<string, bufferlist>& pending_attrs)
+int RGWRados::remove_olh_pending_entries(const RGWBucketInfo& bucket_info, RGWObjState& state, const rgw_obj& olh_obj, map<string, bufferlist>& pending_attrs)
 {
   ObjectWriteOperation op;
 
@@ -10803,7 +10810,7 @@ int RGWRados::remove_olh_pending_entries(RGWObjState& state, const rgw_obj& olh_
   }
 
   rgw_rados_ref ref;
-  int r = get_obj_ref(olh_obj, &ref);
+  int r = get_obj_head_ref(bucket_info, olh_obj, &ref);
   if (r < 0) {
     return r;
   }
@@ -10822,7 +10829,7 @@ int RGWRados::remove_olh_pending_entries(RGWObjState& state, const rgw_obj& olh_
   return 0;
 }
 
-int RGWRados::follow_olh(RGWObjectCtx& obj_ctx, RGWObjState *state, const rgw_obj& olh_obj, rgw_obj *target)
+int RGWRados::follow_olh(const RGWBucketInfo& bucket_info, RGWObjectCtx& obj_ctx, RGWObjState *state, const rgw_obj& olh_obj, rgw_obj *target)
 {
   map<string, bufferlist> pending_entries;
   filter_attrset(state->attrset, RGW_ATTR_OLH_PENDING_PREFIX, &pending_entries);
@@ -10831,7 +10838,7 @@ int RGWRados::follow_olh(RGWObjectCtx& obj_ctx, RGWObjState *state, const rgw_ob
   check_pending_olh_entries(pending_entries, &rm_pending_entries);
 
   if (!rm_pending_entries.empty()) {
-    int ret = remove_olh_pending_entries(*state, olh_obj, rm_pending_entries);
+    int ret = remove_olh_pending_entries(bucket_info, *state, olh_obj, rm_pending_entries);
     if (ret < 0) {
       ldout(cct, 20) << "ERROR: rm_pending_entries returned ret=" << ret << dendl;
       return ret;
@@ -10840,16 +10847,7 @@ int RGWRados::follow_olh(RGWObjectCtx& obj_ctx, RGWObjState *state, const rgw_ob
   if (!pending_entries.empty()) {
     ldout(cct, 20) << __func__ << "(): found pending entries, need to update_olh() on bucket=" << olh_obj.bucket << dendl;
 
-    /* we could save a few cpu cycles if we drilled through all the layers and passed the bucket
-     * info in, but this is supposed to be a rare call and it doesn't seem compelling enough
-     * for cluttering everything
-     */
-    RGWBucketInfo bucket_info;
-    int ret = get_bucket_instance_info(obj_ctx, olh_obj.bucket, bucket_info, NULL, NULL);
-    if (ret < 0) {
-      ldout(cct, 0) << "ERROR: get_bucket_instance_info() returned " << ret << " olh_obj.bucket=" << olh_obj.bucket << dendl;
-    }
-    ret = update_olh(obj_ctx, state, bucket_info, olh_obj);
+    int ret = update_olh(obj_ctx, state, bucket_info, olh_obj);
     if (ret < 0) {
       return ret;
     }
@@ -11749,10 +11747,10 @@ int RGWRados::trim_bi_log_entries(RGWBucketInfo& bucket_info, int shard_id, stri
       cct->_conf->rgw_bucket_index_max_aio)();
 }
 
-int RGWRados::bi_get_instance(rgw_obj& obj, rgw_bucket_dir_entry *dirent)
+int RGWRados::bi_get_instance(const RGWBucketInfo& bucket_info, rgw_obj& obj, rgw_bucket_dir_entry *dirent)
 {
   rgw_rados_ref ref;
-  int r = get_obj_ref(obj, &ref);
+  int r = get_obj_head_ref(bucket_info, obj, &ref);
   if (r < 0) {
     return r;
   }
@@ -12064,7 +12062,7 @@ int RGWRados::cls_bucket_list(RGWBucketInfo& bucket_info, int shard_id, rgw_obj_
        * and if the tags are old we need to do cleanup as well. */
       librados::IoCtx sub_ctx;
       sub_ctx.dup(index_ctx);
-      r = check_disk_state(sub_ctx, bucket_info.bucket, dirent, dirent, updates[vnames[pos]]);
+      r = check_disk_state(sub_ctx, bucket_info, dirent, dirent, updates[vnames[pos]]);
       if (r < 0 && r != -ENOENT) {
           return r;
       }
@@ -12193,11 +12191,12 @@ int RGWRados::remove_objs_from_index(RGWBucketInfo& bucket_info, list<rgw_obj_in
 }
 
 int RGWRados::check_disk_state(librados::IoCtx io_ctx,
-                               rgw_bucket& bucket,
+                               const RGWBucketInfo& bucket_info,
                                rgw_bucket_dir_entry& list_state,
                                rgw_bucket_dir_entry& object,
                                bufferlist& suggested_updates)
 {
+  const rgw_bucket& bucket = bucket_info.bucket;
   uint8_t suggest_flag = (get_zone().log_data ? CEPH_RGW_DIR_SUGGEST_LOG_OP : 0);
 
   std::string loc;
@@ -12215,7 +12214,7 @@ int RGWRados::check_disk_state(librados::IoCtx io_ctx,
 
   RGWObjState *astate = NULL;
   RGWObjectCtx rctx(this);
-  int r = get_obj_state(&rctx, obj, &astate, false);
+  int r = get_obj_state(&rctx, bucket_info, obj, &astate, false);
   if (r < 0)
     return r;
 
@@ -13016,7 +13015,7 @@ int RGWRados::delete_obj_aio(const rgw_obj& obj,
                              list<librados::AioCompletion *>& handles, bool keep_index_consistent)
 {
   rgw_rados_ref ref;
-  int ret = get_obj_ref(obj, &ref);
+  int ret = get_obj_head_ref(bucket_info, obj, &ref);
   if (ret < 0) {
     lderr(cct) << "ERROR: failed to get obj ref with ret=" << ret << dendl;
     return ret;
index 0f666fc9da83fca7c3b4d1f13d2de05d49e02b2c..d560d4d6036c2988b57b3b7d889d0f3e89b04764 100644 (file)
@@ -93,10 +93,15 @@ static inline bool rgw_raw_obj_to_obj(const rgw_bucket& bucket, const rgw_raw_ob
   return true;
 }
 
-bool rgw_obj_to_raw(const RGWZoneGroup& zonegroup, const RGWZoneParams& zone_params,
-                    const rgw_obj& obj, rgw_raw_obj *raw_obj);
+struct rgw_bucket_placement {
+  string placement_rule;
+  rgw_bucket bucket;
+
+  void dump(Formatter *f) const;
+};
 
 class rgw_obj_select {
+  string placement_rule;
   rgw_obj obj;
   rgw_raw_obj raw_obj;
   bool is_raw;
@@ -128,6 +133,10 @@ public:
     is_raw = true;
     return *this;
   }
+
+  void set_placement_rule(const string& rule) {
+    placement_rule = rule;
+  }
 };
 
 struct compression_block {
@@ -360,7 +369,6 @@ struct RGWObjManifestRule {
 };
 WRITE_CLASS_ENCODER(RGWObjManifestRule)
 
-
 class RGWObjManifest {
 protected:
   bool explicit_objs; /* old manifest? */
@@ -370,11 +378,12 @@ protected:
 
   rgw_obj obj;
   uint64_t head_size;
+  string head_placement_rule;
 
   uint64_t max_head_size;
   string prefix;
-  rgw_bucket tail_bucket; /* might be different than the original bucket,
-                             as object might have been copied across pools */
+  rgw_bucket_placement tail_placement; /* might be different than the original bucket,
+                                       as object might have been copied across pools */
   map<uint64_t, RGWObjManifestRule> rules;
 
   string tail_instance; /* tail object's instance */
@@ -402,7 +411,7 @@ public:
     head_size = rhs.head_size;
     max_head_size = rhs.max_head_size;
     prefix = rhs.prefix;
-    tail_bucket = rhs.tail_bucket;
+    tail_placement = rhs.tail_placement;
     rules = rhs.rules;
     tail_instance = rhs.tail_instance;
 
@@ -442,7 +451,7 @@ public:
   }
 
   void encode(bufferlist& bl) const {
-    ENCODE_START(6, 6, bl);
+    ENCODE_START(7, 6, bl);
     ::encode(obj_size, bl);
     ::encode(objs, bl);
     ::encode(explicit_objs, bl);
@@ -451,21 +460,23 @@ public:
     ::encode(max_head_size, bl);
     ::encode(prefix, bl);
     ::encode(rules, bl);
-    bool encode_tail_bucket = !(tail_bucket == obj.bucket);
+    bool encode_tail_bucket = !(tail_placement.bucket == obj.bucket);
     ::encode(encode_tail_bucket, bl);
     if (encode_tail_bucket) {
-      ::encode(tail_bucket, bl);
+      ::encode(tail_placement.bucket, bl);
     }
     bool encode_tail_instance = (tail_instance != obj.key.instance);
     ::encode(encode_tail_instance, bl);
     if (encode_tail_instance) {
       ::encode(tail_instance, bl);
     }
+    ::encode(head_placement_rule, bl);
+    ::encode(tail_placement.placement_rule, bl);
     ENCODE_FINISH(bl);
   }
 
   void decode(bufferlist::iterator& bl) {
-    DECODE_START_LEGACY_COMPAT_LEN_32(6, 2, 2, bl);
+    DECODE_START_LEGACY_COMPAT_LEN_32(7, 2, 2, bl);
     ::decode(obj_size, bl);
     ::decode(objs, bl);
     if (struct_v >= 3) {
@@ -500,14 +511,14 @@ public:
 
     if (struct_v >= 4) {
       if (struct_v < 6) {
-        ::decode(tail_bucket, bl);
+        ::decode(tail_placement.bucket, bl);
       } else {
         bool need_to_decode;
         ::decode(need_to_decode, bl);
         if (need_to_decode) {
-          ::decode(tail_bucket, bl);
+          ::decode(tail_placement.bucket, bl);
         } else {
-          tail_bucket = obj.bucket;
+          tail_placement.bucket = obj.bucket;
         }
       }
     }
@@ -528,6 +539,11 @@ public:
       tail_instance = obj.key.instance;
     }
 
+    if (struct_v >= 7) {
+      ::decode(head_placement_rule, bl);
+      ::decode(tail_placement.placement_rule, bl);
+    }
+
     update_iterators();
     DECODE_FINISH(bl);
   }
@@ -562,7 +578,8 @@ public:
     return (obj_size > head_size);
   }
 
-  void set_head(const rgw_obj& _o, uint64_t _s) {
+  void set_head(const string& placement_rule, const rgw_obj& _o, uint64_t _s) {
+    head_placement_rule = placement_rule;
     obj = _o;
     head_size = _s;
 
@@ -576,12 +593,17 @@ public:
     return obj;
   }
 
-  void set_tail_bucket(const rgw_bucket& _b) {
-    tail_bucket = _b;
+  void set_tail_placement(const string& placement_rule, const rgw_bucket& _b) {
+    tail_placement.placement_rule = placement_rule;
+    tail_placement.bucket = _b;
   }
 
-  rgw_bucket& get_tail_bucket() {
-    return tail_bucket;
+  const rgw_bucket_placement& get_tail_placement() {
+    return tail_placement;
+  }
+
+  const string& get_head_placement_rule() {
+    return head_placement_rule;
   }
 
   void set_prefix(const string& _p) {
@@ -755,7 +777,7 @@ public:
   public:
     generator() : manifest(NULL), last_ofs(0), cur_part_ofs(0), cur_part_id(0), 
                  cur_stripe(0), cur_stripe_size(0) {}
-    int create_begin(CephContext *cct, RGWObjManifest *manifest, rgw_bucket& bucket, rgw_obj& obj);
+    int create_begin(CephContext *cct, RGWObjManifest *manifest, const string& placement_rule, rgw_bucket& bucket, rgw_obj& obj);
 
     int create_next(uint64_t ofs);
 
@@ -1233,23 +1255,10 @@ struct RGWZoneParams : RGWSystemMetaObj {
     return true;
   }
 
-  bool get_index_pool(const rgw_obj& obj, rgw_pool *pool) {
-    if (!obj.bucket.explicit_placement.index_pool.empty()) {
-      *pool = obj.bucket.explicit_placement.index_pool;
-      return true;
-    }
-    if (obj.placement_id.empty()) {
-      return false;
-    }
-    auto iter = placement_pools.find(obj.placement_id);
-    if (iter == placement_pools.end()) {
-      return false;
-    }
-    pool->init(iter->second.index_pool);
-    return true;
-  }
-
-  bool get_data_pool(const rgw_obj& obj, rgw_pool *pool) const {
+  /*
+   * return data pool of the head object
+   */
+  bool get_head_data_pool(const string& placement_id, const rgw_obj& obj, rgw_pool *pool) const {
     const rgw_data_placement_target& explicit_placement = obj.bucket.explicit_placement;
     if (!explicit_placement.data_pool.empty()) {
       if (!obj.in_extra_data) {
@@ -1259,10 +1268,10 @@ struct RGWZoneParams : RGWSystemMetaObj {
       }
       return true;
     }
-    if (obj.placement_id.empty()) {
+    if (placement_id.empty()) {
       return false;
     }
-    auto iter = placement_pools.find(obj.placement_id);
+    auto iter = placement_pools.find(placement_id);
     if (iter == placement_pools.end()) {
       return false;
     }
@@ -2198,16 +2207,17 @@ class RGWRados
   // This field represents the number of bucket index object shards
   uint32_t bucket_index_max_shards;
 
-  int get_obj_ioctx(const rgw_obj& obj, librados::IoCtx *ioctx);
-  int get_obj_ref(const rgw_obj& obj, rgw_rados_ref *ref);
+  int get_obj_head_ioctx(const RGWBucketInfo& bucket_info, const rgw_obj& obj, librados::IoCtx *ioctx);
+  int get_obj_head_ref(const RGWBucketInfo& bucket_info, const rgw_obj& obj, rgw_rados_ref *ref);
   int get_system_obj_ref(const rgw_raw_obj& obj, rgw_rados_ref *ref, rgw_pool *pool = NULL);
   uint64_t max_bucket_id;
 
-  int get_olh_target_state(RGWObjectCtx& rctx, const rgw_obj& obj, RGWObjState *olh_state,
-                           RGWObjState **target_state);
+  int get_olh_target_state(RGWObjectCtx& rctx, const RGWBucketInfo& bucket_info, const rgw_obj& obj,
+                           RGWObjState *olh_state, RGWObjState **target_state);
   int get_system_obj_state_impl(RGWObjectCtx *rctx, rgw_raw_obj& obj, RGWRawObjState **state, RGWObjVersionTracker *objv_tracker);
-  int get_obj_state_impl(RGWObjectCtx *rctx, const rgw_obj& obj, RGWObjState **state, bool follow_olh, bool assume_noent = false);
-  int append_atomic_test(RGWObjectCtx *rctx, const rgw_obj& obj,
+  int get_obj_state_impl(RGWObjectCtx *rctx, const RGWBucketInfo& bucket_info, const rgw_obj& obj, RGWObjState **state,
+                         bool follow_olh, bool assume_noent = false);
+  int append_atomic_test(RGWObjectCtx *rctx, const RGWBucketInfo& bucket_info, const rgw_obj& obj,
                          librados::ObjectOperation& op, RGWObjState **state);
 
   int update_placement_map();
@@ -2412,7 +2422,7 @@ public:
 
   int get_required_alignment(const rgw_pool& pool, uint64_t *alignment);
   int get_max_chunk_size(const rgw_pool& pool, uint64_t *max_chunk_size);
-  int get_max_chunk_size(const rgw_obj& obj, uint64_t *max_chunk_size);
+  int get_max_chunk_size(const string& placement_rule, const rgw_obj& obj, uint64_t *max_chunk_size);
 
   uint32_t get_max_bucket_shards() {
     return MAX_BUCKET_INDEX_SHARDS_PRIME;
@@ -2495,8 +2505,8 @@ public:
   int select_bucket_location_by_rule(const string& location_rule, rgw_bucket& bucket, RGWZonePlacementInfo *rule_info);
   void create_bucket_id(string *bucket_id);
 
-  bool get_obj_data_pool(const rgw_obj& obj, rgw_pool *pool);
-  bool obj_to_raw(const rgw_obj& obj, rgw_raw_obj *raw_obj);
+  bool get_obj_data_pool(const string& placement_rule, const rgw_obj& obj, rgw_pool *pool);
+  bool obj_to_raw(const string& placement_rule, const rgw_obj& obj, rgw_raw_obj *raw_obj);
 
   int create_bucket(RGWUserInfo& owner, rgw_bucket& bucket,
                             const string& zonegroup_id,
@@ -2608,7 +2618,7 @@ public:
     int complete_atomic_modification();
 
   public:
-    Object(RGWRados *_store, RGWBucketInfo& _bucket_info, RGWObjectCtx& _ctx, const rgw_obj& _obj) : store(_store), bucket_info(_bucket_info),
+    Object(RGWRados *_store, const RGWBucketInfo& _bucket_info, RGWObjectCtx& _ctx, const rgw_obj& _obj) : store(_store), bucket_info(_bucket_info),
                                                                                                ctx(_ctx), obj(_obj), bs(store),
                                                                                                state(NULL), versioning_disabled(false),
                                                                                                bs_initialized(false) {}
@@ -2787,7 +2797,7 @@ public:
     int shard_id;
 
   public:
-    Bucket(RGWRados *_store, RGWBucketInfo& _bucket_info) : store(_store), bucket_info(_bucket_info), bucket(bucket_info.bucket),
+    Bucket(RGWRados *_store, const RGWBucketInfo& _bucket_info) : store(_store), bucket_info(_bucket_info), bucket(bucket_info.bucket),
                                                             shard_id(RGW_NO_SHARD) {}
     RGWRados *get_store() { return store; }
     rgw_bucket& get_bucket() { return bucket; }
@@ -3069,7 +3079,7 @@ public:
 
   /** Delete an object.*/
   int delete_obj(RGWObjectCtx& obj_ctx,
-                         RGWBucketInfo& bucket_owner,
+                         const RGWBucketInfo& bucket_owner,
                          const rgw_obj& src_obj,
                          int versioning_status,
                          uint16_t bilog_flags = 0,
@@ -3109,16 +3119,17 @@ public:
    * bl: the contents of the attr
    * Returns: 0 on success, -ERR# otherwise.
    */
-  int set_attr(void *ctx, rgw_obj& obj, const char *name, bufferlist& bl);
+  int set_attr(void *ctx, const RGWBucketInfo& bucket_info, rgw_obj& obj, const char *name, bufferlist& bl);
 
-  int set_attrs(void *ctx, rgw_obj& obj,
+  int set_attrs(void *ctx, const RGWBucketInfo& bucket_info, rgw_obj& obj,
                         map<string, bufferlist>& attrs,
                         map<string, bufferlist>* rmattrs);
 
   int get_system_obj_state(RGWObjectCtx *rctx, rgw_raw_obj& obj, RGWRawObjState **state, RGWObjVersionTracker *objv_tracker);
-  int get_obj_state(RGWObjectCtx *rctx, const rgw_obj& obj, RGWObjState **state, bool follow_olh, bool assume_noent = false);
-  int get_obj_state(RGWObjectCtx *rctx, const rgw_obj& obj, RGWObjState **state) {
-    return get_obj_state(rctx, obj, state, true);
+  int get_obj_state(RGWObjectCtx *rctx, const RGWBucketInfo& bucket_info, const rgw_obj& obj, RGWObjState **state,
+                    bool follow_olh, assume_noent = false);
+  int get_obj_state(RGWObjectCtx *rctx, const RGWBucketInfo& bucket_info, const rgw_obj& obj, RGWObjState **state) {
+    return get_obj_state(rctx, bucket_info, obj, state, true);
   }
 
   virtual int stat_system_obj(RGWObjectCtx& obj_ctx,
@@ -3138,16 +3149,17 @@ public:
   virtual void register_chained_cache(RGWChainedCache *cache) {}
   virtual bool chain_cache_entry(list<rgw_cache_entry_info *>& cache_info_entries, RGWChainedCache::Entry *chained_entry) { return false; }
 
-  int iterate_obj(RGWObjectCtx& ctx, rgw_obj& obj,
+  int iterate_obj(RGWObjectCtx& ctx,
+                  const RGWBucketInfo& bucket_info, const rgw_obj& obj,
                   off_t ofs, off_t end,
                   uint64_t max_chunk_size,
-                  int (*iterate_obj_cb)(const rgw_obj& obj, const rgw_raw_obj&, off_t, off_t, off_t, bool, RGWObjState *, void *),
+                  int (*iterate_obj_cb)(const RGWBucketInfo& bucket_info, const rgw_obj& obj, const rgw_raw_obj&, off_t, off_t, off_t, bool, RGWObjState *, void *),
                   void *arg);
 
   int flush_read_list(struct get_obj_data *d);
 
   int get_obj_iterate_cb(RGWObjectCtx *ctx, RGWObjState *astate,
-                         const rgw_obj& obj,
+                         const RGWBucketInfo& bucket_info, const rgw_obj& obj,
                          const rgw_raw_obj& read_obj,
                          off_t obj_ofs, off_t read_ofs, off_t len,
                          bool is_head_obj, void *arg);
@@ -3162,34 +3174,35 @@ public:
                        map<string, bufferlist> *attrs, bufferlist *first_chunk,
                        RGWObjVersionTracker *objv_tracker);
 
-  int obj_operate(const rgw_obj& obj, librados::ObjectWriteOperation *op);
-  int obj_operate(const rgw_obj& obj, librados::ObjectReadOperation *op);
+  int obj_operate(const RGWBucketInfo& bucket_info, const rgw_obj& obj, librados::ObjectWriteOperation *op);
+  int obj_operate(const RGWBucketInfo& bucket_info, const rgw_obj& obj, librados::ObjectReadOperation *op);
 
   void bucket_index_guard_olh_op(RGWObjState& olh_state, librados::ObjectOperation& op);
-  int olh_init_modification(RGWObjState& state, const rgw_obj& olh_obj, string *op_tag);
-  int olh_init_modification_impl(RGWObjState& state, const rgw_obj& olh_obj, string *op_tag);
-  int bucket_index_link_olh(RGWObjState& olh_state, const rgw_obj& obj_instance, bool delete_marker,
+  int olh_init_modification(const RGWBucketInfo& bucket_info, RGWObjState& state, const rgw_obj& olh_obj, string *op_tag);
+  int olh_init_modification_impl(const RGWBucketInfo& bucket_info, RGWObjState& state, const rgw_obj& olh_obj, string *op_tag);
+  int bucket_index_link_olh(const RGWBucketInfo& bucket_info, RGWObjState& olh_state,
+                            const rgw_obj& obj_instance, bool delete_marker,
                             const string& op_tag, struct rgw_bucket_dir_entry_meta *meta,
                             uint64_t olh_epoch,
                             ceph::real_time unmod_since, bool high_precision_time);
-  int bucket_index_unlink_instance(const rgw_obj& obj_instance, const string& op_tag, const string& olh_tag, uint64_t olh_epoch);
-  int bucket_index_read_olh_log(RGWObjState& state, const rgw_obj& obj_instance, uint64_t ver_marker,
+  int bucket_index_unlink_instance(const RGWBucketInfo& bucket_info, const rgw_obj& obj_instance, const string& op_tag, const string& olh_tag, uint64_t olh_epoch);
+  int bucket_index_read_olh_log(const RGWBucketInfo& bucket_info, RGWObjState& state, const rgw_obj& obj_instance, uint64_t ver_marker,
                                 map<uint64_t, vector<rgw_bucket_olh_log_entry> > *log, bool *is_truncated);
-  int bucket_index_trim_olh_log(RGWObjState& obj_state, const rgw_obj& obj_instance, uint64_t ver);
-  int bucket_index_clear_olh(RGWObjState& state, const rgw_obj& obj_instance);
-  int apply_olh_log(RGWObjectCtx& ctx, RGWObjState& obj_state, RGWBucketInfo& bucket_info, const rgw_obj& obj,
+  int bucket_index_trim_olh_log(const RGWBucketInfo& bucket_info, RGWObjState& obj_state, const rgw_obj& obj_instance, uint64_t ver);
+  int bucket_index_clear_olh(const RGWBucketInfo& bucket_info, RGWObjState& state, const rgw_obj& obj_instance);
+  int apply_olh_log(RGWObjectCtx& ctx, RGWObjState& obj_state, const RGWBucketInfo& bucket_info, const rgw_obj& obj,
                     bufferlist& obj_tag, map<uint64_t, vector<rgw_bucket_olh_log_entry> >& log,
                     uint64_t *plast_ver);
-  int update_olh(RGWObjectCtx& obj_ctx, RGWObjState *state, RGWBucketInfo& bucket_info, const rgw_obj& obj);
+  int update_olh(RGWObjectCtx& obj_ctx, RGWObjState *state, const RGWBucketInfo& bucket_info, const rgw_obj& obj);
   int set_olh(RGWObjectCtx& obj_ctx, RGWBucketInfo& bucket_info, const rgw_obj& target_obj, bool delete_marker, rgw_bucket_dir_entry_meta *meta,
               uint64_t olh_epoch, ceph::real_time unmod_since, bool high_precision_time);
   int unlink_obj_instance(RGWObjectCtx& obj_ctx, RGWBucketInfo& bucket_info, const rgw_obj& target_obj,
                           uint64_t olh_epoch);
 
   void check_pending_olh_entries(map<string, bufferlist>& pending_entries, map<string, bufferlist> *rm_pending_entries);
-  int remove_olh_pending_entries(RGWObjState& state, const rgw_obj& olh_obj, map<string, bufferlist>& pending_attrs);
-  int follow_olh(RGWObjectCtx& ctx, RGWObjState *state, const rgw_obj& olh_obj, rgw_obj *target);
-  int get_olh(const rgw_obj& obj, RGWOLHInfo *olh);
+  int remove_olh_pending_entries(const RGWBucketInfo& bucket_info, RGWObjState& state, const rgw_obj& olh_obj, map<string, bufferlist>& pending_attrs);
+  int follow_olh(const RGWBucketInfo& bucket_info, RGWObjectCtx& ctx, RGWObjState *state, const rgw_obj& olh_obj, rgw_obj *target);
+  int get_olh(const RGWBucketInfo& bucket_info, const rgw_obj& obj, RGWOLHInfo *olh);
 
   void gen_rand_obj_instance_name(rgw_obj *target);
 
@@ -3280,7 +3293,7 @@ public:
   int trim_bi_log_entries(RGWBucketInfo& bucket_info, int shard_id, string& marker, string& end_marker);
   int get_bi_log_status(RGWBucketInfo& bucket_info, int shard_id, map<int, string>& max_marker);
 
-  int bi_get_instance(rgw_obj& obj, rgw_bucket_dir_entry *dirent);
+  int bi_get_instance(const RGWBucketInfo& bucket_info, rgw_obj& obj, rgw_bucket_dir_entry *dirent);
   int bi_get(rgw_bucket& bucket, rgw_obj& obj, BIIndexType index_type, rgw_cls_bi_entry *entry);
   void bi_put(librados::ObjectWriteOperation& op, BucketShard& bs, rgw_cls_bi_entry& entry);
   int bi_put(BucketShard& bs, rgw_cls_bi_entry& entry);
@@ -3352,7 +3365,7 @@ public:
   int list_gc_objs(int *index, string& marker, uint32_t max, bool expired_only, std::list<cls_rgw_gc_obj_info>& result, bool *truncated);
   int process_gc();
   int process_expire_objects();
-  int defer_gc(void *ctx, rgw_obj& obj);
+  int defer_gc(void *ctx, const RGWBucketInfo& bucket_info, const rgw_obj& obj);
 
   int process_lc();
   int list_lc_progress(const string& marker, uint32_t max_entries, map<string, int> *progress_map);
@@ -3366,8 +3379,8 @@ public:
                     const string& src_oid, const string& src_locator,
                     librados::IoCtx& dst_ioctx,
                     const string& dst_oid, const string& dst_locator);
-  int fix_head_obj_locator(rgw_bucket& bucket, bool copy_obj, bool remove_bad, rgw_obj_key& key);
-  int fix_tail_obj_locator(rgw_bucket& bucket, rgw_obj_key& key, bool fix, bool *need_fix);
+  int fix_head_obj_locator(const RGWBucketInfo& bucket_info, bool copy_obj, bool remove_bad, rgw_obj_key& key);
+  int fix_tail_obj_locator(const RGWBucketInfo& bucket_info, rgw_obj_key& key, bool fix, bool *need_fix);
 
   int cls_user_get_header(const string& user_id, cls_user_header *header);
   int cls_user_get_header_async(const string& user_id, RGWGetUserHeader_CB *ctx);
@@ -3491,7 +3504,7 @@ public:
    * will encode that info as a suggested update.)
    */
   int check_disk_state(librados::IoCtx io_ctx,
-                       rgw_bucket& bucket,
+                       const RGWBucketInfo& bucket_info,
                        rgw_bucket_dir_entry& list_state,
                        rgw_bucket_dir_entry& object,
                        bufferlist& suggested_updates);
index 757c8e57284bd08c9ab184ee76374759c1ece7f2..eb51cbe85ab35d17352ff31523afdba42ea9104b 100644 (file)
@@ -1818,7 +1818,7 @@ bool RGWSwiftWebsiteHandler::is_web_dir() const
   obj_ctx.obj.set_prefetch_data(obj);
 
   RGWObjState* state = nullptr;
-  if (store->get_obj_state(&obj_ctx, obj, &state, false) < 0) {
+  if (store->get_obj_state(&obj_ctx, s->bucket_info, obj, &state, false) < 0) {
     return false;
   }
 
@@ -1848,7 +1848,7 @@ bool RGWSwiftWebsiteHandler::is_index_present(const std::string& index)
   obj_ctx.obj.set_prefetch_data(obj);
 
   RGWObjState* state = nullptr;
-  if (store->get_obj_state(&obj_ctx, obj, &state, false) < 0) {
+  if (store->get_obj_state(&obj_ctx, s->bucket_info, obj, &state, false) < 0) {
     return false;
   }
 
index 723330097a9d5b21c25b9c1017c3bb40600e7a12..5e440c5d11fadd4e6a85c6e0cefe5db77078b85b 100644 (file)
@@ -268,7 +268,7 @@ int seed::save_torrent_file()
   rgw_obj obj(s->bucket, s->object.name);    
 
   rgw_raw_obj raw_obj;
-  store->obj_to_raw(obj, &raw_obj);
+  store->obj_to_raw(s->bucket_info.placement_rule, obj, &raw_obj);
 
   op_ret = store->omap_set(raw_obj, key, bl);
   if (op_ret < 0)