lib/ftl: separate non-volatile header write function

The header is being written from multiple places, so having a discrete
function serializing and writing it at the appropriate place in the
cache makes sense.

Change-Id: I7a1e6ebd05e8a4974d141f04202803f507b978e4
Signed-off-by: Konrad Sztyber <konrad.sztyber@intel.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/459620
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Darek Stojaczyk <dariusz.stojaczyk@intel.com>
Reviewed-by: Wojciech Malikowski <wojciech.malikowski@intel.com>
Reviewed-by: Mateusz Kozlowski <mateusz.kozlowski@intel.com>
This commit is contained in:
Konrad Sztyber 2019-06-25 09:14:57 +02:00 committed by Ben Walker
parent 78154d9558
commit 8d1bb260ea
3 changed files with 31 additions and 47 deletions

View File

@ -1060,24 +1060,10 @@ ftl_nv_cache_wrap_cb(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg)
static void
ftl_nv_cache_wrap(void *ctx)
{
struct spdk_ftl_dev *dev = ctx;
struct ftl_nv_cache *nv_cache = &dev->nv_cache;
struct ftl_nv_cache_header *hdr = nv_cache->dma_buf;
struct ftl_io_channel *ioch;
struct spdk_bdev *bdev;
struct ftl_nv_cache *nv_cache = ctx;
int rc;
ioch = spdk_io_channel_get_ctx(dev->ioch);
bdev = spdk_bdev_desc_get_bdev(nv_cache->bdev_desc);
hdr->uuid = dev->uuid;
hdr->size = spdk_bdev_get_num_blocks(bdev);
hdr->version = FTL_NV_CACHE_HEADER_VERSION;
hdr->phase = (uint8_t)nv_cache->phase;
hdr->checksum = spdk_crc32c_update(hdr, offsetof(struct ftl_nv_cache_header, checksum), 0);
rc = spdk_bdev_write_blocks(nv_cache->bdev_desc, ioch->cache_ioch, hdr, 0, 1,
ftl_nv_cache_wrap_cb, nv_cache);
rc = ftl_nv_cache_write_header(nv_cache, ftl_nv_cache_wrap_cb, nv_cache);
if (spdk_unlikely(rc != 0)) {
SPDK_ERRLOG("Unable to write non-volatile cache metadata header: %s\n",
spdk_strerror(-rc));
@ -1118,7 +1104,7 @@ ftl_reserve_nv_cache(struct ftl_nv_cache *nv_cache, size_t *num_lbks, unsigned i
nv_cache->current_addr = FTL_NV_CACHE_DATA_OFFSET;
nv_cache->phase = ftl_nv_cache_next_phase(nv_cache->phase);
nv_cache->ready = false;
spdk_thread_send_msg(ftl_get_core_thread(dev), ftl_nv_cache_wrap, dev);
spdk_thread_send_msg(ftl_get_core_thread(dev), ftl_nv_cache_wrap, nv_cache);
}
out:
pthread_spin_unlock(&nv_cache->lock);
@ -1266,6 +1252,30 @@ ftl_write_nv_cache(struct ftl_io *parent)
_ftl_write_nv_cache(parent);
}
int
ftl_nv_cache_write_header(struct ftl_nv_cache *nv_cache, spdk_bdev_io_completion_cb cb_fn,
void *cb_arg)
{
struct spdk_ftl_dev *dev = SPDK_CONTAINEROF(nv_cache, struct spdk_ftl_dev, nv_cache);
struct ftl_nv_cache_header *hdr = nv_cache->dma_buf;
struct spdk_bdev *bdev;
struct ftl_io_channel *ioch;
bdev = spdk_bdev_desc_get_bdev(nv_cache->bdev_desc);
ioch = spdk_io_channel_get_ctx(dev->ioch);
memset(hdr, 0, spdk_bdev_get_block_size(bdev));
hdr->phase = (uint8_t)nv_cache->phase;
hdr->size = spdk_bdev_get_num_blocks(bdev);
hdr->uuid = dev->uuid;
hdr->version = FTL_NV_CACHE_HEADER_VERSION;
hdr->checksum = spdk_crc32c_update(hdr, offsetof(struct ftl_nv_cache_header, checksum), 0);
return spdk_bdev_write_blocks(nv_cache->bdev_desc, ioch->cache_ioch, hdr, 0, 1,
cb_fn, cb_arg);
}
static void
ftl_write_fail(struct ftl_io *io, int status)
{

View File

@ -294,6 +294,8 @@ int ftl_retrieve_chunk_info(struct spdk_ftl_dev *dev, struct ftl_ppa ppa,
unsigned int num_entries);
bool ftl_ppa_is_written(struct ftl_band *band, struct ftl_ppa ppa);
int ftl_flush_active_bands(struct spdk_ftl_dev *dev, spdk_ftl_fn cb_fn, void *cb_arg);
int ftl_nv_cache_write_header(struct ftl_nv_cache *nv_cache, spdk_bdev_io_completion_cb cb_fn,
void *cb_arg);
#define ftl_to_ppa(addr) \
(struct ftl_ppa) { .ppa = (uint64_t)(addr) }

View File

@ -41,7 +41,6 @@
#include "spdk/ftl.h"
#include "spdk/likely.h"
#include "spdk/string.h"
#include "spdk/crc32.h"
#include "ftl_core.h"
#include "ftl_anm.h"
@ -872,13 +871,8 @@ static void
ftl_write_nv_cache_md_cb(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg)
{
struct spdk_ftl_dev *dev = cb_arg;
struct iovec *iovs = NULL;
int iov_cnt = 0;
spdk_bdev_io_get_iovec(bdev_io, &iovs, &iov_cnt);
spdk_dma_free(iovs[0].iov_base);
spdk_bdev_free_io(bdev_io);
if (spdk_unlikely(!success)) {
SPDK_ERRLOG("Writing non-volatile cache's metadata header failed\n");
ftl_init_fail(dev);
@ -893,40 +887,18 @@ static void
ftl_clear_nv_cache_cb(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg)
{
struct spdk_ftl_dev *dev = cb_arg;
struct spdk_bdev *bdev;
struct ftl_nv_cache *nv_cache = &dev->nv_cache;
struct ftl_io_channel *ioch;
struct ftl_nv_cache_header *hdr;
spdk_bdev_free_io(bdev_io);
ioch = spdk_io_channel_get_ctx(dev->ioch);
bdev = spdk_bdev_desc_get_bdev(nv_cache->bdev_desc);
if (spdk_unlikely(!success)) {
SPDK_ERRLOG("Unable to clear the non-volatile cache bdev\n");
ftl_init_fail(dev);
return;
}
assert(sizeof(*hdr) <= spdk_bdev_get_block_size(bdev));
hdr = spdk_dma_zmalloc(spdk_bdev_get_block_size(bdev), spdk_bdev_get_buf_align(bdev), NULL);
if (spdk_unlikely(!hdr)) {
SPDK_ERRLOG("Memory allocation failure\n");
ftl_init_fail(dev);
return;
}
hdr->uuid = dev->uuid;
hdr->size = spdk_bdev_get_num_blocks(bdev);
hdr->version = FTL_NV_CACHE_HEADER_VERSION;
hdr->phase = dev->nv_cache.phase = 1;
hdr->checksum = spdk_crc32c_update(hdr, offsetof(struct ftl_nv_cache_header, checksum), 0);
if (spdk_bdev_write_blocks(nv_cache->bdev_desc, ioch->cache_ioch, hdr, 0, 1,
ftl_write_nv_cache_md_cb, dev)) {
nv_cache->phase = 1;
if (ftl_nv_cache_write_header(nv_cache, ftl_write_nv_cache_md_cb, dev)) {
SPDK_ERRLOG("Unable to write non-volatile cache metadata header\n");
spdk_dma_free(hdr);
ftl_init_fail(dev);
}
}