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:
Yehuda Sadeh 2015-04-20 09:38:20 -07:00
commit 7efea25c6c
8 changed files with 105 additions and 46 deletions

View File

@ -2415,6 +2415,7 @@ void RGWCopyObj::execute()
src_obj,
dest_bucket_info,
src_bucket_info,
&src_mtime,
&mtime,
mod_ptr,
unmod_ptr,

View File

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

View File

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

View File

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

View File

@ -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];

View File

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

View File

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

View File

@ -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() {}