Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / librbd / journal / Replay.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_JOURNAL_REPLAY_H
5 #define CEPH_LIBRBD_JOURNAL_REPLAY_H
6
7 #include "include/int_types.h"
8 #include "include/buffer_fwd.h"
9 #include "include/Context.h"
10 #include "common/Mutex.h"
11 #include "librbd/io/Types.h"
12 #include "librbd/journal/Types.h"
13 #include <boost/variant.hpp>
14 #include <list>
15 #include <unordered_set>
16 #include <unordered_map>
17
18 namespace librbd {
19
20 class ImageCtx;
21 namespace io { struct AioCompletion; }
22
23 namespace journal {
24
25 template <typename ImageCtxT = ImageCtx>
26 class Replay {
27 public:
28   static Replay *create(ImageCtxT &image_ctx) {
29     return new Replay(image_ctx);
30   }
31
32   Replay(ImageCtxT &image_ctx);
33   ~Replay();
34
35   int decode(bufferlist::iterator *it, EventEntry *event_entry);
36   void process(const EventEntry &event_entry,
37                Context *on_ready, Context *on_safe);
38
39   void shut_down(bool cancel_ops, Context *on_finish);
40   void flush(Context *on_finish);
41
42   void replay_op_ready(uint64_t op_tid, Context *on_resume);
43
44 private:
45   typedef std::unordered_set<int> ReturnValues;
46
47   struct OpEvent {
48     bool op_in_progress = false;
49     bool finish_on_ready = false;
50     Context *on_op_finish_event = nullptr;
51     Context *on_start_ready = nullptr;
52     Context *on_start_safe = nullptr;
53     Context *on_finish_ready = nullptr;
54     Context *on_finish_safe = nullptr;
55     Context *on_op_complete = nullptr;
56     ReturnValues op_finish_error_codes;
57     ReturnValues ignore_error_codes;
58   };
59
60   typedef std::list<uint64_t> OpTids;
61   typedef std::list<Context *> Contexts;
62   typedef std::unordered_set<Context *> ContextSet;
63   typedef std::unordered_map<uint64_t, OpEvent> OpEvents;
64
65   struct C_OpOnComplete : public Context {
66     Replay *replay;
67     uint64_t op_tid;
68     C_OpOnComplete(Replay *replay, uint64_t op_tid)
69       : replay(replay), op_tid(op_tid) {
70     }
71     void finish(int r) override {
72       replay->handle_op_complete(op_tid, r);
73     }
74   };
75
76   struct C_AioModifyComplete : public Context {
77     Replay *replay;
78     Context *on_ready;
79     Context *on_safe;
80     std::set<int> filters;
81     C_AioModifyComplete(Replay *replay, Context *on_ready,
82                         Context *on_safe, std::set<int> &&filters)
83       : replay(replay), on_ready(on_ready), on_safe(on_safe),
84         filters(std::move(filters)) {
85     }
86     void finish(int r) override {
87       replay->handle_aio_modify_complete(on_ready, on_safe, r, filters);
88     }
89   };
90
91   struct C_AioFlushComplete : public Context {
92     Replay *replay;
93     Context *on_flush_safe;
94     Contexts on_safe_ctxs;
95     C_AioFlushComplete(Replay *replay, Context *on_flush_safe,
96                        Contexts &&on_safe_ctxs)
97       : replay(replay), on_flush_safe(on_flush_safe),
98         on_safe_ctxs(on_safe_ctxs) {
99     }
100     void finish(int r) override {
101       replay->handle_aio_flush_complete(on_flush_safe, on_safe_ctxs, r);
102     }
103   };
104
105   struct EventVisitor : public boost::static_visitor<void> {
106     Replay *replay;
107     Context *on_ready;
108     Context *on_safe;
109
110     EventVisitor(Replay *_replay, Context *_on_ready, Context *_on_safe)
111       : replay(_replay), on_ready(_on_ready), on_safe(_on_safe) {
112     }
113
114     template <typename Event>
115     inline void operator()(const Event &event) const {
116       replay->handle_event(event, on_ready, on_safe);
117     }
118   };
119
120   ImageCtxT &m_image_ctx;
121
122   Mutex m_lock;
123
124   uint64_t m_in_flight_aio_flush = 0;
125   uint64_t m_in_flight_aio_modify = 0;
126   Contexts m_aio_modify_unsafe_contexts;
127   ContextSet m_aio_modify_safe_contexts;
128
129   OpEvents m_op_events;
130   uint64_t m_in_flight_op_events = 0;
131
132   bool m_shut_down = false;
133   Context *m_flush_ctx = nullptr;
134   Context *m_on_aio_ready = nullptr;
135
136   void handle_event(const AioDiscardEvent &event, Context *on_ready,
137                     Context *on_safe);
138   void handle_event(const AioWriteEvent &event, Context *on_ready,
139                     Context *on_safe);
140   void handle_event(const AioWriteSameEvent &event, Context *on_ready,
141                     Context *on_safe);
142   void handle_event(const AioCompareAndWriteEvent &event, Context *on_ready,
143                     Context *on_safe);
144   void handle_event(const AioFlushEvent &event, Context *on_ready,
145                     Context *on_safe);
146   void handle_event(const OpFinishEvent &event, Context *on_ready,
147                     Context *on_safe);
148   void handle_event(const SnapCreateEvent &event, Context *on_ready,
149                     Context *on_safe);
150   void handle_event(const SnapRemoveEvent &event, Context *on_ready,
151                     Context *on_safe);
152   void handle_event(const SnapRenameEvent &event, Context *on_ready,
153                     Context *on_safe);
154   void handle_event(const SnapProtectEvent &event, Context *on_ready,
155                     Context *on_safe);
156   void handle_event(const SnapUnprotectEvent &event, Context *on_ready,
157                     Context *on_safe);
158   void handle_event(const SnapRollbackEvent &event, Context *on_ready,
159                     Context *on_safe);
160   void handle_event(const RenameEvent &event, Context *on_ready,
161                     Context *on_safe);
162   void handle_event(const ResizeEvent &event, Context *on_ready,
163                     Context *on_safe);
164   void handle_event(const FlattenEvent &event, Context *on_ready,
165                     Context *on_safe);
166   void handle_event(const DemotePromoteEvent &event, Context *on_ready,
167                     Context *on_safe);
168   void handle_event(const SnapLimitEvent &event, Context *on_ready,
169                     Context *on_safe);
170   void handle_event(const UpdateFeaturesEvent &event, Context *on_ready,
171                     Context *on_safe);
172   void handle_event(const MetadataSetEvent &event, Context *on_ready,
173                     Context *on_safe);
174   void handle_event(const MetadataRemoveEvent &event, Context *on_ready,
175                     Context *on_safe);
176   void handle_event(const UnknownEvent &event, Context *on_ready,
177                     Context *on_safe);
178
179   void handle_aio_modify_complete(Context *on_ready, Context *on_safe,
180                                   int r, std::set<int> &filters);
181   void handle_aio_flush_complete(Context *on_flush_safe, Contexts &on_safe_ctxs,
182                                  int r);
183
184   Context *create_op_context_callback(uint64_t op_tid, Context *on_ready,
185                                       Context *on_safe, OpEvent **op_event);
186   void handle_op_complete(uint64_t op_tid, int r);
187
188   io::AioCompletion *create_aio_modify_completion(Context *on_ready,
189                                                   Context *on_safe,
190                                                   io::aio_type_t aio_type,
191                                                   bool *flush_required,
192                                                   std::set<int> &&filters);
193   io::AioCompletion *create_aio_flush_completion(Context *on_safe);
194   void handle_aio_completion(io::AioCompletion *aio_comp);
195
196 };
197
198 } // namespace journal
199 } // namespace librbd
200
201 extern template class librbd::journal::Replay<librbd::ImageCtx>;
202
203 #endif // CEPH_LIBRBD_JOURNAL_REPLAY_H