Commit 7ff28519 authored by Kozlowski Mateusz's avatar Kozlowski Mateusz Committed by Jim Harris
Browse files

ftl: Add metadata upgrade framework



Added the ability for minor metadata upgrade - updating the internal
fields of metadata structures, without changing the overall layout.

Signed-off-by: default avatarKozlowski Mateusz <mateusz.kozlowski@intel.com>
Signed-off-by: default avatarArtur Paszkiewicz <artur.paszkiewicz@intel.com>
Change-Id: Iec98c62b45b099d6d476d486ba7e4ff6b648bb95
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/13384


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
parent 44b6d585
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -23,7 +23,7 @@ endif

CFLAGS += -I.

FTL_SUBDIRS := mngt utils
FTL_SUBDIRS := mngt utils upgrade

C_SRCS = ftl_core.c ftl_init.c ftl_layout.c ftl_debug.c ftl_io.c ftl_sb.c ftl_l2p.c ftl_l2p_flat.c
C_SRCS += ftl_nv_cache.c ftl_band.c ftl_band_ops.c ftl_writer.c ftl_rq.c ftl_reloc.c ftl_l2p_cache.c
@@ -31,8 +31,9 @@ C_SRCS += ftl_p2l.c
C_SRCS += mngt/ftl_mngt.c mngt/ftl_mngt_bdev.c mngt/ftl_mngt_shutdown.c mngt/ftl_mngt_startup.c
C_SRCS += mngt/ftl_mngt_md.c mngt/ftl_mngt_misc.c mngt/ftl_mngt_ioch.c mngt/ftl_mngt_l2p.c
C_SRCS += mngt/ftl_mngt_band.c mngt/ftl_mngt_self_test.c mngt/ftl_mngt_p2l.c
C_SRCS += mngt/ftl_mngt_recovery.c
C_SRCS += mngt/ftl_mngt_recovery.c mngt/ftl_mngt_upgrade.c
C_SRCS += utils/ftl_conf.c utils/ftl_md.c utils/ftl_mempool.c utils/ftl_bitmap.c
C_SRCS += upgrade/ftl_layout_upgrade.c

SPDK_MAP_FILE = $(abspath $(CURDIR)/spdk_ftl.map)

+74 −0
Original line number Diff line number Diff line
@@ -273,6 +273,80 @@ next_sb_reg:
	return 0;
}

static void
ftl_superblock_md_layout_free_region(struct spdk_ftl_dev *dev,
				     struct ftl_superblock_md_region *sb_reg)
{
	/* TODO: major upgrades: implement */
	sb_reg->type = FTL_LAYOUT_REGION_TYPE_FREE_NVC;
}

int
ftl_superblock_md_layout_upgrade_region(struct spdk_ftl_dev *dev,
					struct ftl_superblock_md_region *sb_reg, uint32_t new_version)
{
	struct ftl_superblock *sb = dev->sb;
	struct ftl_superblock_md_region *sb_reg_iter = &sb->md_layout_head;
	struct ftl_layout *layout = &dev->layout;
	struct ftl_layout_region *reg = &layout->region[sb_reg->type];
	uint32_t old_version = sb_reg->version;

	assert(sb_reg);
	assert(reg->prev.sb_md_reg == sb_reg);
	assert(new_version > old_version);

	while (sb_reg_iter->type != FTL_LAYOUT_REGION_TYPE_INVALID) {
		if (sb_reg_iter->type != sb_reg->type) {
			goto next_sb_reg_iter;
		}

		/* Verify all region versions up to new_version are updated: */
		if (sb_reg_iter->version != old_version && sb_reg_iter->version < new_version) {
			FTL_ERRLOG(dev, "Region upgrade skipped\n");
			return -1;
		}

		if (sb_reg_iter->version == new_version) {
			/* Major upgrades: update region prev version to the new version region found */
			assert(sb_reg != sb_reg_iter);
			reg->prev.offset = sb_reg_iter->blk_offs;
			reg->prev.blocks = sb_reg_iter->blk_sz;
			reg->prev.version = sb_reg_iter->version;
			reg->prev.sb_md_reg = sb_reg_iter;

			ftl_superblock_md_layout_free_region(dev, sb_reg);
			goto exit;
		}

next_sb_reg_iter:
		if (sb_reg_iter->df_next == FTL_DF_OBJ_ID_INVALID) {
			break;
		}

		sb_reg_iter = ftl_df_get_obj_ptr(sb, sb_reg_iter->df_next);
		if (superblock_md_region_overflow(dev, sb_reg_iter)) {
			FTL_ERRLOG(dev, "Buffer overflow\n");
			return -EOVERFLOW;
		}
	}

	/* Minor upgrades: update the region in place (only the new version) */
	assert(sb_reg == reg->prev.sb_md_reg);
	sb_reg->version = new_version;
	reg->prev.version = new_version;

exit:
	/* Update the region current version */
	if (new_version == reg->current.version) {
		reg->current.offset = sb_reg->blk_offs;
		reg->current.blocks = sb_reg->blk_sz;
		reg->current.version = sb_reg->version;
		reg->current.sb_md_reg = sb_reg;
	}

	return 0;
}

void
ftl_superblock_md_layout_dump(struct spdk_ftl_dev *dev)
{
+3 −0
Original line number Diff line number Diff line
@@ -20,6 +20,9 @@ int ftl_superblock_md_layout_build(struct spdk_ftl_dev *dev);

int ftl_superblock_md_layout_load_all(struct spdk_ftl_dev *dev);

int ftl_superblock_md_layout_upgrade_region(struct spdk_ftl_dev *dev,
		struct ftl_superblock_md_region *sb_reg, uint32_t new_version);

void ftl_superblock_md_layout_dump(struct spdk_ftl_dev *dev);

#endif /* FTL_SB_H */
+8 −0
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@
#include "ftl_band.h"
#include "ftl_internal.h"
#include "ftl_sb.h"
#include "upgrade/ftl_layout_upgrade.h"

void
ftl_mngt_init_layout(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
@@ -747,3 +748,10 @@ ftl_mngt_restore_md(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
{
	ftl_mngt_call_process(mngt, &desc_restore);
}

void
ftl_mngt_persist_superblock(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
{
	dev->sb->header.crc = get_sb_crc(dev->sb);
	persist(dev, mngt, FTL_LAYOUT_REGION_TYPE_SB);
}
+6 −0
Original line number Diff line number Diff line
@@ -82,6 +82,10 @@ void ftl_mngt_persist_l2p(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mng

void ftl_mngt_init_layout(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt);

void ftl_mngt_layout_verify(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt);

void ftl_mngt_layout_upgrade(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt);

void ftl_mngt_init_md(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt);

void ftl_mngt_deinit_md(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt);
@@ -136,4 +140,6 @@ void ftl_mngt_persist_band_info_metadata(struct spdk_ftl_dev *dev, struct ftl_mn

void ftl_mngt_persist_nv_cache_metadata(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt);

void ftl_mngt_persist_superblock(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt);

#endif /* FTL_MNGT_STEPS_H */
Loading