Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright 2023 Solidigm All Rights Reserved
3 : : */
4 : :
5 : : #include "ftl_nvc_dev.h"
6 : : #include "ftl_core.h"
7 : : #include "ftl_layout.h"
8 : : #include "utils/ftl_layout_tracker_bdev.h"
9 : :
10 : : static bool
11 : 22 : is_bdev_compatible(struct spdk_ftl_dev *dev, struct spdk_bdev *bdev)
12 : : {
13 [ - + ]: 22 : if (!spdk_bdev_is_md_separate(bdev)) {
14 : : /* It doesn't support separate metadata buffer IO */
15 : 0 : return false;
16 : : }
17 : :
18 [ - + ]: 22 : if (spdk_bdev_get_md_size(bdev) != sizeof(union ftl_md_vss)) {
19 : : /* Bdev's metadata is invalid size */
20 : 0 : return false;
21 : : }
22 : :
23 [ - + ]: 22 : if (spdk_bdev_get_dif_type(bdev) != SPDK_DIF_DISABLE) {
24 : : /* Unsupported DIF type used by bdev */
25 : 0 : return false;
26 : : }
27 : :
28 [ - + ]: 22 : if (ftl_md_xfer_blocks(dev) * spdk_bdev_get_md_size(bdev) > FTL_ZERO_BUFFER_SIZE) {
29 [ # # # # : 0 : FTL_ERRLOG(dev, "Zero buffer too small for bdev %s metadata transfer\n",
# # # # ]
30 : : spdk_bdev_get_name(bdev));
31 : 0 : return false;
32 : : }
33 : :
34 : 22 : return true;
35 : 0 : }
36 : :
37 : : static void
38 : 82 : md_region_setup(struct spdk_ftl_dev *dev, enum ftl_layout_region_type reg_type,
39 : : struct ftl_layout_region *region)
40 : : {
41 [ - + # # ]: 82 : assert(region);
42 [ # # # # ]: 82 : region->type = reg_type;
43 [ # # # # ]: 82 : region->mirror_type = FTL_LAYOUT_REGION_TYPE_INVALID;
44 [ # # # # ]: 82 : region->name = ftl_md_region_name(reg_type);
45 : :
46 [ # # # # : 82 : region->bdev_desc = dev->nv_cache.bdev_desc;
# # # # #
# ]
47 [ # # # # : 82 : region->ioch = dev->nv_cache.cache_ioch;
# # # # #
# ]
48 [ # # # # : 82 : region->vss_blksz = dev->nv_cache.md_size;
# # # # #
# ]
49 : 82 : }
50 : :
51 : : static int
52 : 82 : md_region_create(struct spdk_ftl_dev *dev, enum ftl_layout_region_type reg_type,
53 : : uint32_t reg_version, size_t reg_blks)
54 : : {
55 : 0 : const struct ftl_layout_tracker_bdev_region_props *reg_props;
56 : :
57 [ - + # # ]: 82 : assert(reg_type < FTL_LAYOUT_REGION_TYPE_MAX);
58 : 82 : reg_blks = ftl_md_region_align_blocks(dev, reg_blks);
59 : :
60 [ # # # # ]: 82 : reg_props = ftl_layout_tracker_bdev_add_region(dev->nvc_layout_tracker, reg_type, reg_version,
61 : 0 : reg_blks, 0);
62 [ - + ]: 82 : if (!reg_props) {
63 : 0 : return -1;
64 : : }
65 [ - + # # : 82 : assert(reg_props->type == reg_type);
# # # # ]
66 [ - + # # : 82 : assert(reg_props->ver == reg_version);
# # # # ]
67 [ - + # # : 82 : assert(reg_props->blk_sz == reg_blks);
# # # # ]
68 [ - + # # : 82 : assert(reg_props->blk_offs + reg_blks <= dev->layout.nvc.total_blocks);
# # # # #
# # # # #
# # ]
69 : 82 : return 0;
70 : 0 : }
71 : :
72 : : static int
73 : 82 : md_region_open(struct spdk_ftl_dev *dev, enum ftl_layout_region_type reg_type, uint32_t reg_version,
74 : : size_t entry_size, size_t entry_count, struct ftl_layout_region *region)
75 : : {
76 : 82 : const struct ftl_layout_tracker_bdev_region_props *reg_search_ctx = NULL;
77 : 82 : uint64_t reg_blks = ftl_md_region_blocks(dev, entry_size * entry_count);
78 : :
79 [ + - # # ]: 82 : assert(reg_type < FTL_LAYOUT_REGION_TYPE_MAX);
80 : :
81 : 0 : while (true) {
82 [ # # # # ]: 82 : ftl_layout_tracker_bdev_find_next_region(dev->nvc_layout_tracker, reg_type, ®_search_ctx);
83 [ + - - + : 82 : if (!reg_search_ctx || reg_search_ctx->ver == reg_version) {
# # # # ]
84 : 0 : break;
85 : : }
86 : : }
87 : :
88 [ + - - + : 82 : if (!reg_search_ctx || reg_search_ctx->blk_sz < reg_blks) {
# # # # ]
89 : : /* Region not found or insufficient space */
90 : 0 : return -1;
91 : : }
92 : :
93 [ - + ]: 82 : if (!region) {
94 : 0 : return 0;
95 : : }
96 : :
97 : 82 : md_region_setup(dev, reg_type, region);
98 : :
99 [ # # # # : 82 : region->entry_size = entry_size / FTL_BLOCK_SIZE;
# # ]
100 [ # # # # ]: 82 : region->num_entries = entry_count;
101 : :
102 [ # # # # : 82 : region->current.version = reg_version;
# # ]
103 [ # # # # : 82 : region->current.offset = reg_search_ctx->blk_offs;
# # # # #
# ]
104 [ # # # # : 82 : region->current.blocks = reg_search_ctx->blk_sz;
# # # # #
# ]
105 : :
106 : 82 : return 0;
107 : 0 : }
108 : :
109 : : struct ftl_nv_cache_device_desc nvc_bdev_vss = {
110 : : .name = "bdev",
111 : : .features = {
112 : : },
113 : : .ops = {
114 : : .is_bdev_compatible = is_bdev_compatible,
115 : :
116 : : .md_layout_ops = {
117 : : .region_create = md_region_create,
118 : : .region_open = md_region_open,
119 : : },
120 : : }
121 : : };
122 : 1744 : FTL_NV_CACHE_DEVICE_TYPE_REGISTER(nvc_bdev_vss)
|