]> git.proxmox.com Git - ceph.git/blame - ceph/src/librbd/io/ImageDispatchSpec.h
import ceph nautilus 14.2.2
[ceph.git] / ceph / src / librbd / io / ImageDispatchSpec.h
CommitLineData
11fdf7f2
TL
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/Types.h"
11#include "librbd/io/ReadResult.h"
12#include <boost/variant/variant.hpp>
13
14namespace librbd {
15
16class ImageCtx;
17
18namespace io {
19
20class AioCompletion;
21
22template <typename ImageCtxT = ImageCtx>
23class ImageDispatchSpec {
24public:
25 struct Read {
26 ReadResult read_result;
27
28 Read(ReadResult &&read_result) : read_result(std::move(read_result)) {
29 }
30 };
31
32 struct Discard {
33 uint32_t discard_granularity_bytes;
34
35 Discard(uint32_t discard_granularity_bytes)
36 : discard_granularity_bytes(discard_granularity_bytes) {
37 }
38 };
39
40 struct Write {
41 bufferlist bl;
42
43 Write(bufferlist&& bl) : bl(std::move(bl)) {
44 }
45 };
46
47 struct WriteSame {
48 bufferlist bl;
49
50 WriteSame(bufferlist&& bl) : bl(std::move(bl)) {
51 }
52 };
53
54 struct CompareAndWrite {
55 bufferlist cmp_bl;
56 bufferlist bl;
57 uint64_t *mismatch_offset;
58
59 CompareAndWrite(bufferlist&& cmp_bl, bufferlist&& bl,
60 uint64_t *mismatch_offset)
61 : cmp_bl(std::move(cmp_bl)), bl(std::move(bl)),
62 mismatch_offset(mismatch_offset) {
63 }
64 };
65
66 struct Flush {
67 FlushSource flush_source;
68
69 Flush(FlushSource flush_source) : flush_source(flush_source) {
70 }
71 };
72
73 static ImageDispatchSpec* create_read_request(
74 ImageCtxT &image_ctx, AioCompletion *aio_comp, Extents &&image_extents,
75 ReadResult &&read_result, int op_flags,
76 const ZTracer::Trace &parent_trace) {
77 return new ImageDispatchSpec(image_ctx, aio_comp,
78 std::move(image_extents),
79 Read{std::move(read_result)},
80 op_flags, parent_trace);
81 }
82
83 static ImageDispatchSpec* create_discard_request(
84 ImageCtxT &image_ctx, AioCompletion *aio_comp, uint64_t off, uint64_t len,
85 uint32_t discard_granularity_bytes, const ZTracer::Trace &parent_trace) {
86 return new ImageDispatchSpec(image_ctx, aio_comp, {{off, len}},
87 Discard{discard_granularity_bytes},
88 0, parent_trace);
89 }
90
91 static ImageDispatchSpec* create_write_request(
92 ImageCtxT &image_ctx, AioCompletion *aio_comp, Extents &&image_extents,
93 bufferlist &&bl, int op_flags, const ZTracer::Trace &parent_trace) {
94 return new ImageDispatchSpec(image_ctx, aio_comp, std::move(image_extents),
95 Write{std::move(bl)}, op_flags, parent_trace);
96 }
97
98 static ImageDispatchSpec* create_write_same_request(
99 ImageCtxT &image_ctx, AioCompletion *aio_comp, uint64_t off, uint64_t len,
100 bufferlist &&bl, int op_flags, const ZTracer::Trace &parent_trace) {
101 return new ImageDispatchSpec(image_ctx, aio_comp, {{off, len}},
102 WriteSame{std::move(bl)}, op_flags,
103 parent_trace);
104 }
105
106 static ImageDispatchSpec* create_compare_and_write_request(
107 ImageCtxT &image_ctx, AioCompletion *aio_comp, Extents &&image_extents,
108 bufferlist &&cmp_bl, bufferlist &&bl, uint64_t *mismatch_offset,
109 int op_flags, const ZTracer::Trace &parent_trace) {
110 return new ImageDispatchSpec(image_ctx, aio_comp,
111 std::move(image_extents),
112 CompareAndWrite{std::move(cmp_bl),
113 std::move(bl),
114 mismatch_offset},
115 op_flags, parent_trace);
116 }
117
118 static ImageDispatchSpec* create_flush_request(
119 ImageCtxT &image_ctx, AioCompletion *aio_comp,
120 FlushSource flush_source, const ZTracer::Trace &parent_trace) {
121 return new ImageDispatchSpec(image_ctx, aio_comp, {}, Flush{flush_source},
122 0, parent_trace);
123 }
124
125 void send();
126 void fail(int r);
127
128 bool is_write_op() const;
129
130 void start_op();
131
81eedcae 132 bool tokens_requested(uint64_t flag, uint64_t *tokens);
11fdf7f2
TL
133
134 bool was_throttled(uint64_t flag) {
135 return m_throttled_flag & flag;
136 }
137
138 void set_throttled(uint64_t flag) {
139 m_throttled_flag |= flag;
140 }
141
142 bool were_all_throttled() {
143 return (m_throttled_flag & RBD_QOS_MASK) == RBD_QOS_MASK;
144 }
145
146private:
147 typedef boost::variant<Read,
148 Discard,
149 Write,
150 WriteSame,
151 CompareAndWrite,
152 Flush> Request;
153
154 struct SendVisitor;
155 struct IsWriteOpVisitor;
156 struct TokenRequestedVisitor;
157
158 ImageDispatchSpec(ImageCtxT& image_ctx, AioCompletion* aio_comp,
159 Extents&& image_extents, Request&& request,
160 int op_flags, const ZTracer::Trace& parent_trace)
161 : m_image_ctx(image_ctx), m_aio_comp(aio_comp),
162 m_image_extents(std::move(image_extents)), m_request(std::move(request)),
163 m_op_flags(op_flags), m_parent_trace(parent_trace) {
164 }
165
166 ImageCtxT& m_image_ctx;
167 AioCompletion* m_aio_comp;
168 Extents m_image_extents;
169 Request m_request;
170 int m_op_flags;
171 ZTracer::Trace m_parent_trace;
172 std::atomic<uint64_t> m_throttled_flag = 0;
173
174 uint64_t extents_length();
175};
176
177} // namespace io
178} // namespace librbd
179
180extern template class librbd::io::ImageDispatchSpec<librbd::ImageCtx>;
181
182#endif // CEPH_LIBRBD_IO_IMAGE_DISPATCH_SPEC_H