Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright 2023 Solidigm All Rights Reserved
3 : : * Copyright (C) 2022 Intel Corporation.
4 : : * All rights reserved.
5 : : */
6 : :
7 : : #include <sys/queue.h>
8 : :
9 : : #include "spdk/stdinc.h"
10 : :
11 : : #include "CUnit/Basic.h"
12 : : #include "common/lib/test_env.c"
13 : :
14 : : #include "ftl/ftl_layout.c"
15 : : #include "ftl/upgrade/ftl_layout_upgrade.h"
16 : : #include "ftl/utils/ftl_layout_tracker_bdev.c"
17 : : #include "ftl/upgrade/ftl_sb_v3.c"
18 : : #include "ftl/upgrade/ftl_sb_v5.c"
19 : : #include "ftl/ftl_sb.c"
20 : :
21 : : extern struct ftl_region_upgrade_desc sb_upgrade_desc[];
22 : :
23 : : int l2p_upgrade_v0_to_v1(struct spdk_ftl_dev *dev, struct ftl_layout_upgrade_ctx *ctx);
24 : : int l2p_upgrade_v1_to_v2(struct spdk_ftl_dev *dev, struct ftl_layout_upgrade_ctx *ctx);
25 : : int l2p_upgrade_v2_to_v3(struct spdk_ftl_dev *dev, struct ftl_layout_upgrade_ctx *ctx);
26 : :
27 : : struct ftl_region_upgrade_desc l2p_upgrade_desc[] = {
28 : : [0] = {.verify = ftl_region_upgrade_enabled, .upgrade = l2p_upgrade_v0_to_v1, .new_version = 1},
29 : : [1] = {.verify = ftl_region_upgrade_enabled, .upgrade = l2p_upgrade_v1_to_v2, .new_version = 2},
30 : : [2] = {.verify = ftl_region_upgrade_enabled, .upgrade = l2p_upgrade_v2_to_v3, .new_version = 3},
31 : : };
32 : :
33 : : static struct ftl_layout_upgrade_desc_list layout_upgrade_desc[] = {
34 : : [FTL_LAYOUT_REGION_TYPE_SB] = {
35 : : .latest_ver = FTL_SB_VERSION_CURRENT,
36 : : .count = FTL_SB_VERSION_CURRENT,
37 : : .desc = sb_upgrade_desc,
38 : : },
39 : : [FTL_LAYOUT_REGION_TYPE_SB_BASE] = {
40 : : .latest_ver = FTL_SB_VERSION_CURRENT,
41 : : .count = FTL_SB_VERSION_CURRENT,
42 : : .desc = sb_upgrade_desc,
43 : : },
44 : : [FTL_LAYOUT_REGION_TYPE_L2P] = {
45 : : .latest_ver = 3,
46 : : .count = 3,
47 : : .desc = l2p_upgrade_desc,
48 : : },
49 : : [FTL_LAYOUT_REGION_TYPE_BAND_MD] = {},
50 : : [FTL_LAYOUT_REGION_TYPE_BAND_MD_MIRROR] = {},
51 : : [FTL_LAYOUT_REGION_TYPE_VALID_MAP] = {},
52 : : [FTL_LAYOUT_REGION_TYPE_NVC_MD] = {},
53 : : [FTL_LAYOUT_REGION_TYPE_NVC_MD_MIRROR] = {},
54 : : [FTL_LAYOUT_REGION_TYPE_DATA_NVC] = {},
55 : : [FTL_LAYOUT_REGION_TYPE_DATA_BASE] = {},
56 : : [FTL_LAYOUT_REGION_TYPE_P2L_CKPT_GC] = {},
57 : : [FTL_LAYOUT_REGION_TYPE_P2L_CKPT_GC_NEXT] = {},
58 : : [FTL_LAYOUT_REGION_TYPE_P2L_CKPT_COMP] = {},
59 : : [FTL_LAYOUT_REGION_TYPE_P2L_CKPT_COMP_NEXT] = {},
60 : : [FTL_LAYOUT_REGION_TYPE_TRIM_MD] = {},
61 : : [FTL_LAYOUT_REGION_TYPE_TRIM_MD_MIRROR] = {},
62 : : [FTL_LAYOUT_REGION_TYPE_TRIM_LOG] = {},
63 : : [FTL_LAYOUT_REGION_TYPE_TRIM_LOG_MIRROR] = {},
64 : : [FTL_LAYOUT_REGION_TYPE_P2L_LOG_IO_MIN] = {},
65 : : [FTL_LAYOUT_REGION_TYPE_P2L_LOG_IO_MAX] = {},
66 : : };
67 : :
68 : : SPDK_STATIC_ASSERT(sizeof(layout_upgrade_desc) / sizeof(*layout_upgrade_desc) ==
69 : : FTL_LAYOUT_REGION_TYPE_MAX,
70 : : "Missing layout upgrade descriptors");
71 : :
72 : : #include "ftl/upgrade/ftl_sb_upgrade.c"
73 : : #include "ftl/upgrade/ftl_layout_upgrade.c"
74 : : #include "ftl/mngt/ftl_mngt_md.c"
75 : :
76 : 0 : DEFINE_STUB_V(ftl_mngt_fail_step, (struct ftl_mngt_process *mngt));
77 : 3 : DEFINE_STUB_V(ftl_mngt_next_step, (struct ftl_mngt_process *mngt));
78 : 0 : DEFINE_STUB_V(ftl_md_persist, (struct ftl_md *md));
79 [ # # ]: 0 : DEFINE_STUB(ftl_nv_cache_load_state, int, (struct ftl_nv_cache *nv_cache), 0);
80 : 0 : DEFINE_STUB_V(ftl_valid_map_load_state, (struct spdk_ftl_dev *dev));
81 [ # # ]: 0 : DEFINE_STUB(ftl_bands_load_state, int, (struct spdk_ftl_dev *dev), 0);
82 [ # # ]: 0 : DEFINE_STUB(ftl_md_get_region, const struct ftl_layout_region *, (struct ftl_md *md), 0);
83 : 0 : DEFINE_STUB_V(ftl_md_restore, (struct ftl_md *md));
84 [ # # ]: 0 : DEFINE_STUB(ftl_nv_cache_save_state, int, (struct ftl_nv_cache *nv_cache), 0);
85 [ # # ]: 0 : DEFINE_STUB(ftl_mngt_get_step_ctx, void *, (struct ftl_mngt_process *mngt), 0);
86 : 0 : DEFINE_STUB_V(ftl_mngt_persist_bands_p2l, (struct ftl_mngt_process *mngt));
87 : 3 : DEFINE_STUB_V(ftl_band_init_gc_iter, (struct spdk_ftl_dev *dev));
88 [ # # ]: 0 : DEFINE_STUB(ftl_md_create_region_flags, int, (struct spdk_ftl_dev *dev, int region_type), 0);
89 [ # # ]: 0 : DEFINE_STUB(ftl_md_create, struct ftl_md *, (struct spdk_ftl_dev *dev, uint64_t blocks,
90 : : uint64_t vss_blksz, const char *name, int flags, const struct ftl_layout_region *region), NULL);
91 [ # # ]: 0 : DEFINE_STUB(ftl_md_destroy_region_flags, int, (struct spdk_ftl_dev *dev, int region_type), 0);
92 [ # # ]: 0 : DEFINE_STUB(ftl_md_destroy_shm_flags, int, (struct spdk_ftl_dev *dev), 0);
93 : 0 : DEFINE_STUB_V(ftl_md_destroy, (struct ftl_md *md, int flags));
94 : 0 : DEFINE_STUB_V(ftl_mngt_call_process, (struct ftl_mngt_process *mngt,
95 : : const struct ftl_mngt_process_desc *process,
96 : : void *init_ctx));
97 [ # # ]: 0 : DEFINE_STUB(ftl_md_get_buffer, void *, (struct ftl_md *md), NULL);
98 [ # # ]: 0 : DEFINE_STUB(spdk_bdev_desc_get_bdev, struct spdk_bdev *, (struct spdk_bdev_desc *desc), NULL);
99 [ # # ]: 0 : DEFINE_STUB(spdk_bdev_get_write_unit_size, uint32_t, (const struct spdk_bdev *bdev), 0);
100 [ # # ]: 0 : DEFINE_STUB(spdk_bdev_get_num_blocks, uint64_t, (const struct spdk_bdev *bdev), 0);
101 [ # # ]: 0 : DEFINE_STUB(ftl_nv_cache_chunk_tail_md_num_blocks, size_t, (const struct ftl_nv_cache *nv_cache),
102 : : 0);
103 [ # # ]: 0 : DEFINE_STUB(ftl_band_user_blocks, size_t, (const struct ftl_band *band), 0);
104 : :
105 : : struct spdk_bdev_desc {
106 : : int dummy;
107 : : };
108 : :
109 : : struct spdk_ftl_dev g_dev;
110 : : struct ftl_superblock_shm g_sb_shm = {0};
111 : : struct ftl_base_device_type g_base_type = { .name = "base_dev" };
112 : : struct ftl_nv_cache_device_type g_nvc_type = { .name = "nvc_dev" };
113 : : struct spdk_bdev_desc g_base_bdev_desc = {0};
114 : : struct spdk_bdev_desc g_nvc_bdev_desc = {0};
115 : : static uint8_t g_sb_buf[FTL_SUPERBLOCK_SIZE] = {0};
116 : :
117 : : #define TEST_OP 0x1984
118 : : #define TEST_REG_BLKS 0x10000
119 : : #define TEST_NVC_BLKS 0x1000000;
120 : : #define TEST_BASE_BLKS 0x1000000000;
121 : :
122 : : static int
123 : 3 : test_setup(void)
124 : : {
125 : 3 : int regno_nvc = 0, regno_base = 0, *regno_dev;
126 : :
127 : : /* setup a dummy dev: */
128 : 3 : g_dev.sb = (void *)g_sb_buf;
129 : 3 : g_dev.sb_shm = &g_sb_shm;
130 : 3 : g_dev.conf.overprovisioning = TEST_OP;
131 [ + + ]: 51 : for (uint64_t n = 0; n < sizeof(g_dev.conf.uuid); n++) {
132 : 48 : g_dev.conf.uuid.u.raw[n] = n;
133 : : }
134 : :
135 : 3 : g_dev.layout.nvc.total_blocks = TEST_NVC_BLKS;
136 : 3 : g_dev.layout.base.total_blocks = TEST_BASE_BLKS;
137 : 3 : g_dev.base_type = &g_base_type;
138 : 3 : g_dev.nv_cache.nvc_type = &g_nvc_type;
139 : 3 : g_dev.base_layout_tracker = ftl_layout_tracker_bdev_init(UINT32_MAX);
140 : 3 : g_dev.nvc_layout_tracker = ftl_layout_tracker_bdev_init(UINT32_MAX);
141 : 3 : g_dev.base_bdev_desc = &g_base_bdev_desc;
142 : 3 : g_dev.nv_cache.bdev_desc = &g_nvc_bdev_desc;
143 : :
144 [ + + ]: 63 : for (int regno = 0; regno < FTL_LAYOUT_REGION_TYPE_MAX; regno++) {
145 : 60 : struct ftl_layout_region *reg = &g_dev.layout.region[regno];
146 : 60 : reg->current.blocks = TEST_REG_BLKS;
147 [ + + ]: 60 : regno_dev = sb_v3_md_region_is_nvc(regno) ? ®no_nvc : ®no_base;
148 : 60 : reg->current.offset = *regno_dev * TEST_REG_BLKS;
149 : 60 : (*regno_dev)++;
150 : 60 : reg->current.version = ftl_layout_upgrade_region_get_latest_version(regno);
151 : 60 : reg->type = regno;
152 : 60 : reg->name = "region_test";
153 [ + + ]: 60 : reg->bdev_desc = sb_v3_md_region_is_nvc(regno) ? &g_nvc_bdev_desc : &g_base_bdev_desc;
154 : 60 : reg->ioch = 0;
155 : : }
156 : 3 : return 0;
157 : : }
158 : :
159 : : static int
160 : 3 : test_teardown(void)
161 : : {
162 [ + - ]: 3 : if (g_dev.base_layout_tracker) {
163 : 3 : ftl_layout_tracker_bdev_fini(g_dev.base_layout_tracker);
164 : 3 : g_dev.base_layout_tracker = NULL;
165 : : }
166 [ + - ]: 3 : if (g_dev.nvc_layout_tracker) {
167 : 3 : ftl_layout_tracker_bdev_fini(g_dev.nvc_layout_tracker);
168 : 3 : g_dev.nvc_layout_tracker = NULL;
169 : : }
170 : 3 : return 0;
171 : : }
172 : :
173 : : static void
174 : 3 : test_setup_sb_v5(uint64_t clean)
175 : : {
176 : 3 : union ftl_superblock_ver *sb = (void *)g_sb_buf;
177 : : uint64_t zero_offs;
178 : :
179 [ - + ]: 3 : memset(&g_sb_buf, 0, sizeof(g_sb_buf));
180 : 3 : ftl_mngt_init_default_sb(&g_dev, NULL);
181 : 3 : sb->header.version = FTL_SB_VERSION_5;
182 : :
183 : 3 : zero_offs = sizeof(struct ftl_superblock_v5);
184 [ - + ]: 3 : memset(g_sb_buf + zero_offs, 0, sizeof(g_sb_buf) - zero_offs);
185 : 3 : sb->v5.clean = clean;
186 : :
187 : 3 : sb->header.crc = get_sb_crc(&sb->current);
188 : 3 : }
189 : :
190 : : static void
191 : 3 : test_l2p_upgrade(void)
192 : : {
193 : 3 : union ftl_superblock_ver *sb = (void *)g_sb_buf;
194 : : struct layout_tracker_blob_entry *tbe;
195 : : struct layout_blob_entry *lbe;
196 : : struct ftl_layout_region *reg;
197 : 3 : struct ftl_layout_upgrade_ctx ctx = {0};
198 : : void *blob_nvc, *blob_base, *blob_regs;
199 : : uint64_t upgrades;
200 : : int rc;
201 : :
202 : 3 : test_setup_sb_v5(true);
203 : 3 : CU_ASSERT_EQUAL(ftl_superblock_is_blob_area_empty(&sb->current), true);
204 : :
205 : : /* load failed: empty md list: */
206 : 3 : rc = ftl_superblock_v5_load_blob_area(&g_dev);
207 : 3 : CU_ASSERT_NOT_EQUAL(rc, 0);
208 : :
209 : : /* create md layout: */
210 [ + + ]: 63 : for (enum ftl_layout_region_type regno = 0; regno < FTL_LAYOUT_REGION_TYPE_MAX; regno++) {
211 : 60 : struct ftl_layout_region *reg = &g_dev.layout.region[regno];
212 : 60 : CU_ASSERT_EQUAL(regno, reg->type);
213 [ + + ]: 60 : struct ftl_layout_tracker_bdev *tracker = sb_v3_md_region_is_nvc(regno) ? g_dev.nvc_layout_tracker :
214 : : g_dev.base_layout_tracker;
215 : 100 : const struct ftl_layout_tracker_bdev_region_props *reg_props = ftl_layout_tracker_bdev_add_region(
216 : 60 : tracker, reg->type, reg->current.version, reg->current.blocks, TEST_REG_BLKS);
217 : :
218 : 60 : CU_ASSERT_EQUAL(reg->type, reg_props->type);
219 : 60 : CU_ASSERT_EQUAL(reg->current.version, reg_props->ver);
220 : 60 : CU_ASSERT_EQUAL(reg->current.offset, reg_props->blk_offs);
221 : 60 : CU_ASSERT_EQUAL(reg->current.blocks, reg_props->blk_sz);
222 : : }
223 : 3 : ftl_superblock_v5_store_blob_area(&g_dev);
224 : 3 : CU_ASSERT_EQUAL(ftl_superblock_is_blob_area_empty(&sb->current), false);
225 : :
226 : 3 : blob_nvc = ftl_df_get_obj_ptr(sb->v5.blob_area, sb->v5.md_layout_nvc.df_id);
227 : 3 : blob_base = ftl_df_get_obj_ptr(sb->v5.blob_area, sb->v5.md_layout_base.df_id);
228 : 3 : blob_regs = ftl_df_get_obj_ptr(sb->v5.blob_area, sb->v5.layout_params.df_id);
229 : :
230 : : /* move the sb-stored blobs around: */
231 : 3 : CU_ASSERT(blob_nvc < blob_base);
232 : 3 : CU_ASSERT(blob_base < blob_regs);
233 [ - + - + ]: 3 : blob_regs = memmove(blob_regs + 8192, blob_regs, sb->v5.layout_params.blob_sz);
234 : 3 : sb->v5.layout_params.df_id += 8192;
235 [ - + - + ]: 3 : blob_base = memmove(blob_base + 4096, blob_base, sb->v5.md_layout_base.blob_sz);
236 : 3 : sb->v5.md_layout_base.df_id += 4096;
237 : :
238 : : /* fix l2p region version to v0 */
239 : 3 : tbe = blob_nvc;
240 : 3 : tbe++;
241 : 3 : CU_ASSERT_EQUAL(tbe->type, FTL_LAYOUT_REGION_TYPE_L2P);
242 : 3 : tbe->ver = 0;
243 : 3 : reg = &g_dev.layout.region[FTL_LAYOUT_REGION_TYPE_L2P];
244 : 3 : reg->current.version = 0;
245 : :
246 : : /* fix l2p num entries and size */
247 : 3 : lbe = blob_regs;
248 : 3 : lbe += FTL_LAYOUT_REGION_TYPE_L2P;
249 : 3 : CU_ASSERT_EQUAL(lbe->type, FTL_LAYOUT_REGION_TYPE_L2P);
250 : 3 : lbe->entry_size = 1;
251 : 3 : lbe->num_entries = 0x1000;
252 : :
253 : : /* add l2p v2 region for a major upgrade */
254 : 3 : tbe = (blob_nvc + sb->v5.md_layout_nvc.blob_sz);
255 : 3 : sb->v5.md_layout_nvc.blob_sz += sizeof(*tbe);
256 : 3 : tbe->type = FTL_LAYOUT_REGION_TYPE_L2P;
257 : 3 : tbe->ver = 2;
258 : :
259 : : /* region overlap */
260 : 3 : tbe->blk_offs = 0x1984;
261 : 3 : tbe->blk_sz = 0x0514;
262 : 3 : rc = ftl_superblock_v5_load_blob_area(&g_dev);
263 : 3 : CU_ASSERT_NOT_EQUAL(rc, 0);
264 : :
265 : : /* correct region placement */
266 : 3 : tbe->blk_offs = 0x19840514;
267 : 3 : tbe->blk_sz = 0xc0ffee;
268 : 3 : rc = ftl_superblock_v5_load_blob_area(&g_dev);
269 : 3 : CU_ASSERT_EQUAL(rc, 0);
270 : :
271 : : /* upgrade verification */
272 : 3 : ctx.reg = &g_dev.layout.region[0];
273 : 3 : ctx.upgrade = &layout_upgrade_desc[0];
274 [ + + ]: 63 : for (int reg_type = 0; reg_type < FTL_LAYOUT_REGION_TYPE_MAX;
275 : 60 : reg_type++, ctx.reg++, ctx.upgrade++) {
276 [ + + + + ]: 60 : if (reg_type == FTL_LAYOUT_REGION_TYPE_SB || reg_type == FTL_LAYOUT_REGION_TYPE_SB_BASE) {
277 : 6 : ctx.reg->current.version = g_dev.sb->header.version;
278 : : }
279 : 60 : rc = region_verify(&g_dev, &ctx);
280 : 60 : CU_ASSERT_EQUAL(rc, 0);
281 : : }
282 : :
283 : : /* region upgrade */
284 : 3 : CU_ASSERT_EQUAL(reg->num_entries, 0x1000);
285 : 3 : CU_ASSERT_EQUAL(reg->entry_size, 1);
286 : :
287 : 3 : ctx.reg = &g_dev.layout.region[0];
288 : 3 : ctx.upgrade = &layout_upgrade_desc[0];
289 : 3 : upgrades = 0;
290 : 9 : while (true) {
291 : : uint64_t prev_ver;
292 : :
293 : 12 : rc = layout_upgrade_select_next_region(&g_dev, &ctx);
294 [ + + ]: 12 : if (rc == FTL_LAYOUT_UPGRADE_DONE) {
295 : 3 : break;
296 : : }
297 : 9 : CU_ASSERT_EQUAL(rc, FTL_LAYOUT_UPGRADE_CONTINUE);
298 : 9 : CU_ASSERT_EQUAL(ctx.reg->type, FTL_LAYOUT_REGION_TYPE_L2P);
299 : 9 : upgrades++;
300 : :
301 : 9 : prev_ver = ctx.reg->current.version;
302 : 9 : rc = ftl_region_upgrade(&g_dev, &ctx);
303 : 9 : CU_ASSERT_EQUAL(rc, 0);
304 : 9 : CU_ASSERT_TRUE(prev_ver < ctx.reg->current.version);
305 : 9 : CU_ASSERT_EQUAL(upgrades, ctx.reg->current.version);
306 : : }
307 : 3 : CU_ASSERT_EQUAL(upgrades, 3);
308 : 3 : CU_ASSERT_EQUAL(reg->current.offset, 0x19840514);
309 : 3 : CU_ASSERT_EQUAL(reg->current.blocks, 0xc0ffee);
310 : 3 : CU_ASSERT_EQUAL(reg->num_entries, 0x1984);
311 : 3 : CU_ASSERT_EQUAL(reg->entry_size, 0x1405);
312 : :
313 : : /* no more upgrades: */
314 : 3 : ctx.reg = &g_dev.layout.region[0];
315 : 3 : ctx.upgrade = &layout_upgrade_desc[0];
316 : 3 : rc = layout_upgrade_select_next_region(&g_dev, &ctx);
317 : 3 : CU_ASSERT_EQUAL(rc, FTL_LAYOUT_UPGRADE_DONE);
318 : :
319 : : /* restore the sb: */
320 : 3 : sb->v5.md_layout_nvc.blob_sz -= sizeof(*tbe);
321 : 3 : }
322 : :
323 : : int
324 : 3 : l2p_upgrade_v0_to_v1(struct spdk_ftl_dev *dev, struct ftl_layout_upgrade_ctx *ctx)
325 : : {
326 : 3 : struct ftl_layout_region *region = ctx->reg;
327 : :
328 : : /* minor */
329 : 3 : CU_ASSERT_EQUAL(region->current.version, 0);
330 : 3 : CU_ASSERT_EQUAL(ctx->next_reg_ver, 1);
331 : 3 : CU_ASSERT_NOT_EQUAL(region->current.offset, 0x1984);
332 : 3 : CU_ASSERT_NOT_EQUAL(region->current.blocks, 0x0514);
333 : :
334 : 3 : ftl_region_upgrade_completed(dev, ctx, 0, 0, 0);
335 : 3 : return 0;
336 : : }
337 : :
338 : : int
339 : 3 : l2p_upgrade_v1_to_v2(struct spdk_ftl_dev *dev, struct ftl_layout_upgrade_ctx *ctx)
340 : : {
341 : 3 : struct ftl_layout_region *region = ctx->reg;
342 : :
343 : : /* major */
344 : 3 : CU_ASSERT_EQUAL(region->current.version, 1);
345 : 3 : CU_ASSERT_EQUAL(ctx->next_reg_ver, 2);
346 : 3 : CU_ASSERT_NOT_EQUAL(region->current.offset, 0x1984);
347 : 3 : CU_ASSERT_NOT_EQUAL(region->current.blocks, 0x0514);
348 : :
349 : 3 : ftl_region_upgrade_completed(dev, ctx, 0x1405, 0x1984, 0);
350 : 3 : return 0;
351 : : }
352 : :
353 : : int
354 : 3 : l2p_upgrade_v2_to_v3(struct spdk_ftl_dev *dev, struct ftl_layout_upgrade_ctx *ctx)
355 : : {
356 : 3 : struct ftl_layout_region *region = ctx->reg;
357 : :
358 : : /* minor */
359 : 3 : CU_ASSERT_EQUAL(region->current.version, 2);
360 : 3 : CU_ASSERT_EQUAL(ctx->next_reg_ver, 3);
361 : 3 : CU_ASSERT_EQUAL(region->current.offset, 0x19840514);
362 : 3 : CU_ASSERT_EQUAL(region->current.blocks, 0xc0ffee);
363 : :
364 : 3 : ftl_region_upgrade_completed(dev, ctx, 0, 0, 0);
365 : 3 : return 0;
366 : : }
367 : :
368 : : int
369 : 3 : main(int argc, char **argv)
370 : : {
371 : 3 : CU_pSuite suite = NULL;
372 : 3 : unsigned int num_failures = 0;
373 : :
374 : 3 : CU_set_error_action(CUEA_ABORT);
375 : 3 : CU_initialize_registry();
376 : :
377 : 3 : suite = CU_add_suite("ftl_layout_upgrade", test_setup, test_teardown);
378 : :
379 : 3 : CU_ADD_TEST(suite, test_l2p_upgrade);
380 : :
381 : 3 : CU_basic_set_mode(CU_BRM_VERBOSE);
382 : 3 : CU_basic_run_tests();
383 : 3 : num_failures = CU_get_number_of_failures();
384 : 3 : CU_cleanup_registry();
385 : :
386 : 3 : return num_failures;
387 : : }
|