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