xref: /spdk/lib/ftl/nvc/ftl_nvc_bdev_common.c (revision d4d015a572e1af7b2818e44218c1e661a61545ec)
1 /*   SPDX-License-Identifier: BSD-3-Clause
2  *   Copyright 2023 Solidigm All Rights Reserved
3  */
4 
5 #include "ftl_nvc_bdev_common.h"
6 #include "ftl_nvc_dev.h"
7 #include "ftl_core.h"
8 #include "ftl_layout.h"
9 #include "utils/ftl_layout_tracker_bdev.h"
10 #include "mngt/ftl_mngt.h"
11 
12 bool
13 ftl_nvc_bdev_common_is_chunk_active(struct spdk_ftl_dev *dev, uint64_t chunk_offset)
14 {
15 	const struct ftl_layout_tracker_bdev_region_props *reg_free = ftl_layout_tracker_bdev_insert_region(
16 				dev->nvc_layout_tracker, FTL_LAYOUT_REGION_TYPE_INVALID, 0, chunk_offset,
17 				dev->layout.nvc.chunk_data_blocks);
18 
19 	assert(!reg_free || reg_free->type == FTL_LAYOUT_REGION_TYPE_FREE);
20 	return reg_free != NULL;
21 }
22 
23 static void
24 md_region_setup(struct spdk_ftl_dev *dev, enum ftl_layout_region_type reg_type,
25 		struct ftl_layout_region *region)
26 {
27 	assert(region);
28 	region->type = reg_type;
29 	region->mirror_type = FTL_LAYOUT_REGION_TYPE_INVALID;
30 	region->name = ftl_md_region_name(reg_type);
31 
32 	region->bdev_desc = dev->nv_cache.bdev_desc;
33 	region->ioch = dev->nv_cache.cache_ioch;
34 	region->vss_blksz = dev->nv_cache.md_size;
35 }
36 
37 int
38 ftl_nvc_bdev_common_region_create(struct spdk_ftl_dev *dev, enum ftl_layout_region_type reg_type,
39 				  uint32_t reg_version, size_t reg_blks)
40 {
41 	const struct ftl_layout_tracker_bdev_region_props *reg_props;
42 
43 	assert(reg_type < FTL_LAYOUT_REGION_TYPE_MAX);
44 	reg_blks = ftl_md_region_align_blocks(dev, reg_blks);
45 
46 	reg_props = ftl_layout_tracker_bdev_add_region(dev->nvc_layout_tracker, reg_type, reg_version,
47 			reg_blks, 0);
48 	if (!reg_props) {
49 		return -1;
50 	}
51 	assert(reg_props->type == reg_type);
52 	assert(reg_props->ver == reg_version);
53 	assert(reg_props->blk_sz == reg_blks);
54 	assert(reg_props->blk_offs + reg_blks <= dev->layout.nvc.total_blocks);
55 	return 0;
56 }
57 
58 int
59 ftl_nvc_bdev_common_region_open(struct spdk_ftl_dev *dev, enum ftl_layout_region_type reg_type,
60 				uint32_t reg_version,
61 				size_t entry_size, size_t entry_count, struct ftl_layout_region *region)
62 {
63 	const struct ftl_layout_tracker_bdev_region_props *reg_search_ctx = NULL;
64 	uint64_t reg_blks = ftl_md_region_blocks(dev, entry_size * entry_count);
65 
66 	assert(reg_type < FTL_LAYOUT_REGION_TYPE_MAX);
67 
68 	while (true) {
69 		ftl_layout_tracker_bdev_find_next_region(dev->nvc_layout_tracker, reg_type, &reg_search_ctx);
70 		if (!reg_search_ctx || reg_search_ctx->ver == reg_version) {
71 			break;
72 		}
73 	}
74 
75 	if (!reg_search_ctx || reg_search_ctx->blk_sz < reg_blks) {
76 		/* Region not found or insufficient space */
77 		return -1;
78 	}
79 
80 	if (!region) {
81 		return 0;
82 	}
83 
84 	md_region_setup(dev, reg_type, region);
85 
86 	region->entry_size = entry_size / FTL_BLOCK_SIZE;
87 	region->num_entries = entry_count;
88 
89 	region->current.version = reg_version;
90 	region->current.offset = reg_search_ctx->blk_offs;
91 	region->current.blocks = reg_search_ctx->blk_sz;
92 
93 	return 0;
94 }
95