1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #ifndef CEPH_LIBRBD_IO_IMAGE_DISPATCH_SPEC_H
5 #define CEPH_LIBRBD_IO_IMAGE_DISPATCH_SPEC_H
7 #include "include/int_types.h"
8 #include "include/buffer.h"
9 #include "common/zipkin_trace.h"
10 #include "librbd/io/AioCompletion.h"
11 #include "librbd/io/Types.h"
12 #include "librbd/io/ReadResult.h"
13 #include <boost/variant/variant.hpp>
21 template <typename ImageCtxT
= ImageCtx
>
22 class ImageDispatchSpec
{
25 ReadResult read_result
;
27 Read(ReadResult
&&read_result
) : read_result(std::move(read_result
)) {
32 uint32_t discard_granularity_bytes
;
34 Discard(uint32_t discard_granularity_bytes
)
35 : discard_granularity_bytes(discard_granularity_bytes
) {
42 Write(bufferlist
&& bl
) : bl(std::move(bl
)) {
49 WriteSame(bufferlist
&& bl
) : bl(std::move(bl
)) {
53 struct CompareAndWrite
{
56 uint64_t *mismatch_offset
;
58 CompareAndWrite(bufferlist
&& cmp_bl
, bufferlist
&& bl
,
59 uint64_t *mismatch_offset
)
60 : cmp_bl(std::move(cmp_bl
)), bl(std::move(bl
)),
61 mismatch_offset(mismatch_offset
) {
66 FlushSource flush_source
;
68 Flush(FlushSource flush_source
) : flush_source(flush_source
) {
72 static ImageDispatchSpec
* create_read_request(
73 ImageCtxT
&image_ctx
, AioCompletion
*aio_comp
, Extents
&&image_extents
,
74 ReadResult
&&read_result
, int op_flags
,
75 const ZTracer::Trace
&parent_trace
) {
76 return new ImageDispatchSpec(image_ctx
, aio_comp
,
77 std::move(image_extents
),
78 Read
{std::move(read_result
)},
79 op_flags
, parent_trace
, 0);
82 static ImageDispatchSpec
* create_discard_request(
83 ImageCtxT
&image_ctx
, AioCompletion
*aio_comp
, uint64_t off
, uint64_t len
,
84 uint32_t discard_granularity_bytes
, const ZTracer::Trace
&parent_trace
, uint64_t tid
) {
85 return new ImageDispatchSpec(image_ctx
, aio_comp
, {{off
, len
}},
86 Discard
{discard_granularity_bytes
},
87 0, parent_trace
, tid
);
90 static ImageDispatchSpec
* create_write_request(
91 ImageCtxT
&image_ctx
, AioCompletion
*aio_comp
, Extents
&&image_extents
,
92 bufferlist
&&bl
, int op_flags
, const ZTracer::Trace
&parent_trace
, uint64_t tid
) {
93 return new ImageDispatchSpec(image_ctx
, aio_comp
, std::move(image_extents
),
94 Write
{std::move(bl
)}, op_flags
, parent_trace
, tid
);
97 static ImageDispatchSpec
* create_write_same_request(
98 ImageCtxT
&image_ctx
, AioCompletion
*aio_comp
, uint64_t off
, uint64_t len
,
99 bufferlist
&&bl
, int op_flags
, const ZTracer::Trace
&parent_trace
, uint64_t tid
) {
100 return new ImageDispatchSpec(image_ctx
, aio_comp
, {{off
, len
}},
101 WriteSame
{std::move(bl
)}, op_flags
,
105 static ImageDispatchSpec
* create_compare_and_write_request(
106 ImageCtxT
&image_ctx
, AioCompletion
*aio_comp
, Extents
&&image_extents
,
107 bufferlist
&&cmp_bl
, bufferlist
&&bl
, uint64_t *mismatch_offset
,
108 int op_flags
, const ZTracer::Trace
&parent_trace
, uint64_t tid
) {
109 return new ImageDispatchSpec(image_ctx
, aio_comp
,
110 std::move(image_extents
),
111 CompareAndWrite
{std::move(cmp_bl
),
114 op_flags
, parent_trace
, tid
);
117 static ImageDispatchSpec
* create_flush_request(
118 ImageCtxT
&image_ctx
, AioCompletion
*aio_comp
,
119 FlushSource flush_source
, const ZTracer::Trace
&parent_trace
) {
120 return new ImageDispatchSpec(image_ctx
, aio_comp
, {}, Flush
{flush_source
},
124 ~ImageDispatchSpec() {
131 bool is_write_op() const;
135 bool tokens_requested(uint64_t flag
, uint64_t *tokens
);
137 bool was_throttled(uint64_t flag
) {
138 return m_throttled_flag
& flag
;
141 void set_throttled(uint64_t flag
) {
142 m_throttled_flag
|= flag
;
145 bool were_all_throttled() {
146 return (m_throttled_flag
& RBD_QOS_MASK
) == RBD_QOS_MASK
;
149 const Extents
& get_image_extents() const;
151 AioCompletion
* get_aio_completion() const {
156 bool blocked
= false;
159 typedef boost::variant
<Read
,
167 struct IsWriteOpVisitor
;
168 struct TokenRequestedVisitor
;
170 ImageDispatchSpec(ImageCtxT
& image_ctx
, AioCompletion
* aio_comp
,
171 Extents
&& image_extents
, Request
&& request
,
172 int op_flags
, const ZTracer::Trace
& parent_trace
, uint64_t tid
)
173 : m_image_ctx(image_ctx
), m_aio_comp(aio_comp
),
174 m_image_extents(std::move(image_extents
)), m_request(std::move(request
)),
175 m_op_flags(op_flags
), m_parent_trace(parent_trace
), m_tid(tid
) {
179 ImageCtxT
& m_image_ctx
;
180 AioCompletion
* m_aio_comp
;
181 Extents m_image_extents
;
184 ZTracer::Trace m_parent_trace
;
186 std::atomic
<uint64_t> m_throttled_flag
= 0;
188 uint64_t extents_length();
192 } // namespace librbd
194 extern template class librbd::io::ImageDispatchSpec
<librbd::ImageCtx
>;
196 #endif // CEPH_LIBRBD_IO_IMAGE_DISPATCH_SPEC_H