lib/ftl: Move zone reset logic from band to core

Sine core module is responsible for handling IO it
should also handling zone reset logic.

Change-Id: Id8be4bb221cc85f207d44bd45761a72e263ea5ce
Signed-off-by: Wojciech Malikowski <wojciech.malikowski@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/551
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Konrad Sztyber <konrad.sztyber@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
This commit is contained in:
Wojciech Malikowski 2020-01-30 05:02:48 -05:00 committed by Tomasz Zawadzki
parent c3e0eb456b
commit b75b3553aa
4 changed files with 82 additions and 80 deletions

View File

@ -1015,83 +1015,13 @@ ftl_band_read_head_md(struct ftl_band *band, ftl_io_fn cb_fn, void *cb_ctx)
cb_ctx); cb_ctx);
} }
static void void
ftl_band_remove_zone(struct ftl_band *band, struct ftl_zone *zone) ftl_band_remove_zone(struct ftl_band *band, struct ftl_zone *zone)
{ {
CIRCLEQ_REMOVE(&band->zones, zone, circleq); CIRCLEQ_REMOVE(&band->zones, zone, circleq);
band->num_zones--; band->num_zones--;
} }
static void
ftl_erase_fail(struct ftl_io *io, int status)
{
struct ftl_zone *zone;
struct ftl_band *band = io->band;
char buf[128];
SPDK_ERRLOG("Erase failed @addr: %s, status: %d\n",
ftl_addr2str(io->addr, buf, sizeof(buf)), status);
zone = ftl_band_zone_from_addr(band, io->addr);
zone->info.state = SPDK_BDEV_ZONE_STATE_OFFLINE;
ftl_band_remove_zone(band, zone);
band->tail_md_addr = ftl_band_tail_md_addr(band);
}
static void
ftl_band_erase_cb(struct ftl_io *io, void *ctx, int status)
{
struct ftl_zone *zone;
zone = ftl_band_zone_from_addr(io->band, io->addr);
zone->busy = false;
if (spdk_unlikely(status)) {
ftl_erase_fail(io, status);
return;
}
zone->info.state = SPDK_BDEV_ZONE_STATE_EMPTY;
zone->info.write_pointer = zone->info.zone_id;
}
int
ftl_band_erase(struct ftl_band *band)
{
struct ftl_zone *zone;
struct ftl_io *io;
int rc = 0;
assert(band->state == FTL_BAND_STATE_CLOSED ||
band->state == FTL_BAND_STATE_FREE);
ftl_band_set_state(band, FTL_BAND_STATE_PREP);
CIRCLEQ_FOREACH(zone, &band->zones, circleq) {
if (zone->info.state == SPDK_BDEV_ZONE_STATE_EMPTY) {
continue;
}
io = ftl_io_erase_init(band, 1, ftl_band_erase_cb);
if (!io) {
rc = -ENOMEM;
break;
}
zone->busy = true;
io->addr.offset = zone->info.zone_id;
rc = ftl_io_erase(io);
if (rc) {
zone->busy = false;
assert(0);
/* TODO: change band's state back to close? */
break;
}
}
return rc;
}
int int
ftl_band_write_prep(struct ftl_band *band) ftl_band_write_prep(struct ftl_band *band)
{ {

View File

@ -214,11 +214,12 @@ struct ftl_addr ftl_band_tail_md_addr(struct ftl_band *band);
struct ftl_addr ftl_band_head_md_addr(struct ftl_band *band); struct ftl_addr ftl_band_head_md_addr(struct ftl_band *band);
void ftl_band_write_failed(struct ftl_band *band); void ftl_band_write_failed(struct ftl_band *band);
int ftl_band_full(struct ftl_band *band, size_t offset); int ftl_band_full(struct ftl_band *band, size_t offset);
int ftl_band_erase(struct ftl_band *band);
int ftl_band_write_prep(struct ftl_band *band); int ftl_band_write_prep(struct ftl_band *band);
struct ftl_zone *ftl_band_next_operational_zone(struct ftl_band *band, struct ftl_zone *ftl_band_next_operational_zone(struct ftl_band *band,
struct ftl_zone *zone); struct ftl_zone *zone);
size_t ftl_lba_map_pool_elem_size(struct spdk_ftl_dev *dev); size_t ftl_lba_map_pool_elem_size(struct spdk_ftl_dev *dev);
void ftl_band_remove_zone(struct ftl_band *band, struct ftl_zone *zone);
static inline int static inline int
ftl_band_empty(const struct ftl_band *band) ftl_band_empty(const struct ftl_band *band)

View File

@ -384,12 +384,6 @@ ftl_submit_erase(struct ftl_io *io)
return rc; return rc;
} }
static void
_ftl_io_erase(void *ctx)
{
ftl_io_erase((struct ftl_io *)ctx);
}
static bool static bool
ftl_check_core_thread(const struct spdk_ftl_dev *dev) ftl_check_core_thread(const struct spdk_ftl_dev *dev)
{ {
@ -406,7 +400,15 @@ ftl_get_io_channel(const struct spdk_ftl_dev *dev)
return NULL; return NULL;
} }
int static int ftl_io_erase(struct ftl_io *io);
static void
_ftl_io_erase(void *ctx)
{
ftl_io_erase((struct ftl_io *)ctx);
}
static int
ftl_io_erase(struct ftl_io *io) ftl_io_erase(struct ftl_io *io)
{ {
struct spdk_ftl_dev *dev = io->dev; struct spdk_ftl_dev *dev = io->dev;
@ -419,6 +421,76 @@ ftl_io_erase(struct ftl_io *io)
return 0; return 0;
} }
static void
ftl_erase_fail(struct ftl_io *io, int status)
{
struct ftl_zone *zone;
struct ftl_band *band = io->band;
char buf[128];
SPDK_ERRLOG("Erase failed at address: %s, status: %d\n",
ftl_addr2str(io->addr, buf, sizeof(buf)), status);
zone = ftl_band_zone_from_addr(band, io->addr);
zone->info.state = SPDK_BDEV_ZONE_STATE_OFFLINE;
ftl_band_remove_zone(band, zone);
band->tail_md_addr = ftl_band_tail_md_addr(band);
}
static void
ftl_zone_erase_cb(struct ftl_io *io, void *ctx, int status)
{
struct ftl_zone *zone;
zone = ftl_band_zone_from_addr(io->band, io->addr);
zone->busy = false;
if (spdk_unlikely(status)) {
ftl_erase_fail(io, status);
return;
}
zone->info.state = SPDK_BDEV_ZONE_STATE_EMPTY;
zone->info.write_pointer = zone->info.zone_id;
}
static int
ftl_band_erase(struct ftl_band *band)
{
struct ftl_zone *zone;
struct ftl_io *io;
int rc = 0;
assert(band->state == FTL_BAND_STATE_CLOSED ||
band->state == FTL_BAND_STATE_FREE);
ftl_band_set_state(band, FTL_BAND_STATE_PREP);
CIRCLEQ_FOREACH(zone, &band->zones, circleq) {
if (zone->info.state == SPDK_BDEV_ZONE_STATE_EMPTY) {
continue;
}
io = ftl_io_erase_init(band, 1, ftl_zone_erase_cb);
if (!io) {
rc = -ENOMEM;
break;
}
zone->busy = true;
io->addr.offset = zone->info.zone_id;
rc = ftl_io_erase(io);
if (rc) {
zone->busy = false;
assert(0);
/* TODO: change band's state back to close? */
break;
}
}
return rc;
}
static struct ftl_band * static struct ftl_band *
ftl_next_write_band(struct spdk_ftl_dev *dev) ftl_next_write_band(struct spdk_ftl_dev *dev)
{ {

View File

@ -261,7 +261,6 @@ typedef void (*ftl_restore_fn)(struct spdk_ftl_dev *, struct ftl_restore *, int)
void ftl_apply_limits(struct spdk_ftl_dev *dev); void ftl_apply_limits(struct spdk_ftl_dev *dev);
void ftl_io_read(struct ftl_io *io); void ftl_io_read(struct ftl_io *io);
void ftl_io_write(struct ftl_io *io); void ftl_io_write(struct ftl_io *io);
int ftl_io_erase(struct ftl_io *io);
int ftl_flush_rwb(struct spdk_ftl_dev *dev, spdk_ftl_fn cb_fn, void *cb_arg); int ftl_flush_rwb(struct spdk_ftl_dev *dev, spdk_ftl_fn cb_fn, void *cb_arg);
int ftl_current_limit(const struct spdk_ftl_dev *dev); int ftl_current_limit(const struct spdk_ftl_dev *dev);
int ftl_invalidate_addr(struct spdk_ftl_dev *dev, struct ftl_addr addr); int ftl_invalidate_addr(struct spdk_ftl_dev *dev, struct ftl_addr addr);