Commit cf3d4296 authored by Konrad Sztyber's avatar Konrad Sztyber Committed by Ben Walker
Browse files

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.

Change-Id: I4e99709c8c2a526a928578870d7fbd5fef37db02
Signed-off-by: default avatarKonrad Sztyber <konrad.sztyber@intel.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/466883


Reviewed-by: default avatarMateusz Kozlowski <mateusz.kozlowski@intel.com>
Reviewed-by: default avatarWojciech Malikowski <wojciech.malikowski@intel.com>
Reviewed-by: default avatarTomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
parent a33e2a84
Loading
Loading
Loading
Loading
+11 −5
Original line number Diff line number Diff line
@@ -2095,14 +2095,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;
@@ -2112,6 +2108,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)
{
+1 −1
Original line number Diff line number Diff line
@@ -275,7 +275,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);
+23 −2
Original line number Diff line number Diff line
@@ -543,6 +543,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)
{
@@ -566,9 +587,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);
		}