Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause 2 : : * Copyright 2023 Solidigm All Rights Reserved 3 : : */ 4 : : 5 : : #include "ftl_base_dev.h" 6 : : #include "ftl_core.h" 7 : : #include "ftl_layout.h" 8 : : #include "ftl_band.h" 9 : : #include "utils/ftl_layout_tracker_bdev.h" 10 : : 11 : : static bool 12 : 22 : is_bdev_compatible(struct spdk_ftl_dev *dev, struct spdk_bdev *bdev) 13 : : { 14 : 22 : return spdk_bdev_get_block_size(bdev) == FTL_BLOCK_SIZE; 15 : : } 16 : : 17 : : static void 18 : 32 : md_region_setup(struct spdk_ftl_dev *dev, enum ftl_layout_region_type reg_type, 19 : : struct ftl_layout_region *region) 20 : : { 21 [ - + ]: 32 : assert(region); 22 : 32 : region->type = reg_type; 23 : 32 : region->mirror_type = FTL_LAYOUT_REGION_TYPE_INVALID; 24 : 32 : region->name = ftl_md_region_name(reg_type); 25 : : 26 : 32 : region->bdev_desc = dev->base_bdev_desc; 27 : 32 : region->ioch = dev->base_ioch; 28 : 32 : region->vss_blksz = 0; 29 : 32 : } 30 : : 31 : : static int 32 : 32 : md_region_create(struct spdk_ftl_dev *dev, enum ftl_layout_region_type reg_type, 33 : : uint32_t reg_version, size_t reg_blks) 34 : : { 35 : : const struct ftl_layout_tracker_bdev_region_props *reg_props; 36 : : uint64_t data_base_alignment; 37 : : 38 [ - + ]: 32 : assert(reg_type < FTL_LAYOUT_REGION_TYPE_MAX); 39 : 32 : reg_blks = ftl_md_region_align_blocks(dev, reg_blks); 40 : : 41 : : /* Allocating a ftl_bitmap requires a 8B input buffer alignment, since we're reusing the global valid map md buffer 42 : : * this means that each band starting address needs to be aligned too - each device sector takes 1b in the valid map, 43 : : * so 64 sectors (8*8) is the needed alignment 44 : : */ 45 : 32 : data_base_alignment = 8 * ftl_bitmap_buffer_alignment; 46 : 32 : reg_props = ftl_layout_tracker_bdev_add_region(dev->base_layout_tracker, reg_type, reg_version, 47 : : reg_blks, data_base_alignment); 48 [ - + ]: 32 : if (!reg_props) { 49 : 0 : return -1; 50 : : } 51 [ - + ]: 32 : assert(reg_props->type == reg_type); 52 [ - + ]: 32 : assert(reg_props->ver == reg_version); 53 [ - + ]: 32 : assert(reg_props->blk_sz == reg_blks); 54 [ - + ]: 32 : assert(reg_props->blk_offs + reg_blks <= dev->layout.base.total_blocks); 55 : 32 : return 0; 56 : : } 57 : : 58 : : static int 59 : 32 : md_region_open(struct spdk_ftl_dev *dev, enum ftl_layout_region_type reg_type, uint32_t reg_version, 60 : : size_t entry_size, size_t entry_count, struct ftl_layout_region *region) 61 : : { 62 : 32 : const struct ftl_layout_tracker_bdev_region_props *reg_search_ctx = NULL; 63 : 32 : uint64_t reg_blks = ftl_md_region_blocks(dev, entry_size * entry_count); 64 : : 65 [ + - ]: 32 : assert(reg_type < FTL_LAYOUT_REGION_TYPE_MAX); 66 : : 67 : : while (true) { 68 : 32 : ftl_layout_tracker_bdev_find_next_region(dev->base_layout_tracker, reg_type, ®_search_ctx); 69 [ + - - + ]: 32 : if (!reg_search_ctx || reg_search_ctx->ver == reg_version) { 70 : : break; 71 : : } 72 : : } 73 : : 74 [ + - - + ]: 32 : if (!reg_search_ctx || reg_search_ctx->blk_sz < reg_blks) { 75 : : /* Region not found or insufficient space */ 76 : 0 : return -1; 77 : : } 78 : : 79 [ - + ]: 32 : if (!region) { 80 : 0 : return 0; 81 : : } 82 : : 83 : 32 : md_region_setup(dev, reg_type, region); 84 : : 85 : 32 : region->entry_size = entry_size / FTL_BLOCK_SIZE; 86 : 32 : region->num_entries = entry_count; 87 : : 88 : 32 : region->current.version = reg_version; 89 : 32 : region->current.offset = reg_search_ctx->blk_offs; 90 : 32 : region->current.blocks = reg_search_ctx->blk_sz; 91 : : 92 : 32 : return 0; 93 : : } 94 : : 95 : : struct ftl_base_device_type base_bdev = { 96 : : .name = "base_bdev", 97 : : .ops = { 98 : : .is_bdev_compatible = is_bdev_compatible, 99 : : 100 : : .md_layout_ops = { 101 : : .region_create = md_region_create, 102 : : .region_open = md_region_open, 103 : : }, 104 : : } 105 : : }; 106 : 1882 : FTL_BASE_DEVICE_TYPE_REGISTER(base_bdev)