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