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