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();
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);
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};
}
}
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);
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 */
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 {
}
}
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);
}
}
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);
return;
}
- rgw_placement_rule& dest_placement = s->info.storage_class;
-
op_ret = store->copy_obj(obj_ctx,
s->user->user_id,
&s->info,
src_obj,
dest_bucket_info,
src_bucket_info,
- &dest_placement,
+ s->dest_placement,
&src_mtime,
&mtime,
mod_ptr,
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;
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) {
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);
}
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();
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 */
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 */
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;
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);
}
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,
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()) {
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);
}
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,
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();
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,
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,
{ "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;
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;
(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 "
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);
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);
}
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);
}
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);
}