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 9 static bool 10 is_bdev_compatible(struct spdk_ftl_dev *dev, struct spdk_bdev *bdev) 11 { 12 return spdk_bdev_get_block_size(bdev) == FTL_BLOCK_SIZE; 13 } 14 15 static struct ftl_layout_region * 16 md_region_create(struct spdk_ftl_dev *dev, enum ftl_layout_region_type reg_type, 17 uint32_t reg_version, size_t entry_size, size_t entry_count) 18 { 19 struct ftl_layout *layout = &dev->layout; 20 struct ftl_layout_region *region; 21 uint64_t reg_free_offs = 0, reg_current_end, reg_offs, data_base_alignment; 22 const char *md_region_name; 23 24 assert(reg_type < FTL_LAYOUT_REGION_TYPE_MAX); 25 md_region_name = ftl_md_region_name(reg_type); 26 27 /* As new MD regions are added one after another, find where all existing regions end on the device */ 28 region = layout->region; 29 for (int reg_idx = 0; reg_idx < FTL_LAYOUT_REGION_TYPE_MAX; reg_idx++, region++) { 30 if (region->bdev_desc == dev->base_bdev_desc) { 31 reg_current_end = region->current.offset + region->current.blocks; 32 reg_free_offs = spdk_max(reg_free_offs, reg_current_end); 33 } 34 } 35 36 37 data_base_alignment = 8 * ftl_bitmap_buffer_alignment; 38 /* Allocating a ftl_bitmap requires a 8B input buffer alignment, since we're reusing the global valid map md buffer 39 * this means that each band starting address needs to be aligned too - each device sector takes 1b in the valid map, 40 * so 64 sectors (8*8) is the needed alignment 41 */ 42 reg_offs = SPDK_ALIGN_CEIL(reg_free_offs, data_base_alignment); 43 44 region = &layout->region[reg_type]; 45 region->type = reg_type; 46 region->mirror_type = FTL_LAYOUT_REGION_TYPE_INVALID; 47 region->name = md_region_name; 48 region->current.version = region->prev.version = reg_version; 49 region->current.offset = reg_offs; 50 region->current.blocks = ftl_md_region_blocks(dev, entry_count * entry_size); 51 region->entry_size = entry_size / FTL_BLOCK_SIZE; 52 region->num_entries = entry_count; 53 54 region->bdev_desc = dev->base_bdev_desc; 55 region->ioch = dev->base_ioch; 56 region->vss_blksz = 0; 57 58 reg_offs += region->current.blocks; 59 if (reg_offs > layout->base.total_blocks) { 60 return NULL; 61 } 62 63 return region; 64 } 65 66 struct ftl_base_device_type base_bdev = { 67 .name = "base_bdev", 68 .ops = { 69 .is_bdev_compatible = is_bdev_compatible, 70 .md_layout_ops = { 71 .region_create = md_region_create, 72 }, 73 } 74 }; 75 FTL_BASE_DEVICE_TYPE_REGISTER(base_bdev) 76