]> git.proxmox.com Git - ceph.git/blob - ceph/src/librbd/deep_copy/ObjectCopyRequest.h
import 15.2.0 Octopus source
[ceph.git] / ceph / src / librbd / deep_copy / ObjectCopyRequest.h
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_DEEP_COPY_OBJECT_COPY_REQUEST_H
5 #define CEPH_LIBRBD_DEEP_COPY_OBJECT_COPY_REQUEST_H
6
7 #include "include/int_types.h"
8 #include "include/interval_set.h"
9 #include "include/rados/librados.hpp"
10 #include "common/snap_types.h"
11 #include "librbd/ImageCtx.h"
12 #include "librbd/deep_copy/Types.h"
13 #include "librbd/io/Types.h"
14 #include <list>
15 #include <map>
16 #include <string>
17
18 class Context;
19 class RWLock;
20
21 namespace librbd {
22
23 namespace io { class AsyncOperation; }
24
25 namespace deep_copy {
26
27 template <typename ImageCtxT = librbd::ImageCtx>
28 class ObjectCopyRequest {
29 public:
30 static ObjectCopyRequest* create(ImageCtxT *src_image_ctx,
31 ImageCtxT *dst_image_ctx,
32 librados::snap_t src_snap_id_start,
33 librados::snap_t dst_snap_id_start,
34 const SnapMap &snap_map,
35 uint64_t object_number, bool flatten,
36 Context *on_finish) {
37 return new ObjectCopyRequest(src_image_ctx, dst_image_ctx,
38 src_snap_id_start, dst_snap_id_start, snap_map,
39 object_number, flatten, on_finish);
40 }
41
42 ObjectCopyRequest(ImageCtxT *src_image_ctx, ImageCtxT *dst_image_ctx,
43 librados::snap_t src_snap_id_start,
44 librados::snap_t dst_snap_id_start, const SnapMap &snap_map,
45 uint64_t object_number, bool flatten, Context *on_finish);
46
47 void send();
48
49 // testing support
50 inline librados::IoCtx &get_src_io_ctx() {
51 return m_src_io_ctx;
52 }
53 inline librados::IoCtx &get_dst_io_ctx() {
54 return m_dst_io_ctx;
55 }
56
57 private:
58 /**
59 * @verbatim
60 *
61 * <start>
62 * | /----------------------\
63 * | | |
64 * v v | (repeat for each src object)
65 * LIST_SNAPS < * * * |
66 * | * (-ENOENT and snap set stale)
67 * | * * * * * * |
68 * | * /-----------\ |
69 * | * | | (repeat for each snapshot)
70 * v * v | |
71 * READ_OBJECT ---------/ |
72 * | | |
73 * | \----------------------/
74 * v
75 * READ_FROM_PARENT (skip if not needed)
76 * |
77 * | /-----------\
78 * | | | (repeat for each snapshot)
79 * v v |
80 * WRITE_OBJECT --------/
81 * |
82 * | /-----------\
83 * | | | (repeat for each snapshot)
84 * v v |
85 * UPDATE_OBJECT_MAP ---/ (skip if object
86 * | map disabled)
87 * v
88 * <finish>
89 *
90 * @endverbatim
91 */
92
93 struct SrcObjectExtent {
94 uint64_t object_no = 0;
95 uint64_t offset = 0;
96 uint64_t length = 0;
97 bool noent = false;
98
99 SrcObjectExtent() {
100 }
101 SrcObjectExtent(uint64_t object_no, uint64_t offset, uint64_t length)
102 : object_no(object_no), offset(offset), length(length) {
103 }
104 };
105
106 typedef std::map<uint64_t, SrcObjectExtent> SrcObjectExtents;
107
108 enum CopyOpType {
109 COPY_OP_TYPE_WRITE,
110 COPY_OP_TYPE_ZERO,
111 COPY_OP_TYPE_TRUNC,
112 COPY_OP_TYPE_REMOVE,
113 COPY_OP_TYPE_REMOVE_TRUNC,
114 };
115
116 typedef std::map<uint64_t, uint64_t> ExtentMap;
117
118 struct CopyOp {
119 CopyOp(CopyOpType type, uint64_t src_offset, uint64_t dst_offset,
120 uint64_t length)
121 : type(type), src_offset(src_offset), dst_offset(dst_offset),
122 length(length) {
123 }
124
125 CopyOpType type;
126 uint64_t src_offset;
127 uint64_t dst_offset;
128 uint64_t length;
129
130 ExtentMap src_extent_map;
131 ExtentMap dst_extent_map;
132 bufferlist out_bl;
133 };
134
135 typedef std::list<CopyOp> CopyOps;
136 typedef std::pair<librados::snap_t, librados::snap_t> WriteReadSnapIds;
137 typedef std::map<librados::snap_t, uint8_t> SnapObjectStates;
138 typedef std::map<librados::snap_t, std::map<uint64_t, uint64_t>> SnapObjectSizes;
139
140 ImageCtxT *m_src_image_ctx;
141 ImageCtxT *m_dst_image_ctx;
142 CephContext *m_cct;
143 librados::snap_t m_src_snap_id_start;
144 librados::snap_t m_dst_snap_id_start;
145 SnapMap m_snap_map;
146 uint64_t m_dst_object_number;
147 bool m_flatten;
148 Context *m_on_finish;
149
150 decltype(m_src_image_ctx->data_ctx) m_src_io_ctx;
151 decltype(m_dst_image_ctx->data_ctx) m_dst_io_ctx;
152 std::string m_dst_oid;
153
154 std::set<uint64_t> m_src_objects;
155 uint64_t m_src_ono;
156 std::string m_src_oid;
157 SrcObjectExtents m_src_object_extents;
158 librados::snap_set_t m_snap_set;
159 int m_snap_ret = 0;
160 bool m_retry_missing_read = false;
161 librados::snap_set_t m_retry_snap_set;
162 bool m_read_whole_object = false;
163
164 std::map<WriteReadSnapIds, CopyOps> m_read_ops;
165 std::list<WriteReadSnapIds> m_read_snaps;
166 std::map<librados::snap_t, CopyOps> m_write_ops;
167 std::map<librados::snap_t, interval_set<uint64_t>> m_zero_interval;
168 std::map<librados::snap_t, interval_set<uint64_t>> m_dst_zero_interval;
169 std::map<librados::snap_t, uint8_t> m_dst_object_state;
170 std::map<librados::snap_t, bool> m_dst_object_may_exist;
171 bufferlist m_read_from_parent_data;
172
173 io::AsyncOperation* m_src_async_op = nullptr;
174
175 void send_list_snaps();
176 void handle_list_snaps(int r);
177
178 void send_read_object();
179 void handle_read_object(int r);
180
181 void send_read_from_parent();
182 void handle_read_from_parent(int r);
183
184 void send_write_object();
185 void handle_write_object(int r);
186
187 void send_update_object_map();
188 void handle_update_object_map(int r);
189
190 Context *start_lock_op(ceph::shared_mutex &owner_lock, int* r);
191
192 uint64_t src_to_dst_object_offset(uint64_t objectno, uint64_t offset);
193
194 void compute_src_object_extents();
195 void compute_read_ops();
196 void compute_read_from_parent_ops(io::Extents *image_extents);
197 void merge_write_ops();
198 void compute_zero_ops();
199
200 void compute_dst_object_may_exist();
201
202 void finish(int r);
203 };
204
205 } // namespace deep_copy
206 } // namespace librbd
207
208 extern template class librbd::deep_copy::ObjectCopyRequest<librbd::ImageCtx>;
209
210 #endif // CEPH_LIBRBD_DEEP_COPY_OBJECT_COPY_REQUEST_H