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 12struct 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 28extern const struct admin_state_code *VDO_ADMIN_STATE_NORMAL_OPERATION; 29extern const struct admin_state_code *VDO_ADMIN_STATE_OPERATING; 30extern const struct admin_state_code *VDO_ADMIN_STATE_FORMATTING; 31extern const struct admin_state_code *VDO_ADMIN_STATE_PRE_LOADING; 32extern const struct admin_state_code *VDO_ADMIN_STATE_PRE_LOADED; 33extern const struct admin_state_code *VDO_ADMIN_STATE_LOADING; 34extern const struct admin_state_code *VDO_ADMIN_STATE_LOADING_FOR_RECOVERY; 35extern const struct admin_state_code *VDO_ADMIN_STATE_LOADING_FOR_REBUILD; 36extern const struct admin_state_code *VDO_ADMIN_STATE_WAITING_FOR_RECOVERY; 37extern const struct admin_state_code *VDO_ADMIN_STATE_NEW; 38extern const struct admin_state_code *VDO_ADMIN_STATE_INITIALIZED; 39extern const struct admin_state_code *VDO_ADMIN_STATE_RECOVERING; 40extern const struct admin_state_code *VDO_ADMIN_STATE_REBUILDING; 41extern const struct admin_state_code *VDO_ADMIN_STATE_SAVING; 42extern const struct admin_state_code *VDO_ADMIN_STATE_SAVED; 43extern const struct admin_state_code *VDO_ADMIN_STATE_SCRUBBING; 44extern const struct admin_state_code *VDO_ADMIN_STATE_SAVE_FOR_SCRUBBING; 45extern const struct admin_state_code *VDO_ADMIN_STATE_STOPPING; 46extern const struct admin_state_code *VDO_ADMIN_STATE_STOPPED; 47extern const struct admin_state_code *VDO_ADMIN_STATE_SUSPENDING; 48extern const struct admin_state_code *VDO_ADMIN_STATE_SUSPENDED; 49extern const struct admin_state_code *VDO_ADMIN_STATE_SUSPENDED_OPERATION; 50extern const struct admin_state_code *VDO_ADMIN_STATE_RESUMING; 51 52struct 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 */ 67typedef void (*vdo_admin_initiator_fn)(struct admin_state *state); 68 69static inline const struct admin_state_code * __must_check 70vdo_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 */ 81static 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 87static 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 92static 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 97static 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 102static 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 107static 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 112static 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 117static 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 122static 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 129static 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 134static 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 139bool __must_check vdo_assert_load_operation(const struct admin_state_code *operation, 140 struct vdo_completion *waiter); 141 142bool 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 146bool vdo_finish_loading(struct admin_state *state); 147 148bool vdo_finish_loading_with_result(struct admin_state *state, int result); 149 150bool 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 154bool vdo_finish_resuming(struct admin_state *state); 155 156bool vdo_finish_resuming_with_result(struct admin_state *state, int result); 157 158int vdo_resume_if_quiescent(struct admin_state *state); 159 160bool 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 164bool vdo_finish_draining(struct admin_state *state); 165 166bool vdo_finish_draining_with_result(struct admin_state *state, int result); 167 168int vdo_start_operation(struct admin_state *state, 169 const struct admin_state_code *operation); 170 171int 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 176bool vdo_finish_operation(struct admin_state *state, int result); 177 178#endif /* VDO_ADMIN_STATE_H */ 179