mirror of
https://github.com/ceph/ceph
synced 2024-12-21 02:42:48 +00:00
Merge pull request #3991 from rzarzynski/wip-11087
rgw: multiple fixes for copying Swift objects Reviewed-by: Yehuda Sadeh <yehuda@redhat.com>
This commit is contained in:
commit
7efea25c6c
@ -2415,6 +2415,7 @@ void RGWCopyObj::execute()
|
||||
src_obj,
|
||||
dest_bucket_info,
|
||||
src_bucket_info,
|
||||
&src_mtime,
|
||||
&mtime,
|
||||
mod_ptr,
|
||||
unmod_ptr,
|
||||
|
@ -595,6 +595,7 @@ protected:
|
||||
string dest_bucket_name;
|
||||
rgw_bucket dest_bucket;
|
||||
string dest_object;
|
||||
time_t src_mtime;
|
||||
time_t mtime;
|
||||
RGWRados::AttrsMod attrs_mod;
|
||||
RGWBucketInfo src_bucket_info;
|
||||
@ -626,6 +627,7 @@ public:
|
||||
mod_ptr = NULL;
|
||||
unmod_ptr = NULL;
|
||||
ret = 0;
|
||||
src_mtime = 0;
|
||||
mtime = 0;
|
||||
attrs_mod = RGWRados::ATTRSMOD_NONE;
|
||||
last_ofs = 0;
|
||||
|
@ -3457,6 +3457,7 @@ int RGWRados::fetch_remote_obj(RGWObjectCtx& obj_ctx,
|
||||
rgw_obj& src_obj,
|
||||
RGWBucketInfo& dest_bucket_info,
|
||||
RGWBucketInfo& src_bucket_info,
|
||||
time_t *src_mtime,
|
||||
time_t *mtime,
|
||||
const time_t *mod_ptr,
|
||||
const time_t *unmod_ptr,
|
||||
@ -3484,8 +3485,9 @@ int RGWRados::fetch_remote_obj(RGWObjectCtx& obj_ctx,
|
||||
dest_bucket_info, dest_obj.bucket, dest_obj.get_object(),
|
||||
cct->_conf->rgw_obj_stripe_size, tag, dest_bucket_info.versioning_enabled());
|
||||
int ret = processor.prepare(this, NULL);
|
||||
if (ret < 0)
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
RGWRESTConn *conn;
|
||||
if (source_zone.empty()) {
|
||||
@ -3524,12 +3526,14 @@ int RGWRados::fetch_remote_obj(RGWObjectCtx& obj_ctx,
|
||||
time_t set_mtime;
|
||||
|
||||
ret = conn->get_obj(user_id, info, src_obj, true, &cb, &in_stream_req);
|
||||
if (ret < 0)
|
||||
if (ret < 0) {
|
||||
goto set_err_state;
|
||||
}
|
||||
|
||||
ret = conn->complete_request(in_stream_req, etag, &set_mtime, req_headers);
|
||||
if (ret < 0)
|
||||
if (ret < 0) {
|
||||
goto set_err_state;
|
||||
}
|
||||
|
||||
{ /* opening scope so that we can do goto, sorry */
|
||||
bufferlist& extra_data_bl = processor.get_extra_data();
|
||||
@ -3546,6 +3550,10 @@ int RGWRados::fetch_remote_obj(RGWObjectCtx& obj_ctx,
|
||||
}
|
||||
}
|
||||
|
||||
if (src_mtime) {
|
||||
*src_mtime = set_mtime;
|
||||
}
|
||||
|
||||
if (petag) {
|
||||
map<string, bufferlist>::iterator iter = src_attrs.find(RGW_ATTR_ETAG);
|
||||
if (iter != src_attrs.end()) {
|
||||
@ -3559,8 +3567,9 @@ int RGWRados::fetch_remote_obj(RGWObjectCtx& obj_ctx,
|
||||
}
|
||||
|
||||
ret = cb.complete(etag, mtime, set_mtime, src_attrs);
|
||||
if (ret < 0)
|
||||
if (ret < 0) {
|
||||
goto set_err_state;
|
||||
}
|
||||
|
||||
ret = opstate.set_state(RGWOpState::OPSTATE_COMPLETE);
|
||||
if (ret < 0) {
|
||||
@ -3628,6 +3637,7 @@ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx,
|
||||
rgw_obj& src_obj,
|
||||
RGWBucketInfo& dest_bucket_info,
|
||||
RGWBucketInfo& src_bucket_info,
|
||||
time_t *src_mtime,
|
||||
time_t *mtime,
|
||||
const time_t *mod_ptr,
|
||||
const time_t *unmod_ptr,
|
||||
@ -3646,7 +3656,6 @@ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx,
|
||||
{
|
||||
int ret;
|
||||
uint64_t total_len, obj_size;
|
||||
time_t lastmod;
|
||||
rgw_obj shadow_obj = dest_obj;
|
||||
string shadow_oid;
|
||||
|
||||
@ -3668,7 +3677,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,
|
||||
dest_obj, src_obj, dest_bucket_info, src_bucket_info, src_mtime, mtime, mod_ptr,
|
||||
unmod_ptr, if_match, if_nomatch, attrs_mod, attrs, category,
|
||||
olh_epoch, version_id, ptag, petag, err, progress_cb, progress_data);
|
||||
}
|
||||
@ -3684,7 +3693,7 @@ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx,
|
||||
read_op.conds.if_match = if_match;
|
||||
read_op.conds.if_nomatch = if_nomatch;
|
||||
read_op.params.attrs = &src_attrs;
|
||||
read_op.params.lastmod = &lastmod;
|
||||
read_op.params.lastmod = src_mtime;
|
||||
read_op.params.read_size = &total_len;
|
||||
read_op.params.obj_size = &obj_size;
|
||||
read_op.params.perr = err;
|
||||
@ -3700,8 +3709,9 @@ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx,
|
||||
RGWObjManifest manifest;
|
||||
RGWObjState *astate = NULL;
|
||||
ret = get_obj_state(&obj_ctx, src_obj, &astate, NULL);
|
||||
if (ret < 0)
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
vector<rgw_obj> ref_objs;
|
||||
|
||||
@ -3726,10 +3736,11 @@ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx,
|
||||
uint64_t head_size = astate->manifest.get_head_size();
|
||||
|
||||
if (head_size > 0) {
|
||||
if (head_size > max_chunk_size)
|
||||
copy_data = true;
|
||||
else
|
||||
if (head_size > max_chunk_size) {
|
||||
copy_data = true;
|
||||
} else {
|
||||
copy_first = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3750,8 +3761,9 @@ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx,
|
||||
|
||||
RGWObjManifest::obj_iterator miter = astate->manifest.obj_begin();
|
||||
|
||||
if (copy_first) // we need to copy first chunk, not increase refcount
|
||||
if (copy_first) { // we need to copy first chunk, not increase refcount
|
||||
++miter;
|
||||
}
|
||||
|
||||
rgw_rados_ref ref;
|
||||
rgw_bucket bucket;
|
||||
@ -3780,8 +3792,9 @@ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx,
|
||||
|
||||
string tag;
|
||||
|
||||
if (ptag)
|
||||
if (ptag) {
|
||||
tag = *ptag;
|
||||
}
|
||||
|
||||
if (tag.empty()) {
|
||||
append_rand_alpha(cct, tag, tag, 32);
|
||||
@ -3802,8 +3815,9 @@ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx,
|
||||
ref.ioctx.locator_set_key(key);
|
||||
|
||||
ret = ref.ioctx.operate(oid, &op);
|
||||
if (ret < 0)
|
||||
if (ret < 0) {
|
||||
goto done_ret;
|
||||
}
|
||||
|
||||
ref_objs.push_back(loc);
|
||||
}
|
||||
@ -3817,8 +3831,9 @@ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx,
|
||||
|
||||
if (copy_first) {
|
||||
ret = read_op.read(0, max_chunk_size, first_chunk);
|
||||
if (ret < 0)
|
||||
if (ret < 0) {
|
||||
goto done_ret;
|
||||
}
|
||||
|
||||
pmanifest->set_head(dest_obj);
|
||||
pmanifest->set_head_size(first_chunk.length());
|
||||
@ -3834,8 +3849,9 @@ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx,
|
||||
write_op.meta.olh_epoch = olh_epoch;
|
||||
|
||||
ret = write_op.write_meta(end + 1, attrs);
|
||||
if (ret < 0)
|
||||
if (ret < 0) {
|
||||
goto done_ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
|
@ -1703,6 +1703,7 @@ public:
|
||||
rgw_obj& src_obj,
|
||||
RGWBucketInfo& dest_bucket_info,
|
||||
RGWBucketInfo& src_bucket_info,
|
||||
time_t *src_mtime,
|
||||
time_t *mtime,
|
||||
const time_t *mod_ptr,
|
||||
const time_t *unmod_ptr,
|
||||
@ -1749,6 +1750,7 @@ public:
|
||||
rgw_obj& src_obj,
|
||||
RGWBucketInfo& dest_bucket_info,
|
||||
RGWBucketInfo& src_bucket_info,
|
||||
time_t *src_mtime,
|
||||
time_t *mtime,
|
||||
const time_t *mod_ptr,
|
||||
const time_t *unmod_ptr,
|
||||
|
@ -396,7 +396,7 @@ void dump_redirect(struct req_state *s, const string& redirect)
|
||||
s->cio->print("Location: %s\r\n", redirect.c_str());
|
||||
}
|
||||
|
||||
static void dump_time_header(struct req_state *s, const char *name, time_t t)
|
||||
void dump_time_header(struct req_state *s, const char *name, time_t t)
|
||||
{
|
||||
|
||||
char timestr[TIME_BUF_SIZE];
|
||||
|
@ -373,6 +373,7 @@ extern void dump_string_header(struct req_state *s, const char *name, const char
|
||||
extern void dump_content_length(struct req_state *s, uint64_t len);
|
||||
extern void dump_etag(struct req_state *s, const char *etag);
|
||||
extern void dump_epoch_header(struct req_state *s, const char *name, time_t t);
|
||||
extern void dump_time_header(struct req_state *s, const char *name, time_t t);
|
||||
extern void dump_last_modified(struct req_state *s, time_t t);
|
||||
extern void abort_early(struct req_state *s, RGWOp *op, int err);
|
||||
extern void dump_range(struct req_state *s, uint64_t ofs, uint64_t end, uint64_t total_size);
|
||||
|
@ -560,6 +560,41 @@ void RGWDeleteObj_ObjStore_SWIFT::send_response()
|
||||
rgw_flush_formatter_and_reset(s, s->formatter);
|
||||
}
|
||||
|
||||
static void get_contype_from_attrs(map<string, bufferlist>& attrs,
|
||||
string& content_type)
|
||||
{
|
||||
map<string, bufferlist>::iterator iter = attrs.find(RGW_ATTR_CONTENT_TYPE);
|
||||
if (iter != attrs.end()) {
|
||||
content_type = iter->second.c_str();
|
||||
}
|
||||
}
|
||||
|
||||
static void dump_object_metadata(struct req_state * const s,
|
||||
map<string, bufferlist> attrs)
|
||||
{
|
||||
map<string, string> response_attrs;
|
||||
map<string, string>::const_iterator riter;
|
||||
map<string, bufferlist>::iterator iter;
|
||||
|
||||
for (iter = attrs.begin(); iter != attrs.end(); ++iter) {
|
||||
const char *name = iter->first.c_str();
|
||||
map<string, string>::const_iterator aiter = rgw_to_http_attrs.find(name);
|
||||
|
||||
if (aiter != rgw_to_http_attrs.end() &&
|
||||
aiter->first.compare(RGW_ATTR_CONTENT_TYPE) != 0) {
|
||||
/* Filter out Content-Type. It must be treated separately. */
|
||||
response_attrs[aiter->second] = iter->second.c_str();
|
||||
} else if (strncmp(name, RGW_ATTR_META_PREFIX, sizeof(RGW_ATTR_META_PREFIX)-1) == 0) {
|
||||
name += sizeof(RGW_ATTR_META_PREFIX) - 1;
|
||||
s->cio->print("X-Object-Meta-%s: %s\r\n", name, iter->second.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
for (riter = response_attrs.begin(); riter != response_attrs.end(); ++riter) {
|
||||
s->cio->print("%s: %s\r\n", riter->first.c_str(), riter->second.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
int RGWCopyObj_ObjStore_SWIFT::init_dest_policy()
|
||||
{
|
||||
dest_policy.create_default(s->user.user_id, s->user.display_name);
|
||||
@ -611,14 +646,37 @@ void RGWCopyObj_ObjStore_SWIFT::send_partial_response(off_t ofs)
|
||||
rgw_flush_formatter(s, s->formatter);
|
||||
}
|
||||
|
||||
void RGWCopyObj_ObjStore_SWIFT::dump_copy_info()
|
||||
{
|
||||
/* Dump X-Copied-From */
|
||||
string objname, bucketname;
|
||||
url_encode(src_object.name, objname);
|
||||
url_encode(src_bucket.name, bucketname);
|
||||
s->cio->print("X-Copied-From: %s/%s\r\n", bucketname.c_str(), objname.c_str());
|
||||
|
||||
/* Dump X-Copied-From-Account */
|
||||
string account_name;
|
||||
url_encode(s->user.user_id, account_name);
|
||||
s->cio->print("X-Copied-From-Account: %s\r\n", account_name.c_str());
|
||||
|
||||
/* Dump X-Copied-From-Last-Modified. */
|
||||
dump_time_header(s, "X-Copied-From-Last-Modified", src_mtime);
|
||||
}
|
||||
|
||||
void RGWCopyObj_ObjStore_SWIFT::send_response()
|
||||
{
|
||||
if (!sent_header) {
|
||||
if (!ret)
|
||||
string content_type;
|
||||
if (!ret)
|
||||
ret = STATUS_CREATED;
|
||||
set_req_state_err(s, ret);
|
||||
dump_errno(s);
|
||||
end_header(s, this);
|
||||
dump_etag(s, etag.c_str());
|
||||
dump_last_modified(s, mtime);
|
||||
dump_copy_info();
|
||||
get_contype_from_attrs(attrs, content_type);
|
||||
dump_object_metadata(s, attrs);
|
||||
end_header(s, this, !content_type.empty() ? content_type.c_str() : "binary/octet-stream");
|
||||
} else {
|
||||
s->formatter->close_section();
|
||||
rgw_flush_formatter(s, s->formatter);
|
||||
@ -627,9 +685,7 @@ void RGWCopyObj_ObjStore_SWIFT::send_response()
|
||||
|
||||
int RGWGetObj_ObjStore_SWIFT::send_response_data(bufferlist& bl, off_t bl_ofs, off_t bl_len)
|
||||
{
|
||||
const char *content_type = NULL;
|
||||
map<string, string> response_attrs;
|
||||
map<string, string>::iterator riter;
|
||||
string content_type;
|
||||
|
||||
if (sent_header)
|
||||
goto send_data;
|
||||
@ -651,34 +707,13 @@ int RGWGetObj_ObjStore_SWIFT::send_response_data(bufferlist& bl, off_t bl_ofs, o
|
||||
}
|
||||
}
|
||||
|
||||
for (iter = attrs.begin(); iter != attrs.end(); ++iter) {
|
||||
const char *name = iter->first.c_str();
|
||||
map<string, string>::iterator aiter = rgw_to_http_attrs.find(name);
|
||||
if (aiter != rgw_to_http_attrs.end()) {
|
||||
if (aiter->first.compare(RGW_ATTR_CONTENT_TYPE) == 0) { // special handling for content_type
|
||||
content_type = iter->second.c_str();
|
||||
continue;
|
||||
}
|
||||
response_attrs[aiter->second] = iter->second.c_str();
|
||||
} else {
|
||||
if (strncmp(name, RGW_ATTR_META_PREFIX, sizeof(RGW_ATTR_META_PREFIX)-1) == 0) {
|
||||
name += sizeof(RGW_ATTR_META_PREFIX) - 1;
|
||||
s->cio->print("X-Object-Meta-%s: %s\r\n", name, iter->second.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
get_contype_from_attrs(attrs, content_type);
|
||||
dump_object_metadata(s, attrs);
|
||||
}
|
||||
|
||||
set_req_state_err(s, (partial_content && !ret) ? STATUS_PARTIAL_CONTENT : ret);
|
||||
dump_errno(s);
|
||||
|
||||
for (riter = response_attrs.begin(); riter != response_attrs.end(); ++riter) {
|
||||
s->cio->print("%s: %s\r\n", riter->first.c_str(), riter->second.c_str());
|
||||
}
|
||||
|
||||
if (!content_type)
|
||||
content_type = "binary/octet-stream";
|
||||
end_header(s, this, content_type);
|
||||
end_header(s, this, !content_type.empty() ? content_type.c_str() : "binary/octet-stream");
|
||||
|
||||
sent_header = true;
|
||||
|
||||
|
@ -114,6 +114,8 @@ public:
|
||||
|
||||
class RGWCopyObj_ObjStore_SWIFT : public RGWCopyObj_ObjStore {
|
||||
bool sent_header;
|
||||
protected:
|
||||
void dump_copy_info();
|
||||
public:
|
||||
RGWCopyObj_ObjStore_SWIFT() : sent_header(false) {}
|
||||
~RGWCopyObj_ObjStore_SWIFT() {}
|
||||
|
Loading…
Reference in New Issue
Block a user