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 0 : layout_upgrade(struct spdk_ftl_dev *dev, struct ftl_mngt_process *parent)
94 : {
95 0 : struct ftl_mngt_upgrade_ctx *ctx = ftl_mngt_get_process_ctx(parent);
96 : int rc;
97 :
98 0 : ctx->parent = parent;
99 0 : rc = ftl_layout_upgrade_init_ctx(dev, &ctx->upgrade_ctx);
100 :
101 0 : 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 0 : case FTL_LAYOUT_UPGRADE_DONE:
111 0 : 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 0 : ftl_mngt_next_step(parent);
116 : }
117 0 : break;
118 :
119 0 : case FTL_LAYOUT_UPGRADE_FAULT:
120 0 : ftl_mngt_fail_step(parent);
121 0 : break;
122 : }
123 0 : 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 0 : ftl_mngt_layout_verify(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
143 : {
144 0 : if (ftl_layout_verify(dev)) {
145 0 : ftl_mngt_fail_step(mngt);
146 : } else {
147 0 : ftl_mngt_next_step(mngt);
148 : }
149 0 : }
150 :
151 : void
152 0 : ftl_mngt_layout_upgrade(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
153 : {
154 0 : ftl_mngt_call_process(mngt, &desc_layout_upgrade);
155 0 : }
|