]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
2 | // vim: ts=8 sw=2 smarttab | |
3 | #ifndef CEPH_LIBRBD_OPERATION_RESIZE_REQUEST_H | |
4 | #define CEPH_LIBRBD_OPERATION_RESIZE_REQUEST_H | |
5 | ||
6 | #include "librbd/operation/Request.h" | |
7 | #include "include/xlist.h" | |
8 | ||
9 | namespace librbd | |
10 | { | |
11 | ||
12 | class ImageCtx; | |
13 | class ProgressContext; | |
14 | ||
15 | namespace operation { | |
16 | ||
17 | template <typename ImageCtxT = ImageCtx> | |
18 | class ResizeRequest : public Request<ImageCtxT> { | |
19 | public: | |
20 | static ResizeRequest *create(ImageCtxT &image_ctx, Context *on_finish, | |
21 | uint64_t new_size, bool allow_shrink, | |
22 | ProgressContext &prog_ctx, uint64_t journal_op_tid, | |
23 | bool disable_journal) { | |
24 | return new ResizeRequest(image_ctx, on_finish, new_size, allow_shrink, prog_ctx, | |
25 | journal_op_tid, disable_journal); | |
26 | } | |
27 | ||
28 | ResizeRequest(ImageCtxT &image_ctx, Context *on_finish, uint64_t new_size, | |
29 | bool allow_shrink, ProgressContext &prog_ctx, uint64_t journal_op_tid, | |
30 | bool disable_journal); | |
31 | ~ResizeRequest() override; | |
32 | ||
33 | inline bool shrinking() const { | |
34 | return (m_shrink_size_visible && m_new_size < m_original_size); | |
35 | } | |
36 | ||
37 | inline uint64_t get_image_size() const { | |
38 | return m_new_size; | |
39 | } | |
40 | ||
41 | void send() override; | |
42 | ||
43 | protected: | |
44 | void send_op() override; | |
45 | bool should_complete(int r) override { | |
46 | return true; | |
47 | } | |
48 | bool can_affect_io() const override { | |
49 | return true; | |
50 | } | |
51 | journal::Event create_event(uint64_t op_tid) const override { | |
52 | return journal::ResizeEvent(op_tid, m_new_size); | |
53 | } | |
54 | ||
55 | private: | |
56 | /** | |
57 | * Resize goes through the following state machine to resize the image | |
58 | * and update the object map: | |
59 | * | |
60 | * @verbatim | |
61 | * | |
62 | * <start> | |
63 | * | | |
64 | * v | |
65 | * STATE_PRE_BLOCK_WRITES | |
66 | * | | |
67 | * v | |
68 | * STATE_APPEND_OP_EVENT (skip if journaling | |
69 | * | disabled) | |
7c673cae FG |
70 | * | |
71 | * | (grow) | |
72 | * |\--------> STATE_GROW_OBJECT_MAP (skip if object map | |
73 | * | | disabled) | |
74 | * | v | |
7c673cae | 75 | * | STATE_UPDATE_HEADER ----------------------------\ |
494da23a TL |
76 | * | (unblock writes) | |
77 | * | | | |
78 | * | (unblock writes) | | |
7c673cae FG |
79 | * | | |
80 | * | (shrink) | | |
81 | * |\--------> STATE_FLUSH_CACHE | | |
82 | * | | | | |
83 | * | v | | |
84 | * | STATE_INVALIDATE_CACHE | | |
85 | * | | | | |
86 | * | v | | |
87 | * | STATE_TRIM_IMAGE | | |
88 | * | | | | |
89 | * | v | | |
90 | * | STATE_POST_BLOCK_WRITES | | |
91 | * | | | | |
92 | * | v | | |
93 | * | STATE_UPDATE_HEADER | | |
94 | * | | | | |
95 | * | v | | |
96 | * | STATE_SHRINK_OBJECT_MAP (skip if object map | | |
97 | * | | disabled) | | |
98 | * | | (unblock writes) | | |
99 | * | (no change) v | | |
100 | * \------------> <finish> <-----------------------------------/ | |
101 | * | |
102 | * @endverbatim | |
103 | * | |
104 | * The _OBJECT_MAP states are skipped if the object map isn't enabled. | |
105 | * The state machine will immediately transition to _FINISHED if there | |
106 | * are no objects to trim. | |
107 | */ | |
108 | ||
109 | uint64_t m_original_size; | |
110 | uint64_t m_new_size; | |
111 | bool m_allow_shrink = true; | |
112 | ProgressContext &m_prog_ctx; | |
113 | uint64_t m_new_parent_overlap; | |
114 | bool m_shrink_size_visible = false; | |
115 | bool m_disable_journal = false; | |
116 | ||
117 | typename xlist<ResizeRequest<ImageCtxT>*>::item m_xlist_item; | |
118 | ||
119 | void send_pre_block_writes(); | |
120 | Context *handle_pre_block_writes(int *result); | |
121 | ||
122 | Context *send_append_op_event(); | |
123 | Context *handle_append_op_event(int *result); | |
124 | ||
125 | void send_flush_cache(); | |
126 | Context *handle_flush_cache(int *result); | |
127 | ||
128 | void send_invalidate_cache(); | |
129 | Context *handle_invalidate_cache(int *result); | |
130 | ||
131 | void send_trim_image(); | |
132 | Context *handle_trim_image(int *result); | |
133 | ||
134 | Context *send_grow_object_map(); | |
135 | Context *handle_grow_object_map(int *result); | |
136 | ||
137 | Context *send_shrink_object_map(); | |
138 | Context *handle_shrink_object_map(int *result); | |
139 | ||
140 | void send_post_block_writes(); | |
141 | Context *handle_post_block_writes(int *result); | |
142 | ||
143 | void send_update_header(); | |
144 | Context *handle_update_header(int *result); | |
145 | ||
146 | void compute_parent_overlap(); | |
147 | void update_size_and_overlap(); | |
148 | ||
149 | }; | |
150 | ||
151 | } // namespace operation | |
152 | } // namespace librbd | |
153 | ||
154 | extern template class librbd::operation::ResizeRequest<librbd::ImageCtx>; | |
155 | ||
156 | #endif // CEPH_LIBRBD_OPERATION_RESIZE_REQUEST_H |