]> git.proxmox.com Git - ceph.git/blame - ceph/src/librbd/io/ImageDispatchSpec.cc
buildsys: use download.ceph.com to download source tar ball
[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;
79
80 TokenRequestedVisitor(ImageDispatchSpec* spec, uint64_t _flag)
81 : spec(spec), flag(_flag) {
82 }
83
84 uint64_t operator()(const Read&) const {
85 if (flag & RBD_QOS_WRITE_MASK) {
86 return 0;
87 }
88
89 if (flag & RBD_QOS_BPS_MASK) {
90 return spec->extents_length();
91 }
92 return 1;
93 }
94
95 uint64_t operator()(const Flush&) const {
96 return 0;
97 }
98
99 template <typename T>
100 uint64_t operator()(const T&) const {
101 if (flag & RBD_QOS_READ_MASK) {
102 return 0;
103 }
104
105 if (flag & RBD_QOS_BPS_MASK) {
106 return spec->extents_length();
107 }
108 return 1;
109 }
110};
111
112template <typename I>
113void ImageDispatchSpec<I>::send() {
114 boost::apply_visitor(SendVisitor{this}, m_request);
115}
116
117template <typename I>
118void ImageDispatchSpec<I>::fail(int r) {
119 m_aio_comp->get();
120 m_aio_comp->fail(r);
121}
122
123template <typename I>
124uint64_t ImageDispatchSpec<I>::extents_length() {
125 uint64_t length = 0;
126 auto &extents = this->m_image_extents;
127
128 for (auto &extent : extents) {
129 length += extent.second;
130 }
131 return length;
132}
133
134template <typename I>
135bool ImageDispatchSpec<I>::is_write_op() const {
136 return boost::apply_visitor(IsWriteOpVisitor(), m_request);
137}
138
139template <typename I>
140uint64_t ImageDispatchSpec<I>::tokens_requested(uint64_t flag) {
141 return boost::apply_visitor(TokenRequestedVisitor{this, flag}, m_request);
142}
143
144template <typename I>
145void ImageDispatchSpec<I>::start_op() {
146 m_aio_comp->start_op();
147}
148
149} // namespace io
150} // namespace librbd
151
152template class librbd::io::ImageDispatchSpec<librbd::ImageCtx>;