]> git.proxmox.com Git - ceph.git/blame - ceph/src/librbd/ImageState.h
bump version to 12.0.3-pve3
[ceph.git] / ceph / src / librbd / ImageState.h
CommitLineData
7c673cae
FG
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_IMAGE_STATE_H
5#define CEPH_LIBRBD_IMAGE_STATE_H
6
7#include "include/int_types.h"
8#include "common/Mutex.h"
9#include <list>
10#include <string>
11#include <utility>
12#include "cls/rbd/cls_rbd_types.h"
13
14class Context;
15class RWLock;
16
17namespace librbd {
18
19class ImageCtx;
20class ImageUpdateWatchers;
21class UpdateWatchCtx;
22
23template <typename ImageCtxT = ImageCtx>
24class ImageState {
25public:
26 ImageState(ImageCtxT *image_ctx);
27 ~ImageState();
28
29 int open(bool skip_open_parent);
30 void open(bool skip_open_parent, Context *on_finish);
31
32 int close();
33 void close(Context *on_finish);
34
35 void handle_update_notification();
36
37 bool is_refresh_required() const;
38
39 int refresh();
40 int refresh_if_required();
41 void refresh(Context *on_finish);
42
43 void snap_set(const cls::rbd::SnapshotNamespace &snap_namespace,
44 const std::string &snap_name,
45 Context *on_finish);
46
47 void prepare_lock(Context *on_ready);
48 void handle_prepare_lock_complete();
49
50 int register_update_watcher(UpdateWatchCtx *watcher, uint64_t *handle);
51 int unregister_update_watcher(uint64_t handle);
52 void flush_update_watchers(Context *on_finish);
53 void shut_down_update_watchers(Context *on_finish);
54
55private:
56 enum State {
57 STATE_UNINITIALIZED,
58 STATE_OPEN,
59 STATE_CLOSED,
60 STATE_OPENING,
61 STATE_CLOSING,
62 STATE_REFRESHING,
63 STATE_SETTING_SNAP,
64 STATE_PREPARING_LOCK
65 };
66
67 enum ActionType {
68 ACTION_TYPE_OPEN,
69 ACTION_TYPE_CLOSE,
70 ACTION_TYPE_REFRESH,
71 ACTION_TYPE_SET_SNAP,
72 ACTION_TYPE_LOCK
73 };
74
75 struct Action {
76 ActionType action_type;
77 uint64_t refresh_seq = 0;
78 cls::rbd::SnapshotNamespace snap_namespace;
79 std::string snap_name;
80 Context *on_ready = nullptr;
81
82 Action(ActionType action_type) : action_type(action_type) {
83 }
84 inline bool operator==(const Action &action) const {
85 if (action_type != action.action_type) {
86 return false;
87 }
88 switch (action_type) {
89 case ACTION_TYPE_REFRESH:
90 return (refresh_seq == action.refresh_seq);
91 case ACTION_TYPE_SET_SNAP:
92 return (snap_name == action.snap_name) && (snap_namespace == action.snap_namespace);
93 case ACTION_TYPE_LOCK:
94 return false;
95 default:
96 return true;
97 }
98 }
99 };
100
101 typedef std::list<Context *> Contexts;
102 typedef std::pair<Action, Contexts> ActionContexts;
103 typedef std::list<ActionContexts> ActionsContexts;
104
105 ImageCtxT *m_image_ctx;
106 State m_state;
107
108 mutable Mutex m_lock;
109 ActionsContexts m_actions_contexts;
110
111 uint64_t m_last_refresh;
112 uint64_t m_refresh_seq;
113
114 ImageUpdateWatchers *m_update_watchers;
115
116 bool m_skip_open_parent_image;
117
118 bool is_transition_state() const;
119 bool is_closed() const;
120
121 const Action *find_pending_refresh() const;
122
123 void append_context(const Action &action, Context *context);
124 void execute_next_action_unlock();
125 void execute_action_unlock(const Action &action, Context *context);
126 void complete_action_unlock(State next_state, int r);
127
128 void send_open_unlock();
129 void handle_open(int r);
130
131 void send_close_unlock();
132 void handle_close(int r);
133
134 void send_refresh_unlock();
135 void handle_refresh(int r);
136
137 void send_set_snap_unlock();
138 void handle_set_snap(int r);
139
140 void send_prepare_lock_unlock();
141
142};
143
144} // namespace librbd
145
146extern template class librbd::ImageState<librbd::ImageCtx>;
147
148#endif // CEPH_LIBRBD_IMAGE_STATE_H