lib/ftl: restore non-volatile cache's metadata
When restoring the device, read the first block of the non-volatile cache containing its metadata header and verify that it's indeed a device that was used as write cache. Change-Id: Idf113a9e8eb73160a2d9e6e882c9e026d3fafb3e Signed-off-by: Konrad Sztyber <konrad.sztyber@intel.com> Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/458095 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Mateusz Kozlowski <mateusz.kozlowski@intel.com> Reviewed-by: Darek Stojaczyk <dariusz.stojaczyk@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com> Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
This commit is contained in:
parent
1243c9306d
commit
77ddc70e1c
@ -36,6 +36,7 @@
|
||||
#include "spdk/util.h"
|
||||
#include "spdk/likely.h"
|
||||
#include "spdk/string.h"
|
||||
#include "spdk/crc32.h"
|
||||
|
||||
#include "ftl_core.h"
|
||||
#include "ftl_band.h"
|
||||
@ -371,6 +372,91 @@ ftl_restore_next_band(struct ftl_restore *restore)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
ftl_nv_cache_header_cb(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg)
|
||||
{
|
||||
struct ftl_restore *restore = cb_arg;
|
||||
struct spdk_ftl_dev *dev = restore->dev;
|
||||
struct spdk_bdev *bdev;
|
||||
struct ftl_nv_cache *nv_cache = &dev->nv_cache;
|
||||
struct ftl_nv_cache_header *hdr;
|
||||
struct iovec *iov = NULL;
|
||||
int rc = 0, iov_cnt = 0;
|
||||
uint32_t checksum;
|
||||
|
||||
bdev = spdk_bdev_desc_get_bdev(nv_cache->bdev_desc);
|
||||
spdk_bdev_io_get_iovec(bdev_io, &iov, &iov_cnt);
|
||||
hdr = iov[0].iov_base;
|
||||
|
||||
if (!success) {
|
||||
SPDK_ERRLOG("Unable to read non-volatile cache metadata header\n");
|
||||
rc = -ENOTRECOVERABLE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
checksum = spdk_crc32c_update(hdr, offsetof(struct ftl_nv_cache_header, checksum), 0);
|
||||
if (checksum != hdr->checksum) {
|
||||
SPDK_ERRLOG("Invalid header checksum (found: %"PRIu32", expected: %"PRIu32")\n",
|
||||
checksum, hdr->checksum);
|
||||
rc = -ENOTRECOVERABLE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (hdr->version != FTL_NV_CACHE_HEADER_VERSION) {
|
||||
SPDK_ERRLOG("Invalid header version (found: %"PRIu32", expected: %"PRIu32")\n",
|
||||
hdr->version, FTL_NV_CACHE_HEADER_VERSION);
|
||||
rc = -ENOTRECOVERABLE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (hdr->size != spdk_bdev_get_num_blocks(bdev)) {
|
||||
SPDK_ERRLOG("Unexpected size of the non-volatile cache bdev (%"PRIu64", expected: %"
|
||||
PRIu64")\n", hdr->size, spdk_bdev_get_num_blocks(bdev));
|
||||
rc = -ENOTRECOVERABLE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (spdk_uuid_compare(&hdr->uuid, &dev->uuid)) {
|
||||
SPDK_ERRLOG("Invalid device UUID\n");
|
||||
rc = -ENOTRECOVERABLE;
|
||||
goto out;
|
||||
}
|
||||
out:
|
||||
ftl_restore_complete(restore, rc);
|
||||
spdk_bdev_free_io(bdev_io);
|
||||
spdk_dma_free(hdr);
|
||||
}
|
||||
|
||||
static void
|
||||
ftl_restore_nv_cache(struct ftl_restore *restore)
|
||||
{
|
||||
struct spdk_ftl_dev *dev = restore->dev;
|
||||
struct spdk_bdev *bdev;
|
||||
struct ftl_nv_cache *nv_cache = &dev->nv_cache;
|
||||
struct ftl_io_channel *ioch;
|
||||
void *buf;
|
||||
int rc;
|
||||
|
||||
ioch = spdk_io_channel_get_ctx(dev->ioch);
|
||||
bdev = spdk_bdev_desc_get_bdev(nv_cache->bdev_desc);
|
||||
|
||||
buf = spdk_dma_zmalloc(spdk_bdev_get_block_size(bdev), spdk_bdev_get_buf_align(bdev), NULL);
|
||||
if (spdk_unlikely(!buf)) {
|
||||
SPDK_ERRLOG("Memory allocation failure\n");
|
||||
ftl_restore_complete(restore, -ENOMEM);
|
||||
return;
|
||||
}
|
||||
|
||||
rc = spdk_bdev_read_blocks(nv_cache->bdev_desc, ioch->cache_ioch, buf, 0, 1,
|
||||
ftl_nv_cache_header_cb, restore);
|
||||
if (spdk_unlikely(rc != 0)) {
|
||||
SPDK_ERRLOG("Failed to read non-volatile cache metadata header: %s\n",
|
||||
spdk_strerror(-rc));
|
||||
ftl_restore_complete(restore, rc);
|
||||
spdk_dma_free(buf);
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
ftl_pad_chunk_pad_finish(struct ftl_restore_band *rband, bool direct_access)
|
||||
{
|
||||
@ -572,7 +658,7 @@ ftl_restore_tail_md_cb(struct ftl_io *io, void *ctx, int status)
|
||||
{
|
||||
struct ftl_restore_band *rband = ctx;
|
||||
struct ftl_restore *restore = rband->parent;
|
||||
struct spdk_ftl_dev *dev = rband->band->dev;
|
||||
struct spdk_ftl_dev *dev = restore->dev;
|
||||
|
||||
if (status) {
|
||||
if (!dev->conf.allow_open_bands) {
|
||||
@ -604,9 +690,12 @@ ftl_restore_tail_md_cb(struct ftl_io *io, void *ctx, int status)
|
||||
if (!STAILQ_EMPTY(&restore->pad_bands)) {
|
||||
spdk_thread_send_msg(ftl_get_core_thread(dev), ftl_restore_pad_open_bands,
|
||||
restore);
|
||||
} else if (dev->nv_cache.bdev_desc) {
|
||||
ftl_restore_nv_cache(restore);
|
||||
} else {
|
||||
ftl_restore_complete(restore, status);
|
||||
ftl_restore_complete(restore, 0);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user