Commit d1462266 authored by Kozlowski Mateusz's avatar Kozlowski Mateusz Committed by Jim Harris
Browse files

FTL: Recover chunk state



Recovers the free/open/close chunk state, initializing them to any
specific lists.

Signed-off-by: default avatarKozlowski Mateusz <mateusz.kozlowski@intel.com>
Signed-off-by: default avatarArtur Paszkiewicz <artur.paszkiewicz@intel.com>
Change-Id: Idf689f4fbcd6fc6bd986104dc89f5079c758845a
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/13373


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
parent ca53f5a6
Loading
Loading
Loading
Loading
+62 −0
Original line number Diff line number Diff line
@@ -1660,6 +1660,68 @@ ftl_chunk_close(struct ftl_nv_cache_chunk *chunk)
	ftl_chunk_basic_rq_write(chunk, brq);
}

static void
restore_chunk_state_cb(struct spdk_ftl_dev *dev, struct ftl_md *md, int status)
{
	struct ftl_mngt_process *mngt = md->owner.cb_ctx;
	struct ftl_nv_cache *nvc = &dev->nv_cache;
	struct ftl_nv_cache_chunk *chunk;
	uint64_t i;

	if (status) {
		/* Restore error, end step */
		ftl_mngt_fail_step(mngt);
		return;
	}

	for (i = 0; i < nvc->chunk_count; i++) {
		chunk = &nvc->chunks[i];

		switch (chunk->md->state) {
		case FTL_CHUNK_STATE_FREE:
			break;
		case FTL_CHUNK_STATE_OPEN:
			TAILQ_REMOVE(&nvc->chunk_free_list, chunk, entry);
			nvc->chunk_free_count--;

			TAILQ_INSERT_TAIL(&nvc->chunk_open_list, chunk, entry);
			nvc->chunk_open_count++;

			/* Chunk is not empty, mark it to be recovered */
			chunk->recovery = true;
			break;
		case FTL_CHUNK_STATE_CLOSED:
			TAILQ_REMOVE(&nvc->chunk_free_list, chunk, entry);
			nvc->chunk_free_count--;

			TAILQ_INSERT_TAIL(&nvc->chunk_full_list, chunk, entry);
			nvc->chunk_full_count++;

			/* Chunk is not empty, mark it to be recovered */
			chunk->recovery = true;
			break;
		default:
			status = -EINVAL;
		}
	}

	if (status) {
		ftl_mngt_fail_step(mngt);
	} else {
		ftl_mngt_next_step(mngt);
	}
}

void
ftl_mngt_nv_cache_restore_chunk_state(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
{
	struct ftl_md *md = dev->layout.md[FTL_LAYOUT_REGION_TYPE_NVC_MD];

	md->owner.cb_ctx = mngt;
	md->cb = restore_chunk_state_cb;
	ftl_md_restore(md);
}

int
ftl_nv_cache_chunks_busy(struct ftl_nv_cache *nv_cache)
{
+2 −0
Original line number Diff line number Diff line
@@ -215,6 +215,8 @@ uint64_t chunk_tail_md_offset(struct ftl_nv_cache *nv_cache);
void ftl_nv_cache_get_max_seq_id(struct ftl_nv_cache *nv_cache, uint64_t *open_seq_id,
				 uint64_t *close_seq_id);

void ftl_mngt_nv_cache_restore_chunk_state(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt);

typedef int (*ftl_chunk_md_cb)(struct ftl_nv_cache_chunk *chunk, void *cntx);

struct ftl_nv_cache_chunk *ftl_nv_cache_get_chunk_from_addr(struct spdk_ftl_dev *dev,
+4 −0
Original line number Diff line number Diff line
@@ -712,6 +712,10 @@ static const struct ftl_mngt_process_desc g_desc_recovery = {
			.name = "Recover open bands P2L",
			.action = ftl_mngt_recovery_open_bands_p2l
		},
		{
			.name = "Recover chunk state",
			.action = ftl_mngt_nv_cache_restore_chunk_state
		},
		{
			.name = "Recover max seq ID",
			.action = ftl_mngt_recover_seq_id