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 : :
15 : : #include "spdk/log.h"
16 : :
17 : : void
18 : 6222888 : bs_call_cpl(struct spdk_bs_cpl *cpl, int bserrno)
19 : : {
20 [ + + + + : 6222888 : switch (cpl->type) {
+ - + - ]
21 : 3179 : case SPDK_BS_CPL_TYPE_BS_BASIC:
22 : 3179 : cpl->u.bs_basic.cb_fn(cpl->u.bs_basic.cb_arg,
23 : : bserrno);
24 : 3179 : break;
25 : 10509 : case SPDK_BS_CPL_TYPE_BS_HANDLE:
26 [ + + ]: 10509 : cpl->u.bs_handle.cb_fn(cpl->u.bs_handle.cb_arg,
27 : : bserrno == 0 ? cpl->u.bs_handle.bs : NULL,
28 : : bserrno);
29 : 10509 : break;
30 : 6170258 : case SPDK_BS_CPL_TYPE_BLOB_BASIC:
31 : 6170258 : cpl->u.blob_basic.cb_fn(cpl->u.blob_basic.cb_arg,
32 : : bserrno);
33 : 6170258 : break;
34 : 8584 : case SPDK_BS_CPL_TYPE_BLOBID:
35 [ + + ]: 8584 : cpl->u.blobid.cb_fn(cpl->u.blobid.cb_arg,
36 : : bserrno == 0 ? cpl->u.blobid.blobid : SPDK_BLOBID_INVALID,
37 : : bserrno);
38 : 8584 : break;
39 : 19832 : case SPDK_BS_CPL_TYPE_BLOB_HANDLE:
40 [ + + ]: 19832 : cpl->u.blob_handle.cb_fn(cpl->u.blob_handle.cb_arg,
41 : : bserrno == 0 ? cpl->u.blob_handle.blob : NULL,
42 : : bserrno);
43 : 19832 : 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 : 10526 : case SPDK_BS_CPL_TYPE_NONE:
50 : : /* this completion's callback is handled elsewhere */
51 : 10526 : break;
52 : : }
53 : 6222888 : }
54 : :
55 : : static void
56 : 6212362 : bs_request_set_complete(struct spdk_bs_request_set *set)
57 : : {
58 : 6212362 : struct spdk_bs_cpl cpl = set->cpl;
59 : 6212362 : int bserrno = set->bserrno;
60 : :
61 : 6212362 : TAILQ_INSERT_TAIL(&set->channel->reqs, set, link);
62 : :
63 : 6212362 : bs_call_cpl(&cpl, bserrno);
64 : 6212362 : }
65 : :
66 : : static void
67 : 4938133 : bs_sequence_completion(struct spdk_io_channel *channel, void *cb_arg, int bserrno)
68 : : {
69 : 4938133 : struct spdk_bs_request_set *set = cb_arg;
70 : :
71 : 4938133 : set->bserrno = bserrno;
72 : 4938133 : set->u.sequence.cb_fn((spdk_bs_sequence_t *)set, set->u.sequence.cb_arg, bserrno);
73 : 4938133 : }
74 : :
75 : : static inline spdk_bs_sequence_t *
76 : 4915409 : 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 : 4915409 : channel = spdk_io_channel_get_ctx(_channel);
83 [ - + ]: 4915409 : assert(channel != NULL);
84 : 4915409 : set = TAILQ_FIRST(&channel->reqs);
85 [ + + ]: 4915409 : if (!set) {
86 : 32794 : return NULL;
87 : : }
88 [ + + ]: 4882615 : TAILQ_REMOVE(&channel->reqs, set, link);
89 : :
90 : 4882615 : set->cpl = *cpl;
91 : 4882615 : set->bserrno = 0;
92 : 4882615 : set->channel = channel;
93 : 4882615 : set->back_channel = back_channel;
94 : :
95 : 4882615 : set->cb_args.cb_fn = bs_sequence_completion;
96 : 4882615 : set->cb_args.cb_arg = set;
97 : 4882615 : set->cb_args.channel = channel->dev_channel;
98 : 4882615 : set->ext_io_opts = NULL;
99 : :
100 : 4882615 : 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 : 119024 : bs_sequence_start_bs(struct spdk_io_channel *_channel, struct spdk_bs_cpl *cpl)
106 : : {
107 : 119024 : return bs_sequence_start(_channel, cpl, _channel);
108 : : }
109 : :
110 : : /* Use when performing IO on a blob. */
111 : : spdk_bs_sequence_t *
112 : 4796385 : bs_sequence_start_blob(struct spdk_io_channel *_channel, struct spdk_bs_cpl *cpl,
113 : : struct spdk_blob *blob)
114 : : {
115 : 4796385 : struct spdk_io_channel *esnap_ch = _channel;
116 : :
117 [ + + ]: 4796385 : if (spdk_blob_is_esnap_clone(blob)) {
118 : 19775 : esnap_ch = blob_esnap_get_io_channel(_channel, blob);
119 [ - + ]: 19775 : 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 : 4796385 : return bs_sequence_start(_channel, cpl, esnap_ch);
133 : : }
134 : :
135 : : void
136 : 1175 : 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 : 1175 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)seq;
141 : 1175 : struct spdk_io_channel *back_channel = set->back_channel;
142 : :
143 [ - + - + ]: 1175 : SPDK_DEBUGLOG(blob_rw, "Reading %" PRIu32 " blocks from LBA %" PRIu64 "\n", lba_count,
144 : : lba);
145 : :
146 : 1175 : set->u.sequence.cb_fn = cb_fn;
147 : 1175 : set->u.sequence.cb_arg = cb_arg;
148 : :
149 : 1175 : bs_dev->read(bs_dev, back_channel, payload, lba, lba_count, &set->cb_args);
150 : 1175 : }
151 : :
152 : : void
153 : 76136 : 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 : 76136 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)seq;
158 : 76136 : struct spdk_bs_channel *channel = set->channel;
159 : :
160 [ - + - + ]: 76136 : SPDK_DEBUGLOG(blob_rw, "Reading %" PRIu32 " blocks from LBA %" PRIu64 "\n", lba_count,
161 : : lba);
162 : :
163 : 76136 : set->u.sequence.cb_fn = cb_fn;
164 : 76136 : set->u.sequence.cb_arg = cb_arg;
165 : :
166 : 76136 : channel->dev->read(channel->dev, channel->dev_channel, payload, lba, lba_count, &set->cb_args);
167 : 76136 : }
168 : :
169 : : void
170 : 102320 : 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 : 102320 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)seq;
175 : 102320 : struct spdk_bs_channel *channel = set->channel;
176 : :
177 [ - + - + ]: 102320 : SPDK_DEBUGLOG(blob_rw, "Writing %" PRIu32 " blocks from LBA %" PRIu64 "\n", lba_count,
178 : : lba);
179 : :
180 : 102320 : set->u.sequence.cb_fn = cb_fn;
181 : 102320 : set->u.sequence.cb_arg = cb_arg;
182 : :
183 : 102320 : channel->dev->write(channel->dev, channel->dev_channel, payload, lba, lba_count,
184 : : &set->cb_args);
185 : 102320 : }
186 : :
187 : : void
188 : 896718 : 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 : 896718 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)seq;
193 : 896718 : struct spdk_io_channel *back_channel = set->back_channel;
194 : :
195 [ - + - + ]: 896718 : SPDK_DEBUGLOG(blob_rw, "Reading %" PRIu32 " blocks from LBA %" PRIu64 "\n", lba_count,
196 : : lba);
197 : :
198 : 896718 : set->u.sequence.cb_fn = cb_fn;
199 : 896718 : set->u.sequence.cb_arg = cb_arg;
200 : :
201 [ + + ]: 896718 : if (set->ext_io_opts) {
202 [ - + ]: 890830 : assert(bs_dev->readv_ext);
203 : 890830 : bs_dev->readv_ext(bs_dev, back_channel, iov, iovcnt, lba, lba_count,
204 : : &set->cb_args, set->ext_io_opts);
205 : : } else {
206 : 5888 : bs_dev->readv(bs_dev, back_channel, iov, iovcnt, lba, lba_count, &set->cb_args);
207 : : }
208 : 896718 : }
209 : :
210 : : void
211 : 1410881 : 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 : 1410881 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)seq;
215 : 1410881 : struct spdk_bs_channel *channel = set->channel;
216 : :
217 [ - + - + ]: 1410881 : SPDK_DEBUGLOG(blob_rw, "Reading %" PRIu32 " blocks from LBA %" PRIu64 "\n", lba_count,
218 : : lba);
219 : :
220 : 1410881 : set->u.sequence.cb_fn = cb_fn;
221 : 1410881 : set->u.sequence.cb_arg = cb_arg;
222 [ + + ]: 1410881 : if (set->ext_io_opts) {
223 [ - + ]: 1409585 : assert(channel->dev->readv_ext);
224 : 1409585 : 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 : 1296 : channel->dev->readv(channel->dev, channel->dev_channel, iov, iovcnt, lba, lba_count, &set->cb_args);
228 : : }
229 : 1410881 : }
230 : :
231 : : void
232 : 2450224 : 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 : 2450224 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)seq;
237 : 2450224 : struct spdk_bs_channel *channel = set->channel;
238 : :
239 [ - + - + ]: 2450224 : SPDK_DEBUGLOG(blob_rw, "Writing %" PRIu32 " blocks from LBA %" PRIu64 "\n", lba_count,
240 : : lba);
241 : :
242 : 2450224 : set->u.sequence.cb_fn = cb_fn;
243 : 2450224 : set->u.sequence.cb_arg = cb_arg;
244 : :
245 [ + + ]: 2450224 : if (set->ext_io_opts) {
246 [ - + ]: 2447805 : assert(channel->dev->writev_ext);
247 : 2447805 : 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 : 2419 : channel->dev->writev(channel->dev, channel->dev_channel, iov, iovcnt, lba, lba_count,
251 : : &set->cb_args);
252 : : }
253 : 2450224 : }
254 : :
255 : : void
256 : 113 : 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 : 113 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)seq;
261 : 113 : struct spdk_bs_channel *channel = set->channel;
262 : :
263 [ - + - + ]: 113 : SPDK_DEBUGLOG(blob_rw, "writing zeroes to %" PRIu64 " blocks at LBA %" PRIu64 "\n",
264 : : lba_count, lba);
265 : :
266 : 113 : set->u.sequence.cb_fn = cb_fn;
267 : 113 : set->u.sequence.cb_arg = cb_arg;
268 : :
269 : 113 : channel->dev->write_zeroes(channel->dev, channel->dev_channel, lba, lba_count,
270 : : &set->cb_args);
271 : 113 : }
272 : :
273 : : void
274 : 566 : 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 : 566 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)seq;
278 : 566 : struct spdk_bs_channel *channel = set->channel;
279 : :
280 [ - + - + ]: 566 : SPDK_DEBUGLOG(blob_rw, "Copying %" PRIu64 " blocks from LBA %" PRIu64 " to LBA %" PRIu64 "\n",
281 : : lba_count, src_lba, dst_lba);
282 : :
283 : 566 : set->u.sequence.cb_fn = cb_fn;
284 : 566 : set->u.sequence.cb_arg = cb_arg;
285 : :
286 : 566 : channel->dev->copy(channel->dev, channel->dev_channel, dst_lba, src_lba, lba_count, &set->cb_args);
287 : 566 : }
288 : :
289 : : void
290 : 4882615 : bs_sequence_finish(spdk_bs_sequence_t *seq, int bserrno)
291 : : {
292 [ + + ]: 4882615 : if (bserrno != 0) {
293 : 7840 : seq->bserrno = bserrno;
294 : : }
295 : 4882615 : bs_request_set_complete((struct spdk_bs_request_set *)seq);
296 : 4882615 : }
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 : 1352330 : bs_batch_completion(struct spdk_io_channel *_channel,
308 : : void *cb_arg, int bserrno)
309 : : {
310 : 1352330 : struct spdk_bs_request_set *set = cb_arg;
311 : :
312 : 1352330 : set->u.batch.outstanding_ops--;
313 [ + + ]: 1352330 : if (bserrno != 0) {
314 : 16 : set->bserrno = bserrno;
315 : : }
316 : :
317 [ + + + + ]: 1352330 : if (set->u.batch.outstanding_ops == 0 && set->u.batch.batch_closed) {
318 [ + + ]: 1211708 : if (set->u.batch.cb_fn) {
319 : 17481 : set->cb_args.cb_fn = bs_sequence_completion;
320 : 17481 : set->u.batch.cb_fn((spdk_bs_sequence_t *)set, set->u.batch.cb_arg, bserrno);
321 : : } else {
322 : 1194227 : bs_request_set_complete(set);
323 : : }
324 : : }
325 : 1352330 : }
326 : :
327 : : spdk_bs_batch_t *
328 : 1329747 : 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 : 1329747 : struct spdk_io_channel *back_channel = _channel;
333 : :
334 [ + + ]: 1329747 : if (spdk_blob_is_esnap_clone(blob)) {
335 : 29360 : back_channel = blob_esnap_get_io_channel(_channel, blob);
336 [ - + ]: 29360 : if (back_channel == NULL) {
337 : 0 : return NULL;
338 : : }
339 : : }
340 : :
341 : 1329747 : channel = spdk_io_channel_get_ctx(_channel);
342 [ - + ]: 1329747 : assert(channel != NULL);
343 : 1329747 : set = TAILQ_FIRST(&channel->reqs);
344 [ - + ]: 1329747 : if (!set) {
345 : 0 : return NULL;
346 : : }
347 [ + - ]: 1329747 : TAILQ_REMOVE(&channel->reqs, set, link);
348 : :
349 : 1329747 : set->cpl = *cpl;
350 : 1329747 : set->bserrno = 0;
351 : 1329747 : set->channel = channel;
352 : 1329747 : set->back_channel = back_channel;
353 : :
354 : 1329747 : set->u.batch.cb_fn = NULL;
355 : 1329747 : set->u.batch.cb_arg = NULL;
356 : 1329747 : set->u.batch.outstanding_ops = 0;
357 : 1329747 : set->u.batch.batch_closed = 0;
358 : :
359 : 1329747 : set->cb_args.cb_fn = bs_batch_completion;
360 : 1329747 : set->cb_args.cb_arg = set;
361 : 1329747 : set->cb_args.channel = channel->dev_channel;
362 : :
363 : 1329747 : return (spdk_bs_batch_t *)set;
364 : : }
365 : :
366 : : void
367 : 4352 : 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 : 4352 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)batch;
371 : 4352 : struct spdk_io_channel *back_channel = set->back_channel;
372 : :
373 [ - + - + ]: 4352 : SPDK_DEBUGLOG(blob_rw, "Reading %" PRIu32 " blocks from LBA %" PRIu64 "\n", lba_count,
374 : : lba);
375 : :
376 : 4352 : set->u.batch.outstanding_ops++;
377 : 4352 : bs_dev->read(bs_dev, back_channel, payload, lba, lba_count, &set->cb_args);
378 : 4352 : }
379 : :
380 : : void
381 : 918166 : bs_batch_read_dev(spdk_bs_batch_t *batch, void *payload,
382 : : uint64_t lba, uint32_t lba_count)
383 : : {
384 : 918166 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)batch;
385 : 918166 : struct spdk_bs_channel *channel = set->channel;
386 : :
387 [ - + - + ]: 918166 : SPDK_DEBUGLOG(blob_rw, "Reading %" PRIu32 " blocks from LBA %" PRIu64 "\n", lba_count,
388 : : lba);
389 : :
390 : 918166 : set->u.batch.outstanding_ops++;
391 : 918166 : channel->dev->read(channel->dev, channel->dev_channel, payload, lba, lba_count, &set->cb_args);
392 : 918166 : }
393 : :
394 : : void
395 : 268608 : bs_batch_write_dev(spdk_bs_batch_t *batch, void *payload,
396 : : uint64_t lba, uint32_t lba_count)
397 : : {
398 : 268608 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)batch;
399 : 268608 : struct spdk_bs_channel *channel = set->channel;
400 : :
401 [ - + - + ]: 268608 : SPDK_DEBUGLOG(blob_rw, "Writing %" PRIu32 " blocks to LBA %" PRIu64 "\n", lba_count, lba);
402 : :
403 : 268608 : set->u.batch.outstanding_ops++;
404 : 268608 : channel->dev->write(channel->dev, channel->dev_channel, payload, lba, lba_count,
405 : : &set->cb_args);
406 : 268608 : }
407 : :
408 : : void
409 : 147351 : bs_batch_unmap_dev(spdk_bs_batch_t *batch,
410 : : uint64_t lba, uint64_t lba_count)
411 : : {
412 : 147351 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)batch;
413 : 147351 : struct spdk_bs_channel *channel = set->channel;
414 : :
415 [ - + - + ]: 147351 : SPDK_DEBUGLOG(blob_rw, "Unmapping %" PRIu64 " blocks at LBA %" PRIu64 "\n", lba_count,
416 : : lba);
417 : :
418 : 147351 : set->u.batch.outstanding_ops++;
419 : 147351 : channel->dev->unmap(channel->dev, channel->dev_channel, lba, lba_count,
420 : : &set->cb_args);
421 : 147351 : }
422 : :
423 : : void
424 : 13853 : bs_batch_write_zeroes_dev(spdk_bs_batch_t *batch,
425 : : uint64_t lba, uint64_t lba_count)
426 : : {
427 : 13853 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)batch;
428 : 13853 : struct spdk_bs_channel *channel = set->channel;
429 : :
430 [ - + - + ]: 13853 : SPDK_DEBUGLOG(blob_rw, "Zeroing %" PRIu64 " blocks at LBA %" PRIu64 "\n", lba_count, lba);
431 : :
432 : 13853 : set->u.batch.outstanding_ops++;
433 : 13853 : channel->dev->write_zeroes(channel->dev, channel->dev_channel, lba, lba_count,
434 : : &set->cb_args);
435 : 13853 : }
436 : :
437 : : void
438 : 1564237 : bs_batch_close(spdk_bs_batch_t *batch)
439 : : {
440 : 1564237 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)batch;
441 : :
442 : 1564237 : set->u.batch.batch_closed = 1;
443 : :
444 [ + + ]: 1564237 : if (set->u.batch.outstanding_ops == 0) {
445 [ + + ]: 352529 : if (set->u.batch.cb_fn) {
446 : 217009 : set->cb_args.cb_fn = bs_sequence_completion;
447 : 217009 : set->u.batch.cb_fn((spdk_bs_sequence_t *)set, set->u.batch.cb_arg, set->bserrno);
448 : : } else {
449 : 135520 : bs_request_set_complete(set);
450 : : }
451 : : }
452 : 1564237 : }
453 : :
454 : : spdk_bs_batch_t *
455 : 234490 : bs_sequence_to_batch(spdk_bs_sequence_t *seq, spdk_bs_sequence_cpl cb_fn, void *cb_arg)
456 : : {
457 : 234490 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)seq;
458 : :
459 : 234490 : set->u.batch.cb_fn = cb_fn;
460 : 234490 : set->u.batch.cb_arg = cb_arg;
461 : 234490 : set->u.batch.outstanding_ops = 0;
462 : 234490 : set->u.batch.batch_closed = 0;
463 : :
464 : 234490 : set->cb_args.cb_fn = bs_batch_completion;
465 : :
466 : 234490 : return set;
467 : : }
468 : :
469 : : spdk_bs_user_op_t *
470 : 19868 : 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 : 19868 : channel = spdk_io_channel_get_ctx(_channel);
479 [ - + ]: 19868 : assert(channel != NULL);
480 : 19868 : set = TAILQ_FIRST(&channel->reqs);
481 [ - + ]: 19868 : if (!set) {
482 : 0 : return NULL;
483 : : }
484 [ + - ]: 19868 : TAILQ_REMOVE(&channel->reqs, set, link);
485 : :
486 : 19868 : set->cpl = *cpl;
487 : 19868 : set->channel = channel;
488 : 19868 : set->back_channel = NULL;
489 : 19868 : set->ext_io_opts = NULL;
490 : :
491 : 19868 : args = &set->u.user_op;
492 : :
493 : 19868 : args->type = op_type;
494 : 19868 : args->iovcnt = iovcnt;
495 : 19868 : args->blob = blob;
496 : 19868 : args->offset = offset;
497 : 19868 : args->length = length;
498 : 19868 : args->payload = payload;
499 : :
500 : 19868 : return (spdk_bs_user_op_t *)set;
501 : : }
502 : :
503 : : void
504 : 19867 : 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 : 19867 : set = (struct spdk_bs_request_set *)op;
511 : 19867 : args = &set->u.user_op;
512 : 19867 : ch = spdk_io_channel_from_ctx(set->channel);
513 : :
514 [ + + - - : 19867 : switch (args->type) {
- + - ]
515 : 1836 : case SPDK_BLOB_READ:
516 : 1836 : 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 : 1836 : break;
519 : 1404 : case SPDK_BLOB_WRITE:
520 : 1404 : 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 : 1404 : 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 : 16627 : case SPDK_BLOB_WRITEV:
538 : 16627 : 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 : 16627 : break;
543 : : }
544 : 19867 : TAILQ_INSERT_TAIL(&set->channel->reqs, set, link);
545 : 19867 : }
546 : :
547 : : void
548 : 1 : bs_user_op_abort(spdk_bs_user_op_t *op, int bserrno)
549 : : {
550 : : struct spdk_bs_request_set *set;
551 : :
552 : 1 : set = (struct spdk_bs_request_set *)op;
553 : :
554 : 1 : set->cpl.u.blob_basic.cb_fn(set->cpl.u.blob_basic.cb_arg, bserrno);
555 : 1 : TAILQ_INSERT_TAIL(&set->channel->reqs, set, link);
556 : 1 : }
557 : :
558 : 2345 : SPDK_LOG_REGISTER_COMPONENT(blob_rw)
|