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 0 : is_bdev_compatible(struct spdk_ftl_dev *dev, struct spdk_bdev *bdev) 13 : { 14 0 : return spdk_bdev_get_block_size(bdev) == FTL_BLOCK_SIZE; 15 : } 16 : 17 : static void 18 0 : md_region_setup(struct spdk_ftl_dev *dev, enum ftl_layout_region_type reg_type, 19 : struct ftl_layout_region *region) 20 : { 21 0 : assert(region); 22 0 : region->type = reg_type; 23 0 : region->mirror_type = FTL_LAYOUT_REGION_TYPE_INVALID; 24 0 : region->name = ftl_md_region_name(reg_type); 25 : 26 0 : region->bdev_desc = dev->base_bdev_desc; 27 0 : region->ioch = dev->base_ioch; 28 0 : region->vss_blksz = 0; 29 0 : } 30 : 31 : static int 32 0 : 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 0 : assert(reg_type < FTL_LAYOUT_REGION_TYPE_MAX); 39 0 : 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 0 : data_base_alignment = 8 * ftl_bitmap_buffer_alignment; 46 0 : reg_props = ftl_layout_tracker_bdev_add_region(dev->base_layout_tracker, reg_type, reg_version, 47 : reg_blks, data_base_alignment); 48 0 : if (!reg_props) { 49 0 : return -1; 50 : } 51 0 : assert(reg_props->type == reg_type); 52 0 : assert(reg_props->ver == reg_version); 53 0 : assert(reg_props->blk_sz == reg_blks); 54 0 : assert(reg_props->blk_offs + reg_blks <= dev->layout.base.total_blocks); 55 0 : return 0; 56 : } 57 : 58 : static int 59 0 : 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 0 : const struct ftl_layout_tracker_bdev_region_props *reg_search_ctx = NULL; 63 0 : uint64_t reg_blks = ftl_md_region_blocks(dev, entry_size * entry_count); 64 : 65 0 : assert(reg_type < FTL_LAYOUT_REGION_TYPE_MAX); 66 : 67 : while (true) { 68 0 : ftl_layout_tracker_bdev_find_next_region(dev->base_layout_tracker, reg_type, ®_search_ctx); 69 0 : if (!reg_search_ctx || reg_search_ctx->ver == reg_version) { 70 : break; 71 : } 72 : } 73 : 74 0 : 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 0 : if (!region) { 80 0 : return 0; 81 : } 82 : 83 0 : md_region_setup(dev, reg_type, region); 84 : 85 0 : region->entry_size = entry_size / FTL_BLOCK_SIZE; 86 0 : region->num_entries = entry_count; 87 : 88 0 : region->current.version = reg_version; 89 0 : region->current.offset = reg_search_ctx->blk_offs; 90 0 : region->current.blocks = reg_search_ctx->blk_sz; 91 : 92 0 : 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 0 : FTL_BASE_DEVICE_TYPE_REGISTER(base_bdev)