xref: /spdk/lib/ftl/mngt/ftl_mngt.h (revision 106ad3793f953d7353e5a5a1fa67fa6a82d13747)
1 /*   SPDX-License-Identifier: BSD-3-Clause
2  *   Copyright (C) 2022 Intel Corporation.
3  *   All rights reserved.
4  */
5 
6 #ifndef FTL_MNGT_H
7 #define FTL_MNGT_H
8 
9 #include "spdk/stdinc.h"
10 #include "spdk/ftl.h"
11 
12 struct spdk_ftl_dev;
13 struct ftl_mngt_process;
14 
15 /**
16  * The FTL management callback function
17  *
18  * @param dev FTL device
19  * @param mngt FTL management handle
20  */
21 typedef void (*ftl_mngt_fn)(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt);
22 
23 /**
24  * The FTL management init function
25  *
26  * @param dev FTL device
27  * @param mngt FTL management handle
28  * @param init_ctx The initialization context
29  *
30  * @return Initialization status
31  * @retval 0 initialization successful, the process can be executed
32  * @retval non-zero an error occurred during initialization, fail the process
33  */
34 typedef int (*ftl_mngt_init_fn)(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt,
35 				void *init_ctx);
36 
37 /**
38  * The FTL management process completion callback function
39  *
40  * @param dev FTL device
41  * @param ctx Caller context
42  * @param status The operation result of the management process
43  */
44 typedef void (*ftl_mngt_completion)(struct spdk_ftl_dev *dev, void *ctx, int status);
45 
46 /**
47  * The FTL management step descriptor
48  */
49 struct ftl_mngt_step_desc {
50 	/**
51 	 * Name of the step
52 	 */
53 	const char *name;
54 
55 	/**
56 	 * Size of the step argument (context)
57 	 *
58 	 * The step context will be allocated before execution of step's
59 	 * callback.
60 	 *
61 	 * @note The context can be reallocated (freed and newly allocated
62 	 * when calling ftl_mngt_alloc_step_ctx). The main usage is the ability
63 	 * to set this value to 0 and only allocate as needed if the step is
64 	 * going to be extremely similar - eg. recovery from shared memory and
65 	 * disk - in case of shm all the data is already available in memory, while
66 	 * recovery from disk needs extra context to be able to synchronize IO. This
67 	 * allows for saving a little bit of time on alloc/dealloc in the cases where
68 	 * execution time may be critical.
69 	 * @note It doesn't work like realloc
70 	 * @note The context can be retrieved within callback when calling
71 	 * ftl_mngt_get_step_ctx
72 	 */
73 	size_t ctx_size;
74 
75 	/**
76 	 * Step callback function
77 	 */
78 	ftl_mngt_fn action;
79 
80 	/**
81 	 * It the step requires cleanup this is right place to put your handler.
82 	 * When a FTL management process fails cleanup callbacks are executed
83 	 * in rollback procedure. Cleanup functions are executed in reverse
84 	 * order to actions already called.
85 	 */
86 	ftl_mngt_fn cleanup;
87 };
88 
89 /**
90  * The FTL management process descriptor
91  */
92 struct ftl_mngt_process_desc {
93 	/**
94 	 * The name of the process
95 	 */
96 	const char *name;
97 
98 	/**
99 	 * Size of the process argument (context)
100 	 *
101 	 * The process context will be allocated before execution of the first
102 	 * step
103 	 *
104 	 * @note To get context of the process within FTL management callback,
105 	 * execute ftl_mngt_get_process_ctx
106 	 */
107 	size_t ctx_size;
108 
109 	/**
110 	 * Pointer to the additional error handler when the process fails
111 	 */
112 	ftl_mngt_fn error_handler;
113 
114 	/**
115 	 * The initialization handler is invoked when the management process is
116 	 * being created before the execution of the process
117 	 */
118 	ftl_mngt_init_fn init_handler;
119 
120 	/**
121 	 * When the process wants to cleanup, for example free resources which
122 	 * were allocated in init_handler, the deinit_handler can be provided
123 	 */
124 	ftl_mngt_fn deinit_handler;
125 
126 	/**
127 	 * The FTL process steps
128 	 *
129 	 * The process context will be allocated before execution of the first
130 	 * step
131 	 *
132 	 * @note The step array terminator shall end with action equals NULL
133 	 */
134 	struct ftl_mngt_step_desc steps[];
135 };
136 
137 /**
138  * @brief Executes the FTL management process defined by the process descriptor
139  *
140  * In case of an error all already executed steps will have their rollback functions
141  * called in reverse order.
142  *
143  * @param dev FTL device
144  * @param process The descriptor of process to be executed
145  * @param cb Caller callback
146  * @param cb_ctx Caller context
147  *
148  * @return Result of invoking the operation
149  * @retval 0 - The FTL management process has been started
150  * @retval Non-zero An error occurred when starting The FTL management process
151  */
152 int ftl_mngt_process_execute(struct spdk_ftl_dev *dev,
153 			     const struct ftl_mngt_process_desc *process,
154 			     ftl_mngt_completion cb, void *cb_ctx);
155 
156 /**
157  * @brief Executes rollback on the FTL management process defined by the process
158  * descriptor
159  *
160  * All cleanup function from steps will be executed in reversed order
161  *
162  * @param dev FTL device
163  * @param process The descriptor of process to be rollback
164  * @param cb Caller callback
165  * @param cb_ctx Caller context
166  *
167  * @return Result of invoking the rollback operation
168  * @retval 0 - Rollback of the FTL management process has been started
169  * @retval Non-zero An error occurred when starting the rollback
170  */
171 int ftl_mngt_process_rollback(struct spdk_ftl_dev *dev,
172 			      const struct ftl_mngt_process_desc *process,
173 			      ftl_mngt_completion cb, void *cb_ctx);
174 
175 /*
176  * FTL management API for steps
177  */
178 
179 /**
180  * @brief Gets FTL device
181  *
182  * @param mngt FTL management handle
183  *
184  * @note This function can be invoked within step handler only
185  *
186  * @return FTL device
187  */
188 struct spdk_ftl_dev *ftl_mngt_get_dev(struct ftl_mngt_process *mngt);
189 
190 /**
191  * @brief Allocates a context for the management step
192  *
193  * @param mngt FTL management handle
194  * @param size Size of the step context
195  *
196  * @note This function can be invoked within ftl_mngt_fn callback only
197  *
198  * @return Operation result
199  * @retval 0 Operation successful
200  * @retval Non-zero Operation failure
201  */
202 int ftl_mngt_alloc_step_ctx(struct ftl_mngt_process *mngt, size_t size);
203 
204 /**
205  * @brief Gets the management step context
206  *
207  * @param mngt FTL management handle
208  *
209  * @note This function can be invoked within ftl_mngt_fn callback only
210  *
211  * @return Context of the step containing pointer to buffer and its size
212  */
213 void *ftl_mngt_get_step_ctx(struct ftl_mngt_process *mngt);
214 
215 /**
216  * @brief Gets the management process context
217  *
218  * @param mngt FTL management handle
219  *
220  * @note This function can be invoked within ftl_mngt_fn callback only
221  *
222  * @return Context of the process containing pointer to buffer and its size
223  */
224 void *ftl_mngt_get_process_ctx(struct ftl_mngt_process *mngt);
225 
226 /**
227  * @brief Gets the caller context
228  *
229  * @param mngt FTL management handle
230  *
231  * @note This function can be invoked within ftl_mngt_fn callback only
232  *
233  * @return Pointer to the caller context
234  */
235 void *ftl_mngt_get_caller_ctx(struct ftl_mngt_process *mngt);
236 
237 /**
238  * @brief Finishes the management process immediately
239  *
240  * @note This function can be invoked within ftl_mngt_fn callback only
241  *
242  * @param mngt FTL management handle of process to be finished
243  */
244 void ftl_mngt_finish(struct ftl_mngt_process *mngt);
245 
246 /**
247  * @brief Completes the step currently in progress and jump to a next one
248  *
249  * If no more steps to be executed then the management process is finished and
250  * caller callback is invoked
251  *
252  * @note This function can be invoked within ftl_mngt_fn callback only
253  *
254  * @param mngt FTL management handle
255  */
256 void ftl_mngt_next_step(struct ftl_mngt_process *mngt);
257 
258 /**
259  * @brief Skips the step currently in progress and jump to a next one
260  *
261  * @note This function can be invoked within ftl_mngt_fn callback only
262  *
263  * @param mngt FTL management handle
264  */
265 void ftl_mngt_skip_step(struct ftl_mngt_process *mngt);
266 
267 /**
268  * @brief Continue the step currently in progress
269  *
270  * This causes invoking the same step handler in next iteration of the
271  * management process. This mechanism can be used by a job when polling for
272  * something.
273  *
274  * @note This function can be invoked within ftl_mngt_fn callback only
275  *
276  * @param mngt FTL management handle
277  */
278 void ftl_mngt_continue_step(struct ftl_mngt_process *mngt);
279 
280 /**
281  * @brief Fail the step currently in progress.
282  *
283  * It stops executing all steps and starts the rollback procedure (calling
284  * the cleanup functions of all already executed steps).
285  * If executed from a cleanup function, it will stop executing and the following
286  * cleanup functions (if any) will be executed.
287  *
288  * @param mngt FTL management handle
289  */
290 void ftl_mngt_fail_step(struct ftl_mngt_process *mngt);
291 
292 /**
293  * @brief Calls another management process
294  *
295  * Ends the current step and executes specified process and finally continues
296  * executing the the remaining steps
297  *
298  * @param mngt The management handle
299  * @param process The management process to be called
300  * @param init_ctx Process initialization context
301  *
302  * @note If the initialization procedure is required then both init_ctx and
303  * init_handler in the process descriptor must be provided.
304  */
305 void ftl_mngt_call_process(struct ftl_mngt_process *mngt,
306 			   const struct ftl_mngt_process_desc *process,
307 			   void *init_ctx);
308 
309 /**
310  * @brief Calls rollback steps of another management process
311  *
312  * Ends the current step and executes rollback steps of specified process
313  * and finally continues executing the remaining steps in the original process
314  *
315  * @param mngt The management handle
316  * @param process The management process to be called to execute rollback
317  */
318 void ftl_mngt_call_process_rollback(struct ftl_mngt_process *mngt,
319 				    const struct ftl_mngt_process_desc *process);
320 
321 /*
322  * The specific management functions
323  */
324 /**
325  * @brief Starts up a FTL instance
326  *
327  * @param dev FTL device
328  * @param cb Caller callback
329  * @param cb_cntx Caller context
330  *
331  * @return Operation result
332  * @retval 0 The operation successful has started
333  * @retval Non-zero Startup failure
334  */
335 int ftl_mngt_call_dev_startup(struct spdk_ftl_dev *dev, ftl_mngt_completion cb, void *cb_cntx);
336 
337 /*
338  * The specific management functions
339  */
340 /**
341  * @brief Issue trim on FTL instance
342  *
343  * @param dev FTL device
344  * @param cb Caller callback
345  * @param cb_cntx Caller context
346  *
347  * @return Operation result
348  * @retval 0 The operation successful has started
349  * @retval Non-zero Startup failure
350  */
351 int ftl_mngt_trim(struct spdk_ftl_dev *dev, uint64_t lba, uint64_t num_blocks, spdk_ftl_fn cb,
352 		  void *cb_cntx);
353 
354 /**
355  * @brief Shuts down a FTL instance
356  *
357  * @param dev FTL device
358  * @param cb Caller callback
359  * @param cb_cntx Caller context
360  *
361  * @return Operation result
362  * @retval 0 The operation successful has started
363  * @retval Non-zero Shutdown failure
364  */
365 int ftl_mngt_call_dev_shutdown(struct spdk_ftl_dev *dev, ftl_mngt_completion cb, void *cb_cntx);
366 
367 #endif /* LIB_FTL_FTL_MNGT_H */
368