1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright 2023 Solidigm All Rights Reserved 3 */ 4 5 #include "ftl_nvc_bdev_common.h" 6 #include "ftl_nvc_dev.h" 7 #include "ftl_core.h" 8 #include "ftl_layout.h" 9 #include "utils/ftl_layout_tracker_bdev.h" 10 #include "mngt/ftl_mngt.h" 11 12 bool 13 ftl_nvc_bdev_common_is_chunk_active(struct spdk_ftl_dev *dev, uint64_t chunk_offset) 14 { 15 const struct ftl_layout_tracker_bdev_region_props *reg_free = ftl_layout_tracker_bdev_insert_region( 16 dev->nvc_layout_tracker, FTL_LAYOUT_REGION_TYPE_INVALID, 0, chunk_offset, 17 dev->layout.nvc.chunk_data_blocks); 18 19 assert(!reg_free || reg_free->type == FTL_LAYOUT_REGION_TYPE_FREE); 20 return reg_free != NULL; 21 } 22 23 static void 24 md_region_setup(struct spdk_ftl_dev *dev, enum ftl_layout_region_type reg_type, 25 struct ftl_layout_region *region) 26 { 27 assert(region); 28 region->type = reg_type; 29 region->mirror_type = FTL_LAYOUT_REGION_TYPE_INVALID; 30 region->name = ftl_md_region_name(reg_type); 31 32 region->bdev_desc = dev->nv_cache.bdev_desc; 33 region->ioch = dev->nv_cache.cache_ioch; 34 region->vss_blksz = dev->nv_cache.md_size; 35 } 36 37 int 38 ftl_nvc_bdev_common_region_create(struct spdk_ftl_dev *dev, enum ftl_layout_region_type reg_type, 39 uint32_t reg_version, size_t reg_blks) 40 { 41 const struct ftl_layout_tracker_bdev_region_props *reg_props; 42 43 assert(reg_type < FTL_LAYOUT_REGION_TYPE_MAX); 44 reg_blks = ftl_md_region_align_blocks(dev, reg_blks); 45 46 reg_props = ftl_layout_tracker_bdev_add_region(dev->nvc_layout_tracker, reg_type, reg_version, 47 reg_blks, 0); 48 if (!reg_props) { 49 return -1; 50 } 51 assert(reg_props->type == reg_type); 52 assert(reg_props->ver == reg_version); 53 assert(reg_props->blk_sz == reg_blks); 54 assert(reg_props->blk_offs + reg_blks <= dev->layout.nvc.total_blocks); 55 return 0; 56 } 57 58 int 59 ftl_nvc_bdev_common_region_open(struct spdk_ftl_dev *dev, enum ftl_layout_region_type reg_type, 60 uint32_t reg_version, 61 size_t entry_size, size_t entry_count, struct ftl_layout_region *region) 62 { 63 const struct ftl_layout_tracker_bdev_region_props *reg_search_ctx = NULL; 64 uint64_t reg_blks = ftl_md_region_blocks(dev, entry_size * entry_count); 65 66 assert(reg_type < FTL_LAYOUT_REGION_TYPE_MAX); 67 68 while (true) { 69 ftl_layout_tracker_bdev_find_next_region(dev->nvc_layout_tracker, reg_type, ®_search_ctx); 70 if (!reg_search_ctx || reg_search_ctx->ver == reg_version) { 71 break; 72 } 73 } 74 75 if (!reg_search_ctx || reg_search_ctx->blk_sz < reg_blks) { 76 /* Region not found or insufficient space */ 77 return -1; 78 } 79 80 if (!region) { 81 return 0; 82 } 83 84 md_region_setup(dev, reg_type, region); 85 86 region->entry_size = entry_size / FTL_BLOCK_SIZE; 87 region->num_entries = entry_count; 88 89 region->current.version = reg_version; 90 region->current.offset = reg_search_ctx->blk_offs; 91 region->current.blocks = reg_search_ctx->blk_sz; 92 93 return 0; 94 } 95