LCOV - code coverage report
Current view: top level - spdk/lib/ftl/upgrade - ftl_p2l_upgrade.c (source / functions) Hit Total Coverage
Test: Combined Lines: 0 44 0.0 %
Date: 2024-07-12 12:30:19 Functions: 0 6 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 14 0.0 %

           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 "mngt/ftl_mngt.h"
       7                 :            : #include "mngt/ftl_mngt_steps.h"
       8                 :            : #include "ftl_layout_upgrade.h"
       9                 :            : 
      10                 :            : struct upgrade_ctx {
      11                 :            :         struct ftl_md                   *md;
      12                 :            :         struct ftl_layout_region        reg;
      13                 :            : };
      14                 :            : 
      15                 :            : static void
      16                 :          0 : v2_upgrade_cleanup(struct ftl_layout_upgrade_ctx *lctx)
      17                 :            : {
      18                 :          0 :         struct upgrade_ctx *ctx = lctx->ctx;
      19                 :            : 
      20         [ #  # ]:          0 :         if (ctx->md) {
      21                 :          0 :                 ftl_md_destroy(ctx->md, 0);
      22                 :          0 :                 ctx->md = NULL;
      23                 :            :         }
      24                 :          0 : }
      25                 :            : 
      26                 :            : static void
      27                 :          0 : v2_upgrade_finish(struct spdk_ftl_dev *dev, struct ftl_layout_upgrade_ctx *lctx, int status)
      28                 :            : {
      29                 :          0 :         struct upgrade_ctx *ctx = lctx->ctx;
      30                 :            : 
      31                 :          0 :         v2_upgrade_cleanup(lctx);
      32                 :          0 :         ftl_region_upgrade_completed(dev, lctx, ctx->reg.entry_size, ctx->reg.num_entries, status);
      33                 :          0 : }
      34                 :            : 
      35                 :            : static void
      36                 :          0 : v2_upgrade_md_cb(struct spdk_ftl_dev *dev, struct ftl_md *md, int status)
      37                 :            : {
      38                 :          0 :         struct ftl_layout_upgrade_ctx *lctx = md->owner.cb_ctx;
      39                 :            : 
      40                 :          0 :         v2_upgrade_finish(dev, lctx, status);
      41                 :          0 : }
      42                 :            : 
      43                 :            : static int
      44                 :          0 : v2_upgrade_setup_ctx(struct spdk_ftl_dev *dev, struct ftl_layout_upgrade_ctx *lctx, uint32_t type)
      45                 :            : {
      46                 :          0 :         struct upgrade_ctx *ctx = lctx->ctx;
      47                 :          0 :         const struct ftl_md_layout_ops *md_ops = &dev->nv_cache.nvc_type->ops.md_layout_ops;
      48                 :            : 
      49                 :            :         /* TODO Add validation if no open bands */
      50                 :            : 
      51                 :            :         /* Open metadata region */
      52         [ #  # ]:          0 :         if (md_ops->region_open(dev, lctx->reg->type, FTL_P2L_VERSION_2,
      53                 :            :                                 sizeof(struct ftl_p2l_ckpt_page_no_vss),
      54                 :            :                                 dev->layout.p2l.ckpt_pages, &ctx->reg)) {
      55                 :          0 :                 return -1;
      56                 :            :         }
      57                 :            : 
      58                 :          0 :         ctx->md = ftl_md_create(dev, ctx->reg.current.blocks, 0, ctx->reg.name, FTL_MD_CREATE_HEAP,
      59                 :          0 :                                 &ctx->reg);
      60         [ #  # ]:          0 :         if (!ctx->md) {
      61                 :          0 :                 return -1;
      62                 :            :         }
      63                 :            : 
      64                 :          0 :         ctx->md->owner.cb_ctx = lctx;
      65                 :          0 :         ctx->md->cb = v2_upgrade_md_cb;
      66                 :            : 
      67                 :          0 :         return 0;
      68                 :            : }
      69                 :            : 
      70                 :            : static int
      71                 :          0 : v2_upgrade(struct spdk_ftl_dev *dev, struct ftl_layout_upgrade_ctx *lctx)
      72                 :            : {
      73                 :          0 :         struct upgrade_ctx *ctx = lctx->ctx;
      74                 :            : 
      75         [ #  # ]:          0 :         if (v2_upgrade_setup_ctx(dev, lctx, lctx->reg->type)) {
      76                 :          0 :                 goto error;
      77                 :            :         }
      78                 :          0 :         ftl_md_clear(ctx->md, 0, NULL);
      79                 :          0 :         return 0;
      80                 :          0 : error:
      81                 :          0 :         v2_upgrade_cleanup(lctx);
      82                 :          0 :         return -1;
      83                 :            : }
      84                 :            : 
      85                 :            : static int
      86                 :          0 : v1_to_v2_upgrade_enabled(struct spdk_ftl_dev *dev, struct ftl_layout_region *region)
      87                 :            : {
      88                 :          0 :         const struct ftl_md_layout_ops *md_ops = &dev->nv_cache.nvc_type->ops.md_layout_ops;
      89                 :            : 
      90         [ #  # ]:          0 :         if (ftl_region_major_upgrade_enabled(dev, region)) {
      91                 :          0 :                 return -1;
      92                 :            :         }
      93                 :            : 
      94                 :            :         /* Create the new P2L metadata region (v2) up front - this allocates a separate entry in the superblock and
      95                 :            :          * area on the cache for us. This is to reserve space for other region upgrades allocating new regions and it
      96                 :            :          * allows us to do an atomic upgrade of the whole region.
      97                 :            :          *
      98                 :            :          * If the upgrade is stopped by power failure/crash after the V2 region has been added, then the upgrade process
      99                 :            :          * will start again (since V1 still exists), but region_create will fail (since the v2 region has already been
     100                 :            :          * created). In such a case only verification of the region length by region_open is needed.
     101                 :            :          *
     102                 :            :          * Once the upgrade is fully done, the old v1 region entry will be removed from the SB and its area on the cache
     103                 :            :          * freed.
     104                 :            :          */
     105   [ #  #  #  # ]:          0 :         if (md_ops->region_create(dev, region->type, FTL_P2L_VERSION_2, dev->layout.p2l.ckpt_pages) &&
     106                 :          0 :             md_ops->region_open(dev, region->type, FTL_P2L_VERSION_2, sizeof(struct ftl_p2l_ckpt_page_no_vss),
     107                 :            :                                 dev->layout.p2l.ckpt_pages, NULL)) {
     108                 :          0 :                 return -1;
     109                 :            :         }
     110                 :            : 
     111                 :          0 :         return 0;
     112                 :            : }
     113                 :            : 
     114                 :            : struct ftl_region_upgrade_desc p2l_upgrade_desc[] = {
     115                 :            :         [FTL_P2L_VERSION_0] = {
     116                 :            :                 .verify = ftl_region_upgrade_disabled
     117                 :            :         },
     118                 :            :         [FTL_P2L_VERSION_1] = {
     119                 :            :                 .verify = v1_to_v2_upgrade_enabled,
     120                 :            :                 .ctx_size = sizeof(struct upgrade_ctx),
     121                 :            :                 .new_version = FTL_P2L_VERSION_2,
     122                 :            :                 .upgrade = v2_upgrade,
     123                 :            :         },
     124                 :            : };
     125                 :            : 
     126                 :            : SPDK_STATIC_ASSERT(SPDK_COUNTOF(p2l_upgrade_desc) == FTL_P2L_VERSION_CURRENT,
     127                 :            :                    "Missing P2L region upgrade descriptors");

Generated by: LCOV version 1.14