Commit c3321813 authored by Kozlowski Mateusz's avatar Kozlowski Mateusz Committed by Jim Harris
Browse files

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: default avatarKozlowski Mateusz <mateusz.kozlowski@intel.com>
Change-Id: I8a6eb3c89a229f443ef23d975a8ff0880ba65b08
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/14143


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
parent 759e1769
Loading
Loading
Loading
Loading
+8 −2
Original line number Diff line number Diff line
@@ -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;
}

+0 −6
Original line number Diff line number Diff line
@@ -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)
{
+12 −12
Original line number Diff line number Diff line
@@ -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);

+17 −3
Original line number Diff line number Diff line
@@ -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)
{
+4 −0
Original line number Diff line number Diff line
@@ -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,
Loading