1 /*- 2 * BSD LICENSE 3 * 4 * Copyright (c) Intel Corporation. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name of Intel Corporation nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include "spdk/stdinc.h" 35 36 #include "spdk_cunit.h" 37 #include "spdk/blob.h" 38 39 #include "lib/test_env.c" 40 #include "../bs_dev_common.c" 41 #include "blobstore.c" 42 #include "request.c" 43 44 struct spdk_blob_store *g_bs; 45 spdk_blob_id g_blobid; 46 struct spdk_blob *g_blob; 47 int g_bserrno; 48 struct spdk_xattr_names *g_names; 49 int g_done; 50 51 bool g_scheduler_delay = false; 52 53 struct scheduled_ops { 54 spdk_thread_fn fn; 55 void *ctx; 56 57 TAILQ_ENTRY(scheduled_ops) ops_queue; 58 }; 59 60 static TAILQ_HEAD(, scheduled_ops) g_scheduled_ops = TAILQ_HEAD_INITIALIZER(g_scheduled_ops); 61 62 static void 63 _bs_send_msg(spdk_thread_fn fn, void *ctx, void *thread_ctx) 64 { 65 if (g_scheduler_delay) { 66 struct scheduled_ops *ops = calloc(1, sizeof(*ops)); 67 68 SPDK_CU_ASSERT_FATAL(ops != NULL); 69 ops->fn = fn; 70 ops->ctx = ctx; 71 TAILQ_INSERT_TAIL(&g_scheduled_ops, ops, ops_queue); 72 } else { 73 fn(ctx); 74 } 75 } 76 77 static void 78 _bs_flush_scheduler(void) 79 { 80 struct scheduled_ops *ops, *tmp; 81 82 TAILQ_FOREACH_SAFE(ops, &g_scheduled_ops, ops_queue, tmp) { 83 ops->fn(ops->ctx); 84 TAILQ_REMOVE(&g_scheduled_ops, ops, ops_queue); 85 free(ops); 86 } 87 } 88 89 static void 90 bs_op_complete(void *cb_arg, int bserrno) 91 { 92 g_bserrno = bserrno; 93 } 94 95 static void 96 bs_op_with_handle_complete(void *cb_arg, struct spdk_blob_store *bs, 97 int bserrno) 98 { 99 g_bs = bs; 100 g_bserrno = bserrno; 101 } 102 103 static void 104 blob_op_complete(void *cb_arg, int bserrno) 105 { 106 g_bserrno = bserrno; 107 } 108 109 static void 110 blob_op_with_id_complete(void *cb_arg, spdk_blob_id blobid, int bserrno) 111 { 112 g_blobid = blobid; 113 g_bserrno = bserrno; 114 } 115 116 static void 117 blob_op_with_handle_complete(void *cb_arg, struct spdk_blob *blb, int bserrno) 118 { 119 g_blob = blb; 120 g_bserrno = bserrno; 121 } 122 123 static void 124 blob_init(void) 125 { 126 struct spdk_bs_dev *dev; 127 128 dev = init_dev(); 129 130 /* should fail for an unsupported blocklen */ 131 dev->blocklen = 500; 132 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 133 CU_ASSERT(g_bserrno == -EINVAL); 134 135 dev = init_dev(); 136 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 137 CU_ASSERT(g_bserrno == 0); 138 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 139 140 spdk_bs_unload(g_bs, bs_op_complete, NULL); 141 CU_ASSERT(g_bserrno == 0); 142 g_bs = NULL; 143 } 144 145 static void 146 blob_super(void) 147 { 148 struct spdk_blob_store *bs; 149 struct spdk_bs_dev *dev; 150 spdk_blob_id blobid; 151 152 dev = init_dev(); 153 154 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 155 CU_ASSERT(g_bserrno == 0); 156 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 157 bs = g_bs; 158 159 /* Get the super blob without having set one */ 160 spdk_bs_get_super(bs, blob_op_with_id_complete, NULL); 161 CU_ASSERT(g_bserrno == -ENOENT); 162 CU_ASSERT(g_blobid == SPDK_BLOBID_INVALID); 163 164 /* Create a blob */ 165 spdk_bs_md_create_blob(bs, 166 blob_op_with_id_complete, NULL); 167 CU_ASSERT(g_bserrno == 0); 168 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 169 blobid = g_blobid; 170 171 /* Set the blob as the super blob */ 172 spdk_bs_set_super(bs, blobid, blob_op_complete, NULL); 173 CU_ASSERT(g_bserrno == 0); 174 175 /* Get the super blob */ 176 spdk_bs_get_super(bs, blob_op_with_id_complete, NULL); 177 CU_ASSERT(g_bserrno == 0); 178 CU_ASSERT(blobid == g_blobid); 179 180 spdk_bs_unload(g_bs, bs_op_complete, NULL); 181 CU_ASSERT(g_bserrno == 0); 182 g_bs = NULL; 183 } 184 185 static void 186 blob_open(void) 187 { 188 struct spdk_blob_store *bs; 189 struct spdk_bs_dev *dev; 190 struct spdk_blob *blob; 191 spdk_blob_id blobid, blobid2; 192 193 dev = init_dev(); 194 195 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 196 CU_ASSERT(g_bserrno == 0); 197 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 198 bs = g_bs; 199 200 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 201 CU_ASSERT(g_bserrno == 0); 202 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 203 blobid = g_blobid; 204 205 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 206 CU_ASSERT(g_bserrno == 0); 207 CU_ASSERT(g_blob != NULL); 208 blob = g_blob; 209 210 blobid2 = spdk_blob_get_id(blob); 211 CU_ASSERT(blobid == blobid2); 212 213 /* Try to open file again. It should return success. */ 214 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 215 CU_ASSERT(g_bserrno == 0); 216 CU_ASSERT(blob == g_blob); 217 218 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 219 CU_ASSERT(g_bserrno == 0); 220 CU_ASSERT(blob == NULL); 221 222 /* 223 * Close the file a second time, releasing the second reference. This 224 * should succeed. 225 */ 226 blob = g_blob; 227 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 228 CU_ASSERT(g_bserrno == 0); 229 230 /* 231 * Try to open file again. It should succeed. This tests the case 232 * where the file is opened, closed, then re-opened again. 233 */ 234 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 235 CU_ASSERT(g_bserrno == 0); 236 CU_ASSERT(g_blob != NULL); 237 blob = g_blob; 238 239 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 240 CU_ASSERT(g_bserrno == 0); 241 242 spdk_bs_unload(g_bs, bs_op_complete, NULL); 243 CU_ASSERT(g_bserrno == 0); 244 g_bs = NULL; 245 } 246 247 static void 248 blob_delete(void) 249 { 250 struct spdk_blob_store *bs; 251 struct spdk_bs_dev *dev; 252 spdk_blob_id blobid; 253 254 dev = init_dev(); 255 256 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 257 CU_ASSERT(g_bserrno == 0); 258 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 259 bs = g_bs; 260 261 /* Create a blob and then delete it. */ 262 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 263 CU_ASSERT(g_bserrno == 0); 264 CU_ASSERT(g_blobid > 0); 265 blobid = g_blobid; 266 267 spdk_bs_md_delete_blob(bs, blobid, blob_op_complete, NULL); 268 CU_ASSERT(g_bserrno == 0); 269 270 /* Try to open the blob */ 271 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 272 CU_ASSERT(g_bserrno == -ENOENT); 273 274 spdk_bs_unload(g_bs, bs_op_complete, NULL); 275 CU_ASSERT(g_bserrno == 0); 276 g_bs = NULL; 277 } 278 279 static void 280 blob_resize(void) 281 { 282 struct spdk_blob_store *bs; 283 struct spdk_bs_dev *dev; 284 struct spdk_blob *blob; 285 spdk_blob_id blobid; 286 uint64_t free_clusters; 287 int rc; 288 289 dev = init_dev(); 290 291 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 292 CU_ASSERT(g_bserrno == 0); 293 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 294 bs = g_bs; 295 free_clusters = spdk_bs_free_cluster_count(bs); 296 297 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 298 CU_ASSERT(g_bserrno == 0); 299 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 300 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 301 blobid = g_blobid; 302 303 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 304 CU_ASSERT(g_bserrno == 0); 305 CU_ASSERT(g_blob != NULL); 306 blob = g_blob; 307 308 /* The blob started at 0 clusters. Resize it to be 5. */ 309 rc = spdk_bs_md_resize_blob(blob, 5); 310 CU_ASSERT(rc == 0); 311 CU_ASSERT((free_clusters - 5) == spdk_bs_free_cluster_count(bs)); 312 313 /* Shrink the blob to 3 clusters. This will not actually release 314 * the old clusters until the blob is synced. 315 */ 316 rc = spdk_bs_md_resize_blob(blob, 3); 317 CU_ASSERT(rc == 0); 318 /* Verify there are still 5 clusters in use */ 319 CU_ASSERT((free_clusters - 5) == spdk_bs_free_cluster_count(bs)); 320 321 spdk_bs_md_sync_blob(blob, blob_op_complete, NULL); 322 CU_ASSERT(g_bserrno == 0); 323 /* Now there are only 3 clusters in use */ 324 CU_ASSERT((free_clusters - 3) == spdk_bs_free_cluster_count(bs)); 325 326 /* Resize the blob to be 10 clusters. Growth takes effect immediately. */ 327 rc = spdk_bs_md_resize_blob(blob, 10); 328 CU_ASSERT(rc == 0); 329 CU_ASSERT((free_clusters - 10) == spdk_bs_free_cluster_count(bs)); 330 331 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 332 CU_ASSERT(g_bserrno == 0); 333 334 spdk_bs_md_delete_blob(bs, blobid, blob_op_complete, NULL); 335 CU_ASSERT(g_bserrno == 0); 336 337 spdk_bs_unload(g_bs, bs_op_complete, NULL); 338 CU_ASSERT(g_bserrno == 0); 339 g_bs = NULL; 340 } 341 342 static void 343 channel_ops(void) 344 { 345 struct spdk_blob_store *bs; 346 struct spdk_bs_dev *dev; 347 struct spdk_io_channel *channel; 348 349 dev = init_dev(); 350 351 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 352 CU_ASSERT(g_bserrno == 0); 353 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 354 bs = g_bs; 355 356 channel = spdk_bs_alloc_io_channel(bs); 357 CU_ASSERT(channel != NULL); 358 359 spdk_bs_free_io_channel(channel); 360 361 spdk_bs_unload(g_bs, bs_op_complete, NULL); 362 CU_ASSERT(g_bserrno == 0); 363 g_bs = NULL; 364 } 365 366 static void 367 blob_write(void) 368 { 369 struct spdk_blob_store *bs; 370 struct spdk_bs_dev *dev; 371 struct spdk_blob *blob; 372 struct spdk_io_channel *channel; 373 spdk_blob_id blobid; 374 uint64_t pages_per_cluster; 375 uint8_t payload[10 * 4096]; 376 int rc; 377 378 dev = init_dev(); 379 380 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 381 CU_ASSERT(g_bserrno == 0); 382 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 383 bs = g_bs; 384 385 pages_per_cluster = spdk_bs_get_cluster_size(bs) / spdk_bs_get_page_size(bs); 386 387 channel = spdk_bs_alloc_io_channel(bs); 388 CU_ASSERT(channel != NULL); 389 390 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 391 CU_ASSERT(g_bserrno == 0); 392 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 393 blobid = g_blobid; 394 395 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 396 CU_ASSERT(g_bserrno == 0); 397 CU_ASSERT(g_blob != NULL); 398 blob = g_blob; 399 400 /* Write to a blob with 0 size */ 401 spdk_bs_io_write_blob(blob, channel, payload, 0, 1, blob_op_complete, NULL); 402 CU_ASSERT(g_bserrno == -EINVAL); 403 404 /* Resize the blob */ 405 rc = spdk_bs_md_resize_blob(blob, 5); 406 CU_ASSERT(rc == 0); 407 408 /* Write to the blob */ 409 spdk_bs_io_write_blob(blob, channel, payload, 0, 1, blob_op_complete, NULL); 410 CU_ASSERT(g_bserrno == 0); 411 412 /* Write starting beyond the end */ 413 spdk_bs_io_write_blob(blob, channel, payload, 5 * pages_per_cluster, 1, blob_op_complete, 414 NULL); 415 CU_ASSERT(g_bserrno == -EINVAL); 416 417 /* Write starting at a valid location but going off the end */ 418 spdk_bs_io_write_blob(blob, channel, payload, 4 * pages_per_cluster, pages_per_cluster + 1, 419 blob_op_complete, NULL); 420 CU_ASSERT(g_bserrno == -EINVAL); 421 422 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 423 CU_ASSERT(g_bserrno == 0); 424 425 spdk_bs_free_io_channel(channel); 426 427 spdk_bs_unload(g_bs, bs_op_complete, NULL); 428 CU_ASSERT(g_bserrno == 0); 429 g_bs = NULL; 430 } 431 432 static void 433 blob_read(void) 434 { 435 struct spdk_blob_store *bs; 436 struct spdk_bs_dev *dev; 437 struct spdk_blob *blob; 438 struct spdk_io_channel *channel; 439 spdk_blob_id blobid; 440 uint64_t pages_per_cluster; 441 uint8_t payload[10 * 4096]; 442 int rc; 443 444 dev = init_dev(); 445 446 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 447 CU_ASSERT(g_bserrno == 0); 448 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 449 bs = g_bs; 450 451 pages_per_cluster = spdk_bs_get_cluster_size(bs) / spdk_bs_get_page_size(bs); 452 453 channel = spdk_bs_alloc_io_channel(bs); 454 CU_ASSERT(channel != NULL); 455 456 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 457 CU_ASSERT(g_bserrno == 0); 458 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 459 blobid = g_blobid; 460 461 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 462 CU_ASSERT(g_bserrno == 0); 463 CU_ASSERT(g_blob != NULL); 464 blob = g_blob; 465 466 /* Read from a blob with 0 size */ 467 spdk_bs_io_read_blob(blob, channel, payload, 0, 1, blob_op_complete, NULL); 468 CU_ASSERT(g_bserrno == -EINVAL); 469 470 /* Resize the blob */ 471 rc = spdk_bs_md_resize_blob(blob, 5); 472 CU_ASSERT(rc == 0); 473 474 /* Read from the blob */ 475 spdk_bs_io_read_blob(blob, channel, payload, 0, 1, blob_op_complete, NULL); 476 CU_ASSERT(g_bserrno == 0); 477 478 /* Read starting beyond the end */ 479 spdk_bs_io_read_blob(blob, channel, payload, 5 * pages_per_cluster, 1, blob_op_complete, 480 NULL); 481 CU_ASSERT(g_bserrno == -EINVAL); 482 483 /* Read starting at a valid location but going off the end */ 484 spdk_bs_io_read_blob(blob, channel, payload, 4 * pages_per_cluster, pages_per_cluster + 1, 485 blob_op_complete, NULL); 486 CU_ASSERT(g_bserrno == -EINVAL); 487 488 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 489 CU_ASSERT(g_bserrno == 0); 490 491 spdk_bs_free_io_channel(channel); 492 493 spdk_bs_unload(g_bs, bs_op_complete, NULL); 494 CU_ASSERT(g_bserrno == 0); 495 g_bs = NULL; 496 } 497 498 static void 499 blob_rw_verify(void) 500 { 501 struct spdk_blob_store *bs; 502 struct spdk_bs_dev *dev; 503 struct spdk_blob *blob; 504 struct spdk_io_channel *channel; 505 spdk_blob_id blobid; 506 uint8_t payload_read[10 * 4096]; 507 uint8_t payload_write[10 * 4096]; 508 int rc; 509 510 dev = init_dev(); 511 512 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 513 CU_ASSERT(g_bserrno == 0); 514 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 515 bs = g_bs; 516 517 channel = spdk_bs_alloc_io_channel(bs); 518 CU_ASSERT(channel != NULL); 519 520 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 521 CU_ASSERT(g_bserrno == 0); 522 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 523 blobid = g_blobid; 524 525 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 526 CU_ASSERT(g_bserrno == 0); 527 CU_ASSERT(g_blob != NULL); 528 blob = g_blob; 529 530 rc = spdk_bs_md_resize_blob(blob, 32); 531 CU_ASSERT(rc == 0); 532 533 memset(payload_write, 0xE5, sizeof(payload_write)); 534 spdk_bs_io_write_blob(blob, channel, payload_write, 4, 10, blob_op_complete, NULL); 535 CU_ASSERT(g_bserrno == 0); 536 537 memset(payload_read, 0x00, sizeof(payload_read)); 538 spdk_bs_io_read_blob(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 539 CU_ASSERT(g_bserrno == 0); 540 CU_ASSERT(memcmp(payload_write, payload_read, 4 * 4096) == 0); 541 542 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 543 CU_ASSERT(g_bserrno == 0); 544 545 spdk_bs_free_io_channel(channel); 546 547 spdk_bs_unload(g_bs, bs_op_complete, NULL); 548 CU_ASSERT(g_bserrno == 0); 549 g_bs = NULL; 550 } 551 552 static void 553 blob_rw_verify_iov(void) 554 { 555 struct spdk_blob_store *bs; 556 struct spdk_bs_dev *dev; 557 struct spdk_blob *blob; 558 struct spdk_io_channel *channel; 559 spdk_blob_id blobid; 560 uint8_t payload_read[10 * 4096]; 561 uint8_t payload_write[10 * 4096]; 562 struct iovec iov_read[3]; 563 struct iovec iov_write[3]; 564 void *buf; 565 int rc; 566 567 dev = init_dev(); 568 memset(g_dev_buffer, 0, DEV_BUFFER_SIZE); 569 570 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 571 CU_ASSERT(g_bserrno == 0); 572 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 573 bs = g_bs; 574 575 channel = spdk_bs_alloc_io_channel(bs); 576 CU_ASSERT(channel != NULL); 577 578 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 579 CU_ASSERT(g_bserrno == 0); 580 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 581 blobid = g_blobid; 582 583 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 584 CU_ASSERT(g_bserrno == 0); 585 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 586 blob = g_blob; 587 588 rc = spdk_bs_md_resize_blob(blob, 2); 589 CU_ASSERT(rc == 0); 590 591 /* 592 * Manually adjust the offset of the blob's second cluster. This allows 593 * us to make sure that the readv/write code correctly accounts for I/O 594 * that cross cluster boundaries. Start by asserting that the allocated 595 * clusters are where we expect before modifying the second cluster. 596 */ 597 CU_ASSERT(blob->active.clusters[0] == 1 * 256); 598 CU_ASSERT(blob->active.clusters[1] == 2 * 256); 599 blob->active.clusters[1] = 3 * 256; 600 601 memset(payload_write, 0xE5, sizeof(payload_write)); 602 iov_write[0].iov_base = payload_write; 603 iov_write[0].iov_len = 1 * 4096; 604 iov_write[1].iov_base = payload_write + 1 * 4096; 605 iov_write[1].iov_len = 5 * 4096; 606 iov_write[2].iov_base = payload_write + 6 * 4096; 607 iov_write[2].iov_len = 4 * 4096; 608 /* 609 * Choose a page offset just before the cluster boundary. The first 6 pages of payload 610 * will get written to the first cluster, the last 4 to the second cluster. 611 */ 612 spdk_bs_io_writev_blob(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 613 CU_ASSERT(g_bserrno == 0); 614 615 memset(payload_read, 0xAA, sizeof(payload_read)); 616 iov_read[0].iov_base = payload_read; 617 iov_read[0].iov_len = 3 * 4096; 618 iov_read[1].iov_base = payload_read + 3 * 4096; 619 iov_read[1].iov_len = 4 * 4096; 620 iov_read[2].iov_base = payload_read + 7 * 4096; 621 iov_read[2].iov_len = 3 * 4096; 622 spdk_bs_io_readv_blob(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 623 CU_ASSERT(g_bserrno == 0); 624 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 625 626 buf = calloc(1, 256 * 4096); 627 SPDK_CU_ASSERT_FATAL(buf != NULL); 628 /* Check that cluster 2 on "disk" was not modified. */ 629 CU_ASSERT(memcmp(buf, &g_dev_buffer[512 * 4096], 256 * 4096) == 0); 630 free(buf); 631 632 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 633 CU_ASSERT(g_bserrno == 0); 634 635 spdk_bs_free_io_channel(channel); 636 637 spdk_bs_unload(g_bs, bs_op_complete, NULL); 638 CU_ASSERT(g_bserrno == 0); 639 g_bs = NULL; 640 } 641 642 static uint32_t 643 bs_channel_get_req_count(struct spdk_io_channel *_channel) 644 { 645 struct spdk_bs_channel *channel = spdk_io_channel_get_ctx(_channel); 646 struct spdk_bs_request_set *set; 647 uint32_t count = 0; 648 649 TAILQ_FOREACH(set, &channel->reqs, link) { 650 count++; 651 } 652 653 return count; 654 } 655 656 static void 657 blob_rw_verify_iov_nomem(void) 658 { 659 struct spdk_blob_store *bs; 660 struct spdk_bs_dev *dev; 661 struct spdk_blob *blob; 662 struct spdk_io_channel *channel; 663 spdk_blob_id blobid; 664 uint8_t payload_write[10 * 4096]; 665 struct iovec iov_write[3]; 666 uint32_t req_count; 667 int rc; 668 669 dev = init_dev(); 670 memset(g_dev_buffer, 0, DEV_BUFFER_SIZE); 671 672 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 673 CU_ASSERT(g_bserrno == 0); 674 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 675 bs = g_bs; 676 677 channel = spdk_bs_alloc_io_channel(bs); 678 CU_ASSERT(channel != NULL); 679 680 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 681 CU_ASSERT(g_bserrno == 0); 682 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 683 blobid = g_blobid; 684 685 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 686 CU_ASSERT(g_bserrno == 0); 687 CU_ASSERT(g_blob != NULL); 688 blob = g_blob; 689 690 rc = spdk_bs_md_resize_blob(blob, 2); 691 CU_ASSERT(rc == 0); 692 693 /* 694 * Choose a page offset just before the cluster boundary. The first 6 pages of payload 695 * will get written to the first cluster, the last 4 to the second cluster. 696 */ 697 iov_write[0].iov_base = payload_write; 698 iov_write[0].iov_len = 1 * 4096; 699 iov_write[1].iov_base = payload_write + 1 * 4096; 700 iov_write[1].iov_len = 5 * 4096; 701 iov_write[2].iov_base = payload_write + 6 * 4096; 702 iov_write[2].iov_len = 4 * 4096; 703 MOCK_SET(calloc, void *, NULL); 704 req_count = bs_channel_get_req_count(channel); 705 spdk_bs_io_writev_blob(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 706 CU_ASSERT(g_bserrno = -ENOMEM); 707 CU_ASSERT(req_count == bs_channel_get_req_count(channel)); 708 MOCK_SET(calloc, void *, (void *)MOCK_PASS_THRU); 709 710 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 711 CU_ASSERT(g_bserrno == 0); 712 713 spdk_bs_free_io_channel(channel); 714 715 spdk_bs_unload(g_bs, bs_op_complete, NULL); 716 CU_ASSERT(g_bserrno == 0); 717 g_bs = NULL; 718 } 719 720 static void 721 blob_iter(void) 722 { 723 struct spdk_blob_store *bs; 724 struct spdk_bs_dev *dev; 725 struct spdk_blob *blob; 726 spdk_blob_id blobid; 727 728 dev = init_dev(); 729 730 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 731 CU_ASSERT(g_bserrno == 0); 732 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 733 bs = g_bs; 734 735 spdk_bs_md_iter_first(bs, blob_op_with_handle_complete, NULL); 736 CU_ASSERT(g_blob == NULL); 737 CU_ASSERT(g_bserrno == -ENOENT); 738 739 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 740 CU_ASSERT(g_bserrno == 0); 741 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 742 blobid = g_blobid; 743 744 spdk_bs_md_iter_first(bs, blob_op_with_handle_complete, NULL); 745 CU_ASSERT(g_blob != NULL); 746 CU_ASSERT(g_bserrno == 0); 747 blob = g_blob; 748 CU_ASSERT(spdk_blob_get_id(blob) == blobid); 749 750 spdk_bs_md_iter_next(bs, &blob, blob_op_with_handle_complete, NULL); 751 CU_ASSERT(g_blob == NULL); 752 CU_ASSERT(g_bserrno == -ENOENT); 753 754 spdk_bs_unload(g_bs, bs_op_complete, NULL); 755 CU_ASSERT(g_bserrno == 0); 756 g_bs = NULL; 757 } 758 759 static void 760 blob_xattr(void) 761 { 762 struct spdk_blob_store *bs; 763 struct spdk_bs_dev *dev; 764 struct spdk_blob *blob; 765 spdk_blob_id blobid; 766 uint64_t length; 767 int rc; 768 const char *name1, *name2; 769 const void *value; 770 size_t value_len; 771 struct spdk_xattr_names *names; 772 773 dev = init_dev(); 774 775 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 776 CU_ASSERT(g_bserrno == 0); 777 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 778 bs = g_bs; 779 780 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 781 CU_ASSERT(g_bserrno == 0); 782 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 783 blobid = g_blobid; 784 785 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 786 CU_ASSERT(g_bserrno == 0); 787 CU_ASSERT(g_blob != NULL); 788 blob = g_blob; 789 790 rc = spdk_blob_md_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 791 CU_ASSERT(rc == 0); 792 793 length = 2345; 794 rc = spdk_blob_md_set_xattr(blob, "length", &length, sizeof(length)); 795 CU_ASSERT(rc == 0); 796 797 /* Overwrite "length" xattr. */ 798 length = 3456; 799 rc = spdk_blob_md_set_xattr(blob, "length", &length, sizeof(length)); 800 CU_ASSERT(rc == 0); 801 802 value = NULL; 803 rc = spdk_bs_md_get_xattr_value(blob, "length", &value, &value_len); 804 CU_ASSERT(rc == 0); 805 SPDK_CU_ASSERT_FATAL(value != NULL); 806 CU_ASSERT(*(uint64_t *)value == length); 807 CU_ASSERT(value_len == 8); 808 809 rc = spdk_bs_md_get_xattr_value(blob, "foobar", &value, &value_len); 810 CU_ASSERT(rc == -ENOENT); 811 812 names = NULL; 813 rc = spdk_bs_md_get_xattr_names(blob, &names); 814 CU_ASSERT(rc == 0); 815 SPDK_CU_ASSERT_FATAL(names != NULL); 816 CU_ASSERT(spdk_xattr_names_get_count(names) == 2); 817 name1 = spdk_xattr_names_get_name(names, 0); 818 SPDK_CU_ASSERT_FATAL(name1 != NULL); 819 CU_ASSERT(!strcmp(name1, "name") || !strcmp(name1, "length")); 820 name2 = spdk_xattr_names_get_name(names, 1); 821 SPDK_CU_ASSERT_FATAL(name2 != NULL); 822 CU_ASSERT(!strcmp(name2, "name") || !strcmp(name2, "length")); 823 CU_ASSERT(strcmp(name1, name2)); 824 spdk_xattr_names_free(names); 825 826 rc = spdk_blob_md_remove_xattr(blob, "name"); 827 CU_ASSERT(rc == 0); 828 829 rc = spdk_blob_md_remove_xattr(blob, "foobar"); 830 CU_ASSERT(rc == -ENOENT); 831 832 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 833 834 spdk_bs_unload(g_bs, bs_op_complete, NULL); 835 CU_ASSERT(g_bserrno == 0); 836 g_bs = NULL; 837 } 838 839 static void 840 bs_load(void) 841 { 842 struct spdk_bs_dev *dev; 843 spdk_blob_id blobid; 844 struct spdk_blob *blob; 845 struct spdk_bs_super_block *super_blob; 846 uint64_t length; 847 int rc; 848 const void *value; 849 size_t value_len; 850 851 dev = init_dev(); 852 853 /* Initialize a new blob store */ 854 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 855 CU_ASSERT(g_bserrno == 0); 856 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 857 858 /* Try to open a blobid that does not exist */ 859 spdk_bs_md_open_blob(g_bs, 0, blob_op_with_handle_complete, NULL); 860 CU_ASSERT(g_bserrno == -ENOENT); 861 CU_ASSERT(g_blob == NULL); 862 863 /* Create a blob */ 864 spdk_bs_md_create_blob(g_bs, blob_op_with_id_complete, NULL); 865 CU_ASSERT(g_bserrno == 0); 866 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 867 blobid = g_blobid; 868 869 spdk_bs_md_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 870 CU_ASSERT(g_bserrno == 0); 871 CU_ASSERT(g_blob != NULL); 872 blob = g_blob; 873 874 /* Try again to open valid blob but without the upper bit set */ 875 spdk_bs_md_open_blob(g_bs, blobid & 0xFFFFFFFF, blob_op_with_handle_complete, NULL); 876 CU_ASSERT(g_bserrno == -ENOENT); 877 CU_ASSERT(g_blob == NULL); 878 879 /* Set some xattrs */ 880 rc = spdk_blob_md_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 881 CU_ASSERT(rc == 0); 882 883 length = 2345; 884 rc = spdk_blob_md_set_xattr(blob, "length", &length, sizeof(length)); 885 CU_ASSERT(rc == 0); 886 887 /* Resize the blob */ 888 rc = spdk_bs_md_resize_blob(blob, 10); 889 CU_ASSERT(rc == 0); 890 891 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 892 CU_ASSERT(g_bserrno == 0); 893 blob = NULL; 894 g_blob = NULL; 895 g_blobid = SPDK_BLOBID_INVALID; 896 897 /* Unload the blob store */ 898 spdk_bs_unload(g_bs, bs_op_complete, NULL); 899 CU_ASSERT(g_bserrno == 0); 900 g_bs = NULL; 901 g_blob = NULL; 902 g_blobid = 0; 903 904 super_blob = (struct spdk_bs_super_block *)g_dev_buffer; 905 CU_ASSERT(super_blob->clean == 1); 906 dev = init_dev(); 907 /* Load an existing blob store */ 908 spdk_bs_load(dev, bs_op_with_handle_complete, NULL); 909 CU_ASSERT(g_bserrno == 0); 910 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 911 912 super_blob = (struct spdk_bs_super_block *)g_dev_buffer; 913 CU_ASSERT(super_blob->clean == 0); 914 915 spdk_bs_md_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 916 CU_ASSERT(g_bserrno == 0); 917 CU_ASSERT(g_blob != NULL); 918 blob = g_blob; 919 920 /* Get the xattrs */ 921 value = NULL; 922 rc = spdk_bs_md_get_xattr_value(blob, "length", &value, &value_len); 923 CU_ASSERT(rc == 0); 924 SPDK_CU_ASSERT_FATAL(value != NULL); 925 CU_ASSERT(*(uint64_t *)value == length); 926 CU_ASSERT(value_len == 8); 927 928 rc = spdk_bs_md_get_xattr_value(blob, "foobar", &value, &value_len); 929 CU_ASSERT(rc == -ENOENT); 930 931 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 932 933 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 934 CU_ASSERT(g_bserrno == 0); 935 blob = NULL; 936 g_blob = NULL; 937 g_blobid = SPDK_BLOBID_INVALID; 938 939 spdk_bs_unload(g_bs, bs_op_complete, NULL); 940 CU_ASSERT(g_bserrno == 0); 941 g_bs = NULL; 942 } 943 944 /* 945 * Create a blobstore and then unload it. 946 */ 947 static void 948 bs_unload(void) 949 { 950 struct spdk_bs_dev *dev; 951 952 dev = init_dev(); 953 954 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 955 CU_ASSERT(g_bserrno == 0); 956 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 957 958 g_bserrno = -1; 959 spdk_bs_unload(g_bs, bs_op_complete, NULL); 960 CU_ASSERT(g_bserrno == 0); 961 g_bs = NULL; 962 } 963 964 /* 965 * Create a blobstore with a cluster size different than the default, and ensure it is 966 * persisted. 967 */ 968 static void 969 bs_cluster_sz(void) 970 { 971 struct spdk_bs_dev *dev; 972 struct spdk_bs_opts opts; 973 uint32_t cluster_sz; 974 975 /* Set cluster size to zero */ 976 dev = init_dev(); 977 spdk_bs_opts_init(&opts); 978 opts.cluster_sz = 0; 979 980 /* Initialize a new blob store */ 981 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 982 CU_ASSERT(g_bserrno == -EINVAL); 983 SPDK_CU_ASSERT_FATAL(g_bs == NULL); 984 985 /* 986 * Set cluster size to blobstore page size, 987 * to work it is required to be at least twice the blobstore page size. 988 */ 989 dev = init_dev(); 990 spdk_bs_opts_init(&opts); 991 opts.cluster_sz = SPDK_BS_PAGE_SIZE; 992 993 /* Initialize a new blob store */ 994 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 995 CU_ASSERT(g_bserrno == -ENOMEM); 996 SPDK_CU_ASSERT_FATAL(g_bs == NULL); 997 998 /* Set cluster size to twice the default */ 999 dev = init_dev(); 1000 spdk_bs_opts_init(&opts); 1001 opts.cluster_sz *= 2; 1002 cluster_sz = opts.cluster_sz; 1003 1004 /* Initialize a new blob store */ 1005 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1006 CU_ASSERT(g_bserrno == 0); 1007 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1008 1009 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 1010 1011 /* Unload the blob store */ 1012 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1013 CU_ASSERT(g_bserrno == 0); 1014 g_bs = NULL; 1015 g_blob = NULL; 1016 g_blobid = 0; 1017 1018 dev = init_dev(); 1019 /* Load an existing blob store */ 1020 spdk_bs_load(dev, bs_op_with_handle_complete, NULL); 1021 CU_ASSERT(g_bserrno == 0); 1022 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1023 1024 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 1025 1026 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1027 CU_ASSERT(g_bserrno == 0); 1028 g_bs = NULL; 1029 } 1030 1031 /* 1032 * Test resizing of the metadata blob. This requires creating enough blobs 1033 * so that one cluster is not enough to fit the metadata for those blobs. 1034 * To induce this condition to happen more quickly, we reduce the cluster 1035 * size to 16KB, which means only 4 4KB blob metadata pages can fit. 1036 */ 1037 static void 1038 bs_resize_md(void) 1039 { 1040 const int CLUSTER_PAGE_COUNT = 4; 1041 const int NUM_BLOBS = CLUSTER_PAGE_COUNT * 4; 1042 struct spdk_bs_dev *dev; 1043 struct spdk_bs_opts opts; 1044 uint32_t cluster_sz; 1045 spdk_blob_id blobids[NUM_BLOBS]; 1046 int i; 1047 1048 1049 dev = init_dev(); 1050 spdk_bs_opts_init(&opts); 1051 opts.cluster_sz = CLUSTER_PAGE_COUNT * 4096; 1052 cluster_sz = opts.cluster_sz; 1053 1054 /* Initialize a new blob store */ 1055 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1056 CU_ASSERT(g_bserrno == 0); 1057 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1058 1059 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 1060 1061 for (i = 0; i < NUM_BLOBS; i++) { 1062 g_bserrno = -1; 1063 g_blobid = SPDK_BLOBID_INVALID; 1064 spdk_bs_md_create_blob(g_bs, 1065 blob_op_with_id_complete, NULL); 1066 CU_ASSERT(g_bserrno == 0); 1067 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1068 blobids[i] = g_blobid; 1069 } 1070 1071 /* Unload the blob store */ 1072 g_bserrno = -1; 1073 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1074 CU_ASSERT(g_bserrno == 0); 1075 1076 /* Load an existing blob store */ 1077 g_bserrno = -1; 1078 g_bs = NULL; 1079 dev = init_dev(); 1080 spdk_bs_load(dev, bs_op_with_handle_complete, NULL); 1081 CU_ASSERT(g_bserrno == 0); 1082 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1083 1084 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 1085 1086 for (i = 0; i < NUM_BLOBS; i++) { 1087 g_bserrno = -1; 1088 g_blob = NULL; 1089 spdk_bs_md_open_blob(g_bs, blobids[i], blob_op_with_handle_complete, NULL); 1090 CU_ASSERT(g_bserrno == 0); 1091 CU_ASSERT(g_blob != NULL); 1092 g_bserrno = -1; 1093 spdk_bs_md_close_blob(&g_blob, blob_op_complete, NULL); 1094 CU_ASSERT(g_bserrno == 0); 1095 } 1096 1097 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1098 CU_ASSERT(g_bserrno == 0); 1099 g_bs = NULL; 1100 } 1101 1102 /* Try to hit all of the corner cases associated with serializing 1103 * a blob to disk 1104 */ 1105 static void 1106 blob_serialize(void) 1107 { 1108 struct spdk_bs_dev *dev; 1109 struct spdk_bs_opts opts; 1110 struct spdk_blob_store *bs; 1111 spdk_blob_id blobid[2]; 1112 struct spdk_blob *blob[2]; 1113 uint64_t i; 1114 char *value; 1115 int rc; 1116 1117 dev = init_dev(); 1118 1119 /* Initialize a new blobstore with very small clusters */ 1120 spdk_bs_opts_init(&opts); 1121 opts.cluster_sz = dev->blocklen * 8; 1122 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1123 CU_ASSERT(g_bserrno == 0); 1124 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1125 bs = g_bs; 1126 1127 /* Create and open two blobs */ 1128 for (i = 0; i < 2; i++) { 1129 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 1130 CU_ASSERT(g_bserrno == 0); 1131 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1132 blobid[i] = g_blobid; 1133 1134 /* Open a blob */ 1135 spdk_bs_md_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL); 1136 CU_ASSERT(g_bserrno == 0); 1137 CU_ASSERT(g_blob != NULL); 1138 blob[i] = g_blob; 1139 1140 /* Set a fairly large xattr on both blobs to eat up 1141 * metadata space 1142 */ 1143 value = calloc(dev->blocklen - 64, sizeof(char)); 1144 SPDK_CU_ASSERT_FATAL(value != NULL); 1145 memset(value, i, dev->blocklen / 2); 1146 rc = spdk_blob_md_set_xattr(blob[i], "name", value, dev->blocklen - 64); 1147 CU_ASSERT(rc == 0); 1148 free(value); 1149 } 1150 1151 /* Resize the blobs, alternating 1 cluster at a time. 1152 * This thwarts run length encoding and will cause spill 1153 * over of the extents. 1154 */ 1155 for (i = 0; i < 6; i++) { 1156 rc = spdk_bs_md_resize_blob(blob[i % 2], (i / 2) + 1); 1157 CU_ASSERT(rc == 0); 1158 } 1159 1160 for (i = 0; i < 2; i++) { 1161 spdk_bs_md_sync_blob(blob[i], blob_op_complete, NULL); 1162 CU_ASSERT(g_bserrno == 0); 1163 } 1164 1165 /* Close the blobs */ 1166 for (i = 0; i < 2; i++) { 1167 spdk_bs_md_close_blob(&blob[i], blob_op_complete, NULL); 1168 CU_ASSERT(g_bserrno == 0); 1169 } 1170 1171 /* Unload the blobstore */ 1172 spdk_bs_unload(bs, bs_op_complete, NULL); 1173 CU_ASSERT(g_bserrno == 0); 1174 g_bs = NULL; 1175 g_blob = NULL; 1176 g_blobid = 0; 1177 bs = NULL; 1178 1179 dev = init_dev(); 1180 /* Load an existing blob store */ 1181 spdk_bs_load(dev, bs_op_with_handle_complete, NULL); 1182 CU_ASSERT(g_bserrno == 0); 1183 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1184 bs = g_bs; 1185 1186 for (i = 0; i < 2; i++) { 1187 blob[i] = NULL; 1188 1189 spdk_bs_md_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL); 1190 CU_ASSERT(g_bserrno == 0); 1191 CU_ASSERT(g_blob != NULL); 1192 blob[i] = g_blob; 1193 1194 CU_ASSERT(spdk_blob_get_num_clusters(blob[i]) == 3); 1195 1196 spdk_bs_md_close_blob(&blob[i], blob_op_complete, NULL); 1197 CU_ASSERT(g_bserrno == 0); 1198 } 1199 1200 spdk_bs_unload(bs, bs_op_complete, NULL); 1201 CU_ASSERT(g_bserrno == 0); 1202 g_bs = NULL; 1203 } 1204 1205 static void 1206 blob_crc(void) 1207 { 1208 struct spdk_blob_store *bs; 1209 struct spdk_bs_dev *dev; 1210 struct spdk_blob *blob; 1211 spdk_blob_id blobid; 1212 uint32_t page_num; 1213 int index; 1214 struct spdk_blob_md_page *page; 1215 1216 dev = init_dev(); 1217 1218 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1219 CU_ASSERT(g_bserrno == 0); 1220 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1221 bs = g_bs; 1222 1223 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 1224 CU_ASSERT(g_bserrno == 0); 1225 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1226 blobid = g_blobid; 1227 1228 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1229 CU_ASSERT(g_bserrno == 0); 1230 CU_ASSERT(g_blob != NULL); 1231 blob = g_blob; 1232 1233 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 1234 CU_ASSERT(g_bserrno == 0); 1235 CU_ASSERT(blob == NULL); 1236 1237 page_num = _spdk_bs_blobid_to_page(blobid); 1238 index = DEV_BUFFER_BLOCKLEN * (bs->md_start + page_num); 1239 page = (struct spdk_blob_md_page *)&g_dev_buffer[index]; 1240 page->crc = 0; 1241 1242 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1243 CU_ASSERT(g_bserrno == -EINVAL); 1244 CU_ASSERT(g_blob == NULL); 1245 g_bserrno = 0; 1246 1247 spdk_bs_md_delete_blob(bs, blobid, blob_op_complete, NULL); 1248 CU_ASSERT(g_bserrno == -EINVAL); 1249 1250 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1251 CU_ASSERT(g_bserrno == 0); 1252 g_bs = NULL; 1253 } 1254 1255 static void 1256 super_block_crc(void) 1257 { 1258 struct spdk_bs_dev *dev; 1259 struct spdk_bs_super_block *super_block; 1260 1261 dev = init_dev(); 1262 1263 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1264 CU_ASSERT(g_bserrno == 0); 1265 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1266 1267 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1268 CU_ASSERT(g_bserrno == 0); 1269 g_bs = NULL; 1270 1271 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 1272 super_block->crc = 0; 1273 dev = init_dev(); 1274 1275 g_scheduler_delay = true; 1276 /* Load an existing blob store */ 1277 spdk_bs_load(dev, bs_op_with_handle_complete, NULL); 1278 1279 CU_ASSERT(g_bserrno == -EILSEQ); 1280 _bs_flush_scheduler(); 1281 CU_ASSERT(TAILQ_EMPTY(&g_scheduled_ops)); 1282 1283 g_scheduler_delay = false; 1284 } 1285 1286 int main(int argc, char **argv) 1287 { 1288 CU_pSuite suite = NULL; 1289 unsigned int num_failures; 1290 1291 if (CU_initialize_registry() != CUE_SUCCESS) { 1292 return CU_get_error(); 1293 } 1294 1295 suite = CU_add_suite("blob", NULL, NULL); 1296 if (suite == NULL) { 1297 CU_cleanup_registry(); 1298 return CU_get_error(); 1299 } 1300 1301 if ( 1302 CU_add_test(suite, "blob_init", blob_init) == NULL || 1303 CU_add_test(suite, "blob_open", blob_open) == NULL || 1304 CU_add_test(suite, "blob_delete", blob_delete) == NULL || 1305 CU_add_test(suite, "blob_resize", blob_resize) == NULL || 1306 CU_add_test(suite, "channel_ops", channel_ops) == NULL || 1307 CU_add_test(suite, "blob_super", blob_super) == NULL || 1308 CU_add_test(suite, "blob_write", blob_write) == NULL || 1309 CU_add_test(suite, "blob_read", blob_read) == NULL || 1310 CU_add_test(suite, "blob_rw_verify", blob_rw_verify) == NULL || 1311 CU_add_test(suite, "blob_rw_verify_iov", blob_rw_verify_iov) == NULL || 1312 CU_add_test(suite, "blob_rw_verify_iov_nomem", blob_rw_verify_iov_nomem) == NULL || 1313 CU_add_test(suite, "blob_iter", blob_iter) == NULL || 1314 CU_add_test(suite, "blob_xattr", blob_xattr) == NULL || 1315 CU_add_test(suite, "bs_load", bs_load) == NULL || 1316 CU_add_test(suite, "bs_unload", bs_unload) == NULL || 1317 CU_add_test(suite, "bs_cluster_sz", bs_cluster_sz) == NULL || 1318 CU_add_test(suite, "bs_resize_md", bs_resize_md) == NULL || 1319 CU_add_test(suite, "blob_serialize", blob_serialize) == NULL || 1320 CU_add_test(suite, "blob_crc", blob_crc) == NULL || 1321 CU_add_test(suite, "super_block_crc", super_block_crc) == NULL 1322 ) { 1323 CU_cleanup_registry(); 1324 return CU_get_error(); 1325 } 1326 1327 g_dev_buffer = calloc(1, DEV_BUFFER_SIZE); 1328 spdk_allocate_thread(_bs_send_msg, NULL, "thread0"); 1329 CU_basic_set_mode(CU_BRM_VERBOSE); 1330 CU_basic_run_tests(); 1331 num_failures = CU_get_number_of_failures(); 1332 CU_cleanup_registry(); 1333 spdk_free_thread(); 1334 free(g_dev_buffer); 1335 return num_failures; 1336 } 1337