1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 */ 4 5 #include "spdk/stdinc.h" 6 7 #include "spdk_cunit.h" 8 #include "common/lib/test_env.c" 9 #include "blob/bdev/blob_bdev.c" 10 11 DEFINE_STUB(spdk_bdev_io_type_supported, bool, (struct spdk_bdev *bdev, 12 enum spdk_bdev_io_type io_type), false); 13 DEFINE_STUB_V(spdk_bdev_free_io, (struct spdk_bdev_io *g_bdev_io)); 14 DEFINE_STUB(spdk_bdev_queue_io_wait, int, 15 (struct spdk_bdev *bdev, struct spdk_io_channel *ch, 16 struct spdk_bdev_io_wait_entry *entry), 0); 17 DEFINE_STUB(spdk_bdev_read_blocks, int, 18 (struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, void *buf, 19 uint64_t offset_blocks, uint64_t num_blocks, spdk_bdev_io_completion_cb cb, 20 void *cb_arg), 0); 21 DEFINE_STUB(spdk_bdev_write_blocks, int, 22 (struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, void *buf, 23 uint64_t offset_blocks, uint64_t num_blocks, spdk_bdev_io_completion_cb cb, 24 void *cb_arg), 0); 25 DEFINE_STUB(spdk_bdev_readv_blocks, int, 26 (struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, struct iovec *iov, int iovcnt, 27 uint64_t offset_blocks, uint64_t num_blocks, spdk_bdev_io_completion_cb cb, 28 void *cb_arg), 0); 29 DEFINE_STUB(spdk_bdev_writev_blocks, int, 30 (struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, struct iovec *iov, int iovcnt, 31 uint64_t offset_blocks, uint64_t num_blocks, spdk_bdev_io_completion_cb cb, 32 void *cb_arg), 0); 33 DEFINE_STUB(spdk_bdev_readv_blocks_ext, int, 34 (struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, struct iovec *iov, int iovcnt, 35 uint64_t offset_blocks, uint64_t num_blocks, spdk_bdev_io_completion_cb cb, 36 void *cb_arg, struct spdk_bdev_ext_io_opts *opts), 0); 37 DEFINE_STUB(spdk_bdev_writev_blocks_ext, int, 38 (struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, struct iovec *iov, int iovcnt, 39 uint64_t offset_blocks, uint64_t num_blocks, spdk_bdev_io_completion_cb cb, 40 void *cb_arg, struct spdk_bdev_ext_io_opts *opts), 0); 41 DEFINE_STUB(spdk_bdev_write_zeroes_blocks, int, 42 (struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, uint64_t offset_blocks, 43 uint64_t num_blocks, spdk_bdev_io_completion_cb cb, void *cb_arg), 0); 44 DEFINE_STUB(spdk_bdev_unmap_blocks, int, 45 (struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, uint64_t offset_blocks, 46 uint64_t num_blocks, spdk_bdev_io_completion_cb cb, void *cb_arg), 0); 47 DEFINE_STUB(spdk_bdev_copy_blocks, int, 48 (struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, uint64_t dst_offset_blocks, 49 uint64_t src_offset_blocks, uint64_t num_blocks, spdk_bdev_io_completion_cb cb, 50 void *cb_arg), 0); 51 DEFINE_STUB(spdk_bdev_get_io_channel, struct spdk_io_channel *, 52 (struct spdk_bdev_desc *desc), NULL); 53 DEFINE_STUB(spdk_bdev_module_claim_bdev, int, 54 (struct spdk_bdev *bdev, struct spdk_bdev_desc *desc, struct spdk_bdev_module *module), 55 0); 56 DEFINE_STUB_V(spdk_bdev_module_release_bdev, (struct spdk_bdev *bdev)); 57 58 struct spdk_bdev { 59 char name[16]; 60 uint64_t blockcnt; 61 uint32_t blocklen; 62 uint32_t open_cnt; 63 }; 64 65 struct spdk_bdev_desc { 66 struct spdk_bdev *bdev; 67 }; 68 69 struct spdk_bdev *g_bdev; 70 71 static struct spdk_bdev * 72 get_bdev(const char *bdev_name) 73 { 74 if (g_bdev == NULL) { 75 return NULL; 76 } 77 78 if (strcmp(bdev_name, g_bdev->name) != 0) { 79 return NULL; 80 } 81 82 return g_bdev; 83 } 84 85 int 86 spdk_bdev_open_ext(const char *bdev_name, bool write, spdk_bdev_event_cb_t event_cb, 87 void *event_ctx, struct spdk_bdev_desc **_desc) 88 { 89 struct spdk_bdev_desc *desc; 90 struct spdk_bdev *bdev = get_bdev(bdev_name); 91 92 if (bdev == NULL) { 93 return -ENODEV; 94 } 95 96 desc = calloc(1, sizeof(*desc)); 97 desc->bdev = g_bdev; 98 *_desc = desc; 99 bdev->open_cnt++; 100 101 return 0; 102 } 103 104 void 105 spdk_bdev_close(struct spdk_bdev_desc *desc) 106 { 107 struct spdk_bdev *bdev = desc->bdev; 108 109 bdev->open_cnt--; 110 free(desc); 111 } 112 113 struct spdk_bdev * 114 spdk_bdev_desc_get_bdev(struct spdk_bdev_desc *desc) 115 { 116 return desc->bdev; 117 } 118 119 uint64_t 120 spdk_bdev_get_num_blocks(const struct spdk_bdev *bdev) 121 { 122 return bdev->blockcnt; 123 } 124 125 uint32_t 126 spdk_bdev_get_block_size(const struct spdk_bdev *bdev) 127 { 128 return bdev->blocklen; 129 } 130 131 static void 132 init_bdev(struct spdk_bdev *bdev, const char *name, uint64_t num_blocks) 133 { 134 memset(bdev, 0, sizeof(*bdev)); 135 snprintf(bdev->name, sizeof(bdev->name), "%s", name); 136 bdev->blockcnt = num_blocks; 137 } 138 139 static void 140 create_bs_dev(void) 141 { 142 struct spdk_bdev bdev; 143 struct spdk_bs_dev *bs_dev = NULL; 144 struct blob_bdev *blob_bdev; 145 int rc; 146 147 init_bdev(&bdev, "bdev0", 16); 148 g_bdev = &bdev; 149 150 rc = spdk_bdev_create_bs_dev_ext("bdev0", NULL, NULL, &bs_dev); 151 CU_ASSERT(rc == 0); 152 SPDK_CU_ASSERT_FATAL(bs_dev != NULL); 153 CU_ASSERT(bdev.open_cnt == 1); 154 155 blob_bdev = (struct blob_bdev *)bs_dev; 156 CU_ASSERT(blob_bdev->desc != NULL); 157 CU_ASSERT(blob_bdev->desc->bdev == g_bdev); 158 CU_ASSERT(!blob_bdev->claimed); 159 160 bs_dev->destroy(bs_dev); 161 CU_ASSERT(bdev.open_cnt == 0); 162 g_bdev = NULL; 163 } 164 165 int 166 main(int argc, char **argv) 167 { 168 CU_pSuite suite; 169 unsigned int num_failures; 170 171 CU_set_error_action(CUEA_ABORT); 172 CU_initialize_registry(); 173 174 suite = CU_add_suite("blob_bdev", NULL, NULL); 175 176 CU_ADD_TEST(suite, create_bs_dev); 177 178 CU_basic_set_mode(CU_BRM_VERBOSE); 179 CU_basic_run_tests(); 180 num_failures = CU_get_number_of_failures(); 181 CU_cleanup_registry(); 182 183 return num_failures; 184 } 185