179 lines
6.3 KiB
C
179 lines
6.3 KiB
C
/* SPDX-License-Identifier: GPL-2.0-only */
|
|
/*
|
|
* Copyright 2023 Red Hat
|
|
*/
|
|
|
|
#ifndef VDO_ADMIN_STATE_H
|
|
#define VDO_ADMIN_STATE_H
|
|
|
|
#include "completion.h"
|
|
#include "types.h"
|
|
|
|
struct admin_state_code {
|
|
const char *name;
|
|
/* Normal operation, data_vios may be active */
|
|
bool normal;
|
|
/* I/O is draining, new requests should not start */
|
|
bool draining;
|
|
/* This is a startup time operation */
|
|
bool loading;
|
|
/* The next state will be quiescent */
|
|
bool quiescing;
|
|
/* The VDO is quiescent, there should be no I/O */
|
|
bool quiescent;
|
|
/* Whether an operation is in progress and so no other operation may be started */
|
|
bool operating;
|
|
};
|
|
|
|
extern const struct admin_state_code *VDO_ADMIN_STATE_NORMAL_OPERATION;
|
|
extern const struct admin_state_code *VDO_ADMIN_STATE_OPERATING;
|
|
extern const struct admin_state_code *VDO_ADMIN_STATE_FORMATTING;
|
|
extern const struct admin_state_code *VDO_ADMIN_STATE_PRE_LOADING;
|
|
extern const struct admin_state_code *VDO_ADMIN_STATE_PRE_LOADED;
|
|
extern const struct admin_state_code *VDO_ADMIN_STATE_LOADING;
|
|
extern const struct admin_state_code *VDO_ADMIN_STATE_LOADING_FOR_RECOVERY;
|
|
extern const struct admin_state_code *VDO_ADMIN_STATE_LOADING_FOR_REBUILD;
|
|
extern const struct admin_state_code *VDO_ADMIN_STATE_WAITING_FOR_RECOVERY;
|
|
extern const struct admin_state_code *VDO_ADMIN_STATE_NEW;
|
|
extern const struct admin_state_code *VDO_ADMIN_STATE_INITIALIZED;
|
|
extern const struct admin_state_code *VDO_ADMIN_STATE_RECOVERING;
|
|
extern const struct admin_state_code *VDO_ADMIN_STATE_REBUILDING;
|
|
extern const struct admin_state_code *VDO_ADMIN_STATE_SAVING;
|
|
extern const struct admin_state_code *VDO_ADMIN_STATE_SAVED;
|
|
extern const struct admin_state_code *VDO_ADMIN_STATE_SCRUBBING;
|
|
extern const struct admin_state_code *VDO_ADMIN_STATE_SAVE_FOR_SCRUBBING;
|
|
extern const struct admin_state_code *VDO_ADMIN_STATE_STOPPING;
|
|
extern const struct admin_state_code *VDO_ADMIN_STATE_STOPPED;
|
|
extern const struct admin_state_code *VDO_ADMIN_STATE_SUSPENDING;
|
|
extern const struct admin_state_code *VDO_ADMIN_STATE_SUSPENDED;
|
|
extern const struct admin_state_code *VDO_ADMIN_STATE_SUSPENDED_OPERATION;
|
|
extern const struct admin_state_code *VDO_ADMIN_STATE_RESUMING;
|
|
|
|
struct admin_state {
|
|
const struct admin_state_code *current_state;
|
|
/* The next administrative state (when the current operation finishes) */
|
|
const struct admin_state_code *next_state;
|
|
/* A completion waiting on a state change */
|
|
struct vdo_completion *waiter;
|
|
/* Whether an operation is being initiated */
|
|
bool starting;
|
|
/* Whether an operation has completed in the initiator */
|
|
bool complete;
|
|
};
|
|
|
|
/**
|
|
* typedef vdo_admin_initiator_fn - A method to be called once an admin operation may be initiated.
|
|
*/
|
|
typedef void (*vdo_admin_initiator_fn)(struct admin_state *state);
|
|
|
|
static inline const struct admin_state_code * __must_check
|
|
vdo_get_admin_state_code(const struct admin_state *state)
|
|
{
|
|
return READ_ONCE(state->current_state);
|
|
}
|
|
|
|
/**
|
|
* vdo_set_admin_state_code() - Set the current admin state code.
|
|
*
|
|
* This function should be used primarily for initialization and by adminState internals. Most uses
|
|
* should go through the operation interfaces.
|
|
*/
|
|
static inline void vdo_set_admin_state_code(struct admin_state *state,
|
|
const struct admin_state_code *code)
|
|
{
|
|
WRITE_ONCE(state->current_state, code);
|
|
}
|
|
|
|
static inline bool __must_check vdo_is_state_normal(const struct admin_state *state)
|
|
{
|
|
return vdo_get_admin_state_code(state)->normal;
|
|
}
|
|
|
|
static inline bool __must_check vdo_is_state_suspending(const struct admin_state *state)
|
|
{
|
|
return (vdo_get_admin_state_code(state) == VDO_ADMIN_STATE_SUSPENDING);
|
|
}
|
|
|
|
static inline bool __must_check vdo_is_state_saving(const struct admin_state *state)
|
|
{
|
|
return (vdo_get_admin_state_code(state) == VDO_ADMIN_STATE_SAVING);
|
|
}
|
|
|
|
static inline bool __must_check vdo_is_state_saved(const struct admin_state *state)
|
|
{
|
|
return (vdo_get_admin_state_code(state) == VDO_ADMIN_STATE_SAVED);
|
|
}
|
|
|
|
static inline bool __must_check vdo_is_state_draining(const struct admin_state *state)
|
|
{
|
|
return vdo_get_admin_state_code(state)->draining;
|
|
}
|
|
|
|
static inline bool __must_check vdo_is_state_loading(const struct admin_state *state)
|
|
{
|
|
return vdo_get_admin_state_code(state)->loading;
|
|
}
|
|
|
|
static inline bool __must_check vdo_is_state_resuming(const struct admin_state *state)
|
|
{
|
|
return (vdo_get_admin_state_code(state) == VDO_ADMIN_STATE_RESUMING);
|
|
}
|
|
|
|
static inline bool __must_check vdo_is_state_clean_load(const struct admin_state *state)
|
|
{
|
|
const struct admin_state_code *code = vdo_get_admin_state_code(state);
|
|
|
|
return ((code == VDO_ADMIN_STATE_FORMATTING) || (code == VDO_ADMIN_STATE_LOADING));
|
|
}
|
|
|
|
static inline bool __must_check vdo_is_state_quiescing(const struct admin_state *state)
|
|
{
|
|
return vdo_get_admin_state_code(state)->quiescing;
|
|
}
|
|
|
|
static inline bool __must_check vdo_is_state_quiescent(const struct admin_state *state)
|
|
{
|
|
return vdo_get_admin_state_code(state)->quiescent;
|
|
}
|
|
|
|
bool __must_check vdo_assert_load_operation(const struct admin_state_code *operation,
|
|
struct vdo_completion *waiter);
|
|
|
|
bool vdo_start_loading(struct admin_state *state,
|
|
const struct admin_state_code *operation,
|
|
struct vdo_completion *waiter, vdo_admin_initiator_fn initiator);
|
|
|
|
bool vdo_finish_loading(struct admin_state *state);
|
|
|
|
bool vdo_finish_loading_with_result(struct admin_state *state, int result);
|
|
|
|
bool vdo_start_resuming(struct admin_state *state,
|
|
const struct admin_state_code *operation,
|
|
struct vdo_completion *waiter, vdo_admin_initiator_fn initiator);
|
|
|
|
bool vdo_finish_resuming(struct admin_state *state);
|
|
|
|
bool vdo_finish_resuming_with_result(struct admin_state *state, int result);
|
|
|
|
int vdo_resume_if_quiescent(struct admin_state *state);
|
|
|
|
bool vdo_start_draining(struct admin_state *state,
|
|
const struct admin_state_code *operation,
|
|
struct vdo_completion *waiter, vdo_admin_initiator_fn initiator);
|
|
|
|
bool vdo_finish_draining(struct admin_state *state);
|
|
|
|
bool vdo_finish_draining_with_result(struct admin_state *state, int result);
|
|
|
|
int vdo_start_operation(struct admin_state *state,
|
|
const struct admin_state_code *operation);
|
|
|
|
int vdo_start_operation_with_waiter(struct admin_state *state,
|
|
const struct admin_state_code *operation,
|
|
struct vdo_completion *waiter,
|
|
vdo_admin_initiator_fn initiator);
|
|
|
|
bool vdo_finish_operation(struct admin_state *state, int result);
|
|
|
|
#endif /* VDO_ADMIN_STATE_H */
|