1488570ebSJim Harris /* SPDX-License-Identifier: BSD-3-Clause 2a6dbe372Spaul luse * Copyright (C) 2018 Intel Corporation. 38970f868SBen Walker * All rights reserved. 4ba8f1a9eSAlexey Marchuk * Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 58970f868SBen Walker */ 68970f868SBen Walker 78970f868SBen Walker #include "spdk/stdinc.h" 88970f868SBen Walker #include "spdk/blob.h" 9ba8f1a9eSAlexey Marchuk #include "spdk/dma.h" 108970f868SBen Walker 118970f868SBen Walker #include "blobstore.h" 128970f868SBen Walker 138970f868SBen Walker static void 148970f868SBen Walker zeroes_destroy(struct spdk_bs_dev *bs_dev) 158970f868SBen Walker { 168970f868SBen Walker return; 178970f868SBen Walker } 188970f868SBen Walker 198970f868SBen Walker static void 208970f868SBen Walker zeroes_read(struct spdk_bs_dev *dev, struct spdk_io_channel *channel, void *payload, 218970f868SBen Walker uint64_t lba, uint32_t lba_count, struct spdk_bs_dev_cb_args *cb_args) 228970f868SBen Walker { 238970f868SBen Walker memset(payload, 0, dev->blocklen * lba_count); 248970f868SBen Walker cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, 0); 258970f868SBen Walker } 268970f868SBen Walker 278970f868SBen Walker static void 288970f868SBen Walker zeroes_write(struct spdk_bs_dev *dev, struct spdk_io_channel *channel, void *payload, 298970f868SBen Walker uint64_t lba, uint32_t lba_count, 308970f868SBen Walker struct spdk_bs_dev_cb_args *cb_args) 318970f868SBen Walker { 328970f868SBen Walker cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, -EPERM); 338970f868SBen Walker assert(false); 348970f868SBen Walker } 358970f868SBen Walker 368970f868SBen Walker static void 378970f868SBen Walker zeroes_readv(struct spdk_bs_dev *dev, struct spdk_io_channel *channel, 388970f868SBen Walker struct iovec *iov, int iovcnt, 398970f868SBen Walker uint64_t lba, uint32_t lba_count, struct spdk_bs_dev_cb_args *cb_args) 408970f868SBen Walker { 418970f868SBen Walker int i; 428970f868SBen Walker 438970f868SBen Walker for (i = 0; i < iovcnt; i++) { 448970f868SBen Walker memset(iov[i].iov_base, 0, iov[i].iov_len); 458970f868SBen Walker } 468970f868SBen Walker 478970f868SBen Walker cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, 0); 488970f868SBen Walker } 498970f868SBen Walker 508970f868SBen Walker static void 518970f868SBen Walker zeroes_writev(struct spdk_bs_dev *dev, struct spdk_io_channel *channel, 528970f868SBen Walker struct iovec *iov, int iovcnt, 538970f868SBen Walker uint64_t lba, uint32_t lba_count, 548970f868SBen Walker struct spdk_bs_dev_cb_args *cb_args) 558970f868SBen Walker { 568970f868SBen Walker cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, -EPERM); 578970f868SBen Walker assert(false); 588970f868SBen Walker } 598970f868SBen Walker 608970f868SBen Walker static void 61ba8f1a9eSAlexey Marchuk _read_memory_domain_memzero_done(void *ctx, int rc) 62ba8f1a9eSAlexey Marchuk { 63ba8f1a9eSAlexey Marchuk struct spdk_bs_dev_cb_args *cb_args = (struct spdk_bs_dev_cb_args *)ctx; 64ba8f1a9eSAlexey Marchuk 65ba8f1a9eSAlexey Marchuk cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, rc); 66ba8f1a9eSAlexey Marchuk } 67ba8f1a9eSAlexey Marchuk 68ba8f1a9eSAlexey Marchuk static void 69ba8f1a9eSAlexey Marchuk zeroes_readv_ext(struct spdk_bs_dev *dev, struct spdk_io_channel *channel, 70ba8f1a9eSAlexey Marchuk struct iovec *iov, int iovcnt, 71ba8f1a9eSAlexey Marchuk uint64_t lba, uint32_t lba_count, struct spdk_bs_dev_cb_args *cb_args, 72ba8f1a9eSAlexey Marchuk struct spdk_blob_ext_io_opts *ext_io_opts) 73ba8f1a9eSAlexey Marchuk { 74ba8f1a9eSAlexey Marchuk int i, rc; 75ba8f1a9eSAlexey Marchuk 76ba8f1a9eSAlexey Marchuk if (ext_io_opts->memory_domain) { 77ba8f1a9eSAlexey Marchuk rc = spdk_memory_domain_memzero(ext_io_opts->memory_domain, ext_io_opts->memory_domain_ctx, iov, 78ba8f1a9eSAlexey Marchuk iovcnt, _read_memory_domain_memzero_done, cb_args); 79ba8f1a9eSAlexey Marchuk if (rc) { 80ba8f1a9eSAlexey Marchuk cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, rc); 81ba8f1a9eSAlexey Marchuk } 82ba8f1a9eSAlexey Marchuk return; 83ba8f1a9eSAlexey Marchuk } 84ba8f1a9eSAlexey Marchuk 85ba8f1a9eSAlexey Marchuk for (i = 0; i < iovcnt; i++) { 86ba8f1a9eSAlexey Marchuk memset(iov[i].iov_base, 0, iov[i].iov_len); 87ba8f1a9eSAlexey Marchuk } 88ba8f1a9eSAlexey Marchuk 89ba8f1a9eSAlexey Marchuk cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, 0); 90ba8f1a9eSAlexey Marchuk } 91ba8f1a9eSAlexey Marchuk 92ba8f1a9eSAlexey Marchuk static void 93ba8f1a9eSAlexey Marchuk zeroes_writev_ext(struct spdk_bs_dev *dev, struct spdk_io_channel *channel, 94ba8f1a9eSAlexey Marchuk struct iovec *iov, int iovcnt, 95ba8f1a9eSAlexey Marchuk uint64_t lba, uint32_t lba_count, 96ba8f1a9eSAlexey Marchuk struct spdk_bs_dev_cb_args *cb_args, 97ba8f1a9eSAlexey Marchuk struct spdk_blob_ext_io_opts *ext_io_opts) 98ba8f1a9eSAlexey Marchuk { 99ba8f1a9eSAlexey Marchuk cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, -EPERM); 100ba8f1a9eSAlexey Marchuk assert(false); 101ba8f1a9eSAlexey Marchuk } 102ba8f1a9eSAlexey Marchuk 103ba8f1a9eSAlexey Marchuk static void 1048970f868SBen Walker zeroes_write_zeroes(struct spdk_bs_dev *dev, struct spdk_io_channel *channel, 105f01146aeSJim Harris uint64_t lba, uint64_t lba_count, 1068970f868SBen Walker struct spdk_bs_dev_cb_args *cb_args) 1078970f868SBen Walker { 108a8c32ed5SChangpeng Liu cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, -EPERM); 109a8c32ed5SChangpeng Liu assert(false); 1108970f868SBen Walker } 1118970f868SBen Walker 1128970f868SBen Walker static void 1138970f868SBen Walker zeroes_unmap(struct spdk_bs_dev *dev, struct spdk_io_channel *channel, 114f01146aeSJim Harris uint64_t lba, uint64_t lba_count, 1158970f868SBen Walker struct spdk_bs_dev_cb_args *cb_args) 1168970f868SBen Walker { 117a8c32ed5SChangpeng Liu cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, -EPERM); 118a8c32ed5SChangpeng Liu assert(false); 1198970f868SBen Walker } 1208970f868SBen Walker 1212e7a7fe5SEvgeniy Kochetov static bool 1222e7a7fe5SEvgeniy Kochetov zeroes_is_zeroes(struct spdk_bs_dev *dev, uint64_t lba, uint64_t lba_count) 1232e7a7fe5SEvgeniy Kochetov { 1242e7a7fe5SEvgeniy Kochetov return true; 1252e7a7fe5SEvgeniy Kochetov } 1262e7a7fe5SEvgeniy Kochetov 1279e843fdbSEvgeniy Kochetov static bool 12800311abcSDiwakar Sharma zeroes_is_range_valid(struct spdk_bs_dev *dev, uint64_t lba, uint64_t lba_count) 12900311abcSDiwakar Sharma { 13000311abcSDiwakar Sharma return true; 13100311abcSDiwakar Sharma } 13200311abcSDiwakar Sharma 13300311abcSDiwakar Sharma static bool 1349e843fdbSEvgeniy Kochetov zeroes_translate_lba(struct spdk_bs_dev *dev, uint64_t lba, uint64_t *base_lba) 1359e843fdbSEvgeniy Kochetov { 1369e843fdbSEvgeniy Kochetov return false; 1379e843fdbSEvgeniy Kochetov } 1389e843fdbSEvgeniy Kochetov 1398970f868SBen Walker static struct spdk_bs_dev g_zeroes_bs_dev = { 1408970f868SBen Walker .blockcnt = UINT64_MAX, 1416609b776SPiotr Pelplinski .blocklen = 512, 1428970f868SBen Walker .create_channel = NULL, 1438970f868SBen Walker .destroy_channel = NULL, 1448970f868SBen Walker .destroy = zeroes_destroy, 1458970f868SBen Walker .read = zeroes_read, 1468970f868SBen Walker .write = zeroes_write, 1478970f868SBen Walker .readv = zeroes_readv, 1488970f868SBen Walker .writev = zeroes_writev, 149ba8f1a9eSAlexey Marchuk .readv_ext = zeroes_readv_ext, 150ba8f1a9eSAlexey Marchuk .writev_ext = zeroes_writev_ext, 1518970f868SBen Walker .write_zeroes = zeroes_write_zeroes, 1528970f868SBen Walker .unmap = zeroes_unmap, 1532e7a7fe5SEvgeniy Kochetov .is_zeroes = zeroes_is_zeroes, 15400311abcSDiwakar Sharma .is_range_valid = zeroes_is_range_valid, 1559e843fdbSEvgeniy Kochetov .translate_lba = zeroes_translate_lba, 1568970f868SBen Walker }; 1578970f868SBen Walker 1588970f868SBen Walker struct spdk_bs_dev * 159ad7fdd12SSeth Howell bs_create_zeroes_dev(void) 1608970f868SBen Walker { 1618970f868SBen Walker return &g_zeroes_bs_dev; 1628970f868SBen Walker } 163*d3594f84Sxupeng-mingtu 164*d3594f84Sxupeng-mingtu bool 165*d3594f84Sxupeng-mingtu blob_backed_with_zeroes_dev(struct spdk_blob *blob) 166*d3594f84Sxupeng-mingtu { 167*d3594f84Sxupeng-mingtu return blob != NULL && blob->back_bs_dev == &g_zeroes_bs_dev; 168*d3594f84Sxupeng-mingtu } 169