]>
git.proxmox.com Git - ceph.git/blob - ceph/src/librbd/io/ReadResult.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #include "librbd/io/ReadResult.h"
5 #include "include/buffer.h"
6 #include "common/dout.h"
7 #include "librbd/io/AioCompletion.h"
8 #include <boost/variant/apply_visitor.hpp>
9 #include <boost/variant/static_visitor.hpp>
11 #define dout_subsys ceph_subsys_rbd
13 #define dout_prefix *_dout << "librbd::io::ReadResult: " << this \
14 << " " << __func__ << ": "
19 struct ReadResult::SetClipLengthVisitor
: public boost::static_visitor
<void> {
22 explicit SetClipLengthVisitor(size_t length
) : length(length
) {
25 void operator()(Linear
&linear
) const {
26 ceph_assert(length
<= linear
.buf_len
);
27 linear
.buf_len
= length
;
31 void operator()(T
&t
) const {
35 struct ReadResult::AssembleResultVisitor
: public boost::static_visitor
<void> {
37 Striper::StripedReadResult
&destriper
;
39 AssembleResultVisitor(CephContext
*cct
, Striper::StripedReadResult
&destriper
)
40 : cct(cct
), destriper(destriper
) {
43 void operator()(Empty
&empty
) const {
44 ldout(cct
, 20) << "dropping read result" << dendl
;
47 void operator()(Linear
&linear
) const {
48 ldout(cct
, 20) << "copying resulting bytes to "
49 << reinterpret_cast<void*>(linear
.buf
) << dendl
;
50 destriper
.assemble_result(cct
, linear
.buf
, linear
.buf_len
);
53 void operator()(Vector
&vector
) const {
55 destriper
.assemble_result(cct
, bl
, true);
57 ldout(cct
, 20) << "copying resulting " << bl
.length() << " bytes to iovec "
58 << reinterpret_cast<const void*>(vector
.iov
) << dendl
;
60 bufferlist::iterator it
= bl
.begin();
61 size_t length
= bl
.length();
64 for (; offset
< length
&& idx
< vector
.iov_count
; idx
++) {
65 size_t len
= std::min(vector
.iov
[idx
].iov_len
, length
- offset
);
66 it
.copy(len
, static_cast<char *>(vector
.iov
[idx
].iov_base
));
69 ceph_assert(offset
== bl
.length());
72 void operator()(Bufferlist
&bufferlist
) const {
73 bufferlist
.bl
->clear();
74 destriper
.assemble_result(cct
, *bufferlist
.bl
, true);
76 ldout(cct
, 20) << "moved resulting " << bufferlist
.bl
->length() << " "
77 << "bytes to bl " << reinterpret_cast<void*>(bufferlist
.bl
)
81 void operator()(SparseBufferlist
&sparse_bufferlist
) const {
82 sparse_bufferlist
.extent_map
->clear();
83 sparse_bufferlist
.bl
->clear();
84 destriper
.assemble_result(cct
, sparse_bufferlist
.extent_map
,
85 sparse_bufferlist
.bl
);
87 ldout(cct
, 20) << "moved resulting " << sparse_bufferlist
.extent_map
->size()
88 << " extents of total " << sparse_bufferlist
.bl
->length()
90 << reinterpret_cast<void*>(sparse_bufferlist
.bl
) << dendl
;
94 ReadResult::C_ImageReadRequest::C_ImageReadRequest(
95 AioCompletion
*aio_completion
, const Extents image_extents
)
96 : aio_completion(aio_completion
), image_extents(image_extents
) {
97 aio_completion
->add_request();
100 void ReadResult::C_ImageReadRequest::finish(int r
) {
101 CephContext
*cct
= aio_completion
->ictx
->cct
;
102 ldout(cct
, 10) << "C_ImageReadRequest: r=" << r
106 for (auto &image_extent
: image_extents
) {
107 length
+= image_extent
.second
;
109 ceph_assert(length
== bl
.length());
111 aio_completion
->lock
.lock();
112 aio_completion
->read_result
.m_destriper
.add_partial_result(
113 cct
, bl
, image_extents
);
114 aio_completion
->lock
.unlock();
118 aio_completion
->complete_request(r
);
121 ReadResult::C_ObjectReadRequest::C_ObjectReadRequest(
122 AioCompletion
*aio_completion
, uint64_t object_off
, uint64_t object_len
,
123 LightweightBufferExtents
&& buffer_extents
)
124 : aio_completion(aio_completion
), object_off(object_off
),
125 object_len(object_len
), buffer_extents(std::move(buffer_extents
)) {
126 aio_completion
->add_request();
129 void ReadResult::C_ObjectReadRequest::finish(int r
) {
130 CephContext
*cct
= aio_completion
->ictx
->cct
;
131 ldout(cct
, 10) << "C_ObjectReadRequest: r=" << r
138 ldout(cct
, 10) << " got " << extent_map
139 << " for " << buffer_extents
140 << " bl " << bl
.length() << dendl
;
141 aio_completion
->lock
.lock();
142 if (!extent_map
.empty()) {
143 aio_completion
->read_result
.m_destriper
.add_partial_sparse_result(
144 cct
, bl
, extent_map
, object_off
, buffer_extents
);
146 // handle the case where a sparse-read wasn't issued
147 aio_completion
->read_result
.m_destriper
.add_partial_result(
148 cct
, std::move(bl
), buffer_extents
);
150 aio_completion
->lock
.unlock();
155 aio_completion
->complete_request(r
);
158 ReadResult::ReadResult() : m_buffer(Empty()) {
161 ReadResult::ReadResult(char *buf
, size_t buf_len
)
162 : m_buffer(Linear(buf
, buf_len
)) {
165 ReadResult::ReadResult(const struct iovec
*iov
, int iov_count
)
166 : m_buffer(Vector(iov
, iov_count
)) {
169 ReadResult::ReadResult(ceph::bufferlist
*bl
)
170 : m_buffer(Bufferlist(bl
)) {
173 ReadResult::ReadResult(std::map
<uint64_t, uint64_t> *extent_map
,
174 ceph::bufferlist
*bl
)
175 : m_buffer(SparseBufferlist(extent_map
, bl
)) {
178 void ReadResult::set_clip_length(size_t length
) {
179 boost::apply_visitor(SetClipLengthVisitor(length
), m_buffer
);
182 void ReadResult::assemble_result(CephContext
*cct
) {
183 boost::apply_visitor(AssembleResultVisitor(cct
, m_destriper
), m_buffer
);
187 } // namespace librbd