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_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 0 : ftl_mngt_p2l_init_ckpt(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt) 21 : { 22 0 : if (!ftl_p2l_ckpt_init(dev)) { 23 0 : ftl_mngt_next_step(mngt); 24 : } else { 25 0 : ftl_mngt_fail_step(mngt); 26 : } 27 0 : } 28 : 29 : void 30 0 : ftl_mngt_p2l_deinit_ckpt(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt) 31 : { 32 0 : ftl_p2l_ckpt_deinit(dev); 33 0 : ftl_mngt_next_step(mngt); 34 0 : } 35 : 36 : static void 37 0 : ftl_p2l_wipe_md_region_cb(struct spdk_ftl_dev *dev, struct ftl_md *md, int status) 38 : { 39 0 : struct ftl_mngt_p2l_md_ctx *ctx = md->owner.cb_ctx; 40 : 41 0 : if (status) { 42 0 : ftl_mngt_fail_step(ctx->mngt); 43 0 : return; 44 : } 45 : 46 0 : if (ctx->md_region == FTL_LAYOUT_REGION_TYPE_P2L_CKPT_MAX) { 47 0 : ftl_mngt_next_step(ctx->mngt); 48 0 : return; 49 : } 50 : 51 0 : ctx->md_region++; 52 0 : ftl_p2l_wipe_md_region(dev, ctx); 53 : } 54 : 55 : static void 56 0 : ftl_p2l_wipe_md_region(struct spdk_ftl_dev *dev, struct ftl_mngt_p2l_md_ctx *ctx) 57 : { 58 0 : struct ftl_layout *layout = &dev->layout; 59 0 : struct ftl_md *md = layout->md[ctx->md_region]; 60 : 61 0 : assert(ctx->md_region >= FTL_LAYOUT_REGION_TYPE_P2L_CKPT_MIN); 62 0 : assert(ctx->md_region <= FTL_LAYOUT_REGION_TYPE_P2L_CKPT_MAX); 63 : 64 0 : if (!md) { 65 0 : ftl_mngt_fail_step(ctx->mngt); 66 0 : return; 67 : } 68 : 69 0 : md->owner.cb_ctx = ctx; 70 0 : md->cb = ftl_p2l_wipe_md_region_cb; 71 0 : ftl_md_persist(md); 72 : } 73 : 74 : void 75 0 : 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 0 : if (ftl_mngt_alloc_step_ctx(mngt, sizeof(struct ftl_mngt_p2l_md_ctx))) { 80 0 : ftl_mngt_fail_step(mngt); 81 0 : return; 82 : } 83 0 : ctx = ftl_mngt_get_step_ctx(mngt); 84 0 : ctx->mngt = mngt; 85 0 : ctx->md_region = FTL_LAYOUT_REGION_TYPE_P2L_CKPT_MIN; 86 0 : ftl_p2l_wipe_md_region(dev, ctx); 87 : } 88 : 89 : void 90 0 : 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 0 : for (region_type = FTL_LAYOUT_REGION_TYPE_P2L_CKPT_MIN; 96 : region_type <= FTL_LAYOUT_REGION_TYPE_P2L_CKPT_MAX; 97 0 : region_type++) { 98 0 : md = dev->layout.md[region_type]; 99 0 : assert(md); 100 0 : ftl_md_free_buf(md, ftl_md_destroy_region_flags(dev, dev->layout.region[region_type].type)); 101 : } 102 0 : ftl_mngt_next_step(mngt); 103 0 : } 104 : 105 : static void 106 0 : ftl_mngt_p2l_restore_ckpt_cb(struct spdk_ftl_dev *dev, struct ftl_md *md, int status) 107 : { 108 0 : struct ftl_mngt_p2l_md_ctx *ctx = md->owner.cb_ctx; 109 0 : assert(ctx); 110 0 : if (status) { 111 0 : ctx->status = status; 112 : } 113 : 114 0 : if (++ctx->md_region == FTL_LAYOUT_REGION_TYPE_P2L_COUNT) { 115 0 : if (!ctx->status) { 116 0 : ftl_mngt_next_step(ctx->mngt); 117 : } else { 118 0 : ftl_mngt_fail_step(ctx->mngt); 119 : } 120 : } 121 0 : } 122 : 123 : void 124 0 : ftl_mngt_p2l_restore_ckpt(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt) 125 : { 126 0 : 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 0 : if (ftl_fast_startup(dev)) { 132 0 : FTL_NOTICELOG(dev, "SHM: skipping p2l ckpt restore\n"); 133 0 : ftl_mngt_next_step(mngt); 134 0 : return; 135 : } 136 : 137 0 : if (ftl_mngt_alloc_step_ctx(mngt, sizeof(struct ftl_mngt_p2l_md_ctx))) { 138 0 : ftl_mngt_fail_step(mngt); 139 0 : return; 140 : } 141 0 : ctx = ftl_mngt_get_step_ctx(mngt); 142 0 : ctx->mngt = mngt; 143 0 : ctx->md_region = 0; 144 0 : ctx->status = 0; 145 : 146 0 : for (md_region = FTL_LAYOUT_REGION_TYPE_P2L_CKPT_MIN; 147 0 : md_region <= FTL_LAYOUT_REGION_TYPE_P2L_CKPT_MAX; md_region++) { 148 0 : md = layout->md[md_region]; 149 0 : assert(md); 150 0 : md->owner.cb_ctx = ctx; 151 0 : md->cb = ftl_mngt_p2l_restore_ckpt_cb; 152 0 : ftl_md_restore(md); 153 : } 154 : }