1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (c) 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 "blobstore.h" 11 12 static void 13 blob_bs_dev_write(struct spdk_bs_dev *dev, struct spdk_io_channel *channel, void *payload, 14 uint64_t lba, uint32_t lba_count, 15 struct spdk_bs_dev_cb_args *cb_args) 16 { 17 cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, -EPERM); 18 assert(false); 19 } 20 21 static void 22 blob_bs_dev_writev(struct spdk_bs_dev *dev, struct spdk_io_channel *channel, 23 struct iovec *iov, int iovcnt, 24 uint64_t lba, uint32_t lba_count, 25 struct spdk_bs_dev_cb_args *cb_args) 26 { 27 cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, -EPERM); 28 assert(false); 29 } 30 31 static void 32 blob_bs_dev_writev_ext(struct spdk_bs_dev *dev, struct spdk_io_channel *channel, 33 struct iovec *iov, int iovcnt, 34 uint64_t lba, uint32_t lba_count, 35 struct spdk_bs_dev_cb_args *cb_args, 36 struct spdk_blob_ext_io_opts *ext_opts) 37 { 38 cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, -EPERM); 39 assert(false); 40 } 41 42 static void 43 blob_bs_dev_write_zeroes(struct spdk_bs_dev *dev, struct spdk_io_channel *channel, 44 uint64_t lba, uint64_t lba_count, 45 struct spdk_bs_dev_cb_args *cb_args) 46 { 47 cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, -EPERM); 48 assert(false); 49 } 50 51 static void 52 blob_bs_dev_unmap(struct spdk_bs_dev *dev, struct spdk_io_channel *channel, 53 uint64_t lba, uint64_t lba_count, 54 struct spdk_bs_dev_cb_args *cb_args) 55 { 56 cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, -EPERM); 57 assert(false); 58 } 59 60 static void 61 blob_bs_dev_read_cpl(void *cb_arg, int bserrno) 62 { 63 struct spdk_bs_dev_cb_args *cb_args = (struct spdk_bs_dev_cb_args *)cb_arg; 64 65 cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, bserrno); 66 } 67 68 static inline void 69 blob_bs_dev_read(struct spdk_bs_dev *dev, struct spdk_io_channel *channel, void *payload, 70 uint64_t lba, uint32_t lba_count, struct spdk_bs_dev_cb_args *cb_args) 71 { 72 struct spdk_blob_bs_dev *b = (struct spdk_blob_bs_dev *)dev; 73 74 spdk_blob_io_read(b->blob, channel, payload, lba, lba_count, 75 blob_bs_dev_read_cpl, cb_args); 76 } 77 78 static inline void 79 blob_bs_dev_readv(struct spdk_bs_dev *dev, struct spdk_io_channel *channel, 80 struct iovec *iov, int iovcnt, 81 uint64_t lba, uint32_t lba_count, struct spdk_bs_dev_cb_args *cb_args) 82 { 83 struct spdk_blob_bs_dev *b = (struct spdk_blob_bs_dev *)dev; 84 85 spdk_blob_io_readv(b->blob, channel, iov, iovcnt, lba, lba_count, 86 blob_bs_dev_read_cpl, cb_args); 87 } 88 89 static inline void 90 blob_bs_dev_readv_ext(struct spdk_bs_dev *dev, struct spdk_io_channel *channel, 91 struct iovec *iov, int iovcnt, 92 uint64_t lba, uint32_t lba_count, struct spdk_bs_dev_cb_args *cb_args, 93 struct spdk_blob_ext_io_opts *ext_opts) 94 { 95 struct spdk_blob_bs_dev *b = (struct spdk_blob_bs_dev *)dev; 96 97 spdk_blob_io_readv_ext(b->blob, channel, iov, iovcnt, lba, lba_count, 98 blob_bs_dev_read_cpl, cb_args, ext_opts); 99 } 100 101 static void 102 blob_bs_dev_destroy_cpl(void *cb_arg, int bserrno) 103 { 104 if (bserrno != 0) { 105 SPDK_ERRLOG("Error on blob_bs_dev destroy: %d", bserrno); 106 } 107 108 /* Free blob_bs_dev */ 109 free(cb_arg); 110 } 111 112 static void 113 blob_bs_dev_destroy(struct spdk_bs_dev *bs_dev) 114 { 115 struct spdk_blob_bs_dev *b = (struct spdk_blob_bs_dev *)bs_dev; 116 117 spdk_blob_close(b->blob, blob_bs_dev_destroy_cpl, b); 118 } 119 120 121 struct spdk_bs_dev * 122 bs_create_blob_bs_dev(struct spdk_blob *blob) 123 { 124 struct spdk_blob_bs_dev *b; 125 126 b = calloc(1, sizeof(*b)); 127 if (b == NULL) { 128 return NULL; 129 } 130 /* snapshot blob */ 131 b->bs_dev.blockcnt = blob->active.num_clusters * 132 blob->bs->pages_per_cluster * bs_io_unit_per_page(blob->bs); 133 b->bs_dev.blocklen = spdk_bs_get_io_unit_size(blob->bs); 134 b->bs_dev.create_channel = NULL; 135 b->bs_dev.destroy_channel = NULL; 136 b->bs_dev.destroy = blob_bs_dev_destroy; 137 b->bs_dev.write = blob_bs_dev_write; 138 b->bs_dev.writev = blob_bs_dev_writev; 139 b->bs_dev.writev_ext = blob_bs_dev_writev_ext; 140 b->bs_dev.read = blob_bs_dev_read; 141 b->bs_dev.readv = blob_bs_dev_readv; 142 b->bs_dev.readv_ext = blob_bs_dev_readv_ext; 143 b->bs_dev.write_zeroes = blob_bs_dev_write_zeroes; 144 b->bs_dev.unmap = blob_bs_dev_unmap; 145 b->blob = blob; 146 147 return &b->bs_dev; 148 } 149