xref: /spdk/lib/ftl/upgrade/ftl_layout_upgrade.h (revision 34edd9f1bf5fda4c987f4500ddc3c9f50be32e7d)
17ff28519SKozlowski Mateusz /*   SPDX-License-Identifier: BSD-3-Clause
2a6dbe372Spaul luse  *   Copyright (C) 2022 Intel Corporation.
3a5c04e6dSMateusz Kozlowski  *   Copyright 2023 Solidigm All Rights Reserved
47ff28519SKozlowski Mateusz  *   All rights reserved.
57ff28519SKozlowski Mateusz  */
67ff28519SKozlowski Mateusz 
77ff28519SKozlowski Mateusz #ifndef FTL_LAYOUT_UPGRADE_H
87ff28519SKozlowski Mateusz #define FTL_LAYOUT_UPGRADE_H
97ff28519SKozlowski Mateusz 
107ff28519SKozlowski Mateusz #include "ftl_core.h"
117ff28519SKozlowski Mateusz #include "ftl_layout.h"
127ff28519SKozlowski Mateusz 
137ff28519SKozlowski Mateusz struct spdk_ftl_dev;
147ff28519SKozlowski Mateusz struct ftl_layout_region;
157ff28519SKozlowski Mateusz struct ftl_layout_upgrade_ctx;
167ff28519SKozlowski Mateusz 
177ff28519SKozlowski Mateusz enum ftl_layout_upgrade_result {
187ff28519SKozlowski Mateusz 	/* Continue with the selected region upgrade */
197ff28519SKozlowski Mateusz 	FTL_LAYOUT_UPGRADE_CONTINUE = 0,
207ff28519SKozlowski Mateusz 
217ff28519SKozlowski Mateusz 	/* Layout upgrade done */
227ff28519SKozlowski Mateusz 	FTL_LAYOUT_UPGRADE_DONE,
237ff28519SKozlowski Mateusz 
247ff28519SKozlowski Mateusz 	/* Layout upgrade fault */
257ff28519SKozlowski Mateusz 	FTL_LAYOUT_UPGRADE_FAULT,
267ff28519SKozlowski Mateusz };
277ff28519SKozlowski Mateusz 
287ff28519SKozlowski Mateusz /* MD region upgrade verify fn: return 0 on success */
297ff28519SKozlowski Mateusz typedef int (*ftl_region_upgrade_verify_fn)(struct spdk_ftl_dev *dev,
307ff28519SKozlowski Mateusz 		struct ftl_layout_region *region);
317ff28519SKozlowski Mateusz 
327ff28519SKozlowski Mateusz /* MD region upgrade fn: return 0 on success */
337ff28519SKozlowski Mateusz typedef int (*ftl_region_upgrade_fn)(struct spdk_ftl_dev *dev, struct ftl_layout_upgrade_ctx *ctx);
347ff28519SKozlowski Mateusz 
357ff28519SKozlowski Mateusz /* MD region upgrade descriptor */
367ff28519SKozlowski Mateusz struct ftl_region_upgrade_desc {
377ff28519SKozlowski Mateusz 	/* Qualifies the region for upgrade */
387ff28519SKozlowski Mateusz 	ftl_region_upgrade_verify_fn verify;
397ff28519SKozlowski Mateusz 
407ff28519SKozlowski Mateusz 	/* Upgrades the region */
417ff28519SKozlowski Mateusz 	ftl_region_upgrade_fn upgrade;
427ff28519SKozlowski Mateusz 
437ff28519SKozlowski Mateusz 	/* New region version (i.e. after the upgrade) */
447ff28519SKozlowski Mateusz 	uint32_t new_version;
457ff28519SKozlowski Mateusz 
467ff28519SKozlowski Mateusz 	/* Context buffer allocated for upgrade() */
477ff28519SKozlowski Mateusz 	size_t ctx_size;
487ff28519SKozlowski Mateusz };
497ff28519SKozlowski Mateusz 
507ff28519SKozlowski Mateusz /* MD layout upgrade descriptor - one instance contains information about the upgrade steps necessary
517ff28519SKozlowski Mateusz  * for updating to latest metadata version. For example version 0 of metadata region will have no descriptors
527ff28519SKozlowski Mateusz  * (as it's by definition up to date and there's no need to upgrade it), while version 2 will have 2 (0 -> 1
537ff28519SKozlowski Mateusz  * and 1 -> 2).
547ff28519SKozlowski Mateusz  */
557ff28519SKozlowski Mateusz struct ftl_layout_upgrade_desc_list {
568fc78fd8SMateusz Kozlowski 	/* Latest version of the region */
578fc78fd8SMateusz Kozlowski 	uint64_t latest_ver;
588fc78fd8SMateusz Kozlowski 
597ff28519SKozlowski Mateusz 	/* # of entries in the region upgrade descriptor */
607ff28519SKozlowski Mateusz 	size_t count;
617ff28519SKozlowski Mateusz 
627ff28519SKozlowski Mateusz 	/* Region upgrade descriptor */
637ff28519SKozlowski Mateusz 	struct ftl_region_upgrade_desc *desc;
647ff28519SKozlowski Mateusz };
657ff28519SKozlowski Mateusz 
667ff28519SKozlowski Mateusz /* Region upgrade callback */
677ff28519SKozlowski Mateusz typedef void (*ftl_region_upgrade_cb)(struct spdk_ftl_dev *dev, void *ctx, int status);
687ff28519SKozlowski Mateusz 
697ff28519SKozlowski Mateusz /* MD layout upgrade context */
707ff28519SKozlowski Mateusz struct ftl_layout_upgrade_ctx {
717ff28519SKozlowski Mateusz 	/* MD region being upgraded */
727ff28519SKozlowski Mateusz 	struct ftl_layout_region *reg;
737ff28519SKozlowski Mateusz 
747ff28519SKozlowski Mateusz 	/* MD region upgrade descriptor */
757ff28519SKozlowski Mateusz 	struct ftl_layout_upgrade_desc_list *upgrade;
767ff28519SKozlowski Mateusz 
777ff28519SKozlowski Mateusz 	/* New region version (i.e. after the upgrade) */
787ff28519SKozlowski Mateusz 	uint64_t next_reg_ver;
797ff28519SKozlowski Mateusz 
807ff28519SKozlowski Mateusz 	/* Context buffer for the region upgrade */
817ff28519SKozlowski Mateusz 	void *ctx;
827ff28519SKozlowski Mateusz 
837ff28519SKozlowski Mateusz 	/* Region upgrade callback */
847ff28519SKozlowski Mateusz 	ftl_region_upgrade_cb cb;
857ff28519SKozlowski Mateusz 
867ff28519SKozlowski Mateusz 	/* Ctx for the region upgrade callback */
877ff28519SKozlowski Mateusz 	void *cb_ctx;
887ff28519SKozlowski Mateusz };
897ff28519SKozlowski Mateusz 
907ff28519SKozlowski Mateusz /**
917ff28519SKozlowski Mateusz  * @brief Disable region upgrade for particular version.
927ff28519SKozlowski Mateusz  *
937ff28519SKozlowski Mateusz  * @param dev FTL device
947ff28519SKozlowski Mateusz  * @param region FTL layout region descriptor
957ff28519SKozlowski Mateusz  * @return int -1
967ff28519SKozlowski Mateusz  */
977ff28519SKozlowski Mateusz int ftl_region_upgrade_disabled(struct spdk_ftl_dev *dev, struct ftl_layout_region *region);
987ff28519SKozlowski Mateusz 
997ff28519SKozlowski Mateusz /**
1007ff28519SKozlowski Mateusz  * @brief Enable region upgrade for particular version.
1017ff28519SKozlowski Mateusz  *
1027ff28519SKozlowski Mateusz  * @param dev FTL device
1037ff28519SKozlowski Mateusz  * @param region FTL layout region descriptor
1047ff28519SKozlowski Mateusz  * @return int -1 (i.e. disable) if SB is dirty or SHM clean, 0 otherwise (i.e. enable)
1057ff28519SKozlowski Mateusz  */
1067ff28519SKozlowski Mateusz int ftl_region_upgrade_enabled(struct spdk_ftl_dev *dev, struct ftl_layout_region *region);
1077ff28519SKozlowski Mateusz 
1087ff28519SKozlowski Mateusz /**
109a5c04e6dSMateusz Kozlowski  * @brief Enable major upgrade for particular region.
110a5c04e6dSMateusz Kozlowski  *
111a5c04e6dSMateusz Kozlowski  * @param dev FTL device
112a5c04e6dSMateusz Kozlowski  * @param region the region to be upgraded in major mode
113a5c04e6dSMateusz Kozlowski  *
114a5c04e6dSMateusz Kozlowski  * @retval 0 Upgrade enabled and possible
115a5c04e6dSMateusz Kozlowski  * @retval -1 Upgrade not possible
116a5c04e6dSMateusz Kozlowski  */
117a5c04e6dSMateusz Kozlowski int ftl_region_major_upgrade_enabled(struct spdk_ftl_dev *dev, struct ftl_layout_region *region);
118a5c04e6dSMateusz Kozlowski 
119a5c04e6dSMateusz Kozlowski /**
1207ff28519SKozlowski Mateusz  * @brief Upgrade the superblock.
1217ff28519SKozlowski Mateusz  *
122*34edd9f1SKamil Godzwon  * This call is synchronous.
1237ff28519SKozlowski Mateusz  *
1247ff28519SKozlowski Mateusz  * @param dev FTL device
1257ff28519SKozlowski Mateusz  * @return int 0: success, error code otherwise
1267ff28519SKozlowski Mateusz  */
1277ff28519SKozlowski Mateusz int ftl_superblock_upgrade(struct spdk_ftl_dev *dev);
1287ff28519SKozlowski Mateusz 
1297ff28519SKozlowski Mateusz /**
1307ff28519SKozlowski Mateusz  * @brief Qualify the MD layout for upgrade.
1317ff28519SKozlowski Mateusz  *
1327ff28519SKozlowski Mateusz  * The SB MD layout is built or loaded.
1337ff28519SKozlowski Mateusz  * If loaded, walk through all MD layout and filter out all MD regions that need an upgrade.
1347ff28519SKozlowski Mateusz  * Call .verify() on region upgrade descriptors for all such regions.
1357ff28519SKozlowski Mateusz  *
1367ff28519SKozlowski Mateusz  * @param dev FTL device
1377ff28519SKozlowski Mateusz  * @return int 0: success, error code otherwise
1387ff28519SKozlowski Mateusz  */
1397ff28519SKozlowski Mateusz int ftl_layout_verify(struct spdk_ftl_dev *dev);
1407ff28519SKozlowski Mateusz 
1417ff28519SKozlowski Mateusz /**
1427ff28519SKozlowski Mateusz  * @brief Dump the FTL layout
1437ff28519SKozlowski Mateusz  *
1447ff28519SKozlowski Mateusz  * Verify MD layout in terms of region overlaps.
1457ff28519SKozlowski Mateusz  *
1467ff28519SKozlowski Mateusz  * @param dev FTL device
1477ff28519SKozlowski Mateusz  * @return int 0: success, error code otherwise
1487ff28519SKozlowski Mateusz  */
1497ff28519SKozlowski Mateusz int ftl_upgrade_layout_dump(struct spdk_ftl_dev *dev);
1507ff28519SKozlowski Mateusz 
1517ff28519SKozlowski Mateusz /**
1527ff28519SKozlowski Mateusz  * @brief Upgrade the MD region.
1537ff28519SKozlowski Mateusz  *
1547ff28519SKozlowski Mateusz  * Call .upgrade() on the selected region upgrade descriptor.
1557ff28519SKozlowski Mateusz  * When returned 0, this call is asynchronous.
1567ff28519SKozlowski Mateusz  * The .upgrade() is expected to convert and persist the metadata.
1577ff28519SKozlowski Mateusz  * When that's done, the call to ftl_region_upgrade_completed() is expected
1587ff28519SKozlowski Mateusz  * to continue with the layout upgrade.
1597ff28519SKozlowski Mateusz  *
1607ff28519SKozlowski Mateusz  * When returned an error code, the caller is responsible to abort the mngt pipeline.
1617ff28519SKozlowski Mateusz  *
1627ff28519SKozlowski Mateusz  * @param dev FTL device
1637ff28519SKozlowski Mateusz  * @param ctx Layout upgrade context
1647ff28519SKozlowski Mateusz  * @return int 0: upgrade in progress, error code otherwise
1657ff28519SKozlowski Mateusz  */
1667ff28519SKozlowski Mateusz int ftl_region_upgrade(struct spdk_ftl_dev *dev, struct ftl_layout_upgrade_ctx *ctx);
1677ff28519SKozlowski Mateusz 
1687ff28519SKozlowski Mateusz /**
1697ff28519SKozlowski Mateusz  * @brief Called when MD region upgrade is completed - see ftl_region_upgrade().
1707ff28519SKozlowski Mateusz  *
1717ff28519SKozlowski Mateusz  * Upgrades the SB MD layout and region's prev version descriptor to the just upgraded version.
1727ff28519SKozlowski Mateusz  * Executes the layout upgrade owner's callback (mngt region_upgrade_cb()) to continue
1737ff28519SKozlowski Mateusz  * with the layout upgrade.
1747ff28519SKozlowski Mateusz  *
1757ff28519SKozlowski Mateusz  * @param dev FTL device
1767ff28519SKozlowski Mateusz  * @param ctx Layout upgrade context
1778fc78fd8SMateusz Kozlowski  * @param entry_size Entry size in the upgraded region or 0 if no change
1788fc78fd8SMateusz Kozlowski  * @param num_entries Number of entries in the upgraded region or 0 if no change
1797ff28519SKozlowski Mateusz  * @param status Region upgrade status: 0: success, error code otherwise
1807ff28519SKozlowski Mateusz  */
1817ff28519SKozlowski Mateusz void ftl_region_upgrade_completed(struct spdk_ftl_dev *dev, struct ftl_layout_upgrade_ctx *ctx,
1828fc78fd8SMateusz Kozlowski 				  uint64_t entry_size, uint64_t num_entries, int status);
1837ff28519SKozlowski Mateusz 
1847ff28519SKozlowski Mateusz /**
1857ff28519SKozlowski Mateusz  * @brief Initialize the layout upgrade context.
1867ff28519SKozlowski Mateusz  *
1877ff28519SKozlowski Mateusz  * Select the next region to be upgraded.
1887ff28519SKozlowski Mateusz  *
1897ff28519SKozlowski Mateusz  * @param dev FTL device
1907ff28519SKozlowski Mateusz  * @param ctx Layout upgrade context
1917ff28519SKozlowski Mateusz  * @return int see enum ftl_layout_upgrade_result
1927ff28519SKozlowski Mateusz  */
1937ff28519SKozlowski Mateusz int ftl_layout_upgrade_init_ctx(struct spdk_ftl_dev *dev, struct ftl_layout_upgrade_ctx *ctx);
1947ff28519SKozlowski Mateusz 
1958fc78fd8SMateusz Kozlowski /**
1968fc78fd8SMateusz Kozlowski  * @brief Returns the highest defined version of the given region
1978fc78fd8SMateusz Kozlowski  *
1988fc78fd8SMateusz Kozlowski  * @param reg_type FTL layout region
1998fc78fd8SMateusz Kozlowski  *
2008fc78fd8SMateusz Kozlowski  * @return region's version
2018fc78fd8SMateusz Kozlowski  */
2028fc78fd8SMateusz Kozlowski uint64_t ftl_layout_upgrade_region_get_latest_version(enum ftl_layout_region_type reg_type);
2038fc78fd8SMateusz Kozlowski 
2047ff28519SKozlowski Mateusz #endif /* FTL_LAYOUT_UPGRADE_H */
205