]> git.proxmox.com Git - ceph.git/blob - ceph/src/librbd/io/CopyupRequest.h
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / librbd / io / CopyupRequest.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_IO_COPYUP_REQUEST_H
5 #define CEPH_LIBRBD_IO_COPYUP_REQUEST_H
6
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"
14
15 #include <map>
16 #include <string>
17 #include <vector>
18
19 namespace ZTracer { struct Trace; }
20
21 namespace librbd {
22
23 struct ImageCtx;
24
25 namespace io {
26
27 template <typename I> class AbstractObjectWriteRequest;
28
29 template <typename ImageCtxT = librbd::ImageCtx>
30 class CopyupRequest {
31 public:
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),
36 parent_trace);
37 }
38
39 CopyupRequest(ImageCtxT *ictx, uint64_t objectno, Extents &&image_extents,
40 const ZTracer::Trace &parent_trace);
41 ~CopyupRequest();
42
43 void append_request(AbstractObjectWriteRequest<ImageCtxT> *req,
44 const Extents& object_extents);
45
46 void send();
47
48 private:
49 /**
50 * Copyup requests go through the following state machine to read from the
51 * parent image, update the object map, and copyup the object:
52 *
53 *
54 * @verbatim
55 *
56 * <start>
57 * |
58 * /---------/ \---------\
59 * | |
60 * v v
61 * READ_FROM_PARENT DEEP_COPY
62 * | |
63 * \---------\ /---------/
64 * |
65 * v (skip if not needed)
66 * UPDATE_OBJECT_MAPS
67 * |
68 * v (skip if not needed)
69 * COPYUP
70 * |
71 * v
72 * <finish>
73 *
74 * @endverbatim
75 *
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.
79 */
80
81 typedef std::vector<AbstractObjectWriteRequest<ImageCtxT> *> WriteRequests;
82
83 ImageCtxT *m_image_ctx;
84 uint64_t m_object_no;
85 Extents m_image_extents;
86 ZTracer::Trace m_trace;
87
88 bool m_flatten = false;
89 bool m_copyup_required = true;
90 bool m_copyup_is_zero = true;
91 bool m_deep_copied = false;
92
93 Extents m_copyup_extent_map;
94 ceph::bufferlist m_copyup_data;
95
96 AsyncOperation m_async_op;
97
98 std::vector<uint64_t> m_snap_ids;
99 bool m_first_snap_is_clean = false;
100
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;
105
106 WriteRequests m_restart_requests;
107 bool m_append_request_permitted = true;
108
109 interval_set<uint64_t> m_write_object_extents;
110
111 void read_from_parent();
112 void handle_read_from_parent(int r);
113
114 void deep_copy();
115 void handle_deep_copy(int r);
116
117 void update_object_maps();
118 void handle_update_object_maps(int r);
119
120 void copyup();
121 void handle_copyup(int r);
122
123 void finish(int r);
124 void complete_requests(bool override_restart_retval, int r);
125
126 void disable_append_requests();
127 void remove_from_list();
128
129 bool is_copyup_required();
130 bool is_update_object_map_required(int r);
131 bool is_deep_copy() const;
132
133 void compute_deep_copy_snap_ids();
134 void convert_copyup_extent_map();
135 int prepare_copyup_data();
136 };
137
138 } // namespace io
139 } // namespace librbd
140
141 extern template class librbd::io::CopyupRequest<librbd::ImageCtx>;
142
143 #endif // CEPH_LIBRBD_IO_COPYUP_REQUEST_H