lib/ftl: non-volatile cache's header validation function
Moved metadata header verification to a separate function, since the metadata read callback got pretty large. Change-Id: I0c8b2eb493631a6495ce2ef7d9586d2c7cb7772f Signed-off-by: Konrad Sztyber <konrad.sztyber@intel.com> Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/460795 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
parent
5c9a503990
commit
3e911e17c7
@ -863,17 +863,52 @@ ftl_nv_cache_scan_block(struct ftl_nv_cache_block *block)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
ftl_nv_cache_header_valid(struct spdk_ftl_dev *dev, const struct ftl_nv_cache_header *hdr)
|
||||||
|
{
|
||||||
|
struct spdk_bdev *bdev = spdk_bdev_desc_get_bdev(dev->nv_cache.bdev_desc);
|
||||||
|
uint32_t checksum;
|
||||||
|
|
||||||
|
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);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
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));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (spdk_uuid_compare(&hdr->uuid, &dev->uuid)) {
|
||||||
|
SPDK_ERRLOG("Invalid device UUID\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ftl_nv_cache_phase_is_valid(hdr->phase) && hdr->phase != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ftl_nv_cache_read_header_cb(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg)
|
ftl_nv_cache_read_header_cb(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg)
|
||||||
{
|
{
|
||||||
struct ftl_restore *restore = cb_arg;
|
struct ftl_restore *restore = cb_arg;
|
||||||
struct spdk_ftl_dev *dev = restore->dev;
|
struct spdk_ftl_dev *dev = restore->dev;
|
||||||
struct spdk_bdev *bdev;
|
|
||||||
struct ftl_nv_cache *nv_cache = &dev->nv_cache;
|
struct ftl_nv_cache *nv_cache = &dev->nv_cache;
|
||||||
struct ftl_nv_cache_header *hdr;
|
struct ftl_nv_cache_header *hdr;
|
||||||
struct iovec *iov = NULL;
|
struct iovec *iov = NULL;
|
||||||
int iov_cnt = 0, i, rc;
|
int iov_cnt = 0, i, rc;
|
||||||
uint32_t checksum;
|
|
||||||
|
|
||||||
if (!success) {
|
if (!success) {
|
||||||
SPDK_ERRLOG("Unable to read non-volatile cache metadata header\n");
|
SPDK_ERRLOG("Unable to read non-volatile cache metadata header\n");
|
||||||
@ -881,50 +916,22 @@ ftl_nv_cache_read_header_cb(struct spdk_bdev_io *bdev_io, bool success, void *cb
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
bdev = spdk_bdev_desc_get_bdev(nv_cache->bdev_desc);
|
|
||||||
spdk_bdev_io_get_iovec(bdev_io, &iov, &iov_cnt);
|
spdk_bdev_io_get_iovec(bdev_io, &iov, &iov_cnt);
|
||||||
if (!iov) {
|
assert(iov != NULL);
|
||||||
SPDK_ERRLOG("Unable to get the iov for non-volatile cache metadata header\n");
|
|
||||||
ftl_restore_complete(restore, -ENOTRECOVERABLE);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
hdr = iov[0].iov_base;
|
hdr = iov[0].iov_base;
|
||||||
|
|
||||||
checksum = spdk_crc32c_update(hdr, offsetof(struct ftl_nv_cache_header, checksum), 0);
|
if (!ftl_nv_cache_header_valid(dev, hdr)) {
|
||||||
if (checksum != hdr->checksum) {
|
|
||||||
SPDK_ERRLOG("Invalid header checksum (found: %"PRIu32", expected: %"PRIu32")\n",
|
|
||||||
checksum, hdr->checksum);
|
|
||||||
ftl_restore_complete(restore, -ENOTRECOVERABLE);
|
ftl_restore_complete(restore, -ENOTRECOVERABLE);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hdr->version != FTL_NV_CACHE_HEADER_VERSION) {
|
/* Remember the latest phase */
|
||||||
SPDK_ERRLOG("Invalid header version (found: %"PRIu32", expected: %"PRIu32")\n",
|
nv_cache->phase = hdr->phase;
|
||||||
hdr->version, FTL_NV_CACHE_HEADER_VERSION);
|
|
||||||
ftl_restore_complete(restore, -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));
|
|
||||||
ftl_restore_complete(restore, -ENOTRECOVERABLE);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (spdk_uuid_compare(&hdr->uuid, &dev->uuid)) {
|
|
||||||
SPDK_ERRLOG("Invalid device UUID\n");
|
|
||||||
ftl_restore_complete(restore, -ENOTRECOVERABLE);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ftl_nv_cache_phase_is_valid(hdr->phase)) {
|
|
||||||
/* If the phase equals zero, we lost power during recovery. We need to finish it up
|
/* If the phase equals zero, we lost power during recovery. We need to finish it up
|
||||||
* by scrubbing the device once again.
|
* by scrubbing the device once again.
|
||||||
*/
|
*/
|
||||||
if (hdr->phase != 0) {
|
if (hdr->phase == 0) {
|
||||||
ftl_restore_complete(restore, -ENOTRECOVERABLE);
|
|
||||||
} else {
|
|
||||||
SPDK_DEBUGLOG(SPDK_LOG_FTL_INIT, "Detected phase 0, restarting scrub\n");
|
SPDK_DEBUGLOG(SPDK_LOG_FTL_INIT, "Detected phase 0, restarting scrub\n");
|
||||||
rc = ftl_nv_cache_scrub(nv_cache, ftl_nv_cache_scrub_cb, restore);
|
rc = ftl_nv_cache_scrub(nv_cache, ftl_nv_cache_scrub_cb, restore);
|
||||||
if (spdk_unlikely(rc != 0)) {
|
if (spdk_unlikely(rc != 0)) {
|
||||||
@ -932,13 +939,10 @@ ftl_nv_cache_read_header_cb(struct spdk_bdev_io *bdev_io, bool success, void *cb
|
|||||||
spdk_strerror(-rc));
|
spdk_strerror(-rc));
|
||||||
ftl_restore_complete(restore, -ENOTRECOVERABLE);
|
ftl_restore_complete(restore, -ENOTRECOVERABLE);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remember the latest phase */
|
|
||||||
nv_cache->phase = hdr->phase;
|
|
||||||
restore->nv_cache.current_addr = FTL_NV_CACHE_DATA_OFFSET;
|
restore->nv_cache.current_addr = FTL_NV_CACHE_DATA_OFFSET;
|
||||||
|
|
||||||
for (i = 0; i < FTL_NV_CACHE_RESTORE_DEPTH; ++i) {
|
for (i = 0; i < FTL_NV_CACHE_RESTORE_DEPTH; ++i) {
|
||||||
|
Loading…
Reference in New Issue
Block a user