FTL: Move base device sb to LBA 0
Moving the superblock of the base device to sector 0, in order to prevent other bdevs (e.g. GPT or blobstore) from potentially hijacking the base device during startup (if their metadata by 'luck' manages to find itself at sector 0 of band 0, which depending on the order of operations could be very likely). Signed-off-by: Kozlowski Mateusz <mateusz.kozlowski@intel.com> Change-Id: I8a6eb3c89a229f443ef23d975a8ff0880ba65b08 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/14143 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
parent
759e176927
commit
c332181331
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user