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 42286 : bs_call_cpl(struct spdk_bs_cpl *cpl, int bserrno)
19 : {
20 42286 : switch (cpl->type) {
21 670 : case SPDK_BS_CPL_TYPE_BS_BASIC:
22 670 : cpl->u.bs_basic.cb_fn(cpl->u.bs_basic.cb_arg,
23 : bserrno);
24 670 : break;
25 748 : case SPDK_BS_CPL_TYPE_BS_HANDLE:
26 748 : cpl->u.bs_handle.cb_fn(cpl->u.bs_handle.cb_arg,
27 : bserrno == 0 ? cpl->u.bs_handle.bs : NULL,
28 : bserrno);
29 748 : break;
30 35052 : case SPDK_BS_CPL_TYPE_BLOB_BASIC:
31 35052 : cpl->u.blob_basic.cb_fn(cpl->u.blob_basic.cb_arg,
32 : bserrno);
33 35052 : break;
34 1786 : case SPDK_BS_CPL_TYPE_BLOBID:
35 1786 : cpl->u.blobid.cb_fn(cpl->u.blobid.cb_arg,
36 : bserrno == 0 ? cpl->u.blobid.blobid : SPDK_BLOBID_INVALID,
37 : bserrno);
38 1786 : break;
39 3278 : case SPDK_BS_CPL_TYPE_BLOB_HANDLE:
40 3278 : cpl->u.blob_handle.cb_fn(cpl->u.blob_handle.cb_arg,
41 : bserrno == 0 ? cpl->u.blob_handle.blob : NULL,
42 : bserrno);
43 3278 : 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 752 : case SPDK_BS_CPL_TYPE_NONE:
50 : /* this completion's callback is handled elsewhere */
51 752 : break;
52 : }
53 42286 : }
54 :
55 : static void
56 41534 : bs_request_set_complete(struct spdk_bs_request_set *set)
57 : {
58 41534 : struct spdk_bs_cpl cpl = set->cpl;
59 41534 : int bserrno = set->bserrno;
60 :
61 41534 : TAILQ_INSERT_TAIL(&set->channel->reqs, set, link);
62 :
63 41534 : bs_call_cpl(&cpl, bserrno);
64 41534 : }
65 :
66 : static void
67 23306 : bs_sequence_completion(struct spdk_io_channel *channel, void *cb_arg, int bserrno)
68 : {
69 23306 : struct spdk_bs_request_set *set = cb_arg;
70 :
71 23306 : set->bserrno = bserrno;
72 23306 : set->u.sequence.cb_fn((spdk_bs_sequence_t *)set, set->u.sequence.cb_arg, bserrno);
73 23306 : }
74 :
75 : static inline spdk_bs_sequence_t *
76 16580 : 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 16580 : channel = spdk_io_channel_get_ctx(_channel);
83 16580 : assert(channel != NULL);
84 16580 : set = TAILQ_FIRST(&channel->reqs);
85 16580 : if (!set) {
86 0 : return NULL;
87 : }
88 16580 : TAILQ_REMOVE(&channel->reqs, set, link);
89 :
90 16580 : set->cpl = *cpl;
91 16580 : set->bserrno = 0;
92 16580 : set->channel = channel;
93 16580 : set->back_channel = back_channel;
94 :
95 16580 : set->cb_args.cb_fn = bs_sequence_completion;
96 16580 : set->cb_args.cb_arg = set;
97 16580 : set->cb_args.channel = channel->dev_channel;
98 16580 : set->ext_io_opts = NULL;
99 :
100 16580 : 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 13438 : bs_sequence_start_bs(struct spdk_io_channel *_channel, struct spdk_bs_cpl *cpl)
106 : {
107 13438 : return bs_sequence_start(_channel, cpl, _channel);
108 : }
109 :
110 : /* Use when performing IO on a blob. */
111 : spdk_bs_sequence_t *
112 3142 : bs_sequence_start_blob(struct spdk_io_channel *_channel, struct spdk_bs_cpl *cpl,
113 : struct spdk_blob *blob)
114 : {
115 3142 : struct spdk_io_channel *esnap_ch = _channel;
116 :
117 3142 : if (spdk_blob_is_esnap_clone(blob)) {
118 1468 : esnap_ch = blob_esnap_get_io_channel(_channel, blob);
119 1468 : 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 3142 : return bs_sequence_start(_channel, cpl, esnap_ch);
133 : }
134 :
135 : void
136 188 : 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 188 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)seq;
141 188 : struct spdk_io_channel *back_channel = set->back_channel;
142 :
143 188 : SPDK_DEBUGLOG(blob_rw, "Reading %" PRIu32 " blocks from LBA %" PRIu64 "\n", lba_count,
144 : lba);
145 :
146 188 : set->u.sequence.cb_fn = cb_fn;
147 188 : set->u.sequence.cb_arg = cb_arg;
148 :
149 188 : bs_dev->read(bs_dev, back_channel, payload, lba, lba_count, &set->cb_args);
150 188 : }
151 :
152 : void
153 12826 : 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 12826 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)seq;
158 12826 : struct spdk_bs_channel *channel = set->channel;
159 :
160 12826 : SPDK_DEBUGLOG(blob_rw, "Reading %" PRIu32 " blocks from LBA %" PRIu64 "\n", lba_count,
161 : lba);
162 :
163 12826 : set->u.sequence.cb_fn = cb_fn;
164 12826 : set->u.sequence.cb_arg = cb_arg;
165 :
166 12826 : channel->dev->read(channel->dev, channel->dev_channel, payload, lba, lba_count, &set->cb_args);
167 12826 : }
168 :
169 : void
170 7820 : 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 7820 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)seq;
175 7820 : struct spdk_bs_channel *channel = set->channel;
176 :
177 7820 : SPDK_DEBUGLOG(blob_rw, "Writing %" PRIu32 " blocks from LBA %" PRIu64 "\n", lba_count,
178 : lba);
179 :
180 7820 : set->u.sequence.cb_fn = cb_fn;
181 7820 : set->u.sequence.cb_arg = cb_arg;
182 :
183 7820 : channel->dev->write(channel->dev, channel->dev_channel, payload, lba, lba_count,
184 : &set->cb_args);
185 7820 : }
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 108 : 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 108 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)seq;
278 108 : struct spdk_bs_channel *channel = set->channel;
279 :
280 108 : SPDK_DEBUGLOG(blob_rw, "Copying %" PRIu64 " blocks from LBA %" PRIu64 " to LBA %" PRIu64 "\n",
281 : lba_count, src_lba, dst_lba);
282 :
283 108 : set->u.sequence.cb_fn = cb_fn;
284 108 : set->u.sequence.cb_arg = cb_arg;
285 :
286 108 : channel->dev->copy(channel->dev, channel->dev_channel, dst_lba, src_lba, lba_count, &set->cb_args);
287 108 : }
288 :
289 : void
290 16580 : bs_sequence_finish(spdk_bs_sequence_t *seq, int bserrno)
291 : {
292 16580 : if (bserrno != 0) {
293 168 : seq->bserrno = bserrno;
294 : }
295 16580 : bs_request_set_complete((struct spdk_bs_request_set *)seq);
296 16580 : }
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 29316 : bs_batch_completion(struct spdk_io_channel *_channel,
308 : void *cb_arg, int bserrno)
309 : {
310 29316 : struct spdk_bs_request_set *set = cb_arg;
311 :
312 29316 : set->u.batch.outstanding_ops--;
313 29316 : if (bserrno != 0) {
314 4 : set->bserrno = bserrno;
315 : }
316 :
317 29316 : if (set->u.batch.outstanding_ops == 0 && set->u.batch.batch_closed) {
318 27906 : if (set->u.batch.cb_fn) {
319 3808 : set->cb_args.cb_fn = bs_sequence_completion;
320 3808 : set->u.batch.cb_fn((spdk_bs_sequence_t *)set, set->u.batch.cb_arg, bserrno);
321 : } else {
322 24098 : bs_request_set_complete(set);
323 : }
324 : }
325 29316 : }
326 :
327 : spdk_bs_batch_t *
328 24954 : 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 24954 : struct spdk_io_channel *back_channel = _channel;
333 :
334 24954 : if (spdk_blob_is_esnap_clone(blob)) {
335 3252 : back_channel = blob_esnap_get_io_channel(_channel, blob);
336 3252 : if (back_channel == NULL) {
337 0 : return NULL;
338 : }
339 : }
340 :
341 24954 : channel = spdk_io_channel_get_ctx(_channel);
342 24954 : assert(channel != NULL);
343 24954 : set = TAILQ_FIRST(&channel->reqs);
344 24954 : if (!set) {
345 0 : return NULL;
346 : }
347 24954 : TAILQ_REMOVE(&channel->reqs, set, link);
348 :
349 24954 : set->cpl = *cpl;
350 24954 : set->bserrno = 0;
351 24954 : set->channel = channel;
352 24954 : set->back_channel = back_channel;
353 :
354 24954 : set->u.batch.cb_fn = NULL;
355 24954 : set->u.batch.cb_arg = NULL;
356 24954 : set->u.batch.outstanding_ops = 0;
357 24954 : set->u.batch.batch_closed = 0;
358 :
359 24954 : set->cb_args.cb_fn = bs_batch_completion;
360 24954 : set->cb_args.cb_arg = set;
361 24954 : set->cb_args.channel = channel->dev_channel;
362 :
363 24954 : return (spdk_bs_batch_t *)set;
364 : }
365 :
366 : void
367 988 : 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 988 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)batch;
371 988 : struct spdk_io_channel *back_channel = set->back_channel;
372 :
373 988 : SPDK_DEBUGLOG(blob_rw, "Reading %" PRIu32 " blocks from LBA %" PRIu64 "\n", lba_count,
374 : lba);
375 :
376 988 : set->u.batch.outstanding_ops++;
377 988 : bs_dev->read(bs_dev, back_channel, payload, lba, lba_count, &set->cb_args);
378 988 : }
379 :
380 : void
381 12771 : bs_batch_read_dev(spdk_bs_batch_t *batch, void *payload,
382 : uint64_t lba, uint32_t lba_count)
383 : {
384 12771 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)batch;
385 12771 : struct spdk_bs_channel *channel = set->channel;
386 :
387 12771 : SPDK_DEBUGLOG(blob_rw, "Reading %" PRIu32 " blocks from LBA %" PRIu64 "\n", lba_count,
388 : lba);
389 :
390 12771 : set->u.batch.outstanding_ops++;
391 12771 : channel->dev->read(channel->dev, channel->dev_channel, payload, lba, lba_count, &set->cb_args);
392 12771 : }
393 :
394 : void
395 11279 : bs_batch_write_dev(spdk_bs_batch_t *batch, void *payload,
396 : uint64_t lba, uint32_t lba_count)
397 : {
398 11279 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)batch;
399 11279 : struct spdk_bs_channel *channel = set->channel;
400 :
401 11279 : SPDK_DEBUGLOG(blob_rw, "Writing %" PRIu32 " blocks to LBA %" PRIu64 "\n", lba_count, lba);
402 :
403 11279 : set->u.batch.outstanding_ops++;
404 11279 : channel->dev->write(channel->dev, channel->dev_channel, payload, lba, lba_count,
405 : &set->cb_args);
406 11279 : }
407 :
408 : void
409 1694 : bs_batch_unmap_dev(spdk_bs_batch_t *batch,
410 : uint64_t lba, uint64_t lba_count)
411 : {
412 1694 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)batch;
413 1694 : struct spdk_bs_channel *channel = set->channel;
414 :
415 1694 : SPDK_DEBUGLOG(blob_rw, "Unmapping %" PRIu64 " blocks at LBA %" PRIu64 "\n", lba_count,
416 : lba);
417 :
418 1694 : set->u.batch.outstanding_ops++;
419 1694 : channel->dev->unmap(channel->dev, channel->dev_channel, lba, lba_count,
420 : &set->cb_args);
421 1694 : }
422 :
423 : void
424 2584 : bs_batch_write_zeroes_dev(spdk_bs_batch_t *batch,
425 : uint64_t lba, uint64_t lba_count)
426 : {
427 2584 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)batch;
428 2584 : struct spdk_bs_channel *channel = set->channel;
429 :
430 2584 : SPDK_DEBUGLOG(blob_rw, "Zeroing %" PRIu64 " blocks at LBA %" PRIu64 "\n", lba_count, lba);
431 :
432 2584 : set->u.batch.outstanding_ops++;
433 2584 : channel->dev->write_zeroes(channel->dev, channel->dev_channel, lba, lba_count,
434 : &set->cb_args);
435 2584 : }
436 :
437 : void
438 42574 : bs_batch_close(spdk_bs_batch_t *batch)
439 : {
440 42574 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)batch;
441 :
442 42574 : set->u.batch.batch_closed = 1;
443 :
444 42574 : if (set->u.batch.outstanding_ops == 0) {
445 14668 : if (set->u.batch.cb_fn) {
446 13812 : set->cb_args.cb_fn = bs_sequence_completion;
447 13812 : set->u.batch.cb_fn((spdk_bs_sequence_t *)set, set->u.batch.cb_arg, set->bserrno);
448 : } else {
449 856 : bs_request_set_complete(set);
450 : }
451 : }
452 42574 : }
453 :
454 : spdk_bs_batch_t *
455 17620 : bs_sequence_to_batch(spdk_bs_sequence_t *seq, spdk_bs_sequence_cpl cb_fn, void *cb_arg)
456 : {
457 17620 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)seq;
458 :
459 17620 : set->u.batch.cb_fn = cb_fn;
460 17620 : set->u.batch.cb_arg = cb_arg;
461 17620 : set->u.batch.outstanding_ops = 0;
462 17620 : set->u.batch.batch_closed = 0;
463 :
464 17620 : set->cb_args.cb_fn = bs_batch_completion;
465 :
466 17620 : return set;
467 : }
468 :
469 : spdk_bs_user_op_t *
470 612 : 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 612 : channel = spdk_io_channel_get_ctx(_channel);
479 612 : assert(channel != NULL);
480 612 : set = TAILQ_FIRST(&channel->reqs);
481 612 : if (!set) {
482 0 : return NULL;
483 : }
484 612 : TAILQ_REMOVE(&channel->reqs, set, link);
485 :
486 612 : set->cpl = *cpl;
487 612 : set->channel = channel;
488 612 : set->back_channel = NULL;
489 612 : set->ext_io_opts = NULL;
490 :
491 612 : args = &set->u.user_op;
492 :
493 612 : args->type = op_type;
494 612 : args->iovcnt = iovcnt;
495 612 : args->blob = blob;
496 612 : args->offset = offset;
497 612 : args->length = length;
498 612 : args->payload = payload;
499 :
500 612 : return (spdk_bs_user_op_t *)set;
501 : }
502 :
503 : void
504 612 : 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 612 : set = (struct spdk_bs_request_set *)op;
511 612 : args = &set->u.user_op;
512 612 : ch = spdk_io_channel_from_ctx(set->channel);
513 :
514 612 : switch (args->type) {
515 380 : case SPDK_BLOB_READ:
516 380 : 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 380 : break;
519 216 : case SPDK_BLOB_WRITE:
520 216 : 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 216 : 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 612 : TAILQ_INSERT_TAIL(&set->channel->reqs, set, link);
545 612 : }
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)
|