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