Line data Source code
1 : /* SPDX-License-Identifier: BSD-3-Clause
2 : * Copyright (C) 2018 Intel Corporation.
3 : * All rights reserved.
4 : * Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
5 : */
6 :
7 : #include "spdk/stdinc.h"
8 : #include "spdk/blob.h"
9 : #include "spdk/log.h"
10 : #include "spdk/likely.h"
11 : #include "blobstore.h"
12 :
13 : static void
14 0 : blob_bs_dev_write(struct spdk_bs_dev *dev, struct spdk_io_channel *channel, void *payload,
15 : uint64_t lba, uint32_t lba_count,
16 : struct spdk_bs_dev_cb_args *cb_args)
17 : {
18 0 : cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, -EPERM);
19 0 : assert(false);
20 : }
21 :
22 : static void
23 0 : blob_bs_dev_writev(struct spdk_bs_dev *dev, struct spdk_io_channel *channel,
24 : struct iovec *iov, int iovcnt,
25 : uint64_t lba, uint32_t lba_count,
26 : struct spdk_bs_dev_cb_args *cb_args)
27 : {
28 0 : cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, -EPERM);
29 0 : assert(false);
30 : }
31 :
32 : static void
33 0 : blob_bs_dev_writev_ext(struct spdk_bs_dev *dev, struct spdk_io_channel *channel,
34 : struct iovec *iov, int iovcnt,
35 : uint64_t lba, uint32_t lba_count,
36 : struct spdk_bs_dev_cb_args *cb_args,
37 : struct spdk_blob_ext_io_opts *ext_opts)
38 : {
39 0 : cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, -EPERM);
40 0 : assert(false);
41 : }
42 :
43 : static void
44 0 : blob_bs_dev_write_zeroes(struct spdk_bs_dev *dev, struct spdk_io_channel *channel,
45 : uint64_t lba, uint64_t lba_count,
46 : struct spdk_bs_dev_cb_args *cb_args)
47 : {
48 0 : cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, -EPERM);
49 0 : assert(false);
50 : }
51 :
52 : static void
53 0 : blob_bs_dev_unmap(struct spdk_bs_dev *dev, struct spdk_io_channel *channel,
54 : uint64_t lba, uint64_t lba_count,
55 : struct spdk_bs_dev_cb_args *cb_args)
56 : {
57 0 : cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, -EPERM);
58 0 : assert(false);
59 : }
60 :
61 : static void
62 721 : blob_bs_dev_read_cpl(void *cb_arg, int bserrno)
63 : {
64 721 : struct spdk_bs_dev_cb_args *cb_args = (struct spdk_bs_dev_cb_args *)cb_arg;
65 :
66 721 : cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, bserrno);
67 721 : }
68 :
69 : static inline void
70 721 : zero_trailing_bytes(struct spdk_blob_bs_dev *b, struct iovec *iov, int iovcnt,
71 : uint64_t lba, uint32_t *lba_count)
72 : {
73 721 : uint32_t zero_lba_count;
74 721 : uint64_t zero_bytes, zero_len;
75 721 : uint64_t payload_bytes;
76 721 : uint64_t valid_bytes;
77 721 : void *zero_start;
78 721 : struct iovec *i;
79 :
80 721 : if (spdk_likely(lba + *lba_count <= b->bs_dev.blockcnt)) {
81 671 : return;
82 : }
83 :
84 : /* Figure out how many bytes in the payload will need to be zeroed. */
85 50 : zero_lba_count = spdk_min(*lba_count, lba + *lba_count - b->bs_dev.blockcnt);
86 50 : zero_bytes = zero_lba_count * (uint64_t)b->bs_dev.blocklen;
87 :
88 50 : payload_bytes = *lba_count * (uint64_t)b->bs_dev.blocklen;
89 50 : valid_bytes = payload_bytes - zero_bytes;
90 :
91 50 : i = iov;
92 100 : while (zero_bytes > 0) {
93 50 : if (i->iov_len > valid_bytes) {
94 50 : zero_start = i->iov_base + valid_bytes;
95 50 : zero_len = spdk_min(payload_bytes, i->iov_len - valid_bytes);
96 50 : memset(zero_start, 0, zero_bytes);
97 50 : valid_bytes = 0;
98 50 : zero_bytes -= zero_len;
99 50 : }
100 50 : valid_bytes -= spdk_min(valid_bytes, i->iov_len);
101 50 : payload_bytes -= spdk_min(payload_bytes, i->iov_len);
102 50 : i++;
103 : }
104 :
105 50 : *lba_count -= zero_lba_count;
106 721 : }
107 :
108 : static inline void
109 531 : blob_bs_dev_read(struct spdk_bs_dev *dev, struct spdk_io_channel *channel, void *payload,
110 : uint64_t lba, uint32_t lba_count, struct spdk_bs_dev_cb_args *cb_args)
111 : {
112 531 : struct spdk_blob_bs_dev *b = (struct spdk_blob_bs_dev *)dev;
113 531 : struct iovec iov;
114 :
115 531 : iov.iov_base = payload;
116 531 : iov.iov_len = lba_count * b->bs_dev.blocklen;
117 : /* The backing blob may be smaller than this blob, so zero any trailing bytes. */
118 531 : zero_trailing_bytes(b, &iov, 1, lba, &lba_count);
119 :
120 531 : spdk_blob_io_read(b->blob, channel, payload, lba, lba_count,
121 531 : blob_bs_dev_read_cpl, cb_args);
122 531 : }
123 :
124 : static inline void
125 100 : blob_bs_dev_readv(struct spdk_bs_dev *dev, struct spdk_io_channel *channel,
126 : struct iovec *iov, int iovcnt,
127 : uint64_t lba, uint32_t lba_count, struct spdk_bs_dev_cb_args *cb_args)
128 : {
129 100 : struct spdk_blob_bs_dev *b = (struct spdk_blob_bs_dev *)dev;
130 :
131 : /* The backing blob may be smaller than this blob, so zero any trailing bytes. */
132 100 : zero_trailing_bytes(b, iov, iovcnt, lba, &lba_count);
133 :
134 100 : spdk_blob_io_readv(b->blob, channel, iov, iovcnt, lba, lba_count,
135 100 : blob_bs_dev_read_cpl, cb_args);
136 100 : }
137 :
138 : static inline void
139 90 : blob_bs_dev_readv_ext(struct spdk_bs_dev *dev, struct spdk_io_channel *channel,
140 : struct iovec *iov, int iovcnt,
141 : uint64_t lba, uint32_t lba_count, struct spdk_bs_dev_cb_args *cb_args,
142 : struct spdk_blob_ext_io_opts *ext_opts)
143 : {
144 90 : struct spdk_blob_bs_dev *b = (struct spdk_blob_bs_dev *)dev;
145 :
146 : /* The backing blob may be smaller than this blob, so zero any trailing bytes. */
147 90 : zero_trailing_bytes(b, iov, iovcnt, lba, &lba_count);
148 :
149 90 : spdk_blob_io_readv_ext(b->blob, channel, iov, iovcnt, lba, lba_count,
150 90 : blob_bs_dev_read_cpl, cb_args, ext_opts);
151 90 : }
152 :
153 : static void
154 858 : blob_bs_dev_destroy_cpl(void *cb_arg, int bserrno)
155 : {
156 858 : if (bserrno != 0) {
157 0 : SPDK_ERRLOG("Error on blob_bs_dev destroy: %d", bserrno);
158 0 : }
159 :
160 : /* Free blob_bs_dev */
161 858 : free(cb_arg);
162 858 : }
163 :
164 : static void
165 858 : blob_bs_dev_destroy(struct spdk_bs_dev *bs_dev)
166 : {
167 858 : struct spdk_blob_bs_dev *b = (struct spdk_blob_bs_dev *)bs_dev;
168 :
169 858 : spdk_blob_close(b->blob, blob_bs_dev_destroy_cpl, b);
170 858 : }
171 :
172 : static bool
173 615 : blob_bs_is_zeroes(struct spdk_bs_dev *dev, uint64_t lba, uint64_t lba_count)
174 : {
175 615 : struct spdk_blob_bs_dev *b = (struct spdk_blob_bs_dev *)dev;
176 615 : struct spdk_blob *blob = b->blob;
177 615 : bool is_valid_range;
178 :
179 615 : assert(lba == bs_cluster_to_lba(blob->bs, bs_lba_to_cluster(blob->bs, lba)));
180 615 : assert(lba_count == bs_dev_byte_to_lba(dev, blob->bs->cluster_sz));
181 :
182 615 : if (bs_io_unit_is_allocated(blob, lba)) {
183 325 : return false;
184 : }
185 :
186 290 : assert(blob->back_bs_dev != NULL);
187 290 : is_valid_range = blob->back_bs_dev->is_range_valid(blob->back_bs_dev, lba, lba_count);
188 290 : return is_valid_range && blob->back_bs_dev->is_zeroes(blob->back_bs_dev,
189 240 : bs_io_unit_to_back_dev_lba(blob, lba),
190 240 : bs_io_unit_to_back_dev_lba(blob, lba_count));
191 615 : }
192 :
193 : static bool
194 711 : blob_bs_is_range_valid(struct spdk_bs_dev *dev, uint64_t lba, uint64_t lba_count)
195 : {
196 711 : struct spdk_blob_bs_dev *b = (struct spdk_blob_bs_dev *)dev;
197 711 : struct spdk_blob *blob = b->blob;
198 711 : uint64_t io_units_per_cluster;
199 :
200 : /* The lba here is supposed to be the first lba of cluster. lba_count
201 : * will typically be fixed e.g. 8192 for 4MiB cluster. */
202 711 : assert(lba_count == blob->bs->cluster_sz / dev->blocklen);
203 711 : assert(lba % lba_count == 0);
204 :
205 711 : io_units_per_cluster = blob->bs->io_units_per_cluster;
206 :
207 : /* A blob will either have:
208 : * - no backing bs_bdev (normal thick blob), or
209 : * - zeroes backing bs_bdev (thin provisioned blob), or
210 : * - blob backing bs_bdev (e.g snapshot)
211 : * It may be possible that backing bs_bdev has lesser number of clusters
212 : * than the child lvol blob because lvol blob has been expanded after
213 : * taking snapshot. In such a case, page will be outside the cluster io_unit
214 : * range of the backing dev. Always return true for zeroes backing bdev. */
215 711 : return lba < blob->active.num_clusters * io_units_per_cluster;
216 711 : }
217 :
218 : static bool
219 246 : blob_bs_translate_lba(struct spdk_bs_dev *dev, uint64_t lba, uint64_t *base_lba)
220 : {
221 246 : struct spdk_blob_bs_dev *b = (struct spdk_blob_bs_dev *)dev;
222 246 : struct spdk_blob *blob = b->blob;
223 246 : bool is_valid_range;
224 :
225 246 : assert(base_lba != NULL);
226 246 : if (bs_io_unit_is_allocated(blob, lba)) {
227 130 : *base_lba = bs_blob_io_unit_to_lba(blob, lba);
228 130 : return true;
229 : }
230 :
231 116 : assert(blob->back_bs_dev != NULL);
232 : /* Since here we don't get lba_count directly, passing lba_count derived
233 : * from cluster_sz which typically happens for other calls like is_zeroes
234 : * in CoW path. */
235 232 : is_valid_range = blob->back_bs_dev->is_range_valid(blob->back_bs_dev, lba,
236 116 : bs_dev_byte_to_lba(blob->back_bs_dev, blob->bs->cluster_sz));
237 116 : return is_valid_range && blob->back_bs_dev->translate_lba(blob->back_bs_dev,
238 96 : bs_io_unit_to_back_dev_lba(blob, lba),
239 96 : base_lba);
240 246 : }
241 :
242 : static bool
243 0 : blob_bs_is_degraded(struct spdk_bs_dev *dev)
244 : {
245 0 : struct spdk_blob_bs_dev *b = (struct spdk_blob_bs_dev *)dev;
246 :
247 0 : return spdk_blob_is_degraded(b->blob);
248 0 : }
249 :
250 : struct spdk_bs_dev *
251 858 : bs_create_blob_bs_dev(struct spdk_blob *blob)
252 : {
253 858 : struct spdk_blob_bs_dev *b;
254 :
255 858 : b = calloc(1, sizeof(*b));
256 858 : if (b == NULL) {
257 0 : return NULL;
258 : }
259 : /* snapshot blob */
260 858 : b->bs_dev.blockcnt = blob->active.num_clusters * blob->bs->io_units_per_cluster;
261 858 : b->bs_dev.blocklen = spdk_bs_get_io_unit_size(blob->bs);
262 858 : b->bs_dev.create_channel = NULL;
263 858 : b->bs_dev.destroy_channel = NULL;
264 858 : b->bs_dev.destroy = blob_bs_dev_destroy;
265 858 : b->bs_dev.write = blob_bs_dev_write;
266 858 : b->bs_dev.writev = blob_bs_dev_writev;
267 858 : b->bs_dev.writev_ext = blob_bs_dev_writev_ext;
268 858 : b->bs_dev.read = blob_bs_dev_read;
269 858 : b->bs_dev.readv = blob_bs_dev_readv;
270 858 : b->bs_dev.readv_ext = blob_bs_dev_readv_ext;
271 858 : b->bs_dev.write_zeroes = blob_bs_dev_write_zeroes;
272 858 : b->bs_dev.unmap = blob_bs_dev_unmap;
273 858 : b->bs_dev.is_zeroes = blob_bs_is_zeroes;
274 858 : b->bs_dev.is_range_valid = blob_bs_is_range_valid;
275 858 : b->bs_dev.translate_lba = blob_bs_translate_lba;
276 858 : b->bs_dev.is_degraded = blob_bs_is_degraded;
277 858 : b->blob = blob;
278 :
279 858 : return &b->bs_dev;
280 858 : }
|