4 * Copyright (c) Intel Corporation.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * * Neither the name of Intel Corporation nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 #include "spdk/stdinc.h"
36 #include "spdk/blob_bdev.h"
37 #include "spdk/blob.h"
38 #include "spdk/thread.h"
40 #include "spdk/endian.h"
41 #include "spdk/bdev_module.h"
44 struct spdk_bs_dev bs_dev
;
45 struct spdk_bdev
*bdev
;
46 struct spdk_bdev_desc
*desc
;
50 struct blob_resubmit
{
51 struct spdk_bdev_io_wait_entry bdev_io_wait
;
52 enum spdk_bdev_io_type io_type
;
53 struct spdk_bs_dev
*dev
;
54 struct spdk_io_channel
*channel
;
59 struct spdk_bs_dev_cb_args
*cb_args
;
61 static void bdev_blob_resubmit(void *);
63 static inline struct spdk_bdev_desc
*
64 __get_desc(struct spdk_bs_dev
*dev
)
66 return ((struct blob_bdev
*)dev
)->desc
;
69 static inline struct spdk_bdev
*
70 __get_bdev(struct spdk_bs_dev
*dev
)
72 return ((struct blob_bdev
*)dev
)->bdev
;
76 bdev_blob_io_complete(struct spdk_bdev_io
*bdev_io
, bool success
, void *arg
)
78 struct spdk_bs_dev_cb_args
*cb_args
= arg
;
86 cb_args
->cb_fn(cb_args
->channel
, cb_args
->cb_arg
, bserrno
);
87 spdk_bdev_free_io(bdev_io
);
91 bdev_blob_queue_io(struct spdk_bs_dev
*dev
, struct spdk_io_channel
*channel
, void *payload
,
93 uint64_t lba
, uint32_t lba_count
, enum spdk_bdev_io_type io_type
,
94 struct spdk_bs_dev_cb_args
*cb_args
)
97 struct spdk_bdev
*bdev
= __get_bdev(dev
);
98 struct blob_resubmit
*ctx
;
100 ctx
= calloc(1, sizeof(struct blob_resubmit
));
103 SPDK_ERRLOG("Not enough memory to queue io\n");
104 cb_args
->cb_fn(cb_args
->channel
, cb_args
->cb_arg
, -ENOMEM
);
108 ctx
->io_type
= io_type
;
110 ctx
->channel
= channel
;
111 ctx
->payload
= payload
;
112 ctx
->iovcnt
= iovcnt
;
114 ctx
->lba_count
= lba_count
;
115 ctx
->cb_args
= cb_args
;
116 ctx
->bdev_io_wait
.bdev
= bdev
;
117 ctx
->bdev_io_wait
.cb_fn
= bdev_blob_resubmit
;
118 ctx
->bdev_io_wait
.cb_arg
= ctx
;
120 rc
= spdk_bdev_queue_io_wait(bdev
, channel
, &ctx
->bdev_io_wait
);
122 SPDK_ERRLOG("Queue io failed, rc=%d\n", rc
);
123 cb_args
->cb_fn(cb_args
->channel
, cb_args
->cb_arg
, rc
);
130 bdev_blob_read(struct spdk_bs_dev
*dev
, struct spdk_io_channel
*channel
, void *payload
,
131 uint64_t lba
, uint32_t lba_count
, struct spdk_bs_dev_cb_args
*cb_args
)
135 rc
= spdk_bdev_read_blocks(__get_desc(dev
), channel
, payload
, lba
,
136 lba_count
, bdev_blob_io_complete
, cb_args
);
138 bdev_blob_queue_io(dev
, channel
, payload
, 0, lba
,
139 lba_count
, SPDK_BDEV_IO_TYPE_READ
, cb_args
);
140 } else if (rc
!= 0) {
141 cb_args
->cb_fn(cb_args
->channel
, cb_args
->cb_arg
, rc
);
146 bdev_blob_write(struct spdk_bs_dev
*dev
, struct spdk_io_channel
*channel
, void *payload
,
147 uint64_t lba
, uint32_t lba_count
, struct spdk_bs_dev_cb_args
*cb_args
)
151 rc
= spdk_bdev_write_blocks(__get_desc(dev
), channel
, payload
, lba
,
152 lba_count
, bdev_blob_io_complete
, cb_args
);
154 bdev_blob_queue_io(dev
, channel
, payload
, 0, lba
,
155 lba_count
, SPDK_BDEV_IO_TYPE_WRITE
, cb_args
);
156 } else if (rc
!= 0) {
157 cb_args
->cb_fn(cb_args
->channel
, cb_args
->cb_arg
, rc
);
162 bdev_blob_readv(struct spdk_bs_dev
*dev
, struct spdk_io_channel
*channel
,
163 struct iovec
*iov
, int iovcnt
,
164 uint64_t lba
, uint32_t lba_count
, struct spdk_bs_dev_cb_args
*cb_args
)
168 rc
= spdk_bdev_readv_blocks(__get_desc(dev
), channel
, iov
, iovcnt
, lba
,
169 lba_count
, bdev_blob_io_complete
, cb_args
);
171 bdev_blob_queue_io(dev
, channel
, iov
, iovcnt
, lba
,
172 lba_count
, SPDK_BDEV_IO_TYPE_READ
, cb_args
);
173 } else if (rc
!= 0) {
174 cb_args
->cb_fn(cb_args
->channel
, cb_args
->cb_arg
, rc
);
179 bdev_blob_writev(struct spdk_bs_dev
*dev
, struct spdk_io_channel
*channel
,
180 struct iovec
*iov
, int iovcnt
,
181 uint64_t lba
, uint32_t lba_count
, struct spdk_bs_dev_cb_args
*cb_args
)
185 rc
= spdk_bdev_writev_blocks(__get_desc(dev
), channel
, iov
, iovcnt
, lba
,
186 lba_count
, bdev_blob_io_complete
, cb_args
);
188 bdev_blob_queue_io(dev
, channel
, iov
, iovcnt
, lba
,
189 lba_count
, SPDK_BDEV_IO_TYPE_WRITE
, cb_args
);
190 } else if (rc
!= 0) {
191 cb_args
->cb_fn(cb_args
->channel
, cb_args
->cb_arg
, rc
);
196 bdev_blob_write_zeroes(struct spdk_bs_dev
*dev
, struct spdk_io_channel
*channel
, uint64_t lba
,
197 uint32_t lba_count
, struct spdk_bs_dev_cb_args
*cb_args
)
201 rc
= spdk_bdev_write_zeroes_blocks(__get_desc(dev
), channel
, lba
,
202 lba_count
, bdev_blob_io_complete
, cb_args
);
204 bdev_blob_queue_io(dev
, channel
, NULL
, 0, lba
,
205 lba_count
, SPDK_BDEV_IO_TYPE_WRITE_ZEROES
, cb_args
);
206 } else if (rc
!= 0) {
207 cb_args
->cb_fn(cb_args
->channel
, cb_args
->cb_arg
, rc
);
212 bdev_blob_unmap(struct spdk_bs_dev
*dev
, struct spdk_io_channel
*channel
, uint64_t lba
,
213 uint32_t lba_count
, struct spdk_bs_dev_cb_args
*cb_args
)
215 struct blob_bdev
*blob_bdev
= (struct blob_bdev
*)dev
;
218 if (spdk_bdev_io_type_supported(blob_bdev
->bdev
, SPDK_BDEV_IO_TYPE_UNMAP
)) {
219 rc
= spdk_bdev_unmap_blocks(__get_desc(dev
), channel
, lba
, lba_count
,
220 bdev_blob_io_complete
, cb_args
);
222 bdev_blob_queue_io(dev
, channel
, NULL
, 0, lba
,
223 lba_count
, SPDK_BDEV_IO_TYPE_UNMAP
, cb_args
);
224 } else if (rc
!= 0) {
225 cb_args
->cb_fn(cb_args
->channel
, cb_args
->cb_arg
, rc
);
229 * If the device doesn't support unmap, immediately complete
230 * the request. Blobstore does not rely on unmap zeroing
233 cb_args
->cb_fn(cb_args
->channel
, cb_args
->cb_arg
, 0);
238 bdev_blob_resubmit(void *arg
)
240 struct blob_resubmit
*ctx
= (struct blob_resubmit
*) arg
;
242 switch (ctx
->io_type
) {
243 case SPDK_BDEV_IO_TYPE_READ
:
244 if (ctx
->iovcnt
> 0) {
245 bdev_blob_readv(ctx
->dev
, ctx
->channel
, (struct iovec
*)ctx
->payload
, ctx
->iovcnt
,
246 ctx
->lba
, ctx
->lba_count
, ctx
->cb_args
);
248 bdev_blob_read(ctx
->dev
, ctx
->channel
, ctx
->payload
,
249 ctx
->lba
, ctx
->lba_count
, ctx
->cb_args
);
252 case SPDK_BDEV_IO_TYPE_WRITE
:
253 if (ctx
->iovcnt
> 0) {
254 bdev_blob_writev(ctx
->dev
, ctx
->channel
, (struct iovec
*)ctx
->payload
, ctx
->iovcnt
,
255 ctx
->lba
, ctx
->lba_count
, ctx
->cb_args
);
257 bdev_blob_write(ctx
->dev
, ctx
->channel
, ctx
->payload
,
258 ctx
->lba
, ctx
->lba_count
, ctx
->cb_args
);
261 case SPDK_BDEV_IO_TYPE_UNMAP
:
262 bdev_blob_unmap(ctx
->dev
, ctx
->channel
,
263 ctx
->lba
, ctx
->lba_count
, ctx
->cb_args
);
265 case SPDK_BDEV_IO_TYPE_WRITE_ZEROES
:
266 bdev_blob_write_zeroes(ctx
->dev
, ctx
->channel
,
267 ctx
->lba
, ctx
->lba_count
, ctx
->cb_args
);
270 SPDK_ERRLOG("Unsupported io type %d\n", ctx
->io_type
);
278 spdk_bs_bdev_claim(struct spdk_bs_dev
*bs_dev
, struct spdk_bdev_module
*module
)
280 struct blob_bdev
*blob_bdev
= (struct blob_bdev
*)bs_dev
;
283 rc
= spdk_bdev_module_claim_bdev(blob_bdev
->bdev
, NULL
, module
);
285 SPDK_ERRLOG("could not claim bs dev\n");
289 blob_bdev
->claimed
= true;
294 static struct spdk_io_channel
*
295 bdev_blob_create_channel(struct spdk_bs_dev
*dev
)
297 struct blob_bdev
*blob_bdev
= (struct blob_bdev
*)dev
;
299 return spdk_bdev_get_io_channel(blob_bdev
->desc
);
303 bdev_blob_destroy_channel(struct spdk_bs_dev
*dev
, struct spdk_io_channel
*channel
)
305 spdk_put_io_channel(channel
);
309 bdev_blob_destroy(struct spdk_bs_dev
*bs_dev
)
311 struct spdk_bdev_desc
*desc
= __get_desc(bs_dev
);
312 struct blob_bdev
*blob_bdev
= (struct blob_bdev
*)bs_dev
;
314 if (blob_bdev
->claimed
) {
315 spdk_bdev_module_release_bdev(blob_bdev
->bdev
);
318 spdk_bdev_close(desc
);
323 spdk_bdev_create_bs_dev(struct spdk_bdev
*bdev
, spdk_bdev_remove_cb_t remove_cb
, void *remove_ctx
)
326 struct spdk_bdev_desc
*desc
;
329 b
= calloc(1, sizeof(*b
));
332 SPDK_ERRLOG("could not allocate blob_bdev\n");
336 rc
= spdk_bdev_open(bdev
, true, remove_cb
, remove_ctx
, &desc
);
344 b
->bs_dev
.blockcnt
= spdk_bdev_get_num_blocks(bdev
);
345 b
->bs_dev
.blocklen
= spdk_bdev_get_block_size(bdev
);
346 b
->bs_dev
.create_channel
= bdev_blob_create_channel
;
347 b
->bs_dev
.destroy_channel
= bdev_blob_destroy_channel
;
348 b
->bs_dev
.destroy
= bdev_blob_destroy
;
349 b
->bs_dev
.read
= bdev_blob_read
;
350 b
->bs_dev
.write
= bdev_blob_write
;
351 b
->bs_dev
.readv
= bdev_blob_readv
;
352 b
->bs_dev
.writev
= bdev_blob_writev
;
353 b
->bs_dev
.write_zeroes
= bdev_blob_write_zeroes
;
354 b
->bs_dev
.unmap
= bdev_blob_unmap
;
360 spdk_bdev_create_bs_dev_from_desc(struct spdk_bdev_desc
*desc
)
363 struct spdk_bdev
*bdev
;
365 b
= calloc(1, sizeof(*b
));
368 SPDK_ERRLOG("could not allocate blob_bdev\n");
372 bdev
= spdk_bdev_desc_get_bdev(desc
);
373 assert(bdev
!= NULL
);
377 b
->bs_dev
.blockcnt
= spdk_bdev_get_num_blocks(bdev
);
378 b
->bs_dev
.blocklen
= spdk_bdev_get_block_size(bdev
);
379 b
->bs_dev
.create_channel
= bdev_blob_create_channel
;
380 b
->bs_dev
.destroy_channel
= bdev_blob_destroy_channel
;
381 b
->bs_dev
.destroy
= bdev_blob_destroy
;
382 b
->bs_dev
.read
= bdev_blob_read
;
383 b
->bs_dev
.write
= bdev_blob_write
;
384 b
->bs_dev
.readv
= bdev_blob_readv
;
385 b
->bs_dev
.writev
= bdev_blob_writev
;
386 b
->bs_dev
.write_zeroes
= bdev_blob_write_zeroes
;
387 b
->bs_dev
.unmap
= bdev_blob_unmap
;