rgw: tighten storage_class assignment

Signed-off-by: Yehuda Sadeh <yehuda@redhat.com>
This commit is contained in:
Yehuda Sadeh 2018-10-11 15:09:27 -07:00
parent f3676ebfd4
commit 447b74c13a
8 changed files with 55 additions and 43 deletions

View 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};

View 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);

View 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();

View 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();

View 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,

View 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;

View 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);

View 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);
}