2 #include "rgw_coroutine.h"
3 #include "rgw_boost_asio_yield.h"
4 #include "rgw_cr_rados.h"
6 #include "cls/lock/cls_lock_client.h"
8 #define dout_context g_ceph_context
9 #define dout_subsys ceph_subsys_rgw
11 bool RGWAsyncRadosProcessor::RGWWQ::_enqueue(RGWAsyncRadosRequest
*req
) {
12 if (processor
->is_going_down()) {
16 processor
->m_req_queue
.push_back(req
);
17 dout(20) << "enqueued request req=" << hex
<< req
<< dec
<< dendl
;
22 bool RGWAsyncRadosProcessor::RGWWQ::_empty() {
23 return processor
->m_req_queue
.empty();
26 RGWAsyncRadosRequest
*RGWAsyncRadosProcessor::RGWWQ::_dequeue() {
27 if (processor
->m_req_queue
.empty())
29 RGWAsyncRadosRequest
*req
= processor
->m_req_queue
.front();
30 processor
->m_req_queue
.pop_front();
31 dout(20) << "dequeued request req=" << hex
<< req
<< dec
<< dendl
;
36 void RGWAsyncRadosProcessor::RGWWQ::_process(RGWAsyncRadosRequest
*req
, ThreadPool::TPHandle
& handle
) {
37 processor
->handle_request(req
);
38 processor
->req_throttle
.put(1);
41 void RGWAsyncRadosProcessor::RGWWQ::_dump_queue() {
42 if (!g_conf
->subsys
.should_gather(ceph_subsys_rgw
, 20)) {
45 deque
<RGWAsyncRadosRequest
*>::iterator iter
;
46 if (processor
->m_req_queue
.empty()) {
47 dout(20) << "RGWWQ: empty" << dendl
;
50 dout(20) << "RGWWQ:" << dendl
;
51 for (iter
= processor
->m_req_queue
.begin(); iter
!= processor
->m_req_queue
.end(); ++iter
) {
52 dout(20) << "req: " << hex
<< *iter
<< dec
<< dendl
;
56 RGWAsyncRadosProcessor::RGWAsyncRadosProcessor(RGWRados
*_store
, int num_threads
)
57 : store(_store
), m_tp(store
->ctx(), "RGWAsyncRadosProcessor::m_tp", "rados_async", num_threads
),
58 req_throttle(store
->ctx(), "rgw_async_rados_ops", num_threads
* 2),
59 req_wq(this, g_conf
->rgw_op_thread_timeout
,
60 g_conf
->rgw_op_thread_suicide_timeout
, &m_tp
) {
63 void RGWAsyncRadosProcessor::start() {
67 void RGWAsyncRadosProcessor::stop() {
71 for (auto iter
= m_req_queue
.begin(); iter
!= m_req_queue
.end(); ++iter
) {
76 void RGWAsyncRadosProcessor::handle_request(RGWAsyncRadosRequest
*req
) {
81 void RGWAsyncRadosProcessor::queue(RGWAsyncRadosRequest
*req
) {
86 int RGWAsyncGetSystemObj::_send_request()
88 return store
->get_system_obj(*obj_ctx
, read_state
, objv_tracker
, obj
, *pbl
, ofs
, end
, pattrs
, NULL
);
91 RGWAsyncGetSystemObj::RGWAsyncGetSystemObj(RGWCoroutine
*caller
, RGWAioCompletionNotifier
*cn
, RGWRados
*_store
, RGWObjectCtx
*_obj_ctx
,
92 RGWObjVersionTracker
*_objv_tracker
, const rgw_raw_obj
& _obj
,
93 bufferlist
*_pbl
, off_t _ofs
, off_t _end
) : RGWAsyncRadosRequest(caller
, cn
), store(_store
), obj_ctx(_obj_ctx
),
94 objv_tracker(_objv_tracker
), obj(_obj
), pbl(_pbl
), pattrs(NULL
),
99 int RGWSimpleRadosReadAttrsCR::send_request()
101 req
= new RGWAsyncGetSystemObj(this, stack
->create_completion_notifier(),
102 store
, &obj_ctx
, NULL
,
106 req
->set_read_attrs(pattrs
);
108 async_rados
->queue(req
);
112 int RGWSimpleRadosReadAttrsCR::request_complete()
114 return req
->get_ret_status();
117 int RGWAsyncPutSystemObj::_send_request()
119 return store
->put_system_obj_data(NULL
, obj
, bl
, -1, exclusive
, objv_tracker
);
122 RGWAsyncPutSystemObj::RGWAsyncPutSystemObj(RGWCoroutine
*caller
, RGWAioCompletionNotifier
*cn
, RGWRados
*_store
,
123 RGWObjVersionTracker
*_objv_tracker
, rgw_raw_obj
& _obj
,
124 bool _exclusive
, bufferlist
& _bl
)
125 : RGWAsyncRadosRequest(caller
, cn
), store(_store
), objv_tracker(_objv_tracker
),
126 obj(_obj
), exclusive(_exclusive
), bl(_bl
)
130 int RGWAsyncPutSystemObjAttrs::_send_request()
132 return store
->system_obj_set_attrs(NULL
, obj
, *attrs
, NULL
, objv_tracker
);
135 RGWAsyncPutSystemObjAttrs::RGWAsyncPutSystemObjAttrs(RGWCoroutine
*caller
, RGWAioCompletionNotifier
*cn
, RGWRados
*_store
,
136 RGWObjVersionTracker
*_objv_tracker
, const rgw_raw_obj
& _obj
,
137 map
<string
, bufferlist
> *_attrs
) : RGWAsyncRadosRequest(caller
, cn
), store(_store
),
138 objv_tracker(_objv_tracker
), obj(_obj
),
144 RGWOmapAppend::RGWOmapAppend(RGWAsyncRadosProcessor
*_async_rados
, RGWRados
*_store
, const rgw_raw_obj
& _obj
,
145 uint64_t _window_size
)
146 : RGWConsumerCR
<string
>(_store
->ctx()), async_rados(_async_rados
),
147 store(_store
), obj(_obj
), going_down(false), num_pending_entries(0), window_size(_window_size
), total_entries(0)
151 int RGWAsyncLockSystemObj::_send_request()
154 int r
= store
->get_raw_obj_ref(obj
, &ref
);
156 lderr(store
->ctx()) << "ERROR: failed to get ref for (" << obj
<< ") ret=" << r
<< dendl
;
160 rados::cls::lock::Lock
l(lock_name
);
161 utime_t
duration(duration_secs
, 0);
162 l
.set_duration(duration
);
163 l
.set_cookie(cookie
);
166 return l
.lock_exclusive(&ref
.ioctx
, ref
.oid
);
169 RGWAsyncLockSystemObj::RGWAsyncLockSystemObj(RGWCoroutine
*caller
, RGWAioCompletionNotifier
*cn
, RGWRados
*_store
,
170 RGWObjVersionTracker
*_objv_tracker
, const rgw_raw_obj
& _obj
,
171 const string
& _name
, const string
& _cookie
, uint32_t _duration_secs
) : RGWAsyncRadosRequest(caller
, cn
), store(_store
),
175 duration_secs(_duration_secs
)
179 int RGWAsyncUnlockSystemObj::_send_request()
182 int r
= store
->get_raw_obj_ref(obj
, &ref
);
184 lderr(store
->ctx()) << "ERROR: failed to get ref for (" << obj
<< ") ret=" << r
<< dendl
;
188 rados::cls::lock::Lock
l(lock_name
);
190 l
.set_cookie(cookie
);
192 return l
.unlock(&ref
.ioctx
, ref
.oid
);
195 RGWAsyncUnlockSystemObj::RGWAsyncUnlockSystemObj(RGWCoroutine
*caller
, RGWAioCompletionNotifier
*cn
, RGWRados
*_store
,
196 RGWObjVersionTracker
*_objv_tracker
, const rgw_raw_obj
& _obj
,
197 const string
& _name
, const string
& _cookie
) : RGWAsyncRadosRequest(caller
, cn
), store(_store
),
199 lock_name(_name
), cookie(_cookie
)
204 RGWRadosSetOmapKeysCR::RGWRadosSetOmapKeysCR(RGWRados
*_store
,
205 const rgw_raw_obj
& _obj
,
206 map
<string
, bufferlist
>& _entries
) : RGWSimpleCoroutine(_store
->ctx()),
211 stringstream
& s
= set_description();
212 s
<< "set omap keys dest=" << obj
<< " keys=[" << s
.str() << "]";
213 for (auto i
= entries
.begin(); i
!= entries
.end(); ++i
) {
214 if (i
!= entries
.begin()) {
222 RGWRadosSetOmapKeysCR::~RGWRadosSetOmapKeysCR()
229 int RGWRadosSetOmapKeysCR::send_request()
231 int r
= store
->get_raw_obj_ref(obj
, &ref
);
233 lderr(store
->ctx()) << "ERROR: failed to get ref for (" << obj
<< ") ret=" << r
<< dendl
;
237 set_status() << "sending request";
239 librados::ObjectWriteOperation op
;
240 op
.omap_set(entries
);
242 cn
= stack
->create_completion_notifier();
244 return ref
.ioctx
.aio_operate(ref
.oid
, cn
->completion(), &op
);
247 int RGWRadosSetOmapKeysCR::request_complete()
249 int r
= cn
->completion()->get_return_value();
251 set_status() << "request complete; ret=" << r
;
256 RGWRadosGetOmapKeysCR::RGWRadosGetOmapKeysCR(RGWRados
*_store
,
257 const rgw_raw_obj
& _obj
,
258 const string
& _marker
,
259 map
<string
, bufferlist
> *_entries
, int _max_entries
) : RGWSimpleCoroutine(_store
->ctx()),
262 entries(_entries
), max_entries(_max_entries
), rval(0),
265 set_description() << "set omap keys dest=" << obj
<< " marker=" << marker
;
268 RGWRadosGetOmapKeysCR::~RGWRadosGetOmapKeysCR()
272 int RGWRadosGetOmapKeysCR::send_request() {
273 int r
= store
->get_raw_obj_ref(obj
, &ref
);
275 lderr(store
->ctx()) << "ERROR: failed to get ref for (" << obj
<< ") ret=" << r
<< dendl
;
279 set_status() << "send request";
281 librados::ObjectReadOperation op
;
282 op
.omap_get_vals2(marker
, max_entries
, entries
, nullptr, &rval
);
284 cn
= stack
->create_completion_notifier();
285 return ref
.ioctx
.aio_operate(ref
.oid
, cn
->completion(), &op
, NULL
);
288 RGWRadosRemoveOmapKeysCR::RGWRadosRemoveOmapKeysCR(RGWRados
*_store
,
289 const rgw_raw_obj
& _obj
,
290 const set
<string
>& _keys
) : RGWSimpleCoroutine(_store
->ctx()),
295 set_description() << "remove omap keys dest=" << obj
<< " keys=" << keys
;
298 RGWRadosRemoveOmapKeysCR::~RGWRadosRemoveOmapKeysCR()
302 int RGWRadosRemoveOmapKeysCR::send_request() {
303 int r
= store
->get_raw_obj_ref(obj
, &ref
);
305 lderr(store
->ctx()) << "ERROR: failed to get ref for (" << obj
<< ") ret=" << r
<< dendl
;
309 set_status() << "send request";
311 librados::ObjectWriteOperation op
;
312 op
.omap_rm_keys(keys
);
314 cn
= stack
->create_completion_notifier();
315 return ref
.ioctx
.aio_operate(ref
.oid
, cn
->completion(), &op
);
318 RGWRadosRemoveCR::RGWRadosRemoveCR(RGWRados
*store
, const rgw_raw_obj
& obj
)
319 : RGWSimpleCoroutine(store
->ctx()), store(store
), obj(obj
)
321 set_description() << "remove dest=" << obj
;
324 int RGWRadosRemoveCR::send_request()
326 auto rados
= store
->get_rados_handle();
327 int r
= rados
->ioctx_create(obj
.pool
.name
.c_str(), ioctx
);
329 lderr(cct
) << "ERROR: failed to open pool (" << obj
.pool
.name
<< ") ret=" << r
<< dendl
;
332 ioctx
.locator_set_key(obj
.loc
);
334 set_status() << "send request";
336 librados::ObjectWriteOperation op
;
339 cn
= stack
->create_completion_notifier();
340 return ioctx
.aio_operate(obj
.oid
, cn
->completion(), &op
);
343 int RGWRadosRemoveCR::request_complete()
345 int r
= cn
->completion()->get_return_value();
347 set_status() << "request complete; ret=" << r
;
352 RGWSimpleRadosLockCR::RGWSimpleRadosLockCR(RGWAsyncRadosProcessor
*_async_rados
, RGWRados
*_store
,
353 const rgw_raw_obj
& _obj
,
354 const string
& _lock_name
,
355 const string
& _cookie
,
356 uint32_t _duration
) : RGWSimpleCoroutine(_store
->ctx()),
357 async_rados(_async_rados
),
359 lock_name(_lock_name
),
365 set_description() << "rados lock dest=" << obj
<< " lock=" << lock_name
<< " cookie=" << cookie
<< " duration=" << duration
;
368 void RGWSimpleRadosLockCR::request_cleanup()
376 int RGWSimpleRadosLockCR::send_request()
378 set_status() << "sending request";
379 req
= new RGWAsyncLockSystemObj(this, stack
->create_completion_notifier(),
380 store
, NULL
, obj
, lock_name
, cookie
, duration
);
381 async_rados
->queue(req
);
385 int RGWSimpleRadosLockCR::request_complete()
387 set_status() << "request complete; ret=" << req
->get_ret_status();
388 return req
->get_ret_status();
391 RGWSimpleRadosUnlockCR::RGWSimpleRadosUnlockCR(RGWAsyncRadosProcessor
*_async_rados
, RGWRados
*_store
,
392 const rgw_raw_obj
& _obj
,
393 const string
& _lock_name
,
394 const string
& _cookie
) : RGWSimpleCoroutine(_store
->ctx()),
395 async_rados(_async_rados
),
397 lock_name(_lock_name
),
402 set_description() << "rados unlock dest=" << obj
<< " lock=" << lock_name
<< " cookie=" << cookie
;
405 void RGWSimpleRadosUnlockCR::request_cleanup()
413 int RGWSimpleRadosUnlockCR::send_request()
415 set_status() << "sending request";
417 req
= new RGWAsyncUnlockSystemObj(this, stack
->create_completion_notifier(),
418 store
, NULL
, obj
, lock_name
, cookie
);
419 async_rados
->queue(req
);
423 int RGWSimpleRadosUnlockCR::request_complete()
425 set_status() << "request complete; ret=" << req
->get_ret_status();
426 return req
->get_ret_status();
430 int RGWOmapAppend::operate() {
433 if (!has_product() && going_down
) {
434 set_status() << "going down";
437 set_status() << "waiting for product";
438 yield
wait_for_product();
441 while (consume(&entry
)) {
442 set_status() << "adding entry: " << entry
;
443 entries
[entry
] = bufferlist();
444 if (entries
.size() >= window_size
) {
448 if (entries
.size() >= window_size
|| going_down
) {
449 set_status() << "flushing to omap";
450 call(new RGWRadosSetOmapKeysCR(store
, obj
, entries
));
454 if (get_ret_status() < 0) {
455 ldout(cct
, 0) << "ERROR: failed to store entries in omap" << dendl
;
456 return set_state(RGWCoroutine_Error
);
459 /* done with coroutine */
460 return set_state(RGWCoroutine_Done
);
465 void RGWOmapAppend::flush_pending() {
466 receive(pending_entries
);
467 num_pending_entries
= 0;
470 bool RGWOmapAppend::append(const string
& s
) {
475 pending_entries
.push_back(s
);
476 if (++num_pending_entries
>= (int)window_size
) {
482 bool RGWOmapAppend::finish() {
489 int RGWAsyncGetBucketInstanceInfo::_send_request()
491 RGWObjectCtx
obj_ctx(store
);
492 int r
= store
->get_bucket_instance_info(obj_ctx
, bucket
, *bucket_info
, NULL
, NULL
);
494 ldout(store
->ctx(), 0) << "ERROR: failed to get bucket instance info for "
502 int RGWAsyncFetchRemoteObj::_send_request()
504 RGWObjectCtx
obj_ctx(store
);
508 snprintf(buf
, sizeof(buf
), ".%lld", (long long)store
->instance_id());
509 string client_id
= store
->zone_id() + buf
;
510 string op_id
= store
->unique_id(store
->get_new_req_id());
511 map
<string
, bufferlist
> attrs
;
513 rgw_obj
src_obj(bucket_info
.bucket
, key
);
515 rgw_obj
dest_obj(src_obj
);
517 int r
= store
->fetch_remote_obj(obj_ctx
,
521 false, /* don't record op state in ops log */
526 bucket_info
, /* dest */
527 bucket_info
, /* source */
528 NULL
, /* real_time* src_mtime, */
529 NULL
, /* real_time* mtime, */
530 NULL
, /* const real_time* mod_ptr, */
531 NULL
, /* const real_time* unmod_ptr, */
532 false, /* high precision time */
533 NULL
, /* const char *if_match, */
534 NULL
, /* const char *if_nomatch, */
535 RGWRados::ATTRSMOD_NONE
,
538 RGW_OBJ_CATEGORY_MAIN
,
540 real_time(), /* delete_at */
541 &key
.instance
, /* string *version_id, */
542 NULL
, /* string *ptag, */
543 NULL
, /* string *petag, */
544 NULL
, /* struct rgw_err *err, */
545 NULL
, /* void (*progress_cb)(off_t, void *), */
546 NULL
); /* void *progress_data*); */
549 ldout(store
->ctx(), 0) << "store->fetch_remote_obj() returned r=" << r
<< dendl
;
554 int RGWAsyncStatRemoteObj::_send_request()
556 RGWObjectCtx
obj_ctx(store
);
560 snprintf(buf
, sizeof(buf
), ".%lld", (long long)store
->instance_id());
561 string client_id
= store
->zone_id() + buf
;
562 string op_id
= store
->unique_id(store
->get_new_req_id());
564 rgw_obj
src_obj(bucket_info
.bucket
, key
);
566 rgw_obj
dest_obj(src_obj
);
568 int r
= store
->stat_remote_obj(obj_ctx
,
571 nullptr, /* req_info */
574 bucket_info
, /* source */
575 pmtime
, /* real_time* src_mtime, */
576 psize
, /* uint64_t * */
577 nullptr, /* const real_time* mod_ptr, */
578 nullptr, /* const real_time* unmod_ptr, */
579 true, /* high precision time */
580 nullptr, /* const char *if_match, */
581 nullptr, /* const char *if_nomatch, */
584 nullptr, /* string *ptag, */
585 nullptr); /* string *petag, */
588 ldout(store
->ctx(), 0) << "store->fetch_remote_obj() returned r=" << r
<< dendl
;
594 int RGWAsyncRemoveObj::_send_request()
596 RGWObjectCtx
obj_ctx(store
);
598 rgw_obj
obj(bucket_info
.bucket
, key
);
600 ldout(store
->ctx(), 0) << __func__
<< "(): deleting obj=" << obj
<< dendl
;
602 obj_ctx
.obj
.set_atomic(obj
);
606 int ret
= store
->get_obj_state(&obj_ctx
, bucket_info
, obj
, &state
);
608 ldout(store
->ctx(), 20) << __func__
<< "(): get_obj_state() obj=" << obj
<< " returned ret=" << ret
<< dendl
;
612 /* has there been any racing object write? */
613 if (del_if_older
&& (state
->mtime
> timestamp
)) {
614 ldout(store
->ctx(), 20) << __func__
<< "(): skipping object removal obj=" << obj
<< " (obj mtime=" << state
->mtime
<< ", request timestamp=" << timestamp
<< ")" << dendl
;
618 RGWAccessControlPolicy policy
;
621 map
<string
, bufferlist
>::iterator iter
= state
->attrset
.find(RGW_ATTR_ACL
);
622 if (iter
!= state
->attrset
.end()) {
623 bufferlist::iterator bliter
= iter
->second
.begin();
625 policy
.decode(bliter
);
626 } catch (buffer::error
& err
) {
627 ldout(store
->ctx(), 0) << "ERROR: could not decode policy, caught buffer::error" << dendl
;
632 RGWRados::Object
del_target(store
, bucket_info
, obj_ctx
, obj
);
633 RGWRados::Object::Delete
del_op(&del_target
);
635 del_op
.params
.bucket_owner
= bucket_info
.owner
;
636 del_op
.params
.obj_owner
= policy
.get_owner();
638 del_op
.params
.unmod_since
= timestamp
;
641 del_op
.params
.versioning_status
= BUCKET_VERSIONED
;
643 del_op
.params
.olh_epoch
= versioned_epoch
;
644 del_op
.params
.marker_version_id
= marker_version_id
;
645 del_op
.params
.obj_owner
.set_id(owner
);
646 del_op
.params
.obj_owner
.set_name(owner_display_name
);
647 del_op
.params
.mtime
= timestamp
;
648 del_op
.params
.high_precision_time
= true;
650 ret
= del_op
.delete_obj();
652 ldout(store
->ctx(), 20) << __func__
<< "(): delete_obj() obj=" << obj
<< " returned ret=" << ret
<< dendl
;
657 int RGWContinuousLeaseCR::operate()
660 caller
->set_sleeping(false);
661 return set_cr_done();
664 while (!going_down
) {
665 yield
call(new RGWSimpleRadosLockCR(async_rados
, store
, obj
, lock_name
, cookie
, interval
));
667 caller
->set_sleeping(false); /* will only be relevant when we return, that's why we can do it early */
670 ldout(store
->ctx(), 20) << *this << ": couldn't lock " << obj
<< ":" << lock_name
<< ": retcode=" << retcode
<< dendl
;
671 return set_state(RGWCoroutine_Error
, retcode
);
674 yield
wait(utime_t(interval
/ 2, 0));
676 set_locked(false); /* moot at this point anyway */
677 yield
call(new RGWSimpleRadosUnlockCR(async_rados
, store
, obj
, lock_name
, cookie
));
678 return set_state(RGWCoroutine_Done
);
683 RGWRadosTimelogAddCR::RGWRadosTimelogAddCR(RGWRados
*_store
, const string
& _oid
,
684 const cls_log_entry
& entry
) : RGWSimpleCoroutine(_store
->ctx()),
688 stringstream
& s
= set_description();
689 s
<< "timelog add entry oid=" << oid
<< "entry={id=" << entry
.id
<< ", section=" << entry
.section
<< ", name=" << entry
.name
<< "}";
690 entries
.push_back(entry
);
693 RGWRadosTimelogAddCR::~RGWRadosTimelogAddCR()
700 int RGWRadosTimelogAddCR::send_request()
702 set_status() << "sending request";
704 cn
= stack
->create_completion_notifier();
706 return store
->time_log_add(oid
, entries
, cn
->completion(), true);
709 int RGWRadosTimelogAddCR::request_complete()
711 int r
= cn
->completion()->get_return_value();
713 set_status() << "request complete; ret=" << r
;
718 RGWRadosTimelogTrimCR::RGWRadosTimelogTrimCR(RGWRados
*store
,
719 const std::string
& oid
,
720 const real_time
& start_time
,
721 const real_time
& end_time
,
722 const std::string
& from_marker
,
723 const std::string
& to_marker
)
724 : RGWSimpleCoroutine(store
->ctx()), store(store
), oid(oid
),
725 start_time(start_time
), end_time(end_time
),
726 from_marker(from_marker
), to_marker(to_marker
)
728 set_description() << "timelog trim oid=" << oid
729 << " start_time=" << start_time
<< " end_time=" << end_time
730 << " from_marker=" << from_marker
<< " to_marker=" << to_marker
;
733 RGWRadosTimelogTrimCR::~RGWRadosTimelogTrimCR()
740 int RGWRadosTimelogTrimCR::send_request()
742 set_status() << "sending request";
744 cn
= stack
->create_completion_notifier();
746 return store
->time_log_trim(oid
, start_time
, end_time
, from_marker
,
747 to_marker
, cn
->completion());
750 int RGWRadosTimelogTrimCR::request_complete()
752 int r
= cn
->completion()->get_return_value();
754 set_status() << "request complete; ret=" << r
;
760 RGWSyncLogTrimCR::RGWSyncLogTrimCR(RGWRados
*store
, const std::string
& oid
,
761 const std::string
& to_marker
,
762 std::string
*last_trim_marker
)
763 : RGWRadosTimelogTrimCR(store
, oid
, real_time
{}, real_time
{},
764 std::string
{}, to_marker
),
765 cct(store
->ctx()), last_trim_marker(last_trim_marker
)
769 int RGWSyncLogTrimCR::request_complete()
771 int r
= RGWRadosTimelogTrimCR::request_complete();
772 if (r
< 0 && r
!= -ENODATA
) {
775 if (*last_trim_marker
< to_marker
) {
776 *last_trim_marker
= to_marker
;
782 int RGWAsyncStatObj::_send_request()
785 store
->obj_to_raw(bucket_info
.placement_rule
, obj
, &raw_obj
);
786 return store
->raw_obj_stat(raw_obj
, psize
, pmtime
, pepoch
,
787 nullptr, nullptr, objv_tracker
);
790 RGWStatObjCR::RGWStatObjCR(RGWAsyncRadosProcessor
*async_rados
, RGWRados
*store
,
791 const RGWBucketInfo
& _bucket_info
, const rgw_obj
& obj
, uint64_t *psize
,
792 real_time
* pmtime
, uint64_t *pepoch
,
793 RGWObjVersionTracker
*objv_tracker
)
794 : RGWSimpleCoroutine(store
->ctx()), store(store
), async_rados(async_rados
),
795 bucket_info(_bucket_info
), obj(obj
), psize(psize
), pmtime(pmtime
), pepoch(pepoch
),
796 objv_tracker(objv_tracker
)
800 void RGWStatObjCR::request_cleanup()
808 int RGWStatObjCR::send_request()
810 req
= new RGWAsyncStatObj(this, stack
->create_completion_notifier(),
811 store
, bucket_info
, obj
, psize
, pmtime
, pepoch
, objv_tracker
);
812 async_rados
->queue(req
);
816 int RGWStatObjCR::request_complete()
818 return req
->get_ret_status();