1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3
4 #ifndef CEPH_LIBRBD_IO_IMAGE_DISPATCH_SPEC_H
5 #define CEPH_LIBRBD_IO_IMAGE_DISPATCH_SPEC_H
6
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>
14
15 namespace librbd {
16
17 class ImageCtx;
18
19 namespace io {
20
21 template <typename ImageCtxT = ImageCtx>
22 class ImageDispatchSpec {
23 public:
24 struct Read {
25 ReadResult read_result;
26
27 Read(ReadResult &&read_result) : read_result(std::move(read_result)) {
28 }
29 };
30
31 struct Discard {
32 uint32_t discard_granularity_bytes;
33
34 Discard(uint32_t discard_granularity_bytes)
35 : discard_granularity_bytes(discard_granularity_bytes) {
36 }
37 };
38
39 struct Write {
40 bufferlist bl;
41
42 Write(bufferlist&& bl) : bl(std::move(bl)) {
43 }
44 };
45
46 struct WriteSame {
47 bufferlist bl;
48
49 WriteSame(bufferlist&& bl) : bl(std::move(bl)) {
50 }
51 };
52
53 struct CompareAndWrite {
54 bufferlist cmp_bl;
55 bufferlist bl;
56 uint64_t *mismatch_offset;
57
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) {
62 }
63 };
64
65 struct Flush {
66 FlushSource flush_source;
67
68 Flush(FlushSource flush_source) : flush_source(flush_source) {
69 }
70 };
71
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);
80 }
81
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) {
85 return new ImageDispatchSpec(image_ctx, aio_comp, {{off, len}},
86 Discard{discard_granularity_bytes},
87 0, parent_trace);
88 }
89
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) {
93 return new ImageDispatchSpec(image_ctx, aio_comp, std::move(image_extents),
94 Write{std::move(bl)}, op_flags, parent_trace);
95 }
96
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) {
100 return new ImageDispatchSpec(image_ctx, aio_comp, {{off, len}},
101 WriteSame{std::move(bl)}, op_flags,
102 parent_trace);
103 }
104
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) {
109 return new ImageDispatchSpec(image_ctx, aio_comp,
110 std::move(image_extents),
111 CompareAndWrite{std::move(cmp_bl),
112 std::move(bl),
113 mismatch_offset},
114 op_flags, parent_trace);
115 }
116
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},
121 0, parent_trace);
122 }
123
(1) Event exn_spec_violation: |
An exception of type "_ZN5boost16exception_detail10clone_implINS0_19error_info_injectorINSt8ios_base7failureB5cxx11EEEEE" is thrown but the throw list "throw()" doesn't allow it to be thrown. This will cause a call to unexpected() which usually calls terminate(). |
Also see events: |
[fun_call_w_exception] |
124 ~ImageDispatchSpec() {
(2) Event fun_call_w_exception: |
Called function throws an exception of type "_ZN5boost16exception_detail10clone_implINS0_19error_info_injectorINSt8ios_base7failureB5cxx11EEEEE". [details] |
Also see events: |
[exn_spec_violation] |
125 m_aio_comp->put();
126 }
127
128 void send();
129 void fail(int r);
130
131 bool is_write_op() const;
132
133 void start_op();
134
135 bool tokens_requested(uint64_t flag, uint64_t *tokens);
136
137 bool was_throttled(uint64_t flag) {
138 return m_throttled_flag & flag;
139 }
140
141 void set_throttled(uint64_t flag) {
142 m_throttled_flag |= flag;
143 }
144
145 bool were_all_throttled() {
146 return (m_throttled_flag & RBD_QOS_MASK) == RBD_QOS_MASK;
147 }
148
149 private:
150 typedef boost::variant<Read,
151 Discard,
152 Write,
153 WriteSame,
154 CompareAndWrite,
155 Flush> Request;
156
157 struct SendVisitor;
158 struct IsWriteOpVisitor;
159 struct TokenRequestedVisitor;
160
161 ImageDispatchSpec(ImageCtxT& image_ctx, AioCompletion* aio_comp,
162 Extents&& image_extents, Request&& request,
163 int op_flags, const ZTracer::Trace& parent_trace)
164 : m_image_ctx(image_ctx), m_aio_comp(aio_comp),
165 m_image_extents(std::move(image_extents)), m_request(std::move(request)),
166 m_op_flags(op_flags), m_parent_trace(parent_trace) {
167 m_aio_comp->get();
168 }
169
170 ImageCtxT& m_image_ctx;
171 AioCompletion* m_aio_comp;
172 Extents m_image_extents;
173 Request m_request;
174 int m_op_flags;
175 ZTracer::Trace m_parent_trace;
176 std::atomic<uint64_t> m_throttled_flag = 0;
177
178 uint64_t extents_length();
179 };
180
181 } // namespace io
182 } // namespace librbd
183
184 extern template class librbd::io::ImageDispatchSpec<librbd::ImageCtx>;
185
186 #endif // CEPH_LIBRBD_IO_IMAGE_DISPATCH_SPEC_H
187