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_IO_COPYUP_REQUEST_H
5 #define CEPH_LIBRBD_IO_COPYUP_REQUEST_H
7 #include "include/int_types.h"
8 #include "include/buffer.h"
9 #include "include/interval_set.h"
10 #include "common/ceph_mutex.h"
11 #include "common/zipkin_trace.h"
12 #include "librbd/io/AsyncOperation.h"
13 #include "librbd/io/Types.h"
19 namespace ZTracer
{ struct Trace
; }
27 template <typename I
> class AbstractObjectWriteRequest
;
29 template <typename ImageCtxT
= librbd::ImageCtx
>
32 static CopyupRequest
* create(ImageCtxT
*ictx
, uint64_t objectno
,
33 Extents
&&image_extents
,
34 const ZTracer::Trace
&parent_trace
) {
35 return new CopyupRequest(ictx
, objectno
, std::move(image_extents
),
39 CopyupRequest(ImageCtxT
*ictx
, uint64_t objectno
, Extents
&&image_extents
,
40 const ZTracer::Trace
&parent_trace
);
43 void append_request(AbstractObjectWriteRequest
<ImageCtxT
> *req
,
44 const Extents
& object_extents
);
50 * Copyup requests go through the following state machine to read from the
51 * parent image, update the object map, and copyup the object:
58 * /---------/ \---------\
61 * READ_FROM_PARENT DEEP_COPY
63 * \---------\ /---------/
65 * v (skip if not needed)
68 * v (skip if not needed)
76 * The OBJECT_MAP state is skipped if the object map isn't enabled or if
77 * an object map update isn't required. The COPYUP state is skipped if
78 * no data was read from the parent *and* there are no additional ops.
81 typedef std::vector
<AbstractObjectWriteRequest
<ImageCtxT
> *> WriteRequests
;
83 ImageCtxT
*m_image_ctx
;
85 Extents m_image_extents
;
86 ZTracer::Trace m_trace
;
88 bool m_flatten
= false;
89 bool m_copyup_required
= true;
90 bool m_copyup_is_zero
= true;
91 bool m_deep_copied
= false;
93 Extents m_copyup_extent_map
;
94 ceph::bufferlist m_copyup_data
;
96 AsyncOperation m_async_op
;
98 std::vector
<uint64_t> m_snap_ids
;
99 bool m_first_snap_is_clean
= false;
101 ceph::mutex m_lock
= ceph::make_mutex("CopyupRequest", false);
102 WriteRequests m_pending_requests
;
103 unsigned m_pending_copyups
= 0;
104 int m_copyup_ret_val
= 0;
106 WriteRequests m_restart_requests
;
107 bool m_append_request_permitted
= true;
109 interval_set
<uint64_t> m_write_object_extents
;
111 void read_from_parent();
112 void handle_read_from_parent(int r
);
115 void handle_deep_copy(int r
);
117 void update_object_maps();
118 void handle_update_object_maps(int r
);
121 void handle_copyup(int r
);
124 void complete_requests(bool override_restart_retval
, int r
);
126 void disable_append_requests();
127 void remove_from_list();
129 bool is_copyup_required();
130 bool is_update_object_map_required(int r
);
131 bool is_deep_copy() const;
133 void compute_deep_copy_snap_ids();
134 void convert_copyup_extent_map();
135 int prepare_copyup_data();
139 } // namespace librbd
141 extern template class librbd::io::CopyupRequest
<librbd::ImageCtx
>;
143 #endif // CEPH_LIBRBD_IO_COPYUP_REQUEST_H