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<string, bufferlist> 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()
{
}
};
+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;
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<string, bufferlist>& attrs,
+ string *version_id,
+ string *ptag,
+ string *petag)
+{
+ /* source is in a different zonegroup, copy from there */
+
+ RGWRESTStreamRWRequest *in_stream_req;
+ string tag;
+ map<string, bufferlist> 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<string, RGWRESTConn *>::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<string, RGWRESTConn *>::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<string, string> 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<string, bufferlist>::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,
};
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<string, bufferlist>& attrs,
+ string *version_id,
+ string *ptag,
+ string *petag);
+
int fetch_remote_obj(RGWObjectCtx& obj_ctx,
const rgw_user& user_id,
const string& client_id,