diff --git a/include/spdk/ftl.h b/include/spdk/ftl.h index 751e3599c..ff9b1cf3d 100644 --- a/include/spdk/ftl.h +++ b/include/spdk/ftl.h @@ -89,6 +89,9 @@ struct spdk_ftl_conf { /* Number of interleaving units per ws_opt */ size_t num_interleave_units; + + /* Allow for partial recovery from open bands instead of returning error */ + bool allow_open_bands; }; /* Range of parallel units (inclusive) */ diff --git a/lib/ftl/ftl_init.c b/lib/ftl/ftl_init.c index 0bca08243..36d8c6add 100644 --- a/lib/ftl/ftl_init.c +++ b/lib/ftl/ftl_init.c @@ -90,6 +90,12 @@ static const struct spdk_ftl_conf g_default_conf = { /* Number of interleaving units per ws_opt */ /* 1 for default and 3 for 3D TLC NAND */ .num_interleave_units = 1, + /* + * If clear ftl will return error when restoring after a dirty shutdown + * If set, last band will be padded, ftl will restore based only on closed bands - this + * will result in lost data after recovery. + */ + .allow_open_bands = false, }; static void ftl_dev_free_sync(struct spdk_ftl_dev *dev); diff --git a/lib/ftl/ftl_restore.c b/lib/ftl/ftl_restore.c index 3ef059ea7..257258c65 100644 --- a/lib/ftl/ftl_restore.c +++ b/lib/ftl/ftl_restore.c @@ -573,10 +573,17 @@ ftl_restore_tail_md_cb(struct ftl_io *io, void *ctx, int status) struct spdk_ftl_dev *dev = rband->band->dev; if (status) { - SPDK_ERRLOG("%s while restoring tail md. Will attempt to pad band %u.\n", - spdk_strerror(status), rband->band->id); - STAILQ_INSERT_TAIL(&restore->pad_bands, rband, stailq); - restore->num_pad_bands++; + if (!dev->conf.allow_open_bands) { + SPDK_ERRLOG("%s while restoring tail md in band %u.\n", + spdk_strerror(-status), rband->band->id); + ftl_restore_complete(restore, status); + return; + } else { + SPDK_ERRLOG("%s while restoring tail md. Will attempt to pad band %u.\n", + spdk_strerror(-status), rband->band->id); + STAILQ_INSERT_TAIL(&restore->pad_bands, rband, stailq); + restore->num_pad_bands++; + } } if (!status && ftl_restore_l2p(rband->band)) {