From 447b74c13a7eadc56d27c88a17ebffdd8c4af5d2 Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Thu, 11 Oct 2018 15:09:27 -0700 Subject: [PATCH] rgw: tighten storage_class assignment Signed-off-by: Yehuda Sadeh --- src/rgw/rgw_common.h | 11 +++++++++-- src/rgw/rgw_file.cc | 1 + src/rgw/rgw_op.cc | 26 ++++++++++++++----------- src/rgw/rgw_rados.cc | 41 +++++++++++++++++++-------------------- src/rgw/rgw_rados.h | 4 ++-- src/rgw/rgw_rest.cc | 1 - src/rgw/rgw_rest_s3.cc | 8 +++++--- src/rgw/rgw_rest_swift.cc | 6 +++--- 8 files changed, 55 insertions(+), 43 deletions(-) diff --git a/src/rgw/rgw_common.h b/src/rgw/rgw_common.h index fc8845e9fdd..07fe1eff5b9 100644 --- a/src/rgw/rgw_common.h +++ b/src/rgw/rgw_common.h @@ -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 bucket_attrs; bool bucket_exists{false}; + rgw_placement_rule dest_placement; bool has_bad_meta{false}; diff --git a/src/rgw/rgw_file.cc b/src/rgw/rgw_file.cc index 16bf507bbb4..b4c688380a7 100644 --- a/src/rgw/rgw_file.cc +++ b/src/rgw/rgw_file.cc @@ -1452,6 +1452,7 @@ namespace rgw { } } processor.emplace(&*aio, get_store(), s->bucket_info, + &s->dest_placement, s->bucket_owner.get_id(), *static_cast(s->obj_ctx), obj, olh_epoch, s->req_id); diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index 16829a4cc79..c6b52c9486b 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -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( - &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( - &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(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(); diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index df379b3e4a9..819c957c900 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -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(); diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h index fec92774ab1..3114a083d03 100644 --- a/src/rgw/rgw_rados.h +++ b/src/rgw/rgw_rados.h @@ -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, diff --git a/src/rgw/rgw_rest.cc b/src/rgw/rgw_rest.cc index 9b321b29f27..3d623c3659a 100644 --- a/src/rgw/rgw_rest.cc +++ b/src/rgw/rgw_rest.cc @@ -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 rgw_to_http_attrs; diff --git a/src/rgw/rgw_rest_s3.cc b/src/rgw/rgw_rest_s3.cc index 741e2199d7e..c87b0cb13d3 100644 --- a/src/rgw/rgw_rest_s3.cc +++ b/src/rgw/rgw_rest_s3.cc @@ -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); diff --git a/src/rgw/rgw_rest_swift.cc b/src/rgw/rgw_rest_swift.cc index 8ef2ed4bd17..702a435bd06 100644 --- a/src/rgw/rgw_rest_swift.cc +++ b/src/rgw/rgw_rest_swift.cc @@ -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); }