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 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 */ 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 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 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 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 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 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 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 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 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 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 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