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 "ftl_sb.h"
8 : : #include "ftl_core.h"
9 : : #include "ftl_layout.h"
10 : : #include "upgrade/ftl_sb_upgrade.h"
11 : : #include "upgrade/ftl_sb_v3.h"
12 : : #include "upgrade/ftl_sb_v5.h"
13 : :
14 : : static bool ftl_superblock_v2_check_magic(union ftl_superblock_ver *sb_ver);
15 : :
16 : : struct sb_ops {
17 : : bool (*check_magic)(union ftl_superblock_ver *sb_ver);
18 : :
19 : : bool (*blob_is_empty)(union ftl_superblock_ver *sb_ver);
20 : : bool (*blob_validate)(struct spdk_ftl_dev *dev);
21 : : int (*blob_store)(struct spdk_ftl_dev *dev);
22 : : int (*blob_load)(struct spdk_ftl_dev *dev);
23 : :
24 : : int (*upgrade_region)(struct spdk_ftl_dev *dev, struct ftl_layout_region *reg,
25 : : uint32_t new_version);
26 : :
27 : : int (*layout_apply)(struct spdk_ftl_dev *dev);
28 : : void (*layout_dump)(struct spdk_ftl_dev *dev);
29 : : };
30 : :
31 : : static struct sb_ops *
32 : 156 : sb_get_ops(uint64_t version)
33 : : {
34 : : static struct sb_ops ops[] = {
35 : : [FTL_SB_VERSION_0] = {
36 : : .check_magic = ftl_superblock_v2_check_magic,
37 : : },
38 : : [FTL_SB_VERSION_1] = {
39 : : .check_magic = ftl_superblock_v2_check_magic,
40 : : },
41 : : [FTL_SB_VERSION_2] = {
42 : : .check_magic = ftl_superblock_v2_check_magic,
43 : : },
44 : : [FTL_SB_VERSION_3] = {
45 : : .check_magic = ftl_superblock_v3_check_magic,
46 : : .blob_is_empty = ftl_superblock_v3_md_layout_is_empty,
47 : : .blob_load = ftl_superblock_v3_md_layout_load_all,
48 : : .layout_dump = ftl_superblock_v3_md_layout_dump,
49 : : },
50 : : [FTL_SB_VERSION_4] = {
51 : : .check_magic = ftl_superblock_v3_check_magic,
52 : : .blob_is_empty = ftl_superblock_v3_md_layout_is_empty,
53 : : .blob_load = ftl_superblock_v3_md_layout_load_all,
54 : : .layout_dump = ftl_superblock_v3_md_layout_dump,
55 : : },
56 : : [FTL_SB_VERSION_5] = {
57 : : .check_magic = ftl_superblock_v3_check_magic,
58 : : .blob_is_empty = ftl_superblock_v5_is_blob_area_empty,
59 : : .blob_validate = ftl_superblock_v5_validate_blob_area,
60 : : .blob_store = ftl_superblock_v5_store_blob_area,
61 : : .blob_load = ftl_superblock_v5_load_blob_area,
62 : : .upgrade_region = ftl_superblock_v5_md_layout_upgrade_region,
63 : : .layout_apply = ftl_superblock_v5_md_layout_apply,
64 : : .layout_dump = ftl_superblock_v5_md_layout_dump,
65 : : },
66 : : };
67 : :
68 [ - + ]: 156 : if (version >= SPDK_COUNTOF(ops)) {
69 : 0 : return NULL;
70 : : }
71 : :
72 [ # # # # ]: 156 : return &ops[version];
73 : 0 : }
74 : :
75 : : static bool
76 : 0 : ftl_superblock_v2_check_magic(union ftl_superblock_ver *sb_ver)
77 : : {
78 [ # # # # : 0 : return sb_ver->header.magic == FTL_SUPERBLOCK_MAGIC_V2;
# # # # #
# # # ]
79 : : }
80 : :
81 : : bool
82 : 17 : ftl_superblock_check_magic(struct ftl_superblock *sb)
83 : : {
84 : 17 : union ftl_superblock_ver *sb_ver = (union ftl_superblock_ver *)sb;
85 [ # # # # : 17 : struct sb_ops *ops = sb_get_ops(sb_ver->header.version);
# # ]
86 : :
87 [ + - - + : 17 : if (!ops || !ops->check_magic) {
# # ]
88 [ # # ]: 0 : ftl_abort();
89 : 0 : return false;
90 : : }
91 [ # # # # : 17 : return ops->check_magic(sb_ver);
# # # # ]
92 : 0 : }
93 : :
94 : : bool
95 : 35 : ftl_superblock_is_blob_area_empty(struct ftl_superblock *sb)
96 : : {
97 : 35 : union ftl_superblock_ver *sb_ver = (union ftl_superblock_ver *)sb;
98 [ # # # # : 35 : struct sb_ops *ops = sb_get_ops(sb_ver->header.version);
# # ]
99 : :
100 [ + - - + : 35 : if (!ops || !ops->blob_is_empty) {
# # ]
101 [ # # ]: 0 : ftl_abort();
102 : 0 : return false;
103 : : }
104 [ # # # # : 35 : return ops->blob_is_empty(sb_ver);
# # # # ]
105 : 0 : }
106 : :
107 : : bool
108 : 17 : ftl_superblock_validate_blob_area(struct spdk_ftl_dev *dev)
109 : : {
110 [ # # # # : 17 : struct sb_ops *ops = sb_get_ops(dev->sb->header.version);
# # # # #
# ]
111 : :
112 [ + - - + : 17 : if (!ops || !ops->blob_validate) {
# # # # ]
113 : 0 : return true;
114 : : }
115 [ # # # # : 17 : return ops->blob_validate(dev);
# # # # ]
116 : 0 : }
117 : :
118 : : int
119 : 22 : ftl_superblock_store_blob_area(struct spdk_ftl_dev *dev)
120 : : {
121 [ # # # # : 22 : struct sb_ops *ops = sb_get_ops(dev->sb->header.version);
# # # # #
# ]
122 : :
123 [ + - - + : 22 : if (!ops || !ops->blob_store) {
# # ]
124 [ # # ]: 0 : ftl_abort();
125 : 0 : return -1;
126 : : }
127 [ # # # # : 22 : return ops->blob_store(dev);
# # # # ]
128 : 0 : }
129 : :
130 : : int
131 : 17 : ftl_superblock_load_blob_area(struct spdk_ftl_dev *dev)
132 : : {
133 [ # # # # : 17 : struct sb_ops *ops = sb_get_ops(dev->sb->header.version);
# # # # #
# ]
134 : :
135 [ + - - + : 17 : if (!ops || !ops->blob_load) {
# # ]
136 [ # # ]: 0 : ftl_abort();
137 : 0 : return -1;
138 : : }
139 [ # # # # : 17 : return ops->blob_load(dev);
# # # # ]
140 : 0 : }
141 : :
142 : : int
143 : 9 : ftl_superblock_md_layout_upgrade_region(struct spdk_ftl_dev *dev,
144 : : struct ftl_layout_region *reg, uint32_t new_version)
145 : : {
146 [ # # # # : 9 : struct sb_ops *ops = sb_get_ops(dev->sb->header.version);
# # # # #
# ]
147 : :
148 [ + - - + : 9 : if (!ops || !ops->upgrade_region) {
# # ]
149 [ # # ]: 0 : ftl_abort();
150 : 0 : return -1;
151 : : }
152 [ # # # # : 9 : return ops->upgrade_region(dev, reg, new_version);
# # # # ]
153 : 0 : }
154 : :
155 : : int
156 : 17 : ftl_superblock_md_layout_apply(struct spdk_ftl_dev *dev)
157 : : {
158 [ # # # # : 17 : struct sb_ops *ops = sb_get_ops(dev->sb->header.version);
# # # # #
# ]
159 : :
160 [ + - - + : 17 : if (!ops || !ops->layout_apply) {
# # # # ]
161 : 0 : return 0;
162 : : }
163 [ # # # # : 17 : return ops->layout_apply(dev);
# # # # ]
164 : 0 : }
165 : :
166 : : void
167 : 22 : ftl_superblock_md_layout_dump(struct spdk_ftl_dev *dev)
168 : : {
169 [ # # # # : 22 : struct sb_ops *ops = sb_get_ops(dev->sb->header.version);
# # # # #
# ]
170 : :
171 [ + - - + : 22 : if (!ops || !ops->layout_dump) {
# # ]
172 [ # # ]: 0 : ftl_abort();
173 : 0 : return;
174 : : }
175 [ # # # # : 22 : return ops->layout_dump(dev);
# # # # ]
176 : 0 : }
|