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