Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (C) 2019 Intel Corporation.
3 : : * All rights reserved.
4 : : */
5 : :
6 : : #include "spdk/stdinc.h"
7 : :
8 : : #include "spdk/bdev_zone.h"
9 : : #include "spdk/bdev_module.h"
10 : : #include "spdk/likely.h"
11 : :
12 : : #include "bdev_internal.h"
13 : :
14 : : uint64_t
15 : 48 : spdk_bdev_get_zone_size(const struct spdk_bdev *bdev)
16 : : {
17 : 48 : return bdev->zone_size;
18 : : }
19 : :
20 : : uint64_t
21 : 6 : spdk_bdev_get_num_zones(const struct spdk_bdev *bdev)
22 : : {
23 [ + - - + ]: 6 : return bdev->zone_size ? bdev->blockcnt / bdev->zone_size : 0;
24 : : }
25 : :
26 : : uint64_t
27 : 223655 : spdk_bdev_get_zone_id(const struct spdk_bdev *bdev, uint64_t offset_blocks)
28 : : {
29 : : uint64_t zslba;
30 : :
31 [ + - ]: 223655 : if (spdk_likely(spdk_u64_is_pow2(bdev->zone_size))) {
32 : 223655 : uint64_t zone_mask = bdev->zone_size - 1;
33 : 223655 : zslba = offset_blocks & ~zone_mask;
34 : : } else {
35 : : /* integer division */
36 [ # # ]: 0 : zslba = (offset_blocks / bdev->zone_size) * bdev->zone_size;
37 : : }
38 : :
39 : 223655 : return zslba;
40 : : }
41 : :
42 : : uint32_t
43 : 4 : spdk_bdev_get_max_zone_append_size(const struct spdk_bdev *bdev)
44 : : {
45 : 4 : return bdev->max_zone_append_size;
46 : : }
47 : :
48 : : uint32_t
49 : 5 : spdk_bdev_get_max_open_zones(const struct spdk_bdev *bdev)
50 : : {
51 : 5 : return bdev->max_open_zones;
52 : : }
53 : :
54 : : uint32_t
55 : 4 : spdk_bdev_get_max_active_zones(const struct spdk_bdev *bdev)
56 : : {
57 : 4 : return bdev->max_active_zones;
58 : : }
59 : :
60 : : uint32_t
61 : 4 : spdk_bdev_get_optimal_open_zones(const struct spdk_bdev *bdev)
62 : : {
63 : 4 : return bdev->optimal_open_zones;
64 : : }
65 : :
66 : : int
67 : 5 : spdk_bdev_get_zone_info(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
68 : : uint64_t zone_id, size_t num_zones, struct spdk_bdev_zone_info *info,
69 : : spdk_bdev_io_completion_cb cb, void *cb_arg)
70 : : {
71 : 5 : struct spdk_bdev *bdev = spdk_bdev_desc_get_bdev(desc);
72 : : struct spdk_bdev_io *bdev_io;
73 : 5 : struct spdk_bdev_channel *channel = spdk_io_channel_get_ctx(ch);
74 : :
75 : 5 : bdev_io = bdev_channel_get_io(channel);
76 [ - + ]: 5 : if (!bdev_io) {
77 : 0 : return -ENOMEM;
78 : : }
79 : :
80 : 5 : bdev_io->internal.ch = channel;
81 : 5 : bdev_io->internal.desc = desc;
82 : 5 : bdev_io->type = SPDK_BDEV_IO_TYPE_GET_ZONE_INFO;
83 : 5 : bdev_io->u.zone_mgmt.zone_id = zone_id;
84 : 5 : bdev_io->u.zone_mgmt.num_zones = num_zones;
85 : 5 : bdev_io->u.zone_mgmt.buf = info;
86 : 5 : bdev_io_init(bdev_io, bdev, cb_arg, cb);
87 : :
88 : 5 : bdev_io_submit(bdev_io);
89 : 5 : return 0;
90 : : }
91 : :
92 : : int
93 : 47 : spdk_bdev_zone_management(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
94 : : uint64_t zone_id, enum spdk_bdev_zone_action action,
95 : : spdk_bdev_io_completion_cb cb, void *cb_arg)
96 : : {
97 : 47 : struct spdk_bdev *bdev = spdk_bdev_desc_get_bdev(desc);
98 : : struct spdk_bdev_io *bdev_io;
99 : 47 : struct spdk_bdev_channel *channel = spdk_io_channel_get_ctx(ch);
100 : :
101 : 47 : bdev_io = bdev_channel_get_io(channel);
102 [ - + ]: 47 : if (!bdev_io) {
103 : 0 : return -ENOMEM;
104 : : }
105 : :
106 : 47 : bdev_io->internal.ch = channel;
107 : 47 : bdev_io->internal.desc = desc;
108 : 47 : bdev_io->type = SPDK_BDEV_IO_TYPE_ZONE_MANAGEMENT;
109 : 47 : bdev_io->u.zone_mgmt.zone_action = action;
110 : 47 : bdev_io->u.zone_mgmt.zone_id = zone_id;
111 : 47 : bdev_io->u.zone_mgmt.num_zones = 1;
112 : 47 : bdev_io_init(bdev_io, bdev, cb_arg, cb);
113 : :
114 : 47 : bdev_io_submit(bdev_io);
115 : 47 : return 0;
116 : : }
117 : :
118 : : static int
119 : 223659 : zone_bdev_append_with_md(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
120 : : void *buf, void *md_buf, uint64_t zone_id, uint64_t num_blocks,
121 : : spdk_bdev_io_completion_cb cb, void *cb_arg)
122 : : {
123 : 223659 : struct spdk_bdev *bdev = spdk_bdev_desc_get_bdev(desc);
124 : : struct spdk_bdev_io *bdev_io;
125 : 223659 : struct spdk_bdev_channel *channel = spdk_io_channel_get_ctx(ch);
126 : :
127 : 223659 : bdev_io = bdev_channel_get_io(channel);
128 [ - + ]: 223659 : if (!bdev_io) {
129 : 0 : return -ENOMEM;
130 : : }
131 : :
132 : 223659 : bdev_io->internal.ch = channel;
133 : 223659 : bdev_io->internal.desc = desc;
134 : 223659 : bdev_io->type = SPDK_BDEV_IO_TYPE_ZONE_APPEND;
135 : 223659 : bdev_io->u.bdev.iovs = &bdev_io->iov;
136 : 223659 : bdev_io->u.bdev.iovs[0].iov_base = buf;
137 : 223659 : bdev_io->u.bdev.iovs[0].iov_len = num_blocks * bdev->blocklen;
138 : 223659 : bdev_io->u.bdev.iovcnt = 1;
139 : 223659 : bdev_io->u.bdev.md_buf = md_buf;
140 : 223659 : bdev_io->u.bdev.num_blocks = num_blocks;
141 : 223659 : bdev_io->u.bdev.offset_blocks = zone_id;
142 : 223659 : bdev_io_init(bdev_io, bdev, cb_arg, cb);
143 : :
144 : 223659 : bdev_io_submit(bdev_io);
145 : 223659 : return 0;
146 : : }
147 : :
148 : : int
149 : 223655 : spdk_bdev_zone_append(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
150 : : void *buf, uint64_t start_lba, uint64_t num_blocks,
151 : : spdk_bdev_io_completion_cb cb, void *cb_arg)
152 : : {
153 : 223655 : return zone_bdev_append_with_md(desc, ch, buf, NULL, start_lba, num_blocks,
154 : : cb, cb_arg);
155 : : }
156 : :
157 : : int
158 : 4 : spdk_bdev_zone_append_with_md(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
159 : : void *buf, void *md, uint64_t start_lba, uint64_t num_blocks,
160 : : spdk_bdev_io_completion_cb cb, void *cb_arg)
161 : : {
162 : 4 : return zone_bdev_append_with_md(desc, ch, buf, md, start_lba, num_blocks,
163 : : cb, cb_arg);
164 : : }
165 : :
166 : : int
167 : 8 : spdk_bdev_zone_appendv_with_md(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
168 : : struct iovec *iov, int iovcnt, void *md_buf, uint64_t zone_id,
169 : : uint64_t num_blocks, spdk_bdev_io_completion_cb cb,
170 : : void *cb_arg)
171 : : {
172 : 8 : struct spdk_bdev *bdev = spdk_bdev_desc_get_bdev(desc);
173 : : struct spdk_bdev_io *bdev_io;
174 : 8 : struct spdk_bdev_channel *channel = spdk_io_channel_get_ctx(ch);
175 : :
176 : 8 : bdev_io = bdev_channel_get_io(channel);
177 [ - + ]: 8 : if (!bdev_io) {
178 : 0 : return -ENOMEM;
179 : : }
180 : :
181 : 8 : bdev_io->internal.ch = channel;
182 : 8 : bdev_io->internal.desc = desc;
183 : 8 : bdev_io->type = SPDK_BDEV_IO_TYPE_ZONE_APPEND;
184 : 8 : bdev_io->u.bdev.iovs = iov;
185 : 8 : bdev_io->u.bdev.iovcnt = iovcnt;
186 : 8 : bdev_io->u.bdev.md_buf = md_buf;
187 : 8 : bdev_io->u.bdev.num_blocks = num_blocks;
188 : 8 : bdev_io->u.bdev.offset_blocks = zone_id;
189 : 8 : bdev_io_init(bdev_io, bdev, cb_arg, cb);
190 : :
191 : 8 : bdev_io_submit(bdev_io);
192 : 8 : return 0;
193 : : }
194 : :
195 : : int
196 : 4 : spdk_bdev_zone_appendv(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
197 : : struct iovec *iovs, int iovcnt, uint64_t zone_id, uint64_t num_blocks,
198 : : spdk_bdev_io_completion_cb cb, void *cb_arg)
199 : : {
200 : 4 : return spdk_bdev_zone_appendv_with_md(desc, ch, iovs, iovcnt, NULL, zone_id, num_blocks,
201 : : cb, cb_arg);
202 : : }
203 : :
204 : : uint64_t
205 : 4 : spdk_bdev_io_get_append_location(struct spdk_bdev_io *bdev_io)
206 : : {
207 : 4 : return bdev_io->u.bdev.offset_blocks;
208 : : }
|