Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (C) 2022 Intel Corporation.
3 : : * All rights reserved.
4 : : */
5 : :
6 : : #include "ftl_core.h"
7 : : #include "ftl_mngt.h"
8 : : #include "ftl_mngt_steps.h"
9 : : #include "ftl_sb.h"
10 : : #include "upgrade/ftl_layout_upgrade.h"
11 : :
12 : : struct ftl_mngt_upgrade_ctx {
13 : : struct ftl_mngt_process *parent;
14 : : struct ftl_mngt_process *mngt;
15 : : struct ftl_layout_upgrade_ctx upgrade_ctx;
16 : : };
17 : :
18 : : static void
19 : 0 : region_upgrade_cb(struct spdk_ftl_dev *dev, void *_ctx, int status)
20 : : {
21 : 0 : struct ftl_mngt_upgrade_ctx *ctx = _ctx;
22 : :
23 : 0 : free(ctx->upgrade_ctx.ctx);
24 : 0 : ctx->upgrade_ctx.ctx = NULL;
25 : :
26 [ # # ]: 0 : if (status) {
27 [ # # ]: 0 : FTL_ERRLOG(dev, "Upgrade failed for region %d (rc=%d)\n", ctx->upgrade_ctx.reg->type, status);
28 : 0 : ftl_mngt_fail_step(ctx->mngt);
29 : : } else {
30 : 0 : ftl_superblock_store_blob_area(dev);
31 : 0 : ftl_mngt_next_step(ctx->mngt);
32 : : }
33 : 0 : }
34 : :
35 : : static void
36 : 0 : region_upgrade(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
37 : : {
38 : 0 : struct ftl_mngt_upgrade_ctx *ctx = ftl_mngt_get_caller_ctx(mngt);
39 : 0 : struct ftl_layout_upgrade_ctx *upgrade_ctx = &ctx->upgrade_ctx;
40 : 0 : size_t ctx_size = upgrade_ctx->upgrade->desc[upgrade_ctx->reg->current.version].ctx_size;
41 : 0 : int rc = -1;
42 : :
43 [ # # ]: 0 : assert(upgrade_ctx->ctx == NULL);
44 [ # # ]: 0 : if (ctx_size) {
45 : 0 : upgrade_ctx->ctx = calloc(1, ctx_size);
46 [ # # ]: 0 : if (!upgrade_ctx->ctx) {
47 : 0 : goto exit;
48 : : }
49 : : }
50 : 0 : upgrade_ctx->cb = region_upgrade_cb;
51 : 0 : upgrade_ctx->cb_ctx = ctx;
52 : 0 : ctx->mngt = mngt;
53 : :
54 : 0 : rc = ftl_region_upgrade(dev, upgrade_ctx);
55 : 0 : exit:
56 [ # # ]: 0 : if (rc) {
57 : 0 : region_upgrade_cb(dev, ctx, rc);
58 : : }
59 : 0 : }
60 : :
61 : : static const struct ftl_mngt_process_desc desc_region_upgrade = {
62 : : .name = "FTL region upgrade",
63 : : .steps = {
64 : : {
65 : : .name = "Region upgrade",
66 : : .action = region_upgrade,
67 : : },
68 : : {
69 : : .name = "Persist superblock",
70 : : .action = ftl_mngt_persist_superblock,
71 : : },
72 : : {}
73 : : }
74 : : };
75 : :
76 : : static void
77 : 0 : layout_upgrade_cb(struct spdk_ftl_dev *dev, void *_ctx, int status)
78 : : {
79 : 0 : struct ftl_mngt_upgrade_ctx *ctx = _ctx;
80 : :
81 [ # # ]: 0 : if (status) {
82 : 0 : free(ctx->upgrade_ctx.ctx);
83 : 0 : ctx->upgrade_ctx.ctx = NULL;
84 : 0 : ftl_mngt_fail_step(ctx->parent);
85 : 0 : return;
86 : : }
87 : :
88 : : /* go back to ftl_mngt_upgrade() step and select the next region/version to upgrade */
89 : 0 : ftl_mngt_continue_step(ctx->parent);
90 : : }
91 : :
92 : : static void
93 : 27 : layout_upgrade(struct spdk_ftl_dev *dev, struct ftl_mngt_process *parent)
94 : : {
95 : 27 : struct ftl_mngt_upgrade_ctx *ctx = ftl_mngt_get_process_ctx(parent);
96 : : int rc;
97 : :
98 : 27 : ctx->parent = parent;
99 : 27 : rc = ftl_layout_upgrade_init_ctx(dev, &ctx->upgrade_ctx);
100 : :
101 [ - + - - ]: 27 : switch (rc) {
102 : 0 : case FTL_LAYOUT_UPGRADE_CONTINUE:
103 [ # # ]: 0 : if (!ftl_mngt_process_execute(dev, &desc_region_upgrade, layout_upgrade_cb, ctx)) {
104 : 0 : return;
105 : : }
106 : :
107 : 0 : ftl_mngt_fail_step(parent);
108 : 0 : break;
109 : :
110 : 27 : case FTL_LAYOUT_UPGRADE_DONE:
111 [ - + ]: 27 : if (ftl_upgrade_layout_dump(dev)) {
112 [ # # ]: 0 : FTL_ERRLOG(dev, "MD layout verification failed after upgrade.\n");
113 : 0 : ftl_mngt_fail_step(parent);
114 : : } else {
115 : 27 : ftl_mngt_next_step(parent);
116 : : }
117 : 27 : break;
118 : :
119 : 0 : case FTL_LAYOUT_UPGRADE_FAULT:
120 : 0 : ftl_mngt_fail_step(parent);
121 : 0 : break;
122 : : }
123 [ - + ]: 27 : if (ctx->upgrade_ctx.ctx) {
124 : 0 : free(ctx->upgrade_ctx.ctx);
125 : : }
126 : : }
127 : :
128 : : static const struct ftl_mngt_process_desc desc_layout_upgrade = {
129 : : .name = "FTL layout upgrade",
130 : : .ctx_size = sizeof(struct ftl_mngt_upgrade_ctx),
131 : : .steps = {
132 : : {
133 : : .name = "Layout upgrade",
134 : : .action = layout_upgrade,
135 : : },
136 : : {}
137 : : }
138 : : };
139 : :
140 : :
141 : : void
142 : 27 : ftl_mngt_layout_verify(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
143 : : {
144 [ - + ]: 27 : if (ftl_layout_verify(dev)) {
145 : 0 : ftl_mngt_fail_step(mngt);
146 : : } else {
147 : 27 : ftl_mngt_next_step(mngt);
148 : : }
149 : 27 : }
150 : :
151 : : void
152 : 27 : ftl_mngt_layout_upgrade(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
153 : : {
154 : 27 : ftl_mngt_call_process(mngt, &desc_layout_upgrade, NULL);
155 : 27 : }
|