]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: tighten storage_class assignment
authorYehuda Sadeh <yehuda@redhat.com>
Thu, 11 Oct 2018 22:09:27 +0000 (15:09 -0700)
committerYehuda Sadeh <yehuda@redhat.com>
Fri, 4 Jan 2019 03:00:21 +0000 (19:00 -0800)
Signed-off-by: Yehuda Sadeh <yehuda@redhat.com>
src/rgw/rgw_common.h
src/rgw/rgw_file.cc
src/rgw/rgw_op.cc
src/rgw/rgw_rados.cc
src/rgw/rgw_rados.h
src/rgw/rgw_rest.cc
src/rgw/rgw_rest_s3.cc
src/rgw/rgw_rest_swift.cc

index fc8845e9fdd8babbafb40b198a764daedfe503a9..07fe1eff5b99aa592062150a2072168fcbb51cc9 100644 (file)
@@ -658,7 +658,13 @@ struct rgw_placement_rule {
 
   rgw_placement_rule() {}
   rgw_placement_rule(const string& _n, const string& _sc) : name(_n), storage_class(_sc) {}
-
+  rgw_placement_rule(const rgw_placement_rule& _r, const string& _sc) : name(_r.name) {
+    if (!_sc.empty()) {
+      storage_class = _sc;
+    } else {
+      storage_class = _r.storage_class;
+    }
+  }
 
   bool empty() const {
     return name.empty() && storage_class.empty();
@@ -1624,7 +1630,7 @@ struct req_info {
   string effective_uri;
   string request_params;
   string domain;
-  rgw_placement_rule storage_class;
+  string storage_class;
 
   req_info(CephContext *cct, const RGWEnv *env);
   void rebuild_from(req_info& src);
@@ -1981,6 +1987,7 @@ struct req_state : DoutPrefixProvider {
   real_time bucket_mtime;
   std::map<std::string, ceph::bufferlist> bucket_attrs;
   bool bucket_exists{false};
+  rgw_placement_rule dest_placement;
 
   bool has_bad_meta{false};
 
index 16bf507bbb4bc98e90e3bc4576f20f5f21a65fb5..b4c688380a708ad20661275b4e9cf30bfb7dbd48 100644 (file)
@@ -1452,6 +1452,7 @@ namespace rgw {
       }
     }
     processor.emplace(&*aio, get_store(), s->bucket_info,
+                      &s->dest_placement,
                       s->bucket_owner.get_id(),
                       *static_cast<RGWObjectCtx *>(s->obj_ctx),
                       obj, olh_epoch, s->req_id);
index 16829a4cc79a951b1ad6664b65f1ad1f555a9ef2..c6b52c9486bff5eb16b814a79a09c79152eeb948 100644 (file)
@@ -545,6 +545,13 @@ int rgw_build_bucket_policies(RGWRados* store, struct req_state* s)
         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);
+    }
   }
 
   /* handle user ACL only for those APIs which support it */
@@ -3506,7 +3513,7 @@ void RGWPutObj::execute()
 
   if (multipart) {
     processor.emplace<MultipartObjectProcessor>(
-        &aio, store, s->bucket_info, &s->info.storage_class,
+        &aio, store, s->bucket_info, &s->dest_placement,
         s->owner.get_id(), obj_ctx, obj,
         multipart_upload_id, multipart_part_num, multipart_part_str);
   } else {
@@ -3519,7 +3526,7 @@ void RGWPutObj::execute()
       }
     }
     processor.emplace<AtomicObjectProcessor>(
-        &aio, store, s->bucket_info, &s->info.storage_class,
+        &aio, store, s->bucket_info, &s->dest_placement,
         s->bucket_owner.get_id(), obj_ctx, obj, olh_epoch, s->req_id);
   }
 
@@ -3842,11 +3849,10 @@ void RGWPostObj::execute()
     }
 
     rgw::AioThrottle aio(s->cct->_conf->rgw_put_obj_min_window_size);
-    rgw_placement_rule& tail_placement = s->info.storage_class;
 
     using namespace rgw::putobj;
     AtomicObjectProcessor processor(&aio, store, s->bucket_info,
-                                    &tail_placement,
+                                    &s->dest_placement,
                                     s->bucket_owner.get_id(),
                                     *static_cast<RGWObjectCtx*>(s->obj_ctx),
                                     obj, 0, s->req_id);
@@ -4704,8 +4710,6 @@ void RGWCopyObj::execute()
     return;
   }
 
