1488570ebSJim Harris /* SPDX-License-Identifier: BSD-3-Clause 2a6dbe372Spaul luse * Copyright (C) 2017 Intel Corporation. 3d89352a9SBen Walker * All rights reserved. 431c2852bSMike Gerdts * Copyright (c) 2022-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 5d89352a9SBen Walker */ 6d89352a9SBen Walker 7b961d9ccSBen Walker #include "spdk/stdinc.h" 8d89352a9SBen Walker 9d89352a9SBen Walker #include "blobstore.h" 10d89352a9SBen Walker #include "request.h" 11d89352a9SBen Walker 12a83f91c2SBen Walker #include "spdk/thread.h" 13d89352a9SBen Walker #include "spdk/queue.h" 14*c6c1234dSxupeng-mingtu #include "spdk/trace.h" 15d89352a9SBen Walker 16*c6c1234dSxupeng-mingtu #include "spdk_internal/trace_defs.h" 174e8e97c8STomasz Zawadzki #include "spdk/log.h" 18d89352a9SBen Walker 19d89352a9SBen Walker void 20ad7fdd12SSeth Howell bs_call_cpl(struct spdk_bs_cpl *cpl, int bserrno) 21d89352a9SBen Walker { 22d89352a9SBen Walker switch (cpl->type) { 23d89352a9SBen Walker case SPDK_BS_CPL_TYPE_BS_BASIC: 24d89352a9SBen Walker cpl->u.bs_basic.cb_fn(cpl->u.bs_basic.cb_arg, 25d89352a9SBen Walker bserrno); 26d89352a9SBen Walker break; 27d89352a9SBen Walker case SPDK_BS_CPL_TYPE_BS_HANDLE: 28d89352a9SBen Walker cpl->u.bs_handle.cb_fn(cpl->u.bs_handle.cb_arg, 296ff6f6d6SJim Harris bserrno == 0 ? cpl->u.bs_handle.bs : NULL, 30d89352a9SBen Walker bserrno); 31d89352a9SBen Walker break; 32d89352a9SBen Walker case SPDK_BS_CPL_TYPE_BLOB_BASIC: 33d89352a9SBen Walker cpl->u.blob_basic.cb_fn(cpl->u.blob_basic.cb_arg, 34d89352a9SBen Walker bserrno); 35d89352a9SBen Walker break; 36d89352a9SBen Walker case SPDK_BS_CPL_TYPE_BLOBID: 37d89352a9SBen Walker cpl->u.blobid.cb_fn(cpl->u.blobid.cb_arg, 386ff6f6d6SJim Harris bserrno == 0 ? cpl->u.blobid.blobid : SPDK_BLOBID_INVALID, 39d89352a9SBen Walker bserrno); 40d89352a9SBen Walker break; 41d89352a9SBen Walker case SPDK_BS_CPL_TYPE_BLOB_HANDLE: 42d89352a9SBen Walker cpl->u.blob_handle.cb_fn(cpl->u.blob_handle.cb_arg, 436ff6f6d6SJim Harris bserrno == 0 ? cpl->u.blob_handle.blob : NULL, 44d89352a9SBen Walker bserrno); 45d89352a9SBen Walker break; 46d89352a9SBen Walker case SPDK_BS_CPL_TYPE_NESTED_SEQUENCE: 47d89352a9SBen Walker cpl->u.nested_seq.cb_fn(cpl->u.nested_seq.cb_arg, 48d89352a9SBen Walker cpl->u.nested_seq.parent, 49d89352a9SBen Walker bserrno); 50d89352a9SBen Walker break; 51130d278aSPaul Luse case SPDK_BS_CPL_TYPE_NONE: 52130d278aSPaul Luse /* this completion's callback is handled elsewhere */ 53130d278aSPaul Luse break; 54d89352a9SBen Walker } 55d89352a9SBen Walker } 56d89352a9SBen Walker 57d89352a9SBen Walker static void 583456377bSSeth Howell bs_request_set_complete(struct spdk_bs_request_set *set) 59d89352a9SBen Walker { 60d89352a9SBen Walker struct spdk_bs_cpl cpl = set->cpl; 61d89352a9SBen Walker int bserrno = set->bserrno; 62d89352a9SBen Walker 63*c6c1234dSxupeng-mingtu spdk_trace_record(TRACE_BLOB_REQ_SET_COMPLETE, 0, 0, (uintptr_t)&set->cb_args, 64*c6c1234dSxupeng-mingtu (uintptr_t)set->cpl.u.blob_basic.cb_arg); 65*c6c1234dSxupeng-mingtu 66d89352a9SBen Walker TAILQ_INSERT_TAIL(&set->channel->reqs, set, link); 67d89352a9SBen Walker 68ad7fdd12SSeth Howell bs_call_cpl(&cpl, bserrno); 69d89352a9SBen Walker } 70d89352a9SBen Walker 71d89352a9SBen Walker static void 723456377bSSeth Howell bs_sequence_completion(struct spdk_io_channel *channel, void *cb_arg, int bserrno) 73d89352a9SBen Walker { 74d89352a9SBen Walker struct spdk_bs_request_set *set = cb_arg; 75d89352a9SBen Walker 76d89352a9SBen Walker set->bserrno = bserrno; 77d89352a9SBen Walker set->u.sequence.cb_fn((spdk_bs_sequence_t *)set, set->u.sequence.cb_arg, bserrno); 78d89352a9SBen Walker } 79d89352a9SBen Walker 80b47cee6cSMike Gerdts static inline spdk_bs_sequence_t * 81b47cee6cSMike Gerdts bs_sequence_start(struct spdk_io_channel *_channel, struct spdk_bs_cpl *cpl, 82b47cee6cSMike Gerdts struct spdk_io_channel *back_channel) 83d89352a9SBen Walker { 84d89352a9SBen Walker struct spdk_bs_channel *channel; 85d89352a9SBen Walker struct spdk_bs_request_set *set; 86d89352a9SBen Walker 87d89352a9SBen Walker channel = spdk_io_channel_get_ctx(_channel); 8804ce0e12Syidong0635 assert(channel != NULL); 89d89352a9SBen Walker set = TAILQ_FIRST(&channel->reqs); 90d89352a9SBen Walker if (!set) { 91d89352a9SBen Walker return NULL; 92d89352a9SBen Walker } 93d89352a9SBen Walker TAILQ_REMOVE(&channel->reqs, set, link); 94d89352a9SBen Walker 95*c6c1234dSxupeng-mingtu spdk_trace_record(TRACE_BLOB_REQ_SET_START, 0, 0, (uintptr_t)&set->cb_args, 96*c6c1234dSxupeng-mingtu (uintptr_t)cpl->u.blob_basic.cb_arg); 97*c6c1234dSxupeng-mingtu 98d89352a9SBen Walker set->cpl = *cpl; 99d89352a9SBen Walker set->bserrno = 0; 100d89352a9SBen Walker set->channel = channel; 101b47cee6cSMike Gerdts set->back_channel = back_channel; 102d89352a9SBen Walker 1033456377bSSeth Howell set->cb_args.cb_fn = bs_sequence_completion; 104d89352a9SBen Walker set->cb_args.cb_arg = set; 105d89352a9SBen Walker set->cb_args.channel = channel->dev_channel; 106a2360845SAlexey Marchuk set->ext_io_opts = NULL; 107d89352a9SBen Walker 108d89352a9SBen Walker return (spdk_bs_sequence_t *)set; 109d89352a9SBen Walker } 110d89352a9SBen Walker 1112948183fSMike Gerdts /* Use when performing IO directly on the blobstore (e.g. metadata - not a blob). */ 1122948183fSMike Gerdts spdk_bs_sequence_t * 1132948183fSMike Gerdts bs_sequence_start_bs(struct spdk_io_channel *_channel, struct spdk_bs_cpl *cpl) 1142948183fSMike Gerdts { 115b47cee6cSMike Gerdts return bs_sequence_start(_channel, cpl, _channel); 1162948183fSMike Gerdts } 1172948183fSMike Gerdts 1182948183fSMike Gerdts /* Use when performing IO on a blob. */ 1192948183fSMike Gerdts spdk_bs_sequence_t * 1202948183fSMike Gerdts bs_sequence_start_blob(struct spdk_io_channel *_channel, struct spdk_bs_cpl *cpl, 1212948183fSMike Gerdts struct spdk_blob *blob) 1222948183fSMike Gerdts { 123b47cee6cSMike Gerdts struct spdk_io_channel *esnap_ch = _channel; 124b47cee6cSMike Gerdts 125b47cee6cSMike Gerdts if (spdk_blob_is_esnap_clone(blob)) { 126b47cee6cSMike Gerdts esnap_ch = blob_esnap_get_io_channel(_channel, blob); 127b47cee6cSMike Gerdts if (esnap_ch == NULL) { 128b47cee6cSMike Gerdts /* 129b47cee6cSMike Gerdts * The most likely reason we are here is because of some logic error 130b47cee6cSMike Gerdts * elsewhere that caused channel allocations to fail. We could get here due 131b47cee6cSMike Gerdts * to being out of memory as well. If we are out of memory, the process is 132b47cee6cSMike Gerdts * this will be just one of many problems that this process will be having. 133b47cee6cSMike Gerdts * Killing it off debug builds now due to logic errors is the right thing to 134b47cee6cSMike Gerdts * do and killing it off due to ENOMEM is no big loss. 135b47cee6cSMike Gerdts */ 136b47cee6cSMike Gerdts assert(false); 137b47cee6cSMike Gerdts return NULL; 138b47cee6cSMike Gerdts } 139b47cee6cSMike Gerdts } 140b47cee6cSMike Gerdts return bs_sequence_start(_channel, cpl, esnap_ch); 1412948183fSMike Gerdts } 1422948183fSMike Gerdts 143d89352a9SBen Walker void 144ad7fdd12SSeth Howell bs_sequence_read_bs_dev(spdk_bs_sequence_t *seq, struct spdk_bs_dev *bs_dev, 1450e917256SMaciej Szwed void *payload, uint64_t lba, uint32_t lba_count, 146d89352a9SBen Walker spdk_bs_sequence_cpl cb_fn, void *cb_arg) 147d89352a9SBen Walker { 148d89352a9SBen Walker struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)seq; 14931c2852bSMike Gerdts struct spdk_io_channel *back_channel = set->back_channel; 150d89352a9SBen Walker 1512172c432STomasz Zawadzki SPDK_DEBUGLOG(blob_rw, "Reading %" PRIu32 " blocks from LBA %" PRIu64 "\n", lba_count, 1523e717065STomasz Kulasek lba); 153d89352a9SBen Walker 154d89352a9SBen Walker set->u.sequence.cb_fn = cb_fn; 155d89352a9SBen Walker set->u.sequence.cb_arg = cb_arg; 156d89352a9SBen Walker 15731c2852bSMike Gerdts bs_dev->read(bs_dev, back_channel, payload, lba, lba_count, &set->cb_args); 1580e917256SMaciej Szwed } 1590e917256SMaciej Szwed 1600e917256SMaciej Szwed void 161ad7fdd12SSeth Howell bs_sequence_read_dev(spdk_bs_sequence_t *seq, void *payload, 1620e917256SMaciej Szwed uint64_t lba, uint32_t lba_count, 1630e917256SMaciej Szwed spdk_bs_sequence_cpl cb_fn, void *cb_arg) 1640e917256SMaciej Szwed { 1650e917256SMaciej Szwed struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)seq; 1660e917256SMaciej Szwed struct spdk_bs_channel *channel = set->channel; 1670e917256SMaciej Szwed 1682172c432STomasz Zawadzki SPDK_DEBUGLOG(blob_rw, "Reading %" PRIu32 " blocks from LBA %" PRIu64 "\n", lba_count, 1693e717065STomasz Kulasek lba); 1703e717065STomasz Kulasek 1714dc04dc6SPiotr Pelplinski set->u.sequence.cb_fn = cb_fn; 1724dc04dc6SPiotr Pelplinski set->u.sequence.cb_arg = cb_arg; 1734dc04dc6SPiotr Pelplinski 1744dc04dc6SPiotr Pelplinski channel->dev->read(channel->dev, channel->dev_channel, payload, lba, lba_count, &set->cb_args); 175d89352a9SBen Walker } 176d89352a9SBen Walker 177d89352a9SBen Walker void 178ad7fdd12SSeth Howell bs_sequence_write_dev(spdk_bs_sequence_t *seq, void *payload, 179d89352a9SBen Walker uint64_t lba, uint32_t lba_count, 180d89352a9SBen Walker spdk_bs_sequence_cpl cb_fn, void *cb_arg) 181d89352a9SBen Walker { 182d89352a9SBen Walker struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)seq; 183d89352a9SBen Walker struct spdk_bs_channel *channel = set->channel; 184d89352a9SBen Walker 1852172c432STomasz Zawadzki SPDK_DEBUGLOG(blob_rw, "Writing %" PRIu32 " blocks from LBA %" PRIu64 "\n", lba_count, 1863e717065STomasz Kulasek lba); 187d89352a9SBen Walker 188d89352a9SBen Walker set->u.sequence.cb_fn = cb_fn; 189d89352a9SBen Walker set->u.sequence.cb_arg = cb_arg; 190d89352a9SBen Walker 191d89352a9SBen Walker channel->dev->write(channel->dev, channel->dev_channel, payload, lba, lba_count, 192d89352a9SBen Walker &set->cb_args); 193d89352a9SBen Walker } 194d89352a9SBen Walker 195d89352a9SBen Walker void 196ad7fdd12SSeth Howell bs_sequence_readv_bs_dev(spdk_bs_sequence_t *seq, struct spdk_bs_dev *bs_dev, 1970e917256SMaciej Szwed struct iovec *iov, int iovcnt, uint64_t lba, uint32_t lba_count, 198179ed697SJim Harris spdk_bs_sequence_cpl cb_fn, void *cb_arg) 199179ed697SJim Harris { 200179ed697SJim Harris struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)seq; 20131c2852bSMike Gerdts struct spdk_io_channel *back_channel = set->back_channel; 202179ed697SJim Harris 2032172c432STomasz Zawadzki SPDK_DEBUGLOG(blob_rw, "Reading %" PRIu32 " blocks from LBA %" PRIu64 "\n", lba_count, 2043e717065STomasz Kulasek lba); 205179ed697SJim Harris 206179ed697SJim Harris set->u.sequence.cb_fn = cb_fn; 207179ed697SJim Harris set->u.sequence.cb_arg = cb_arg; 208179ed697SJim Harris 209a2360845SAlexey Marchuk if (set->ext_io_opts) { 210a2360845SAlexey Marchuk assert(bs_dev->readv_ext); 21131c2852bSMike Gerdts bs_dev->readv_ext(bs_dev, back_channel, iov, iovcnt, lba, lba_count, 212a2360845SAlexey Marchuk &set->cb_args, set->ext_io_opts); 213a2360845SAlexey Marchuk } else { 21431c2852bSMike Gerdts bs_dev->readv(bs_dev, back_channel, iov, iovcnt, lba, lba_count, &set->cb_args); 215179ed697SJim Harris } 216a2360845SAlexey Marchuk } 217179ed697SJim Harris 218179ed697SJim Harris void 219ad7fdd12SSeth Howell bs_sequence_readv_dev(spdk_bs_sequence_t *seq, struct iovec *iov, int iovcnt, 2200e917256SMaciej Szwed uint64_t lba, uint32_t lba_count, spdk_bs_sequence_cpl cb_fn, void *cb_arg) 2210e917256SMaciej Szwed { 2220e917256SMaciej Szwed struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)seq; 2230e917256SMaciej Szwed struct spdk_bs_channel *channel = set->channel; 2240e917256SMaciej Szwed 2252172c432STomasz Zawadzki SPDK_DEBUGLOG(blob_rw, "Reading %" PRIu32 " blocks from LBA %" PRIu64 "\n", lba_count, 2263e717065STomasz Kulasek lba); 2273e717065STomasz Kulasek 2284dc04dc6SPiotr Pelplinski set->u.sequence.cb_fn = cb_fn; 2294dc04dc6SPiotr Pelplinski set->u.sequence.cb_arg = cb_arg; 230a2360845SAlexey Marchuk if (set->ext_io_opts) { 231a2360845SAlexey Marchuk assert(channel->dev->readv_ext); 232a2360845SAlexey Marchuk channel->dev->readv_ext(channel->dev, channel->dev_channel, iov, iovcnt, lba, lba_count, 233a2360845SAlexey Marchuk &set->cb_args, set->ext_io_opts); 234a2360845SAlexey Marchuk } else { 235a2360845SAlexey Marchuk channel->dev->readv(channel->dev, channel->dev_channel, iov, iovcnt, lba, lba_count, &set->cb_args); 236a2360845SAlexey Marchuk } 2370e917256SMaciej Szwed } 2380e917256SMaciej Szwed 2390e917256SMaciej Szwed void 240ad7fdd12SSeth Howell bs_sequence_writev_dev(spdk_bs_sequence_t *seq, struct iovec *iov, int iovcnt, 241179ed697SJim Harris uint64_t lba, uint32_t lba_count, 242179ed697SJim Harris spdk_bs_sequence_cpl cb_fn, void *cb_arg) 243179ed697SJim Harris { 244179ed697SJim Harris struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)seq; 245179ed697SJim Harris struct spdk_bs_channel *channel = set->channel; 246179ed697SJim Harris 2472172c432STomasz Zawadzki SPDK_DEBUGLOG(blob_rw, "Writing %" PRIu32 " blocks from LBA %" PRIu64 "\n", lba_count, 2483e717065STomasz Kulasek lba); 249179ed697SJim Harris 250179ed697SJim Harris set->u.sequence.cb_fn = cb_fn; 251179ed697SJim Harris set->u.sequence.cb_arg = cb_arg; 252179ed697SJim Harris 253a2360845SAlexey Marchuk if (set->ext_io_opts) { 254a2360845SAlexey Marchuk assert(channel->dev->writev_ext); 255a2360845SAlexey Marchuk channel->dev->writev_ext(channel->dev, channel->dev_channel, iov, iovcnt, lba, lba_count, 256a2360845SAlexey Marchuk &set->cb_args, set->ext_io_opts); 257a2360845SAlexey Marchuk } else { 258179ed697SJim Harris channel->dev->writev(channel->dev, channel->dev_channel, iov, iovcnt, lba, lba_count, 259179ed697SJim Harris &set->cb_args); 260179ed697SJim Harris } 261a2360845SAlexey Marchuk } 262179ed697SJim Harris 263179ed697SJim Harris void 264ad7fdd12SSeth Howell bs_sequence_write_zeroes_dev(spdk_bs_sequence_t *seq, 265f01146aeSJim Harris uint64_t lba, uint64_t lba_count, 2663f9cbe51SSeth Howell spdk_bs_sequence_cpl cb_fn, void *cb_arg) 2673f9cbe51SSeth Howell { 2683f9cbe51SSeth Howell struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)seq; 2693f9cbe51SSeth Howell struct spdk_bs_channel *channel = set->channel; 2703f9cbe51SSeth Howell 271f01146aeSJim Harris SPDK_DEBUGLOG(blob_rw, "writing zeroes to %" PRIu64 " blocks at LBA %" PRIu64 "\n", 2723e717065STomasz Kulasek lba_count, lba); 2733f9cbe51SSeth Howell 2743f9cbe51SSeth Howell set->u.sequence.cb_fn = cb_fn; 2753f9cbe51SSeth Howell set->u.sequence.cb_arg = cb_arg; 2763f9cbe51SSeth Howell 2773f9cbe51SSeth Howell channel->dev->write_zeroes(channel->dev, channel->dev_channel, lba, lba_count, 2783f9cbe51SSeth Howell &set->cb_args); 2793f9cbe51SSeth Howell } 2803f9cbe51SSeth Howell 2813f9cbe51SSeth Howell void 282b7bfa504SEvgeniy Kochetov bs_sequence_copy_dev(spdk_bs_sequence_t *seq, uint64_t dst_lba, uint64_t src_lba, 283b7bfa504SEvgeniy Kochetov uint64_t lba_count, spdk_bs_sequence_cpl cb_fn, void *cb_arg) 284b7bfa504SEvgeniy Kochetov { 285b7bfa504SEvgeniy Kochetov struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)seq; 286b7bfa504SEvgeniy Kochetov struct spdk_bs_channel *channel = set->channel; 287b7bfa504SEvgeniy Kochetov 288b7bfa504SEvgeniy Kochetov SPDK_DEBUGLOG(blob_rw, "Copying %" PRIu64 " blocks from LBA %" PRIu64 " to LBA %" PRIu64 "\n", 289b7bfa504SEvgeniy Kochetov lba_count, src_lba, dst_lba); 290b7bfa504SEvgeniy Kochetov 291b7bfa504SEvgeniy Kochetov set->u.sequence.cb_fn = cb_fn; 292b7bfa504SEvgeniy Kochetov set->u.sequence.cb_arg = cb_arg; 293b7bfa504SEvgeniy Kochetov 294b7bfa504SEvgeniy Kochetov channel->dev->copy(channel->dev, channel->dev_channel, dst_lba, src_lba, lba_count, &set->cb_args); 295b7bfa504SEvgeniy Kochetov } 296b7bfa504SEvgeniy Kochetov 297b7bfa504SEvgeniy Kochetov void 298ad7fdd12SSeth Howell bs_sequence_finish(spdk_bs_sequence_t *seq, int bserrno) 299d89352a9SBen Walker { 300d89352a9SBen Walker if (bserrno != 0) { 301d89352a9SBen Walker seq->bserrno = bserrno; 302d89352a9SBen Walker } 3033456377bSSeth Howell bs_request_set_complete((struct spdk_bs_request_set *)seq); 304d89352a9SBen Walker } 305d89352a9SBen Walker 3064132ac52SMaciej Szwed void 307ad7fdd12SSeth Howell bs_user_op_sequence_finish(void *cb_arg, int bserrno) 3084132ac52SMaciej Szwed { 3094132ac52SMaciej Szwed spdk_bs_sequence_t *seq = cb_arg; 3104132ac52SMaciej Szwed 311ad7fdd12SSeth Howell bs_sequence_finish(seq, bserrno); 3124132ac52SMaciej Szwed } 3134132ac52SMaciej Szwed 314d89352a9SBen Walker static void 3153456377bSSeth Howell bs_batch_completion(struct spdk_io_channel *_channel, 316d89352a9SBen Walker void *cb_arg, int bserrno) 317d89352a9SBen Walker { 318d89352a9SBen Walker struct spdk_bs_request_set *set = cb_arg; 319d89352a9SBen Walker 320d89352a9SBen Walker set->u.batch.outstanding_ops--; 321d89352a9SBen Walker if (bserrno != 0) { 322d89352a9SBen Walker set->bserrno = bserrno; 323d89352a9SBen Walker } 324d89352a9SBen Walker 325d89352a9SBen Walker if (set->u.batch.outstanding_ops == 0 && set->u.batch.batch_closed) { 326d89352a9SBen Walker if (set->u.batch.cb_fn) { 3273456377bSSeth Howell set->cb_args.cb_fn = bs_sequence_completion; 328d89352a9SBen Walker set->u.batch.cb_fn((spdk_bs_sequence_t *)set, set->u.batch.cb_arg, bserrno); 329d89352a9SBen Walker } else { 3303456377bSSeth Howell bs_request_set_complete(set); 331d89352a9SBen Walker } 332d89352a9SBen Walker } 333d89352a9SBen Walker } 334d89352a9SBen Walker 335d89352a9SBen Walker spdk_bs_batch_t * 336b47cee6cSMike Gerdts bs_batch_open(struct spdk_io_channel *_channel, struct spdk_bs_cpl *cpl, struct spdk_blob *blob) 337d89352a9SBen Walker { 338d89352a9SBen Walker struct spdk_bs_channel *channel; 339d89352a9SBen Walker struct spdk_bs_request_set *set; 340b47cee6cSMike Gerdts struct spdk_io_channel *back_channel = _channel; 341b47cee6cSMike Gerdts 342b47cee6cSMike Gerdts if (spdk_blob_is_esnap_clone(blob)) { 343b47cee6cSMike Gerdts back_channel = blob_esnap_get_io_channel(_channel, blob); 344b47cee6cSMike Gerdts if (back_channel == NULL) { 345b47cee6cSMike Gerdts return NULL; 346b47cee6cSMike Gerdts } 347b47cee6cSMike Gerdts } 348d89352a9SBen Walker 349d89352a9SBen Walker channel = spdk_io_channel_get_ctx(_channel); 35004ce0e12Syidong0635 assert(channel != NULL); 351d89352a9SBen Walker set = TAILQ_FIRST(&channel->reqs); 352d89352a9SBen Walker if (!set) { 353d89352a9SBen Walker return NULL; 354d89352a9SBen Walker } 355d89352a9SBen Walker TAILQ_REMOVE(&channel->reqs, set, link); 356d89352a9SBen Walker 357*c6c1234dSxupeng-mingtu spdk_trace_record(TRACE_BLOB_REQ_SET_START, 0, 0, (uintptr_t)&set->cb_args, 358*c6c1234dSxupeng-mingtu (uintptr_t)cpl->u.blob_basic.cb_arg); 359*c6c1234dSxupeng-mingtu 360d89352a9SBen Walker set->cpl = *cpl; 361d89352a9SBen Walker set->bserrno = 0; 362d89352a9SBen Walker set->channel = channel; 363b47cee6cSMike Gerdts set->back_channel = back_channel; 364d89352a9SBen Walker 365d89352a9SBen Walker set->u.batch.cb_fn = NULL; 366d89352a9SBen Walker set->u.batch.cb_arg = NULL; 367d89352a9SBen Walker set->u.batch.outstanding_ops = 0; 368d89352a9SBen Walker set->u.batch.batch_closed = 0; 369d89352a9SBen Walker 3703456377bSSeth Howell set->cb_args.cb_fn = bs_batch_completion; 371d89352a9SBen Walker set->cb_args.cb_arg = set; 372d89352a9SBen Walker set->cb_args.channel = channel->dev_channel; 373d89352a9SBen Walker 374d89352a9SBen Walker return (spdk_bs_batch_t *)set; 375d89352a9SBen Walker } 376d89352a9SBen Walker 377d89352a9SBen Walker void 378964463e4SSeth Howell bs_batch_read_bs_dev(spdk_bs_batch_t *batch, struct spdk_bs_dev *bs_dev, 3790e917256SMaciej Szwed void *payload, uint64_t lba, uint32_t lba_count) 380d89352a9SBen Walker { 381d89352a9SBen Walker struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)batch; 38231c2852bSMike Gerdts struct spdk_io_channel *back_channel = set->back_channel; 383d89352a9SBen Walker 3842172c432STomasz Zawadzki SPDK_DEBUGLOG(blob_rw, "Reading %" PRIu32 " blocks from LBA %" PRIu64 "\n", lba_count, 3853e717065STomasz Kulasek lba); 386d89352a9SBen Walker 387d89352a9SBen Walker set->u.batch.outstanding_ops++; 38831c2852bSMike Gerdts bs_dev->read(bs_dev, back_channel, payload, lba, lba_count, &set->cb_args); 3890e917256SMaciej Szwed } 3900e917256SMaciej Szwed 3910e917256SMaciej Szwed void 392ad7fdd12SSeth Howell bs_batch_read_dev(spdk_bs_batch_t *batch, void *payload, 3930e917256SMaciej Szwed uint64_t lba, uint32_t lba_count) 3940e917256SMaciej Szwed { 3950e917256SMaciej Szwed struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)batch; 3960e917256SMaciej Szwed struct spdk_bs_channel *channel = set->channel; 3970e917256SMaciej Szwed 3982172c432STomasz Zawadzki SPDK_DEBUGLOG(blob_rw, "Reading %" PRIu32 " blocks from LBA %" PRIu64 "\n", lba_count, 3993e717065STomasz Kulasek lba); 4003e717065STomasz Kulasek 4014dc04dc6SPiotr Pelplinski set->u.batch.outstanding_ops++; 4024dc04dc6SPiotr Pelplinski channel->dev->read(channel->dev, channel->dev_channel, payload, lba, lba_count, &set->cb_args); 403d89352a9SBen Walker } 404d89352a9SBen Walker 405d89352a9SBen Walker void 406ad7fdd12SSeth Howell bs_batch_write_dev(spdk_bs_batch_t *batch, void *payload, 407d89352a9SBen Walker uint64_t lba, uint32_t lba_count) 408d89352a9SBen Walker { 409d89352a9SBen Walker struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)batch; 410d89352a9SBen Walker struct spdk_bs_channel *channel = set->channel; 411d89352a9SBen Walker 4122172c432STomasz Zawadzki SPDK_DEBUGLOG(blob_rw, "Writing %" PRIu32 " blocks to LBA %" PRIu64 "\n", lba_count, lba); 413d89352a9SBen Walker 414d89352a9SBen Walker set->u.batch.outstanding_ops++; 415d89352a9SBen Walker channel->dev->write(channel->dev, channel->dev_channel, payload, lba, lba_count, 416d89352a9SBen Walker &set->cb_args); 417d89352a9SBen Walker } 418d89352a9SBen Walker 419d89352a9SBen Walker void 420ad7fdd12SSeth Howell bs_batch_unmap_dev(spdk_bs_batch_t *batch, 421f01146aeSJim Harris uint64_t lba, uint64_t lba_count) 422d89352a9SBen Walker { 423d89352a9SBen Walker struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)batch; 424d89352a9SBen Walker struct spdk_bs_channel *channel = set->channel; 425d89352a9SBen Walker 426f01146aeSJim Harris SPDK_DEBUGLOG(blob_rw, "Unmapping %" PRIu64 " blocks at LBA %" PRIu64 "\n", lba_count, 4273e717065STomasz Kulasek lba); 428d89352a9SBen Walker 429d89352a9SBen Walker set->u.batch.outstanding_ops++; 430d89352a9SBen Walker channel->dev->unmap(channel->dev, channel->dev_channel, lba, lba_count, 431d89352a9SBen Walker &set->cb_args); 432d89352a9SBen Walker } 433d89352a9SBen Walker 434d89352a9SBen Walker void 435ad7fdd12SSeth Howell bs_batch_write_zeroes_dev(spdk_bs_batch_t *batch, 436f01146aeSJim Harris uint64_t lba, uint64_t lba_count) 4373f9cbe51SSeth Howell { 4383f9cbe51SSeth Howell struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)batch; 4393f9cbe51SSeth Howell struct spdk_bs_channel *channel = set->channel; 4403f9cbe51SSeth Howell 441f01146aeSJim Harris SPDK_DEBUGLOG(blob_rw, "Zeroing %" PRIu64 " blocks at LBA %" PRIu64 "\n", lba_count, lba); 4423f9cbe51SSeth Howell 4433f9cbe51SSeth Howell set->u.batch.outstanding_ops++; 4443f9cbe51SSeth Howell channel->dev->write_zeroes(channel->dev, channel->dev_channel, lba, lba_count, 4453f9cbe51SSeth Howell &set->cb_args); 4463f9cbe51SSeth Howell } 4473f9cbe51SSeth Howell 4484132ac52SMaciej Szwed void 449ad7fdd12SSeth Howell bs_batch_close(spdk_bs_batch_t *batch) 450d89352a9SBen Walker { 451d89352a9SBen Walker struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)batch; 452d89352a9SBen Walker 453d89352a9SBen Walker set->u.batch.batch_closed = 1; 454d89352a9SBen Walker 455d89352a9SBen Walker if (set->u.batch.outstanding_ops == 0) { 456d89352a9SBen Walker if (set->u.batch.cb_fn) { 4573456377bSSeth Howell set->cb_args.cb_fn = bs_sequence_completion; 458d89352a9SBen Walker set->u.batch.cb_fn((spdk_bs_sequence_t *)set, set->u.batch.cb_arg, set->bserrno); 459d89352a9SBen Walker } else { 4603456377bSSeth Howell bs_request_set_complete(set); 461d89352a9SBen Walker } 462d89352a9SBen Walker } 463d89352a9SBen Walker } 464d89352a9SBen Walker 465d89352a9SBen Walker spdk_bs_batch_t * 466ad7fdd12SSeth Howell bs_sequence_to_batch(spdk_bs_sequence_t *seq, spdk_bs_sequence_cpl cb_fn, void *cb_arg) 467d89352a9SBen Walker { 468d89352a9SBen Walker struct spdk_bs_request_set *set = (struct spdk_bs_request_set *)seq; 469d89352a9SBen Walker 470d89352a9SBen Walker set->u.batch.cb_fn = cb_fn; 471d89352a9SBen Walker set->u.batch.cb_arg = cb_arg; 472d89352a9SBen Walker set->u.batch.outstanding_ops = 0; 473d89352a9SBen Walker set->u.batch.batch_closed = 0; 474d89352a9SBen Walker 4753456377bSSeth Howell set->cb_args.cb_fn = bs_batch_completion; 476d89352a9SBen Walker 477d89352a9SBen Walker return set; 478d89352a9SBen Walker } 479d89352a9SBen Walker 480b2503cb3SJim Harris spdk_bs_user_op_t * 481ad7fdd12SSeth Howell bs_user_op_alloc(struct spdk_io_channel *_channel, struct spdk_bs_cpl *cpl, 482b2503cb3SJim Harris enum spdk_blob_op_type op_type, struct spdk_blob *blob, 483b2503cb3SJim Harris void *payload, int iovcnt, uint64_t offset, uint64_t length) 484b2503cb3SJim Harris { 485b2503cb3SJim Harris struct spdk_bs_channel *channel; 486b2503cb3SJim Harris struct spdk_bs_request_set *set; 487b2503cb3SJim Harris struct spdk_bs_user_op_args *args; 488b2503cb3SJim Harris 489b2503cb3SJim Harris channel = spdk_io_channel_get_ctx(_channel); 49004ce0e12Syidong0635 assert(channel != NULL); 491b2503cb3SJim Harris set = TAILQ_FIRST(&channel->reqs); 492b2503cb3SJim Harris if (!set) { 493b2503cb3SJim Harris return NULL; 494b2503cb3SJim Harris } 495b2503cb3SJim Harris TAILQ_REMOVE(&channel->reqs, set, link); 496b2503cb3SJim Harris 497*c6c1234dSxupeng-mingtu spdk_trace_record(TRACE_BLOB_REQ_SET_START, 0, 0, (uintptr_t)&set->cb_args, 498*c6c1234dSxupeng-mingtu (uintptr_t)cpl->u.blob_basic.cb_arg); 499*c6c1234dSxupeng-mingtu 500b2503cb3SJim Harris set->cpl = *cpl; 501b2503cb3SJim Harris set->channel = channel; 50231c2852bSMike Gerdts set->back_channel = NULL; 503a2360845SAlexey Marchuk set->ext_io_opts = NULL; 504b2503cb3SJim Harris 505b2503cb3SJim Harris args = &set->u.user_op; 506b2503cb3SJim Harris 507b2503cb3SJim Harris args->type = op_type; 50868b8237cSMaciej Szwed args->iovcnt = iovcnt; 509b2503cb3SJim Harris args->blob = blob; 510b2503cb3SJim Harris args->offset = offset; 511b2503cb3SJim Harris args->length = length; 512b2503cb3SJim Harris args->payload = payload; 513b2503cb3SJim Harris 514b2503cb3SJim Harris return (spdk_bs_user_op_t *)set; 515b2503cb3SJim Harris } 516b2503cb3SJim Harris 517b2503cb3SJim Harris void 518ad7fdd12SSeth Howell bs_user_op_execute(spdk_bs_user_op_t *op) 519b2503cb3SJim Harris { 520b2503cb3SJim Harris struct spdk_bs_request_set *set; 521b2503cb3SJim Harris struct spdk_bs_user_op_args *args; 522b2503cb3SJim Harris struct spdk_io_channel *ch; 523b2503cb3SJim Harris 524b2503cb3SJim Harris set = (struct spdk_bs_request_set *)op; 525b2503cb3SJim Harris args = &set->u.user_op; 526b2503cb3SJim Harris ch = spdk_io_channel_from_ctx(set->channel); 527b2503cb3SJim Harris 528b2503cb3SJim Harris switch (args->type) { 529b2503cb3SJim Harris case SPDK_BLOB_READ: 53066fc591fSJim Harris spdk_blob_io_read(args->blob, ch, args->payload, args->offset, args->length, 531b2503cb3SJim Harris set->cpl.u.blob_basic.cb_fn, set->cpl.u.blob_basic.cb_arg); 532b2503cb3SJim Harris break; 533b2503cb3SJim Harris case SPDK_BLOB_WRITE: 53466fc591fSJim Harris spdk_blob_io_write(args->blob, ch, args->payload, args->offset, args->length, 535b2503cb3SJim Harris set->cpl.u.blob_basic.cb_fn, set->cpl.u.blob_basic.cb_arg); 536b2503cb3SJim Harris break; 537b2503cb3SJim Harris case SPDK_BLOB_UNMAP: 53866fc591fSJim Harris spdk_blob_io_unmap(args->blob, ch, args->offset, args->length, 539b2503cb3SJim Harris set->cpl.u.blob_basic.cb_fn, set->cpl.u.blob_basic.cb_arg); 540b2503cb3SJim Harris break; 541b2503cb3SJim Harris case SPDK_BLOB_WRITE_ZEROES: 54266fc591fSJim Harris spdk_blob_io_write_zeroes(args->blob, ch, args->offset, args->length, 543b2503cb3SJim Harris set->cpl.u.blob_basic.cb_fn, set->cpl.u.blob_basic.cb_arg); 544b2503cb3SJim Harris break; 545b2503cb3SJim Harris case SPDK_BLOB_READV: 546a2360845SAlexey Marchuk spdk_blob_io_readv_ext(args->blob, ch, args->payload, args->iovcnt, 547b2503cb3SJim Harris args->offset, args->length, 548a2360845SAlexey Marchuk set->cpl.u.blob_basic.cb_fn, set->cpl.u.blob_basic.cb_arg, 549a2360845SAlexey Marchuk set->ext_io_opts); 550b2503cb3SJim Harris break; 551b2503cb3SJim Harris case SPDK_BLOB_WRITEV: 552a2360845SAlexey Marchuk spdk_blob_io_writev_ext(args->blob, ch, args->payload, args->iovcnt, 553b2503cb3SJim Harris args->offset, args->length, 554a2360845SAlexey Marchuk set->cpl.u.blob_basic.cb_fn, set->cpl.u.blob_basic.cb_arg, 555a2360845SAlexey Marchuk set->ext_io_opts); 556b2503cb3SJim Harris break; 557b2503cb3SJim Harris } 558b2503cb3SJim Harris TAILQ_INSERT_TAIL(&set->channel->reqs, set, link); 559b2503cb3SJim Harris } 560b2503cb3SJim Harris 561b2503cb3SJim Harris void 5620b034da1STomasz Zawadzki bs_user_op_abort(spdk_bs_user_op_t *op, int bserrno) 563b2503cb3SJim Harris { 564b2503cb3SJim Harris struct spdk_bs_request_set *set; 565b2503cb3SJim Harris 566b2503cb3SJim Harris set = (struct spdk_bs_request_set *)op; 567b2503cb3SJim Harris 5680b034da1STomasz Zawadzki set->cpl.u.blob_basic.cb_fn(set->cpl.u.blob_basic.cb_arg, bserrno); 569b2503cb3SJim Harris TAILQ_INSERT_TAIL(&set->channel->reqs, set, link); 570b2503cb3SJim Harris } 571b2503cb3SJim Harris 5722172c432STomasz Zawadzki SPDK_LOG_REGISTER_COMPONENT(blob_rw) 573