1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (C) 2018 Intel Corporation. 3 * All rights reserved. 4 * Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 5 */ 6 7 #include "spdk/stdinc.h" 8 #include "spdk/blob.h" 9 #include "spdk/log.h" 10 #include "spdk/likely.h" 11 #include "blobstore.h" 12 13 static void 14 blob_bs_dev_write(struct spdk_bs_dev *dev, struct spdk_io_channel *channel, void *payload, 15 uint64_t lba, uint32_t lba_count, 16 struct spdk_bs_dev_cb_args *cb_args) 17 { 18 cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, -EPERM); 19 assert(false); 20 } 21 22 static void 23 blob_bs_dev_writev(struct spdk_bs_dev *dev, struct spdk_io_channel *channel, 24 struct iovec *iov, int iovcnt, 25 uint64_t lba, uint32_t lba_count, 26 struct spdk_bs_dev_cb_args *cb_args) 27 { 28 cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, -EPERM); 29 assert(false); 30 } 31 32 static void 33 blob_bs_dev_writev_ext(struct spdk_bs_dev *dev, struct spdk_io_channel *channel, 34 struct iovec *iov, int iovcnt, 35 uint64_t lba, uint32_t lba_count, 36 struct spdk_bs_dev_cb_args *cb_args, 37 struct spdk_blob_ext_io_opts *ext_opts) 38 { 39 cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, -EPERM); 40 assert(false); 41 } 42 43 static void 44 blob_bs_dev_write_zeroes(struct spdk_bs_dev *dev, struct spdk_io_channel *channel, 45 uint64_t lba, uint64_t lba_count, 46 struct spdk_bs_dev_cb_args *cb_args) 47 { 48 cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, -EPERM); 49 assert(false); 50 } 51 52 static void 53 blob_bs_dev_unmap(struct spdk_bs_dev *dev, struct spdk_io_channel *channel, 54 uint64_t lba, uint64_t lba_count, 55 struct spdk_bs_dev_cb_args *cb_args) 56 { 57 cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, -EPERM); 58 assert(false); 59 } 60 61 static void 62 blob_bs_dev_read_cpl(void *cb_arg, int bserrno) 63 { 64 struct spdk_bs_dev_cb_args *cb_args = (struct spdk_bs_dev_cb_args *)cb_arg; 65 66 cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, bserrno); 67 } 68 69 static inline void 70 zero_trailing_bytes(struct spdk_blob_bs_dev *b, struct iovec *iov, int iovcnt, 71 uint64_t lba, uint32_t *lba_count) 72 { 73 uint32_t zero_lba_count; 74 uint64_t zero_bytes, zero_len; 75 uint64_t payload_bytes; 76 uint64_t valid_bytes; 77 void *zero_start; 78 struct iovec *i; 79 80 if (spdk_likely(lba + *lba_count <= b->bs_dev.blockcnt)) { 81 return; 82 } 83 84 /* Figure out how many bytes in the payload will need to be zeroed. */ 85 zero_lba_count = spdk_min(*lba_count, lba + *lba_count - b->bs_dev.blockcnt); 86 zero_bytes = zero_lba_count * (uint64_t)b->bs_dev.blocklen; 87 88 payload_bytes = *lba_count * (uint64_t)b->bs_dev.blocklen; 89 valid_bytes = payload_bytes - zero_bytes; 90 91 i = iov; 92 while (zero_bytes > 0) { 93 if (i->iov_len > valid_bytes) { 94 zero_start = i->iov_base + valid_bytes; 95 zero_len = spdk_min(payload_bytes, i->iov_len - valid_bytes); 96 memset(zero_start, 0, zero_bytes); 97 valid_bytes = 0; 98 zero_bytes -= zero_len; 99 } 100 valid_bytes -= spdk_min(valid_bytes, i->iov_len); 101 payload_bytes -= spdk_min(payload_bytes, i->iov_len); 102 i++; 103 } 104 105 *lba_count -= zero_lba_count; 106 } 107 108 static inline void 109 blob_bs_dev_read(struct spdk_bs_dev *dev, struct spdk_io_channel *channel, void *payload, 110 uint64_t lba, uint32_t lba_count, struct spdk_bs_dev_cb_args *cb_args) 111 { 112 struct spdk_blob_bs_dev *b = (struct spdk_blob_bs_dev *)dev; 113 struct iovec iov; 114 115 iov.iov_base = payload; 116 iov.iov_len = lba_count * b->bs_dev.blocklen; 117 /* The backing blob may be smaller than this blob, so zero any trailing bytes. */ 118 zero_trailing_bytes(b, &iov, 1, lba, &lba_count); 119 120 spdk_blob_io_read(b->blob, channel, payload, lba, lba_count, 121 blob_bs_dev_read_cpl, cb_args); 122 } 123 124 static inline void 125 blob_bs_dev_readv(struct spdk_bs_dev *dev, struct spdk_io_channel *channel, 126 struct iovec *iov, int iovcnt, 127 uint64_t lba, uint32_t lba_count, struct spdk_bs_dev_cb_args *cb_args) 128 { 129 struct spdk_blob_bs_dev *b = (struct spdk_blob_bs_dev *)dev; 130 131 /* The backing blob may be smaller than this blob, so zero any trailing bytes. */ 132 zero_trailing_bytes(b, iov, iovcnt, lba, &lba_count); 133 134 spdk_blob_io_readv(b->blob, channel, iov, iovcnt, lba, lba_count, 135 blob_bs_dev_read_cpl, cb_args); 136 } 137 138 static inline void 139 blob_bs_dev_readv_ext(struct spdk_bs_dev *dev, struct spdk_io_channel *channel, 140 struct iovec *iov, int iovcnt, 141 uint64_t lba, uint32_t lba_count, struct spdk_bs_dev_cb_args *cb_args, 142 struct spdk_blob_ext_io_opts *ext_opts) 143 { 144 struct spdk_blob_bs_dev *b = (struct spdk_blob_bs_dev *)dev; 145 146 /* The backing blob may be smaller than this blob, so zero any trailing bytes. */ 147 zero_trailing_bytes(b, iov, iovcnt, lba, &lba_count); 148 149 spdk_blob_io_readv_ext(b->blob, channel, iov, iovcnt, lba, lba_count, 150 blob_bs_dev_read_cpl, cb_args, ext_opts); 151 } 152 153 static void 154 blob_bs_dev_destroy_cpl(void *cb_arg, int bserrno) 155 { 156 if (bserrno != 0) { 157 SPDK_ERRLOG("Error on blob_bs_dev destroy: %d", bserrno); 158 } 159 160 /* Free blob_bs_dev */ 161 free(cb_arg); 162 } 163 164 static void 165 blob_bs_dev_destroy(struct spdk_bs_dev *bs_dev) 166 { 167 struct spdk_blob_bs_dev *b = (struct spdk_blob_bs_dev *)bs_dev; 168 169 spdk_blob_close(b->blob, blob_bs_dev_destroy_cpl, b); 170 } 171 172 static bool 173 blob_bs_is_zeroes(struct spdk_bs_dev *dev, uint64_t lba, uint64_t lba_count) 174 { 175 struct spdk_blob_bs_dev *b = (struct spdk_blob_bs_dev *)dev; 176 struct spdk_blob *blob = b->blob; 177 bool is_valid_range; 178 179 assert(lba == bs_cluster_to_lba(blob->bs, bs_lba_to_cluster(blob->bs, lba))); 180 assert(lba_count == bs_dev_byte_to_lba(dev, blob->bs->cluster_sz)); 181 182 if (bs_io_unit_is_allocated(blob, lba)) { 183 return false; 184 } 185 186 assert(blob->back_bs_dev != NULL); 187 is_valid_range = blob->back_bs_dev->is_range_valid(blob->back_bs_dev, lba, lba_count); 188 return is_valid_range && blob->back_bs_dev->is_zeroes(blob->back_bs_dev, 189 bs_io_unit_to_back_dev_lba(blob, lba), 190 bs_io_unit_to_back_dev_lba(blob, lba_count)); 191 } 192 193 static bool 194 blob_bs_is_range_valid(struct spdk_bs_dev *dev, uint64_t lba, uint64_t lba_count) 195 { 196 struct spdk_blob_bs_dev *b = (struct spdk_blob_bs_dev *)dev; 197 struct spdk_blob *blob = b->blob; 198 uint64_t io_units_per_cluster; 199 200 /* The lba here is supposed to be the first lba of cluster. lba_count 201 * will typically be fixed e.g. 8192 for 4MiB cluster. */ 202 assert(lba_count == blob->bs->cluster_sz / dev->blocklen); 203 assert(lba % lba_count == 0); 204 205 io_units_per_cluster = blob->bs->io_units_per_cluster; 206 207 /* A blob will either have: 208 * - no backing bs_bdev (normal thick blob), or 209 * - zeroes backing bs_bdev (thin provisioned blob), or 210 * - blob backing bs_bdev (e.g snapshot) 211 * It may be possible that backing bs_bdev has lesser number of clusters 212 * than the child lvol blob because lvol blob has been expanded after 213 * taking snapshot. In such a case, page will be outside the cluster io_unit 214 * range of the backing dev. Always return true for zeroes backing bdev. */ 215 return lba < blob->active.num_clusters * io_units_per_cluster; 216 } 217 218 static bool 219 blob_bs_translate_lba(struct spdk_bs_dev *dev, uint64_t lba, uint64_t *base_lba) 220 { 221 struct spdk_blob_bs_dev *b = (struct spdk_blob_bs_dev *)dev; 222 struct spdk_blob *blob = b->blob; 223 bool is_valid_range; 224 225 assert(base_lba != NULL); 226 if (bs_io_unit_is_allocated(blob, lba)) { 227 *base_lba = bs_blob_io_unit_to_lba(blob, lba); 228 return true; 229 } 230 231 assert(blob->back_bs_dev != NULL); 232 /* Since here we don't get lba_count directly, passing lba_count derived 233 * from cluster_sz which typically happens for other calls like is_zeroes 234 * in CoW path. */ 235 is_valid_range = blob->back_bs_dev->is_range_valid(blob->back_bs_dev, lba, 236 bs_dev_byte_to_lba(blob->back_bs_dev, blob->bs->cluster_sz)); 237 return is_valid_range && blob->back_bs_dev->translate_lba(blob->back_bs_dev, 238 bs_io_unit_to_back_dev_lba(blob, lba), 239 base_lba); 240 } 241 242 static bool 243 blob_bs_is_degraded(struct spdk_bs_dev *dev) 244 { 245 struct spdk_blob_bs_dev *b = (struct spdk_blob_bs_dev *)dev; 246 247 return spdk_blob_is_degraded(b->blob); 248 } 249 250 struct spdk_bs_dev * 251 bs_create_blob_bs_dev(struct spdk_blob *blob) 252 { 253 struct spdk_blob_bs_dev *b; 254 255 b = calloc(1, sizeof(*b)); 256 if (b == NULL) { 257 return NULL; 258 } 259 /* snapshot blob */ 260 b->bs_dev.blockcnt = blob->active.num_clusters * blob->bs->io_units_per_cluster; 261 b->bs_dev.blocklen = spdk_bs_get_io_unit_size(blob->bs); 262 b->bs_dev.create_channel = NULL; 263 b->bs_dev.destroy_channel = NULL; 264 b->bs_dev.destroy = blob_bs_dev_destroy; 265 b->bs_dev.write = blob_bs_dev_write; 266 b->bs_dev.writev = blob_bs_dev_writev; 267 b->bs_dev.writev_ext = blob_bs_dev_writev_ext; 268 b->bs_dev.read = blob_bs_dev_read; 269 b->bs_dev.readv = blob_bs_dev_readv; 270 b->bs_dev.readv_ext = blob_bs_dev_readv_ext; 271 b->bs_dev.write_zeroes = blob_bs_dev_write_zeroes; 272 b->bs_dev.unmap = blob_bs_dev_unmap; 273 b->bs_dev.is_zeroes = blob_bs_is_zeroes; 274 b->bs_dev.is_range_valid = blob_bs_is_range_valid; 275 b->bs_dev.translate_lba = blob_bs_translate_lba; 276 b->bs_dev.is_degraded = blob_bs_is_degraded; 277 b->blob = blob; 278 279 return &b->bs_dev; 280 } 281