1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #ifndef CEPH_LIBRBD_DEEP_COPY_OBJECT_COPY_REQUEST_H
5 #define CEPH_LIBRBD_DEEP_COPY_OBJECT_COPY_REQUEST_H
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"
23 namespace io
{ class AsyncOperation
; }
29 template <typename ImageCtxT
= librbd::ImageCtx
>
30 class ObjectCopyRequest
{
32 static ObjectCopyRequest
* create(ImageCtxT
*src_image_ctx
,
33 ImageCtxT
*dst_image_ctx
,
34 librados::snap_t src_snap_id_start
,
35 librados::snap_t dst_snap_id_start
,
36 const SnapMap
&snap_map
,
37 uint64_t object_number
, bool flatten
,
38 Handler
* handler
, Context
*on_finish
) {
39 return new ObjectCopyRequest(src_image_ctx
, dst_image_ctx
,
40 src_snap_id_start
, dst_snap_id_start
, snap_map
,
41 object_number
, flatten
, handler
, on_finish
);
44 ObjectCopyRequest(ImageCtxT
*src_image_ctx
, ImageCtxT
*dst_image_ctx
,
45 librados::snap_t src_snap_id_start
,
46 librados::snap_t dst_snap_id_start
, const SnapMap
&snap_map
,
47 uint64_t object_number
, bool flatten
, Handler
* handler
,
53 inline librados::IoCtx
&get_src_io_ctx() {
56 inline librados::IoCtx
&get_dst_io_ctx() {
65 * | /----------------------\
67 * v v | (repeat for each src object)
68 * LIST_SNAPS < * * * |
69 * | * (-ENOENT and snap set stale)
72 * | * | | (repeat for each snapshot)
74 * READ_OBJECT ---------/ |
76 * | \----------------------/
78 * READ_FROM_PARENT (skip if not needed)
81 * | | | (repeat for each snapshot)
83 * WRITE_OBJECT --------/
86 * | | | (repeat for each snapshot)
88 * UPDATE_OBJECT_MAP ---/ (skip if object
96 struct SrcObjectExtent
{
97 uint64_t object_no
= 0;
104 SrcObjectExtent(uint64_t object_no
, uint64_t offset
, uint64_t length
)
105 : object_no(object_no
), offset(offset
), length(length
) {
109 typedef std::map
<uint64_t, SrcObjectExtent
> SrcObjectExtents
;
116 COPY_OP_TYPE_REMOVE_TRUNC
,
119 typedef std::map
<uint64_t, uint64_t> ExtentMap
;
122 CopyOp(CopyOpType type
, uint64_t src_offset
, uint64_t dst_offset
,
124 : type(type
), src_offset(src_offset
), dst_offset(dst_offset
),
133 ExtentMap src_extent_map
;
134 ExtentMap dst_extent_map
;
138 typedef std::list
<CopyOp
> CopyOps
;
139 typedef std::pair
<librados::snap_t
, librados::snap_t
> WriteReadSnapIds
;
140 typedef std::map
<librados::snap_t
, uint8_t> SnapObjectStates
;
141 typedef std::map
<librados::snap_t
, std::map
<uint64_t, uint64_t>> SnapObjectSizes
;
143 ImageCtxT
*m_src_image_ctx
;
144 ImageCtxT
*m_dst_image_ctx
;
146 librados::snap_t m_src_snap_id_start
;
147 librados::snap_t m_dst_snap_id_start
;
149 uint64_t m_dst_object_number
;
152 Context
*m_on_finish
;
154 decltype(m_src_image_ctx
->data_ctx
) m_src_io_ctx
;
155 decltype(m_dst_image_ctx
->data_ctx
) m_dst_io_ctx
;
156 std::string m_dst_oid
;
158 std::set
<uint64_t> m_src_objects
;
160 std::string m_src_oid
;
161 SrcObjectExtents m_src_object_extents
;
162 librados::snap_set_t m_snap_set
;
164 bool m_retry_missing_read
= false;
165 librados::snap_set_t m_retry_snap_set
;
166 bool m_read_whole_object
= false;
168 std::map
<WriteReadSnapIds
, CopyOps
> m_read_ops
;
169 std::list
<WriteReadSnapIds
> m_read_snaps
;
170 std::map
<librados::snap_t
, CopyOps
> m_write_ops
;
171 std::map
<librados::snap_t
, interval_set
<uint64_t>> m_zero_interval
;
172 std::map
<librados::snap_t
, interval_set
<uint64_t>> m_dst_zero_interval
;
173 std::map
<librados::snap_t
, uint8_t> m_dst_object_state
;
174 std::map
<librados::snap_t
, bool> m_dst_object_may_exist
;
175 bufferlist m_read_from_parent_data
;
177 io::AsyncOperation
* m_src_async_op
= nullptr;
179 void send_list_snaps();
180 void handle_list_snaps(int r
);
182 void send_read_object();
183 void handle_read_object(int r
);
185 void send_read_from_parent();
186 void handle_read_from_parent(int r
);
188 void send_write_object();
189 void handle_write_object(int r
);
191 void send_update_object_map();
192 void handle_update_object_map(int r
);
194 Context
*start_lock_op(ceph::shared_mutex
&owner_lock
, int* r
);
196 uint64_t src_to_dst_object_offset(uint64_t objectno
, uint64_t offset
);
198 void compute_src_object_extents();
199 void compute_read_ops();
200 void compute_read_from_parent_ops(io::Extents
*image_extents
);
201 void merge_write_ops();
202 void compute_zero_ops();
204 void compute_dst_object_may_exist();
209 } // namespace deep_copy
210 } // namespace librbd
212 extern template class librbd::deep_copy::ObjectCopyRequest
<librbd::ImageCtx
>;
214 #endif // CEPH_LIBRBD_DEEP_COPY_OBJECT_COPY_REQUEST_H