xref: /linux/drivers/md/dm-vdo/admin-state.h (revision 79790b6818e96c58fe2bffee1b418c16e64e7b80)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Copyright 2023 Red Hat
4  */
5 
6 #ifndef VDO_ADMIN_STATE_H
7 #define VDO_ADMIN_STATE_H
8 
9 #include "completion.h"
10 #include "types.h"
11 
12 struct admin_state_code {
13 	const char *name;
14 	/* Normal operation, data_vios may be active */
15 	bool normal;
16 	/* I/O is draining, new requests should not start */
17 	bool draining;
18 	/* This is a startup time operation */
19 	bool loading;
20 	/* The next state will be quiescent */
21 	bool quiescing;
22 	/* The VDO is quiescent, there should be no I/O */
23 	bool quiescent;
24 	/* Whether an operation is in progress and so no other operation may be started */
25 	bool operating;
26 };
27 
28 extern const struct admin_state_code *VDO_ADMIN_STATE_NORMAL_OPERATION;
29 extern const struct admin_state_code *VDO_ADMIN_STATE_OPERATING;
30 extern const struct admin_state_code *VDO_ADMIN_STATE_FORMATTING;
31 extern const struct admin_state_code *VDO_ADMIN_STATE_PRE_LOADING;
32 extern const struct admin_state_code *VDO_ADMIN_STATE_PRE_LOADED;
33 extern const struct admin_state_code *VDO_ADMIN_STATE_LOADING;
34 extern const struct admin_state_code *VDO_ADMIN_STATE_LOADING_FOR_RECOVERY;
35 extern const struct admin_state_code *VDO_ADMIN_STATE_LOADING_FOR_REBUILD;
36 extern const struct admin_state_code *VDO_ADMIN_STATE_WAITING_FOR_RECOVERY;
37 extern const struct admin_state_code *VDO_ADMIN_STATE_NEW;
38 extern const struct admin_state_code *VDO_ADMIN_STATE_INITIALIZED;
39 extern const struct admin_state_code *VDO_ADMIN_STATE_RECOVERING;
40 extern const struct admin_state_code *VDO_ADMIN_STATE_REBUILDING;
41 extern const struct admin_state_code *VDO_ADMIN_STATE_SAVING;
42 extern const struct admin_state_code *VDO_ADMIN_STATE_SAVED;
43 extern const struct admin_state_code *VDO_ADMIN_STATE_SCRUBBING;
44 extern const struct admin_state_code *VDO_ADMIN_STATE_SAVE_FOR_SCRUBBING;
45 extern const struct admin_state_code *VDO_ADMIN_STATE_STOPPING;
46 extern const struct admin_state_code *VDO_ADMIN_STATE_STOPPED;
47 extern const struct admin_state_code *VDO_ADMIN_STATE_SUSPENDING;
48 extern const struct admin_state_code *VDO_ADMIN_STATE_SUSPENDED;
49 extern const struct admin_state_code *VDO_ADMIN_STATE_SUSPENDED_OPERATION;
50 extern const struct admin_state_code *VDO_ADMIN_STATE_RESUMING;
51 
52 struct admin_state {
53 	const struct admin_state_code *current_state;
54 	/* The next administrative state (when the current operation finishes) */
55 	const struct admin_state_code *next_state;
56 	/* A completion waiting on a state change */
57 	struct vdo_completion *waiter;
58 	/* Whether an operation is being initiated */
59 	bool starting;
60 	/* Whether an operation has completed in the initiator */
61 	bool complete;
62 };
63 
64 /**
65  * typedef vdo_admin_initiator_fn - A method to be called once an admin operation may be initiated.
66  */
67 typedef void (*vdo_admin_initiator_fn)(struct admin_state *state);
68 
69 static inline const struct admin_state_code * __must_check
vdo_get_admin_state_code(const struct admin_state * state)70 vdo_get_admin_state_code(const struct admin_state *state)
71 {
72 	return READ_ONCE(state->current_state);
73 }
74 
75 /**
76  * vdo_set_admin_state_code() - Set the current admin state code.
77  *
78  * This function should be used primarily for initialization and by adminState internals. Most uses
79  * should go through the operation interfaces.
80  */
vdo_set_admin_state_code(struct admin_state * state,const struct admin_state_code * code)81 static inline void vdo_set_admin_state_code(struct admin_state *state,
82 					    const struct admin_state_code *code)
83 {
84 	WRITE_ONCE(state->current_state, code);
85 }
86 
vdo_is_state_normal(const struct admin_state * state)87 static inline bool __must_check vdo_is_state_normal(const struct admin_state *state)
88 {
89 	return vdo_get_admin_state_code(state)->normal;
90 }
91 
vdo_is_state_suspending(const struct admin_state * state)92 static inline bool __must_check vdo_is_state_suspending(const struct admin_state *state)
93 {
94 	return (vdo_get_admin_state_code(state) == VDO_ADMIN_STATE_SUSPENDING);
95 }
96 
vdo_is_state_saving(const struct admin_state * state)97 static inline bool __must_check vdo_is_state_saving(const struct admin_state *state)
98 {
99 	return (vdo_get_admin_state_code(state) == VDO_ADMIN_STATE_SAVING);
100 }
101 
vdo_is_state_saved(const struct admin_state * state)102 static inline bool __must_check vdo_is_state_saved(const struct admin_state *state)
103 {
104 	return (vdo_get_admin_state_code(state) == VDO_ADMIN_STATE_SAVED);
105 }
106 
vdo_is_state_draining(const struct admin_state * state)107 static inline bool __must_check vdo_is_state_draining(const struct admin_state *state)
108 {
109 	return vdo_get_admin_state_code(state)->draining;
110 }
111 
vdo_is_state_loading(const struct admin_state * state)112 static inline bool __must_check vdo_is_state_loading(const struct admin_state *state)
113 {
114 	return vdo_get_admin_state_code(state)->loading;
115 }
116 
vdo_is_state_resuming(const struct admin_state * state)117 static inline bool __must_check vdo_is_state_resuming(const struct admin_state *state)
118 {
119 	return (vdo_get_admin_state_code(state) == VDO_ADMIN_STATE_RESUMING);
120 }
121 
vdo_is_state_clean_load(const struct admin_state * state)122 static inline bool __must_check vdo_is_state_clean_load(const struct admin_state *state)
123 {
124 	const struct admin_state_code *code = vdo_get_admin_state_code(state);
125 
126 	return ((code == VDO_ADMIN_STATE_FORMATTING) || (code == VDO_ADMIN_STATE_LOADING));
127 }
128 
vdo_is_state_quiescing(const struct admin_state * state)129 static inline bool __must_check vdo_is_state_quiescing(const struct admin_state *state)
130 {
131 	return vdo_get_admin_state_code(state)->quiescing;
132 }
133 
vdo_is_state_quiescent(const struct admin_state * state)134 static inline bool __must_check vdo_is_state_quiescent(const struct admin_state *state)
135 {
136 	return vdo_get_admin_state_code(state)->quiescent;
137 }
138 
139 bool __must_check vdo_assert_load_operation(const struct admin_state_code *operation,
140 					    struct vdo_completion *waiter);
141 
142 bool vdo_start_loading(struct admin_state *state,
143 		       const struct admin_state_code *operation,
144 		       struct vdo_completion *waiter, vdo_admin_initiator_fn initiator);
145 
146 bool vdo_finish_loading(struct admin_state *state);
147 
148 bool vdo_finish_loading_with_result(struct admin_state *state, int result);
149 
150 bool vdo_start_resuming(struct admin_state *state,
151 			const struct admin_state_code *operation,
152 			struct vdo_completion *waiter, vdo_admin_initiator_fn initiator);
153 
154 bool vdo_finish_resuming(struct admin_state *state);
155 
156 bool vdo_finish_resuming_with_result(struct admin_state *state, int result);
157 
158 int vdo_resume_if_quiescent(struct admin_state *state);
159 
160 bool vdo_start_draining(struct admin_state *state,
161 			const struct admin_state_code *operation,
162 			struct vdo_completion *waiter, vdo_admin_initiator_fn initiator);
163 
164 bool vdo_finish_draining(struct admin_state *state);
165 
166 bool vdo_finish_draining_with_result(struct admin_state *state, int result);
167 
168 int vdo_start_operation(struct admin_state *state,
169 			const struct admin_state_code *operation);
170 
171 int vdo_start_operation_with_waiter(struct admin_state *state,
172 				    const struct admin_state_code *operation,
173 				    struct vdo_completion *waiter,
174 				    vdo_admin_initiator_fn initiator);
175 
176 bool vdo_finish_operation(struct admin_state *state, int result);
177 
178 #endif /* VDO_ADMIN_STATE_H */
179