179 lines · c
1/* SPDX-License-Identifier: GPL-2.0-only */2/*3 * Copyright 2023 Red Hat4 */5 6#ifndef VDO_ADMIN_STATE_H7#define VDO_ADMIN_STATE_H8 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_check70vdo_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 uses79 * 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