xref: /spdk/lib/blob/request.c (revision a83f91c29a4740e4bea5f9509b7036e9e7dc2788)
1d89352a9SBen Walker /*-
2d89352a9SBen Walker  *   BSD LICENSE
3d89352a9SBen Walker  *
4d89352a9SBen Walker  *   Copyright (c) Intel Corporation.
5d89352a9SBen Walker  *   All rights reserved.
6d89352a9SBen Walker  *
7d89352a9SBen Walker  *   Redistribution and use in source and binary forms, with or without
8d89352a9SBen Walker  *   modification, are permitted provided that the following conditions
9d89352a9SBen Walker  *   are met:
10d89352a9SBen Walker  *
11d89352a9SBen Walker  *     * Redistributions of source code must retain the above copyright
12d89352a9SBen Walker  *       notice, this list of conditions and the following disclaimer.
13d89352a9SBen Walker  *     * Redistributions in binary form must reproduce the above copyright
14d89352a9SBen Walker  *       notice, this list of conditions and the following disclaimer in
15d89352a9SBen Walker  *       the documentation and/or other materials provided with the
16d89352a9SBen Walker  *       distribution.
17d89352a9SBen Walker  *     * Neither the name of Intel Corporation nor the names of its
18d89352a9SBen Walker  *       contributors may be used to endorse or promote products derived
19d89352a9SBen Walker  *       from this software without specific prior written permission.
20d89352a9SBen Walker  *
21d89352a9SBen Walker  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22d89352a9SBen Walker  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23d89352a9SBen Walker  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24d89352a9SBen Walker  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25d89352a9SBen Walker  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26d89352a9SBen Walker  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27d89352a9SBen Walker  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28d89352a9SBen Walker  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29d89352a9SBen Walker  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30d89352a9SBen Walker  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31d89352a9SBen Walker  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32d89352a9SBen Walker  */
33d89352a9SBen Walker 
34b961d9ccSBen Walker #include "spdk/stdinc.h"
35d89352a9SBen Walker 
36d89352a9SBen Walker #include "blobstore.h"
37d89352a9SBen Walker #include "request.h"
38d89352a9SBen Walker 
39*a83f91c2SBen Walker #include "spdk/thread.h"
40d89352a9SBen Walker #include "spdk/queue.h"
41d89352a9SBen Walker 
42d89352a9SBen Walker #include "spdk_internal/log.h"
43d89352a9SBen Walker 
44d89352a9SBen Walker void
45d89352a9SBen Walker spdk_bs_call_cpl(struct spdk_bs_cpl *cpl, int bserrno)
46d89352a9SBen Walker {
47d89352a9SBen Walker 	switch (cpl->type) {
48d89352a9SBen Walker 	case SPDK_BS_CPL_TYPE_BS_BASIC:
49d89352a9SBen Walker 		cpl->u.bs_basic.cb_fn(cpl->u.bs_basic.cb_arg,
50d89352a9SBen Walker 				      bserrno);
51d89352a9SBen Walker 		break;
52d89352a9SBen Walker 	case SPDK_BS_CPL_TYPE_BS_HANDLE:
53d89352a9SBen Walker 		cpl->u.bs_handle.cb_fn(cpl->u.bs_handle.cb_arg,
54d89352a9SBen Walker 				       cpl->u.bs_handle.bs,
55d89352a9SBen Walker 				       bserrno);
56d89352a9SBen Walker 		break;
57d89352a9SBen Walker 	case SPDK_BS_CPL_TYPE_BLOB_BASIC:
58d89352a9SBen Walker 		cpl->u.blob_basic.cb_fn(cpl->u.blob_basic.cb_arg,
59d89352a9SBen Walker 					bserrno);
60d89352a9SBen Walker 		break;
61d89352a9SBen Walker 	case SPDK_BS_CPL_TYPE_BLOBID:
62d89352a9SBen Walker 		cpl->u.blobid.cb_fn(cpl->u.blobid.cb_arg,
63d89352a9SBen Walker 				    cpl->u.blobid.blobid,
64d89352a9SBen Walker 				    bserrno);
65d89352a9SBen Walker 		break;
66d89352a9SBen Walker 	case SPDK_BS_CPL_TYPE_BLOB_HANDLE:
67d89352a9SBen Walker 		cpl->u.blob_handle.cb_fn(cpl->u.blob_handle.cb_arg,
68d89352a9SBen Walker 					 cpl->u.blob_handle.blob,
69d89352a9SBen Walker 					 bserrno);
70d89352a9SBen Walker 		break;
71d89352a9SBen Walker 	case SPDK_BS_CPL_TYPE_NESTED_SEQUENCE:
72d89352a9SBen Walker 		cpl->u.nested_seq.cb_fn(cpl->u.nested_seq.cb_arg,
73d89352a9SBen Walker 					cpl->u.nested_seq.parent,
74d89352a9SBen Walker 					bserrno);
75d89352a9SBen Walker 		break;
76130d278aSPaul Luse 	case SPDK_BS_CPL_TYPE_NONE:
77130d278aSPaul Luse 		/* this completion's callback is handled elsewhere */
78130d278aSPaul Luse 		break;
79d89352a9SBen Walker 	}
80d89352a9SBen Walker }
81d89352a9SBen Walker 
82d89352a9SBen Walker static void
83d89352a9SBen Walker spdk_bs_request_set_complete(struct spdk_bs_request_set *set)
84d89352a9SBen Walker {
85d89352a9SBen Walker 	struct spdk_bs_cpl cpl = set->cpl;
86d89352a9SBen Walker 	int bserrno = set->bserrno;
87d89352a9SBen Walker 
88d89352a9SBen Walker 	TAILQ_INSERT_TAIL(&set->channel->reqs, set, link);
89d89352a9SBen Walker 
90d89352a9SBen Walker 	spdk_bs_call_cpl(&cpl, bserrno);
91d89352a9SBen Walker }
92d89352a9SBen Walker 
93d89352a9SBen Walker static void
94d89352a9SBen Walker spdk_bs_sequence_completion(struct spdk_io_channel *channel, void *cb_arg, int bserrno)
95d89352a9SBen Walker {
96d89352a9SBen Walker 	struct spdk_bs_request_set *set = cb_arg;
97d89352a9SBen Walker 
98d89352a9SBen Walker 	set->bserrno = bserrno;
99d89352a9SBen Walker 	set->u.sequence.cb_fn((spdk_bs_sequence_t *)set, set->u.sequence.cb_arg, bserrno);
100d89352a9SBen Walker }
101d89352a9SBen Walker 
102d89352a9SBen Walker spdk_bs_sequence_t *
103d89352a9SBen Walker spdk_bs_sequence_start(struct spdk_io_channel *_channel,
104d89352a9SBen Walker 		       struct spdk_bs_cpl *cpl)
105d89352a9SBen Walker {
106d89352a9SBen Walker 	struct spdk_bs_channel		*channel;
107d89352a9SBen Walker 	struct spdk_bs_request_set	*set;
108d89352a9SBen Walker 
109d89352a9SBen Walker 	channel = spdk_io_channel_get_ctx(_channel);
110d89352a9SBen Walker 
111d89352a9SBen Walker 	set = TAILQ_FIRST(&channel->reqs);
112d89352a9SBen Walker 	if (!set) {
113d89352a9SBen Walker 		return NULL;
114d89352a9SBen Walker 	}
115d89352a9SBen Walker 	TAILQ_REMOVE(&channel->reqs, set, link);
116d89352a9SBen Walker 
117d89352a9SBen Walker 	set->cpl = *cpl;
118d89352a9SBen Walker 	set->bserrno = 0;
119d89352a9SBen Walker 	set->channel = channel;
120d89352a9SBen Walker 
121d89352a9SBen Walker 	set->cb_args.cb_fn = spdk_bs_sequence_completion;
122d89352a9SBen Walker 	set->cb_args.cb_arg = set;
123d89352a9SBen Walker 	set->cb_args.channel = channel->dev_channel;
124d89352a9SBen Walker 
125d89352a9SBen Walker 	return (spdk_bs_sequence_t *)set;
126d89352a9SBen Walker }
127d89352a9SBen Walker 
128d89352a9SBen Walker void
1290e917256SMaciej Szwed spdk_bs_sequence_read_bs_dev(spdk_bs_sequence_t *seq, struct spdk_bs_dev *bs_dev,
1300e917256SMaciej Szwed 			     void *payload, uint64_t lba, uint32_t lba_count,
131d89352a9SBen Walker 			     spdk_bs_sequence_cpl cb_fn, void *cb_arg)
132d89352a9SBen Walker {
133d89352a9SBen Walker 	struct spdk_bs_request_set      *set = (struct spdk_bs_request_set *)seq;
134d89352a9SBen Walker 	struct spdk_bs_channel       *channel = set->channel;
135d89352a9SBen Walker 
1363e717065STomasz Kulasek 	SPDK_DEBUGLOG(SPDK_LOG_BLOB_RW, "Reading %" PRIu32 " blocks from LBA %" PRIu64 "\n", lba_count,
1373e717065STomasz Kulasek 		      lba);
138d89352a9SBen Walker 
139d89352a9SBen Walker 	set->u.sequence.cb_fn = cb_fn;
140d89352a9SBen Walker 	set->u.sequence.cb_arg = cb_arg;
141d89352a9SBen Walker 
1424dc04dc6SPiotr Pelplinski 	bs_dev->read(bs_dev, spdk_io_channel_from_ctx(channel), payload, lba, lba_count, &set->cb_args);
1430e917256SMaciej Szwed }
1440e917256SMaciej Szwed 
1450e917256SMaciej Szwed void
146c4659139SJim Harris spdk_bs_sequence_read_dev(spdk_bs_sequence_t *seq, void *payload,
1470e917256SMaciej Szwed 			  uint64_t lba, uint32_t lba_count,
1480e917256SMaciej Szwed 			  spdk_bs_sequence_cpl cb_fn, void *cb_arg)
1490e917256SMaciej Szwed {
1500e917256SMaciej Szwed 	struct spdk_bs_request_set      *set = (struct spdk_bs_request_set *)seq;
1510e917256SMaciej Szwed 	struct spdk_bs_channel       *channel = set->channel;
1520e917256SMaciej Szwed 
1533e717065STomasz Kulasek 	SPDK_DEBUGLOG(SPDK_LOG_BLOB_RW, "Reading %" PRIu32 " blocks from LBA %" PRIu64 "\n", lba_count,
1543e717065STomasz Kulasek 		      lba);
1553e717065STomasz Kulasek 
1564dc04dc6SPiotr Pelplinski 	set->u.sequence.cb_fn = cb_fn;
1574dc04dc6SPiotr Pelplinski 	set->u.sequence.cb_arg = cb_arg;
1584dc04dc6SPiotr Pelplinski 
1594dc04dc6SPiotr Pelplinski 	channel->dev->read(channel->dev, channel->dev_channel, payload, lba, lba_count, &set->cb_args);
160d89352a9SBen Walker }
161d89352a9SBen Walker 
162d89352a9SBen Walker void
163c4659139SJim Harris spdk_bs_sequence_write_dev(spdk_bs_sequence_t *seq, void *payload,
164d89352a9SBen Walker 			   uint64_t lba, uint32_t lba_count,
165d89352a9SBen Walker 			   spdk_bs_sequence_cpl cb_fn, void *cb_arg)
166d89352a9SBen Walker {
167d89352a9SBen Walker 	struct spdk_bs_request_set      *set = (struct spdk_bs_request_set *)seq;
168d89352a9SBen Walker 	struct spdk_bs_channel       *channel = set->channel;
169d89352a9SBen Walker 
1703e717065STomasz Kulasek 	SPDK_DEBUGLOG(SPDK_LOG_BLOB_RW, "Writing %" PRIu32 " blocks from LBA %" PRIu64 "\n", lba_count,
1713e717065STomasz Kulasek 		      lba);
172d89352a9SBen Walker 
173d89352a9SBen Walker 	set->u.sequence.cb_fn = cb_fn;
174d89352a9SBen Walker 	set->u.sequence.cb_arg = cb_arg;
175d89352a9SBen Walker 
176d89352a9SBen Walker 	channel->dev->write(channel->dev, channel->dev_channel, payload, lba, lba_count,
177d89352a9SBen Walker 			    &set->cb_args);
178d89352a9SBen Walker }
179d89352a9SBen Walker 
180d89352a9SBen Walker void
1810e917256SMaciej Szwed spdk_bs_sequence_readv_bs_dev(spdk_bs_sequence_t *seq, struct spdk_bs_dev *bs_dev,
1820e917256SMaciej Szwed 			      struct iovec *iov, int iovcnt, uint64_t lba, uint32_t lba_count,
183179ed697SJim Harris 			      spdk_bs_sequence_cpl cb_fn, void *cb_arg)
184179ed697SJim Harris {
185179ed697SJim Harris 	struct spdk_bs_request_set      *set = (struct spdk_bs_request_set *)seq;
186179ed697SJim Harris 	struct spdk_bs_channel       *channel = set->channel;
187179ed697SJim Harris 
1883e717065STomasz Kulasek 	SPDK_DEBUGLOG(SPDK_LOG_BLOB_RW, "Reading %" PRIu32 " blocks from LBA %" PRIu64 "\n", lba_count,
1893e717065STomasz Kulasek 		      lba);
190179ed697SJim Harris 
191179ed697SJim Harris 	set->u.sequence.cb_fn = cb_fn;
192179ed697SJim Harris 	set->u.sequence.cb_arg = cb_arg;
193179ed697SJim Harris 
1944dc04dc6SPiotr Pelplinski 	bs_dev->readv(bs_dev, spdk_io_channel_from_ctx(channel), iov, iovcnt, lba, lba_count,
195179ed697SJim Harris 		      &set->cb_args);
196179ed697SJim Harris }
197179ed697SJim Harris 
198179ed697SJim Harris void
199c4659139SJim Harris spdk_bs_sequence_readv_dev(spdk_bs_sequence_t *seq, struct iovec *iov, int iovcnt,
2000e917256SMaciej Szwed 			   uint64_t lba, uint32_t lba_count, spdk_bs_sequence_cpl cb_fn, void *cb_arg)
2010e917256SMaciej Szwed {
2020e917256SMaciej Szwed 	struct spdk_bs_request_set      *set = (struct spdk_bs_request_set *)seq;
2030e917256SMaciej Szwed 	struct spdk_bs_channel       *channel = set->channel;
2040e917256SMaciej Szwed 
2053e717065STomasz Kulasek 	SPDK_DEBUGLOG(SPDK_LOG_BLOB_RW, "Reading %" PRIu32 " blocks from LBA %" PRIu64 "\n", lba_count,
2063e717065STomasz Kulasek 		      lba);
2073e717065STomasz Kulasek 
2084dc04dc6SPiotr Pelplinski 	set->u.sequence.cb_fn = cb_fn;
2094dc04dc6SPiotr Pelplinski 	set->u.sequence.cb_arg = cb_arg;
2104dc04dc6SPiotr Pelplinski 	channel->dev->readv(channel->dev, channel->dev_channel, iov, iovcnt, lba, lba_count,
2114dc04dc6SPiotr Pelplinski 			    &set->cb_args);
2120e917256SMaciej Szwed }
2130e917256SMaciej Szwed 
2140e917256SMaciej Szwed void
215c4659139SJim Harris spdk_bs_sequence_writev_dev(spdk_bs_sequence_t *seq, struct iovec *iov, int iovcnt,
216179ed697SJim Harris 			    uint64_t lba, uint32_t lba_count,
217179ed697SJim Harris 			    spdk_bs_sequence_cpl cb_fn, void *cb_arg)
218179ed697SJim Harris {
219179ed697SJim Harris 	struct spdk_bs_request_set      *set = (struct spdk_bs_request_set *)seq;
220179ed697SJim Harris 	struct spdk_bs_channel       *channel = set->channel;
221179ed697SJim Harris 
2223e717065STomasz Kulasek 	SPDK_DEBUGLOG(SPDK_LOG_BLOB_RW, "Writing %" PRIu32 " blocks from LBA %" PRIu64 "\n", lba_count,
2233e717065STomasz Kulasek 		      lba);
224179ed697SJim Harris 
225179ed697SJim Harris 	set->u.sequence.cb_fn = cb_fn;
226179ed697SJim Harris 	set->u.sequence.cb_arg = cb_arg;
227179ed697SJim Harris 
228179ed697SJim Harris 	channel->dev->writev(channel->dev, channel->dev_channel, iov, iovcnt, lba, lba_count,
229179ed697SJim Harris 			     &set->cb_args);
230179ed697SJim Harris }
231179ed697SJim Harris 
232179ed697SJim Harris void
233c4659139SJim Harris spdk_bs_sequence_unmap_dev(spdk_bs_sequence_t *seq,
234d89352a9SBen Walker 			   uint64_t lba, uint32_t lba_count,
235d89352a9SBen Walker 			   spdk_bs_sequence_cpl cb_fn, void *cb_arg)
236d89352a9SBen Walker {
237d89352a9SBen Walker 	struct spdk_bs_request_set      *set = (struct spdk_bs_request_set *)seq;
238d89352a9SBen Walker 	struct spdk_bs_channel       *channel = set->channel;
239d89352a9SBen Walker 
2403e717065STomasz Kulasek 	SPDK_DEBUGLOG(SPDK_LOG_BLOB_RW, "Unmapping %" PRIu32 " blocks at LBA %" PRIu64 "\n", lba_count,
2413e717065STomasz Kulasek 		      lba);
242d89352a9SBen Walker 
243d89352a9SBen Walker 	set->u.sequence.cb_fn = cb_fn;
244d89352a9SBen Walker 	set->u.sequence.cb_arg = cb_arg;
245d89352a9SBen Walker 
246d89352a9SBen Walker 	channel->dev->unmap(channel->dev, channel->dev_channel, lba, lba_count,
247d89352a9SBen Walker 			    &set->cb_args);
248d89352a9SBen Walker }
249d89352a9SBen Walker 
250d89352a9SBen Walker void
251c4659139SJim Harris spdk_bs_sequence_write_zeroes_dev(spdk_bs_sequence_t *seq,
2523f9cbe51SSeth Howell 				  uint64_t lba, uint32_t lba_count,
2533f9cbe51SSeth Howell 				  spdk_bs_sequence_cpl cb_fn, void *cb_arg)
2543f9cbe51SSeth Howell {
2553f9cbe51SSeth Howell 	struct spdk_bs_request_set      *set = (struct spdk_bs_request_set *)seq;
2563f9cbe51SSeth Howell 	struct spdk_bs_channel       *channel = set->channel;
2573f9cbe51SSeth Howell 
2583e717065STomasz Kulasek 	SPDK_DEBUGLOG(SPDK_LOG_BLOB_RW, "writing zeroes to %" PRIu32 " blocks at LBA %" PRIu64 "\n",
2593e717065STomasz Kulasek 		      lba_count, lba);
2603f9cbe51SSeth Howell 
2613f9cbe51SSeth Howell 	set->u.sequence.cb_fn = cb_fn;
2623f9cbe51SSeth Howell 	set->u.sequence.cb_arg = cb_arg;
2633f9cbe51SSeth Howell 
2643f9cbe51SSeth Howell 	channel->dev->write_zeroes(channel->dev, channel->dev_channel, lba, lba_count,
2653f9cbe51SSeth Howell 				   &set->cb_args);
2663f9cbe51SSeth Howell }
2673f9cbe51SSeth Howell 
2683f9cbe51SSeth Howell void
269d89352a9SBen Walker spdk_bs_sequence_finish(spdk_bs_sequence_t *seq, int bserrno)
270d89352a9SBen Walker {
271d89352a9SBen Walker 	if (bserrno != 0) {
272d89352a9SBen Walker 		seq->bserrno = bserrno;
273d89352a9SBen Walker 	}
274d89352a9SBen Walker 	spdk_bs_request_set_complete((struct spdk_bs_request_set *)seq);
275d89352a9SBen Walker }
276d89352a9SBen Walker 
2774132ac52SMaciej Szwed void
2784132ac52SMaciej Szwed spdk_bs_user_op_sequence_finish(void *cb_arg, int bserrno)
2794132ac52SMaciej Szwed {
2804132ac52SMaciej Szwed 	spdk_bs_sequence_t *seq = cb_arg;
2814132ac52SMaciej Szwed 
2824132ac52SMaciej Szwed 	spdk_bs_sequence_finish(seq, bserrno);
2834132ac52SMaciej Szwed }
2844132ac52SMaciej Szwed 
285d89352a9SBen Walker static void
286d89352a9SBen Walker spdk_bs_batch_completion(struct spdk_io_channel *_channel,
287d89352a9SBen Walker 			 void *cb_arg, int bserrno)
288d89352a9SBen Walker {
289d89352a9SBen Walker 	struct spdk_bs_request_set	*set = cb_arg;
290d89352a9SBen Walker 
291d89352a9SBen Walker 	set->u.batch.outstanding_ops--;
292d89352a9SBen Walker 	if (bserrno != 0) {
293d89352a9SBen Walker 		set->bserrno = bserrno;
294d89352a9SBen Walker 	}
295d89352a9SBen Walker 
296d89352a9SBen Walker 	if (set->u.batch.outstanding_ops == 0 && set->u.batch.batch_closed) {
297d89352a9SBen Walker 		if (set->u.batch.cb_fn) {
298d89352a9SBen Walker 			set->cb_args.cb_fn = spdk_bs_sequence_completion;
299d89352a9SBen Walker 			set->u.batch.cb_fn((spdk_bs_sequence_t *)set, set->u.batch.cb_arg, bserrno);
300d89352a9SBen Walker 		} else {
301d89352a9SBen Walker 			spdk_bs_request_set_complete(set);
302d89352a9SBen Walker 		}
303d89352a9SBen Walker 	}
304d89352a9SBen Walker }
305d89352a9SBen Walker 
306d89352a9SBen Walker spdk_bs_batch_t *
307d89352a9SBen Walker spdk_bs_batch_open(struct spdk_io_channel *_channel,
308d89352a9SBen Walker 		   struct spdk_bs_cpl *cpl)
309d89352a9SBen Walker {
310d89352a9SBen Walker 	struct spdk_bs_channel		*channel;
311d89352a9SBen Walker 	struct spdk_bs_request_set	*set;
312d89352a9SBen Walker 
313d89352a9SBen Walker 	channel = spdk_io_channel_get_ctx(_channel);
314d89352a9SBen Walker 
315d89352a9SBen Walker 	set = TAILQ_FIRST(&channel->reqs);
316d89352a9SBen Walker 	if (!set) {
317d89352a9SBen Walker 		return NULL;
318d89352a9SBen Walker 	}
319d89352a9SBen Walker 	TAILQ_REMOVE(&channel->reqs, set, link);
320d89352a9SBen Walker 
321d89352a9SBen Walker 	set->cpl = *cpl;
322d89352a9SBen Walker 	set->bserrno = 0;
323d89352a9SBen Walker 	set->channel = channel;
324d89352a9SBen Walker 
325d89352a9SBen Walker 	set->u.batch.cb_fn = NULL;
326d89352a9SBen Walker 	set->u.batch.cb_arg = NULL;
327d89352a9SBen Walker 	set->u.batch.outstanding_ops = 0;
328d89352a9SBen Walker 	set->u.batch.batch_closed = 0;
329d89352a9SBen Walker 
330d89352a9SBen Walker 	set->cb_args.cb_fn = spdk_bs_batch_completion;
331d89352a9SBen Walker 	set->cb_args.cb_arg = set;
332d89352a9SBen Walker 	set->cb_args.channel = channel->dev_channel;
333d89352a9SBen Walker 
334d89352a9SBen Walker 	return (spdk_bs_batch_t *)set;
335d89352a9SBen Walker }
336d89352a9SBen Walker 
337d89352a9SBen Walker void
3380e917256SMaciej Szwed spdk_bs_batch_read_bs_dev(spdk_bs_batch_t *batch, struct spdk_bs_dev *bs_dev,
3390e917256SMaciej Szwed 			  void *payload, uint64_t lba, uint32_t lba_count)
340d89352a9SBen Walker {
341d89352a9SBen Walker 	struct spdk_bs_request_set	*set = (struct spdk_bs_request_set *)batch;
342d89352a9SBen Walker 	struct spdk_bs_channel		*channel = set->channel;
343d89352a9SBen Walker 
3443e717065STomasz Kulasek 	SPDK_DEBUGLOG(SPDK_LOG_BLOB_RW, "Reading %" PRIu32 " blocks from LBA %" PRIu64 "\n", lba_count,
3453e717065STomasz Kulasek 		      lba);
346d89352a9SBen Walker 
347d89352a9SBen Walker 	set->u.batch.outstanding_ops++;
3484dc04dc6SPiotr Pelplinski 	bs_dev->read(bs_dev, spdk_io_channel_from_ctx(channel), payload, lba, lba_count, &set->cb_args);
3490e917256SMaciej Szwed }
3500e917256SMaciej Szwed 
3510e917256SMaciej Szwed void
352c4659139SJim Harris spdk_bs_batch_read_dev(spdk_bs_batch_t *batch, void *payload,
3530e917256SMaciej Szwed 		       uint64_t lba, uint32_t lba_count)
3540e917256SMaciej Szwed {
3550e917256SMaciej Szwed 	struct spdk_bs_request_set	*set = (struct spdk_bs_request_set *)batch;
3560e917256SMaciej Szwed 	struct spdk_bs_channel		*channel = set->channel;
3570e917256SMaciej Szwed 
3583e717065STomasz Kulasek 	SPDK_DEBUGLOG(SPDK_LOG_BLOB_RW, "Reading %" PRIu32 " blocks from LBA %" PRIu64 "\n", lba_count,
3593e717065STomasz Kulasek 		      lba);
3603e717065STomasz Kulasek 
3614dc04dc6SPiotr Pelplinski 	set->u.batch.outstanding_ops++;
3624dc04dc6SPiotr Pelplinski 	channel->dev->read(channel->dev, channel->dev_channel, payload, lba, lba_count, &set->cb_args);
363d89352a9SBen Walker }
364d89352a9SBen Walker 
365d89352a9SBen Walker void
366c4659139SJim Harris spdk_bs_batch_write_dev(spdk_bs_batch_t *batch, void *payload,
367d89352a9SBen Walker 			uint64_t lba, uint32_t lba_count)
368d89352a9SBen Walker {
369d89352a9SBen Walker 	struct spdk_bs_request_set	*set = (struct spdk_bs_request_set *)batch;
370d89352a9SBen Walker 	struct spdk_bs_channel		*channel = set->channel;
371d89352a9SBen Walker 
3723e717065STomasz Kulasek 	SPDK_DEBUGLOG(SPDK_LOG_BLOB_RW, "Writing %" PRIu32 " blocks to LBA %" PRIu64 "\n", lba_count, lba);
373d89352a9SBen Walker 
374d89352a9SBen Walker 	set->u.batch.outstanding_ops++;
375d89352a9SBen Walker 	channel->dev->write(channel->dev, channel->dev_channel, payload, lba, lba_count,
376d89352a9SBen Walker 			    &set->cb_args);
377d89352a9SBen Walker }
378d89352a9SBen Walker 
379d89352a9SBen Walker void
380c4659139SJim Harris spdk_bs_batch_unmap_dev(spdk_bs_batch_t *batch,
381d89352a9SBen Walker 			uint64_t lba, uint32_t lba_count)
382d89352a9SBen Walker {
383d89352a9SBen Walker 	struct spdk_bs_request_set	*set = (struct spdk_bs_request_set *)batch;
384d89352a9SBen Walker 	struct spdk_bs_channel		*channel = set->channel;
385d89352a9SBen Walker 
3863e717065STomasz Kulasek 	SPDK_DEBUGLOG(SPDK_LOG_BLOB_RW, "Unmapping %" PRIu32 " blocks at LBA %" PRIu64 "\n", lba_count,
3873e717065STomasz Kulasek 		      lba);
388d89352a9SBen Walker 
389d89352a9SBen Walker 	set->u.batch.outstanding_ops++;
390d89352a9SBen Walker 	channel->dev->unmap(channel->dev, channel->dev_channel, lba, lba_count,
391d89352a9SBen Walker 			    &set->cb_args);
392d89352a9SBen Walker }
393d89352a9SBen Walker 
394d89352a9SBen Walker void
395c4659139SJim Harris spdk_bs_batch_write_zeroes_dev(spdk_bs_batch_t *batch,
3963f9cbe51SSeth Howell 			       uint64_t lba, uint32_t lba_count)
3973f9cbe51SSeth Howell {
3983f9cbe51SSeth Howell 	struct spdk_bs_request_set	*set = (struct spdk_bs_request_set *)batch;
3993f9cbe51SSeth Howell 	struct spdk_bs_channel		*channel = set->channel;
4003f9cbe51SSeth Howell 
4013e717065STomasz Kulasek 	SPDK_DEBUGLOG(SPDK_LOG_BLOB_RW, "Zeroing %" PRIu32 " blocks at LBA %" PRIu64 "\n", lba_count, lba);
4023f9cbe51SSeth Howell 
4033f9cbe51SSeth Howell 	set->u.batch.outstanding_ops++;
4043f9cbe51SSeth Howell 	channel->dev->write_zeroes(channel->dev, channel->dev_channel, lba, lba_count,
4053f9cbe51SSeth Howell 				   &set->cb_args);
4063f9cbe51SSeth Howell }
4073f9cbe51SSeth Howell 
408a5ecbadbSJim Harris static void
409a5ecbadbSJim Harris spdk_bs_batch_blob_op_complete(void *arg, int bserrno)
410a5ecbadbSJim Harris {
411a5ecbadbSJim Harris 	/* TODO: spdk_bs_batch_completion does not actually use the channel parameter -
412a5ecbadbSJim Harris 	 *  just pass NULL here instead of getting the channel from the set cb_arg.
413a5ecbadbSJim Harris 	 */
414a5ecbadbSJim Harris 	spdk_bs_batch_completion(NULL, arg, bserrno);
415a5ecbadbSJim Harris }
416a5ecbadbSJim Harris 
417a5ecbadbSJim Harris void
418a5ecbadbSJim Harris spdk_bs_batch_read_blob(spdk_bs_batch_t *batch, struct spdk_blob *blob,
419a5ecbadbSJim Harris 			void *payload, uint64_t offset, uint64_t length)
420a5ecbadbSJim Harris {
421a5ecbadbSJim Harris 	struct spdk_bs_request_set	*set = (struct spdk_bs_request_set *)batch;
422a5ecbadbSJim Harris 	struct spdk_bs_channel		*channel = set->channel;
423a5ecbadbSJim Harris 
4243e717065STomasz Kulasek 	SPDK_DEBUGLOG(SPDK_LOG_BLOB_RW, "Reading %" PRIu64 " pages from offset %" PRIu64 "\n", length,
4253e717065STomasz Kulasek 		      offset);
426a5ecbadbSJim Harris 
427a5ecbadbSJim Harris 	set->u.batch.outstanding_ops++;
42866fc591fSJim Harris 	spdk_blob_io_read(blob, spdk_io_channel_from_ctx(channel), payload, offset,
429a5ecbadbSJim Harris 			  length, spdk_bs_batch_blob_op_complete, set);
430a5ecbadbSJim Harris }
431a5ecbadbSJim Harris 
432a5ecbadbSJim Harris void
433a5ecbadbSJim Harris spdk_bs_batch_write_blob(spdk_bs_batch_t *batch, struct spdk_blob *blob,
434a5ecbadbSJim Harris 			 void *payload, uint64_t offset, uint64_t length)
435a5ecbadbSJim Harris {
436a5ecbadbSJim Harris 	struct spdk_bs_request_set	*set = (struct spdk_bs_request_set *)batch;
437a5ecbadbSJim Harris 	struct spdk_bs_channel		*channel = set->channel;
438a5ecbadbSJim Harris 
4393e717065STomasz Kulasek 	SPDK_DEBUGLOG(SPDK_LOG_BLOB_RW, "Writing %" PRIu64 " pages from offset %" PRIu64 "\n", length,
4403e717065STomasz Kulasek 		      offset);
441a5ecbadbSJim Harris 
442a5ecbadbSJim Harris 	set->u.batch.outstanding_ops++;
44366fc591fSJim Harris 	spdk_blob_io_write(blob, spdk_io_channel_from_ctx(channel), payload, offset,
444a5ecbadbSJim Harris 			   length, spdk_bs_batch_blob_op_complete, set);
445a5ecbadbSJim Harris }
446a5ecbadbSJim Harris 
447a5ecbadbSJim Harris void
448a5ecbadbSJim Harris spdk_bs_batch_unmap_blob(spdk_bs_batch_t *batch, struct spdk_blob *blob,
449a5ecbadbSJim Harris 			 uint64_t offset, uint64_t length)
450a5ecbadbSJim Harris {
451a5ecbadbSJim Harris 	struct spdk_bs_request_set	*set = (struct spdk_bs_request_set *)batch;
452a5ecbadbSJim Harris 	struct spdk_bs_channel		*channel = set->channel;
453a5ecbadbSJim Harris 
4543e717065STomasz Kulasek 	SPDK_DEBUGLOG(SPDK_LOG_BLOB_RW, "Unmapping %" PRIu64 " pages from offset %" PRIu64 "\n", length,
4553e717065STomasz Kulasek 		      offset);
456a5ecbadbSJim Harris 
457a5ecbadbSJim Harris 	set->u.batch.outstanding_ops++;
45866fc591fSJim Harris 	spdk_blob_io_unmap(blob, spdk_io_channel_from_ctx(channel), offset, length,
459a5ecbadbSJim Harris 			   spdk_bs_batch_blob_op_complete, set);
460a5ecbadbSJim Harris }
461a5ecbadbSJim Harris 
462a5ecbadbSJim Harris void
463a5ecbadbSJim Harris spdk_bs_batch_write_zeroes_blob(spdk_bs_batch_t *batch, struct spdk_blob *blob,
464a5ecbadbSJim Harris 				uint64_t offset, uint64_t length)
465a5ecbadbSJim Harris {
466a5ecbadbSJim Harris 	struct spdk_bs_request_set	*set = (struct spdk_bs_request_set *)batch;
467a5ecbadbSJim Harris 	struct spdk_bs_channel		*channel = set->channel;
468a5ecbadbSJim Harris 
4693e717065STomasz Kulasek 	SPDK_DEBUGLOG(SPDK_LOG_BLOB_RW, "Zeroing %" PRIu64 " pages from offset %" PRIu64 "\n", length,
4703e717065STomasz Kulasek 		      offset);
471a5ecbadbSJim Harris 
472a5ecbadbSJim Harris 	set->u.batch.outstanding_ops++;
47366fc591fSJim Harris 	spdk_blob_io_write_zeroes(blob, spdk_io_channel_from_ctx(channel), offset, length,
474a5ecbadbSJim Harris 				  spdk_bs_batch_blob_op_complete, set);
475a5ecbadbSJim Harris }
476a5ecbadbSJim Harris 
4773f9cbe51SSeth Howell void
4784132ac52SMaciej Szwed spdk_bs_batch_set_errno(spdk_bs_batch_t *batch, int bserrno)
4794132ac52SMaciej Szwed {
4804132ac52SMaciej Szwed 	struct spdk_bs_request_set	*set = (struct spdk_bs_request_set *)batch;
4814132ac52SMaciej Szwed 
4824132ac52SMaciej Szwed 	set->bserrno = bserrno;
4834132ac52SMaciej Szwed }
4844132ac52SMaciej Szwed 
4854132ac52SMaciej Szwed void
486d89352a9SBen Walker spdk_bs_batch_close(spdk_bs_batch_t *batch)
487d89352a9SBen Walker {
488d89352a9SBen Walker 	struct spdk_bs_request_set	*set = (struct spdk_bs_request_set *)batch;
489d89352a9SBen Walker 
490d89352a9SBen Walker 	set->u.batch.batch_closed = 1;
491d89352a9SBen Walker 
492d89352a9SBen Walker 	if (set->u.batch.outstanding_ops == 0) {
493d89352a9SBen Walker 		if (set->u.batch.cb_fn) {
494d89352a9SBen Walker 			set->cb_args.cb_fn = spdk_bs_sequence_completion;
495d89352a9SBen Walker 			set->u.batch.cb_fn((spdk_bs_sequence_t *)set, set->u.batch.cb_arg, set->bserrno);
496d89352a9SBen Walker 		} else {
497d89352a9SBen Walker 			spdk_bs_request_set_complete(set);
498d89352a9SBen Walker 		}
499d89352a9SBen Walker 	}
500d89352a9SBen Walker }
501d89352a9SBen Walker 
502d89352a9SBen Walker spdk_bs_batch_t *
503d89352a9SBen Walker spdk_bs_sequence_to_batch(spdk_bs_sequence_t *seq, spdk_bs_sequence_cpl cb_fn, void *cb_arg)
504d89352a9SBen Walker {
505d89352a9SBen Walker 	struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)seq;
506d89352a9SBen Walker 
507d89352a9SBen Walker 	set->u.batch.cb_fn = cb_fn;
508d89352a9SBen Walker 	set->u.batch.cb_arg = cb_arg;
509d89352a9SBen Walker 	set->u.batch.outstanding_ops = 0;
510d89352a9SBen Walker 	set->u.batch.batch_closed = 0;
511d89352a9SBen Walker 
512d89352a9SBen Walker 	set->cb_args.cb_fn = spdk_bs_batch_completion;
513d89352a9SBen Walker 
514d89352a9SBen Walker 	return set;
515d89352a9SBen Walker }
516d89352a9SBen Walker 
5174132ac52SMaciej Szwed spdk_bs_sequence_t *
5184132ac52SMaciej Szwed spdk_bs_batch_to_sequence(spdk_bs_batch_t *batch)
5194132ac52SMaciej Szwed {
5204132ac52SMaciej Szwed 	struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)batch;
5214132ac52SMaciej Szwed 
5224132ac52SMaciej Szwed 	set->u.batch.outstanding_ops++;
5234132ac52SMaciej Szwed 
5244132ac52SMaciej Szwed 	set->cpl.type = SPDK_BS_CPL_TYPE_BLOB_BASIC;
5254132ac52SMaciej Szwed 	set->cpl.u.blob_basic.cb_fn = spdk_bs_sequence_to_batch_completion;
5264132ac52SMaciej Szwed 	set->cpl.u.blob_basic.cb_arg = set;
5274132ac52SMaciej Szwed 	set->bserrno = 0;
5284132ac52SMaciej Szwed 
5294132ac52SMaciej Szwed 	set->cb_args.cb_fn = spdk_bs_sequence_completion;
5304132ac52SMaciej Szwed 	set->cb_args.cb_arg = set;
5314132ac52SMaciej Szwed 	set->cb_args.channel = set->channel->dev_channel;
5324132ac52SMaciej Szwed 
5334132ac52SMaciej Szwed 	return (spdk_bs_sequence_t *)set;
5344132ac52SMaciej Szwed }
5354132ac52SMaciej Szwed 
536b2503cb3SJim Harris spdk_bs_user_op_t *
537b2503cb3SJim Harris spdk_bs_user_op_alloc(struct spdk_io_channel *_channel, struct spdk_bs_cpl *cpl,
538b2503cb3SJim Harris 		      enum spdk_blob_op_type op_type, struct spdk_blob *blob,
539b2503cb3SJim Harris 		      void *payload, int iovcnt, uint64_t offset, uint64_t length)
540b2503cb3SJim Harris {
541b2503cb3SJim Harris 	struct spdk_bs_channel		*channel;
542b2503cb3SJim Harris 	struct spdk_bs_request_set	*set;
543b2503cb3SJim Harris 	struct spdk_bs_user_op_args	*args;
544b2503cb3SJim Harris 
545b2503cb3SJim Harris 	channel = spdk_io_channel_get_ctx(_channel);
546b2503cb3SJim Harris 
547b2503cb3SJim Harris 	set = TAILQ_FIRST(&channel->reqs);
548b2503cb3SJim Harris 	if (!set) {
549b2503cb3SJim Harris 		return NULL;
550b2503cb3SJim Harris 	}
551b2503cb3SJim Harris 	TAILQ_REMOVE(&channel->reqs, set, link);
552b2503cb3SJim Harris 
553b2503cb3SJim Harris 	set->cpl = *cpl;
554b2503cb3SJim Harris 	set->channel = channel;
555b2503cb3SJim Harris 
556b2503cb3SJim Harris 	args = &set->u.user_op;
557b2503cb3SJim Harris 
558b2503cb3SJim Harris 	args->type = op_type;
55968b8237cSMaciej Szwed 	args->iovcnt = iovcnt;
560b2503cb3SJim Harris 	args->blob = blob;
561b2503cb3SJim Harris 	args->offset = offset;
562b2503cb3SJim Harris 	args->length = length;
563b2503cb3SJim Harris 	args->payload = payload;
564b2503cb3SJim Harris 
565b2503cb3SJim Harris 	return (spdk_bs_user_op_t *)set;
566b2503cb3SJim Harris }
567b2503cb3SJim Harris 
568b2503cb3SJim Harris void
569b2503cb3SJim Harris spdk_bs_user_op_execute(spdk_bs_user_op_t *op)
570b2503cb3SJim Harris {
571b2503cb3SJim Harris 	struct spdk_bs_request_set	*set;
572b2503cb3SJim Harris 	struct spdk_bs_user_op_args	*args;
573b2503cb3SJim Harris 	struct spdk_io_channel		*ch;
574b2503cb3SJim Harris 
575b2503cb3SJim Harris 	set = (struct spdk_bs_request_set *)op;
576b2503cb3SJim Harris 	args = &set->u.user_op;
577b2503cb3SJim Harris 	ch = spdk_io_channel_from_ctx(set->channel);
578b2503cb3SJim Harris 
579b2503cb3SJim Harris 	switch (args->type) {
580b2503cb3SJim Harris 	case SPDK_BLOB_READ:
58166fc591fSJim Harris 		spdk_blob_io_read(args->blob, ch, args->payload, args->offset, args->length,
582b2503cb3SJim Harris 				  set->cpl.u.blob_basic.cb_fn, set->cpl.u.blob_basic.cb_arg);
583b2503cb3SJim Harris 		break;
584b2503cb3SJim Harris 	case SPDK_BLOB_WRITE:
58566fc591fSJim Harris 		spdk_blob_io_write(args->blob, ch, args->payload, args->offset, args->length,
586b2503cb3SJim Harris 				   set->cpl.u.blob_basic.cb_fn, set->cpl.u.blob_basic.cb_arg);
587b2503cb3SJim Harris 		break;
588b2503cb3SJim Harris 	case SPDK_BLOB_UNMAP:
58966fc591fSJim Harris 		spdk_blob_io_unmap(args->blob, ch, args->offset, args->length,
590b2503cb3SJim Harris 				   set->cpl.u.blob_basic.cb_fn, set->cpl.u.blob_basic.cb_arg);
591b2503cb3SJim Harris 		break;
592b2503cb3SJim Harris 	case SPDK_BLOB_WRITE_ZEROES:
59366fc591fSJim Harris 		spdk_blob_io_write_zeroes(args->blob, ch, args->offset, args->length,
594b2503cb3SJim Harris 					  set->cpl.u.blob_basic.cb_fn, set->cpl.u.blob_basic.cb_arg);
595b2503cb3SJim Harris 		break;
596b2503cb3SJim Harris 	case SPDK_BLOB_READV:
59766fc591fSJim Harris 		spdk_blob_io_readv(args->blob, ch, args->payload, args->iovcnt,
598b2503cb3SJim Harris 				   args->offset, args->length,
599b2503cb3SJim Harris 				   set->cpl.u.blob_basic.cb_fn, set->cpl.u.blob_basic.cb_arg);
600b2503cb3SJim Harris 		break;
601b2503cb3SJim Harris 	case SPDK_BLOB_WRITEV:
60266fc591fSJim Harris 		spdk_blob_io_writev(args->blob, ch, args->payload, args->iovcnt,
603b2503cb3SJim Harris 				    args->offset, args->length,
604b2503cb3SJim Harris 				    set->cpl.u.blob_basic.cb_fn, set->cpl.u.blob_basic.cb_arg);
605b2503cb3SJim Harris 		break;
606b2503cb3SJim Harris 	}
607b2503cb3SJim Harris 	TAILQ_INSERT_TAIL(&set->channel->reqs, set, link);
608b2503cb3SJim Harris }
609b2503cb3SJim Harris 
610b2503cb3SJim Harris void
611b2503cb3SJim Harris spdk_bs_user_op_abort(spdk_bs_user_op_t *op)
612b2503cb3SJim Harris {
613b2503cb3SJim Harris 	struct spdk_bs_request_set	*set;
614b2503cb3SJim Harris 
615b2503cb3SJim Harris 	set = (struct spdk_bs_request_set *)op;
616b2503cb3SJim Harris 
617b2503cb3SJim Harris 	set->cpl.u.blob_basic.cb_fn(set->cpl.u.blob_basic.cb_arg, -EIO);
618b2503cb3SJim Harris 	TAILQ_INSERT_TAIL(&set->channel->reqs, set, link);
619b2503cb3SJim Harris }
620b2503cb3SJim Harris 
6214132ac52SMaciej Szwed void
6224132ac52SMaciej Szwed spdk_bs_sequence_to_batch_completion(void *cb_arg, int bserrno)
6234132ac52SMaciej Szwed {
6244132ac52SMaciej Szwed 	struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)cb_arg;
6254132ac52SMaciej Szwed 
6264132ac52SMaciej Szwed 	set->u.batch.outstanding_ops--;
6274132ac52SMaciej Szwed 
6284132ac52SMaciej Szwed 	if (set->u.batch.outstanding_ops == 0 && set->u.batch.batch_closed) {
6294132ac52SMaciej Szwed 		if (set->cb_args.cb_fn) {
6304132ac52SMaciej Szwed 			set->cb_args.cb_fn(set->cb_args.channel, set->cb_args.cb_arg, bserrno);
6314132ac52SMaciej Szwed 		}
6324132ac52SMaciej Szwed 	}
6334132ac52SMaciej Szwed }
6344132ac52SMaciej Szwed 
635ea1c1579SDaniel Verkamp SPDK_LOG_REGISTER_COMPONENT("blob_rw", SPDK_LOG_BLOB_RW)
636