Commit 36049672 authored by Artur Paszkiewicz's avatar Artur Paszkiewicz Committed by Jim Harris
Browse files

ftl: sequence id tracking



Track the relative sequence of opening and closing bands and chunks.
Necessary for detecting the most recent user data during dirty shutdown recovery.

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


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Mellanox Build Bot
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
parent 35a9ddb5
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -68,6 +68,7 @@ _ftl_band_set_free(struct ftl_band *band)

	/* Add the band to the free band list */
	TAILQ_INSERT_TAIL(&dev->free_bands, band, queue_entry);
	band->md->close_seq_id = 0;
	band->reloc = false;

	dev->num_free++;
@@ -192,7 +193,7 @@ ftl_band_set_addr(struct ftl_band *band, uint64_t lba, ftl_addr addr)

	offset = ftl_band_block_offset_from_addr(band, addr);

	p2l_map->band_map[offset] = lba;
	p2l_map->band_map[offset].lba = lba;
	p2l_map->num_valid++;
	ftl_bitmap_set(band->dev->valid_map, addr);
}
@@ -387,12 +388,17 @@ ftl_band_p2l_map_addr(struct ftl_band *band)
int
ftl_band_write_prep(struct ftl_band *band)
{
	struct spdk_ftl_dev *dev = band->dev;

	if (ftl_band_alloc_p2l_map(band)) {
		return -1;
	}

	ftl_band_iter_init(band);

	band->md->seq = ftl_get_next_seq_id(dev);

	FTL_DEBUGLOG(dev, "Band to write, id %u seq %"PRIu64"\n", band->id, band->md->seq);
	return 0;
}

+6 −0
Original line number Diff line number Diff line
@@ -61,6 +61,12 @@ struct ftl_band_md {
	/* Band type set during opening */
	enum ftl_band_type		type;

	/* Sequence ID when band was opened */
	uint64_t			seq;

	/* Sequence ID when band was closed */
	uint64_t			close_seq_id;

	/* Number of times band was fully written (ie. number of free -> closed state cycles) */
	uint64_t			wr_cnt;

+2 −0
Original line number Diff line number Diff line
@@ -341,6 +341,7 @@ ftl_band_close(struct ftl_band *band)
	uint64_t num_blocks = ftl_tail_md_num_blocks(dev);

	/* Write P2L map first, after completion, set the state to close on nvcache, then internally */
	band->md->close_seq_id = ftl_get_next_seq_id(dev);
	ftl_band_set_state(band, FTL_BAND_STATE_CLOSING);
	ftl_basic_rq_init(dev, &band->metadata_rq, metadata, num_blocks);
	ftl_basic_rq_set_owner(&band->metadata_rq, band_map_write_cb, band);
@@ -374,6 +375,7 @@ ftl_band_free(struct ftl_band *band)

	memcpy(p2l_map->band_dma_md, band->md, region->entry_size * FTL_BLOCK_SIZE);
	p2l_map->band_dma_md->state = FTL_BAND_STATE_FREE;
	p2l_map->band_dma_md->close_seq_id = 0;
	p2l_map->band_dma_md->p2l_map_checksum = 0;

	ftl_md_persist_entry(md, band->id, p2l_map->band_dma_md, NULL,
+2 −1
Original line number Diff line number Diff line
@@ -151,7 +151,8 @@ ftl_invalidate_addr(struct spdk_ftl_dev *dev, ftl_addr addr)
	/* Invalidate open/full band p2l_map entry to keep p2l and l2p
	 * consistency when band is going to close state */
	if (FTL_BAND_STATE_OPEN == band->md->state || FTL_BAND_STATE_FULL == band->md->state) {
		p2l_map->band_map[ftl_band_block_offset_from_addr(band, addr)] = FTL_LBA_INVALID;
		p2l_map->band_map[ftl_band_block_offset_from_addr(band, addr)].lba = FTL_LBA_INVALID;
		p2l_map->band_map[ftl_band_block_offset_from_addr(band, addr)].seq_id = 0;
	}
}

+10 −2
Original line number Diff line number Diff line
@@ -183,6 +183,8 @@ bool ftl_needs_reloc(struct spdk_ftl_dev *dev);

struct ftl_band *ftl_band_get_next_free(struct spdk_ftl_dev *dev);

void ftl_recover_max_seq(struct spdk_ftl_dev *dev);

static inline uint64_t
ftl_get_num_blocks_in_band(const struct spdk_ftl_dev *dev)
{
@@ -250,11 +252,17 @@ ftl_addr_from_nvc_offset(const struct spdk_ftl_dev *dev, uint64_t cache_offset)
	return cache_offset + dev->layout.base.total_blocks;
}

static inline uint64_t
ftl_get_next_seq_id(struct spdk_ftl_dev *dev)
{
	return ++dev->sb->seq_id;
}

static inline size_t
ftl_p2l_map_num_blocks(const struct spdk_ftl_dev *dev)
{
	return spdk_divide_round_up(ftl_get_num_blocks_in_band(dev) * sizeof(uint64_t),
				    FTL_BLOCK_SIZE);
	return spdk_divide_round_up(ftl_get_num_blocks_in_band(dev) *
				    sizeof(struct ftl_p2l_map_entry), FTL_BLOCK_SIZE);
}

static inline size_t
Loading