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 : 22452661 : bs_call_cpl(struct spdk_bs_cpl *cpl, int bserrno)
19 : : {
20 [ + + + + : 22452661 : switch (cpl->type) {
+ + + + +
+ - + ]
21 : 3796 : case SPDK_BS_CPL_TYPE_BS_BASIC:
22 [ + - + - : 4466 : cpl->u.bs_basic.cb_fn(cpl->u.bs_basic.cb_arg,
+ - + - -
+ + - + -
+ - + - +
- ]
23 : 670 : bserrno);
24 : 4466 : break;
25 : 9237 : case SPDK_BS_CPL_TYPE_BS_HANDLE:
26 [ + + + - : 10823 : cpl->u.bs_handle.cb_fn(cpl->u.bs_handle.cb_arg,
+ - + - -
+ + - + -
+ - + - +
- ]
27 [ + + + - : 793 : bserrno == 0 ? cpl->u.bs_handle.bs : NULL,
+ - + - +
- ]
28 : 793 : bserrno);
29 : 10030 : break;
30 : 22341103 : case SPDK_BS_CPL_TYPE_BLOB_BASIC:
31 [ + - + - : 22376155 : cpl->u.blob_basic.cb_fn(cpl->u.blob_basic.cb_arg,
+ - + - -
+ + - + -
+ - + - +
- ]
32 : 35052 : bserrno);
33 : 22376155 : break;
34 : 11761 : case SPDK_BS_CPL_TYPE_BLOBID:
35 [ + + + - : 15333 : cpl->u.blobid.cb_fn(cpl->u.blobid.cb_arg,
+ - + - -
+ + - + -
+ - + - +
- ]
36 [ + + + - : 1786 : bserrno == 0 ? cpl->u.blobid.blobid : SPDK_BLOBID_INVALID,
+ - + - +
- ]
37 : 1786 : bserrno);
38 : 13547 : break;
39 : 35130 : case SPDK_BS_CPL_TYPE_BLOB_HANDLE:
40 [ + + + - : 41686 : cpl->u.blob_handle.cb_fn(cpl->u.blob_handle.cb_arg,
+ - + - -
+ + - + -
+ - + - +
- ]
41 [ + + - + : 3278 : bserrno == 0 ? cpl->u.blob_handle.blob : NULL,
- + - + -
+ ]
42 : 3278 : bserrno);
43 : 38408 : 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 [ # # # # : 0 : cpl->u.nested_seq.parent,
# # # # ]
47 : 0 : bserrno);
48 : 0 : break;
49 : 9258 : case SPDK_BS_CPL_TYPE_NONE:
50 : : /* this completion's callback is handled elsewhere */
51 : 10055 : break;
52 : : }
53 : 22452661 : }
54 : :
55 : : static void
56 : 22442606 : bs_request_set_complete(struct spdk_bs_request_set *set)
57 : : {
58 [ + - ]: 22442606 : struct spdk_bs_cpl cpl = set->cpl;
59 [ + - + - ]: 22442606 : int bserrno = set->bserrno;
60 : :
61 [ + - + - : 22442606 : TAILQ_INSERT_TAIL(&set->channel->reqs, set, link);
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - ]
62 : :
63 : 22442606 : bs_call_cpl(&cpl, bserrno);
64 : 22442606 : }
65 : :
66 : : static void
67 : 16531006 : bs_sequence_completion(struct spdk_io_channel *channel, void *cb_arg, int bserrno)
68 : : {
69 : 16531006 : struct spdk_bs_request_set *set = cb_arg;
70 : :
71 [ + - + - ]: 16531006 : set->bserrno = bserrno;
72 [ + - + - : 16531006 : set->u.sequence.cb_fn((spdk_bs_sequence_t *)set, set->u.sequence.cb_arg, bserrno);
+ - + - -
+ + - + -
+ - + - +
- ]
73 : 16531006 : }
74 : :
75 : : static inline spdk_bs_sequence_t *
76 : 16462214 : bs_sequence_start(struct spdk_io_channel *_channel, struct spdk_bs_cpl *cpl,
77 : : struct spdk_io_channel *back_channel)
78 : : {
79 : 16580 : struct spdk_bs_channel *channel;
80 : 16580 : struct spdk_bs_request_set *set;
81 : :
82 : 16462214 : channel = spdk_io_channel_get_ctx(_channel);
83 [ + + # # ]: 16462214 : assert(channel != NULL);
84 [ + - + - : 16462214 : set = TAILQ_FIRST(&channel->reqs);
+ - ]
85 [ + + ]: 16462214 : if (!set) {
86 : 72850 : return NULL;
87 : : }
88 [ + + + - : 16389364 : TAILQ_REMOVE(&channel->reqs, set, link);
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - # # #
# # # # #
# # # # +
- + - + -
+ - + - +
- + - ]
89 : :
90 [ + - ]: 16389364 : set->cpl = *cpl;
91 [ + - + - ]: 16389364 : set->bserrno = 0;
92 [ + - + - ]: 16389364 : set->channel = channel;
93 [ + - + - ]: 16389364 : set->back_channel = back_channel;
94 : :
95 [ + - + - : 16389364 : set->cb_args.cb_fn = bs_sequence_completion;
+ - ]
96 [ + - + - : 16389364 : set->cb_args.cb_arg = set;
+ - ]
97 [ + - + - : 16389364 : set->cb_args.channel = channel->dev_channel;
+ - + - +
- ]
98 [ + - + - ]: 16389364 : set->ext_io_opts = NULL;
99 : :
100 : 16389364 : return (spdk_bs_sequence_t *)set;
101 : 16625 : }
102 : :
103 : : /* Use when performing IO directly on the blobstore (e.g. metadata - not a blob). */
104 : : spdk_bs_sequence_t *
105 : 299225 : bs_sequence_start_bs(struct spdk_io_channel *_channel, struct spdk_bs_cpl *cpl)
106 : : {
107 : 299225 : return bs_sequence_start(_channel, cpl, _channel);
108 : : }
109 : :
110 : : /* Use when performing IO on a blob. */
111 : : spdk_bs_sequence_t *
112 : 16162989 : bs_sequence_start_blob(struct spdk_io_channel *_channel, struct spdk_bs_cpl *cpl,
113 : : struct spdk_blob *blob)
114 : : {
115 : 16162989 : struct spdk_io_channel *esnap_ch = _channel;
116 : :
117 [ + + ]: 16162989 : if (spdk_blob_is_esnap_clone(blob)) {
118 : 8993 : esnap_ch = blob_esnap_get_io_channel(_channel, blob);
119 [ + + ]: 8993 : 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 : 1468 : }
132 : 16166131 : return bs_sequence_start(_channel, cpl, esnap_ch);
133 : 3142 : }
134 : :
135 : : void
136 : 1181 : 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 : 1181 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)seq;
141 [ + - + - ]: 1181 : struct spdk_io_channel *back_channel = set->back_channel;
142 : :
143 [ + + + + : 1181 : SPDK_DEBUGLOG(blob_rw, "Reading %" PRIu32 " blocks from LBA %" PRIu64 "\n", lba_count,
+ - ]
144 : : lba);
145 : :
146 [ + - + - : 1181 : set->u.sequence.cb_fn = cb_fn;
+ - + - ]
147 [ + - + - : 1181 : set->u.sequence.cb_arg = cb_arg;
+ - + - ]
148 : :
149 [ + - + - : 1181 : bs_dev->read(bs_dev, back_channel, payload, lba, lba_count, &set->cb_args);
- + + - +
- ]
150 : 1181 : }
151 : :
152 : : void
153 : 128626 : 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 : 128626 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)seq;
158 [ + - + - ]: 128626 : struct spdk_bs_channel *channel = set->channel;
159 : :
160 [ + + + + : 128626 : SPDK_DEBUGLOG(blob_rw, "Reading %" PRIu32 " blocks from LBA %" PRIu64 "\n", lba_count,
+ - ]
161 : : lba);
162 : :
163 [ + - + - : 128626 : set->u.sequence.cb_fn = cb_fn;
+ - + - ]
164 [ + - + - : 128626 : set->u.sequence.cb_arg = cb_arg;
+ - + - ]
165 : :
166 [ + - + - : 128626 : channel->dev->read(channel->dev, channel->dev_channel, payload, lba, lba_count, &set->cb_args);
+ - + - -
+ + - + -
+ - + - +
- + - ]
167 : 128626 : }
168 : :
169 : : void
170 : 340977 : 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 : 340977 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)seq;
175 [ + - + - ]: 340977 : struct spdk_bs_channel *channel = set->channel;
176 : :
177 [ + + + + : 340977 : SPDK_DEBUGLOG(blob_rw, "Writing %" PRIu32 " blocks from LBA %" PRIu64 "\n", lba_count,
+ - ]
178 : : lba);
179 : :
180 [ + - + - : 340977 : set->u.sequence.cb_fn = cb_fn;
+ - + - ]
181 [ + - + - : 340977 : set->u.sequence.cb_arg = cb_arg;
+ - + - ]
182 : :
183 [ + - + - : 340977 : channel->dev->write(channel->dev, channel->dev_channel, payload, lba, lba_count,
+ - + - -
+ + - + -
+ - + - +
- ]
184 [ + - ]: 7820 : &set->cb_args);
185 : 340977 : }
186 : :
187 : : void
188 : 826575 : 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 : 826575 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)seq;
193 [ + - + - ]: 826575 : struct spdk_io_channel *back_channel = set->back_channel;
194 : :
195 [ + + + + : 826575 : SPDK_DEBUGLOG(blob_rw, "Reading %" PRIu32 " blocks from LBA %" PRIu64 "\n", lba_count,
+ - ]
196 : : lba);
197 : :
198 [ + - + - : 826575 : set->u.sequence.cb_fn = cb_fn;
+ - + - ]
199 [ + - + - : 826575 : set->u.sequence.cb_arg = cb_arg;
+ - + - ]
200 : :
201 [ + + + - : 826575 : if (set->ext_io_opts) {
+ + ]
202 [ + + + - : 817743 : assert(bs_dev->readv_ext);
+ - # # ]
203 [ + - + - : 817815 : bs_dev->readv_ext(bs_dev, back_channel, iov, iovcnt, lba, lba_count,
- + + - ]
204 [ + - + - : 72 : &set->cb_args, set->ext_io_opts);
+ - ]
205 : 72 : } else {
206 [ + - + - : 8832 : bs_dev->readv(bs_dev, back_channel, iov, iovcnt, lba, lba_count, &set->cb_args);
- + + - +
- ]
207 : : }
208 : 826575 : }
209 : :
210 : : void
211 : 7013538 : 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 : 7013538 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)seq;
215 [ + - + - ]: 7013538 : struct spdk_bs_channel *channel = set->channel;
216 : :
217 [ + + + + : 7013538 : SPDK_DEBUGLOG(blob_rw, "Reading %" PRIu32 " blocks from LBA %" PRIu64 "\n", lba_count,
+ - ]
218 : : lba);
219 : :
220 [ + - + - : 7013538 : set->u.sequence.cb_fn = cb_fn;
+ - + - ]
221 [ + - + - : 7013538 : set->u.sequence.cb_arg = cb_arg;
+ - + - ]
222 [ + + + - : 7013538 : if (set->ext_io_opts) {
+ + ]
223 [ + + + - : 7011594 : assert(channel->dev->readv_ext);
+ - + - +
- # # ]
224 [ + - + - : 7011810 : channel->dev->readv_ext(channel->dev, channel->dev_channel, iov, iovcnt, lba, lba_count,
+ - + - -
+ + - + -
+ - + - +
- ]
225 [ + - + - : 216 : &set->cb_args, set->ext_io_opts);
+ - ]
226 : 216 : } else {
227 [ + - + - : 1944 : channel->dev->readv(channel->dev, channel->dev_channel, iov, iovcnt, lba, lba_count, &set->cb_args);
+ - + - -
+ + - + -
+ - + - +
- + - ]
228 : : }
229 : 7013538 : }
230 : :
231 : : void
232 : 8219276 : 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 : 8219276 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)seq;
237 [ + - + - ]: 8219276 : struct spdk_bs_channel *channel = set->channel;
238 : :
239 [ + + + + : 8219276 : SPDK_DEBUGLOG(blob_rw, "Writing %" PRIu32 " blocks from LBA %" PRIu64 "\n", lba_count,
+ - ]
240 : : lba);
241 : :
242 [ + - + - : 8219276 : set->u.sequence.cb_fn = cb_fn;
+ - + - ]
243 [ + - + - : 8219276 : set->u.sequence.cb_arg = cb_arg;
+ - + - ]
244 : :
245 [ + + + - : 8219276 : if (set->ext_io_opts) {
+ + ]
246 [ + + + - : 8216567 : assert(channel->dev->writev_ext);
+ - + - +
- # # ]
247 [ + - + - : 8216639 : channel->dev->writev_ext(channel->dev, channel->dev_channel, iov, iovcnt, lba, lba_count,
+ - + - -
+ + - + -
+ - + - +
- ]
248 [ + - + - : 72 : &set->cb_args, set->ext_io_opts);
+ - ]
249 : 72 : } else {
250 [ + - + - : 2709 : channel->dev->writev(channel->dev, channel->dev_channel, iov, iovcnt, lba, lba_count,
+ - + - -
+ + - + -
+ - + - +
- ]
251 [ + - ]: 204 : &set->cb_args);
252 : : }
253 : 8219276 : }
254 : :
255 : : void
256 : 137 : 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 : 137 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)seq;
261 [ + - + - ]: 137 : struct spdk_bs_channel *channel = set->channel;
262 : :
263 [ + + + + : 137 : SPDK_DEBUGLOG(blob_rw, "writing zeroes to %" PRIu64 " blocks at LBA %" PRIu64 "\n",
+ - ]
264 : : lba_count, lba);
265 : :
266 [ + - + - : 137 : set->u.sequence.cb_fn = cb_fn;
+ - + - ]
267 [ + - + - : 137 : set->u.sequence.cb_arg = cb_arg;
+ - + - ]
268 : :
269 [ + - + - : 137 : channel->dev->write_zeroes(channel->dev, channel->dev_channel, lba, lba_count,
+ - + - -
+ + - + -
+ - + - +
- ]
270 [ + - ]: 4 : &set->cb_args);
271 : 137 : }
272 : :
273 : : void
274 : 696 : 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 : 696 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)seq;
278 [ + - + - ]: 696 : struct spdk_bs_channel *channel = set->channel;
279 : :
280 [ + + + + : 696 : SPDK_DEBUGLOG(blob_rw, "Copying %" PRIu64 " blocks from LBA %" PRIu64 " to LBA %" PRIu64 "\n",
+ - ]
281 : : lba_count, src_lba, dst_lba);
282 : :
283 [ + - + - : 696 : set->u.sequence.cb_fn = cb_fn;
+ - + - ]
284 [ + - + - : 696 : set->u.sequence.cb_arg = cb_arg;
+ - + - ]
285 : :
286 [ + - + - : 696 : channel->dev->copy(channel->dev, channel->dev_channel, dst_lba, src_lba, lba_count, &set->cb_args);
+ - + - -
+ + - + -
+ - + - +
- + - ]
287 : 696 : }
288 : :
289 : : void
290 : 16389364 : bs_sequence_finish(spdk_bs_sequence_t *seq, int bserrno)
291 : : {
292 [ + + ]: 16389364 : if (bserrno != 0) {
293 [ + - + - ]: 6285 : seq->bserrno = bserrno;
294 : 213 : }
295 : 16389364 : bs_request_set_complete((struct spdk_bs_request_set *)seq);
296 : 16389364 : }
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 : 6113780 : bs_batch_completion(struct spdk_io_channel *_channel,
308 : : void *cb_arg, int bserrno)
309 : : {
310 : 6113780 : struct spdk_bs_request_set *set = cb_arg;
311 : :
312 [ + - + - : 6113780 : set->u.batch.outstanding_ops--;
+ - ]
313 [ + + ]: 6113780 : if (bserrno != 0) {
314 [ + - + - ]: 24 : set->bserrno = bserrno;
315 : 4 : }
316 : :
317 [ + + + + : 6113780 : if (set->u.batch.outstanding_ops == 0 && set->u.batch.batch_closed) {
+ - + - +
+ + - + -
+ - + - +
+ ]
318 [ + + + - : 5922375 : if (set->u.batch.cb_fn) {
+ - + - +
+ ]
319 [ + - + - : 27325 : set->cb_args.cb_fn = bs_sequence_completion;
+ - ]
320 [ + - + - : 27325 : set->u.batch.cb_fn((spdk_bs_sequence_t *)set, set->u.batch.cb_arg, bserrno);
+ - + - -
+ - + + -
+ - + - +
- ]
321 : 3808 : } else {
322 : 5895050 : bs_request_set_complete(set);
323 : : }
324 : 27906 : }
325 : 6113780 : }
326 : :
327 : : spdk_bs_batch_t *
328 : 6053295 : bs_batch_open(struct spdk_io_channel *_channel, struct spdk_bs_cpl *cpl, struct spdk_blob *blob)
329 : : {
330 : 24954 : struct spdk_bs_channel *channel;
331 : 24954 : struct spdk_bs_request_set *set;
332 : 6053295 : struct spdk_io_channel *back_channel = _channel;
333 : :
334 [ + + ]: 6053295 : if (spdk_blob_is_esnap_clone(blob)) {
335 : 19512 : back_channel = blob_esnap_get_io_channel(_channel, blob);
336 [ + + ]: 19512 : if (back_channel == NULL) {
337 : 0 : return NULL;
338 : : }
339 : 3252 : }
340 : :
341 : 6053295 : channel = spdk_io_channel_get_ctx(_channel);
342 [ + + # # ]: 6053295 : assert(channel != NULL);
343 [ + - + - : 6053295 : set = TAILQ_FIRST(&channel->reqs);
+ - ]
344 [ + + ]: 6053295 : if (!set) {
345 : 53 : return NULL;
346 : : }
347 [ + + + - : 6053242 : TAILQ_REMOVE(&channel->reqs, set, link);
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - # # #
# # # # #
# # # # +
- + - + -
+ - + - +
- + - ]
348 : :
349 [ + - ]: 6053242 : set->cpl = *cpl;
350 [ + - + - ]: 6053242 : set->bserrno = 0;
351 [ + - + - ]: 6053242 : set->channel = channel;
352 [ + - + - ]: 6053242 : set->back_channel = back_channel;
353 : :
354 [ + - + - : 6053242 : set->u.batch.cb_fn = NULL;
+ - + - ]
355 [ + - + - : 6053242 : set->u.batch.cb_arg = NULL;
+ - + - ]
356 [ + - + - : 6053242 : set->u.batch.outstanding_ops = 0;
+ - + - ]
357 [ + - + - : 6053242 : set->u.batch.batch_closed = 0;
+ - + - ]
358 : :
359 [ + - + - : 6053242 : set->cb_args.cb_fn = bs_batch_completion;
+ - ]
360 [ + - + - : 6053242 : set->cb_args.cb_arg = set;
+ - ]
361 [ + - + - : 6053242 : set->cb_args.channel = channel->dev_channel;
+ - + - +
- ]
362 : :
363 : 6053242 : return (spdk_bs_batch_t *)set;
364 : 24954 : }
365 : :
366 : : void
367 : 5928 : 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 : 5928 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)batch;
371 [ + - + - ]: 5928 : struct spdk_io_channel *back_channel = set->back_channel;
372 : :
373 [ + + + + : 5928 : SPDK_DEBUGLOG(blob_rw, "Reading %" PRIu32 " blocks from LBA %" PRIu64 "\n", lba_count,
+ - ]
374 : : lba);
375 : :
376 [ + - + - : 5928 : set->u.batch.outstanding_ops++;
+ - ]
377 [ + - + - : 5928 : bs_dev->read(bs_dev, back_channel, payload, lba, lba_count, &set->cb_args);
- + + - +
- ]
378 : 5928 : }
379 : :
380 : : void
381 : 5058443 : bs_batch_read_dev(spdk_bs_batch_t *batch, void *payload,
382 : : uint64_t lba, uint32_t lba_count)
383 : : {
384 : 5058443 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)batch;
385 [ + - + - ]: 5058443 : struct spdk_bs_channel *channel = set->channel;
386 : :
387 [ + + + + : 5058443 : SPDK_DEBUGLOG(blob_rw, "Reading %" PRIu32 " blocks from LBA %" PRIu64 "\n", lba_count,
+ - ]
388 : : lba);
389 : :
390 [ + - + - : 5058443 : set->u.batch.outstanding_ops++;
+ - ]
391 [ + - + - : 5058443 : channel->dev->read(channel->dev, channel->dev_channel, payload, lba, lba_count, &set->cb_args);
+ - + - -
+ + - + -
+ - + - +
- + - ]
392 : 5058443 : }
393 : :
394 : : void
395 : 783142 : bs_batch_write_dev(spdk_bs_batch_t *batch, void *payload,
396 : : uint64_t lba, uint32_t lba_count)
397 : : {
398 : 783142 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)batch;
399 [ + - + - ]: 783142 : struct spdk_bs_channel *channel = set->channel;
400 : :
401 [ + + + + : 783142 : SPDK_DEBUGLOG(blob_rw, "Writing %" PRIu32 " blocks to LBA %" PRIu64 "\n", lba_count, lba);
+ - ]
402 : :
403 [ + - + - : 783142 : set->u.batch.outstanding_ops++;
+ - ]
404 [ + - + - : 783142 : channel->dev->write(channel->dev, channel->dev_channel, payload, lba, lba_count,
+ - + - -
+ + - + -
+ - + - +
- ]
405 [ + - ]: 11279 : &set->cb_args);
406 : 783142 : }
407 : :
408 : : void
409 : 241172 : bs_batch_unmap_dev(spdk_bs_batch_t *batch,
410 : : uint64_t lba, uint64_t lba_count)
411 : : {
412 : 241172 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)batch;
413 [ + - + - ]: 241172 : struct spdk_bs_channel *channel = set->channel;
414 : :
415 [ + + + + : 241172 : SPDK_DEBUGLOG(blob_rw, "Unmapping %" PRIu64 " blocks at LBA %" PRIu64 "\n", lba_count,
+ - ]
416 : : lba);
417 : :
418 [ + - + - : 241172 : set->u.batch.outstanding_ops++;
+ - ]
419 [ + - + - : 241172 : channel->dev->unmap(channel->dev, channel->dev_channel, lba, lba_count,
+ - + - -
+ + - + -
+ - + - +
- ]
420 [ + - ]: 1694 : &set->cb_args);
421 : 241172 : }
422 : :
423 : : void
424 : 25095 : bs_batch_write_zeroes_dev(spdk_bs_batch_t *batch,
425 : : uint64_t lba, uint64_t lba_count)
426 : : {
427 : 25095 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)batch;
428 [ + - + - ]: 25095 : struct spdk_bs_channel *channel = set->channel;
429 : :
430 [ + + + + : 25095 : SPDK_DEBUGLOG(blob_rw, "Zeroing %" PRIu64 " blocks at LBA %" PRIu64 "\n", lba_count, lba);
+ - ]
431 : :
432 [ + - + - : 25095 : set->u.batch.outstanding_ops++;
+ - ]
433 [ + - + - : 25095 : channel->dev->write_zeroes(channel->dev, channel->dev_channel, lba, lba_count,
+ - + - -
+ + - + -
+ - + - +
- ]
434 [ + - ]: 2584 : &set->cb_args);
435 : 25095 : }
436 : :
437 : : void
438 : 6770365 : bs_batch_close(spdk_bs_batch_t *batch)
439 : : {
440 : 6770365 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)batch;
441 : :
442 [ + - + - : 6770365 : set->u.batch.batch_closed = 1;
+ - + - ]
443 : :
444 [ + + + - : 6770365 : if (set->u.batch.outstanding_ops == 0) {
+ - + - +
+ ]
445 [ + + + - : 847990 : if (set->u.batch.cb_fn) {
+ - + - +
+ ]
446 [ + - + - : 689798 : set->cb_args.cb_fn = bs_sequence_completion;
+ - ]
447 [ + - + - : 689798 : set->u.batch.cb_fn((spdk_bs_sequence_t *)set, set->u.batch.cb_arg, set->bserrno);
+ - + - -
+ - + + -
+ - + - +
- + - +
- ]
448 : 13812 : } else {
449 : 158192 : bs_request_set_complete(set);
450 : : }
451 : 14668 : }
452 : 6770365 : }
453 : :
454 : : spdk_bs_batch_t *
455 : 717123 : bs_sequence_to_batch(spdk_bs_sequence_t *seq, spdk_bs_sequence_cpl cb_fn, void *cb_arg)
456 : : {
457 : 717123 : struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)seq;
458 : :
459 [ + - + - : 717123 : set->u.batch.cb_fn = cb_fn;
+ - + - ]
460 [ + - + - : 717123 : set->u.batch.cb_arg = cb_arg;
+ - + - ]
461 [ + - + - : 717123 : set->u.batch.outstanding_ops = 0;
+ - + - ]
462 [ + - + - : 717123 : set->u.batch.batch_closed = 0;
+ - + - ]
463 : :
464 [ + - + - : 717123 : set->cb_args.cb_fn = bs_batch_completion;
+ - ]
465 : :
466 : 734743 : return set;
467 : 17620 : }
468 : :
469 : : spdk_bs_user_op_t *
470 : 147271 : 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 : 612 : struct spdk_bs_channel *channel;
475 : 612 : struct spdk_bs_request_set *set;
476 : 612 : struct spdk_bs_user_op_args *args;
477 : :
478 : 147271 : channel = spdk_io_channel_get_ctx(_channel);
479 [ + + # # ]: 147271 : assert(channel != NULL);
480 [ + - + - : 147271 : set = TAILQ_FIRST(&channel->reqs);
+ - ]
481 [ + + ]: 147271 : if (!set) {
482 : 0 : return NULL;
483 : : }
484 [ + - + - : 147271 : TAILQ_REMOVE(&channel->reqs, set, link);
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - # # #
# # # # #
# # # # +
- + - + -
+ - + - +
- + - ]
485 : :
486 [ + - ]: 147271 : set->cpl = *cpl;
487 [ + - + - ]: 147271 : set->channel = channel;
488 [ + - + - ]: 147271 : set->back_channel = NULL;
489 [ + - + - ]: 147271 : set->ext_io_opts = NULL;
490 : :
491 [ + - + - ]: 147271 : args = &set->u.user_op;
492 : :
493 [ + - + - ]: 147271 : args->type = op_type;
494 [ + - + - ]: 147271 : args->iovcnt = iovcnt;
495 [ + - + - ]: 147271 : args->blob = blob;
496 [ + - + - ]: 147271 : args->offset = offset;
497 [ + - + - ]: 147271 : args->length = length;
498 [ + - + - ]: 147271 : args->payload = payload;
499 : :
500 : 147271 : return (spdk_bs_user_op_t *)set;
501 : 612 : }
502 : :
503 : : void
504 : 147270 : bs_user_op_execute(spdk_bs_user_op_t *op)
505 : : {
506 : 612 : struct spdk_bs_request_set *set;
507 : 612 : struct spdk_bs_user_op_args *args;
508 : 612 : struct spdk_io_channel *ch;
509 : :
510 : 147270 : set = (struct spdk_bs_request_set *)op;
511 [ + - + - ]: 147270 : args = &set->u.user_op;
512 [ + - + - ]: 147270 : ch = spdk_io_channel_from_ctx(set->channel);
513 : :
514 [ + + + - : 147270 : switch (args->type) {
+ + - - -
+ - ]
515 : 1928 : case SPDK_BLOB_READ:
516 [ + - + - : 2688 : spdk_blob_io_read(args->blob, ch, args->payload, args->offset, args->length,
+ - + - +
- + - + -
+ - ]
517 [ + - + - : 380 : set->cpl.u.blob_basic.cb_fn, set->cpl.u.blob_basic.cb_arg);
+ - + - +
- + - + -
+ - + - +
- ]
518 : 2308 : break;
519 : 1191 : case SPDK_BLOB_WRITE:
520 [ + - + - : 1623 : spdk_blob_io_write(args->blob, ch, args->payload, args->offset, args->length,
+ - + - +
- + - + -
+ - ]
521 [ + - + - : 216 : set->cpl.u.blob_basic.cb_fn, set->cpl.u.blob_basic.cb_arg);
+ - + - +
- + - + -
+ - + - +
- ]
522 : 1407 : break;
523 : 0 : case SPDK_BLOB_UNMAP:
524 [ # # # # : 0 : spdk_blob_io_unmap(args->blob, ch, args->offset, args->length,
# # # # #
# # # ]
525 [ # # # # : 0 : 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 [ # # # # : 0 : 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 [ # # # # : 0 : args->offset, args->length,
# # # # ]
534 [ # # # # : 0 : set->cpl.u.blob_basic.cb_fn, set->cpl.u.blob_basic.cb_arg,
# # # # #
# # # # #
# # # # #
# ]
535 [ # # # # ]: 0 : set->ext_io_opts);
536 : 0 : break;
537 : 143539 : case SPDK_BLOB_WRITEV:
538 [ + - + - : 143571 : spdk_blob_io_writev_ext(args->blob, ch, args->payload, args->iovcnt,
+ - + - +
- + - ]
539 [ + - + - : 16 : args->offset, args->length,
+ - + - ]
540 [ + - + - : 16 : set->cpl.u.blob_basic.cb_fn, set->cpl.u.blob_basic.cb_arg,
+ - + - +
- + - + -
+ - + - +
- ]
541 [ + - + - ]: 16 : set->ext_io_opts);
542 : 143555 : break;
543 : : }
544 [ + - + - : 147270 : TAILQ_INSERT_TAIL(&set->channel->reqs, set, link);
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - ]
545 : 147270 : }
546 : :
547 : : void
548 : 1 : bs_user_op_abort(spdk_bs_user_op_t *op, int bserrno)
549 : : {
550 : 0 : 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 : 1979 : SPDK_LOG_REGISTER_COMPONENT(blob_rw)
|