]> git.proxmox.com Git - ceph.git/blame - ceph/src/librbd/io/Utils.cc
Import ceph 15.2.8
[ceph.git] / ceph / src / librbd / io / Utils.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/Utils.h"
f91f0fd5 5#include "common/dout.h"
11fdf7f2 6#include "include/buffer.h"
f91f0fd5
TL
7#include "include/rados/librados.hpp"
8#include "librbd/io/AioCompletion.h"
9#include "librbd/io/ImageRequest.h"
11fdf7f2 10#include "osd/osd_types.h"
f91f0fd5
TL
11#include "osdc/Striper.h"
12
13#define dout_subsys ceph_subsys_rbd
14#undef dout_prefix
15#define dout_prefix *_dout << "librbd::io::util: " << __func__ << ": "
11fdf7f2
TL
16
17namespace librbd {
18namespace io {
19namespace util {
20
21bool assemble_write_same_extent(
9f95a23c 22 const LightweightObjectExtent &object_extent, const ceph::bufferlist& data,
11fdf7f2
TL
23 ceph::bufferlist *ws_data, bool force_write) {
24 size_t data_len = data.length();
25
26 if (!force_write) {
27 bool may_writesame = true;
28 for (auto& q : object_extent.buffer_extents) {
29 if (!(q.first % data_len == 0 && q.second % data_len == 0)) {
30 may_writesame = false;
31 break;
32 }
33 }
34
35 if (may_writesame) {
36 ws_data->append(data);
37 return true;
38 }
39 }
40
41 for (auto& q : object_extent.buffer_extents) {
42 bufferlist sub_bl;
43 uint64_t sub_off = q.first % data_len;
44 uint64_t sub_len = data_len - sub_off;
45 uint64_t extent_left = q.second;
46 while (extent_left >= sub_len) {
47 sub_bl.substr_of(data, sub_off, sub_len);
48 ws_data->claim_append(sub_bl);
49 extent_left -= sub_len;
50 if (sub_off) {
51 sub_off = 0;
52 sub_len = data_len;
53 }
54 }
55 if (extent_left) {
56 sub_bl.substr_of(data, sub_off, extent_left);
57 ws_data->claim_append(sub_bl);
58 }
59 }
60 return false;
61}
62
f91f0fd5
TL
63template <typename I>
64void read_parent(I *image_ctx, uint64_t object_no, uint64_t off,
65 uint64_t len, librados::snap_t snap_id,
66 const ZTracer::Trace &trace, ceph::bufferlist* data,
67 Context* on_finish) {
68
69 auto cct = image_ctx->cct;
70
71 std::shared_lock image_locker{image_ctx->image_lock};
72
73 // calculate reverse mapping onto the image
74 Extents parent_extents;
75 Striper::extent_to_file(cct, &image_ctx->layout, object_no, off, len,
76 parent_extents);
77
78 uint64_t parent_overlap = 0;
79 uint64_t object_overlap = 0;
80 int r = image_ctx->get_parent_overlap(snap_id, &parent_overlap);
81 if (r == 0) {
82 object_overlap = image_ctx->prune_parent_extents(parent_extents,
83 parent_overlap);
84 }
85
86 if (object_overlap == 0) {
87 image_locker.unlock();
88
89 on_finish->complete(-ENOENT);
90 return;
91 }
92
93 ldout(cct, 20) << dendl;
94
95 auto comp = AioCompletion::create_and_start(on_finish, image_ctx->parent,
96 AIO_TYPE_READ);
97 ldout(cct, 20) << "completion " << comp << ", extents " << parent_extents
98 << dendl;
99
100 ImageRequest<I>::aio_read(image_ctx->parent, comp, std::move(parent_extents),
101 ReadResult{data}, 0, trace);
102}
103
11fdf7f2
TL
104} // namespace util
105} // namespace io
106} // namespace librbd
107
f91f0fd5
TL
108template void librbd::io::util::read_parent(
109 librbd::ImageCtx *image_ctx, uint64_t object_no, uint64_t off, uint64_t len,
110 librados::snap_t snap_id, const ZTracer::Trace &trace,
111 ceph::bufferlist* data, Context* on_finish);