struct ftl_nv_cache_chunk_md {
/* Current lba to write */
uint32_t write_pointer;
/* Number of blocks written */
uint32_t blocks_written;
/* Number of skipped block (case when IO size is greater than blocks left in chunk) */
uint32_t blocks_skipped;
/* Next block to be compacted */
uint32_t read_pointer;
/* Number of compacted (both valid and invalid) blocks */
uint32_t blocks_compacted;
/* Chunk state */
enum ftl_chunk_state state;
/* CRC32 checksum of the associated P2L map when chunk is in closed state */
uint32_t p2l_map_checksum;
} __attribute__((aligned(FTL_BLOCK_SIZE)));
// 在 ftl_nv_cache_init 中被初始化
struct ftl_nv_cache_chunk {
struct ftl_nv_cache *nv_cache;
// 指向的是 nv_cache->md 申请的 memory buffer 区域
struct ftl_nv_cache_chunk_md *md;
/* Offset from start lba of the cache */
// 该chunk在 nv_cache 设备的起始lba
uint64_t offset;
/* P2L map */
struct ftl_p2l_map p2l_map;
/* Metadata request */
struct ftl_basic_rq metadata_rq;
TAILQ_ENTRY(ftl_nv_cache_chunk) entry;
/* This flag is used to indicate chunk is used in recovery */
bool recovery;
/* For writing metadata */
struct ftl_md_io_entry_ctx md_persist_entry_ctx;
};
struct ftl_nv_cache {
/* Flag indicating halt request */
bool halt;
/* Write buffer cache bdev */
struct spdk_bdev_desc *bdev_desc;
/* Persistent cache IO channel */
struct spdk_io_channel *cache_ioch;
/* Metadata pool */
// 在 ftl_nv_cache_init 中被初始化
// 一次申请 xfer_size(32或者zns自定的写单元大小) 个 md_size(64 B)
struct ftl_mempool *md_pool;
/* P2L map memory pool */
// 在 ftl_nv_cache_init 中被初始化
// 申请了 2(FTL_MAX_OPEN_CHUNKS) 个,每个大小为一个 chunk 的 blocks 数量 * l2p.addr_size(用来放chunk的 l2p 表)
struct ftl_mempool *p2l_pool;
/* Chunk md memory pool */
// 在 ftl_nv_cache_init 中被初始化
// 申请了 2(FTL_MAX_OPEN_CHUNKS) 个,每个大小为一个 struct ftl_nv_cache_chunk_md 的大小
struct ftl_mempool *chunk_md_pool;
/* Block Metadata size */
uint64_t md_size;
/* NV cache metadata object handle */
// 在 ftl_nv_cache_init 中被初始化为 dev->layout.md[FTL_LAYOUT_REGION_TYPE_NVC_MD]
struct ftl_md *md;
/* Number of blocks in chunk */
// 在 ftl_nv_cache_init 中被初始化为 dev->layout.nvc.chunk_data_blocks
uint64_t chunk_blocks;
/* Number of chunks */
// 在 ftl_nv_cache_init 中被初始化为 dev->layout.nvc.chunk_count
uint64_t chunk_count;
/* Current processed chunk */
struct ftl_nv_cache_chunk *chunk_current;
// 下面3个 list 在 ftl_nv_cache_init 中被初始化
/* Free chunks list */
TAILQ_HEAD(, ftl_nv_cache_chunk) chunk_free_list;
uint64_t chunk_free_count;
/* Open chunks list */
TAILQ_HEAD(, ftl_nv_cache_chunk) chunk_open_list;
uint64_t chunk_open_count;
/* Full chunks list */
TAILQ_HEAD(, ftl_nv_cache_chunk) chunk_full_list;
uint64_t chunk_full_count;
// 在 ftl_nv_cache_init 被初始化,申请了 chunk_count 个 struct ftl_nv_cache_chunk 的空间
struct ftl_nv_cache_chunk *chunks;
};