// 函数指针:FTL mngt回调函数
typedef void (*ftl_mngt_fn)(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt);
typedef void (*ftl_mngt_completion)(struct spdk_ftl_dev *dev, void *ctx, int status);

struct ftl_mngt_step_desc {
	const char *name;
	
	/**
	 * step参数(上下文)的大小
	 * step的上下文会在执行step回调函数之前被分配空间
	 * 上下文可能会被rellocated(通过调用ftl_mngt_alloc_step_ctx)
	 */
	size_t ctx_size;
	
	/**
	 * 步骤的回调函数
	 */
	ftl_mngt_fn action;
	
	/**
	 * 如果这个步骤需要回滚的话,定义这个cleanup函数可以在FTL mngt process失败的时候以逆序的方式执行步骤回滚
	 */
	ftl_mngt_fn cleanup;
};

struct ftl_mngt_process_desc {
	const char *name;
	
	/**
	 * mngt process的上下文会在执行第一个step之前被分配,
	 * 在执行FTL mngt回调的过程中通过ftl_mngt_get_process_ctx获取 process 上下文
	 */
	size_t ctx_size;
	
	/**
	 * 额外的process错误处理函数指针
	 */
	ftl_mngt_fn error_handler;
	
	/**
	 * step 数组需要以 NULL 结尾
	 */
	struct ftl_mngt_step_desc steps[];
};

// 执行由process desc定义的mngt process,返回0表示process成功启动了,否则返回非0,cb_ctx表示调用者的上下文
int ftl_mngt_process_execute(struct spdk_ftl_dev *dev,
							 const struct ftl_mngt_process_desc *process,
							 ftl_mngt_completion cb, void *cb_ctx);

// 执行由process desc定义的rollback过程,返回0表示回滚过程成功启动,否则返回非0,cb_ctx表示调用者的上下文
int ftl_mngt_process_rollback(struct spdk_ftl_dev *dev,
                              const struct ftl_mngt_process_desc *process,
                              ftl_mngt_completion cb, void *cb_ctx);

// 以下的函数仅应该在 ftl_mngt_fn 回调中被调用
int ftl_mngt_alloc_step_ctx(struct ftl_mngt_process *mngt, size_t size);
void *ftl_mngt_get_step_ctx(struct ftl_mngt_process *mngt);
void *ftl_mngt_get_process_ctx(struct ftl_mngt_process *mngt);
void *ftl_mngt_get_caller_ctx(struct ftl_mngt_process *mngt);
// 获取执行的 mngt process 的状态
int ftl_mngt_get_status(struct ftl_mngt_process *mngt);
// 立即完成mngt process
void ftl_mngt_finish(struct ftl_mngt_process *mngt);
// 完成现在在process中进行的step并跳转到下一个step,如果没有更多的step了则表示process执行完了,开始执行回调函数
void ftl_mngt_next_step(struct ftl_mngt_process *mngt);
void ftl_mngt_skip_step(struct ftl_mngt_process *mngt);
void ftl_mngt_continue_step(struct ftl_mngt_process *mngt);
// 停止执行所有步骤并启动回滚程序(调用所有已执行步骤的清理函数)。
// 如果从清理函数执行,则将停止执行,并执行后续的清理函数(如果有的话)。
void ftl_mngt_fail_step(struct ftl_mngt_process *mngt);
// 结束当前步骤并执行指定进程,最后继续执行剩余步骤
void ftl_mngt_call_process(struct ftl_mngt_process *mngt,
                           const struct ftl_mngt_process_desc *process);
// 结束当前步骤,执行指定进程的回滚步骤,最后继续执行原进程的剩余步骤
void ftl_mngt_call_process_rollback(struct ftl_mngt_process *mngt,
                                    const struct ftl_mngt_process_desc *process);

int ftl_mngt_call_dev_startup(struct spdk_ftl_dev *dev, ftl_mngt_completion cb, void *cb_cntx);
int ftl_mngt_call_dev_shutdown(struct spdk_ftl_dev *dev, ftl_mngt_completion cb, void *cb_cntx);