From 22e353bcbb0219b4beda57cc3c1cab9817c76678 Mon Sep 17 00:00:00 2001 From: Konrad Sztyber Date: Fri, 30 Aug 2019 10:21:10 +0200 Subject: [PATCH] lib/ftl: flush the write buffer during nv_cache recovery When recovering the data from the non-volatile cache, the data inside the volatile cache needs to be flushed before flushing active bands. Otherwise, if the number of blocks in a band is smaller than the number of blocks inside the volatile cache, part of the data may not get flushed. Signed-off-by: Konrad Sztyber Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/466883 (master) (cherry picked from commit cf3d42961b7100c4a64993c3043bbe03d7ecaaf3) Change-Id: I4e99709c8c2a526a928578870d7fbd5fef37db02 Signed-off-by: Tomasz Zawadzki Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/468303 Tested-by: SPDK CI Jenkins Reviewed-by: Jim Harris Reviewed-by: Ben Walker --- lib/ftl/ftl_core.c | 16 +++++++++++----- lib/ftl/ftl_core.h | 2 +- lib/ftl/ftl_restore.c | 25 +++++++++++++++++++++++-- 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/lib/ftl/ftl_core.c b/lib/ftl/ftl_core.c index c01dcf09b..a2ee2ec6d 100644 --- a/lib/ftl/ftl_core.c +++ b/lib/ftl/ftl_core.c @@ -2080,14 +2080,10 @@ _ftl_flush(void *ctx) } int -spdk_ftl_flush(struct spdk_ftl_dev *dev, spdk_ftl_fn cb_fn, void *cb_arg) +ftl_flush_rwb(struct spdk_ftl_dev *dev, spdk_ftl_fn cb_fn, void *cb_arg) { struct ftl_flush *flush; - if (!dev->initialized) { - return -EBUSY; - } - flush = ftl_flush_init(dev, cb_fn, cb_arg); if (!flush) { return -ENOMEM; @@ -2097,6 +2093,16 @@ spdk_ftl_flush(struct spdk_ftl_dev *dev, spdk_ftl_fn cb_fn, void *cb_arg) return 0; } +int +spdk_ftl_flush(struct spdk_ftl_dev *dev, spdk_ftl_fn cb_fn, void *cb_arg) +{ + if (!dev->initialized) { + return -EBUSY; + } + + return ftl_flush_rwb(dev, cb_fn, cb_arg); +} + static void _ftl_process_anm_event(void *ctx) { diff --git a/lib/ftl/ftl_core.h b/lib/ftl/ftl_core.h index 1435d0a90..24a8a8bb6 100644 --- a/lib/ftl/ftl_core.h +++ b/lib/ftl/ftl_core.h @@ -276,7 +276,7 @@ void ftl_apply_limits(struct spdk_ftl_dev *dev); void ftl_io_read(struct ftl_io *io); void ftl_io_write(struct ftl_io *io); int ftl_io_erase(struct ftl_io *io); -int ftl_io_flush(struct ftl_io *io); +int ftl_flush_rwb(struct spdk_ftl_dev *dev, spdk_ftl_fn cb_fn, void *cb_arg); int ftl_current_limit(const struct spdk_ftl_dev *dev); int ftl_invalidate_addr(struct spdk_ftl_dev *dev, struct ftl_ppa ppa); int ftl_task_core(void *ctx); diff --git a/lib/ftl/ftl_restore.c b/lib/ftl/ftl_restore.c index ef8598b05..4b06d18fb 100644 --- a/lib/ftl/ftl_restore.c +++ b/lib/ftl/ftl_restore.c @@ -544,6 +544,27 @@ ftl_nv_cache_band_flush_cb(void *ctx, int status) } } +static void +ftl_nv_cache_rwb_flush_cb(void *ctx, int status) +{ + struct ftl_nv_cache_restore *restore = ctx; + struct ftl_nv_cache *nv_cache = restore->nv_cache; + struct spdk_ftl_dev *dev = SPDK_CONTAINEROF(nv_cache, struct spdk_ftl_dev, nv_cache); + int rc; + + if (spdk_unlikely(status != 0)) { + SPDK_ERRLOG("Flushing the write buffer failed: %s\n", spdk_strerror(-status)); + ftl_nv_cache_restore_complete(restore, status); + return; + } + + rc = ftl_flush_active_bands(dev, ftl_nv_cache_band_flush_cb, restore); + if (spdk_unlikely(rc != 0)) { + SPDK_ERRLOG("Unable to flush active bands: %s\n", spdk_strerror(-rc)); + ftl_nv_cache_restore_complete(restore, rc); + } +} + static void ftl_nv_cache_recovery_done(struct ftl_nv_cache_restore *restore) { @@ -567,9 +588,9 @@ ftl_nv_cache_recovery_done(struct ftl_nv_cache_restore *restore) range_current->start_addr < range_prev->last_addr)) { SPDK_DEBUGLOG(SPDK_LOG_FTL_INIT, "Non-volatile cache inconsistency detected\n"); - rc = ftl_flush_active_bands(dev, ftl_nv_cache_band_flush_cb, restore); + rc = ftl_flush_rwb(dev, ftl_nv_cache_rwb_flush_cb, restore); if (spdk_unlikely(rc != 0)) { - SPDK_ERRLOG("Unable to flush active bands: %s\n", spdk_strerror(-rc)); + SPDK_ERRLOG("Unable to flush the write buffer: %s\n", spdk_strerror(-rc)); ftl_nv_cache_restore_complete(restore, rc); }