/* Size of superblock on NV cache, make it bigger for future fields */
#define FTL_SUPERBLOCK_SIZE (128ULL * KiB)

#define FTL_MAGIC(a, b, c, d) \
    ((UINT64_C(a) << 48) | (UINT64_C(b) << 32) | (UINT64_C(c) << 16) | \
     UINT64_C(d))

/**
 * Magic number identifies FTL superblock
 */
#define FTL_SUPERBLOCK_MAGIC FTL_MAGIC(0x1410, 0x1683, 0x1920, 0x1989)

struct ftl_superblock_gc_info {
	/* High priority band; if there's no free bands after dirty shutdown, don't restart GC from same id, or phys_id -
	 * pick actual lowest validity band to avoid being stuck and try to write it to the open band.
	 */
	uint64_t band_id_high_prio;
	/* Currently relocated band (note it's just id, not seq_id ie. its actual location on disk) */
	uint64_t current_band_id;
	/* Bands are grouped together into larger reclaim units; this is the band id translated to those units */
	uint64_t band_phys_id;
	/* May be updating multiple fields at the same time, clearing/setting this marks the transaction */
	uint64_t is_valid;
};

struct ftl_superblock_header {
	uint64_t magic;
	uint64_t crc;
	uint64_t version;
};

struct ftl_superblock_md_region {
	uint32_t type;
	uint32_t version;
	uint64_t blk_offs;
	uint64_t blk_sz;
};

/*
* dev->sb对应的数据结构,用来描述superblock
* 在 ftl_mngt_init_default_sb 中被初始化
* clean设为0
*/
struct ftl_superblock {
	struct ftl_superblock_header header;
	
	struct spdk_uuid uuid;
	
	/* Flag describing clean shutdown */
	uint64_t clean;
	
	/* Number of surfaced LBAs 
	 * 在 ftl_layout_setup 中被初始化,设置为与dev->lba_cnt一致
	 */
	uint64_t lba_cnt;
	
	/* Percentage of base device blocks not exposed to the user */
    // 在 ftl_mngt_init_default_sb 中被初始化为和dev->overprovisioning一致
	uint64_t overprovisioning;
	
	/* Maximum IO depth per band relocate */
    // 在 ftl_mngt_init_default_sb 中被初始化为16
	uint64_t max_reloc_qdepth;
	
	/* Reserved field */
	uint64_t reserved;
	
	uint32_t reserved2;
	
	struct ftl_superblock_gc_info gc_info;

    // 在 ftl_mngt_init_default_sb 中 type 被设置为 FTL_LAYOUT_REGION_TYPE_INVALID
	struct ftl_superblock_md_region md_layout_head;
};