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 1 : spdk_bdev_get_zone_size(const struct spdk_bdev *bdev)
16 : {
17 1 : return bdev->zone_size;
18 : }
19 :
20 : uint64_t
21 1 : spdk_bdev_get_num_zones(const struct spdk_bdev *bdev)
22 : {
23 1 : return bdev->zone_size ? bdev->blockcnt / bdev->zone_size : 0;
24 : }
25 :
26 : uint64_t
27 1 : spdk_bdev_get_zone_id(const struct spdk_bdev *bdev, uint64_t offset_blocks)
28 : {
29 1 : uint64_t zslba;
30 :
31 1 : if (spdk_likely(spdk_u64_is_pow2(bdev->zone_size))) {
32 1 : uint64_t zone_mask = bdev->zone_size - 1;
33 1 : zslba = offset_blocks & ~zone_mask;
34 1 : } else {
35 : /* integer division */
36 0 : zslba = (offset_blocks / bdev->zone_size) * bdev->zone_size;
37 : }
38 :
39 2 : return zslba;
40 1 : }
41 :
42 : uint32_t
43 1 : spdk_bdev_get_max_zone_append_size(const struct spdk_bdev *bdev)
44 : {
45 1 : return bdev->max_zone_append_size;
46 : }
47 :
48 : uint32_t
49 1 : spdk_bdev_get_max_open_zones(const struct spdk_bdev *bdev)
50 : {
51 1 : return bdev->max_open_zones;
52 : }
53 :
54 : uint32_t
55 1 : spdk_bdev_get_max_active_zones(const struct spdk_bdev *bdev)
56 : {
57 1 : return bdev->max_active_zones;
58 : }
59 :
60 : uint32_t
61 1 : spdk_bdev_get_optimal_open_zones(const struct spdk_bdev *bdev)
62 : {
63 1 : return bdev->optimal_open_zones;
64 : }
65 :
66 : int
67 1 : 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 1 : struct spdk_bdev *bdev = spdk_bdev_desc_get_bdev(desc);
72 1 : struct spdk_bdev_io *bdev_io;
73 1 : struct spdk_bdev_channel *channel = spdk_io_channel_get_ctx(ch);
74 :
75 1 : bdev_io = bdev_channel_get_io(channel);
76 1 : if (!bdev_io) {
77 0 : return -ENOMEM;
78 : }
79 :
80 1 : bdev_io->internal.ch = channel;
81 1 : bdev_io->internal.desc = desc;
82 1 : bdev_io->type = SPDK_BDEV_IO_TYPE_GET_ZONE_INFO;
83 1 : bdev_io->u.zone_mgmt.zone_id = zone_id;
84 1 : bdev_io->u.zone_mgmt.num_zones = num_zones;
85 1 : bdev_io->u.zone_mgmt.buf = info;
86 1 : bdev_io_init(bdev_io, bdev, cb_arg, cb);
87 :
88 1 : bdev_io_submit(bdev_io);
89 1 : return 0;
90 1 : }
91 :
92 : int
93 1 : 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 1 : struct spdk_bdev *bdev = spdk_bdev_desc_get_bdev(desc);
98 1 : struct spdk_bdev_io *bdev_io;
99 1 : struct spdk_bdev_channel *channel = spdk_io_channel_get_ctx(ch);
100 :
101 1 : bdev_io = bdev_channel_get_io(channel);
102 1 : if (!bdev_io) {
103 0 : return -ENOMEM;
104 : }
105 :
106 1 : bdev_io->internal.ch = channel;
107 1 : bdev_io->internal.desc = desc;
108 1 : bdev_io->type = SPDK_BDEV_IO_TYPE_ZONE_MANAGEMENT;
109 1 : bdev_io->u.zone_mgmt.zone_action = action;
110 1 : bdev_io->u.zone_mgmt.zone_id = zone_id;
111 1 : bdev_io->u.zone_mgmt.num_zones = 1;
112 1 : bdev_io_init(bdev_io, bdev, cb_arg, cb);
113 :
114 1 : bdev_io_submit(bdev_io);
115 1 : return 0;
116 1 : }
117 :
118 : static int
119 2 : 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 2 : struct spdk_bdev *bdev = spdk_bdev_desc_get_bdev(desc);
124 2 : struct spdk_bdev_io *bdev_io;
125 2 : struct spdk_bdev_channel *channel = spdk_io_channel_get_ctx(ch);
126 :
127 2 : bdev_io = bdev_channel_get_io(channel);
128 2 : if (!bdev_io) {
129 0 : return -ENOMEM;
130 : }
131 :
132 2 : bdev_io->internal.ch = channel;
133 2 : bdev_io->internal.desc = desc;
134 2 : bdev_io->type = SPDK_BDEV_IO_TYPE_ZONE_APPEND;
135 2 : bdev_io->u.bdev.iovs = &bdev_io->iov;
136 2 : bdev_io->u.bdev.iovs[0].iov_base = buf;
137 2 : bdev_io->u.bdev.iovs[0].iov_len = num_blocks * bdev->blocklen;
138 2 : bdev_io->u.bdev.iovcnt = 1;
139 2 : bdev_io->u.bdev.md_buf = md_buf;
140 2 : bdev_io->u.bdev.num_blocks = num_blocks;
141 2 : bdev_io->u.bdev.offset_blocks = zone_id;
142 2 : bdev_io_init(bdev_io, bdev, cb_arg, cb);
143 :
144 2 : bdev_io_submit(bdev_io);
145 2 : return 0;
146 2 : }
147 :
148 : int
149 1 : 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 2 : return zone_bdev_append_with_md(desc, ch, buf, NULL, start_lba, num_blocks,
154 1 : cb, cb_arg);
155 : }
156 :
157 : int
158 1 : 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 2 : return zone_bdev_append_with_md(desc, ch, buf, md, start_lba, num_blocks,
163 1 : cb, cb_arg);
164 : }
165 :
166 : int
167 2 : 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 2 : struct spdk_bdev *bdev = spdk_bdev_desc_get_bdev(desc);
173 2 : struct spdk_bdev_io *bdev_io;
174 2 : struct spdk_bdev_channel *channel = spdk_io_channel_get_ctx(ch);
175 :
176 2 : bdev_io = bdev_channel_get_io(channel);
177 2 : if (!bdev_io) {
178 0 : return -ENOMEM;
179 : }
180 :
181 2 : bdev_io->internal.ch = channel;
182 2 : bdev_io->internal.desc = desc;
183 2 : bdev_io->type = SPDK_BDEV_IO_TYPE_ZONE_APPEND;
184 2 : bdev_io->u.bdev.iovs = iov;
185 2 : bdev_io->u.bdev.iovcnt = iovcnt;
186 2 : bdev_io->u.bdev.md_buf = md_buf;
187 2 : bdev_io->u.bdev.num_blocks = num_blocks;
188 2 : bdev_io->u.bdev.offset_blocks = zone_id;
189 2 : bdev_io_init(bdev_io, bdev, cb_arg, cb);
190 :
191 2 : bdev_io_submit(bdev_io);
192 2 : return 0;
193 2 : }
194 :
195 : int
196 1 : 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 2 : return spdk_bdev_zone_appendv_with_md(desc, ch, iovs, iovcnt, NULL, zone_id, num_blocks,
201 1 : cb, cb_arg);
202 : }
203 :
204 : uint64_t
205 1 : spdk_bdev_io_get_append_location(struct spdk_bdev_io *bdev_io)
206 : {
207 1 : return bdev_io->u.bdev.offset_blocks;
208 : }
|