LCOV - code coverage report
Current view: top level - lib/ftl/upgrade - ftl_trim_upgrade.c (source / functions) Hit Total Coverage
Test: ut_cov_unit.info Lines: 0 44 0.0 %
Date: 2024-07-15 04:35:48 Functions: 0 6 0.0 %

          Line data    Source code
       1             : /*   SPDX-License-Identifier: BSD-3-Clause
       2             :  *   Copyright 2023 Solidigm All Rights Reserved
       3             :  *   Copyright (C) 2022 Intel Corporation.
       4             :  *   All rights reserved.
       5             :  */
       6             : 
       7             : #include "ftl_nv_cache.h"
       8             : #include "ftl_layout_upgrade.h"
       9             : #include "ftl_utils.h"
      10             : 
      11             : struct upgrade_ctx {
      12             :         struct ftl_md                   *md;
      13             :         struct ftl_layout_region        reg;
      14             : };
      15             : 
      16             : static void
      17           0 : v0_to_v1_upgrade_cleanup(struct ftl_layout_upgrade_ctx *lctx)
      18             : {
      19           0 :         struct upgrade_ctx *ctx = lctx->ctx;
      20             : 
      21           0 :         if (ctx->md) {
      22           0 :                 ftl_md_destroy(ctx->md, 0);
      23           0 :                 ctx->md = NULL;
      24             :         }
      25           0 : }
      26             : 
      27             : static void
      28           0 : v0_to_v1_upgrade_finish(struct spdk_ftl_dev *dev, struct ftl_layout_upgrade_ctx *lctx, int status)
      29             : {
      30           0 :         struct upgrade_ctx *ctx = lctx->ctx;
      31             : 
      32           0 :         v0_to_v1_upgrade_cleanup(lctx);
      33           0 :         ftl_region_upgrade_completed(dev, lctx, ctx->reg.entry_size, ctx->reg.num_entries, status);
      34           0 : }
      35             : 
      36             : static void
      37           0 : v0_to_v1_upgrade_md_cb(struct spdk_ftl_dev *dev, struct ftl_md *md, int status)
      38             : {
      39           0 :         struct ftl_layout_upgrade_ctx *lctx = md->owner.cb_ctx;
      40             : 
      41           0 :         v0_to_v1_upgrade_finish(dev, lctx, status);
      42           0 : }
      43             : 
      44             : static int
      45           0 : v0_to_v1_upgrade_setup_ctx(struct spdk_ftl_dev *dev, struct ftl_layout_upgrade_ctx *lctx,
      46             :                            uint32_t type)
      47             : {
      48           0 :         struct upgrade_ctx *ctx = lctx->ctx;
      49           0 :         const struct ftl_md_layout_ops *md_ops = &dev->nv_cache.nvc_type->ops.md_layout_ops;
      50             : 
      51             :         /* Create the new NV cache metadata region - v2 */
      52           0 :         if (md_ops->region_open(dev, type, FTL_TRIM_LOG_VERSION_1, sizeof(struct ftl_trim_log), 1,
      53             :                                 &ctx->reg)) {
      54           0 :                 return -1;
      55             :         }
      56           0 :         ctx->md = ftl_md_create(dev, ctx->reg.current.blocks, 0, ctx->reg.name, FTL_MD_CREATE_HEAP,
      57           0 :                                 &ctx->reg);
      58           0 :         if (!ctx->md) {
      59           0 :                 return -1;
      60             :         }
      61             : 
      62           0 :         ctx->md->owner.cb_ctx = lctx;
      63           0 :         ctx->md->cb = v0_to_v1_upgrade_md_cb;
      64             : 
      65           0 :         return 0;
      66             : }
      67             : 
      68             : static int
      69           0 : v0_to_v1_upgrade(struct spdk_ftl_dev *dev, struct ftl_layout_upgrade_ctx *lctx)
      70             : {
      71           0 :         struct upgrade_ctx *ctx = lctx->ctx;
      72             : 
      73           0 :         if (v0_to_v1_upgrade_setup_ctx(dev, lctx, lctx->reg->type)) {
      74           0 :                 goto error;
      75             :         }
      76           0 :         ftl_md_clear(ctx->md, 0, NULL);
      77           0 :         return 0;
      78             : 
      79           0 : error:
      80           0 :         v0_to_v1_upgrade_cleanup(lctx);
      81           0 :         return -1;
      82             : }
      83             : 
      84             : static int
      85           0 : v0_to_v1_upgrade_enabled(struct spdk_ftl_dev *dev, struct ftl_layout_region *region)
      86             : {
      87           0 :         const struct ftl_md_layout_ops *md_ops = &dev->nv_cache.nvc_type->ops.md_layout_ops;
      88             : 
      89             :         assert(sizeof(struct ftl_nv_cache_chunk_md) == FTL_BLOCK_SIZE);
      90             : 
      91           0 :         if (ftl_region_major_upgrade_enabled(dev, region)) {
      92           0 :                 return -1;
      93             :         }
      94             : 
      95             :         /* Create the new trim metadata region (v1) up front - this allocates a separate entry in the superblock and
      96             :          * area on the cache for us. This is to reserve space for other region upgrades allocating new regions and it
      97             :          * allows us to do an atomic upgrade of the whole region.
      98             :          *
      99             :          * If the upgrade is stopped by power failure/crash after the V1 region has been added, then the upgrade process
     100             :          * will start again (since V0 still exists), but region_create will fail (since the v1 region has already been
     101             :          * created). In such a case only verification of the region length by region_open is needed.
     102             :          *
     103             :          * Once the upgrade is fully done, the old v0 region entry will be removed from the SB and its area on the cache
     104             :          * freed.
     105             :          */
     106             : 
     107             : 
     108           0 :         if (md_ops->region_create(dev, region->type, FTL_TRIM_LOG_VERSION_1, 1) &&
     109           0 :             md_ops->region_open(dev, region->type, FTL_TRIM_LOG_VERSION_1, sizeof(struct ftl_trim_log),
     110             :                                 1, NULL)) {
     111           0 :                 return -1;
     112             :         }
     113             : 
     114           0 :         return 0;
     115             : }
     116             : 
     117             : struct ftl_region_upgrade_desc trim_log_upgrade_desc[] = {
     118             :         [FTL_TRIM_LOG_VERSION_0] = {
     119             :                 .verify = v0_to_v1_upgrade_enabled,
     120             :                 .ctx_size = sizeof(struct upgrade_ctx),
     121             :                 .new_version = FTL_TRIM_LOG_VERSION_1,
     122             :                 .upgrade = v0_to_v1_upgrade,
     123             :         },
     124             : };
     125             : 
     126             : SPDK_STATIC_ASSERT(SPDK_COUNTOF(trim_log_upgrade_desc) == FTL_TRIM_LOG_VERSION_CURRENT,
     127             :                    "Missing NVC region upgrade descriptors");

Generated by: LCOV version 1.15