xref: /spdk/lib/ftl/mngt/ftl_mngt_upgrade.c (revision 8afdeef3becfe9409cc9e7372bd0bc10e8b7d46d)
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 region_upgrade_cb(struct spdk_ftl_dev *dev, void *_ctx, int status)
20 {
21 	struct ftl_mngt_upgrade_ctx *ctx = _ctx;
22 
23 	free(ctx->upgrade_ctx.ctx);
24 	ctx->upgrade_ctx.ctx = NULL;
25 
26 	if (status) {
27 		FTL_ERRLOG(dev, "Upgrade failed for region %d (rc=%d)\n", ctx->upgrade_ctx.reg->type, status);
28 		ftl_mngt_fail_step(ctx->mngt);
29 	} else {
30 		ftl_superblock_store_blob_area(dev);
31 		ftl_mngt_next_step(ctx->mngt);
32 	}
33 }
34 
35 static void
36 region_upgrade(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
37 {
38 	struct ftl_mngt_upgrade_ctx *ctx = ftl_mngt_get_caller_ctx(mngt);
39 	struct ftl_layout_upgrade_ctx *upgrade_ctx = &ctx->upgrade_ctx;
40 	size_t ctx_size = upgrade_ctx->upgrade->desc[upgrade_ctx->reg->current.version].ctx_size;
41 	int rc = -1;
42 
43 	assert(upgrade_ctx->ctx == NULL);
44 	if (ctx_size) {
45 		upgrade_ctx->ctx = calloc(1, ctx_size);
46 		if (!upgrade_ctx->ctx) {
47 			goto exit;
48 		}
49 	}
50 	upgrade_ctx->cb = region_upgrade_cb;
51 	upgrade_ctx->cb_ctx = ctx;
52 	ctx->mngt = mngt;
53 
54 	rc = ftl_region_upgrade(dev, upgrade_ctx);
55 exit:
56 	if (rc) {
57 		region_upgrade_cb(dev, ctx, rc);
58 	}
59 }
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 layout_upgrade_cb(struct spdk_ftl_dev *dev, void *_ctx, int status)
78 {
79 	struct ftl_mngt_upgrade_ctx *ctx = _ctx;
80 
81 	if (status) {
82 		free(ctx->upgrade_ctx.ctx);
83 		ctx->upgrade_ctx.ctx = NULL;
84 		ftl_mngt_fail_step(ctx->parent);
85 		return;
86 	}
87 
88 	/* go back to ftl_mngt_upgrade() step and select the next region/version to upgrade */
89 	ftl_mngt_continue_step(ctx->parent);
90 }
91 
92 static void
93 layout_upgrade(struct spdk_ftl_dev *dev, struct ftl_mngt_process *parent)
94 {
95 	struct ftl_mngt_upgrade_ctx *ctx = ftl_mngt_get_process_ctx(parent);
96 	int rc;
97 
98 	ctx->parent = parent;
99 	rc = ftl_layout_upgrade_init_ctx(dev, &ctx->upgrade_ctx);
100 
101 	switch (rc) {
102 	case FTL_LAYOUT_UPGRADE_CONTINUE:
103 		if (!ftl_mngt_process_execute(dev, &desc_region_upgrade, layout_upgrade_cb, ctx)) {
104 			return;
105 		}
106 
107 		ftl_mngt_fail_step(parent);
108 		break;
109 
110 	case FTL_LAYOUT_UPGRADE_DONE:
111 		if (ftl_upgrade_layout_dump(dev)) {
112 			FTL_ERRLOG(dev, "MD layout verification failed after upgrade.\n");
113 			ftl_mngt_fail_step(parent);
114 		} else {
115 			ftl_mngt_next_step(parent);
116 		}
117 		break;
118 
119 	case FTL_LAYOUT_UPGRADE_FAULT:
120 		ftl_mngt_fail_step(parent);
121 		break;
122 	}
123 	if (ctx->upgrade_ctx.ctx) {
124 		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 ftl_mngt_layout_verify(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
143 {
144 	if (ftl_layout_verify(dev)) {
145 		ftl_mngt_fail_step(mngt);
146 	} else {
147 		ftl_mngt_next_step(mngt);
148 	}
149 }
150 
151 void
152 ftl_mngt_layout_upgrade(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
153 {
154 	ftl_mngt_call_process(mngt, &desc_layout_upgrade, NULL);
155 }
156