FTL: Add band state change functions
Signed-off-by: Kozlowski Mateusz <mateusz.kozlowski@intel.com> Signed-off-by: Artur Paszkiewicz <artur.paszkiewicz@intel.com> Change-Id: I6a985f0b54a05fbebb8d65343cffaed7e47ed60d Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/13332 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
parent
7c9d3ea595
commit
5af491a2ee
@ -145,6 +145,9 @@ int ftl_band_filled(struct ftl_band *band, size_t offset);
|
||||
int ftl_band_write_prep(struct ftl_band *band);
|
||||
size_t ftl_p2l_map_pool_elem_size(struct spdk_ftl_dev *dev);
|
||||
ftl_addr ftl_band_p2l_map_addr(struct ftl_band *band);
|
||||
void ftl_band_open(struct ftl_band *band, enum ftl_band_type type);
|
||||
void ftl_band_close(struct ftl_band *band);
|
||||
void ftl_band_free(struct ftl_band *band);
|
||||
void ftl_band_rq_write(struct ftl_band *band, struct ftl_rq *rq);
|
||||
void ftl_band_rq_read(struct ftl_band *band, struct ftl_rq *rq);
|
||||
void ftl_band_basic_rq_write(struct ftl_band *band, struct ftl_basic_rq *brq);
|
||||
|
@ -251,6 +251,137 @@ ftl_band_basic_rq_read(struct ftl_band *band, struct ftl_basic_rq *brq)
|
||||
dev->io_activity_total += brq->num_blocks;
|
||||
}
|
||||
|
||||
static void
|
||||
band_open_cb(int status, void *cb_arg)
|
||||
{
|
||||
struct ftl_band *band = cb_arg;
|
||||
|
||||
if (spdk_unlikely(status)) {
|
||||
ftl_md_persist_entry_retry(&band->md_persist_entry_ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
ftl_band_set_state(band, FTL_BAND_STATE_OPEN);
|
||||
}
|
||||
|
||||
void
|
||||
ftl_band_open(struct ftl_band *band, enum ftl_band_type type)
|
||||
{
|
||||
struct spdk_ftl_dev *dev = band->dev;
|
||||
struct ftl_md *md = dev->layout.md[FTL_LAYOUT_REGION_TYPE_BAND_MD];
|
||||
struct ftl_layout_region *region = &dev->layout.region[FTL_LAYOUT_REGION_TYPE_BAND_MD];
|
||||
struct ftl_p2l_map *p2l_map = &band->p2l_map;
|
||||
|
||||
ftl_band_set_type(band, type);
|
||||
ftl_band_set_state(band, FTL_BAND_STATE_OPENING);
|
||||
|
||||
memcpy(p2l_map->band_dma_md, band->md, region->entry_size * FTL_BLOCK_SIZE);
|
||||
p2l_map->band_dma_md->state = FTL_BAND_STATE_OPEN;
|
||||
p2l_map->band_dma_md->p2l_map_checksum = 0;
|
||||
|
||||
if (spdk_unlikely(0 != band->p2l_map.num_valid)) {
|
||||
/*
|
||||
* This is inconsistent state, a band with valid block,
|
||||
* it could be moved on the free list
|
||||
*/
|
||||
assert(false && 0 == band->p2l_map.num_valid);
|
||||
ftl_abort();
|
||||
}
|
||||
|
||||
ftl_md_persist_entry(md, band->id, p2l_map->band_dma_md, NULL,
|
||||
band_open_cb, band, &band->md_persist_entry_ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
band_close_cb(int status, void *cb_arg)
|
||||
{
|
||||
struct ftl_band *band = cb_arg;
|
||||
|
||||
if (spdk_unlikely(status)) {
|
||||
ftl_md_persist_entry_retry(&band->md_persist_entry_ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
band->md->p2l_map_checksum = band->p2l_map.band_dma_md->p2l_map_checksum;
|
||||
ftl_band_set_state(band, FTL_BAND_STATE_CLOSED);
|
||||
}
|
||||
|
||||
static void
|
||||
band_map_write_cb(struct ftl_basic_rq *brq)
|
||||
{
|
||||
struct ftl_band *band = brq->io.band;
|
||||
struct ftl_p2l_map *p2l_map = &band->p2l_map;
|
||||
struct spdk_ftl_dev *dev = band->dev;
|
||||
struct ftl_layout_region *region = &dev->layout.region[FTL_LAYOUT_REGION_TYPE_BAND_MD];
|
||||
struct ftl_md *md = dev->layout.md[FTL_LAYOUT_REGION_TYPE_BAND_MD];
|
||||
uint32_t band_map_crc;
|
||||
|
||||
if (spdk_likely(brq->success)) {
|
||||
|
||||
band_map_crc = spdk_crc32c_update(p2l_map->band_map,
|
||||
ftl_tail_md_num_blocks(dev) * FTL_BLOCK_SIZE, 0);
|
||||
memcpy(p2l_map->band_dma_md, band->md, region->entry_size * FTL_BLOCK_SIZE);
|
||||
p2l_map->band_dma_md->state = FTL_BAND_STATE_CLOSED;
|
||||
p2l_map->band_dma_md->p2l_map_checksum = band_map_crc;
|
||||
|
||||
ftl_md_persist_entry(md, band->id, p2l_map->band_dma_md, NULL,
|
||||
band_close_cb, band, &band->md_persist_entry_ctx);
|
||||
} else {
|
||||
/* Try to retry in case of failure */
|
||||
ftl_band_brq_bdev_write(brq);
|
||||
band->queue_depth++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ftl_band_close(struct ftl_band *band)
|
||||
{
|
||||
struct spdk_ftl_dev *dev = band->dev;
|
||||
void *metadata = band->p2l_map.band_map;
|
||||
uint64_t num_blocks = ftl_tail_md_num_blocks(dev);
|
||||
|
||||
/* Write LBA map first, after completion, set the state to close on nvcache, then internally */
|
||||
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);
|
||||
|
||||
ftl_band_basic_rq_write(band, &band->metadata_rq);
|
||||
}
|
||||
|
||||
static void
|
||||
band_free_cb(int status, void *ctx)
|
||||
{
|
||||
struct ftl_band *band = (struct ftl_band *)ctx;
|
||||
|
||||
if (spdk_unlikely(status)) {
|
||||
ftl_md_persist_entry_retry(&band->md_persist_entry_ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
ftl_band_release_p2l_map(band);
|
||||
FTL_DEBUGLOG(band->dev, "Band is going to free state. Band id: %u\n", band->id);
|
||||
ftl_band_set_state(band, FTL_BAND_STATE_FREE);
|
||||
assert(0 == band->p2l_map.ref_cnt);
|
||||
}
|
||||
|
||||
void
|
||||
ftl_band_free(struct ftl_band *band)
|
||||
{
|
||||
struct spdk_ftl_dev *dev = band->dev;
|
||||
struct ftl_p2l_map *p2l_map = &band->p2l_map;
|
||||
struct ftl_md *md = dev->layout.md[FTL_LAYOUT_REGION_TYPE_BAND_MD];
|
||||
struct ftl_layout_region *region = &dev->layout.region[FTL_LAYOUT_REGION_TYPE_BAND_MD];
|
||||
|
||||
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->p2l_map_checksum = 0;
|
||||
|
||||
ftl_md_persist_entry(md, band->id, p2l_map->band_dma_md, NULL,
|
||||
band_free_cb, band, &band->md_persist_entry_ctx);
|
||||
|
||||
/* TODO: The whole band erase code should probably be done here instead */
|
||||
}
|
||||
|
||||
static void
|
||||
read_tail_md_cb(struct ftl_basic_rq *brq)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user