if (need_metadata_upload()) {
/* It's supposed that following functions WILL NOT change any special
* attributes (like RGW_ATTR_ACL) if they are already present in attrs. */
- rgw_get_request_metadata(s->cct, s->info, attrs, false);
+ op_ret = rgw_get_request_metadata(s->cct, s->info, attrs, false);
+ if (op_ret < 0) {
+ return;
+ }
prepare_add_del_attrs(s->bucket_attrs, rmattr_names, attrs);
populate_with_generic_attrs(s, attrs);
attrs.clear();
- rgw_get_request_metadata(s->cct, s->info, attrs, false);
+ op_ret = rgw_get_request_metadata(s->cct, s->info, attrs, false);
+ if (op_ret < 0) {
+ return;
+ }
prepare_add_del_attrs(s->bucket_attrs, rmattr_names, attrs);
populate_with_generic_attrs(s, attrs);
op_ret = filter_out_quota_info(attrs, rmattr_names, s->bucket_info.quota);
emplace_attr(RGW_ATTR_ETAG, std::move(bl));
populate_with_generic_attrs(s, attrs);
- rgw_get_request_metadata(s->cct, s->info, attrs);
+ op_ret = rgw_get_request_metadata(s->cct, s->info, attrs);
+ if (op_ret < 0) {
+ goto done;
+ }
encode_delete_at_attr(delete_at, attrs);
encode_obj_tags_attr(obj_tags.get(), attrs);
attrs.emplace(RGW_ATTR_ACL, std::move(acl_bl));
}
- rgw_get_request_metadata(s->cct, s->info, attrs, false);
+ op_ret = rgw_get_request_metadata(s->cct, s->info, attrs, false);
+ if (op_ret < 0) {
+ return op_ret;
+ }
prepare_add_del_attrs(orig_attrs, rmattr_names, attrs);
populate_with_generic_attrs(s, attrs);
return;
}
- rgw_get_request_metadata(s->cct, s->info, attrs, false);
+ op_ret = rgw_get_request_metadata(s->cct, s->info, attrs, false);
+ if (op_ret < 0) {
+ return;
+ }
if (!placement_rule.empty() &&
placement_rule != s->bucket_info.placement_rule) {
return;
}
- rgw_get_request_metadata(s->cct, s->info, attrs);
+ op_ret = rgw_get_request_metadata(s->cct, s->info, attrs);
+ if (op_ret < 0) {
+ return;
+ }
+
/* check if obj exists, read orig attrs */
op_ret = get_obj_attrs(store, s, obj, orig_attrs);
if (op_ret < 0) {
dest_policy.encode(aclbl);
emplace_attr(RGW_ATTR_ACL, std::move(aclbl));
- rgw_get_request_metadata(s->cct, s->info, attrs);
+ op_ret = rgw_get_request_metadata(s->cct, s->info, attrs);
+ if (op_ret < 0) {
+ return op_ret;
+ }
populate_with_generic_attrs(s, attrs);
return 0;
if (op_ret != 0)
return;
- rgw_get_request_metadata(s->cct, s->info, attrs);
+ op_ret = rgw_get_request_metadata(s->cct, s->info, attrs);
+ if (op_ret < 0) {
+ return;
+ }
do {
char buf[33];
* map(<attr_name, attr_contents>, where attr_name is RGW_ATTR_PREFIX.HTTP_NAME)
* s: The request state
* attrs: will be filled up with attrs mapped as <attr_name, attr_contents>
+ * On success returns 0.
+ * On failure returns a negative error code.
*
*/
-static inline void rgw_get_request_metadata(CephContext *cct,
- struct req_info& info,
- map<string, bufferlist>& attrs,
- const bool allow_empty_attrs = true)
+static inline int rgw_get_request_metadata(CephContext* const cct,
+ struct req_info& info,
+ std::map<std::string, ceph::bufferlist>& attrs,
+ const bool allow_empty_attrs = true)
{
static const std::set<std::string> blacklisted_headers = {
"x-amz-server-side-encryption-customer-algorithm",
format_xattr(xattr);
string attr_name(RGW_ATTR_PREFIX);
attr_name.append(name);
+
+ /* Check early whether we aren't going behind the limit on attribute
+ * name. Passing here doesn't guarantee that an OSD will accept that
+ * as ObjectStore::get_max_attr_name_length() can set the limit even
+ * lower. However, we're claiming "max_meta_name_length" in /info as
+ * being dependent on the "osd_max_attr_name_len". */
+ if (attr_name.length() > cct->_conf->osd_max_attr_name_len) {
+ return -ENAMETOOLONG;
+ }
+
map<string, bufferlist>::value_type v(attr_name, bufferlist());
std::pair < map<string, bufferlist>::iterator, bool >
rval(attrs.insert(v));
bl.append(xattr.c_str(), xattr.size() + 1);
}
}
+
+ return 0;
} /* rgw_get_request_metadata */
static inline void encode_delete_at_attr(boost::optional<ceph::real_time> delete_at,