]> git.proxmox.com Git - ceph.git/blame - ceph/src/librbd/io/ImageDispatchSpec.cc
import ceph nautilus 14.2.2
[ceph.git] / ceph / src / librbd / io / ImageDispatchSpec.cc
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#include "librbd/io/ImageDispatchSpec.h"
5#include "librbd/ImageCtx.h"
6#include "librbd/io/AioCompletion.h"
7#include "librbd/io/ImageRequest.h"
8#include <boost/variant.hpp>
9
10namespace librbd {
11namespace io {
12
13template <typename I>
14struct ImageDispatchSpec<I>::SendVisitor
15 : public boost::static_visitor<void> {
16 ImageDispatchSpec* spec;
17
18 explicit SendVisitor(ImageDispatchSpec* spec)
19 : spec(spec) {
20 }
21
22 void operator()(Read& read) const {
23 ImageRequest<I>::aio_read(
24 &spec->m_image_ctx, spec->m_aio_comp, std::move(spec->m_image_extents),
25 std::move(read.read_result), spec->m_op_flags, spec->m_parent_trace);
26 }
27
28 void operator()(Discard& discard) const {
29 ImageRequest<I>::aio_discard(
30 &spec->m_image_ctx, spec->m_aio_comp, std::move(spec->m_image_extents),
31 discard.discard_granularity_bytes, spec->m_parent_trace);
32 }
33
34 void operator()(Write& write) const {
35 ImageRequest<I>::aio_write(
36 &spec->m_image_ctx, spec->m_aio_comp, std::move(spec->m_image_extents),
37 std::move(write.bl), spec->m_op_flags, spec->m_parent_trace);
38 }
39
40 void operator()(WriteSame& write_same) const {
41 ImageRequest<I>::aio_writesame(
42 &spec->m_image_ctx, spec->m_aio_comp, std::move(spec->m_image_extents),
43 std::move(write_same.bl), spec->m_op_flags, spec->m_parent_trace);
44 }
45
46 void operator()(CompareAndWrite& compare_and_write) const {
47 ImageRequest<I>::aio_compare_and_write(
48 &spec->m_image_ctx, spec->m_aio_comp, std::move(spec->m_image_extents),
49 std::move(compare_and_write.cmp_bl), std::move(compare_and_write.bl),
50 compare_and_write.mismatch_offset, spec->m_op_flags,
51 spec->m_parent_trace);
52 }
53
54 void operator()(Flush& flush) const {
55 ImageRequest<I>::aio_flush(
56 &spec->m_image_ctx, spec->m_aio_comp, flush.flush_source,
57 spec->m_parent_trace);
58 }
59};
60
61template <typename I>
62struct ImageDispatchSpec<I>::IsWriteOpVisitor
63 : public boost::static_visitor<bool> {
64 bool operator()(const Read&) const {
65 return false;
66 }
67
68 template <typename T>
69 bool operator()(const T&) const {
70 return true;
71 }
72};
73
74template <typename I>
75struct ImageDispatchSpec<I>::TokenRequestedVisitor
76 : public boost::static_visitor<uint64_t> {
77 ImageDispatchSpec* spec;
78 uint64_t flag;
81eedcae 79 uint64_t *tokens;
11fdf7f2 80
81eedcae
TL
81 TokenRequestedVisitor(ImageDispatchSpec* spec, uint64_t _flag,
82 uint64_t *tokens)
83 : spec(spec), flag(_flag), tokens(tokens) {
11fdf7f2
TL
84 }
85
86 uint64_t operator()(const Read&) const {
87 if (flag & RBD_QOS_WRITE_MASK) {
81eedcae
TL
88 *tokens = 0;
89 return false;
11fdf7f2
TL
90 }
91
81eedcae
TL
92 *tokens = (flag & RBD_QOS_BPS_MASK) ? spec->extents_length() : 1;
93 return true;
11fdf7f2
TL
94 }
95
96 uint64_t operator()(const Flush&) const {
81eedcae
TL
97 *tokens = 0;
98 return true;
11fdf7f2
TL
99 }
100
101 template <typename T>
102 uint64_t operator()(const T&) const {
103 if (flag & RBD_QOS_READ_MASK) {
81eedcae
TL
104 *tokens = 0;
105 return false;
11fdf7f2
TL
106 }
107
81eedcae
TL
108 *tokens = (flag & RBD_QOS_BPS_MASK) ? spec->extents_length() : 1;
109 return true;
11fdf7f2
TL
110 }
111};
112
113template <typename I>
114void ImageDispatchSpec<I>::send() {
115 boost::apply_visitor(SendVisitor{this}, m_request);
116}
117
118template <typename I>
119void ImageDispatchSpec<I>::fail(int r) {
120 m_aio_comp->get();
121 m_aio_comp->fail(r);
122}
123
124template <typename I>
125uint64_t ImageDispatchSpec<I>::extents_length() {
126 uint64_t length = 0;
127 auto &extents = this->m_image_extents;
128
129 for (auto &extent : extents) {
130 length += extent.second;
131 }
132 return length;
133}
134
135template <typename I>
136bool ImageDispatchSpec<I>::is_write_op() const {
137 return boost::apply_visitor(IsWriteOpVisitor(), m_request);
138}
139
140template <typename I>
81eedcae
TL
141bool ImageDispatchSpec<I>::tokens_requested(uint64_t flag, uint64_t *tokens) {
142 return boost::apply_visitor(TokenRequestedVisitor{this, flag, tokens},
143 m_request);
11fdf7f2
TL
144}
145
146template <typename I>
147void ImageDispatchSpec<I>::start_op() {
148 m_aio_comp->start_op();
149}
150
151} // namespace io
152} // namespace librbd
153
154template class librbd::io::ImageDispatchSpec<librbd::ImageCtx>;