xref: /spdk/lib/ftl/base/ftl_base_bdev.c (revision 780cb81f62366bd50be32af7aaaa51db1443acf6)
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