]> git.proxmox.com Git - ceph.git/blob - ceph/src/rgw/rgw_cr_rados.h
import 15.2.0 Octopus source
[ceph.git] / ceph / src / rgw / rgw_cr_rados.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab ft=cpp
3
4 #ifndef CEPH_RGW_CR_RADOS_H
5 #define CEPH_RGW_CR_RADOS_H
6
7 #include <boost/intrusive_ptr.hpp>
8 #include "include/ceph_assert.h"
9 #include "rgw_coroutine.h"
10 #include "rgw_sal.h"
11 #include "common/WorkQueue.h"
12 #include "common/Throttle.h"
13
14 #include <atomic>
15
16 #include "services/svc_sys_obj.h"
17 #include "services/svc_bucket.h"
18
19 class RGWAsyncRadosRequest : public RefCountedObject {
20 RGWCoroutine *caller;
21 RGWAioCompletionNotifier *notifier;
22
23 int retcode;
24
25 ceph::mutex lock = ceph::make_mutex("RGWAsyncRadosRequest::lock");
26
27 protected:
28 virtual int _send_request() = 0;
29 public:
30 RGWAsyncRadosRequest(RGWCoroutine *_caller, RGWAioCompletionNotifier *_cn)
31 : caller(_caller), notifier(_cn), retcode(0) {
32 }
33 ~RGWAsyncRadosRequest() override {
34 if (notifier) {
35 notifier->put();
36 }
37 }
38
39 void send_request() {
40 get();
41 retcode = _send_request();
42 {
43 std::lock_guard l{lock};
44 if (notifier) {
45 notifier->cb(); // drops its own ref
46 notifier = nullptr;
47 }
48 }
49 put();
50 }
51
52 int get_ret_status() { return retcode; }
53
54 void finish() {
55 {
56 std::lock_guard l{lock};
57 if (notifier) {
58 // we won't call notifier->cb() to drop its ref, so drop it here
59 notifier->put();
60 notifier = nullptr;
61 }
62 }
63 put();
64 }
65 };
66
67
68 class RGWAsyncRadosProcessor {
69 deque<RGWAsyncRadosRequest *> m_req_queue;
70 std::atomic<bool> going_down = { false };
71 protected:
72 CephContext *cct;
73 ThreadPool m_tp;
74 Throttle req_throttle;
75
76 struct RGWWQ : public ThreadPool::WorkQueue<RGWAsyncRadosRequest> {
77 RGWAsyncRadosProcessor *processor;
78 RGWWQ(RGWAsyncRadosProcessor *p, time_t timeout, time_t suicide_timeout, ThreadPool *tp)
79 : ThreadPool::WorkQueue<RGWAsyncRadosRequest>("RGWWQ", timeout, suicide_timeout, tp), processor(p) {}
80
81 bool _enqueue(RGWAsyncRadosRequest *req) override;
82 void _dequeue(RGWAsyncRadosRequest *req) override {
83 ceph_abort();
84 }
85 bool _empty() override;
86 RGWAsyncRadosRequest *_dequeue() override;
87 using ThreadPool::WorkQueue<RGWAsyncRadosRequest>::_process;
88 void _process(RGWAsyncRadosRequest *req, ThreadPool::TPHandle& handle) override;
89 void _dump_queue();
90 void _clear() override {
91 ceph_assert(processor->m_req_queue.empty());
92 }
93 } req_wq;
94
95 public:
96 RGWAsyncRadosProcessor(CephContext *_cct, int num_threads);
97 ~RGWAsyncRadosProcessor() {}
98 void start();
99 void stop();
100 void handle_request(RGWAsyncRadosRequest *req);
101 void queue(RGWAsyncRadosRequest *req);
102
103 bool is_going_down() {
104 return going_down;
105 }
106 };
107
108 template <class P>
109 class RGWSimpleWriteOnlyAsyncCR : public RGWSimpleCoroutine {
110 RGWAsyncRadosProcessor *async_rados;
111 rgw::sal::RGWRadosStore *store;
112
113 P params;
114 const DoutPrefixProvider *dpp;
115
116 class Request : public RGWAsyncRadosRequest {
117 rgw::sal::RGWRadosStore *store;
118 P params;
119 const DoutPrefixProvider *dpp;
120 protected:
121 int _send_request() override;
122 public:
123 Request(RGWCoroutine *caller,
124 RGWAioCompletionNotifier *cn,
125 rgw::sal::RGWRadosStore *store,
126 const P& _params,
127 const DoutPrefixProvider *dpp) : RGWAsyncRadosRequest(caller, cn),
128 store(store),
129 params(_params),
130 dpp(dpp) {}
131 } *req{nullptr};
132
133 public:
134 RGWSimpleWriteOnlyAsyncCR(RGWAsyncRadosProcessor *_async_rados,
135 rgw::sal::RGWRadosStore *_store,
136 const P& _params,
137 const DoutPrefixProvider *_dpp) : RGWSimpleCoroutine(_store->ctx()),
138 async_rados(_async_rados),
139 store(_store),
140 params(_params),
141 dpp(_dpp) {}
142
143 ~RGWSimpleWriteOnlyAsyncCR() override {
144 request_cleanup();
145 }
146 void request_cleanup() override {
147 if (req) {
148 req->finish();
149 req = NULL;
150 }
151 }
152
153 int send_request() override {
154 req = new Request(this,
155 stack->create_completion_notifier(),
156 store,
157 params,
158 dpp);
159
160 async_rados->queue(req);
161 return 0;
162 }
163 int request_complete() override {
164 return req->get_ret_status();
165 }
166 };
167
168
169 template <class P, class R>
170 class RGWSimpleAsyncCR : public RGWSimpleCoroutine {
171 RGWAsyncRadosProcessor *async_rados;
172 rgw::sal::RGWRadosStore *store;
173
174 P params;
175 std::shared_ptr<R> result;
176
177 class Request : public RGWAsyncRadosRequest {
178 rgw::sal::RGWRadosStore *store;
179 P params;
180 std::shared_ptr<R> result;
181 protected:
182 int _send_request() override;
183 public:
184 Request(RGWCoroutine *caller,
185 RGWAioCompletionNotifier *cn,
186 rgw::sal::RGWRadosStore *_store,
187 const P& _params,
188 std::shared_ptr<R>& _result) : RGWAsyncRadosRequest(caller, cn),
189 store(_store),
190 params(_params),
191 result(_result) {}
192 } *req{nullptr};
193
194 public:
195 RGWSimpleAsyncCR(RGWAsyncRadosProcessor *_async_rados,
196 rgw::sal::RGWRadosStore *_store,
197 const P& _params,
198 std::shared_ptr<R>& _result) : RGWSimpleCoroutine(_store->ctx()),
199 async_rados(_async_rados),
200 store(_store),
201 params(_params),
202 result(_result) {}
203
204 ~RGWSimpleAsyncCR() override {
205 request_cleanup();
206 }
207 void request_cleanup() override {
208 if (req) {
209 req->finish();
210 req = NULL;
211 }
212 }
213
214 int send_request() override {
215 req = new Request(this,
216 stack->create_completion_notifier(),
217 store,
218 params,
219 result);
220
221 async_rados->queue(req);
222 return 0;
223 }
224 int request_complete() override {
225 return req->get_ret_status();
226 }
227 };
228
229 class RGWGenericAsyncCR : public RGWSimpleCoroutine {
230 RGWAsyncRadosProcessor *async_rados;
231 rgw::sal::RGWRadosStore *store;
232
233
234 public:
235 class Action {
236 public:
237 virtual ~Action() {}
238 virtual int operate() = 0;
239 };
240
241 private:
242 std::shared_ptr<Action> action;
243
244 class Request : public RGWAsyncRadosRequest {
245 std::shared_ptr<Action> action;
246 protected:
247 int _send_request() override {
248 if (!action) {
249 return 0;
250 }
251 return action->operate();
252 }
253 public:
254 Request(RGWCoroutine *caller,
255 RGWAioCompletionNotifier *cn,
256 std::shared_ptr<Action>& _action) : RGWAsyncRadosRequest(caller, cn),
257 action(_action) {}
258 } *req{nullptr};
259
260 public:
261 RGWGenericAsyncCR(CephContext *_cct,
262 RGWAsyncRadosProcessor *_async_rados,
263 std::shared_ptr<Action>& _action) : RGWSimpleCoroutine(_cct),
264 async_rados(_async_rados),
265 action(_action) {}
266 template<typename T>
267 RGWGenericAsyncCR(CephContext *_cct,
268 RGWAsyncRadosProcessor *_async_rados,
269 std::shared_ptr<T>& _action) : RGWSimpleCoroutine(_cct),
270 async_rados(_async_rados),
271 action(std::static_pointer_cast<Action>(_action)) {}
272
273 ~RGWGenericAsyncCR() override {
274 request_cleanup();
275 }
276 void request_cleanup() override {
277 if (req) {
278 req->finish();
279 req = NULL;
280 }
281 }
282
283 int send_request() override {
284 req = new Request(this,
285 stack->create_completion_notifier(),
286 action);
287
288 async_rados->queue(req);
289 return 0;
290 }
291 int request_complete() override {
292 return req->get_ret_status();
293 }
294 };
295
296
297 class RGWAsyncGetSystemObj : public RGWAsyncRadosRequest {
298 RGWSysObjectCtx obj_ctx;
299 RGWObjVersionTracker objv_tracker;
300 rgw_raw_obj obj;
301 const bool want_attrs;
302 const bool raw_attrs;
303 protected:
304 int _send_request() override;
305 public:
306 RGWAsyncGetSystemObj(RGWCoroutine *caller, RGWAioCompletionNotifier *cn, RGWSI_SysObj *_svc,
307 RGWObjVersionTracker *_objv_tracker, const rgw_raw_obj& _obj,
308 bool want_attrs, bool raw_attrs);
309
310 bufferlist bl;
311 map<string, bufferlist> attrs;
312 };
313
314 class RGWAsyncPutSystemObj : public RGWAsyncRadosRequest {
315 RGWSI_SysObj *svc;
316 rgw_raw_obj obj;
317 bool exclusive;
318 bufferlist bl;
319
320 protected:
321 int _send_request() override;
322 public:
323 RGWAsyncPutSystemObj(RGWCoroutine *caller, RGWAioCompletionNotifier *cn, RGWSI_SysObj *_svc,
324 RGWObjVersionTracker *_objv_tracker, const rgw_raw_obj& _obj,
325 bool _exclusive, bufferlist _bl);
326
327 RGWObjVersionTracker objv_tracker;
328 };
329
330 class RGWAsyncPutSystemObjAttrs : public RGWAsyncRadosRequest {
331 RGWSI_SysObj *svc;
332 rgw_raw_obj obj;
333 map<string, bufferlist> attrs;
334
335 protected:
336 int _send_request() override;
337 public:
338 RGWAsyncPutSystemObjAttrs(RGWCoroutine *caller, RGWAioCompletionNotifier *cn, RGWSI_SysObj *_svc,
339 RGWObjVersionTracker *_objv_tracker, const rgw_raw_obj& _obj,
340 map<string, bufferlist> _attrs);
341
342 RGWObjVersionTracker objv_tracker;
343 };
344
345 class RGWAsyncLockSystemObj : public RGWAsyncRadosRequest {
346 rgw::sal::RGWRadosStore *store;
347 rgw_raw_obj obj;
348 string lock_name;
349 string cookie;
350 uint32_t duration_secs;
351
352 protected:
353 int _send_request() override;
354 public:
355 RGWAsyncLockSystemObj(RGWCoroutine *caller, RGWAioCompletionNotifier *cn, rgw::sal::RGWRadosStore *_store,
356 RGWObjVersionTracker *_objv_tracker, const rgw_raw_obj& _obj,
357 const string& _name, const string& _cookie, uint32_t _duration_secs);
358 };
359
360 class RGWAsyncUnlockSystemObj : public RGWAsyncRadosRequest {
361 rgw::sal::RGWRadosStore *store;
362 rgw_raw_obj obj;
363 string lock_name;
364 string cookie;
365
366 protected:
367 int _send_request() override;
368 public:
369 RGWAsyncUnlockSystemObj(RGWCoroutine *caller, RGWAioCompletionNotifier *cn, rgw::sal::RGWRadosStore *_store,
370 RGWObjVersionTracker *_objv_tracker, const rgw_raw_obj& _obj,
371 const string& _name, const string& _cookie);
372 };
373
374 template <class T>
375 class RGWSimpleRadosReadCR : public RGWSimpleCoroutine {
376 RGWAsyncRadosProcessor *async_rados;
377 RGWSI_SysObj *svc;
378
379 rgw_raw_obj obj;
380 T *result;
381 /// on ENOENT, call handle_data() with an empty object instead of failing
382 const bool empty_on_enoent;
383 RGWObjVersionTracker *objv_tracker;
384 RGWAsyncGetSystemObj *req{nullptr};
385
386 public:
387 RGWSimpleRadosReadCR(RGWAsyncRadosProcessor *_async_rados, RGWSI_SysObj *_svc,
388 const rgw_raw_obj& _obj,
389 T *_result, bool empty_on_enoent = true,
390 RGWObjVersionTracker *objv_tracker = nullptr)
391 : RGWSimpleCoroutine(_svc->ctx()), async_rados(_async_rados), svc(_svc),
392 obj(_obj), result(_result),
393 empty_on_enoent(empty_on_enoent), objv_tracker(objv_tracker) {}
394 ~RGWSimpleRadosReadCR() override {
395 request_cleanup();
396 }
397
398 void request_cleanup() override {
399 if (req) {
400 req->finish();
401 req = NULL;
402 }
403 }
404
405 int send_request() override;
406 int request_complete() override;
407
408 virtual int handle_data(T& data) {
409 return 0;
410 }
411 };
412
413 template <class T>
414 int RGWSimpleRadosReadCR<T>::send_request()
415 {
416 req = new RGWAsyncGetSystemObj(this, stack->create_completion_notifier(), svc,
417 objv_tracker, obj, false, false);
418 async_rados->queue(req);
419 return 0;
420 }
421
422 template <class T>
423 int RGWSimpleRadosReadCR<T>::request_complete()
424 {
425 int ret = req->get_ret_status();
426 retcode = ret;
427 if (ret == -ENOENT && empty_on_enoent) {
428 *result = T();
429 } else {
430 if (ret < 0) {
431 return ret;
432 }
433 try {
434 auto iter = req->bl.cbegin();
435 if (iter.end()) {
436 // allow successful reads with empty buffers. ReadSyncStatus coroutines
437 // depend on this to be able to read without locking, because the
438 // cls lock from InitSyncStatus will create an empty object if it didn't
439 // exist
440 *result = T();
441 } else {
442 decode(*result, iter);
443 }
444 } catch (buffer::error& err) {
445 return -EIO;
446 }
447 }
448
449 return handle_data(*result);
450 }
451
452 class RGWSimpleRadosReadAttrsCR : public RGWSimpleCoroutine {
453 RGWAsyncRadosProcessor *async_rados;
454 RGWSI_SysObj *svc;
455
456 rgw_raw_obj obj;
457 map<string, bufferlist> *pattrs;
458 bool raw_attrs;
459 RGWAsyncGetSystemObj *req;
460
461 public:
462 RGWSimpleRadosReadAttrsCR(RGWAsyncRadosProcessor *_async_rados, RGWSI_SysObj *_svc,
463 const rgw_raw_obj& _obj,
464 map<string, bufferlist> *_pattrs, bool _raw_attrs) : RGWSimpleCoroutine(_svc->ctx()),
465 async_rados(_async_rados), svc(_svc),
466 obj(_obj),
467 pattrs(_pattrs),
468 raw_attrs(_raw_attrs),
469 req(NULL) {}
470 ~RGWSimpleRadosReadAttrsCR() override {
471 request_cleanup();
472 }
473
474 void request_cleanup() override {
475 if (req) {
476 req->finish();
477 req = NULL;
478 }
479 }
480
481 int send_request() override;
482 int request_complete() override;
483 };
484
485 template <class T>
486 class RGWSimpleRadosWriteCR : public RGWSimpleCoroutine {
487 RGWAsyncRadosProcessor *async_rados;
488 RGWSI_SysObj *svc;
489 bufferlist bl;
490 rgw_raw_obj obj;
491 RGWObjVersionTracker *objv_tracker;
492 RGWAsyncPutSystemObj *req{nullptr};
493
494 public:
495 RGWSimpleRadosWriteCR(RGWAsyncRadosProcessor *_async_rados, RGWSI_SysObj *_svc,
496 const rgw_raw_obj& _obj,
497 const T& _data, RGWObjVersionTracker *objv_tracker = nullptr)
498 : RGWSimpleCoroutine(_svc->ctx()), async_rados(_async_rados),
499 svc(_svc), obj(_obj), objv_tracker(objv_tracker) {
500 encode(_data, bl);
501 }
502
503 ~RGWSimpleRadosWriteCR() override {
504 request_cleanup();
505 }
506
507 void request_cleanup() override {
508 if (req) {
509 req->finish();
510 req = NULL;
511 }
512 }
513
514 int send_request() override {
515 req = new RGWAsyncPutSystemObj(this, stack->create_completion_notifier(),
516 svc, objv_tracker, obj, false, std::move(bl));
517 async_rados->queue(req);
518 return 0;
519 }
520
521 int request_complete() override {
522 if (objv_tracker) { // copy the updated version
523 *objv_tracker = req->objv_tracker;
524 }
525 return req->get_ret_status();
526 }
527 };
528
529 class RGWSimpleRadosWriteAttrsCR : public RGWSimpleCoroutine {
530 RGWAsyncRadosProcessor *async_rados;
531 RGWSI_SysObj *svc;
532 RGWObjVersionTracker *objv_tracker;
533
534 rgw_raw_obj obj;
535 map<string, bufferlist> attrs;
536 RGWAsyncPutSystemObjAttrs *req = nullptr;
537
538 public:
539 RGWSimpleRadosWriteAttrsCR(RGWAsyncRadosProcessor *_async_rados,
540 RGWSI_SysObj *_svc, const rgw_raw_obj& _obj,
541 map<string, bufferlist> _attrs,
542 RGWObjVersionTracker *objv_tracker = nullptr)
543 : RGWSimpleCoroutine(_svc->ctx()), async_rados(_async_rados),
544 svc(_svc), objv_tracker(objv_tracker), obj(_obj),
545 attrs(std::move(_attrs)) {
546 }
547 ~RGWSimpleRadosWriteAttrsCR() override {
548 request_cleanup();
549 }
550
551 void request_cleanup() override {
552 if (req) {
553 req->finish();
554 req = NULL;
555 }
556 }
557
558 int send_request() override {
559 req = new RGWAsyncPutSystemObjAttrs(this, stack->create_completion_notifier(),
560 svc, objv_tracker, obj, std::move(attrs));
561 async_rados->queue(req);
562 return 0;
563 }
564
565 int request_complete() override {
566 if (objv_tracker) { // copy the updated version
567 *objv_tracker = req->objv_tracker;
568 }
569 return req->get_ret_status();
570 }
571 };
572
573 class RGWRadosSetOmapKeysCR : public RGWSimpleCoroutine {
574 rgw::sal::RGWRadosStore *store;
575 map<string, bufferlist> entries;
576
577 rgw_rados_ref ref;
578
579 rgw_raw_obj obj;
580
581 boost::intrusive_ptr<RGWAioCompletionNotifier> cn;
582
583 public:
584 RGWRadosSetOmapKeysCR(rgw::sal::RGWRadosStore *_store,
585 const rgw_raw_obj& _obj,
586 map<string, bufferlist>& _entries);
587
588 int send_request() override;
589 int request_complete() override;
590 };
591
592 class RGWRadosGetOmapKeysCR : public RGWSimpleCoroutine {
593 public:
594 struct Result {
595 rgw_rados_ref ref;
596 std::set<std::string> entries;
597 bool more = false;
598 };
599 using ResultPtr = std::shared_ptr<Result>;
600
601 RGWRadosGetOmapKeysCR(rgw::sal::RGWRadosStore *_store, const rgw_raw_obj& _obj,
602 const string& _marker, int _max_entries,
603 ResultPtr result);
604
605 int send_request() override;
606 int request_complete() override;
607
608 private:
609 rgw::sal::RGWRadosStore *store;
610 rgw_raw_obj obj;
611 string marker;
612 int max_entries;
613 ResultPtr result;
614 boost::intrusive_ptr<RGWAioCompletionNotifier> cn;
615 };
616
617 class RGWRadosRemoveOmapKeysCR : public RGWSimpleCoroutine {
618 rgw::sal::RGWRadosStore *store;
619
620 rgw_rados_ref ref;
621
622 set<string> keys;
623
624 rgw_raw_obj obj;
625
626 boost::intrusive_ptr<RGWAioCompletionNotifier> cn;
627
628 public:
629 RGWRadosRemoveOmapKeysCR(rgw::sal::RGWRadosStore *_store,
630 const rgw_raw_obj& _obj,
631 const set<string>& _keys);
632
633 int send_request() override;
634
635 int request_complete() override;
636 };
637
638 class RGWRadosRemoveCR : public RGWSimpleCoroutine {
639 rgw::sal::RGWRadosStore *store;
640 librados::IoCtx ioctx;
641 const rgw_raw_obj obj;
642 boost::intrusive_ptr<RGWAioCompletionNotifier> cn;
643
644 public:
645 RGWRadosRemoveCR(rgw::sal::RGWRadosStore *store, const rgw_raw_obj& obj);
646
647 int send_request() override;
648 int request_complete() override;
649 };
650
651 class RGWSimpleRadosLockCR : public RGWSimpleCoroutine {
652 RGWAsyncRadosProcessor *async_rados;
653 rgw::sal::RGWRadosStore *store;
654 string lock_name;
655 string cookie;
656 uint32_t duration;
657
658 rgw_raw_obj obj;
659
660 RGWAsyncLockSystemObj *req;
661
662 public:
663 RGWSimpleRadosLockCR(RGWAsyncRadosProcessor *_async_rados, rgw::sal::RGWRadosStore *_store,
664 const rgw_raw_obj& _obj,
665 const string& _lock_name,
666 const string& _cookie,
667 uint32_t _duration);
668 ~RGWSimpleRadosLockCR() override {
669 request_cleanup();
670 }
671 void request_cleanup() override;
672
673 int send_request() override;
674 int request_complete() override;
675
676 static std::string gen_random_cookie(CephContext* cct) {
677 #define COOKIE_LEN 16
678 char buf[COOKIE_LEN + 1];
679 gen_rand_alphanumeric(cct, buf, sizeof(buf) - 1);
680 return buf;
681 }
682 };
683
684 class RGWSimpleRadosUnlockCR : public RGWSimpleCoroutine {
685 RGWAsyncRadosProcessor *async_rados;
686 rgw::sal::RGWRadosStore *store;
687 string lock_name;
688 string cookie;
689
690 rgw_raw_obj obj;
691
692 RGWAsyncUnlockSystemObj *req;
693
694 public:
695 RGWSimpleRadosUnlockCR(RGWAsyncRadosProcessor *_async_rados, rgw::sal::RGWRadosStore *_store,
696 const rgw_raw_obj& _obj,
697 const string& _lock_name,
698 const string& _cookie);
699 ~RGWSimpleRadosUnlockCR() override {
700 request_cleanup();
701 }
702 void request_cleanup() override;
703
704 int send_request() override;
705 int request_complete() override;
706 };
707
708 #define OMAP_APPEND_MAX_ENTRIES_DEFAULT 100
709
710 class RGWOmapAppend : public RGWConsumerCR<string> {
711 RGWAsyncRadosProcessor *async_rados;
712 rgw::sal::RGWRadosStore *store;
713
714 rgw_raw_obj obj;
715
716 bool going_down;
717
718 int num_pending_entries;
719 list<string> pending_entries;
720
721 map<string, bufferlist> entries;
722
723 uint64_t window_size;
724 uint64_t total_entries;
725 public:
726 RGWOmapAppend(RGWAsyncRadosProcessor *_async_rados, rgw::sal::RGWRadosStore *_store,
727 const rgw_raw_obj& _obj,
728 uint64_t _window_size = OMAP_APPEND_MAX_ENTRIES_DEFAULT);
729 int operate() override;
730 void flush_pending();
731 bool append(const string& s);
732 bool finish();
733
734 uint64_t get_total_entries() {
735 return total_entries;
736 }
737
738 const rgw_raw_obj& get_obj() {
739 return obj;
740 }
741 };
742
743 class RGWAsyncWait : public RGWAsyncRadosRequest {
744 CephContext *cct;
745 ceph::mutex *lock;
746 ceph::condition_variable *cond;
747 std::chrono::seconds interval;
748 protected:
749 int _send_request() override {
750 std::unique_lock l{*lock};
751 return (cond->wait_for(l, interval) == std::cv_status::timeout ?
752 ETIMEDOUT : 0);
753 }
754 public:
755 RGWAsyncWait(RGWCoroutine *caller, RGWAioCompletionNotifier *cn, CephContext *_cct,
756 ceph::mutex *_lock, ceph::condition_variable *_cond, int _secs)
757 : RGWAsyncRadosRequest(caller, cn),
758 cct(_cct),
759 lock(_lock), cond(_cond), interval(_secs) {}
760
761 void wakeup() {
762 std::lock_guard l{*lock};
763 cond->notify_all();
764 }
765 };
766
767 class RGWWaitCR : public RGWSimpleCoroutine {
768 CephContext *cct;
769 RGWAsyncRadosProcessor *async_rados;
770 ceph::mutex *lock;
771 ceph::condition_variable *cond;
772 int secs;
773
774 RGWAsyncWait *req;
775
776 public:
777 RGWWaitCR(RGWAsyncRadosProcessor *_async_rados, CephContext *_cct,
778 ceph::mutex *_lock, ceph::condition_variable *_cond,
779 int _secs) : RGWSimpleCoroutine(_cct), cct(_cct),
780 async_rados(_async_rados), lock(_lock), cond(_cond), secs(_secs), req(NULL) {
781 }
782 ~RGWWaitCR() override {
783 request_cleanup();
784 }
785
786 void request_cleanup() override {
787 if (req) {
788 wakeup();
789 req->finish();
790 req = NULL;
791 }
792 }
793
794 int send_request() override {
795 req = new RGWAsyncWait(this, stack->create_completion_notifier(), cct, lock, cond, secs);
796 async_rados->queue(req);
797 return 0;
798 }
799
800 int request_complete() override {
801 return req->get_ret_status();
802 }
803
804 void wakeup() {
805 req->wakeup();
806 }
807 };
808
809 class RGWShardedOmapCRManager {
810 RGWAsyncRadosProcessor *async_rados;
811 rgw::sal::RGWRadosStore *store;
812 RGWCoroutine *op;
813
814 int num_shards;
815
816 vector<RGWOmapAppend *> shards;
817 public:
818 RGWShardedOmapCRManager(RGWAsyncRadosProcessor *_async_rados, rgw::sal::RGWRadosStore *_store, RGWCoroutine *_op, int _num_shards, const rgw_pool& pool, const string& oid_prefix)
819 : async_rados(_async_rados),
820 store(_store), op(_op), num_shards(_num_shards) {
821 shards.reserve(num_shards);
822 for (int i = 0; i < num_shards; ++i) {
823 char buf[oid_prefix.size() + 16];
824 snprintf(buf, sizeof(buf), "%s.%d", oid_prefix.c_str(), i);
825 RGWOmapAppend *shard = new RGWOmapAppend(async_rados, store, rgw_raw_obj(pool, buf));
826 shard->get();
827 shards.push_back(shard);
828 op->spawn(shard, false);
829 }
830 }
831
832 ~RGWShardedOmapCRManager() {
833 for (auto shard : shards) {
834 shard->put();
835 }
836 }
837
838 bool append(const string& entry, int shard_id) {
839 return shards[shard_id]->append(entry);
840 }
841 bool finish() {
842 bool success = true;
843 for (vector<RGWOmapAppend *>::iterator iter = shards.begin(); iter != shards.end(); ++iter) {
844 success &= ((*iter)->finish() && (!(*iter)->is_error()));
845 }
846 return success;
847 }
848
849 uint64_t get_total_entries(int shard_id) {
850 return shards[shard_id]->get_total_entries();
851 }
852 };
853
854 class RGWAsyncGetBucketInstanceInfo : public RGWAsyncRadosRequest {
855 rgw::sal::RGWRadosStore *store;
856 rgw_bucket bucket;
857
858 protected:
859 int _send_request() override;
860 public:
861 RGWAsyncGetBucketInstanceInfo(RGWCoroutine *caller, RGWAioCompletionNotifier *cn,
862 rgw::sal::RGWRadosStore *_store, const rgw_bucket& bucket)
863 : RGWAsyncRadosRequest(caller, cn), store(_store), bucket(bucket) {}
864
865 RGWBucketInfo bucket_info;
866 map<string, bufferlist> attrs;
867 };
868
869 class RGWGetBucketInstanceInfoCR : public RGWSimpleCoroutine {
870 RGWAsyncRadosProcessor *async_rados;
871 rgw::sal::RGWRadosStore *store;
872 rgw_bucket bucket;
873 RGWBucketInfo *bucket_info;
874 map<string, bufferlist> *pattrs;
875
876 RGWAsyncGetBucketInstanceInfo *req{nullptr};
877
878 public:
879 // rgw_bucket constructor
880 RGWGetBucketInstanceInfoCR(RGWAsyncRadosProcessor *_async_rados, rgw::sal::RGWRadosStore *_store,
881 const rgw_bucket& _bucket, RGWBucketInfo *_bucket_info,
882 map<string, bufferlist> *_pattrs)
883 : RGWSimpleCoroutine(_store->ctx()), async_rados(_async_rados), store(_store),
884 bucket(_bucket), bucket_info(_bucket_info), pattrs(_pattrs) {}
885 ~RGWGetBucketInstanceInfoCR() override {
886 request_cleanup();
887 }
888 void request_cleanup() override {
889 if (req) {
890 req->finish();
891 req = NULL;
892 }
893 }
894
895 int send_request() override {
896 req = new RGWAsyncGetBucketInstanceInfo(this, stack->create_completion_notifier(), store, bucket);
897 async_rados->queue(req);
898 return 0;
899 }
900 int request_complete() override {
901 if (bucket_info) {
902 *bucket_info = std::move(req->bucket_info);
903 }
904 if (pattrs) {
905 *pattrs = std::move(req->attrs);
906 }
907 return req->get_ret_status();
908 }
909 };
910
911 class RGWRadosBILogTrimCR : public RGWSimpleCoroutine {
912 RGWRados::BucketShard bs;
913 std::string start_marker;
914 std::string end_marker;
915 boost::intrusive_ptr<RGWAioCompletionNotifier> cn;
916 public:
917 RGWRadosBILogTrimCR(rgw::sal::RGWRadosStore *store, const RGWBucketInfo& bucket_info,
918 int shard_id, const std::string& start_marker,
919 const std::string& end_marker);
920
921 int send_request() override;
922 int request_complete() override;
923 };
924
925 class RGWAsyncFetchRemoteObj : public RGWAsyncRadosRequest {
926 rgw::sal::RGWRadosStore *store;
927 rgw_zone_id source_zone;
928
929 std::optional<rgw_user> user_id;
930
931 rgw_bucket src_bucket;
932 std::optional<rgw_placement_rule> dest_placement_rule;
933 RGWBucketInfo dest_bucket_info;
934
935 rgw_obj_key key;
936 std::optional<rgw_obj_key> dest_key;
937 std::optional<uint64_t> versioned_epoch;
938
939 real_time src_mtime;
940
941 bool copy_if_newer;
942 std::shared_ptr<RGWFetchObjFilter> filter;
943 rgw_zone_set zones_trace;
944 PerfCounters* counters;
945 const DoutPrefixProvider *dpp;
946
947 protected:
948 int _send_request() override;
949 public:
950 RGWAsyncFetchRemoteObj(RGWCoroutine *caller, RGWAioCompletionNotifier *cn, rgw::sal::RGWRadosStore *_store,
951 const rgw_zone_id& _source_zone,
952 std::optional<rgw_user>& _user_id,
953 const rgw_bucket& _src_bucket,
954 std::optional<rgw_placement_rule> _dest_placement_rule,
955 const RGWBucketInfo& _dest_bucket_info,
956 const rgw_obj_key& _key,
957 const std::optional<rgw_obj_key>& _dest_key,
958 std::optional<uint64_t> _versioned_epoch,
959 bool _if_newer,
960 std::shared_ptr<RGWFetchObjFilter> _filter,
961 rgw_zone_set *_zones_trace,
962 PerfCounters* counters, const DoutPrefixProvider *dpp)
963 : RGWAsyncRadosRequest(caller, cn), store(_store),
964 source_zone(_source_zone),
965 user_id(_user_id),
966 src_bucket(_src_bucket),
967 dest_placement_rule(_dest_placement_rule),
968 dest_bucket_info(_dest_bucket_info),
969 key(_key),
970 dest_key(_dest_key),
971 versioned_epoch(_versioned_epoch),
972 copy_if_newer(_if_newer),
973 filter(_filter),
974 counters(counters),
975 dpp(dpp)
976 {
977 if (_zones_trace) {
978 zones_trace = *_zones_trace;
979 }
980 }
981 };
982
983 class RGWFetchRemoteObjCR : public RGWSimpleCoroutine {
984 CephContext *cct;
985 RGWAsyncRadosProcessor *async_rados;
986 rgw::sal::RGWRadosStore *store;
987 rgw_zone_id source_zone;
988
989 std::optional<rgw_user> user_id;
990
991 rgw_bucket src_bucket;
992 std::optional<rgw_placement_rule> dest_placement_rule;
993 RGWBucketInfo dest_bucket_info;
994
995 rgw_obj_key key;
996 std::optional<rgw_obj_key> dest_key;
997 std::optional<uint64_t> versioned_epoch;
998
999 real_time src_mtime;
1000
1001 bool copy_if_newer;
1002
1003 std::shared_ptr<RGWFetchObjFilter> filter;
1004
1005 RGWAsyncFetchRemoteObj *req;
1006 rgw_zone_set *zones_trace;
1007 PerfCounters* counters;
1008 const DoutPrefixProvider *dpp;
1009
1010 public:
1011 RGWFetchRemoteObjCR(RGWAsyncRadosProcessor *_async_rados, rgw::sal::RGWRadosStore *_store,
1012 const rgw_zone_id& _source_zone,
1013 std::optional<rgw_user> _user_id,
1014 const rgw_bucket& _src_bucket,
1015 std::optional<rgw_placement_rule> _dest_placement_rule,
1016 const RGWBucketInfo& _dest_bucket_info,
1017 const rgw_obj_key& _key,
1018 const std::optional<rgw_obj_key>& _dest_key,
1019 std::optional<uint64_t> _versioned_epoch,
1020 bool _if_newer,
1021 std::shared_ptr<RGWFetchObjFilter> _filter,
1022 rgw_zone_set *_zones_trace,
1023 PerfCounters* counters, const DoutPrefixProvider *dpp)
1024 : RGWSimpleCoroutine(_store->ctx()), cct(_store->ctx()),
1025 async_rados(_async_rados), store(_store),
1026 source_zone(_source_zone),
1027 user_id(_user_id),
1028 src_bucket(_src_bucket),
1029 dest_placement_rule(_dest_placement_rule),
1030 dest_bucket_info(_dest_bucket_info),
1031 key(_key),
1032 dest_key(_dest_key),
1033 versioned_epoch(_versioned_epoch),
1034 copy_if_newer(_if_newer),
1035 filter(_filter),
1036 req(NULL),
1037 zones_trace(_zones_trace), counters(counters), dpp(dpp) {}
1038
1039
1040 ~RGWFetchRemoteObjCR() override {
1041 request_cleanup();
1042 }
1043
1044 void request_cleanup() override {
1045 if (req) {
1046 req->finish();
1047 req = NULL;
1048 }
1049 }
1050
1051 int send_request() override {
1052 req = new RGWAsyncFetchRemoteObj(this, stack->create_completion_notifier(), store,
1053 source_zone, user_id, src_bucket, dest_placement_rule, dest_bucket_info,
1054 key, dest_key, versioned_epoch, copy_if_newer, filter,
1055 zones_trace, counters, dpp);
1056 async_rados->queue(req);
1057 return 0;
1058 }
1059
1060 int request_complete() override {
1061 return req->get_ret_status();
1062 }
1063 };
1064
1065 class RGWAsyncStatRemoteObj : public RGWAsyncRadosRequest {
1066 rgw::sal::RGWRadosStore *store;
1067 rgw_zone_id source_zone;
1068
1069 rgw_bucket src_bucket;
1070 rgw_obj_key key;
1071
1072 ceph::real_time *pmtime;
1073 uint64_t *psize;
1074 string *petag;
1075 map<string, bufferlist> *pattrs;
1076 map<string, string> *pheaders;
1077
1078 protected:
1079 int _send_request() override;
1080 public:
1081 RGWAsyncStatRemoteObj(RGWCoroutine *caller, RGWAioCompletionNotifier *cn, rgw::sal::RGWRadosStore *_store,
1082 const rgw_zone_id& _source_zone,
1083 rgw_bucket& _src_bucket,
1084 const rgw_obj_key& _key,
1085 ceph::real_time *_pmtime,
1086 uint64_t *_psize,
1087 string *_petag,
1088 map<string, bufferlist> *_pattrs,
1089 map<string, string> *_pheaders) : RGWAsyncRadosRequest(caller, cn), store(_store),
1090 source_zone(_source_zone),
1091 src_bucket(_src_bucket),
1092 key(_key),
1093 pmtime(_pmtime),
1094 psize(_psize),
1095 petag(_petag),
1096 pattrs(_pattrs),
1097 pheaders(_pheaders) {}
1098 };
1099
1100 class RGWStatRemoteObjCR : public RGWSimpleCoroutine {
1101 CephContext *cct;
1102 RGWAsyncRadosProcessor *async_rados;
1103 rgw::sal::RGWRadosStore *store;
1104 rgw_zone_id source_zone;
1105
1106 rgw_bucket src_bucket;
1107 rgw_obj_key key;
1108
1109 ceph::real_time *pmtime;
1110 uint64_t *psize;
1111 string *petag;
1112 map<string, bufferlist> *pattrs;
1113 map<string, string> *pheaders;
1114
1115 RGWAsyncStatRemoteObj *req;
1116
1117 public:
1118 RGWStatRemoteObjCR(RGWAsyncRadosProcessor *_async_rados, rgw::sal::RGWRadosStore *_store,
1119 const rgw_zone_id& _source_zone,
1120 rgw_bucket& _src_bucket,
1121 const rgw_obj_key& _key,
1122 ceph::real_time *_pmtime,
1123 uint64_t *_psize,
1124 string *_petag,
1125 map<string, bufferlist> *_pattrs,
1126 map<string, string> *_pheaders) : RGWSimpleCoroutine(_store->ctx()), cct(_store->ctx()),
1127 async_rados(_async_rados), store(_store),
1128 source_zone(_source_zone),
1129 src_bucket(_src_bucket),
1130 key(_key),
1131 pmtime(_pmtime),
1132 psize(_psize),
1133 petag(_petag),
1134 pattrs(_pattrs),
1135 pheaders(_pheaders),
1136 req(NULL) {}
1137
1138
1139 ~RGWStatRemoteObjCR() override {
1140 request_cleanup();
1141 }
1142
1143 void request_cleanup() override {
1144 if (req) {
1145 req->finish();
1146 req = NULL;
1147 }
1148 }
1149
1150 int send_request() override {
1151 req = new RGWAsyncStatRemoteObj(this, stack->create_completion_notifier(), store, source_zone,
1152 src_bucket, key, pmtime, psize, petag, pattrs, pheaders);
1153 async_rados->queue(req);
1154 return 0;
1155 }
1156
1157 int request_complete() override {
1158 return req->get_ret_status();
1159 }
1160 };
1161
1162 class RGWAsyncRemoveObj : public RGWAsyncRadosRequest {
1163 rgw::sal::RGWRadosStore *store;
1164 rgw_zone_id source_zone;
1165
1166 RGWBucketInfo bucket_info;
1167
1168 rgw_obj_key key;
1169 string owner;
1170 string owner_display_name;
1171 bool versioned;
1172 uint64_t versioned_epoch;
1173 string marker_version_id;
1174
1175 bool del_if_older;
1176 ceph::real_time timestamp;
1177 rgw_zone_set zones_trace;
1178
1179 protected:
1180 int _send_request() override;
1181 public:
1182 RGWAsyncRemoveObj(RGWCoroutine *caller, RGWAioCompletionNotifier *cn, rgw::sal::RGWRadosStore *_store,
1183 const rgw_zone_id& _source_zone,
1184 RGWBucketInfo& _bucket_info,
1185 const rgw_obj_key& _key,
1186 const string& _owner,
1187 const string& _owner_display_name,
1188 bool _versioned,
1189 uint64_t _versioned_epoch,
1190 bool _delete_marker,
1191 bool _if_older,
1192 real_time& _timestamp,
1193 rgw_zone_set* _zones_trace) : RGWAsyncRadosRequest(caller, cn), store(_store),
1194 source_zone(_source_zone),
1195 bucket_info(_bucket_info),
1196 key(_key),
1197 owner(_owner),
1198 owner_display_name(_owner_display_name),
1199 versioned(_versioned),
1200 versioned_epoch(_versioned_epoch),
1201 del_if_older(_if_older),
1202 timestamp(_timestamp) {
1203 if (_delete_marker) {
1204 marker_version_id = key.instance;
1205 }
1206
1207 if (_zones_trace) {
1208 zones_trace = *_zones_trace;
1209 }
1210 }
1211 };
1212
1213 class RGWRemoveObjCR : public RGWSimpleCoroutine {
1214 CephContext *cct;
1215 RGWAsyncRadosProcessor *async_rados;
1216 rgw::sal::RGWRadosStore *store;
1217 rgw_zone_id source_zone;
1218
1219 RGWBucketInfo bucket_info;
1220
1221 rgw_obj_key key;
1222 bool versioned;
1223 uint64_t versioned_epoch;
1224 bool delete_marker;
1225 string owner;
1226 string owner_display_name;
1227
1228 bool del_if_older;
1229 real_time timestamp;
1230
1231 RGWAsyncRemoveObj *req;
1232
1233 rgw_zone_set *zones_trace;
1234
1235 public:
1236 RGWRemoveObjCR(RGWAsyncRadosProcessor *_async_rados, rgw::sal::RGWRadosStore *_store,
1237 const rgw_zone_id& _source_zone,
1238 RGWBucketInfo& _bucket_info,
1239 const rgw_obj_key& _key,
1240 bool _versioned,
1241 uint64_t _versioned_epoch,
1242 string *_owner,
1243 string *_owner_display_name,
1244 bool _delete_marker,
1245 real_time *_timestamp,
1246 rgw_zone_set *_zones_trace) : RGWSimpleCoroutine(_store->ctx()), cct(_store->ctx()),
1247 async_rados(_async_rados), store(_store),
1248 source_zone(_source_zone),
1249 bucket_info(_bucket_info),
1250 key(_key),
1251 versioned(_versioned),
1252 versioned_epoch(_versioned_epoch),
1253 delete_marker(_delete_marker), req(NULL), zones_trace(_zones_trace) {
1254 del_if_older = (_timestamp != NULL);
1255 if (_timestamp) {
1256 timestamp = *_timestamp;
1257 }
1258
1259 if (_owner) {
1260 owner = *_owner;
1261 }
1262
1263 if (_owner_display_name) {
1264 owner_display_name = *_owner_display_name;
1265 }
1266 }
1267 ~RGWRemoveObjCR() override {
1268 request_cleanup();
1269 }
1270
1271 void request_cleanup() override {
1272 if (req) {
1273 req->finish();
1274 req = NULL;
1275 }
1276 }
1277
1278 int send_request() override {
1279 req = new RGWAsyncRemoveObj(this, stack->create_completion_notifier(), store, source_zone, bucket_info,
1280 key, owner, owner_display_name, versioned, versioned_epoch,
1281 delete_marker, del_if_older, timestamp, zones_trace);
1282 async_rados->queue(req);
1283 return 0;
1284 }
1285
1286 int request_complete() override {
1287 return req->get_ret_status();
1288 }
1289 };
1290
1291 class RGWContinuousLeaseCR : public RGWCoroutine {
1292 RGWAsyncRadosProcessor *async_rados;
1293 rgw::sal::RGWRadosStore *store;
1294
1295 const rgw_raw_obj obj;
1296
1297 const string lock_name;
1298 const string cookie;
1299
1300 int interval;
1301
1302 ceph::mutex lock = ceph::make_mutex("RGWContinuousLeaseCR");
1303 std::atomic<bool> going_down = { false };
1304 bool locked{false};
1305
1306 RGWCoroutine *caller;
1307
1308 bool aborted{false};
1309
1310 public:
1311 RGWContinuousLeaseCR(RGWAsyncRadosProcessor *_async_rados, rgw::sal::RGWRadosStore *_store,
1312 const rgw_raw_obj& _obj,
1313 const string& _lock_name, int _interval, RGWCoroutine *_caller)
1314 : RGWCoroutine(_store->ctx()), async_rados(_async_rados), store(_store),
1315 obj(_obj), lock_name(_lock_name),
1316 cookie(RGWSimpleRadosLockCR::gen_random_cookie(cct)),
1317 interval(_interval), caller(_caller)
1318 {}
1319
1320 int operate() override;
1321
1322 bool is_locked() {
1323 std::lock_guard l{lock};
1324 return locked;
1325 }
1326
1327 void set_locked(bool status) {
1328 std::lock_guard l{lock};
1329 locked = status;
1330 }
1331
1332 void go_down() {
1333 going_down = true;
1334 wakeup();
1335 }
1336
1337 void abort() {
1338 aborted = true;
1339 }
1340 };
1341
1342 class RGWRadosTimelogAddCR : public RGWSimpleCoroutine {
1343 rgw::sal::RGWRadosStore *store;
1344 list<cls_log_entry> entries;
1345
1346 string oid;
1347
1348 boost::intrusive_ptr<RGWAioCompletionNotifier> cn;
1349
1350 public:
1351 RGWRadosTimelogAddCR(rgw::sal::RGWRadosStore *_store, const string& _oid,
1352 const cls_log_entry& entry);
1353
1354 int send_request() override;
1355 int request_complete() override;
1356 };
1357
1358 class RGWRadosTimelogTrimCR : public RGWSimpleCoroutine {
1359 rgw::sal::RGWRadosStore *store;
1360 boost::intrusive_ptr<RGWAioCompletionNotifier> cn;
1361 protected:
1362 std::string oid;
1363 real_time start_time;
1364 real_time end_time;
1365 std::string from_marker;
1366 std::string to_marker;
1367
1368 public:
1369 RGWRadosTimelogTrimCR(rgw::sal::RGWRadosStore *store, const std::string& oid,
1370 const real_time& start_time, const real_time& end_time,
1371 const std::string& from_marker,
1372 const std::string& to_marker);
1373
1374 int send_request() override;
1375 int request_complete() override;
1376 };
1377
1378 // wrapper to update last_trim_marker on success
1379 class RGWSyncLogTrimCR : public RGWRadosTimelogTrimCR {
1380 CephContext *cct;
1381 std::string *last_trim_marker;
1382 public:
1383 // a marker that compares greater than any timestamp-based index
1384 static constexpr const char* max_marker = "99999999";
1385
1386 RGWSyncLogTrimCR(rgw::sal::RGWRadosStore *store, const std::string& oid,
1387 const std::string& to_marker, std::string *last_trim_marker);
1388 int request_complete() override;
1389 };
1390
1391 class RGWAsyncStatObj : public RGWAsyncRadosRequest {
1392 rgw::sal::RGWRadosStore *store;
1393 RGWBucketInfo bucket_info;
1394 rgw_obj obj;
1395 uint64_t *psize;
1396 real_time *pmtime;
1397 uint64_t *pepoch;
1398 RGWObjVersionTracker *objv_tracker;
1399 protected:
1400 int _send_request() override;
1401 public:
1402 RGWAsyncStatObj(RGWCoroutine *caller, RGWAioCompletionNotifier *cn, rgw::sal::RGWRadosStore *store,
1403 const RGWBucketInfo& _bucket_info, const rgw_obj& obj, uint64_t *psize = nullptr,
1404 real_time *pmtime = nullptr, uint64_t *pepoch = nullptr,
1405 RGWObjVersionTracker *objv_tracker = nullptr)
1406 : RGWAsyncRadosRequest(caller, cn), store(store), obj(obj), psize(psize),
1407 pmtime(pmtime), pepoch(pepoch), objv_tracker(objv_tracker) {}
1408 };
1409
1410 class RGWStatObjCR : public RGWSimpleCoroutine {
1411 rgw::sal::RGWRadosStore *store;
1412 RGWAsyncRadosProcessor *async_rados;
1413 RGWBucketInfo bucket_info;
1414 rgw_obj obj;
1415 uint64_t *psize;
1416 real_time *pmtime;
1417 uint64_t *pepoch;
1418 RGWObjVersionTracker *objv_tracker;
1419 RGWAsyncStatObj *req = nullptr;
1420 public:
1421 RGWStatObjCR(RGWAsyncRadosProcessor *async_rados, rgw::sal::RGWRadosStore *store,
1422 const RGWBucketInfo& _bucket_info, const rgw_obj& obj, uint64_t *psize = nullptr,
1423 real_time* pmtime = nullptr, uint64_t *pepoch = nullptr,
1424 RGWObjVersionTracker *objv_tracker = nullptr);
1425 ~RGWStatObjCR() override {
1426 request_cleanup();
1427 }
1428 void request_cleanup() override;
1429
1430 int send_request() override;
1431 int request_complete() override;
1432 };
1433
1434 /// coroutine wrapper for IoCtx::aio_notify()
1435 class RGWRadosNotifyCR : public RGWSimpleCoroutine {
1436 rgw::sal::RGWRadosStore *const store;
1437 const rgw_raw_obj obj;
1438 bufferlist request;
1439 const uint64_t timeout_ms;
1440 bufferlist *response;
1441 rgw_rados_ref ref;
1442 boost::intrusive_ptr<RGWAioCompletionNotifier> cn;
1443
1444 public:
1445 RGWRadosNotifyCR(rgw::sal::RGWRadosStore *store, const rgw_raw_obj& obj,
1446 bufferlist& request, uint64_t timeout_ms,
1447 bufferlist *response);
1448
1449 int send_request() override;
1450 int request_complete() override;
1451 };
1452
1453 #endif