summaryrefslogtreecommitdiff
path: root/drivers/md/dm-vdo/admin-state.h
blob: a7d6ac2c30a668c81c3833f38cbe10f4361a340d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
/* 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 */