FTL: Add internal band state changes
Signed-off-by: Kozlowski Mateusz <mateusz.kozlowski@intel.com> Signed-off-by: Artur Paszkiewicz <artur.paszkiewicz@intel.com> Change-Id: Icaecc4e77996919a23f70c1ffad15b783741fd5e Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/13327 Reviewed-by: Ben Walker <benjamin.walker@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
This commit is contained in:
parent
0f99700db9
commit
8c519d31bd
@ -59,6 +59,52 @@ ftl_band_free_md_entry(struct ftl_band *band)
|
||||
p2l_map->band_dma_md = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
_ftl_band_set_free(struct ftl_band *band)
|
||||
{
|
||||
struct spdk_ftl_dev *dev = band->dev;
|
||||
|
||||
/* Add the band to the free band list */
|
||||
TAILQ_INSERT_TAIL(&dev->free_bands, band, queue_entry);
|
||||
|
||||
dev->num_free++;
|
||||
ftl_apply_limits(dev);
|
||||
}
|
||||
|
||||
static void
|
||||
_ftl_band_set_preparing(struct ftl_band *band)
|
||||
{
|
||||
struct spdk_ftl_dev *dev = band->dev;
|
||||
|
||||
/* Remove band from free list */
|
||||
TAILQ_REMOVE(&dev->free_bands, band, queue_entry);
|
||||
|
||||
band->md->wr_cnt++;
|
||||
|
||||
assert(dev->num_free > 0);
|
||||
dev->num_free--;
|
||||
|
||||
ftl_apply_limits(dev);
|
||||
}
|
||||
|
||||
static void
|
||||
_ftl_band_set_closed(struct ftl_band *band)
|
||||
{
|
||||
struct spdk_ftl_dev *dev = band->dev;
|
||||
|
||||
/* Set the state as free_md() checks for that */
|
||||
band->md->state = FTL_BAND_STATE_CLOSED;
|
||||
if (band->owner.state_change_fn) {
|
||||
band->owner.state_change_fn(band);
|
||||
}
|
||||
|
||||
/* Free the p2l map if there are no outstanding IOs */
|
||||
ftl_band_release_p2l_map(band);
|
||||
assert(band->p2l_map.ref_cnt == 0);
|
||||
|
||||
TAILQ_INSERT_TAIL(&dev->shut_bands, band, queue_entry);
|
||||
}
|
||||
|
||||
ftl_addr
|
||||
ftl_band_tail_md_addr(struct ftl_band *band)
|
||||
{
|
||||
@ -72,6 +118,46 @@ ftl_band_tail_md_addr(struct ftl_band *band)
|
||||
return addr;
|
||||
}
|
||||
|
||||
void
|
||||
ftl_band_set_state(struct ftl_band *band, enum ftl_band_state state)
|
||||
{
|
||||
switch (state) {
|
||||
case FTL_BAND_STATE_FREE:
|
||||
assert(band->md->state == FTL_BAND_STATE_CLOSED);
|
||||
_ftl_band_set_free(band);
|
||||
|
||||
band->md->p2l_map_checksum = 0;
|
||||
break;
|
||||
|
||||
case FTL_BAND_STATE_PREP:
|
||||
assert(band->md->state == FTL_BAND_STATE_FREE);
|
||||
_ftl_band_set_preparing(band);
|
||||
break;
|
||||
|
||||
case FTL_BAND_STATE_CLOSED:
|
||||
if (band->md->state != FTL_BAND_STATE_CLOSED) {
|
||||
assert(band->md->state == FTL_BAND_STATE_CLOSING);
|
||||
_ftl_band_set_closed(band);
|
||||
return; /* state can be changed asynchronously */
|
||||
}
|
||||
break;
|
||||
|
||||
case FTL_BAND_STATE_OPEN:
|
||||
band->md->p2l_map_checksum = 0;
|
||||
break;
|
||||
case FTL_BAND_STATE_OPENING:
|
||||
case FTL_BAND_STATE_FULL:
|
||||
case FTL_BAND_STATE_CLOSING:
|
||||
break;
|
||||
default:
|
||||
FTL_ERRLOG(band->dev, "Unknown band state, %u", state);
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
|
||||
band->md->state = state;
|
||||
}
|
||||
|
||||
void
|
||||
ftl_band_set_type(struct ftl_band *band, enum ftl_band_type type)
|
||||
{
|
||||
|
@ -26,6 +26,15 @@ spdk_ftl_io_size(void)
|
||||
return sizeof(struct ftl_io);
|
||||
}
|
||||
|
||||
static void
|
||||
ftl_band_erase(struct ftl_band *band)
|
||||
{
|
||||
assert(band->md->state == FTL_BAND_STATE_CLOSED ||
|
||||
band->md->state == FTL_BAND_STATE_FREE);
|
||||
|
||||
ftl_band_set_state(band, FTL_BAND_STATE_PREP);
|
||||
}
|
||||
|
||||
static size_t
|
||||
ftl_get_limit(const struct spdk_ftl_dev *dev, int type)
|
||||
{
|
||||
@ -263,6 +272,20 @@ ftl_core_poller(void *ctx)
|
||||
return SPDK_POLLER_IDLE;
|
||||
}
|
||||
|
||||
struct ftl_band *
|
||||
ftl_band_get_next_free(struct spdk_ftl_dev *dev)
|
||||
{
|
||||
struct ftl_band *band = NULL;
|
||||
|
||||
if (!TAILQ_EMPTY(&dev->free_bands)) {
|
||||
band = TAILQ_FIRST(&dev->free_bands);
|
||||
TAILQ_REMOVE(&dev->free_bands, band, queue_entry);
|
||||
ftl_band_erase(band);
|
||||
}
|
||||
|
||||
return band;
|
||||
}
|
||||
|
||||
void *g_ftl_write_buf;
|
||||
void *g_ftl_read_buf;
|
||||
|
||||
|
@ -150,6 +150,8 @@ int ftl_io_channel_poll(void *arg);
|
||||
|
||||
struct ftl_io_channel *ftl_io_channel_get_ctx(struct spdk_io_channel *ioch);
|
||||
|
||||
struct ftl_band *ftl_band_get_next_free(struct spdk_ftl_dev *dev);
|
||||
|
||||
static inline uint64_t
|
||||
ftl_get_num_blocks_in_band(const struct spdk_ftl_dev *dev)
|
||||
{
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
#include "ftl_io.h"
|
||||
#include "ftl_core.h"
|
||||
#include "ftl_band.h"
|
||||
#include "ftl_debug.h"
|
||||
|
||||
void
|
||||
@ -238,4 +239,5 @@ ftl_io_clear(struct ftl_io *io)
|
||||
io->done = false;
|
||||
io->status = 0;
|
||||
io->flags = 0;
|
||||
io->band = NULL;
|
||||
}
|
||||
|
@ -88,6 +88,9 @@ struct ftl_io {
|
||||
/* Offset within the iovec (in blocks) */
|
||||
size_t iov_off;
|
||||
|
||||
/* Band this IO is being written to */
|
||||
struct ftl_band *band;
|
||||
|
||||
/* Request status */
|
||||
int status;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user