1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (C) 2017 Intel Corporation. 3 * All rights reserved. 4 */ 5 6 #include "spdk/stdinc.h" 7 8 #include "CUnit/Basic.h" 9 10 #include "common/lib/ut_multithread.c" 11 12 #include "spdk_cunit.h" 13 #include "blobfs/blobfs.c" 14 #include "blobfs/tree.c" 15 #include "blob/blobstore.h" 16 17 #include "unit/lib/blob/bs_dev_common.c" 18 19 struct spdk_filesystem *g_fs; 20 struct spdk_file *g_file; 21 int g_fserrno; 22 23 DEFINE_STUB(spdk_memory_domain_memzero, int, (struct spdk_memory_domain *src_domain, 24 void *src_domain_ctx, struct iovec *iov, uint32_t iovcnt, void (*cpl_cb)(void *, int), 25 void *cpl_cb_arg), 0); 26 DEFINE_STUB(spdk_mempool_lookup, struct spdk_mempool *, (const char *name), NULL); 27 28 static void 29 fs_op_complete(void *ctx, int fserrno) 30 { 31 g_fserrno = fserrno; 32 } 33 34 static void 35 fs_op_with_handle_complete(void *ctx, struct spdk_filesystem *fs, int fserrno) 36 { 37 g_fs = fs; 38 g_fserrno = fserrno; 39 } 40 41 static void 42 fs_poll_threads(void) 43 { 44 poll_threads(); 45 while (spdk_thread_poll(g_cache_pool_thread, 0, 0) > 0) {} 46 } 47 48 static void 49 fs_init(void) 50 { 51 struct spdk_filesystem *fs; 52 struct spdk_bs_dev *dev; 53 54 dev = init_dev(); 55 56 spdk_fs_init(dev, NULL, NULL, fs_op_with_handle_complete, NULL); 57 fs_poll_threads(); 58 SPDK_CU_ASSERT_FATAL(g_fs != NULL); 59 CU_ASSERT(g_fserrno == 0); 60 fs = g_fs; 61 SPDK_CU_ASSERT_FATAL(fs->bs->dev == dev); 62 63 g_fserrno = 1; 64 spdk_fs_unload(fs, fs_op_complete, NULL); 65 fs_poll_threads(); 66 CU_ASSERT(g_fserrno == 0); 67 } 68 69 static void 70 create_cb(void *ctx, int fserrno) 71 { 72 g_fserrno = fserrno; 73 } 74 75 static void 76 open_cb(void *ctx, struct spdk_file *f, int fserrno) 77 { 78 g_fserrno = fserrno; 79 g_file = f; 80 } 81 82 static void 83 delete_cb(void *ctx, int fserrno) 84 { 85 g_fserrno = fserrno; 86 } 87 88 static void 89 fs_open(void) 90 { 91 struct spdk_filesystem *fs; 92 spdk_fs_iter iter; 93 struct spdk_bs_dev *dev; 94 struct spdk_file *file; 95 char name[257] = {'\0'}; 96 97 dev = init_dev(); 98 memset(name, 'a', sizeof(name) - 1); 99 100 spdk_fs_init(dev, NULL, NULL, fs_op_with_handle_complete, NULL); 101 fs_poll_threads(); 102 SPDK_CU_ASSERT_FATAL(g_fs != NULL); 103 CU_ASSERT(g_fserrno == 0); 104 fs = g_fs; 105 SPDK_CU_ASSERT_FATAL(fs->bs->dev == dev); 106 107 g_fserrno = 0; 108 /* Open should fail, because the file name is too long. */ 109 spdk_fs_open_file_async(fs, name, SPDK_BLOBFS_OPEN_CREATE, open_cb, NULL); 110 fs_poll_threads(); 111 CU_ASSERT(g_fserrno == -ENAMETOOLONG); 112 113 g_fserrno = 0; 114 spdk_fs_open_file_async(fs, "file1", 0, open_cb, NULL); 115 fs_poll_threads(); 116 CU_ASSERT(g_fserrno == -ENOENT); 117 118 g_file = NULL; 119 g_fserrno = 1; 120 spdk_fs_open_file_async(fs, "file1", SPDK_BLOBFS_OPEN_CREATE, open_cb, NULL); 121 fs_poll_threads(); 122 CU_ASSERT(g_fserrno == 0); 123 SPDK_CU_ASSERT_FATAL(g_file != NULL); 124 CU_ASSERT(!strcmp("file1", g_file->name)); 125 CU_ASSERT(g_file->ref_count == 1); 126 127 iter = spdk_fs_iter_first(fs); 128 CU_ASSERT(iter != NULL); 129 file = spdk_fs_iter_get_file(iter); 130 SPDK_CU_ASSERT_FATAL(file != NULL); 131 CU_ASSERT(!strcmp("file1", file->name)); 132 iter = spdk_fs_iter_next(iter); 133 CU_ASSERT(iter == NULL); 134 135 g_fserrno = 0; 136 /* Delete should successful, we will mark the file as deleted. */ 137 spdk_fs_delete_file_async(fs, "file1", delete_cb, NULL); 138 fs_poll_threads(); 139 CU_ASSERT(g_fserrno == 0); 140 CU_ASSERT(!TAILQ_EMPTY(&fs->files)); 141 142 g_fserrno = 1; 143 spdk_file_close_async(g_file, fs_op_complete, NULL); 144 fs_poll_threads(); 145 CU_ASSERT(g_fserrno == 0); 146 CU_ASSERT(TAILQ_EMPTY(&fs->files)); 147 148 g_fserrno = 1; 149 spdk_fs_unload(fs, fs_op_complete, NULL); 150 fs_poll_threads(); 151 CU_ASSERT(g_fserrno == 0); 152 } 153 154 static void 155 fs_create(void) 156 { 157 struct spdk_filesystem *fs; 158 struct spdk_bs_dev *dev; 159 char name[257] = {'\0'}; 160 161 dev = init_dev(); 162 memset(name, 'a', sizeof(name) - 1); 163 164 spdk_fs_init(dev, NULL, NULL, fs_op_with_handle_complete, NULL); 165 fs_poll_threads(); 166 SPDK_CU_ASSERT_FATAL(g_fs != NULL); 167 CU_ASSERT(g_fserrno == 0); 168 fs = g_fs; 169 SPDK_CU_ASSERT_FATAL(fs->bs->dev == dev); 170 171 g_fserrno = 0; 172 /* Create should fail, because the file name is too long. */ 173 spdk_fs_create_file_async(fs, name, create_cb, NULL); 174 fs_poll_threads(); 175 CU_ASSERT(g_fserrno == -ENAMETOOLONG); 176 177 g_fserrno = 1; 178 spdk_fs_create_file_async(fs, "file1", create_cb, NULL); 179 fs_poll_threads(); 180 CU_ASSERT(g_fserrno == 0); 181 182 g_fserrno = 1; 183 spdk_fs_create_file_async(fs, "file1", create_cb, NULL); 184 fs_poll_threads(); 185 CU_ASSERT(g_fserrno == -EEXIST); 186 187 g_fserrno = 1; 188 spdk_fs_delete_file_async(fs, "file1", delete_cb, NULL); 189 fs_poll_threads(); 190 CU_ASSERT(g_fserrno == 0); 191 CU_ASSERT(TAILQ_EMPTY(&fs->files)); 192 193 g_fserrno = 1; 194 spdk_fs_unload(fs, fs_op_complete, NULL); 195 fs_poll_threads(); 196 CU_ASSERT(g_fserrno == 0); 197 } 198 199 static void 200 fs_truncate(void) 201 { 202 struct spdk_filesystem *fs; 203 struct spdk_bs_dev *dev; 204 205 dev = init_dev(); 206 207 spdk_fs_init(dev, NULL, NULL, fs_op_with_handle_complete, NULL); 208 fs_poll_threads(); 209 SPDK_CU_ASSERT_FATAL(g_fs != NULL); 210 CU_ASSERT(g_fserrno == 0); 211 fs = g_fs; 212 SPDK_CU_ASSERT_FATAL(fs->bs->dev == dev); 213 214 g_file = NULL; 215 g_fserrno = 1; 216 spdk_fs_open_file_async(fs, "file1", SPDK_BLOBFS_OPEN_CREATE, open_cb, NULL); 217 fs_poll_threads(); 218 CU_ASSERT(g_fserrno == 0); 219 SPDK_CU_ASSERT_FATAL(g_file != NULL); 220 221 g_fserrno = 1; 222 spdk_file_truncate_async(g_file, 18 * 1024 * 1024 + 1, fs_op_complete, NULL); 223 fs_poll_threads(); 224 CU_ASSERT(g_fserrno == 0); 225 CU_ASSERT(g_file->length == 18 * 1024 * 1024 + 1); 226 227 g_fserrno = 1; 228 spdk_file_truncate_async(g_file, 1, fs_op_complete, NULL); 229 fs_poll_threads(); 230 CU_ASSERT(g_fserrno == 0); 231 CU_ASSERT(g_file->length == 1); 232 233 g_fserrno = 1; 234 spdk_file_truncate_async(g_file, 18 * 1024 * 1024 + 1, fs_op_complete, NULL); 235 fs_poll_threads(); 236 CU_ASSERT(g_fserrno == 0); 237 CU_ASSERT(g_file->length == 18 * 1024 * 1024 + 1); 238 239 g_fserrno = 1; 240 spdk_file_close_async(g_file, fs_op_complete, NULL); 241 fs_poll_threads(); 242 CU_ASSERT(g_fserrno == 0); 243 CU_ASSERT(g_file->ref_count == 0); 244 245 g_fserrno = 1; 246 spdk_fs_delete_file_async(fs, "file1", delete_cb, NULL); 247 fs_poll_threads(); 248 CU_ASSERT(g_fserrno == 0); 249 CU_ASSERT(TAILQ_EMPTY(&fs->files)); 250 251 g_fserrno = 1; 252 spdk_fs_unload(fs, fs_op_complete, NULL); 253 fs_poll_threads(); 254 CU_ASSERT(g_fserrno == 0); 255 } 256 257 static void 258 fs_rename(void) 259 { 260 struct spdk_filesystem *fs; 261 struct spdk_file *file, *file2, *file_iter; 262 struct spdk_bs_dev *dev; 263 264 dev = init_dev(); 265 266 spdk_fs_init(dev, NULL, NULL, fs_op_with_handle_complete, NULL); 267 fs_poll_threads(); 268 SPDK_CU_ASSERT_FATAL(g_fs != NULL); 269 CU_ASSERT(g_fserrno == 0); 270 fs = g_fs; 271 SPDK_CU_ASSERT_FATAL(fs->bs->dev == dev); 272 273 g_fserrno = 1; 274 spdk_fs_create_file_async(fs, "file1", create_cb, NULL); 275 fs_poll_threads(); 276 CU_ASSERT(g_fserrno == 0); 277 278 g_file = NULL; 279 g_fserrno = 1; 280 spdk_fs_open_file_async(fs, "file1", 0, open_cb, NULL); 281 fs_poll_threads(); 282 CU_ASSERT(g_fserrno == 0); 283 SPDK_CU_ASSERT_FATAL(g_file != NULL); 284 CU_ASSERT(g_file->ref_count == 1); 285 286 file = g_file; 287 g_file = NULL; 288 g_fserrno = 1; 289 spdk_file_close_async(file, fs_op_complete, NULL); 290 fs_poll_threads(); 291 CU_ASSERT(g_fserrno == 0); 292 SPDK_CU_ASSERT_FATAL(file->ref_count == 0); 293 294 g_file = NULL; 295 g_fserrno = 1; 296 spdk_fs_open_file_async(fs, "file2", SPDK_BLOBFS_OPEN_CREATE, open_cb, NULL); 297 fs_poll_threads(); 298 CU_ASSERT(g_fserrno == 0); 299 SPDK_CU_ASSERT_FATAL(g_file != NULL); 300 CU_ASSERT(g_file->ref_count == 1); 301 302 file2 = g_file; 303 g_file = NULL; 304 g_fserrno = 1; 305 spdk_file_close_async(file2, fs_op_complete, NULL); 306 fs_poll_threads(); 307 CU_ASSERT(g_fserrno == 0); 308 SPDK_CU_ASSERT_FATAL(file2->ref_count == 0); 309 310 /* 311 * Do a 3-way rename. This should delete the old "file2", then rename 312 * "file1" to "file2". 313 */ 314 g_fserrno = 1; 315 spdk_fs_rename_file_async(fs, "file1", "file2", fs_op_complete, NULL); 316 fs_poll_threads(); 317 CU_ASSERT(g_fserrno == 0); 318 CU_ASSERT(file->ref_count == 0); 319 CU_ASSERT(!strcmp(file->name, "file2")); 320 CU_ASSERT(TAILQ_FIRST(&fs->files) == file); 321 CU_ASSERT(TAILQ_NEXT(file, tailq) == NULL); 322 323 g_fserrno = 0; 324 spdk_fs_delete_file_async(fs, "file1", delete_cb, NULL); 325 fs_poll_threads(); 326 CU_ASSERT(g_fserrno == -ENOENT); 327 CU_ASSERT(!TAILQ_EMPTY(&fs->files)); 328 TAILQ_FOREACH(file_iter, &fs->files, tailq) { 329 if (file_iter == NULL) { 330 SPDK_CU_ASSERT_FATAL(false); 331 } 332 } 333 334 g_fserrno = 1; 335 spdk_fs_delete_file_async(fs, "file2", delete_cb, NULL); 336 fs_poll_threads(); 337 CU_ASSERT(g_fserrno == 0); 338 CU_ASSERT(TAILQ_EMPTY(&fs->files)); 339 340 g_fserrno = 1; 341 spdk_fs_unload(fs, fs_op_complete, NULL); 342 fs_poll_threads(); 343 CU_ASSERT(g_fserrno == 0); 344 } 345 346 static void 347 fs_rw_async(void) 348 { 349 struct spdk_filesystem *fs; 350 struct spdk_bs_dev *dev; 351 uint8_t w_buf[4096]; 352 uint8_t r_buf[4096]; 353 354 dev = init_dev(); 355 356 spdk_fs_init(dev, NULL, NULL, fs_op_with_handle_complete, NULL); 357 fs_poll_threads(); 358 SPDK_CU_ASSERT_FATAL(g_fs != NULL); 359 CU_ASSERT(g_fserrno == 0); 360 fs = g_fs; 361 SPDK_CU_ASSERT_FATAL(fs->bs->dev == dev); 362 363 g_file = NULL; 364 g_fserrno = 1; 365 spdk_fs_open_file_async(fs, "file1", SPDK_BLOBFS_OPEN_CREATE, open_cb, NULL); 366 fs_poll_threads(); 367 CU_ASSERT(g_fserrno == 0); 368 SPDK_CU_ASSERT_FATAL(g_file != NULL); 369 370 /* Write file */ 371 CU_ASSERT(g_file->length == 0); 372 g_fserrno = 1; 373 memset(w_buf, 0x5a, sizeof(w_buf)); 374 spdk_file_write_async(g_file, fs->sync_target.sync_io_channel, w_buf, 0, 4096, 375 fs_op_complete, NULL); 376 fs_poll_threads(); 377 CU_ASSERT(g_fserrno == 0); 378 CU_ASSERT(g_file->length == 4096); 379 380 /* Read file */ 381 g_fserrno = 1; 382 memset(r_buf, 0x0, sizeof(r_buf)); 383 spdk_file_read_async(g_file, fs->sync_target.sync_io_channel, r_buf, 0, 4096, 384 fs_op_complete, NULL); 385 fs_poll_threads(); 386 CU_ASSERT(g_fserrno == 0); 387 CU_ASSERT(memcmp(r_buf, w_buf, sizeof(r_buf)) == 0); 388 389 g_fserrno = 1; 390 spdk_file_close_async(g_file, fs_op_complete, NULL); 391 fs_poll_threads(); 392 CU_ASSERT(g_fserrno == 0); 393 394 g_fserrno = 1; 395 spdk_fs_unload(fs, fs_op_complete, NULL); 396 fs_poll_threads(); 397 CU_ASSERT(g_fserrno == 0); 398 } 399 400 static void 401 fs_writev_readv_async(void) 402 { 403 struct spdk_filesystem *fs; 404 struct spdk_bs_dev *dev; 405 struct iovec w_iov[2]; 406 struct iovec r_iov[2]; 407 uint8_t w_buf[4096]; 408 uint8_t r_buf[4096]; 409 410 dev = init_dev(); 411 412 spdk_fs_init(dev, NULL, NULL, fs_op_with_handle_complete, NULL); 413 fs_poll_threads(); 414 SPDK_CU_ASSERT_FATAL(g_fs != NULL); 415 CU_ASSERT(g_fserrno == 0); 416 fs = g_fs; 417 SPDK_CU_ASSERT_FATAL(fs->bs->dev == dev); 418 419 g_file = NULL; 420 g_fserrno = 1; 421 spdk_fs_open_file_async(fs, "file1", SPDK_BLOBFS_OPEN_CREATE, open_cb, NULL); 422 fs_poll_threads(); 423 CU_ASSERT(g_fserrno == 0); 424 SPDK_CU_ASSERT_FATAL(g_file != NULL); 425 426 /* Write file */ 427 CU_ASSERT(g_file->length == 0); 428 g_fserrno = 1; 429 memset(w_buf, 0x5a, sizeof(w_buf)); 430 w_iov[0].iov_base = w_buf; 431 w_iov[0].iov_len = 2048; 432 w_iov[1].iov_base = w_buf + 2048; 433 w_iov[1].iov_len = 2048; 434 spdk_file_writev_async(g_file, fs->sync_target.sync_io_channel, 435 w_iov, 2, 0, 4096, fs_op_complete, NULL); 436 fs_poll_threads(); 437 CU_ASSERT(g_fserrno == 0); 438 CU_ASSERT(g_file->length == 4096); 439 440 /* Read file */ 441 g_fserrno = 1; 442 memset(r_buf, 0x0, sizeof(r_buf)); 443 r_iov[0].iov_base = r_buf; 444 r_iov[0].iov_len = 2048; 445 r_iov[1].iov_base = r_buf + 2048; 446 r_iov[1].iov_len = 2048; 447 spdk_file_readv_async(g_file, fs->sync_target.sync_io_channel, 448 r_iov, 2, 0, 4096, fs_op_complete, NULL); 449 fs_poll_threads(); 450 CU_ASSERT(g_fserrno == 0); 451 CU_ASSERT(memcmp(r_buf, w_buf, sizeof(r_buf)) == 0); 452 453 /* Overwrite file with block aligned */ 454 g_fserrno = 1; 455 memset(w_buf, 0x6a, sizeof(w_buf)); 456 w_iov[0].iov_base = w_buf; 457 w_iov[0].iov_len = 2048; 458 w_iov[1].iov_base = w_buf + 2048; 459 w_iov[1].iov_len = 2048; 460 spdk_file_writev_async(g_file, fs->sync_target.sync_io_channel, 461 w_iov, 2, 0, 4096, fs_op_complete, NULL); 462 fs_poll_threads(); 463 CU_ASSERT(g_fserrno == 0); 464 CU_ASSERT(g_file->length == 4096); 465 466 /* Read file to verify the overwritten data */ 467 g_fserrno = 1; 468 memset(r_buf, 0x0, sizeof(r_buf)); 469 r_iov[0].iov_base = r_buf; 470 r_iov[0].iov_len = 2048; 471 r_iov[1].iov_base = r_buf + 2048; 472 r_iov[1].iov_len = 2048; 473 spdk_file_readv_async(g_file, fs->sync_target.sync_io_channel, 474 r_iov, 2, 0, 4096, fs_op_complete, NULL); 475 fs_poll_threads(); 476 CU_ASSERT(g_fserrno == 0); 477 CU_ASSERT(memcmp(r_buf, w_buf, sizeof(r_buf)) == 0); 478 479 g_fserrno = 1; 480 spdk_file_close_async(g_file, fs_op_complete, NULL); 481 fs_poll_threads(); 482 CU_ASSERT(g_fserrno == 0); 483 484 g_fserrno = 1; 485 spdk_fs_unload(fs, fs_op_complete, NULL); 486 fs_poll_threads(); 487 CU_ASSERT(g_fserrno == 0); 488 } 489 490 static void 491 tree_find_buffer_ut(void) 492 { 493 struct cache_tree *root; 494 struct cache_tree *level1_0; 495 struct cache_tree *level0_0_0; 496 struct cache_tree *level0_0_12; 497 struct cache_buffer *leaf_0_0_4; 498 struct cache_buffer *leaf_0_12_8; 499 struct cache_buffer *leaf_9_23_15; 500 struct cache_buffer *buffer; 501 502 level1_0 = calloc(1, sizeof(struct cache_tree)); 503 SPDK_CU_ASSERT_FATAL(level1_0 != NULL); 504 level0_0_0 = calloc(1, sizeof(struct cache_tree)); 505 SPDK_CU_ASSERT_FATAL(level0_0_0 != NULL); 506 level0_0_12 = calloc(1, sizeof(struct cache_tree)); 507 SPDK_CU_ASSERT_FATAL(level0_0_12 != NULL); 508 leaf_0_0_4 = calloc(1, sizeof(struct cache_buffer)); 509 SPDK_CU_ASSERT_FATAL(leaf_0_0_4 != NULL); 510 leaf_0_12_8 = calloc(1, sizeof(struct cache_buffer)); 511 SPDK_CU_ASSERT_FATAL(leaf_0_12_8 != NULL); 512 leaf_9_23_15 = calloc(1, sizeof(struct cache_buffer)); 513 SPDK_CU_ASSERT_FATAL(leaf_9_23_15 != NULL); 514 515 level1_0->level = 1; 516 level0_0_0->level = 0; 517 level0_0_12->level = 0; 518 519 leaf_0_0_4->offset = CACHE_BUFFER_SIZE * 4; 520 level0_0_0->u.buffer[4] = leaf_0_0_4; 521 level0_0_0->present_mask |= (1ULL << 4); 522 523 leaf_0_12_8->offset = CACHE_TREE_LEVEL_SIZE(1) * 12 + CACHE_BUFFER_SIZE * 8; 524 level0_0_12->u.buffer[8] = leaf_0_12_8; 525 level0_0_12->present_mask |= (1ULL << 8); 526 527 level1_0->u.tree[0] = level0_0_0; 528 level1_0->present_mask |= (1ULL << 0); 529 level1_0->u.tree[12] = level0_0_12; 530 level1_0->present_mask |= (1ULL << 12); 531 532 buffer = tree_find_buffer(NULL, 0); 533 CU_ASSERT(buffer == NULL); 534 535 buffer = tree_find_buffer(level0_0_0, 0); 536 CU_ASSERT(buffer == NULL); 537 538 buffer = tree_find_buffer(level0_0_0, CACHE_TREE_LEVEL_SIZE(0) + 1); 539 CU_ASSERT(buffer == NULL); 540 541 buffer = tree_find_buffer(level0_0_0, leaf_0_0_4->offset); 542 CU_ASSERT(buffer == leaf_0_0_4); 543 544 buffer = tree_find_buffer(level1_0, leaf_0_0_4->offset); 545 CU_ASSERT(buffer == leaf_0_0_4); 546 547 buffer = tree_find_buffer(level1_0, leaf_0_12_8->offset); 548 CU_ASSERT(buffer == leaf_0_12_8); 549 550 buffer = tree_find_buffer(level1_0, leaf_0_12_8->offset + CACHE_BUFFER_SIZE - 1); 551 CU_ASSERT(buffer == leaf_0_12_8); 552 553 buffer = tree_find_buffer(level1_0, leaf_0_12_8->offset - 1); 554 CU_ASSERT(buffer == NULL); 555 556 leaf_9_23_15->offset = CACHE_TREE_LEVEL_SIZE(2) * 9 + 557 CACHE_TREE_LEVEL_SIZE(1) * 23 + 558 CACHE_BUFFER_SIZE * 15; 559 root = tree_insert_buffer(level1_0, leaf_9_23_15); 560 CU_ASSERT(root != level1_0); 561 buffer = tree_find_buffer(root, leaf_9_23_15->offset); 562 CU_ASSERT(buffer == leaf_9_23_15); 563 tree_free_buffers(root); 564 free(root); 565 } 566 567 static void 568 channel_ops(void) 569 { 570 struct spdk_filesystem *fs; 571 struct spdk_bs_dev *dev; 572 struct spdk_io_channel *channel; 573 574 dev = init_dev(); 575 576 spdk_fs_init(dev, NULL, NULL, fs_op_with_handle_complete, NULL); 577 fs_poll_threads(); 578 SPDK_CU_ASSERT_FATAL(g_fs != NULL); 579 CU_ASSERT(g_fserrno == 0); 580 fs = g_fs; 581 SPDK_CU_ASSERT_FATAL(fs->bs->dev == dev); 582 583 channel = spdk_fs_alloc_io_channel(fs); 584 CU_ASSERT(channel != NULL); 585 586 spdk_fs_free_io_channel(channel); 587 588 g_fserrno = 1; 589 spdk_fs_unload(fs, fs_op_complete, NULL); 590 fs_poll_threads(); 591 CU_ASSERT(g_fserrno == 0); 592 g_fs = NULL; 593 } 594 595 static void 596 channel_ops_sync(void) 597 { 598 struct spdk_filesystem *fs; 599 struct spdk_bs_dev *dev; 600 struct spdk_fs_thread_ctx *channel; 601 602 dev = init_dev(); 603 604 spdk_fs_init(dev, NULL, NULL, fs_op_with_handle_complete, NULL); 605 fs_poll_threads(); 606 SPDK_CU_ASSERT_FATAL(g_fs != NULL); 607 CU_ASSERT(g_fserrno == 0); 608 fs = g_fs; 609 SPDK_CU_ASSERT_FATAL(fs->bs->dev == dev); 610 611 channel = spdk_fs_alloc_thread_ctx(fs); 612 CU_ASSERT(channel != NULL); 613 614 spdk_fs_free_thread_ctx(channel); 615 616 g_fserrno = 1; 617 spdk_fs_unload(fs, fs_op_complete, NULL); 618 fs_poll_threads(); 619 CU_ASSERT(g_fserrno == 0); 620 g_fs = NULL; 621 } 622 623 int 624 main(int argc, char **argv) 625 { 626 CU_pSuite suite = NULL; 627 unsigned int num_failures; 628 629 CU_set_error_action(CUEA_ABORT); 630 CU_initialize_registry(); 631 632 suite = CU_add_suite("blobfs_async_ut", NULL, NULL); 633 634 CU_ADD_TEST(suite, fs_init); 635 CU_ADD_TEST(suite, fs_open); 636 CU_ADD_TEST(suite, fs_create); 637 CU_ADD_TEST(suite, fs_truncate); 638 CU_ADD_TEST(suite, fs_rename); 639 CU_ADD_TEST(suite, fs_rw_async); 640 CU_ADD_TEST(suite, fs_writev_readv_async); 641 CU_ADD_TEST(suite, tree_find_buffer_ut); 642 CU_ADD_TEST(suite, channel_ops); 643 CU_ADD_TEST(suite, channel_ops_sync); 644 645 allocate_threads(1); 646 set_thread(0); 647 648 g_dev_buffer = calloc(1, DEV_BUFFER_SIZE); 649 CU_basic_set_mode(CU_BRM_VERBOSE); 650 CU_basic_run_tests(); 651 num_failures = CU_get_number_of_failures(); 652 CU_cleanup_registry(); 653 free(g_dev_buffer); 654 655 free_threads(); 656 657 return num_failures; 658 } 659