xref: /spdk/lib/ftl/upgrade/ftl_layout_upgrade.h (revision 34edd9f1bf5fda4c987f4500ddc3c9f50be32e7d)
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 synchronous.
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