1 /*- 2 * BSD LICENSE 3 * 4 * Copyright (c) Intel Corporation. 5 * All rights reserved. 6 * Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * * Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * * Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in 16 * the documentation and/or other materials provided with the 17 * distribution. 18 * * Neither the name of Intel Corporation nor the names of its 19 * contributors may be used to endorse or promote products derived 20 * from this software without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 25 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 26 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 */ 34 35 #include "spdk/stdinc.h" 36 #include "spdk/blob.h" 37 #include "spdk/dma.h" 38 39 #include "blobstore.h" 40 41 static void 42 zeroes_destroy(struct spdk_bs_dev *bs_dev) 43 { 44 return; 45 } 46 47 static void 48 zeroes_read(struct spdk_bs_dev *dev, struct spdk_io_channel *channel, void *payload, 49 uint64_t lba, uint32_t lba_count, struct spdk_bs_dev_cb_args *cb_args) 50 { 51 memset(payload, 0, dev->blocklen * lba_count); 52 cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, 0); 53 } 54 55 static void 56 zeroes_write(struct spdk_bs_dev *dev, struct spdk_io_channel *channel, void *payload, 57 uint64_t lba, uint32_t lba_count, 58 struct spdk_bs_dev_cb_args *cb_args) 59 { 60 cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, -EPERM); 61 assert(false); 62 } 63 64 static void 65 zeroes_readv(struct spdk_bs_dev *dev, struct spdk_io_channel *channel, 66 struct iovec *iov, int iovcnt, 67 uint64_t lba, uint32_t lba_count, struct spdk_bs_dev_cb_args *cb_args) 68 { 69 int i; 70 71 for (i = 0; i < iovcnt; i++) { 72 memset(iov[i].iov_base, 0, iov[i].iov_len); 73 } 74 75 cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, 0); 76 } 77 78 static void 79 zeroes_writev(struct spdk_bs_dev *dev, struct spdk_io_channel *channel, 80 struct iovec *iov, int iovcnt, 81 uint64_t lba, uint32_t lba_count, 82 struct spdk_bs_dev_cb_args *cb_args) 83 { 84 cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, -EPERM); 85 assert(false); 86 } 87 88 static void 89 _read_memory_domain_memzero_done(void *ctx, int rc) 90 { 91 struct spdk_bs_dev_cb_args *cb_args = (struct spdk_bs_dev_cb_args *)ctx; 92 93 cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, rc); 94 } 95 96 static void 97 zeroes_readv_ext(struct spdk_bs_dev *dev, struct spdk_io_channel *channel, 98 struct iovec *iov, int iovcnt, 99 uint64_t lba, uint32_t lba_count, struct spdk_bs_dev_cb_args *cb_args, 100 struct spdk_blob_ext_io_opts *ext_io_opts) 101 { 102 int i, rc; 103 104 if (ext_io_opts->memory_domain) { 105 rc = spdk_memory_domain_memzero(ext_io_opts->memory_domain, ext_io_opts->memory_domain_ctx, iov, 106 iovcnt, _read_memory_domain_memzero_done, cb_args); 107 if (rc) { 108 cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, rc); 109 } 110 return; 111 } 112 113 for (i = 0; i < iovcnt; i++) { 114 memset(iov[i].iov_base, 0, iov[i].iov_len); 115 } 116 117 cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, 0); 118 } 119 120 static void 121 zeroes_writev_ext(struct spdk_bs_dev *dev, struct spdk_io_channel *channel, 122 struct iovec *iov, int iovcnt, 123 uint64_t lba, uint32_t lba_count, 124 struct spdk_bs_dev_cb_args *cb_args, 125 struct spdk_blob_ext_io_opts *ext_io_opts) 126 { 127 cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, -EPERM); 128 assert(false); 129 } 130 131 static void 132 zeroes_write_zeroes(struct spdk_bs_dev *dev, struct spdk_io_channel *channel, 133 uint64_t lba, uint64_t lba_count, 134 struct spdk_bs_dev_cb_args *cb_args) 135 { 136 cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, -EPERM); 137 assert(false); 138 } 139 140 static void 141 zeroes_unmap(struct spdk_bs_dev *dev, struct spdk_io_channel *channel, 142 uint64_t lba, uint64_t lba_count, 143 struct spdk_bs_dev_cb_args *cb_args) 144 { 145 cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, -EPERM); 146 assert(false); 147 } 148 149 static struct spdk_bs_dev g_zeroes_bs_dev = { 150 .blockcnt = UINT64_MAX, 151 .blocklen = 512, 152 .create_channel = NULL, 153 .destroy_channel = NULL, 154 .destroy = zeroes_destroy, 155 .read = zeroes_read, 156 .write = zeroes_write, 157 .readv = zeroes_readv, 158 .writev = zeroes_writev, 159 .readv_ext = zeroes_readv_ext, 160 .writev_ext = zeroes_writev_ext, 161 .write_zeroes = zeroes_write_zeroes, 162 .unmap = zeroes_unmap, 163 }; 164 165 struct spdk_bs_dev * 166 bs_create_zeroes_dev(void) 167 { 168 return &g_zeroes_bs_dev; 169 } 170