diff --git a/lib/ftl/ftl_band.c b/lib/ftl/ftl_band.c index 775166766..ebd84dc99 100644 --- a/lib/ftl/ftl_band.c +++ b/lib/ftl/ftl_band.c @@ -1096,6 +1096,7 @@ ftl_band_erase_cb(struct ftl_io *io, void *ctx, int status) } chunk = ftl_band_chunk_from_ppa(io->band, io->ppa); chunk->state = FTL_CHUNK_STATE_FREE; + chunk->write_offset = 0; } int diff --git a/lib/ftl/ftl_band.h b/lib/ftl/ftl_band.h index d0afbad0d..29b81f844 100644 --- a/lib/ftl/ftl_band.h +++ b/lib/ftl/ftl_band.h @@ -63,6 +63,9 @@ struct ftl_chunk { /* Indicates that there is inflight write */ bool busy; + /* Current logical block's offset */ + uint64_t write_offset; + /* First PPA */ struct ftl_ppa start_ppa; diff --git a/lib/ftl/ftl_core.c b/lib/ftl/ftl_core.c index b20b750b7..2a6103633 100644 --- a/lib/ftl/ftl_core.c +++ b/lib/ftl/ftl_core.c @@ -1283,6 +1283,7 @@ ftl_io_child_write_cb(struct ftl_io *io, void *ctx, int status) chunk = ftl_band_chunk_from_ppa(io->band, io->ppa); chunk->busy = false; + chunk->write_offset += io->lbk_cnt; } static int @@ -1913,6 +1914,14 @@ ftl_process_anm_event(struct ftl_anm_event *event) ftl_anm_event_complete(event); } +bool +ftl_ppa_is_written(struct ftl_band *band, struct ftl_ppa ppa) +{ + struct ftl_chunk *chunk = ftl_band_chunk_from_ppa(band, ppa); + + return ppa.lbk < chunk->write_offset; +} + static void ftl_process_retry_queue(struct spdk_ftl_dev *dev) { diff --git a/lib/ftl/ftl_core.h b/lib/ftl/ftl_core.h index 3fbabc974..2455a1aac 100644 --- a/lib/ftl/ftl_core.h +++ b/lib/ftl/ftl_core.h @@ -257,6 +257,7 @@ int ftl_band_set_direct_access(struct ftl_band *band, bool access); int ftl_retrieve_chunk_info(struct spdk_ftl_dev *dev, struct ftl_ppa ppa, struct spdk_ocssd_chunk_information_entry *info, unsigned int num_entries); +bool ftl_ppa_is_written(struct ftl_band *band, struct ftl_ppa ppa); #define ftl_to_ppa(addr) \ (struct ftl_ppa) { .ppa = (uint64_t)(addr) } diff --git a/lib/ftl/ftl_init.c b/lib/ftl/ftl_init.c index c974244f1..ad9293532 100644 --- a/lib/ftl/ftl_init.c +++ b/lib/ftl/ftl_init.c @@ -369,6 +369,7 @@ ftl_dev_init_bands(struct spdk_ftl_dev *dev) chunk->punit = punit; chunk->start_ppa = punit->start_ppa; chunk->start_ppa.chk = band->id; + chunk->write_offset = ftl_dev_lbks_in_chunk(dev); if (chunk->state != FTL_CHUNK_STATE_BAD) { band->num_chunks++; diff --git a/lib/ftl/ftl_reloc.c b/lib/ftl/ftl_reloc.c index 3ebd8cc34..2f24e1751 100644 --- a/lib/ftl/ftl_reloc.c +++ b/lib/ftl/ftl_reloc.c @@ -304,7 +304,10 @@ ftl_reloc_iter_next_chk(struct ftl_band_reloc *breloc) static int ftl_reloc_lbk_valid(struct ftl_band_reloc *breloc, size_t lbkoff) { - return spdk_bit_array_get(breloc->reloc_map, lbkoff) && + struct ftl_ppa ppa = ftl_band_ppa_from_lbkoff(breloc->band, lbkoff); + + return ftl_ppa_is_written(breloc->band, ppa) && + spdk_bit_array_get(breloc->reloc_map, lbkoff) && ftl_band_lbkoff_valid(breloc->band, lbkoff); } diff --git a/test/unit/lib/ftl/ftl_reloc.c/ftl_reloc_ut.c b/test/unit/lib/ftl/ftl_reloc.c/ftl_reloc_ut.c index 39372d968..db04f9106 100644 --- a/test/unit/lib/ftl/ftl_reloc.c/ftl_reloc_ut.c +++ b/test/unit/lib/ftl/ftl_reloc.c/ftl_reloc_ut.c @@ -57,6 +57,7 @@ static struct spdk_ftl_punit_range g_range = { }; DEFINE_STUB(ftl_dev_tail_md_disk_size, size_t, (const struct spdk_ftl_dev *dev), 1); +DEFINE_STUB(ftl_ppa_is_written, bool, (struct ftl_band *band, struct ftl_ppa ppa), true); DEFINE_STUB_V(ftl_band_set_state, (struct ftl_band *band, enum ftl_band_state state)); DEFINE_STUB_V(ftl_trace_lba_io_init, (struct spdk_ftl_dev *dev, const struct ftl_io *io)); DEFINE_STUB_V(ftl_free_io, (struct ftl_io *io));