1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (C) 2022 Intel Corporation. 3 * Copyright 2023 Solidigm All Rights Reserved 4 * All rights reserved. 5 */ 6 7 #ifndef FTL_LAYOUT_UPGRADE_H 8 #define FTL_LAYOUT_UPGRADE_H 9 10 #include "ftl_core.h" 11 #include "ftl_layout.h" 12 13 struct spdk_ftl_dev; 14 struct ftl_layout_region; 15 struct ftl_layout_upgrade_ctx; 16 17 enum ftl_layout_upgrade_result { 18 /* Continue with the selected region upgrade */ 19 FTL_LAYOUT_UPGRADE_CONTINUE = 0, 20 21 /* Layout upgrade done */ 22 FTL_LAYOUT_UPGRADE_DONE, 23 24 /* Layout upgrade fault */ 25 FTL_LAYOUT_UPGRADE_FAULT, 26 }; 27 28 /* MD region upgrade verify fn: return 0 on success */ 29 typedef int (*ftl_region_upgrade_verify_fn)(struct spdk_ftl_dev *dev, 30 struct ftl_layout_region *region); 31 32 /* MD region upgrade fn: return 0 on success */ 33 typedef int (*ftl_region_upgrade_fn)(struct spdk_ftl_dev *dev, struct ftl_layout_upgrade_ctx *ctx); 34 35 /* MD region upgrade descriptor */ 36 struct ftl_region_upgrade_desc { 37 /* Qualifies the region for upgrade */ 38 ftl_region_upgrade_verify_fn verify; 39 40 /* Upgrades the region */ 41 ftl_region_upgrade_fn upgrade; 42 43 /* New region version (i.e. after the upgrade) */ 44 uint32_t new_version; 45 46 /* Context buffer allocated for upgrade() */ 47 size_t ctx_size; 48 }; 49 50 /* MD layout upgrade descriptor - one instance contains information about the upgrade steps necessary 51 * for updating to latest metadata version. For example version 0 of metadata region will have no descriptors 52 * (as it's by definition up to date and there's no need to upgrade it), while version 2 will have 2 (0 -> 1 53 * and 1 -> 2). 54 */ 55 struct ftl_layout_upgrade_desc_list { 56 /* Latest version of the region */ 57 uint64_t latest_ver; 58 59 /* # of entries in the region upgrade descriptor */ 60 size_t count; 61 62 /* Region upgrade descriptor */ 63 struct ftl_region_upgrade_desc *desc; 64 }; 65 66 /* Region upgrade callback */ 67 typedef void (*ftl_region_upgrade_cb)(struct spdk_ftl_dev *dev, void *ctx, int status); 68 69 /* MD layout upgrade context */ 70 struct ftl_layout_upgrade_ctx { 71 /* MD region being upgraded */ 72 struct ftl_layout_region *reg; 73 74 /* MD region upgrade descriptor */ 75 struct ftl_layout_upgrade_desc_list *upgrade; 76 77 /* New region version (i.e. after the upgrade) */ 78 uint64_t next_reg_ver; 79 80 /* Context buffer for the region upgrade */ 81 void *ctx; 82 83 /* Region upgrade callback */ 84 ftl_region_upgrade_cb cb; 85 86 /* Ctx for the region upgrade callback */ 87 void *cb_ctx; 88 }; 89 90 /** 91 * @brief Disable region upgrade for particular version. 92 * 93 * @param dev FTL device 94 * @param region FTL layout region descriptor 95 * @return int -1 96 */ 97 int ftl_region_upgrade_disabled(struct spdk_ftl_dev *dev, struct ftl_layout_region *region); 98 99 /** 100 * @brief Enable region upgrade for particular version. 101 * 102 * @param dev FTL device 103 * @param region FTL layout region descriptor 104 * @return int -1 (i.e. disable) if SB is dirty or SHM clean, 0 otherwise (i.e. enable) 105 */ 106 int ftl_region_upgrade_enabled(struct spdk_ftl_dev *dev, struct ftl_layout_region *region); 107 108 /** 109 * @brief Enable major upgrade for particular region. 110 * 111 * @param dev FTL device 112 * @param region the region to be upgraded in major mode 113 * 114 * @retval 0 Upgrade enabled and possible 115 * @retval -1 Upgrade not possible 116 */ 117 int ftl_region_major_upgrade_enabled(struct spdk_ftl_dev *dev, struct ftl_layout_region *region); 118 119 /** 120 * @brief Upgrade the superblock. 121 * 122 * This call is sychronous. 123 * 124 * @param dev FTL device 125 * @return int 0: success, error code otherwise 126 */ 127 int ftl_superblock_upgrade(struct spdk_ftl_dev *dev); 128 129 /** 130 * @brief Qualify the MD layout for upgrade. 131 * 132 * The SB MD layout is built or loaded. 133 * If loaded, walk through all MD layout and filter out all MD regions that need an upgrade. 134 * Call .verify() on region upgrade descriptors for all such regions. 135 * 136 * @param dev FTL device 137 * @return int 0: success, error code otherwise 138 */ 139 int ftl_layout_verify(struct spdk_ftl_dev *dev); 140 141 /** 142 * @brief Dump the FTL layout 143 * 144 * Verify MD layout in terms of region overlaps. 145 * 146 * @param dev FTL device 147 * @return int 0: success, error code otherwise 148 */ 149 int ftl_upgrade_layout_dump(struct spdk_ftl_dev *dev); 150 151 /** 152 * @brief Upgrade the MD region. 153 * 154 * Call .upgrade() on the selected region upgrade descriptor. 155 * When returned 0, this call is asynchronous. 156 * The .upgrade() is expected to convert and persist the metadata. 157 * When that's done, the call to ftl_region_upgrade_completed() is expected 158 * to continue with the layout upgrade. 159 * 160 * When returned an error code, the caller is responsible to abort the mngt pipeline. 161 * 162 * @param dev FTL device 163 * @param ctx Layout upgrade context 164 * @return int 0: upgrade in progress, error code otherwise 165 */ 166 int ftl_region_upgrade(struct spdk_ftl_dev *dev, struct ftl_layout_upgrade_ctx *ctx); 167 168 /** 169 * @brief Called when MD region upgrade is completed - see ftl_region_upgrade(). 170 * 171 * Upgrades the SB MD layout and region's prev version descriptor to the just upgraded version. 172 * Executes the layout upgrade owner's callback (mngt region_upgrade_cb()) to continue 173 * with the layout upgrade. 174 * 175 * @param dev FTL device 176 * @param ctx Layout upgrade context 177 * @param entry_size Entry size in the upgraded region or 0 if no change 178 * @param num_entries Number of entries in the upgraded region or 0 if no change 179 * @param status Region upgrade status: 0: success, error code otherwise 180 */ 181 void ftl_region_upgrade_completed(struct spdk_ftl_dev *dev, struct ftl_layout_upgrade_ctx *ctx, 182 uint64_t entry_size, uint64_t num_entries, int status); 183 184 /** 185 * @brief Initialize the layout upgrade context. 186 * 187 * Select the next region to be upgraded. 188 * 189 * @param dev FTL device 190 * @param ctx Layout upgrade context 191 * @return int see enum ftl_layout_upgrade_result 192 */ 193 int ftl_layout_upgrade_init_ctx(struct spdk_ftl_dev *dev, struct ftl_layout_upgrade_ctx *ctx); 194 195 /** 196 * @brief Returns the highest defined version of the given region 197 * 198 * @param reg_type FTL layout region 199 * 200 * @return region's version 201 */ 202 uint64_t ftl_layout_upgrade_region_get_latest_version(enum ftl_layout_region_type reg_type); 203 204 #endif /* FTL_LAYOUT_UPGRADE_H */ 205