Line data Source code
1 : /* SPDX-License-Identifier: BSD-3-Clause
2 : * Copyright (C) 2017 Intel Corporation.
3 : * All rights reserved.
4 : * Copyright (c) 2022-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
5 : */
6 :
7 : #include "spdk/stdinc.h"
8 :
9 : #include "blobstore.h"
10 : #include "request.h"
11 :
12 : #include "spdk/thread.h"
13 : #include "spdk/queue.h"
14 :
15 : #include "spdk/log.h"
16 :
17 : void
18 56278 : bs_call_cpl(struct spdk_bs_cpl *cpl, int bserrno)
19 : {
20 56278 : switch (cpl->type) {
21 698 : case SPDK_BS_CPL_TYPE_BS_BASIC:
22 698 : cpl->u.bs_basic.cb_fn(cpl->u.bs_basic.cb_arg,
23 : bserrno);
24 698 : break;
25 776 : case SPDK_BS_CPL_TYPE_BS_HANDLE:
26 776 : cpl->u.bs_handle.cb_fn(cpl->u.bs_handle.cb_arg,
27 : bserrno == 0 ? cpl->u.bs_handle.bs : NULL,
28 : bserrno);
29 776 : break;
30 48672 : case SPDK_BS_CPL_TYPE_BLOB_BASIC:
31 48672 : cpl->u.blob_basic.cb_fn(cpl->u.blob_basic.cb_arg,
32 : bserrno);
33 48672 : break;
34 1878 : case SPDK_BS_CPL_TYPE_BLOBID:
35 1878 : cpl->u.blobid.cb_fn(cpl->u.blobid.cb_arg,
36 : bserrno == 0 ? cpl->u.blobid.blobid : SPDK_BLOBID_INVALID,
37 : bserrno);
38 1878 : break;
39 3474 : case SPDK_BS_CPL_TYPE_BLOB_HANDLE:
40 3474 : cpl->u.blob_handle.cb_fn(cpl->u.blob_handle.cb_arg,
41 : bserrno == 0 ? cpl->u.blob_handle.blob : NULL,
42 : bserrno);
43 3474 : break;
44 0 : case SPDK_BS_CPL_TYPE_NESTED_SEQUENCE:
45 0 : cpl->u.nested_seq.cb_fn(cpl->u.nested_seq.cb_arg,
46 : cpl->u.nested_seq.parent,
47 : bserrno);
48 0 : break;
49 780 : case SPDK_BS_CPL_TYPE_NONE:
50 : /* this completion's callback is handled elsewhere */
51 780 : break;
52 : }
53 56278 : }
54 :
55 : static void
56 55498 : bs_request_set_complete(struct spdk_bs_request_set *set)
57 : {
58 55498 : struct spdk_bs_cpl cpl = set->cpl;
59 55498 : int bserrno = set->bserrno;
60 :
61 55498 : TAILQ_INSERT_TAIL(&set->channel->reqs, set, link);
62 :
63 55498 : bs_call_cpl(&cpl, bserrno);
64 55498 : }
65 :
66 : static void
67 24390 : bs_sequence_completion(struct spdk_io_channel *channel, void *cb_arg, int bserrno)
68 : {
69 24390 : struct spdk_bs_request_set *set = cb_arg;
70 :
71 24390 : set->bserrno = bserrno;
72 24390 : set->u.sequence.cb_fn((spdk_bs_sequence_t *)set, set->u.sequence.cb_arg, bserrno);
73 24390 : }
74 :
75 : static inline spdk_bs_sequence_t *
76 18008 : bs_sequence_start(struct spdk_io_channel *_channel, struct spdk_bs_cpl *cpl,
77 : struct spdk_io_channel *back_channel)
78 : {
79 : struct spdk_bs_channel *channel;
80 : struct spdk_bs_request_set *set;
81 :
82 18008 : channel = spdk_io_channel_get_ctx(_channel);
83 18008 : assert(channel != NULL);
84 18008 : set = TAILQ_FIRST(&channel->reqs);
85 18008 : if (!set) {
86 0 : return NULL;
87 : }
88 18008 : TAILQ_REMOVE(&channel->reqs, set, link);
89 :
90 18008 : set->cpl = *cpl;
91 18008 : set->bserrno = 0;
92 18008 : set->channel = channel;
93 18008 : set->back_channel = back_channel;
94 :
95 18008 : set->cb_args.cb_fn = bs_sequence_completion;
96 18008 : set->cb_args.cb_arg = set;
97 18008 : set->cb_args.channel = channel->dev_channel;
98 18008 : set->ext_io_opts = NULL;
99 :
100 18008 : return (spdk_bs_sequence_t *)set;
101 : }
102 :
103 : /* Use when performing IO directly on the blobstore (e.g. metadata - not a blob). */
104 : spdk_bs_sequence_t *
105 14658 : bs_sequence_start_bs(struct spdk_io_channel *_channel, struct spdk_bs_cpl *cpl)
106 : {
107 14658 : return bs_sequence_start(_channel, cpl, _channel);
108 : }
109 :
110 : /* Use when performing IO on a blob. */
111 : spdk_bs_sequence_t *
112 3350 : bs_sequence_start_blob(struct spdk_io_channel *_channel, struct spdk_bs_cpl *cpl,
113 : struct spdk_blob *blob)
114 : {
115 3350 : struct spdk_io_channel *esnap_ch = _channel;
116 :
117 3350 : if (spdk_blob_is_esnap_clone(blob)) {
118 1500 : esnap_ch = blob_esnap_get_io_channel(_channel, blob);
119 1500 : if (esnap_ch == NULL) {
120 : /*
121 : * The most likely reason we are here is because of some logic error
122 : * elsewhere that caused channel allocations to fail. We could get here due
123 : * to being out of memory as well. If we are out of memory, the process is
124 : * this will be just one of many problems that this process will be having.
125 : * Killing it off debug builds now due to logic errors is the right thing to
126 : * do and killing it off due to ENOMEM is no big loss.
127 : */
128 0 : assert(false);
129 : return NULL;
130 : }
131 : }
132 3350 : return bs_sequence_start(_channel, cpl, esnap_ch);
133 : }
134 :
135 : void
136 280 : bs_sequence_read_bs_dev(spdk_bs_sequence_t *seq, struct spdk_bs_dev *bs_dev,
137 : void *payload, uint64_t lba, uint32_t lba_count,
138 : spdk_bs_sequence_cpl cb_fn, void *cb_arg)
139 : {
140 280 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)seq;
141 280 : struct spdk_io_channel *back_channel = set->back_channel;
142 :
143 280 : SPDK_DEBUGLOG(blob_rw, "Reading %" PRIu32 " blocks from LBA %" PRIu64 "\n", lba_count,
144 : lba);
145 :
146 280 : set->u.sequence.cb_fn = cb_fn;
147 280 : set->u.sequence.cb_arg = cb_arg;
148 :
149 280 : bs_dev->read(bs_dev, back_channel, payload, lba, lba_count, &set->cb_args);
150 280 : }
151 :
152 : void
153 13062 : bs_sequence_read_dev(spdk_bs_sequence_t *seq, void *payload,
154 : uint64_t lba, uint32_t lba_count,
155 : spdk_bs_sequence_cpl cb_fn, void *cb_arg)
156 : {
157 13062 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)seq;
158 13062 : struct spdk_bs_channel *channel = set->channel;
159 :
160 13062 : SPDK_DEBUGLOG(blob_rw, "Reading %" PRIu32 " blocks from LBA %" PRIu64 "\n", lba_count,
161 : lba);
162 :
163 13062 : set->u.sequence.cb_fn = cb_fn;
164 13062 : set->u.sequence.cb_arg = cb_arg;
165 :
166 13062 : channel->dev->read(channel->dev, channel->dev_channel, payload, lba, lba_count, &set->cb_args);
167 13062 : }
168 :
169 : void
170 8556 : bs_sequence_write_dev(spdk_bs_sequence_t *seq, void *payload,
171 : uint64_t lba, uint32_t lba_count,
172 : spdk_bs_sequence_cpl cb_fn, void *cb_arg)
173 : {
174 8556 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)seq;
175 8556 : struct spdk_bs_channel *channel = set->channel;
176 :
177 8556 : SPDK_DEBUGLOG(blob_rw, "Writing %" PRIu32 " blocks from LBA %" PRIu64 "\n", lba_count,
178 : lba);
179 :
180 8556 : set->u.sequence.cb_fn = cb_fn;
181 8556 : set->u.sequence.cb_arg = cb_arg;
182 :
183 8556 : channel->dev->write(channel->dev, channel->dev_channel, payload, lba, lba_count,
184 : &set->cb_args);
185 8556 : }
186 :
187 : void
188 1544 : bs_sequence_readv_bs_dev(spdk_bs_sequence_t *seq, struct spdk_bs_dev *bs_dev,
189 : struct iovec *iov, int iovcnt, uint64_t lba, uint32_t lba_count,
190 : spdk_bs_sequence_cpl cb_fn, void *cb_arg)
191 : {
192 1544 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)seq;
193 1544 : struct spdk_io_channel *back_channel = set->back_channel;
194 :
195 1544 : SPDK_DEBUGLOG(blob_rw, "Reading %" PRIu32 " blocks from LBA %" PRIu64 "\n", lba_count,
196 : lba);
197 :
198 1544 : set->u.sequence.cb_fn = cb_fn;
199 1544 : set->u.sequence.cb_arg = cb_arg;
200 :
201 1544 : if (set->ext_io_opts) {
202 72 : assert(bs_dev->readv_ext);
203 72 : bs_dev->readv_ext(bs_dev, back_channel, iov, iovcnt, lba, lba_count,
204 : &set->cb_args, set->ext_io_opts);
205 : } else {
206 1472 : bs_dev->readv(bs_dev, back_channel, iov, iovcnt, lba, lba_count, &set->cb_args);
207 : }
208 1544 : }
209 :
210 : void
211 540 : bs_sequence_readv_dev(spdk_bs_sequence_t *seq, struct iovec *iov, int iovcnt,
212 : uint64_t lba, uint32_t lba_count, spdk_bs_sequence_cpl cb_fn, void *cb_arg)
213 : {
214 540 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)seq;
215 540 : struct spdk_bs_channel *channel = set->channel;
216 :
217 540 : SPDK_DEBUGLOG(blob_rw, "Reading %" PRIu32 " blocks from LBA %" PRIu64 "\n", lba_count,
218 : lba);
219 :
220 540 : set->u.sequence.cb_fn = cb_fn;
221 540 : set->u.sequence.cb_arg = cb_arg;
222 540 : if (set->ext_io_opts) {
223 216 : assert(channel->dev->readv_ext);
224 216 : channel->dev->readv_ext(channel->dev, channel->dev_channel, iov, iovcnt, lba, lba_count,
225 : &set->cb_args, set->ext_io_opts);
226 : } else {
227 324 : channel->dev->readv(channel->dev, channel->dev_channel, iov, iovcnt, lba, lba_count, &set->cb_args);
228 : }
229 540 : }
230 :
231 : void
232 276 : bs_sequence_writev_dev(spdk_bs_sequence_t *seq, struct iovec *iov, int iovcnt,
233 : uint64_t lba, uint32_t lba_count,
234 : spdk_bs_sequence_cpl cb_fn, void *cb_arg)
235 : {
236 276 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)seq;
237 276 : struct spdk_bs_channel *channel = set->channel;
238 :
239 276 : SPDK_DEBUGLOG(blob_rw, "Writing %" PRIu32 " blocks from LBA %" PRIu64 "\n", lba_count,
240 : lba);
241 :
242 276 : set->u.sequence.cb_fn = cb_fn;
243 276 : set->u.sequence.cb_arg = cb_arg;
244 :
245 276 : if (set->ext_io_opts) {
246 72 : assert(channel->dev->writev_ext);
247 72 : channel->dev->writev_ext(channel->dev, channel->dev_channel, iov, iovcnt, lba, lba_count,
248 : &set->cb_args, set->ext_io_opts);
249 : } else {
250 204 : channel->dev->writev(channel->dev, channel->dev_channel, iov, iovcnt, lba, lba_count,
251 : &set->cb_args);
252 : }
253 276 : }
254 :
255 : void
256 4 : bs_sequence_write_zeroes_dev(spdk_bs_sequence_t *seq,
257 : uint64_t lba, uint64_t lba_count,
258 : spdk_bs_sequence_cpl cb_fn, void *cb_arg)
259 : {
260 4 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)seq;
261 4 : struct spdk_bs_channel *channel = set->channel;
262 :
263 4 : SPDK_DEBUGLOG(blob_rw, "writing zeroes to %" PRIu64 " blocks at LBA %" PRIu64 "\n",
264 : lba_count, lba);
265 :
266 4 : set->u.sequence.cb_fn = cb_fn;
267 4 : set->u.sequence.cb_arg = cb_arg;
268 :
269 4 : channel->dev->write_zeroes(channel->dev, channel->dev_channel, lba, lba_count,
270 : &set->cb_args);
271 4 : }
272 :
273 : void
274 128 : bs_sequence_copy_dev(spdk_bs_sequence_t *seq, uint64_t dst_lba, uint64_t src_lba,
275 : uint64_t lba_count, spdk_bs_sequence_cpl cb_fn, void *cb_arg)
276 : {
277 128 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)seq;
278 128 : struct spdk_bs_channel *channel = set->channel;
279 :
280 128 : SPDK_DEBUGLOG(blob_rw, "Copying %" PRIu64 " blocks from LBA %" PRIu64 " to LBA %" PRIu64 "\n",
281 : lba_count, src_lba, dst_lba);
282 :
283 128 : set->u.sequence.cb_fn = cb_fn;
284 128 : set->u.sequence.cb_arg = cb_arg;
285 :
286 128 : channel->dev->copy(channel->dev, channel->dev_channel, dst_lba, src_lba, lba_count, &set->cb_args);
287 128 : }
288 :
289 : void
290 18008 : bs_sequence_finish(spdk_bs_sequence_t *seq, int bserrno)
291 : {
292 18008 : if (bserrno != 0) {
293 168 : seq->bserrno = bserrno;
294 : }
295 18008 : bs_request_set_complete((struct spdk_bs_request_set *)seq);
296 18008 : }
297 :
298 : void
299 0 : bs_user_op_sequence_finish(void *cb_arg, int bserrno)
300 : {
301 0 : spdk_bs_sequence_t *seq = cb_arg;
302 :
303 0 : bs_sequence_finish(seq, bserrno);
304 0 : }
305 :
306 : static void
307 42002 : bs_batch_completion(struct spdk_io_channel *_channel,
308 : void *cb_arg, int bserrno)
309 : {
310 42002 : struct spdk_bs_request_set *set = cb_arg;
311 :
312 42002 : set->u.batch.outstanding_ops--;
313 42002 : if (bserrno != 0) {
314 4 : set->bserrno = bserrno;
315 : }
316 :
317 42002 : if (set->u.batch.outstanding_ops == 0 && set->u.batch.batch_closed) {
318 40484 : if (set->u.batch.cb_fn) {
319 3930 : set->cb_args.cb_fn = bs_sequence_completion;
320 3930 : set->u.batch.cb_fn((spdk_bs_sequence_t *)set, set->u.batch.cb_arg, bserrno);
321 : } else {
322 36554 : bs_request_set_complete(set);
323 : }
324 : }
325 42002 : }
326 :
327 : spdk_bs_batch_t *
328 37490 : bs_batch_open(struct spdk_io_channel *_channel, struct spdk_bs_cpl *cpl, struct spdk_blob *blob)
329 : {
330 : struct spdk_bs_channel *channel;
331 : struct spdk_bs_request_set *set;
332 37490 : struct spdk_io_channel *back_channel = _channel;
333 :
334 37490 : if (spdk_blob_is_esnap_clone(blob)) {
335 7340 : back_channel = blob_esnap_get_io_channel(_channel, blob);
336 7340 : if (back_channel == NULL) {
337 0 : return NULL;
338 : }
339 : }
340 :
341 37490 : channel = spdk_io_channel_get_ctx(_channel);
342 37490 : assert(channel != NULL);
343 37490 : set = TAILQ_FIRST(&channel->reqs);
344 37490 : if (!set) {
345 0 : return NULL;
346 : }
347 37490 : TAILQ_REMOVE(&channel->reqs, set, link);
348 :
349 37490 : set->cpl = *cpl;
350 37490 : set->bserrno = 0;
351 37490 : set->channel = channel;
352 37490 : set->back_channel = back_channel;
353 :
354 37490 : set->u.batch.cb_fn = NULL;
355 37490 : set->u.batch.cb_arg = NULL;
356 37490 : set->u.batch.outstanding_ops = 0;
357 37490 : set->u.batch.batch_closed = 0;
358 :
359 37490 : set->cb_args.cb_fn = bs_batch_completion;
360 37490 : set->cb_args.cb_arg = set;
361 37490 : set->cb_args.channel = channel->dev_channel;
362 :
363 37490 : return (spdk_bs_batch_t *)set;
364 : }
365 :
366 : void
367 1088 : bs_batch_read_bs_dev(spdk_bs_batch_t *batch, struct spdk_bs_dev *bs_dev,
368 : void *payload, uint64_t lba, uint32_t lba_count)
369 : {
370 1088 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)batch;
371 1088 : struct spdk_io_channel *back_channel = set->back_channel;
372 :
373 1088 : SPDK_DEBUGLOG(blob_rw, "Reading %" PRIu32 " blocks from LBA %" PRIu64 "\n", lba_count,
374 : lba);
375 :
376 1088 : set->u.batch.outstanding_ops++;
377 1088 : bs_dev->read(bs_dev, back_channel, payload, lba, lba_count, &set->cb_args);
378 1088 : }
379 :
380 : void
381 15851 : bs_batch_read_dev(spdk_bs_batch_t *batch, void *payload,
382 : uint64_t lba, uint32_t lba_count)
383 : {
384 15851 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)batch;
385 15851 : struct spdk_bs_channel *channel = set->channel;
386 :
387 15851 : SPDK_DEBUGLOG(blob_rw, "Reading %" PRIu32 " blocks from LBA %" PRIu64 "\n", lba_count,
388 : lba);
389 :
390 15851 : set->u.batch.outstanding_ops++;
391 15851 : channel->dev->read(channel->dev, channel->dev_channel, payload, lba, lba_count, &set->cb_args);
392 15851 : }
393 :
394 : void
395 20563 : bs_batch_write_dev(spdk_bs_batch_t *batch, void *payload,
396 : uint64_t lba, uint32_t lba_count)
397 : {
398 20563 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)batch;
399 20563 : struct spdk_bs_channel *channel = set->channel;
400 :
401 20563 : SPDK_DEBUGLOG(blob_rw, "Writing %" PRIu32 " blocks to LBA %" PRIu64 "\n", lba_count, lba);
402 :
403 20563 : set->u.batch.outstanding_ops++;
404 20563 : channel->dev->write(channel->dev, channel->dev_channel, payload, lba, lba_count,
405 : &set->cb_args);
406 20563 : }
407 :
408 : void
409 1810 : bs_batch_unmap_dev(spdk_bs_batch_t *batch,
410 : uint64_t lba, uint64_t lba_count)
411 : {
412 1810 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)batch;
413 1810 : struct spdk_bs_channel *channel = set->channel;
414 :
415 1810 : SPDK_DEBUGLOG(blob_rw, "Unmapping %" PRIu64 " blocks at LBA %" PRIu64 "\n", lba_count,
416 : lba);
417 :
418 1810 : set->u.batch.outstanding_ops++;
419 1810 : channel->dev->unmap(channel->dev, channel->dev_channel, lba, lba_count,
420 : &set->cb_args);
421 1810 : }
422 :
423 : void
424 2690 : bs_batch_write_zeroes_dev(spdk_bs_batch_t *batch,
425 : uint64_t lba, uint64_t lba_count)
426 : {
427 2690 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)batch;
428 2690 : struct spdk_bs_channel *channel = set->channel;
429 :
430 2690 : SPDK_DEBUGLOG(blob_rw, "Zeroing %" PRIu64 " blocks at LBA %" PRIu64 "\n", lba_count, lba);
431 :
432 2690 : set->u.batch.outstanding_ops++;
433 2690 : channel->dev->write_zeroes(channel->dev, channel->dev_channel, lba, lba_count,
434 : &set->cb_args);
435 2690 : }
436 :
437 : void
438 56826 : bs_batch_close(spdk_bs_batch_t *batch)
439 : {
440 56826 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)batch;
441 :
442 56826 : set->u.batch.batch_closed = 1;
443 :
444 56826 : if (set->u.batch.outstanding_ops == 0) {
445 16342 : if (set->u.batch.cb_fn) {
446 15406 : set->cb_args.cb_fn = bs_sequence_completion;
447 15406 : set->u.batch.cb_fn((spdk_bs_sequence_t *)set, set->u.batch.cb_arg, set->bserrno);
448 : } else {
449 936 : bs_request_set_complete(set);
450 : }
451 : }
452 56826 : }
453 :
454 : spdk_bs_batch_t *
455 19336 : bs_sequence_to_batch(spdk_bs_sequence_t *seq, spdk_bs_sequence_cpl cb_fn, void *cb_arg)
456 : {
457 19336 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)seq;
458 :
459 19336 : set->u.batch.cb_fn = cb_fn;
460 19336 : set->u.batch.cb_arg = cb_arg;
461 19336 : set->u.batch.outstanding_ops = 0;
462 19336 : set->u.batch.batch_closed = 0;
463 :
464 19336 : set->cb_args.cb_fn = bs_batch_completion;
465 :
466 19336 : return set;
467 : }
468 :
469 : spdk_bs_user_op_t *
470 816 : bs_user_op_alloc(struct spdk_io_channel *_channel, struct spdk_bs_cpl *cpl,
471 : enum spdk_blob_op_type op_type, struct spdk_blob *blob,
472 : void *payload, int iovcnt, uint64_t offset, uint64_t length)
473 : {
474 : struct spdk_bs_channel *channel;
475 : struct spdk_bs_request_set *set;
476 : struct spdk_bs_user_op_args *args;
477 :
478 816 : channel = spdk_io_channel_get_ctx(_channel);
479 816 : assert(channel != NULL);
480 816 : set = TAILQ_FIRST(&channel->reqs);
481 816 : if (!set) {
482 0 : return NULL;
483 : }
484 816 : TAILQ_REMOVE(&channel->reqs, set, link);
485 :
486 816 : set->cpl = *cpl;
487 816 : set->channel = channel;
488 816 : set->back_channel = NULL;
489 816 : set->ext_io_opts = NULL;
490 :
491 816 : args = &set->u.user_op;
492 :
493 816 : args->type = op_type;
494 816 : args->iovcnt = iovcnt;
495 816 : args->blob = blob;
496 816 : args->offset = offset;
497 816 : args->length = length;
498 816 : args->payload = payload;
499 :
500 816 : return (spdk_bs_user_op_t *)set;
501 : }
502 :
503 : void
504 816 : bs_user_op_execute(spdk_bs_user_op_t *op)
505 : {
506 : struct spdk_bs_request_set *set;
507 : struct spdk_bs_user_op_args *args;
508 : struct spdk_io_channel *ch;
509 :
510 816 : set = (struct spdk_bs_request_set *)op;
511 816 : args = &set->u.user_op;
512 816 : ch = spdk_io_channel_from_ctx(set->channel);
513 :
514 816 : switch (args->type) {
515 452 : case SPDK_BLOB_READ:
516 452 : spdk_blob_io_read(args->blob, ch, args->payload, args->offset, args->length,
517 : set->cpl.u.blob_basic.cb_fn, set->cpl.u.blob_basic.cb_arg);
518 452 : break;
519 348 : case SPDK_BLOB_WRITE:
520 348 : spdk_blob_io_write(args->blob, ch, args->payload, args->offset, args->length,
521 : set->cpl.u.blob_basic.cb_fn, set->cpl.u.blob_basic.cb_arg);
522 348 : break;
523 0 : case SPDK_BLOB_UNMAP:
524 0 : spdk_blob_io_unmap(args->blob, ch, args->offset, args->length,
525 : set->cpl.u.blob_basic.cb_fn, set->cpl.u.blob_basic.cb_arg);
526 0 : break;
527 0 : case SPDK_BLOB_WRITE_ZEROES:
528 0 : spdk_blob_io_write_zeroes(args->blob, ch, args->offset, args->length,
529 : set->cpl.u.blob_basic.cb_fn, set->cpl.u.blob_basic.cb_arg);
530 0 : break;
531 0 : case SPDK_BLOB_READV:
532 0 : spdk_blob_io_readv_ext(args->blob, ch, args->payload, args->iovcnt,
533 : args->offset, args->length,
534 : set->cpl.u.blob_basic.cb_fn, set->cpl.u.blob_basic.cb_arg,
535 : set->ext_io_opts);
536 0 : break;
537 16 : case SPDK_BLOB_WRITEV:
538 16 : spdk_blob_io_writev_ext(args->blob, ch, args->payload, args->iovcnt,
539 : args->offset, args->length,
540 : set->cpl.u.blob_basic.cb_fn, set->cpl.u.blob_basic.cb_arg,
541 : set->ext_io_opts);
542 16 : break;
543 : }
544 816 : TAILQ_INSERT_TAIL(&set->channel->reqs, set, link);
545 816 : }
546 :
547 : void
548 0 : bs_user_op_abort(spdk_bs_user_op_t *op, int bserrno)
549 : {
550 : struct spdk_bs_request_set *set;
551 :
552 0 : set = (struct spdk_bs_request_set *)op;
553 :
554 0 : set->cpl.u.blob_basic.cb_fn(set->cpl.u.blob_basic.cb_arg, bserrno);
555 0 : TAILQ_INSERT_TAIL(&set->channel->reqs, set, link);
556 0 : }
557 :
558 3 : SPDK_LOG_REGISTER_COMPONENT(blob_rw)
|