]> git.proxmox.com Git - ceph.git/blob - ceph/src/librbd/io/ImageDispatchSpec.h
import 15.2.0 Octopus source
[ceph.git] / ceph / src / librbd / io / ImageDispatchSpec.h
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, 0);
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, uint64_t tid) {
85 return new ImageDispatchSpec(image_ctx, aio_comp, {{off, len}},
86 Discard{discard_granularity_bytes},
87 0, parent_trace, tid);
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, 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);
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, uint64_t tid) {
100 return new ImageDispatchSpec(image_ctx, aio_comp, {{off, len}},
101 WriteSame{std::move(bl)}, op_flags,
102 parent_trace, tid);
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, uint64_t tid) {
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, tid);
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, 0);
122 }
123
124 ~ImageDispatchSpec() {
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 const Extents& get_image_extents() const;
150
151 AioCompletion* get_aio_completion() const {
152 return m_aio_comp;
153 }
154
155 uint64_t get_tid();
156 bool blocked = false;
157
158 private:
159 typedef boost::variant<Read,
160 Discard,
161 Write,
162 WriteSame,
163 CompareAndWrite,
164 Flush> Request;
165
166 struct SendVisitor;
167 struct IsWriteOpVisitor;
168 struct TokenRequestedVisitor;
169
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) {
176 m_aio_comp->get();
177 }
178
179 ImageCtxT& m_image_ctx;
180 AioCompletion* m_aio_comp;
181 Extents m_image_extents;
182 Request m_request;
183 int m_op_flags;
184 ZTracer::Trace m_parent_trace;
185 uint64_t m_tid;
186 std::atomic<uint64_t> m_throttled_flag = 0;
187
188 uint64_t extents_length();
189 };
190
191 } // namespace io
192 } // namespace librbd
193
194 extern template class librbd::io::ImageDispatchSpec<librbd::ImageCtx>;
195
196 #endif // CEPH_LIBRBD_IO_IMAGE_DISPATCH_SPEC_H