From: Yehuda Sadeh Date: Thu, 4 Aug 2016 00:27:09 +0000 (-0700) Subject: rgw: add cr to stat remote obj X-Git-Tag: v11.1.0~681^2~24 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=d75ffe42773813aa6a24ce6d49dd65ee98cd5546;p=ceph.git rgw: add cr to stat remote obj Signed-off-by: Yehuda Sadeh --- diff --git a/src/rgw/rgw_cr_rados.cc b/src/rgw/rgw_cr_rados.cc index 99f8427e45178..5e54cc4ef2534 100644 --- a/src/rgw/rgw_cr_rados.cc +++ b/src/rgw/rgw_cr_rados.cc @@ -525,6 +525,46 @@ int RGWAsyncFetchRemoteObj::_send_request() return r; } +int RGWAsyncStatRemoteObj::_send_request() +{ + RGWObjectCtx obj_ctx(store); + + string user_id; + char buf[16]; + snprintf(buf, sizeof(buf), ".%lld", (long long)store->instance_id()); + string client_id = store->zone_id() + buf; + string op_id = store->unique_id(store->get_new_req_id()); + map attrs; + + rgw_obj src_obj(bucket_info.bucket, key.name); + src_obj.set_instance(key.instance); + + rgw_obj dest_obj(src_obj); + + int r = store->stat_remote_obj(obj_ctx, + user_id, + client_id, + nullptr, /* req_info */ + source_zone, + src_obj, + bucket_info, /* source */ + nullptr, /* real_time* src_mtime, */ + nullptr, /* const real_time* mod_ptr, */ + nullptr, /* const real_time* unmod_ptr, */ + true, /* high precision time */ + nullptr, /* const char *if_match, */ + nullptr, /* const char *if_nomatch, */ + attrs, + nullptr, + nullptr, /* string *ptag, */ + nullptr); /* string *petag, */ + + if (r < 0) { + ldout(store->ctx(), 0) << "store->fetch_remote_obj() returned r=" << r << dendl; + } + return r; +} + int RGWAsyncRemoveObj::_send_request() { diff --git a/src/rgw/rgw_cr_rados.h b/src/rgw/rgw_cr_rados.h index a1cbfabc8dee3..4265a4192c833 100644 --- a/src/rgw/rgw_cr_rados.h +++ b/src/rgw/rgw_cr_rados.h @@ -789,6 +789,82 @@ public: } }; +class RGWAsyncStatRemoteObj : public RGWAsyncRadosRequest { + RGWRados *store; + string source_zone; + + RGWBucketInfo bucket_info; + + rgw_obj_key key; + uint64_t versioned_epoch; + + real_time src_mtime; + +protected: + int _send_request(); +public: + RGWAsyncStatRemoteObj(RGWCoroutine *caller, RGWAioCompletionNotifier *cn, RGWRados *_store, + const string& _source_zone, + RGWBucketInfo& _bucket_info, + const rgw_obj_key& _key, + uint64_t _versioned_epoch) : RGWAsyncRadosRequest(caller, cn), store(_store), + source_zone(_source_zone), + bucket_info(_bucket_info), + key(_key), + versioned_epoch(_versioned_epoch) {} +}; + +class RGWStatRemoteObjCR : public RGWSimpleCoroutine { + CephContext *cct; + RGWAsyncRadosProcessor *async_rados; + RGWRados *store; + string source_zone; + + RGWBucketInfo bucket_info; + + rgw_obj_key key; + uint64_t versioned_epoch; + + RGWAsyncStatRemoteObj *req; + +public: + RGWStatRemoteObjCR(RGWAsyncRadosProcessor *_async_rados, RGWRados *_store, + const string& _source_zone, + RGWBucketInfo& _bucket_info, + const rgw_obj_key& _key, + uint64_t _versioned_epoch, + bool _if_newer) : RGWSimpleCoroutine(_store->ctx()), cct(_store->ctx()), + async_rados(_async_rados), store(_store), + source_zone(_source_zone), + bucket_info(_bucket_info), + key(_key), + versioned_epoch(_versioned_epoch), + req(NULL) {} + + + ~RGWStatRemoteObjCR() { + request_cleanup(); + } + + void request_cleanup() { + if (req) { + req->finish(); + req = NULL; + } + } + + int send_request() { + req = new RGWAsyncStatRemoteObj(this, stack->create_completion_notifier(), store, source_zone, bucket_info, + key, versioned_epoch); + async_rados->queue(req); + return 0; + } + + int request_complete() { + return req->get_ret_status(); + } +}; + class RGWAsyncRemoveObj : public RGWAsyncRadosRequest { RGWRados *store; string source_zone; diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index 98e2b6af0a526..acc5b73a6e27a 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -6743,6 +6743,126 @@ inline ostream& operator<<(ostream& out, const obj_time_weight &o) { return out; } +class RGWGetExtraDataCB : public RGWGetDataCB { + bufferlist extra_data; +public: + RGWGetExtraDataCB() {} + int handle_data(bufferlist& bl, off_t bl_ofs, off_t bl_len) { + if (extra_data.length() < extra_data_len) { + off_t max = extra_data_len - extra_data.length(); + if (max > bl_len) { + max = bl_len; + } + bl.splice(0, max, &extra_data); + } + return bl_len; + } + + bufferlist& get_extra_data() { + return extra_data; + } +}; + +int RGWRados::stat_remote_obj(RGWObjectCtx& obj_ctx, + const rgw_user& user_id, + const string& client_id, + req_info *info, + const string& source_zone, + rgw_obj& src_obj, + RGWBucketInfo& src_bucket_info, + real_time *src_mtime, + const real_time *mod_ptr, + const real_time *unmod_ptr, + bool high_precision_time, + const char *if_match, + const char *if_nomatch, + map& attrs, + string *version_id, + string *ptag, + string *petag) +{ + /* source is in a different zonegroup, copy from there */ + + RGWRESTStreamRWRequest *in_stream_req; + string tag; + map src_attrs; + append_rand_alpha(cct, tag, tag, 32); + obj_time_weight set_mtime_weight; + set_mtime_weight.high_precision = high_precision_time; + + RGWRESTConn *conn; + if (source_zone.empty()) { + if (src_bucket_info.zonegroup.empty()) { + /* source is in the master zonegroup */ + conn = rest_master_conn; + } else { + map::iterator iter = zonegroup_conn_map.find(src_bucket_info.zonegroup); + if (iter == zonegroup_conn_map.end()) { + ldout(cct, 0) << "could not find zonegroup connection to zonegroup: " << source_zone << dendl; + return -ENOENT; + } + conn = iter->second; + } + } else { + map::iterator iter = zone_conn_map.find(source_zone); + if (iter == zone_conn_map.end()) { + ldout(cct, 0) << "could not find zone connection to zone: " << source_zone << dendl; + return -ENOENT; + } + conn = iter->second; + } + + RGWGetExtraDataCB cb; + string etag; + map req_headers; + real_time set_mtime; + + const real_time *pmod = mod_ptr; + + obj_time_weight dest_mtime_weight; + + int ret = conn->get_obj(user_id, info, src_obj, pmod, unmod_ptr, + dest_mtime_weight.zone_short_id, dest_mtime_weight.pg_ver, + true, false, &cb, &in_stream_req); + if (ret < 0) { + return ret; + } + + ret = conn->complete_request(in_stream_req, etag, &set_mtime, req_headers); + if (ret < 0) { + return ret; + } + + bufferlist& extra_data_bl = cb.get_extra_data(); + if (extra_data_bl.length()) { + JSONParser jp; + if (!jp.parse(extra_data_bl.c_str(), extra_data_bl.length())) { + ldout(cct, 0) << "failed to parse response extra data. len=" << extra_data_bl.length() << " data=" << extra_data_bl.c_str() << dendl; + return -EIO; + } + + JSONDecoder::decode_json("attrs", src_attrs, &jp); + + src_attrs.erase(RGW_ATTR_MANIFEST); // not interested in original object layout + } + + if (src_mtime) { + *src_mtime = set_mtime; + } + + if (petag) { + map::iterator iter = src_attrs.find(RGW_ATTR_ETAG); + if (iter != src_attrs.end()) { + bufferlist& etagbl = iter->second; + *petag = etagbl.to_str(); + } + } + + attrs = src_attrs; + + return 0; +} + int RGWRados::fetch_remote_obj(RGWObjectCtx& obj_ctx, const rgw_user& user_id, const string& client_id, diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h index e3e8e25ade9d8..e13d36ae40bed 100644 --- a/src/rgw/rgw_rados.h +++ b/src/rgw/rgw_rados.h @@ -2557,6 +2557,25 @@ public: }; int rewrite_obj(RGWBucketInfo& dest_bucket_info, rgw_obj& obj); + + int stat_remote_obj(RGWObjectCtx& obj_ctx, + const rgw_user& user_id, + const string& client_id, + req_info *info, + const string& source_zone, + rgw_obj& src_obj, + RGWBucketInfo& src_bucket_info, + real_time *src_mtime, + const real_time *mod_ptr, + const real_time *unmod_ptr, + bool high_precision_time, + const char *if_match, + const char *if_nomatch, + map& attrs, + string *version_id, + string *ptag, + string *petag); + int fetch_remote_obj(RGWObjectCtx& obj_ctx, const rgw_user& user_id, const string& client_id,