Struct spdk_ftl_dev

struct spdk_ftl_dev {
	struct spdk_ftl_conf conf;

	/* FTL device layout */
    struct ftl_layout layout;

	/* FTL superblock 
	 * 在 ftl_mngt_init_default_sb 中被初始化
	 */
    struct ftl_superblock *sb;

	/* Queue of registered IO channels */
	TAILQ_HEAD(, ftl_io_channel)ioch_queue;

	/* Underlying device */
	struct spdk_bdev_desc *base_bdev_desc;
	
	/* Cache VSS metadata size */
	// 在ftl_mngt_open_cache_bdev中调用spdk接口初始化,cache设备必须通过spdk_bdev_is_md_separate的检测
	// 必须得和 ftl_md_vss 的 size 一致
	uint64_t cache_md_size;
	
	/* 保存一些经常使用的变量值,这些都是指的base设备的属性 */
	uint64_t num_blocks_in_band;
	bool is_zoned;
	
	/* Indicates the device is fully initialized */
	bool initialized;
	
	/* Indicates the device is about to be stopped */
	bool halt;
	
	/* counters for poller busy, include
	   1. nv cache read/write
	   2. metadata read/write
	   3. base bdev read/write */
	uint64_t io_activity_total;
	
	/* Number of operational bands */
	uint64_t num_bands;
	
	/* Number of free bands */
	uint64_t num_free;

	/* Logical -> physical table */
    void* l2p;
 
	/* l2p deferred pins list */
	TAILQ_HEAD(, ftl_l2p_pin_ctx) l2p_deferred_pins;
	
	/* Size of the l2p table
	 * 在ftl_layout_setup中被初始化 
	 */
	uint64_t num_lbas;

	
	/* Metadata size */
	// 在ftl_mngt_open_base_bdev中调用spdk接口初始化
	uint64_t md_size;
	
	/* Transfer unit size */
	// 在ftl_mngt_open_base_bdev中调用ftl_get_write_unit_size被初始化
	//(如果是zone设备则调用spdk接口获取写单元的大小,否则就直接置32)
	uint64_t xfer_size;
	
	/* Inflight IO operations */
	uint32_t num_inflight;
	
	/* Thread on which the poller is running
	 * 在 ftl_init.c/init_core_thread中被初始化
	 * 如果core_mask被conf指定了则在满足mask的第一个cpu线程上创建 core 线程,否则就使用现在的用户线程
	*/
	struct spdk_thread *core_thread;
	
	/* IO channel to the FTL device, used for internal management operations
	 * consuming FTL's external API
	 */
	struct spdk_io_channel *ioch;
	
	/* Underlying device IO channel */
	// 在ftl_mngt_open_base_bdev中直接调用spdk接口初始化
	struct spdk_io_channel *base_ioch;
	
	/* Cache IO channel */
	// 在ftl_mngt_open_cache_bdev中直接调用spdk接口初始化
	struct spdk_io_channel *cas`he_ioch;

    // 在ftl_mngt_start_core_poller中被初始化
	struct spdk_poller *core_poller;

	// 在allocate_dev中被初始化
	/* R/W submission queue */
	TAILQ_HEAD(, ftl_io) rd_sq;
	TAILQ_HEAD(, ftl_io) wr_sq;
};

static inline uint64_t
ftl_get_num_blocks_in_band(const struct spdk_ftl_dev *dev)
static inline size_t
ftl_get_num_zones_in_band(const struct spdk_ftl_dev *dev)
static inline size_t
ftl_get_num_blocks_in_zone(const struct spdk_ftl_dev *dev)
static inline uint32_t
ftl_get_write_unit_size(struct spdk_bdev *bdev)
{
	if (spdk_bdev_is_zoned(bdev)) {
	    return spdk_bdev_get_write_unit_size(bdev);
	}
	
	/* TODO: this should be passed via input parameter */
	return 32;
}