From 506315a651e201585c2b35f61cb9e8a764e758d2 Mon Sep 17 00:00:00 2001 From: Kozlowski Mateusz Date: Mon, 13 Jun 2022 10:59:05 +0200 Subject: [PATCH] FTL: Initialize nv_cache metadata on startup Signed-off-by: Kozlowski Mateusz Signed-off-by: Artur Paszkiewicz Change-Id: Ie1a60ec8d1e05b1e4dec85a7187cffad24496460 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/13320 Tested-by: SPDK CI Jenkins Reviewed-by: Jim Harris Reviewed-by: Ben Walker --- lib/ftl/ftl_nv_cache.c | 38 +++++++++++++++++++++++++++++++++ lib/ftl/ftl_nv_cache.h | 2 ++ lib/ftl/mngt/ftl_mngt_md.c | 11 ++++++++++ lib/ftl/mngt/ftl_mngt_startup.c | 4 ++++ lib/ftl/mngt/ftl_mngt_steps.h | 2 ++ 5 files changed, 57 insertions(+) diff --git a/lib/ftl/ftl_nv_cache.c b/lib/ftl/ftl_nv_cache.c index 0e78f6086..51da8eea1 100644 --- a/lib/ftl/ftl_nv_cache.c +++ b/lib/ftl/ftl_nv_cache.c @@ -325,6 +325,44 @@ chunk_free_p2l_map(struct ftl_nv_cache_chunk *chunk) ftl_chunk_free_md_entry(chunk); } +int +ftl_nv_cache_save_state(struct ftl_nv_cache *nv_cache) +{ + struct spdk_ftl_dev *dev = SPDK_CONTAINEROF(nv_cache, struct spdk_ftl_dev, nv_cache); + struct ftl_nv_cache_chunk *chunk; + int status = 0; + uint64_t i; + + assert(nv_cache->chunk_open_count == 0); + + chunk = nv_cache->chunks; + if (!chunk) { + FTL_ERRLOG(dev, "Cannot save NV cache state, no NV cache metadata\n"); + return -ENOMEM; + } + + for (i = 0; i < nv_cache->chunk_count; i++, chunk++) { + nvc_validate_md(nv_cache, chunk->md); + + if (chunk->md->blocks_written == nv_cache->chunk_blocks) { + /* Full chunk */ + } else if (0 == chunk->md->blocks_written) { + /* Empty chunk */ + } else { + assert(0); + status = -EINVAL; + break; + } + } + + if (status) { + FTL_ERRLOG(dev, "Cannot save NV cache state, inconsistent NV cache" + "metadata\n"); + } + + return status; +} + static int chunk_alloc_p2l_map(struct ftl_nv_cache_chunk *chunk) { diff --git a/lib/ftl/ftl_nv_cache.h b/lib/ftl/ftl_nv_cache.h index eb7e46d9f..dd082130b 100644 --- a/lib/ftl/ftl_nv_cache.h +++ b/lib/ftl/ftl_nv_cache.h @@ -137,6 +137,8 @@ int ftl_nv_cache_read(struct ftl_io *io, ftl_addr addr, uint32_t num_blocks, bool ftl_nv_cache_full(struct ftl_nv_cache *nv_cache); void ftl_nv_cache_process(struct spdk_ftl_dev *dev); +int ftl_nv_cache_save_state(struct ftl_nv_cache *nv_cache); + void ftl_nv_cache_halt(struct ftl_nv_cache *nv_cache); int ftl_nv_cache_chunks_busy(struct ftl_nv_cache *nv_cache); diff --git a/lib/ftl/mngt/ftl_mngt_md.c b/lib/ftl/mngt/ftl_mngt_md.c index 7fbacb133..e7b24e873 100644 --- a/lib/ftl/mngt/ftl_mngt_md.c +++ b/lib/ftl/mngt/ftl_mngt_md.c @@ -120,6 +120,17 @@ persist(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt, ftl_md_persist(md); } +void +ftl_mngt_persist_nv_cache_metadata(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt) +{ + if (ftl_nv_cache_save_state(&dev->nv_cache)) { + ftl_mngt_fail_step(mngt); + return; + } + + persist(dev, mngt, FTL_LAYOUT_REGION_TYPE_NVC_MD); +} + static uint32_t get_sb_crc(struct ftl_superblock *sb) { diff --git a/lib/ftl/mngt/ftl_mngt_startup.c b/lib/ftl/mngt/ftl_mngt_startup.c index def2952ac..35ca08624 100644 --- a/lib/ftl/mngt/ftl_mngt_startup.c +++ b/lib/ftl/mngt/ftl_mngt_startup.c @@ -108,6 +108,10 @@ static const struct ftl_mngt_process_desc desc_first_start = { .name = "Scrub NV cache", .action = ftl_mngt_scrub_nv_cache, }, + { + .name = "Save initial chunk info metadata", + .action = ftl_mngt_persist_nv_cache_metadata, + }, { .name = "Set FTL dirty state", .action = ftl_mngt_set_dirty, diff --git a/lib/ftl/mngt/ftl_mngt_steps.h b/lib/ftl/mngt/ftl_mngt_steps.h index 1c98c97c7..38c55606e 100644 --- a/lib/ftl/mngt/ftl_mngt_steps.h +++ b/lib/ftl/mngt/ftl_mngt_steps.h @@ -68,4 +68,6 @@ void ftl_mngt_init_default_sb(struct spdk_ftl_dev *dev, struct ftl_mngt_process void ftl_mngt_set_dirty(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt); +void ftl_mngt_persist_nv_cache_metadata(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt); + #endif /* FTL_MNGT_STEPS_H */