lib/ftl: Skip block with ongoing write during relocation

In case ANM event occurs on open band there
can be situation that reloc will try to read
block on which there is ongoing write.
This is happening because lba valid map is
updated before write  submission to allow sent
consistent metadata to disk before all user
writes are completed.

Added write offset to the each chunk and
add check to reloc if particular ppa is written
on that chunk.

Change-Id: Ic95a06e69381d2152a86984b65a0975afaff955d
Signed-off-by: Wojciech Malikowski <wojciech.malikowski@intel.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/458056
Reviewed-by: Konrad Sztyber <konrad.sztyber@intel.com>
Reviewed-by: Darek Stojaczyk <dariusz.stojaczyk@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
This commit is contained in:
Wojciech Malikowski 2019-06-14 05:21:33 -04:00 committed by Darek Stojaczyk
parent bf4973087f
commit 2cc6bd2a26
7 changed files with 20 additions and 1 deletions

View File

@ -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

View File

@ -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;

View File

@ -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)
{

View File

@ -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) }

View File

@ -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++;

View File

@ -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);
}

View File

@ -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));