xref: /spdk/lib/ftl/mngt/ftl_mngt_p2l.c (revision 588dfe314bb83d86effdf67ec42837b11c2620bf)
1 /*   SPDX-License-Identifier: BSD-3-Clause
2  *   Copyright (C) 2022 Intel Corporation.
3  *   All rights reserved.
4  */
5 
6 #include "ftl_mngt.h"
7 #include "ftl_mngt_steps.h"
8 #include "ftl_internal.h"
9 #include "ftl_core.h"
10 
11 struct ftl_mngt_p2l_md_ctx {
12 	struct ftl_mngt_process *mngt;
13 	int md_region;
14 	int status;
15 };
16 
17 static void ftl_p2l_wipe_md_region(struct spdk_ftl_dev *dev, struct ftl_mngt_p2l_md_ctx *ctx);
18 
19 void
20 ftl_mngt_p2l_init_ckpt(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
21 {
22 	if (!ftl_p2l_ckpt_init(dev)) {
23 		ftl_mngt_next_step(mngt);
24 	} else {
25 		ftl_mngt_fail_step(mngt);
26 	}
27 }
28 
29 void
30 ftl_mngt_p2l_deinit_ckpt(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
31 {
32 	ftl_p2l_ckpt_deinit(dev);
33 	ftl_mngt_next_step(mngt);
34 }
35 
36 static void
37 ftl_p2l_wipe_md_region_cb(struct spdk_ftl_dev *dev, struct ftl_md *md, int status)
38 {
39 	struct ftl_mngt_p2l_md_ctx *ctx = md->owner.cb_ctx;
40 
41 	if (status) {
42 		ftl_mngt_fail_step(ctx->mngt);
43 		return;
44 	}
45 
46 	if (ctx->md_region == FTL_LAYOUT_REGION_TYPE_P2L_CKPT_MAX) {
47 		ftl_mngt_next_step(ctx->mngt);
48 		return;
49 	}
50 
51 	ctx->md_region++;
52 	ftl_p2l_wipe_md_region(dev, ctx);
53 }
54 
55 static void
56 ftl_p2l_wipe_md_region(struct spdk_ftl_dev *dev, struct ftl_mngt_p2l_md_ctx *ctx)
57 {
58 	struct ftl_layout *layout = &dev->layout;
59 	struct ftl_md *md = layout->md[ctx->md_region];
60 
61 	assert(ctx->md_region >= FTL_LAYOUT_REGION_TYPE_P2L_CKPT_MIN);
62 	assert(ctx->md_region <= FTL_LAYOUT_REGION_TYPE_P2L_CKPT_MAX);
63 
64 	if (!md) {
65 		ftl_mngt_fail_step(ctx->mngt);
66 		return;
67 	}
68 
69 	md->owner.cb_ctx = ctx;
70 	md->cb = ftl_p2l_wipe_md_region_cb;
71 	ftl_md_persist(md);
72 }
73 
74 void
75 ftl_mngt_p2l_wipe(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
76 {
77 	struct ftl_mngt_p2l_md_ctx *ctx;
78 
79 	if (ftl_mngt_alloc_step_ctx(mngt, sizeof(struct ftl_mngt_p2l_md_ctx))) {
80 		ftl_mngt_fail_step(mngt);
81 		return;
82 	}
83 	ctx = ftl_mngt_get_step_ctx(mngt);
84 	ctx->mngt = mngt;
85 	ctx->md_region = FTL_LAYOUT_REGION_TYPE_P2L_CKPT_MIN;
86 	ftl_p2l_wipe_md_region(dev, ctx);
87 }
88 
89 void
90 ftl_mngt_p2l_free_bufs(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
91 {
92 	struct ftl_md *md;
93 	int region_type;
94 
95 	for (region_type = FTL_LAYOUT_REGION_TYPE_P2L_CKPT_MIN;
96 	     region_type <= FTL_LAYOUT_REGION_TYPE_P2L_CKPT_MAX;
97 	     region_type++) {
98 		md = dev->layout.md[region_type];
99 		assert(md);
100 		ftl_md_free_buf(md, ftl_md_destroy_region_flags(dev, dev->layout.region[region_type].type));
101 	}
102 	ftl_mngt_next_step(mngt);
103 }
104 
105 static void
106 ftl_mngt_p2l_restore_ckpt_cb(struct spdk_ftl_dev *dev, struct ftl_md *md, int status)
107 {
108 	struct ftl_mngt_p2l_md_ctx *ctx = md->owner.cb_ctx;
109 	assert(ctx);
110 	if (status) {
111 		ctx->status = status;
112 	}
113 
114 	if (++ctx->md_region == FTL_LAYOUT_REGION_TYPE_P2L_COUNT) {
115 		if (!ctx->status) {
116 			ftl_mngt_next_step(ctx->mngt);
117 		} else {
118 			ftl_mngt_fail_step(ctx->mngt);
119 		}
120 	}
121 }
122 
123 void
124 ftl_mngt_p2l_restore_ckpt(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
125 {
126 	struct ftl_layout *layout = &dev->layout;
127 	struct ftl_md *md;
128 	struct ftl_mngt_p2l_md_ctx *ctx;
129 	int md_region;
130 
131 	if (ftl_fast_startup(dev)) {
132 		FTL_NOTICELOG(dev, "SHM: skipping p2l ckpt restore\n");
133 		ftl_mngt_next_step(mngt);
134 		return;
135 	}
136 
137 	if (ftl_mngt_alloc_step_ctx(mngt, sizeof(struct ftl_mngt_p2l_md_ctx))) {
138 		ftl_mngt_fail_step(mngt);
139 		return;
140 	}
141 	ctx = ftl_mngt_get_step_ctx(mngt);
142 	ctx->mngt = mngt;
143 	ctx->md_region = 0;
144 	ctx->status = 0;
145 
146 	for (md_region = FTL_LAYOUT_REGION_TYPE_P2L_CKPT_MIN;
147 	     md_region <= FTL_LAYOUT_REGION_TYPE_P2L_CKPT_MAX; md_region++) {
148 		md = layout->md[md_region];
149 		assert(md);
150 		md->owner.cb_ctx = ctx;
151 		md->cb = ftl_mngt_p2l_restore_ckpt_cb;
152 		ftl_md_restore(md);
153 	}
154 }
155