1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #include "librbd/io/QueueImageDispatch.h"
5 #include "common/dout.h"
6 #include "common/Cond.h"
7 #include "librbd/AsioEngine.h"
8 #include "librbd/ImageCtx.h"
9 #include "librbd/Utils.h"
10 #include "librbd/io/AioCompletion.h"
11 #include "librbd/io/FlushTracker.h"
12 #include "librbd/io/ImageDispatchSpec.h"
14 #define dout_subsys ceph_subsys_rbd
16 #define dout_prefix *_dout << "librbd::io::QueueImageDispatch: " << this \
17 << " " << __func__ << ": "
23 QueueImageDispatch
<I
>::QueueImageDispatch(I
* image_ctx
)
24 : m_image_ctx(image_ctx
), m_flush_tracker(new FlushTracker
<I
>(image_ctx
)) {
25 auto cct
= m_image_ctx
->cct
;
26 ldout(cct
, 5) << "ictx=" << image_ctx
<< dendl
;
30 QueueImageDispatch
<I
>::~QueueImageDispatch() {
31 delete m_flush_tracker
;
35 void QueueImageDispatch
<I
>::shut_down(Context
* on_finish
) {
36 m_flush_tracker
->shut_down();
37 on_finish
->complete(0);
41 bool QueueImageDispatch
<I
>::read(
42 AioCompletion
* aio_comp
, Extents
&&image_extents
, ReadResult
&&read_result
,
43 IOContext io_context
, int op_flags
, int read_flags
,
44 const ZTracer::Trace
&parent_trace
, uint64_t tid
,
45 std::atomic
<uint32_t>* image_dispatch_flags
,
46 DispatchResult
* dispatch_result
, Context
** on_finish
,
47 Context
* on_dispatched
) {
48 auto cct
= m_image_ctx
->cct
;
49 ldout(cct
, 20) << "tid=" << tid
<< dendl
;
51 return enqueue(true, tid
, dispatch_result
, on_finish
, on_dispatched
);
55 bool QueueImageDispatch
<I
>::write(
56 AioCompletion
* aio_comp
, Extents
&&image_extents
, bufferlist
&&bl
,
57 IOContext io_context
, int op_flags
, const ZTracer::Trace
&parent_trace
,
58 uint64_t tid
, std::atomic
<uint32_t>* image_dispatch_flags
,
59 DispatchResult
* dispatch_result
, Context
** on_finish
,
60 Context
* on_dispatched
) {
61 auto cct
= m_image_ctx
->cct
;
62 ldout(cct
, 20) << "tid=" << tid
<< dendl
;
64 return enqueue(false, tid
, dispatch_result
, on_finish
, on_dispatched
);
68 bool QueueImageDispatch
<I
>::discard(
69 AioCompletion
* aio_comp
, Extents
&&image_extents
,
70 uint32_t discard_granularity_bytes
, IOContext io_context
,
71 const ZTracer::Trace
&parent_trace
,
72 uint64_t tid
, std::atomic
<uint32_t>* image_dispatch_flags
,
73 DispatchResult
* dispatch_result
, Context
** on_finish
,
74 Context
* on_dispatched
) {
75 auto cct
= m_image_ctx
->cct
;
76 ldout(cct
, 20) << "tid=" << tid
<< dendl
;
78 return enqueue(false, tid
, dispatch_result
, on_finish
, on_dispatched
);
82 bool QueueImageDispatch
<I
>::write_same(
83 AioCompletion
* aio_comp
, Extents
&&image_extents
, bufferlist
&&bl
,
84 IOContext io_context
, int op_flags
, const ZTracer::Trace
&parent_trace
,
85 uint64_t tid
, std::atomic
<uint32_t>* image_dispatch_flags
,
86 DispatchResult
* dispatch_result
, Context
** on_finish
,
87 Context
* on_dispatched
) {
88 auto cct
= m_image_ctx
->cct
;
89 ldout(cct
, 20) << "tid=" << tid
<< dendl
;
91 return enqueue(false, tid
, dispatch_result
, on_finish
, on_dispatched
);
95 bool QueueImageDispatch
<I
>::compare_and_write(
96 AioCompletion
* aio_comp
, Extents
&&image_extents
, bufferlist
&&cmp_bl
,
97 bufferlist
&&bl
, uint64_t *mismatch_offset
, IOContext io_context
,
98 int op_flags
, const ZTracer::Trace
&parent_trace
, uint64_t tid
,
99 std::atomic
<uint32_t>* image_dispatch_flags
,
100 DispatchResult
* dispatch_result
, Context
** on_finish
,
101 Context
* on_dispatched
) {
102 auto cct
= m_image_ctx
->cct
;
103 ldout(cct
, 20) << "tid=" << tid
<< dendl
;
105 return enqueue(false, tid
, dispatch_result
, on_finish
, on_dispatched
);
108 template <typename I
>
109 bool QueueImageDispatch
<I
>::flush(
110 AioCompletion
* aio_comp
, FlushSource flush_source
,
111 const ZTracer::Trace
&parent_trace
, uint64_t tid
,
112 std::atomic
<uint32_t>* image_dispatch_flags
,
113 DispatchResult
* dispatch_result
, Context
** on_finish
,
114 Context
* on_dispatched
) {
115 auto cct
= m_image_ctx
->cct
;
116 ldout(cct
, 20) << "tid=" << tid
<< dendl
;
118 *dispatch_result
= DISPATCH_RESULT_CONTINUE
;
119 m_flush_tracker
->flush(on_dispatched
);
123 template <typename I
>
124 void QueueImageDispatch
<I
>::handle_finished(int r
, uint64_t tid
) {
125 auto cct
= m_image_ctx
->cct
;
126 ldout(cct
, 20) << "tid=" << tid
<< dendl
;
128 m_flush_tracker
->finish_io(tid
);
131 template <typename I
>
132 bool QueueImageDispatch
<I
>::enqueue(
133 bool read_op
, uint64_t tid
, DispatchResult
* dispatch_result
,
134 Context
** on_finish
, Context
* on_dispatched
) {
135 if (!m_image_ctx
->non_blocking_aio
) {
140 m_flush_tracker
->start_io(tid
);
141 *on_finish
= new LambdaContext([this, tid
, on_finish
=*on_finish
](int r
) {
142 handle_finished(r
, tid
);
143 on_finish
->complete(r
);
147 *dispatch_result
= DISPATCH_RESULT_CONTINUE
;
148 m_image_ctx
->asio_engine
->post(on_dispatched
, 0);
153 } // namespace librbd
155 template class librbd::io::QueueImageDispatch
<librbd::ImageCtx
>;