/* 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;
};