-  rgw_placement_rule& dest_placement = s->info.storage_class;
-
   op_ret = store->copy_obj(obj_ctx,
                           s->user->user_id,
                           &s->info,
@@ -4714,7 +4718,7 @@ void RGWCopyObj::execute()
                           src_obj,
                           dest_bucket_info,
                           src_bucket_info,
-                           &dest_placement,
+                           s->dest_placement,
                           &src_mtime,
                           &mtime,
                           mod_ptr,
@@ -6399,6 +6403,7 @@ int RGWBulkUploadOp::handle_dir(const boost::string_ref path)
     pmaster_num_shards = nullptr;
   }
 
+  rgw_placement_rule placement_rule(binfo.placement_rule, s->info.storage_class);
 
   if (bucket_exists) {
     rgw_placement_rule selected_placement_rule;
@@ -6407,7 +6412,7 @@ int RGWBulkUploadOp::handle_dir(const boost::string_ref path)
     bucket.name = s->bucket_name;
     op_ret = store->svc.zone->select_bucket_placement(*(s->user),
                                             store->svc.zone->get_zonegroup().get_id(),
-                                            s->info.storage_class,
+                                            placement_rule,
                                             &selected_placement_rule,
                                             nullptr);
     if (selected_placement_rule != binfo.placement_rule) {
@@ -6437,7 +6442,7 @@ int RGWBulkUploadOp::handle_dir(const boost::string_ref path)
   op_ret = store->create_bucket(*(s->user),
                                 bucket,
                                 store->svc.zone->get_zonegroup().get_id(),
-                                s->info.storage_class, binfo.swift_ver_location,
+                                placement_rule, binfo.swift_ver_location,
                                 pquota_info, attrs,
                                 out_info, pobjv, &ep_objv, creation_time,
                                 pmaster_bucket, pmaster_num_shards, true);
@@ -6574,11 +6579,10 @@ int RGWBulkUploadOp::handle_file(const boost::string_ref path,
   }
 
   rgw::AioThrottle aio(store->ctx()->_conf->rgw_put_obj_min_window_size);
-  rgw_placement_rule& tail_placement = s->info.storage_class;
 
   using namespace rgw::putobj;
 
-  AtomicObjectProcessor processor(&aio, store, binfo, &tail_placement, bowner.get_id(),
+  AtomicObjectProcessor processor(&aio, store, binfo, &s->dest_placement, bowner.get_id(),
                                   obj_ctx, obj, 0, s->req_id);
 
   op_ret = processor.prepare();
index df379b3e4a9ee7cb3708b0f85c44547b32300ff3..819c957c90088c3a6107b7ea56ee21cae3dd2fc6 100644 (file)
@@ -3385,7 +3385,7 @@ int RGWRados::swift_versioning_copy(RGWObjectCtx& obj_ctx,
                obj,
                dest_bucket_info,
                bucket_info,
-               nullptr, /* const string *tail_rule */
+               bucket_info.placement_rule,
                NULL, /* time_t *src_mtime */
                NULL, /* time_t *mtime */
                NULL, /* const time_t *mod_ptr */
@@ -3477,7 +3477,7 @@ int RGWRados::swift_versioning_restore(RGWSysObjectCtx& sysobj_ctx,
                        archive_obj,   /* src obj */
                        bucket_info,   /* dest bucket info */
                        archive_binfo, /* src bucket info */
-                       nullptr,       /* const string *ptail_rule */
+                       bucket_info.placement_rule,  /* placement_rule */
                        nullptr,       /* time_t *src_mtime */
                        nullptr,       /* time_t *mtime */
                        nullptr,       /* const time_t *mod_ptr */
@@ -3640,6 +3640,12 @@ int RGWRados::Object::Write::_do_write_meta(uint64_t size, uint64_t accounted_si
     op.setxattr(RGW_ATTR_SOURCE_ZONE, bl);
   }
 
+  if (!storage_class.empty()) {
+    bufferlist bl;
+    bl.append(storage_class);
+    op.setxattr(RGW_ATTR_STORAGE_CLASS, bl);
+  }
+
   if (!op.size())
     return 0;
 
@@ -3979,7 +3985,8 @@ int RGWRados::rewrite_obj(RGWBucketInfo& dest_bucket_info, const rgw_obj& obj)
   attrset.erase(RGW_ATTR_ID_TAG);
   attrset.erase(RGW_ATTR_TAIL_TAG);
 
-  return copy_obj_data(rctx, dest_bucket_info, nullptr, read_op, obj_size - 1, obj, NULL, mtime, attrset,
+  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);
 }
 
@@ -4486,7 +4493,7 @@ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx,
                rgw_obj& src_obj,
                RGWBucketInfo& dest_bucket_info,
                RGWBucketInfo& src_bucket_info,
-               rgw_placement_rule *ptail_rule,
+               const rgw_placement_rule& dest_placement,
                real_time *src_mtime,
                real_time *mtime,
                const real_time *mod_ptr,
@@ -4611,31 +4618,23 @@ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx,
     src_rule = &src_bucket_info.placement_rule;
   }
 
-  if (!ptail_rule) {
-    ptail_rule = &dest_bucket_info.placement_rule;
-  } else {
-    ptail_rule->inherit_from(dest_bucket_info.placement_rule);
-  }
-
-  auto& dest_storage_class = ptail_rule->get_storage_class();
-  bufferlist scbl;
-  scbl.append(dest_storage_class);
-  attrs[RGW_ATTR_STORAGE_CLASS] = scbl;
-
   if (!get_obj_data_pool(*src_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(*ptail_rule, dest_obj, &dest_pool)) {
+  if (!get_obj_data_pool(dest_placement, dest_obj, &dest_pool)) {
     ldout(cct, 0) << "ERROR: failed to locate data pool for " << dest_obj << dendl;
     return -EIO;
   }
 
   ldout(cct, 20) << __func__ << "(): src_rule=" << src_rule->to_str() << " src_pool=" << src_pool
-                             << " dest_rule=" << ptail_rule->to_str() << " dest_pool=" << dest_pool << dendl;
+                             << " dest_rule=" << dest_placement.to_str() << " dest_pool=" << dest_pool << dendl;
+
+  bool copy_data = !astate->has_manifest ||
+    (*src_rule != dest_placement) ||
+    (src_pool != dest_pool);
 
-  bool copy_data = !astate->has_manifest || (src_pool != dest_pool);
   bool copy_first = false;
   if (astate->has_manifest) {
     if (!astate->manifest.has_tail()) {
@@ -4662,7 +4661,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, ptail_rule, read_op, obj_size - 1, dest_obj,
+    return copy_obj_data(obj_ctx, dest_bucket_info, dest_placement, read_op, obj_size - 1, dest_obj,
                          mtime, real_time(), attrs, olh_epoch, delete_at, petag);
   }
 
@@ -4779,7 +4778,7 @@ done_ret:
 
 int RGWRados::copy_obj_data(RGWObjectCtx& obj_ctx,
                RGWBucketInfo& dest_bucket_info,
-               const rgw_placement_rule *ptail_rule,
+               const rgw_placement_rule& dest_placement,
               RGWRados::Object::Read& read_op, off_t end,
                const rgw_obj& dest_obj,
               real_time *mtime,
@@ -4794,7 +4793,7 @@ int RGWRados::copy_obj_data(RGWObjectCtx& obj_ctx,
 
   rgw::AioThrottle aio(cct->_conf->rgw_put_obj_min_window_size);
   using namespace rgw::putobj;
-  AtomicObjectProcessor processor(&aio, this, dest_bucket_info, ptail_rule,
+  AtomicObjectProcessor processor(&aio, this, dest_bucket_info, &dest_placement,
                                   dest_bucket_info.owner, obj_ctx,
                                   dest_obj, olh_epoch, tag);
   int ret = processor.prepare();
index fec92774ab1fdd1ec2e5c9dd7cefd95273003c06..3114a083d0310ac2c0d82a5a9709f50fb8394190 100644 (file)
@@ -1942,7 +1942,7 @@ public:
                rgw_obj& src_obj,
                RGWBucketInfo& dest_bucket_info,
                RGWBucketInfo& src_bucket_info,
-               rgw_placement_rule *ptail_rule,
+               const rgw_placement_rule& dest_placement,
                ceph::real_time *src_mtime,
                ceph::real_time *mtime,
                const ceph::real_time *mod_ptr,
@@ -1964,7 +1964,7 @@ public:
 
   int copy_obj_data(RGWObjectCtx& obj_ctx,
                RGWBucketInfo& dest_bucket_info,
-               const rgw_placement_rule *ptail_rule,
+               const rgw_placement_rule& dest_placement,
               RGWRados::Object::Read& read_op, off_t end,
                const rgw_obj& dest_obj,
               ceph::real_time *mtime,
index 9b321b29f277ceb8bc9a846888ffe867ecbb6f52..3d623c3659ade2ede38b1d6c4f02606c25dc4a09 100644 (file)
@@ -117,7 +117,6 @@ static const struct generic_attr generic_attrs[] = {
   { "HTTP_CONTENT_DISPOSITION", RGW_ATTR_CONTENT_DISP },
   { "HTTP_CONTENT_ENCODING",    RGW_ATTR_CONTENT_ENC },
   { "HTTP_X_ROBOTS_TAG",        RGW_ATTR_X_ROBOTS_TAG },
-  { "HTTP_X_AMZ_STORAGE_CLASS", RGW_ATTR_STORAGE_CLASS },
 };
 
 map<string, string> rgw_to_http_attrs;
index 741e2199d7ede394965469b3d46e708d035381fc..c87b0cb13d34a452925dfdc61d22f5744644f47c 100644 (file)
@@ -1243,8 +1243,10 @@ int RGWCreateBucket_ObjStore_S3::get_params()
 
   size_t pos = location_constraint.find(':');
   if (pos != string::npos) {
-    placement_rule.init(location_constraint.substr(pos + 1), s->info.storage_class.storage_class);
+    placement_rule.init(location_constraint.substr(pos + 1), s->info.storage_class);
     location_constraint = location_constraint.substr(0, pos);
+  } else {
+    placement_rule.storage_class = s->info.storage_class;
   }
 
   return 0;
@@ -2196,7 +2198,7 @@ int RGWCopyObj_ObjStore_S3::get_params()
       (dest_bucket_name.compare(src_bucket_name) == 0) &&
       (dest_object.compare(src_object.name) == 0) &&
       src_object.instance.empty() &&
-      s->info.storage_class.storage_class.empty() &&
+      s->info.storage_class.empty() &&
       (attrs_mod != RGWRados::ATTRSMOD_REPLACE)) {
     /* can only copy object into itself if replacing attrs */
     s->err.message = "This copy request is illegal because it is trying to copy "
@@ -3440,7 +3442,7 @@ int RGWHandler_REST_S3::init(RGWRados *store, struct req_state *s,
 
   const char *sc = s->info.env->get("HTTP_X_AMZ_STORAGE_CLASS");
   if (sc) {
-    s->info.storage_class.storage_class = sc;
+    s->info.storage_class = sc;
   }
 
   return RGWHandler_REST::init(store, s, cio);
index 8ef2ed4bd175b21d85c5fadba673dc0f2c4864ff..702a435bd06394aeb87a2860022e2ebb16b1cb1f 100644 (file)
@@ -711,7 +711,7 @@ int RGWCreateBucket_ObjStore_SWIFT::get_params()
   location_constraint = store->svc.zone->get_zonegroup().api_name;
   get_rmattrs_from_headers(s, CONT_PUT_ATTR_PREFIX,
                            CONT_REMOVE_ATTR_PREFIX, rmattr_names);
-  placement_rule.init(s->info.env->get("HTTP_X_STORAGE_POLICY", ""), s->info.storage_class.storage_class);
+  placement_rule.init(s->info.env->get("HTTP_X_STORAGE_POLICY", ""), s->info.storage_class);
 
   return get_swift_versioning_settings(s, swift_ver_location);
 }
@@ -1125,7 +1125,7 @@ int RGWPutMetadataBucket_ObjStore_SWIFT::get_params()
 
   get_rmattrs_from_headers(s, CONT_PUT_ATTR_PREFIX, CONT_REMOVE_ATTR_PREFIX,
                           rmattr_names);
-  placement_rule.init(s->info.env->get("HTTP_X_STORAGE_POLICY", ""), s->info.storage_class.storage_class);
+  placement_rule.init(s->info.env->get("HTTP_X_STORAGE_POLICY", ""), s->info.storage_class);
 
   return get_swift_versioning_settings(s, swift_ver_location);
 }
@@ -3050,7 +3050,7 @@ int RGWHandler_REST_SWIFT::init(RGWRados* store, struct req_state* s,
     s->op = OP_PUT;
   }
 
-  s->info.storage_class.storage_class = s->info.env->get("HTTP_X_OBJECT_STORAGE_CLASS", "");
+  s->info.storage_class = s->info.env->get("HTTP_X_OBJECT_STORAGE_CLASS", "");
 
   return RGWHandler_REST::init(store, s, cio);
 }