mirror of
https://github.com/ceph/ceph
synced 2024-12-18 01:16:55 +00:00
Merge pull request #4054 from diurchenko/wip-10662
rgw: Swift API. Allows setting attributes with COPY object operation. Reviewed-by: Yehuda Sadeh <yehuda@redhat.com>
This commit is contained in:
commit
6c5fe91e2c
@ -2407,7 +2407,7 @@ void RGWCopyObj::execute()
|
||||
unmod_ptr,
|
||||
if_match,
|
||||
if_nomatch,
|
||||
replace_attrs,
|
||||
attrs_mod,
|
||||
attrs, RGW_OBJ_CATEGORY_MAIN,
|
||||
olh_epoch,
|
||||
(version_id.empty() ? NULL : &version_id),
|
||||
|
@ -595,7 +595,7 @@ protected:
|
||||
rgw_bucket dest_bucket;
|
||||
string dest_object;
|
||||
time_t mtime;
|
||||
bool replace_attrs;
|
||||
RGWRados::AttrsMod attrs_mod;
|
||||
RGWBucketInfo src_bucket_info;
|
||||
RGWBucketInfo dest_bucket_info;
|
||||
string source_zone;
|
||||
@ -626,7 +626,7 @@ public:
|
||||
unmod_ptr = NULL;
|
||||
ret = 0;
|
||||
mtime = 0;
|
||||
replace_attrs = false;
|
||||
attrs_mod = RGWRados::ATTRSMOD_NONE;
|
||||
last_ofs = 0;
|
||||
olh_epoch = 0;
|
||||
}
|
||||
|
@ -3374,19 +3374,27 @@ public:
|
||||
};
|
||||
|
||||
/*
|
||||
* prepare attrset, either replace it with new attrs, or keep it (other than acls).
|
||||
* prepare attrset depending on attrs_mod.
|
||||
*/
|
||||
static void set_copy_attrs(map<string, bufferlist>& src_attrs, map<string, bufferlist>& attrs, bool replace_attrs, bool intra_region)
|
||||
static void set_copy_attrs(map<string, bufferlist>& src_attrs,
|
||||
map<string, bufferlist>& attrs,
|
||||
RGWRados::AttrsMod attrs_mod)
|
||||
{
|
||||
if (replace_attrs) {
|
||||
if (!attrs[RGW_ATTR_ETAG].length())
|
||||
switch (attrs_mod) {
|
||||
case RGWRados::ATTRSMOD_NONE:
|
||||
src_attrs[RGW_ATTR_ACL] = attrs[RGW_ATTR_ACL];
|
||||
break;
|
||||
case RGWRados::ATTRSMOD_REPLACE:
|
||||
if (!attrs[RGW_ATTR_ETAG].length()) {
|
||||
attrs[RGW_ATTR_ETAG] = src_attrs[RGW_ATTR_ETAG];
|
||||
|
||||
}
|
||||
src_attrs = attrs;
|
||||
} else {
|
||||
/* copying attrs from source, however acls should only be copied if it's intra-region operation */
|
||||
if (!intra_region)
|
||||
src_attrs[RGW_ATTR_ACL] = attrs[RGW_ATTR_ACL];
|
||||
break;
|
||||
case RGWRados::ATTRSMOD_MERGE:
|
||||
for (map<string, bufferlist>::iterator it = attrs.begin(); it != attrs.end(); ++it) {
|
||||
src_attrs[it->first] = it->second;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3441,7 +3449,7 @@ int RGWRados::fetch_remote_obj(RGWObjectCtx& obj_ctx,
|
||||
const time_t *unmod_ptr,
|
||||
const char *if_match,
|
||||
const char *if_nomatch,
|
||||
bool replace_attrs,
|
||||
AttrsMod attrs_mod,
|
||||
map<string, bufferlist>& attrs,
|
||||
RGWObjCategory category,
|
||||
uint64_t olh_epoch,
|
||||
@ -3533,7 +3541,9 @@ int RGWRados::fetch_remote_obj(RGWObjectCtx& obj_ctx,
|
||||
}
|
||||
}
|
||||
|
||||
set_copy_attrs(src_attrs, attrs, replace_attrs, !source_zone.empty());
|
||||
if (source_zone.empty()) {
|
||||
set_copy_attrs(src_attrs, attrs, attrs_mod);
|
||||
}
|
||||
|
||||
ret = cb.complete(etag, mtime, set_mtime, src_attrs);
|
||||
if (ret < 0)
|
||||
@ -3584,7 +3594,14 @@ int RGWRados::copy_obj_to_remote_dest(RGWObjState *astate,
|
||||
* Copy an object.
|
||||
* dest_obj: the object to copy into
|
||||
* src_obj: the object to copy from
|
||||
* attrs: if replace_attrs is set then these are placed on the new object
|
||||
* attrs: usage depends on attrs_mod parameter
|
||||
* attrs_mod: the modification mode of the attrs, may have the following values:
|
||||
* ATTRSMOD_NONE - the attributes of the source object will be
|
||||
* copied without modifications, attrs parameter is ignored;
|
||||
* ATTRSMOD_REPLACE - new object will have the attributes provided by attrs
|
||||
* parameter, source object attributes are not copied;
|
||||
* ATTRSMOD_MERGE - any conflicting meta keys on the source object's attributes
|
||||
* are overwritten by values contained in attrs parameter.
|
||||
* err: stores any errors resulting from the get of the original object
|
||||
* Returns: 0 on success, -ERR# otherwise.
|
||||
*/
|
||||
@ -3603,7 +3620,7 @@ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx,
|
||||
const time_t *unmod_ptr,
|
||||
const char *if_match,
|
||||
const char *if_nomatch,
|
||||
bool replace_attrs,
|
||||
AttrsMod attrs_mod,
|
||||
map<string, bufferlist>& attrs,
|
||||
RGWObjCategory category,
|
||||
uint64_t olh_epoch,
|
||||
@ -3639,7 +3656,7 @@ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx,
|
||||
if (remote_src || !source_zone.empty()) {
|
||||
return fetch_remote_obj(obj_ctx, user_id, client_id, op_id, info, source_zone,
|
||||
dest_obj, src_obj, dest_bucket_info, src_bucket_info, mtime, mod_ptr,
|
||||
unmod_ptr, if_match, if_nomatch, replace_attrs, attrs, category,
|
||||
unmod_ptr, if_match, if_nomatch, attrs_mod, attrs, category,
|
||||
olh_epoch, version_id, ptag, petag, err, progress_cb, progress_data);
|
||||
}
|
||||
|
||||
@ -3664,7 +3681,7 @@ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx,
|
||||
return ret;
|
||||
}
|
||||
|
||||
set_copy_attrs(src_attrs, attrs, replace_attrs, false);
|
||||
set_copy_attrs(src_attrs, attrs, attrs_mod);
|
||||
src_attrs.erase(RGW_ATTR_ID_TAG);
|
||||
|
||||
RGWObjManifest manifest;
|
||||
|
@ -1685,6 +1685,12 @@ public:
|
||||
virtual int aio_wait(void *handle);
|
||||
virtual bool aio_completed(void *handle);
|
||||
|
||||
enum AttrsMod {
|
||||
ATTRSMOD_NONE = 0,
|
||||
ATTRSMOD_REPLACE = 1,
|
||||
ATTRSMOD_MERGE = 2
|
||||
};
|
||||
|
||||
int rewrite_obj(RGWBucketInfo& dest_bucket_info, rgw_obj& obj);
|
||||
int fetch_remote_obj(RGWObjectCtx& obj_ctx,
|
||||
const string& user_id,
|
||||
@ -1701,7 +1707,7 @@ public:
|
||||
const time_t *unmod_ptr,
|
||||
const char *if_match,
|
||||
const char *if_nomatch,
|
||||
bool replace_attrs,
|
||||
AttrsMod attrs_mod,
|
||||
map<string, bufferlist>& attrs,
|
||||
RGWObjCategory category,
|
||||
uint64_t olh_epoch,
|
||||
@ -1721,7 +1727,14 @@ public:
|
||||
* Copy an object.
|
||||
* dest_obj: the object to copy into
|
||||
* src_obj: the object to copy from
|
||||
* attrs: if replace_attrs is set then these are placed on the new object
|
||||
* attrs: usage depends on attrs_mod parameter
|
||||
* attrs_mod: the modification mode of the attrs, may have the following values:
|
||||
* ATTRSMOD_NONE - the attributes of the source object will be
|
||||
* copied without modifications, attrs parameter is ignored;
|
||||
* ATTRSMOD_REPLACE - new object will have the attributes provided by attrs
|
||||
* parameter, source object attributes are not copied;
|
||||
* ATTRSMOD_MERGE - any conflicting meta keys on the source object's attributes
|
||||
* are overwritten by values contained in attrs parameter.
|
||||
* err: stores any errors resulting from the get of the original object
|
||||
* Returns: 0 on success, -ERR# otherwise.
|
||||
*/
|
||||
@ -1740,7 +1753,7 @@ public:
|
||||
const time_t *unmod_ptr,
|
||||
const char *if_match,
|
||||
const char *if_nomatch,
|
||||
bool replace_attrs,
|
||||
AttrsMod attrs_mod,
|
||||
map<std::string, bufferlist>& attrs,
|
||||
RGWObjCategory category,
|
||||
uint64_t olh_epoch,
|
||||
|
@ -1448,11 +1448,11 @@ int RGWCopyObj_ObjStore_S3::get_params()
|
||||
const char *md_directive = s->info.env->get("HTTP_X_AMZ_METADATA_DIRECTIVE");
|
||||
if (md_directive) {
|
||||
if (strcasecmp(md_directive, "COPY") == 0) {
|
||||
replace_attrs = false;
|
||||
attrs_mod = RGWRados::ATTRSMOD_NONE;
|
||||
} else if (strcasecmp(md_directive, "REPLACE") == 0) {
|
||||
replace_attrs = true;
|
||||
attrs_mod = RGWRados::ATTRSMOD_REPLACE;
|
||||
} else if (!source_zone.empty()) {
|
||||
replace_attrs = false; // default for intra-region copy
|
||||
attrs_mod = RGWRados::ATTRSMOD_NONE; // default for intra-region copy
|
||||
} else {
|
||||
ldout(s->cct, 0) << "invalid metadata directive" << dendl;
|
||||
return -EINVAL;
|
||||
@ -1463,7 +1463,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() &&
|
||||
!replace_attrs) {
|
||||
(attrs_mod != RGWRados::ATTRSMOD_REPLACE)) {
|
||||
/* can only copy object into itself if replacing attrs */
|
||||
ldout(s->cct, 0) << "can't copy object into itself if not replacing attrs" << dendl;
|
||||
return -ERR_INVALID_REQUEST;
|
||||
|
@ -572,6 +572,10 @@ int RGWCopyObj_ObjStore_SWIFT::get_params()
|
||||
dest_bucket_name = s->bucket_name_str;
|
||||
dest_object = s->object.name;
|
||||
|
||||
if (!s->info.x_meta_map.empty()) {
|
||||
attrs_mod = RGWRados::ATTRSMOD_MERGE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user