Branch data 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 : 117201 : bs_call_cpl(struct spdk_bs_cpl *cpl, int bserrno)
21 : : {
22 [ + + + + : 117201 : switch (cpl->type) {
+ - + - ]
23 : 1420 : case SPDK_BS_CPL_TYPE_BS_BASIC:
24 : 1420 : cpl->u.bs_basic.cb_fn(cpl->u.bs_basic.cb_arg,
25 : : bserrno);
26 : 1420 : break;
27 : 3305 : case SPDK_BS_CPL_TYPE_BS_HANDLE:
28 [ + + ]: 3305 : cpl->u.bs_handle.cb_fn(cpl->u.bs_handle.cb_arg,
29 : : bserrno == 0 ? cpl->u.bs_handle.bs : NULL,
30 : : bserrno);
31 : 3305 : break;
32 : 98363 : case SPDK_BS_CPL_TYPE_BLOB_BASIC:
33 : 98363 : cpl->u.blob_basic.cb_fn(cpl->u.blob_basic.cb_arg,
34 : : bserrno);
35 : 98363 : break;
36 : 3772 : case SPDK_BS_CPL_TYPE_BLOBID:
37 [ + + ]: 3772 : cpl->u.blobid.cb_fn(cpl->u.blobid.cb_arg,
38 : : bserrno == 0 ? cpl->u.blobid.blobid : SPDK_BLOBID_INVALID,
39 : : bserrno);
40 : 3772 : break;
41 : 7028 : case SPDK_BS_CPL_TYPE_BLOB_HANDLE:
42 [ + + ]: 7028 : cpl->u.blob_handle.cb_fn(cpl->u.blob_handle.cb_arg,
43 : : bserrno == 0 ? cpl->u.blob_handle.blob : NULL,
44 : : bserrno);
45 : 7028 : break;
46 : 0 : case SPDK_BS_CPL_TYPE_NESTED_SEQUENCE:
47 : 0 : cpl->u.nested_seq.cb_fn(cpl->u.nested_seq.cb_arg,
48 : : cpl->u.nested_seq.parent,
49 : : bserrno);
50 : 0 : break;
51 : 3313 : case SPDK_BS_CPL_TYPE_NONE:
52 : : /* this completion's callback is handled elsewhere */
53 : 3313 : break;
54 : : }
55 : 117201 : }
56 : :
57 : : static void
58 : 113888 : bs_request_set_complete(struct spdk_bs_request_set *set)
59 : : {
60 : 113888 : struct spdk_bs_cpl cpl = set->cpl;
61 : 113888 : int bserrno = set->bserrno;
62 : :
63 [ + + - + ]: 113888 : spdk_trace_record(TRACE_BLOB_PROCESS_COMPLETE, 0, 0, (uintptr_t)&set->cb_args,
64 : : (uintptr_t)set->cpl.u.blob_basic.cb_arg);
65 : :
66 : 113888 : TAILQ_INSERT_TAIL(&set->channel->reqs, set, link);
67 : :
68 : 113888 : bs_call_cpl(&cpl, bserrno);
69 : 113888 : }
70 : :
71 : : static void
72 : 51703 : bs_sequence_completion(struct spdk_io_channel *channel, void *cb_arg, int bserrno)
73 : : {
74 : 51703 : struct spdk_bs_request_set *set = cb_arg;
75 : :
76 : 51703 : set->bserrno = bserrno;
77 : 51703 : set->u.sequence.cb_fn((spdk_bs_sequence_t *)set, set->u.sequence.cb_arg, bserrno);
78 : 51703 : }
79 : :
80 : : static inline spdk_bs_sequence_t *
81 : 38898 : bs_sequence_start(struct spdk_io_channel *_channel, struct spdk_bs_cpl *cpl,
82 : : struct spdk_io_channel *back_channel)
83 : : {
84 : : struct spdk_bs_channel *channel;
85 : : struct spdk_bs_request_set *set;
86 : :
87 : 38898 : channel = spdk_io_channel_get_ctx(_channel);
88 [ - + ]: 38898 : assert(channel != NULL);
89 : 38898 : set = TAILQ_FIRST(&channel->reqs);
90 [ - + ]: 38898 : if (!set) {
91 : 0 : return NULL;
92 : : }
93 [ + - ]: 38898 : TAILQ_REMOVE(&channel->reqs, set, link);
94 : :
95 [ + + - + ]: 38898 : spdk_trace_record(TRACE_BLOB_PROCESS_START, 0, 0, (uintptr_t)&set->cb_args,
96 : : (uintptr_t)cpl->u.blob_basic.cb_arg);
97 : :
98 : 38898 : set->cpl = *cpl;
99 : 38898 : set->bserrno = 0;
100 : 38898 : set->channel = channel;
101 : 38898 : set->back_channel = back_channel;
102 : :
103 : 38898 : set->cb_args.cb_fn = bs_sequence_completion;
104 : 38898 : set->cb_args.cb_arg = set;
105 : 38898 : set->cb_args.channel = channel->dev_channel;
106 : 38898 : set->ext_io_opts = NULL;
107 : :
108 : 38898 : return (spdk_bs_sequence_t *)set;
109 : : }
110 : :
111 : : /* Use when performing IO directly on the blobstore (e.g. metadata - not a blob). */
112 : : spdk_bs_sequence_t *
113 : 31260 : bs_sequence_start_bs(struct spdk_io_channel *_channel, struct spdk_bs_cpl *cpl)
114 : : {
115 : 31260 : return bs_sequence_start(_channel, cpl, _channel);
116 : : }
117 : :
118 : : /* Use when performing IO on a blob. */
119 : : spdk_bs_sequence_t *
120 : 7638 : bs_sequence_start_blob(struct spdk_io_channel *_channel, struct spdk_bs_cpl *cpl,
121 : : struct spdk_blob *blob)
122 : : {
123 : 7638 : struct spdk_io_channel *esnap_ch = _channel;
124 : :
125 [ + + ]: 7638 : if (spdk_blob_is_esnap_clone(blob)) {
126 : 3000 : esnap_ch = blob_esnap_get_io_channel(_channel, blob);
127 [ - + ]: 3000 : 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 : : }
140 : 7638 : return bs_sequence_start(_channel, cpl, esnap_ch);
141 : : }
142 : :
143 : : void
144 : 560 : 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 : 560 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)seq;
149 : 560 : struct spdk_io_channel *back_channel = set->back_channel;
150 : :
151 [ - + ]: 560 : SPDK_DEBUGLOG(blob_rw, "Reading %" PRIu32 " blocks from LBA %" PRIu64 "\n", lba_count,
152 : : lba);
153 : :
154 : 560 : set->u.sequence.cb_fn = cb_fn;
155 : 560 : set->u.sequence.cb_arg = cb_arg;
156 : :
157 : 560 : bs_dev->read(bs_dev, back_channel, payload, lba, lba_count, &set->cb_args);
158 : 560 : }
159 : :
160 : : void
161 : 28025 : 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 : 28025 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)seq;
166 : 28025 : struct spdk_bs_channel *channel = set->channel;
167 : :
168 [ - + ]: 28025 : SPDK_DEBUGLOG(blob_rw, "Reading %" PRIu32 " blocks from LBA %" PRIu64 "\n", lba_count,
169 : : lba);
170 : :
171 : 28025 : set->u.sequence.cb_fn = cb_fn;
172 : 28025 : set->u.sequence.cb_arg = cb_arg;
173 : :
174 : 28025 : channel->dev->read(channel->dev, channel->dev_channel, payload, lba, lba_count, &set->cb_args);
175 : 28025 : }
176 : :
177 : : void
178 : 17200 : 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 : 17200 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)seq;
183 : 17200 : struct spdk_bs_channel *channel = set->channel;
184 : :
185 [ - + ]: 17200 : SPDK_DEBUGLOG(blob_rw, "Writing %" PRIu32 " blocks from LBA %" PRIu64 "\n", lba_count,
186 : : lba);
187 : :
188 : 17200 : set->u.sequence.cb_fn = cb_fn;
189 : 17200 : set->u.sequence.cb_arg = cb_arg;
190 : :
191 : 17200 : channel->dev->write(channel->dev, channel->dev_channel, payload, lba, lba_count,
192 : : &set->cb_args);
193 : 17200 : }
194 : :
195 : : void
196 : 3124 : 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 : 3124 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)seq;
201 : 3124 : struct spdk_io_channel *back_channel = set->back_channel;
202 : :
203 [ - + ]: 3124 : SPDK_DEBUGLOG(blob_rw, "Reading %" PRIu32 " blocks from LBA %" PRIu64 "\n", lba_count,
204 : : lba);
205 : :
206 : 3124 : set->u.sequence.cb_fn = cb_fn;
207 : 3124 : set->u.sequence.cb_arg = cb_arg;
208 : :
209 [ + + ]: 3124 : if (set->ext_io_opts) {
210 [ - + ]: 180 : assert(bs_dev->readv_ext);
211 : 180 : bs_dev->readv_ext(bs_dev, back_channel, iov, iovcnt, lba, lba_count,
212 : : &set->cb_args, set->ext_io_opts);
213 : : } else {
214 : 2944 : bs_dev->readv(bs_dev, back_channel, iov, iovcnt, lba, lba_count, &set->cb_args);
215 : : }
216 : 3124 : }
217 : :
218 : : void
219 : 1699 : 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 : 1699 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)seq;
223 : 1699 : struct spdk_bs_channel *channel = set->channel;
224 : :
225 [ - + ]: 1699 : SPDK_DEBUGLOG(blob_rw, "Reading %" PRIu32 " blocks from LBA %" PRIu64 "\n", lba_count,
226 : : lba);
227 : :
228 : 1699 : set->u.sequence.cb_fn = cb_fn;
229 : 1699 : set->u.sequence.cb_arg = cb_arg;
230 [ + + ]: 1699 : if (set->ext_io_opts) {
231 [ - + ]: 1051 : assert(channel->dev->readv_ext);
232 : 1051 : channel->dev->readv_ext(channel->dev, channel->dev_channel, iov, iovcnt, lba, lba_count,
233 : : &set->cb_args, set->ext_io_opts);
234 : : } else {
235 : 648 : channel->dev->readv(channel->dev, channel->dev_channel, iov, iovcnt, lba, lba_count, &set->cb_args);
236 : : }
237 : 1699 : }
238 : :
239 : : void
240 : 829 : 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 : 829 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)seq;
245 : 829 : struct spdk_bs_channel *channel = set->channel;
246 : :
247 [ - + ]: 829 : SPDK_DEBUGLOG(blob_rw, "Writing %" PRIu32 " blocks from LBA %" PRIu64 "\n", lba_count,
248 : : lba);
249 : :
250 : 829 : set->u.sequence.cb_fn = cb_fn;
251 : 829 : set->u.sequence.cb_arg = cb_arg;
252 : :
253 [ + + ]: 829 : if (set->ext_io_opts) {
254 [ - + ]: 421 : assert(channel->dev->writev_ext);
255 : 421 : channel->dev->writev_ext(channel->dev, channel->dev_channel, iov, iovcnt, lba, lba_count,
256 : : &set->cb_args, set->ext_io_opts);
257 : : } else {
258 : 408 : channel->dev->writev(channel->dev, channel->dev_channel, iov, iovcnt, lba, lba_count,
259 : : &set->cb_args);
260 : : }
261 : 829 : }
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 : : &set->cb_args);
279 : 10 : }
280 : :
281 : : void
282 : 256 : 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 : 256 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)seq;
286 : 256 : struct spdk_bs_channel *channel = set->channel;
287 : :
288 [ - + ]: 256 : SPDK_DEBUGLOG(blob_rw, "Copying %" PRIu64 " blocks from LBA %" PRIu64 " to LBA %" PRIu64 "\n",
289 : : lba_count, src_lba, dst_lba);
290 : :
291 : 256 : set->u.sequence.cb_fn = cb_fn;
292 : 256 : set->u.sequence.cb_arg = cb_arg;
293 : :
294 : 256 : channel->dev->copy(channel->dev, channel->dev_channel, dst_lba, src_lba, lba_count, &set->cb_args);
295 : 256 : }
296 : :
297 : : void
298 : 38898 : bs_sequence_finish(spdk_bs_sequence_t *seq, int bserrno)
299 : : {
300 [ + + ]: 38898 : if (bserrno != 0) {
301 : 2074 : seq->bserrno = bserrno;
302 : : }
303 : 38898 : bs_request_set_complete((struct spdk_bs_request_set *)seq);
304 : 38898 : }
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 : 84038 : bs_batch_completion(struct spdk_io_channel *_channel,
316 : : void *cb_arg, int bserrno)
317 : : {
318 : 84038 : struct spdk_bs_request_set *set = cb_arg;
319 : :
320 : 84038 : set->u.batch.outstanding_ops--;
321 [ + + ]: 84038 : if (bserrno != 0) {
322 : 8 : set->bserrno = bserrno;
323 : : }
324 : :
325 [ + + + + ]: 84038 : if (set->u.batch.outstanding_ops == 0 && set->u.batch.batch_closed) {
326 [ + + ]: 80993 : if (set->u.batch.cb_fn) {
327 : 7875 : set->cb_args.cb_fn = bs_sequence_completion;
328 : 7875 : set->u.batch.cb_fn((spdk_bs_sequence_t *)set, set->u.batch.cb_arg, bserrno);
329 : : } else {
330 : 73118 : bs_request_set_complete(set);
331 : : }
332 : : }
333 : 84038 : }
334 : :
335 : : spdk_bs_batch_t *
336 : 74990 : bs_batch_open(struct spdk_io_channel *_channel, struct spdk_bs_cpl *cpl, struct spdk_blob *blob)
337 : : {
338 : : struct spdk_bs_channel *channel;
339 : : struct spdk_bs_request_set *set;
340 : 74990 : struct spdk_io_channel *back_channel = _channel;
341 : :
342 [ + + ]: 74990 : if (spdk_blob_is_esnap_clone(blob)) {
343 : 14680 : back_channel = blob_esnap_get_io_channel(_channel, blob);
344 [ - + ]: 14680 : if (back_channel == NULL) {
345 : 0 : return NULL;
346 : : }
347 : : }
348 : :
349 : 74990 : channel = spdk_io_channel_get_ctx(_channel);
350 [ - + ]: 74990 : assert(channel != NULL);
351 : 74990 : set = TAILQ_FIRST(&channel->reqs);
352 [ - + ]: 74990 : if (!set) {
353 : 0 : return NULL;
354 : : }
355 [ + - ]: 74990 : TAILQ_REMOVE(&channel->reqs, set, link);
356 : :
357 : 74990 : set->cpl = *cpl;
358 : 74990 : set->bserrno = 0;
359 : 74990 : set->channel = channel;
360 : 74990 : set->back_channel = back_channel;
361 : :
362 : 74990 : set->u.batch.cb_fn = NULL;
363 : 74990 : set->u.batch.cb_arg = NULL;
364 : 74990 : set->u.batch.outstanding_ops = 0;
365 : 74990 : set->u.batch.batch_closed = 0;
366 : :
367 : 74990 : set->cb_args.cb_fn = bs_batch_completion;
368 : 74990 : set->cb_args.cb_arg = set;
369 : 74990 : set->cb_args.channel = channel->dev_channel;
370 : :
371 : 74990 : return (spdk_bs_batch_t *)set;
372 : : }
373 : :
374 : : void
375 : 2176 : bs_batch_read_bs_dev(spdk_bs_batch_t *batch, struct spdk_bs_dev *bs_dev,
376 : : void *payload, uint64_t lba, uint32_t lba_count)
377 : : {
378 : 2176 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)batch;
379 : 2176 : struct spdk_io_channel *back_channel = set->back_channel;
380 : :
381 [ - + ]: 2176 : SPDK_DEBUGLOG(blob_rw, "Reading %" PRIu32 " blocks from LBA %" PRIu64 "\n", lba_count,
382 : : lba);
383 : :
384 : 2176 : set->u.batch.outstanding_ops++;
385 : 2176 : bs_dev->read(bs_dev, back_channel, payload, lba, lba_count, &set->cb_args);
386 : 2176 : }
387 : :
388 : : void
389 : 31702 : bs_batch_read_dev(spdk_bs_batch_t *batch, void *payload,
390 : : uint64_t lba, uint32_t lba_count)
391 : : {
392 : 31702 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)batch;
393 : 31702 : struct spdk_bs_channel *channel = set->channel;
394 : :
395 [ - + ]: 31702 : SPDK_DEBUGLOG(blob_rw, "Reading %" PRIu32 " blocks from LBA %" PRIu64 "\n", lba_count,
396 : : lba);
397 : :
398 : 31702 : set->u.batch.outstanding_ops++;
399 : 31702 : channel->dev->read(channel->dev, channel->dev_channel, payload, lba, lba_count, &set->cb_args);
400 : 31702 : }
401 : :
402 : : void
403 : 41126 : bs_batch_write_dev(spdk_bs_batch_t *batch, void *payload,
404 : : uint64_t lba, uint32_t lba_count)
405 : : {
406 : 41126 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)batch;
407 : 41126 : struct spdk_bs_channel *channel = set->channel;
408 : :
409 [ - + ]: 41126 : SPDK_DEBUGLOG(blob_rw, "Writing %" PRIu32 " blocks to LBA %" PRIu64 "\n", lba_count, lba);
410 : :
411 : 41126 : set->u.batch.outstanding_ops++;
412 : 41126 : channel->dev->write(channel->dev, channel->dev_channel, payload, lba, lba_count,
413 : : &set->cb_args);
414 : 41126 : }
415 : :
416 : : void
417 : 3641 : bs_batch_unmap_dev(spdk_bs_batch_t *batch,
418 : : uint64_t lba, uint64_t lba_count)
419 : : {
420 : 3641 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)batch;
421 : 3641 : struct spdk_bs_channel *channel = set->channel;
422 : :
423 [ - + ]: 3641 : SPDK_DEBUGLOG(blob_rw, "Unmapping %" PRIu64 " blocks at LBA %" PRIu64 "\n", lba_count,
424 : : lba);
425 : :
426 : 3641 : set->u.batch.outstanding_ops++;
427 : 3641 : channel->dev->unmap(channel->dev, channel->dev_channel, lba, lba_count,
428 : : &set->cb_args);
429 : 3641 : }
430 : :
431 : : void
432 : 5393 : bs_batch_write_zeroes_dev(spdk_bs_batch_t *batch,
433 : : uint64_t lba, uint64_t lba_count)
434 : : {
435 : 5393 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)batch;
436 : 5393 : struct spdk_bs_channel *channel = set->channel;
437 : :
438 [ - + ]: 5393 : SPDK_DEBUGLOG(blob_rw, "Zeroing %" PRIu64 " blocks at LBA %" PRIu64 "\n", lba_count, lba);
439 : :
440 : 5393 : set->u.batch.outstanding_ops++;
441 : 5393 : channel->dev->write_zeroes(channel->dev, channel->dev_channel, lba, lba_count,
442 : : &set->cb_args);
443 : 5393 : }
444 : :
445 : : void
446 : 113681 : bs_batch_close(spdk_bs_batch_t *batch)
447 : : {
448 : 113681 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)batch;
449 : :
450 : 113681 : set->u.batch.batch_closed = 1;
451 : :
452 [ + + ]: 113681 : if (set->u.batch.outstanding_ops == 0) {
453 [ + + ]: 32688 : if (set->u.batch.cb_fn) {
454 : 30816 : set->cb_args.cb_fn = bs_sequence_completion;
455 : 30816 : set->u.batch.cb_fn((spdk_bs_sequence_t *)set, set->u.batch.cb_arg, set->bserrno);
456 : : } else {
457 : 1872 : bs_request_set_complete(set);
458 : : }
459 : : }
460 : 113681 : }
461 : :
462 : : spdk_bs_batch_t *
463 : 38691 : bs_sequence_to_batch(spdk_bs_sequence_t *seq, spdk_bs_sequence_cpl cb_fn, void *cb_arg)
464 : : {
465 : 38691 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)seq;
466 : :
467 : 38691 : set->u.batch.cb_fn = cb_fn;
468 : 38691 : set->u.batch.cb_arg = cb_arg;
469 : 38691 : set->u.batch.outstanding_ops = 0;
470 : 38691 : set->u.batch.batch_closed = 0;
471 : :
472 : 38691 : set->cb_args.cb_fn = bs_batch_completion;
473 : :
474 : 38691 : return set;
475 : : }
476 : :
477 : : spdk_bs_user_op_t *
478 : 1888 : bs_user_op_alloc(struct spdk_io_channel *_channel, struct spdk_bs_cpl *cpl,
479 : : enum spdk_blob_op_type op_type, struct spdk_blob *blob,
480 : : void *payload, int iovcnt, uint64_t offset, uint64_t length)
481 : : {
482 : : struct spdk_bs_channel *channel;
483 : : struct spdk_bs_request_set *set;
484 : : struct spdk_bs_user_op_args *args;
485 : :
486 : 1888 : channel = spdk_io_channel_get_ctx(_channel);
487 [ - + ]: 1888 : assert(channel != NULL);
488 : 1888 : set = TAILQ_FIRST(&channel->reqs);
489 [ - + ]: 1888 : if (!set) {
490 : 0 : return NULL;
491 : : }
492 [ + - ]: 1888 : TAILQ_REMOVE(&channel->reqs, set, link);
493 : :
494 : 1888 : set->cpl = *cpl;
495 : 1888 : set->channel = channel;
496 : 1888 : set->back_channel = NULL;
497 : 1888 : set->ext_io_opts = NULL;
498 : :
499 : 1888 : args = &set->u.user_op;
500 : :
501 : 1888 : args->type = op_type;
502 : 1888 : args->iovcnt = iovcnt;
503 : 1888 : args->blob = blob;
504 : 1888 : args->offset = offset;
505 : 1888 : args->length = length;
506 : 1888 : args->payload = payload;
507 : :
508 : 1888 : return (spdk_bs_user_op_t *)set;
509 : : }
510 : :
511 : : void
512 : 1888 : bs_user_op_execute(spdk_bs_user_op_t *op)
513 : : {
514 : : struct spdk_bs_request_set *set;
515 : : struct spdk_bs_user_op_args *args;
516 : : struct spdk_io_channel *ch;
517 : :
518 : 1888 : set = (struct spdk_bs_request_set *)op;
519 : 1888 : args = &set->u.user_op;
520 : 1888 : ch = spdk_io_channel_from_ctx(set->channel);
521 : :
522 [ + + - - : 1888 : switch (args->type) {
- + - ]
523 : 904 : case SPDK_BLOB_READ:
524 : 904 : spdk_blob_io_read(args->blob, ch, args->payload, args->offset, args->length,
525 : : set->cpl.u.blob_basic.cb_fn, set->cpl.u.blob_basic.cb_arg);
526 : 904 : break;
527 : 696 : case SPDK_BLOB_WRITE:
528 : 696 : spdk_blob_io_write(args->blob, ch, args->payload, args->offset, args->length,
529 : : set->cpl.u.blob_basic.cb_fn, set->cpl.u.blob_basic.cb_arg);
530 : 696 : break;
531 : 0 : case SPDK_BLOB_UNMAP:
532 : 0 : spdk_blob_io_unmap(args->blob, ch, args->offset, args->length,
533 : : set->cpl.u.blob_basic.cb_fn, set->cpl.u.blob_basic.cb_arg);
534 : 0 : break;
535 : 0 : case SPDK_BLOB_WRITE_ZEROES:
536 : 0 : spdk_blob_io_write_zeroes(args->blob, ch, args->offset, args->length,
537 : : set->cpl.u.blob_basic.cb_fn, set->cpl.u.blob_basic.cb_arg);
538 : 0 : break;
539 : 0 : case SPDK_BLOB_READV:
540 : 0 : spdk_blob_io_readv_ext(args->blob, ch, args->payload, args->iovcnt,
541 : : args->offset, args->length,
542 : : set->cpl.u.blob_basic.cb_fn, set->cpl.u.blob_basic.cb_arg,
543 : : set->ext_io_opts);
544 : 0 : break;
545 : 288 : case SPDK_BLOB_WRITEV:
546 : 288 : spdk_blob_io_writev_ext(args->blob, ch, args->payload, args->iovcnt,
547 : : args->offset, args->length,
548 : : set->cpl.u.blob_basic.cb_fn, set->cpl.u.blob_basic.cb_arg,
549 : : set->ext_io_opts);
550 : 288 : break;
551 : : }
552 : 1888 : TAILQ_INSERT_TAIL(&set->channel->reqs, set, link);
553 : 1888 : }
554 : :
555 : : void
556 : 0 : bs_user_op_abort(spdk_bs_user_op_t *op, int bserrno)
557 : : {
558 : : struct spdk_bs_request_set *set;
559 : :
560 : 0 : set = (struct spdk_bs_request_set *)op;
561 : :
562 : 0 : set->cpl.u.blob_basic.cb_fn(set->cpl.u.blob_basic.cb_arg, bserrno);
563 : 0 : TAILQ_INSERT_TAIL(&set->channel->reqs, set, link);
564 : 0 : }
565 : :
566 : 493 : SPDK_LOG_REGISTER_COMPONENT(blob_rw)
|