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