Commit 8c519d31 authored by Kozlowski Mateusz's avatar Kozlowski Mateusz Committed by Jim Harris
Browse files

FTL: Add internal band state changes

parent 0f99700d
Loading
Loading
Loading
Loading
+86 −0
Original line number Diff line number Diff line
@@ -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)
{
+23 −0
Original line number Diff line number Diff line
@@ -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;

+2 −0
Original line number Diff line number Diff line
@@ -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)
{
+2 −0
Original line number Diff line number Diff line
@@ -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;
}
+3 −0
Original line number Diff line number Diff line
@@ -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;