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:
parent
bf4973087f
commit
2cc6bd2a26
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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) }
|
||||
|
@ -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++;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
|
Loading…
Reference in New Issue
Block a user