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