diff --git a/lib/ftl/ftl_band.c b/lib/ftl/ftl_band.c index 87038e442..479524a2e 100644 --- a/lib/ftl/ftl_band.c +++ b/lib/ftl/ftl_band.c @@ -225,6 +225,12 @@ ftl_band_user_blocks(const struct ftl_band *band) ftl_tail_md_num_blocks(band->dev); } +static inline uint64_t +ftl_addr_get_band(const struct spdk_ftl_dev *dev, ftl_addr addr) +{ + return (addr - dev->bands->start_addr) / ftl_get_num_blocks_in_band(dev); +} + struct ftl_band * ftl_band_from_addr(struct spdk_ftl_dev *dev, ftl_addr addr) { @@ -238,7 +244,7 @@ uint64_t ftl_band_block_offset_from_addr(struct ftl_band *band, ftl_addr addr) { assert(ftl_addr_get_band(band->dev, addr) == band->id); - return addr % ftl_get_num_blocks_in_band(band->dev); + return addr - band->start_addr; } ftl_addr @@ -285,7 +291,7 @@ ftl_band_addr_from_block_offset(struct ftl_band *band, uint64_t block_off) { ftl_addr addr; - addr = block_off + band->id * ftl_get_num_blocks_in_band(band->dev); + addr = block_off + band->start_addr; return addr; } diff --git a/lib/ftl/ftl_core.h b/lib/ftl/ftl_core.h index d0fca2e5f..b49cd9f08 100644 --- a/lib/ftl/ftl_core.h +++ b/lib/ftl/ftl_core.h @@ -220,12 +220,6 @@ ftl_get_num_blocks_in_band(const struct spdk_ftl_dev *dev) return dev->num_blocks_in_band; } -static inline uint64_t -ftl_addr_get_band(const struct spdk_ftl_dev *dev, ftl_addr addr) -{ - return addr / ftl_get_num_blocks_in_band(dev); -} - static inline uint32_t ftl_get_write_unit_size(struct spdk_bdev *bdev) { diff --git a/lib/ftl/ftl_layout.c b/lib/ftl/ftl_layout.c index f3f040fec..5992c8814 100644 --- a/lib/ftl/ftl_layout.c +++ b/lib/ftl/ftl_layout.c @@ -344,30 +344,33 @@ setup_layout_base(struct spdk_ftl_dev *dev) uint64_t left, offset; struct ftl_layout *layout = &dev->layout; struct ftl_layout_region *region; + uint64_t data_base_alignment = 8 * ftl_bitmap_buffer_alignment; + /* Allocating a ftl_bitmap requires a 8B input buffer alignment, since we're reusing the global valid map md buffer + * this means that each band starting address needs to be aligned too - each device sector takes 1b in the valid map, + * so 64 sectors (8*8) is the needed alignment + */ layout->base.num_usable_blocks = ftl_get_num_blocks_in_band(dev); layout->base.user_blocks = ftl_band_user_blocks(dev->bands); /* Base device layout is following: - * - data * - superblock + * - data * - valid map - * - * Superblock has been already configured, its offset marks the end of the data region */ - offset = layout->region[FTL_LAYOUT_REGION_TYPE_SB_BASE].current.offset; + offset = layout->region[FTL_LAYOUT_REGION_TYPE_SB_BASE].current.blocks; + offset = SPDK_ALIGN_CEIL(offset, data_base_alignment); /* Setup data region on base device */ region = &layout->region[FTL_LAYOUT_REGION_TYPE_DATA_BASE]; region->type = FTL_LAYOUT_REGION_TYPE_DATA_BASE; region->name = "data_btm"; region->current.version = region->prev.version = 0; - region->current.offset = 0; - region->current.blocks = offset; + region->current.offset = offset; + region->current.blocks = layout_base_offset(dev); set_region_bdev_btm(region, dev); - /* Move offset after base superblock */ - offset += layout->region[FTL_LAYOUT_REGION_TYPE_SB_BASE].current.blocks; + offset += region->current.blocks; /* Setup validity map */ region = &layout->region[FTL_LAYOUT_REGION_TYPE_VALID_MAP]; @@ -529,10 +532,7 @@ ftl_layout_setup_superblock(struct spdk_ftl_dev *dev) region->name = "sb_mirror"; region->current.version = FTL_SB_VERSION_CURRENT; region->prev.version = FTL_SB_VERSION_CURRENT; - /* TODO: This should really be at offset 0 - think how best to upgrade between the two layouts - * This is an issue if some other metadata appears at block 0 of base device (most likely GPT or blobstore) - */ - region->current.offset = layout_base_offset(dev); + region->current.offset = 0; region->current.blocks = blocks_region(FTL_SUPERBLOCK_SIZE); set_region_bdev_btm(region, dev); diff --git a/lib/ftl/mngt/ftl_mngt_band.c b/lib/ftl/mngt/ftl_mngt_band.c index 37c1f01e9..438b9107f 100644 --- a/lib/ftl/mngt/ftl_mngt_band.c +++ b/lib/ftl/mngt/ftl_mngt_band.c @@ -26,7 +26,7 @@ ftl_band_init_md(struct ftl_band *band) band_valid_map_bytes = band_num_blocks / 8; p2l_map->valid = ftl_bitmap_create(ftl_md_get_buffer(valid_map_md) + - band_valid_map_bytes * band->id, band_valid_map_bytes); + band->start_addr / 8, band_valid_map_bytes); if (!p2l_map->valid) { return -ENOMEM; } @@ -170,8 +170,6 @@ decorate_bands(struct spdk_ftl_dev *dev) i = 0; while (i < ftl_get_num_bands(dev) - num_to_drop) { band = &dev->bands[i]; - band->start_addr = i * dev->num_blocks_in_band; - band->tail_md_addr = ftl_band_tail_md_addr(band); band->phys_id = phys_id; i++; @@ -199,6 +197,22 @@ ftl_mngt_decorate_bands(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt) ftl_mngt_next_step(mngt); } +void +ftl_mngt_initialize_band_address(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt) +{ + struct ftl_band *band; + struct ftl_md *data_md = dev->layout.md[FTL_LAYOUT_REGION_TYPE_DATA_BASE]; + uint64_t i; + + for (i = 0; i < ftl_get_num_bands(dev); i++) { + band = &dev->bands[i]; + band->start_addr = data_md->region->current.offset + i * dev->num_blocks_in_band; + band->tail_md_addr = ftl_band_tail_md_addr(band); + } + + ftl_mngt_next_step(mngt); +} + void ftl_recover_max_seq(struct spdk_ftl_dev *dev) { diff --git a/lib/ftl/mngt/ftl_mngt_startup.c b/lib/ftl/mngt/ftl_mngt_startup.c index 9de97f5b7..8e9d24dcd 100644 --- a/lib/ftl/mngt/ftl_mngt_startup.c +++ b/lib/ftl/mngt/ftl_mngt_startup.c @@ -104,6 +104,10 @@ static const struct ftl_mngt_process_desc desc_startup = { .action = ftl_mngt_init_md, .cleanup = ftl_mngt_deinit_md }, + { + .name = "Initialize band addresses", + .action = ftl_mngt_initialize_band_address + }, { .name = "Initialize NV cache", .action = ftl_mngt_init_nv_cache, diff --git a/lib/ftl/mngt/ftl_mngt_steps.h b/lib/ftl/mngt/ftl_mngt_steps.h index 11894a8b9..de3e3e069 100644 --- a/lib/ftl/mngt/ftl_mngt_steps.h +++ b/lib/ftl/mngt/ftl_mngt_steps.h @@ -50,6 +50,8 @@ void ftl_mngt_deinit_io_channel(struct spdk_ftl_dev *dev, struct ftl_mngt_proces void ftl_mngt_decorate_bands(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt); +void ftl_mngt_initialize_band_address(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt); + void ftl_mngt_init_reloc(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt); void ftl_mngt_deinit_reloc(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt);