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