From a6c5feb0a221a0d8911d41130fb1d201befb1f34 Mon Sep 17 00:00:00 2001 From: Mike Gerdts Date: Thu, 18 Nov 2021 16:44:51 +0000 Subject: [PATCH] blob: add forced recovery Add the ability to open a blobstore in such a way that recovery happens even if the superblock says it is clean. Signed-off-by: Mike Gerdts Change-Id: I475e51beff24428d387446f7785e025294d2f014 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/11253 Community-CI: Broadcom CI Community-CI: Mellanox Build Bot Tested-by: SPDK CI Jenkins Reviewed-by: Ben Walker Reviewed-by: Jim Harris --- include/spdk/blob.h | 4 ++++ lib/blob/blobstore.c | 9 +++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/include/spdk/blob.h b/include/spdk/blob.h index 66dbf81011..5007d1fbb2 100644 --- a/include/spdk/blob.h +++ b/include/spdk/blob.h @@ -3,6 +3,7 @@ * * Copyright (c) Intel Corporation. * All rights reserved. + * Copyright (c) 2021, NVIDIA CORPORATION & AFFILIATES. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -233,6 +234,9 @@ struct spdk_bs_opts { * After that, new added fields should be put in the end of the struct. */ size_t opts_size; + + /** Force recovery during import. This is a uint64_t for padding reasons, treated as a bool. */ + uint64_t force_recover; }; /** diff --git a/lib/blob/blobstore.c b/lib/blob/blobstore.c index 97969a0971..17a2a60a48 100644 --- a/lib/blob/blobstore.c +++ b/lib/blob/blobstore.c @@ -3260,6 +3260,7 @@ spdk_bs_opts_init(struct spdk_bs_opts *opts, size_t opts_size) SET_FIELD(iter_cb_fn, NULL); SET_FIELD(iter_cb_arg, NULL); + SET_FIELD(force_recover, false); #undef FIELD_OK #undef SET_FIELD @@ -3302,6 +3303,8 @@ struct spdk_bs_load_ctx { struct spdk_blob *blob; spdk_blob_id blobid; + bool force_recover; + /* These fields are used in the spdk_bs_dump path. */ bool dumping; FILE *fp; @@ -3345,6 +3348,7 @@ bs_alloc(struct spdk_bs_dev *dev, struct spdk_bs_opts *opts, struct spdk_blob_st ctx->bs = bs; ctx->iter_cb_fn = opts->iter_cb_fn; ctx->iter_cb_arg = opts->iter_cb_arg; + ctx->force_recover = opts->force_recover; ctx->super = spdk_zmalloc(sizeof(*ctx->super), 0x1000, NULL, SPDK_ENV_SOCKET_ID_ANY, SPDK_MALLOC_DMA); @@ -4414,7 +4418,7 @@ bs_load_super_cpl(spdk_bs_sequence_t *seq, void *cb_arg, int bserrno) return; } - if (ctx->super->used_blobid_mask_len == 0 || ctx->super->clean == 0) { + if (ctx->super->used_blobid_mask_len == 0 || ctx->super->clean == 0 || ctx->force_recover) { bs_recover(ctx); } else { bs_load_read_used_pages(ctx); @@ -4449,12 +4453,13 @@ bs_opts_copy(struct spdk_bs_opts *src, struct spdk_bs_opts *dst) } SET_FIELD(iter_cb_fn); SET_FIELD(iter_cb_arg); + SET_FIELD(force_recover); dst->opts_size = src->opts_size; /* You should not remove this statement, but need to update the assert statement * if you add a new field, and also add a corresponding SET_FIELD statement */ - SPDK_STATIC_ASSERT(sizeof(struct spdk_bs_opts) == 64, "Incorrect size"); + SPDK_STATIC_ASSERT(sizeof(struct spdk_bs_opts) == 72, "Incorrect size"); #undef FIELD_OK #undef SET_FIELD