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 struct spdk_bs_super_block_ver1 { 63 uint8_t signature[8]; 64 uint32_t version; 65 uint32_t length; 66 uint32_t clean; /* If there was a clean shutdown, this is 1. */ 67 spdk_blob_id super_blob; 68 69 uint32_t cluster_size; /* In bytes */ 70 71 uint32_t used_page_mask_start; /* Offset from beginning of disk, in pages */ 72 uint32_t used_page_mask_len; /* Count, in pages */ 73 74 uint32_t used_cluster_mask_start; /* Offset from beginning of disk, in pages */ 75 uint32_t used_cluster_mask_len; /* Count, in pages */ 76 77 uint32_t md_start; /* Offset from beginning of disk, in pages */ 78 uint32_t md_len; /* Count, in pages */ 79 80 uint8_t reserved[4036]; 81 uint32_t crc; 82 } __attribute__((packed)); 83 SPDK_STATIC_ASSERT(sizeof(struct spdk_bs_super_block_ver1) == 0x1000, "Invalid super block size"); 84 85 static void 86 _bs_send_msg(spdk_thread_fn fn, void *ctx, void *thread_ctx) 87 { 88 if (g_scheduler_delay) { 89 struct scheduled_ops *ops = calloc(1, sizeof(*ops)); 90 91 SPDK_CU_ASSERT_FATAL(ops != NULL); 92 ops->fn = fn; 93 ops->ctx = ctx; 94 TAILQ_INSERT_TAIL(&g_scheduled_ops, ops, ops_queue); 95 } else { 96 fn(ctx); 97 } 98 } 99 100 static void 101 _bs_flush_scheduler(void) 102 { 103 struct scheduled_ops *ops, *tmp; 104 105 TAILQ_FOREACH_SAFE(ops, &g_scheduled_ops, ops_queue, tmp) { 106 ops->fn(ops->ctx); 107 TAILQ_REMOVE(&g_scheduled_ops, ops, ops_queue); 108 free(ops); 109 } 110 } 111 112 static void 113 bs_op_complete(void *cb_arg, int bserrno) 114 { 115 g_bserrno = bserrno; 116 } 117 118 static void 119 bs_op_with_handle_complete(void *cb_arg, struct spdk_blob_store *bs, 120 int bserrno) 121 { 122 g_bs = bs; 123 g_bserrno = bserrno; 124 } 125 126 static void 127 blob_op_complete(void *cb_arg, int bserrno) 128 { 129 g_bserrno = bserrno; 130 } 131 132 static void 133 blob_op_with_id_complete(void *cb_arg, spdk_blob_id blobid, int bserrno) 134 { 135 g_blobid = blobid; 136 g_bserrno = bserrno; 137 } 138 139 static void 140 blob_op_with_handle_complete(void *cb_arg, struct spdk_blob *blb, int bserrno) 141 { 142 g_blob = blb; 143 g_bserrno = bserrno; 144 } 145 146 static void 147 blob_init(void) 148 { 149 struct spdk_bs_dev *dev; 150 151 dev = init_dev(); 152 153 /* should fail for an unsupported blocklen */ 154 dev->blocklen = 500; 155 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 156 CU_ASSERT(g_bserrno == -EINVAL); 157 158 dev = init_dev(); 159 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 160 CU_ASSERT(g_bserrno == 0); 161 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 162 163 spdk_bs_unload(g_bs, bs_op_complete, NULL); 164 CU_ASSERT(g_bserrno == 0); 165 g_bs = NULL; 166 } 167 168 static void 169 blob_super(void) 170 { 171 struct spdk_blob_store *bs; 172 struct spdk_bs_dev *dev; 173 spdk_blob_id blobid; 174 175 dev = init_dev(); 176 177 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 178 CU_ASSERT(g_bserrno == 0); 179 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 180 bs = g_bs; 181 182 /* Get the super blob without having set one */ 183 spdk_bs_get_super(bs, blob_op_with_id_complete, NULL); 184 CU_ASSERT(g_bserrno == -ENOENT); 185 CU_ASSERT(g_blobid == SPDK_BLOBID_INVALID); 186 187 /* Create a blob */ 188 spdk_bs_md_create_blob(bs, 189 blob_op_with_id_complete, NULL); 190 CU_ASSERT(g_bserrno == 0); 191 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 192 blobid = g_blobid; 193 194 /* Set the blob as the super blob */ 195 spdk_bs_set_super(bs, blobid, blob_op_complete, NULL); 196 CU_ASSERT(g_bserrno == 0); 197 198 /* Get the super blob */ 199 spdk_bs_get_super(bs, blob_op_with_id_complete, NULL); 200 CU_ASSERT(g_bserrno == 0); 201 CU_ASSERT(blobid == g_blobid); 202 203 spdk_bs_unload(g_bs, bs_op_complete, NULL); 204 CU_ASSERT(g_bserrno == 0); 205 g_bs = NULL; 206 } 207 208 static void 209 blob_open(void) 210 { 211 struct spdk_blob_store *bs; 212 struct spdk_bs_dev *dev; 213 struct spdk_blob *blob; 214 spdk_blob_id blobid, blobid2; 215 216 dev = init_dev(); 217 218 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 219 CU_ASSERT(g_bserrno == 0); 220 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 221 bs = g_bs; 222 223 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 224 CU_ASSERT(g_bserrno == 0); 225 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 226 blobid = g_blobid; 227 228 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 229 CU_ASSERT(g_bserrno == 0); 230 CU_ASSERT(g_blob != NULL); 231 blob = g_blob; 232 233 blobid2 = spdk_blob_get_id(blob); 234 CU_ASSERT(blobid == blobid2); 235 236 /* Try to open file again. It should return success. */ 237 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 238 CU_ASSERT(g_bserrno == 0); 239 CU_ASSERT(blob == g_blob); 240 241 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 242 CU_ASSERT(g_bserrno == 0); 243 CU_ASSERT(blob == NULL); 244 245 /* 246 * Close the file a second time, releasing the second reference. This 247 * should succeed. 248 */ 249 blob = g_blob; 250 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 251 CU_ASSERT(g_bserrno == 0); 252 253 /* 254 * Try to open file again. It should succeed. This tests the case 255 * where the file is opened, closed, then re-opened again. 256 */ 257 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 258 CU_ASSERT(g_bserrno == 0); 259 CU_ASSERT(g_blob != NULL); 260 blob = g_blob; 261 262 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 263 CU_ASSERT(g_bserrno == 0); 264 265 spdk_bs_unload(g_bs, bs_op_complete, NULL); 266 CU_ASSERT(g_bserrno == 0); 267 g_bs = NULL; 268 } 269 270 static void 271 blob_delete(void) 272 { 273 struct spdk_blob_store *bs; 274 struct spdk_bs_dev *dev; 275 spdk_blob_id blobid; 276 277 dev = init_dev(); 278 279 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 280 CU_ASSERT(g_bserrno == 0); 281 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 282 bs = g_bs; 283 284 /* Create a blob and then delete it. */ 285 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 286 CU_ASSERT(g_bserrno == 0); 287 CU_ASSERT(g_blobid > 0); 288 blobid = g_blobid; 289 290 spdk_bs_md_delete_blob(bs, blobid, blob_op_complete, NULL); 291 CU_ASSERT(g_bserrno == 0); 292 293 /* Try to open the blob */ 294 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 295 CU_ASSERT(g_bserrno == -ENOENT); 296 297 spdk_bs_unload(g_bs, bs_op_complete, NULL); 298 CU_ASSERT(g_bserrno == 0); 299 g_bs = NULL; 300 } 301 302 static void 303 blob_resize(void) 304 { 305 struct spdk_blob_store *bs; 306 struct spdk_bs_dev *dev; 307 struct spdk_blob *blob; 308 spdk_blob_id blobid; 309 uint64_t free_clusters; 310 int rc; 311 312 dev = init_dev(); 313 314 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 315 CU_ASSERT(g_bserrno == 0); 316 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 317 bs = g_bs; 318 free_clusters = spdk_bs_free_cluster_count(bs); 319 320 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 321 CU_ASSERT(g_bserrno == 0); 322 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 323 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 324 blobid = g_blobid; 325 326 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 327 CU_ASSERT(g_bserrno == 0); 328 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 329 blob = g_blob; 330 331 /* Confirm that resize fails if blob is marked read-only. */ 332 blob->md_ro = true; 333 rc = spdk_bs_md_resize_blob(blob, 5); 334 CU_ASSERT(rc == -EPERM); 335 blob->md_ro = false; 336 337 /* The blob started at 0 clusters. Resize it to be 5. */ 338 rc = spdk_bs_md_resize_blob(blob, 5); 339 CU_ASSERT(rc == 0); 340 CU_ASSERT((free_clusters - 5) == spdk_bs_free_cluster_count(bs)); 341 342 /* Shrink the blob to 3 clusters. This will not actually release 343 * the old clusters until the blob is synced. 344 */ 345 rc = spdk_bs_md_resize_blob(blob, 3); 346 CU_ASSERT(rc == 0); 347 /* Verify there are still 5 clusters in use */ 348 CU_ASSERT((free_clusters - 5) == spdk_bs_free_cluster_count(bs)); 349 350 spdk_bs_md_sync_blob(blob, blob_op_complete, NULL); 351 CU_ASSERT(g_bserrno == 0); 352 /* Now there are only 3 clusters in use */ 353 CU_ASSERT((free_clusters - 3) == spdk_bs_free_cluster_count(bs)); 354 355 /* Resize the blob to be 10 clusters. Growth takes effect immediately. */ 356 rc = spdk_bs_md_resize_blob(blob, 10); 357 CU_ASSERT(rc == 0); 358 CU_ASSERT((free_clusters - 10) == spdk_bs_free_cluster_count(bs)); 359 360 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 361 CU_ASSERT(g_bserrno == 0); 362 363 spdk_bs_md_delete_blob(bs, blobid, blob_op_complete, NULL); 364 CU_ASSERT(g_bserrno == 0); 365 366 spdk_bs_unload(g_bs, bs_op_complete, NULL); 367 CU_ASSERT(g_bserrno == 0); 368 g_bs = NULL; 369 } 370 371 static void 372 channel_ops(void) 373 { 374 struct spdk_blob_store *bs; 375 struct spdk_bs_dev *dev; 376 struct spdk_io_channel *channel; 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 channel = spdk_bs_alloc_io_channel(bs); 386 CU_ASSERT(channel != NULL); 387 388 spdk_bs_free_io_channel(channel); 389 390 spdk_bs_unload(g_bs, bs_op_complete, NULL); 391 CU_ASSERT(g_bserrno == 0); 392 g_bs = NULL; 393 } 394 395 static void 396 blob_write(void) 397 { 398 struct spdk_blob_store *bs; 399 struct spdk_bs_dev *dev; 400 struct spdk_blob *blob; 401 struct spdk_io_channel *channel; 402 spdk_blob_id blobid; 403 uint64_t pages_per_cluster; 404 uint8_t payload[10 * 4096]; 405 int rc; 406 407 dev = init_dev(); 408 409 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 410 CU_ASSERT(g_bserrno == 0); 411 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 412 bs = g_bs; 413 414 pages_per_cluster = spdk_bs_get_cluster_size(bs) / spdk_bs_get_page_size(bs); 415 416 channel = spdk_bs_alloc_io_channel(bs); 417 CU_ASSERT(channel != NULL); 418 419 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 420 CU_ASSERT(g_bserrno == 0); 421 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 422 blobid = g_blobid; 423 424 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 425 CU_ASSERT(g_bserrno == 0); 426 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 427 blob = g_blob; 428 429 /* Write to a blob with 0 size */ 430 spdk_bs_io_write_blob(blob, channel, payload, 0, 1, blob_op_complete, NULL); 431 CU_ASSERT(g_bserrno == -EINVAL); 432 433 /* Resize the blob */ 434 rc = spdk_bs_md_resize_blob(blob, 5); 435 CU_ASSERT(rc == 0); 436 437 /* Confirm that write fails if blob is marked read-only. */ 438 blob->data_ro = true; 439 spdk_bs_io_write_blob(blob, channel, payload, 0, 1, blob_op_complete, NULL); 440 CU_ASSERT(g_bserrno == -EPERM); 441 blob->data_ro = false; 442 443 /* Write to the blob */ 444 spdk_bs_io_write_blob(blob, channel, payload, 0, 1, blob_op_complete, NULL); 445 CU_ASSERT(g_bserrno == 0); 446 447 /* Write starting beyond the end */ 448 spdk_bs_io_write_blob(blob, channel, payload, 5 * pages_per_cluster, 1, blob_op_complete, 449 NULL); 450 CU_ASSERT(g_bserrno == -EINVAL); 451 452 /* Write starting at a valid location but going off the end */ 453 spdk_bs_io_write_blob(blob, channel, payload, 4 * pages_per_cluster, pages_per_cluster + 1, 454 blob_op_complete, NULL); 455 CU_ASSERT(g_bserrno == -EINVAL); 456 457 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 458 CU_ASSERT(g_bserrno == 0); 459 460 spdk_bs_free_io_channel(channel); 461 462 spdk_bs_unload(g_bs, bs_op_complete, NULL); 463 CU_ASSERT(g_bserrno == 0); 464 g_bs = NULL; 465 } 466 467 static void 468 blob_read(void) 469 { 470 struct spdk_blob_store *bs; 471 struct spdk_bs_dev *dev; 472 struct spdk_blob *blob; 473 struct spdk_io_channel *channel; 474 spdk_blob_id blobid; 475 uint64_t pages_per_cluster; 476 uint8_t payload[10 * 4096]; 477 int rc; 478 479 dev = init_dev(); 480 481 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 482 CU_ASSERT(g_bserrno == 0); 483 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 484 bs = g_bs; 485 486 pages_per_cluster = spdk_bs_get_cluster_size(bs) / spdk_bs_get_page_size(bs); 487 488 channel = spdk_bs_alloc_io_channel(bs); 489 CU_ASSERT(channel != NULL); 490 491 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 492 CU_ASSERT(g_bserrno == 0); 493 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 494 blobid = g_blobid; 495 496 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 497 CU_ASSERT(g_bserrno == 0); 498 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 499 blob = g_blob; 500 501 /* Read from a blob with 0 size */ 502 spdk_bs_io_read_blob(blob, channel, payload, 0, 1, blob_op_complete, NULL); 503 CU_ASSERT(g_bserrno == -EINVAL); 504 505 /* Resize the blob */ 506 rc = spdk_bs_md_resize_blob(blob, 5); 507 CU_ASSERT(rc == 0); 508 509 /* Confirm that read passes if blob is marked read-only. */ 510 blob->data_ro = true; 511 spdk_bs_io_read_blob(blob, channel, payload, 0, 1, blob_op_complete, NULL); 512 CU_ASSERT(g_bserrno == 0); 513 blob->data_ro = false; 514 515 /* Read from the blob */ 516 spdk_bs_io_read_blob(blob, channel, payload, 0, 1, blob_op_complete, NULL); 517 CU_ASSERT(g_bserrno == 0); 518 519 /* Read starting beyond the end */ 520 spdk_bs_io_read_blob(blob, channel, payload, 5 * pages_per_cluster, 1, blob_op_complete, 521 NULL); 522 CU_ASSERT(g_bserrno == -EINVAL); 523 524 /* Read starting at a valid location but going off the end */ 525 spdk_bs_io_read_blob(blob, channel, payload, 4 * pages_per_cluster, pages_per_cluster + 1, 526 blob_op_complete, NULL); 527 CU_ASSERT(g_bserrno == -EINVAL); 528 529 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 530 CU_ASSERT(g_bserrno == 0); 531 532 spdk_bs_free_io_channel(channel); 533 534 spdk_bs_unload(g_bs, bs_op_complete, NULL); 535 CU_ASSERT(g_bserrno == 0); 536 g_bs = NULL; 537 } 538 539 static void 540 blob_rw_verify(void) 541 { 542 struct spdk_blob_store *bs; 543 struct spdk_bs_dev *dev; 544 struct spdk_blob *blob; 545 struct spdk_io_channel *channel; 546 spdk_blob_id blobid; 547 uint8_t payload_read[10 * 4096]; 548 uint8_t payload_write[10 * 4096]; 549 int rc; 550 551 dev = init_dev(); 552 553 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 554 CU_ASSERT(g_bserrno == 0); 555 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 556 bs = g_bs; 557 558 channel = spdk_bs_alloc_io_channel(bs); 559 CU_ASSERT(channel != NULL); 560 561 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 562 CU_ASSERT(g_bserrno == 0); 563 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 564 blobid = g_blobid; 565 566 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 567 CU_ASSERT(g_bserrno == 0); 568 CU_ASSERT(g_blob != NULL); 569 blob = g_blob; 570 571 rc = spdk_bs_md_resize_blob(blob, 32); 572 CU_ASSERT(rc == 0); 573 574 memset(payload_write, 0xE5, sizeof(payload_write)); 575 spdk_bs_io_write_blob(blob, channel, payload_write, 4, 10, blob_op_complete, NULL); 576 CU_ASSERT(g_bserrno == 0); 577 578 memset(payload_read, 0x00, sizeof(payload_read)); 579 spdk_bs_io_read_blob(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 580 CU_ASSERT(g_bserrno == 0); 581 CU_ASSERT(memcmp(payload_write, payload_read, 4 * 4096) == 0); 582 583 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 584 CU_ASSERT(g_bserrno == 0); 585 586 spdk_bs_free_io_channel(channel); 587 588 spdk_bs_unload(g_bs, bs_op_complete, NULL); 589 CU_ASSERT(g_bserrno == 0); 590 g_bs = NULL; 591 } 592 593 static void 594 blob_rw_verify_iov(void) 595 { 596 struct spdk_blob_store *bs; 597 struct spdk_bs_dev *dev; 598 struct spdk_blob *blob; 599 struct spdk_io_channel *channel; 600 spdk_blob_id blobid; 601 uint8_t payload_read[10 * 4096]; 602 uint8_t payload_write[10 * 4096]; 603 struct iovec iov_read[3]; 604 struct iovec iov_write[3]; 605 void *buf; 606 int rc; 607 608 dev = init_dev(); 609 memset(g_dev_buffer, 0, DEV_BUFFER_SIZE); 610 611 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 612 CU_ASSERT(g_bserrno == 0); 613 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 614 bs = g_bs; 615 616 channel = spdk_bs_alloc_io_channel(bs); 617 CU_ASSERT(channel != NULL); 618 619 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 620 CU_ASSERT(g_bserrno == 0); 621 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 622 blobid = g_blobid; 623 624 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 625 CU_ASSERT(g_bserrno == 0); 626 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 627 blob = g_blob; 628 629 rc = spdk_bs_md_resize_blob(blob, 2); 630 CU_ASSERT(rc == 0); 631 632 /* 633 * Manually adjust the offset of the blob's second cluster. This allows 634 * us to make sure that the readv/write code correctly accounts for I/O 635 * that cross cluster boundaries. Start by asserting that the allocated 636 * clusters are where we expect before modifying the second cluster. 637 */ 638 CU_ASSERT(blob->active.clusters[0] == 1 * 256); 639 CU_ASSERT(blob->active.clusters[1] == 2 * 256); 640 blob->active.clusters[1] = 3 * 256; 641 642 memset(payload_write, 0xE5, sizeof(payload_write)); 643 iov_write[0].iov_base = payload_write; 644 iov_write[0].iov_len = 1 * 4096; 645 iov_write[1].iov_base = payload_write + 1 * 4096; 646 iov_write[1].iov_len = 5 * 4096; 647 iov_write[2].iov_base = payload_write + 6 * 4096; 648 iov_write[2].iov_len = 4 * 4096; 649 /* 650 * Choose a page offset just before the cluster boundary. The first 6 pages of payload 651 * will get written to the first cluster, the last 4 to the second cluster. 652 */ 653 spdk_bs_io_writev_blob(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 654 CU_ASSERT(g_bserrno == 0); 655 656 memset(payload_read, 0xAA, sizeof(payload_read)); 657 iov_read[0].iov_base = payload_read; 658 iov_read[0].iov_len = 3 * 4096; 659 iov_read[1].iov_base = payload_read + 3 * 4096; 660 iov_read[1].iov_len = 4 * 4096; 661 iov_read[2].iov_base = payload_read + 7 * 4096; 662 iov_read[2].iov_len = 3 * 4096; 663 spdk_bs_io_readv_blob(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 664 CU_ASSERT(g_bserrno == 0); 665 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 666 667 buf = calloc(1, 256 * 4096); 668 SPDK_CU_ASSERT_FATAL(buf != NULL); 669 /* Check that cluster 2 on "disk" was not modified. */ 670 CU_ASSERT(memcmp(buf, &g_dev_buffer[512 * 4096], 256 * 4096) == 0); 671 free(buf); 672 673 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 674 CU_ASSERT(g_bserrno == 0); 675 676 spdk_bs_free_io_channel(channel); 677 678 spdk_bs_unload(g_bs, bs_op_complete, NULL); 679 CU_ASSERT(g_bserrno == 0); 680 g_bs = NULL; 681 } 682 683 static uint32_t 684 bs_channel_get_req_count(struct spdk_io_channel *_channel) 685 { 686 struct spdk_bs_channel *channel = spdk_io_channel_get_ctx(_channel); 687 struct spdk_bs_request_set *set; 688 uint32_t count = 0; 689 690 TAILQ_FOREACH(set, &channel->reqs, link) { 691 count++; 692 } 693 694 return count; 695 } 696 697 static void 698 blob_rw_verify_iov_nomem(void) 699 { 700 struct spdk_blob_store *bs; 701 struct spdk_bs_dev *dev; 702 struct spdk_blob *blob; 703 struct spdk_io_channel *channel; 704 spdk_blob_id blobid; 705 uint8_t payload_write[10 * 4096]; 706 struct iovec iov_write[3]; 707 uint32_t req_count; 708 int rc; 709 710 dev = init_dev(); 711 memset(g_dev_buffer, 0, DEV_BUFFER_SIZE); 712 713 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 714 CU_ASSERT(g_bserrno == 0); 715 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 716 bs = g_bs; 717 718 channel = spdk_bs_alloc_io_channel(bs); 719 CU_ASSERT(channel != NULL); 720 721 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 722 CU_ASSERT(g_bserrno == 0); 723 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 724 blobid = g_blobid; 725 726 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 727 CU_ASSERT(g_bserrno == 0); 728 CU_ASSERT(g_blob != NULL); 729 blob = g_blob; 730 731 rc = spdk_bs_md_resize_blob(blob, 2); 732 CU_ASSERT(rc == 0); 733 734 /* 735 * Choose a page offset just before the cluster boundary. The first 6 pages of payload 736 * will get written to the first cluster, the last 4 to the second cluster. 737 */ 738 iov_write[0].iov_base = payload_write; 739 iov_write[0].iov_len = 1 * 4096; 740 iov_write[1].iov_base = payload_write + 1 * 4096; 741 iov_write[1].iov_len = 5 * 4096; 742 iov_write[2].iov_base = payload_write + 6 * 4096; 743 iov_write[2].iov_len = 4 * 4096; 744 MOCK_SET(calloc, void *, NULL); 745 req_count = bs_channel_get_req_count(channel); 746 spdk_bs_io_writev_blob(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 747 CU_ASSERT(g_bserrno = -ENOMEM); 748 CU_ASSERT(req_count == bs_channel_get_req_count(channel)); 749 MOCK_SET(calloc, void *, (void *)MOCK_PASS_THRU); 750 751 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 752 CU_ASSERT(g_bserrno == 0); 753 754 spdk_bs_free_io_channel(channel); 755 756 spdk_bs_unload(g_bs, bs_op_complete, NULL); 757 CU_ASSERT(g_bserrno == 0); 758 g_bs = NULL; 759 } 760 761 static void 762 blob_rw_iov_read_only(void) 763 { 764 struct spdk_blob_store *bs; 765 struct spdk_bs_dev *dev; 766 struct spdk_blob *blob; 767 struct spdk_io_channel *channel; 768 spdk_blob_id blobid; 769 uint8_t payload_read[4096]; 770 uint8_t payload_write[4096]; 771 struct iovec iov_read; 772 struct iovec iov_write; 773 int rc; 774 775 dev = init_dev(); 776 memset(g_dev_buffer, 0, DEV_BUFFER_SIZE); 777 778 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 779 CU_ASSERT(g_bserrno == 0); 780 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 781 bs = g_bs; 782 783 channel = spdk_bs_alloc_io_channel(bs); 784 CU_ASSERT(channel != NULL); 785 786 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 787 CU_ASSERT(g_bserrno == 0); 788 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 789 blobid = g_blobid; 790 791 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 792 CU_ASSERT(g_bserrno == 0); 793 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 794 blob = g_blob; 795 796 rc = spdk_bs_md_resize_blob(blob, 2); 797 CU_ASSERT(rc == 0); 798 799 /* Verify that writev failed if read_only flag is set. */ 800 blob->data_ro = true; 801 iov_write.iov_base = payload_write; 802 iov_write.iov_len = sizeof(payload_write); 803 spdk_bs_io_writev_blob(blob, channel, &iov_write, 1, 0, 1, blob_op_complete, NULL); 804 CU_ASSERT(g_bserrno == -EPERM); 805 806 /* Verify that reads pass if data_ro flag is set. */ 807 iov_read.iov_base = payload_read; 808 iov_read.iov_len = sizeof(payload_read); 809 spdk_bs_io_readv_blob(blob, channel, &iov_read, 1, 0, 1, blob_op_complete, NULL); 810 CU_ASSERT(g_bserrno == 0); 811 812 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 813 CU_ASSERT(g_bserrno == 0); 814 815 spdk_bs_free_io_channel(channel); 816 817 spdk_bs_unload(g_bs, bs_op_complete, NULL); 818 CU_ASSERT(g_bserrno == 0); 819 g_bs = NULL; 820 } 821 822 static void 823 blob_iter(void) 824 { 825 struct spdk_blob_store *bs; 826 struct spdk_bs_dev *dev; 827 struct spdk_blob *blob; 828 spdk_blob_id blobid; 829 830 dev = init_dev(); 831 832 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 833 CU_ASSERT(g_bserrno == 0); 834 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 835 bs = g_bs; 836 837 spdk_bs_md_iter_first(bs, blob_op_with_handle_complete, NULL); 838 CU_ASSERT(g_blob == NULL); 839 CU_ASSERT(g_bserrno == -ENOENT); 840 841 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 842 CU_ASSERT(g_bserrno == 0); 843 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 844 blobid = g_blobid; 845 846 spdk_bs_md_iter_first(bs, blob_op_with_handle_complete, NULL); 847 CU_ASSERT(g_blob != NULL); 848 CU_ASSERT(g_bserrno == 0); 849 blob = g_blob; 850 CU_ASSERT(spdk_blob_get_id(blob) == blobid); 851 852 spdk_bs_md_iter_next(bs, &blob, blob_op_with_handle_complete, NULL); 853 CU_ASSERT(g_blob == NULL); 854 CU_ASSERT(g_bserrno == -ENOENT); 855 856 spdk_bs_unload(g_bs, bs_op_complete, NULL); 857 CU_ASSERT(g_bserrno == 0); 858 g_bs = NULL; 859 } 860 861 static void 862 blob_xattr(void) 863 { 864 struct spdk_blob_store *bs; 865 struct spdk_bs_dev *dev; 866 struct spdk_blob *blob; 867 spdk_blob_id blobid; 868 uint64_t length; 869 int rc; 870 const char *name1, *name2; 871 const void *value; 872 size_t value_len; 873 struct spdk_xattr_names *names; 874 875 dev = init_dev(); 876 877 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 878 CU_ASSERT(g_bserrno == 0); 879 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 880 bs = g_bs; 881 882 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 883 CU_ASSERT(g_bserrno == 0); 884 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 885 blobid = g_blobid; 886 887 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 888 CU_ASSERT(g_bserrno == 0); 889 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 890 blob = g_blob; 891 892 /* Test that set_xattr fails if md_ro flag is set. */ 893 blob->md_ro = true; 894 rc = spdk_blob_md_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 895 CU_ASSERT(rc == -EPERM); 896 897 blob->md_ro = false; 898 rc = spdk_blob_md_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 899 CU_ASSERT(rc == 0); 900 901 length = 2345; 902 rc = spdk_blob_md_set_xattr(blob, "length", &length, sizeof(length)); 903 CU_ASSERT(rc == 0); 904 905 /* Overwrite "length" xattr. */ 906 length = 3456; 907 rc = spdk_blob_md_set_xattr(blob, "length", &length, sizeof(length)); 908 CU_ASSERT(rc == 0); 909 910 /* get_xattr should still work even if md_ro flag is set. */ 911 value = NULL; 912 blob->md_ro = true; 913 rc = spdk_bs_md_get_xattr_value(blob, "length", &value, &value_len); 914 CU_ASSERT(rc == 0); 915 SPDK_CU_ASSERT_FATAL(value != NULL); 916 CU_ASSERT(*(uint64_t *)value == length); 917 CU_ASSERT(value_len == 8); 918 blob->md_ro = false; 919 920 rc = spdk_bs_md_get_xattr_value(blob, "foobar", &value, &value_len); 921 CU_ASSERT(rc == -ENOENT); 922 923 names = NULL; 924 rc = spdk_bs_md_get_xattr_names(blob, &names); 925 CU_ASSERT(rc == 0); 926 SPDK_CU_ASSERT_FATAL(names != NULL); 927 CU_ASSERT(spdk_xattr_names_get_count(names) == 2); 928 name1 = spdk_xattr_names_get_name(names, 0); 929 SPDK_CU_ASSERT_FATAL(name1 != NULL); 930 CU_ASSERT(!strcmp(name1, "name") || !strcmp(name1, "length")); 931 name2 = spdk_xattr_names_get_name(names, 1); 932 SPDK_CU_ASSERT_FATAL(name2 != NULL); 933 CU_ASSERT(!strcmp(name2, "name") || !strcmp(name2, "length")); 934 CU_ASSERT(strcmp(name1, name2)); 935 spdk_xattr_names_free(names); 936 937 /* Confirm that remove_xattr fails if md_ro is set to true. */ 938 blob->md_ro = true; 939 rc = spdk_blob_md_remove_xattr(blob, "name"); 940 CU_ASSERT(rc == -EPERM); 941 942 blob->md_ro = false; 943 rc = spdk_blob_md_remove_xattr(blob, "name"); 944 CU_ASSERT(rc == 0); 945 946 rc = spdk_blob_md_remove_xattr(blob, "foobar"); 947 CU_ASSERT(rc == -ENOENT); 948 949 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 950 951 spdk_bs_unload(g_bs, bs_op_complete, NULL); 952 CU_ASSERT(g_bserrno == 0); 953 g_bs = NULL; 954 } 955 956 static void 957 bs_load(void) 958 { 959 struct spdk_bs_dev *dev; 960 spdk_blob_id blobid; 961 struct spdk_blob *blob; 962 struct spdk_bs_super_block *super_block; 963 uint64_t length; 964 int rc; 965 const void *value; 966 size_t value_len; 967 struct spdk_bs_opts opts; 968 969 g_scheduler_delay = true; 970 971 dev = init_dev(); 972 spdk_bs_opts_init(&opts); 973 strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH); 974 975 /* Initialize a new blob store */ 976 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 977 CU_ASSERT(g_bserrno == 0); 978 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 979 980 /* Try to open a blobid that does not exist */ 981 spdk_bs_md_open_blob(g_bs, 0, blob_op_with_handle_complete, NULL); 982 CU_ASSERT(g_bserrno == -ENOENT); 983 CU_ASSERT(g_blob == NULL); 984 985 /* Create a blob */ 986 spdk_bs_md_create_blob(g_bs, blob_op_with_id_complete, NULL); 987 CU_ASSERT(g_bserrno == 0); 988 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 989 blobid = g_blobid; 990 991 spdk_bs_md_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 992 CU_ASSERT(g_bserrno == 0); 993 CU_ASSERT(g_blob != NULL); 994 blob = g_blob; 995 996 /* Try again to open valid blob but without the upper bit set */ 997 spdk_bs_md_open_blob(g_bs, blobid & 0xFFFFFFFF, blob_op_with_handle_complete, NULL); 998 CU_ASSERT(g_bserrno == -ENOENT); 999 CU_ASSERT(g_blob == NULL); 1000 1001 /* Set some xattrs */ 1002 rc = spdk_blob_md_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 1003 CU_ASSERT(rc == 0); 1004 1005 length = 2345; 1006 rc = spdk_blob_md_set_xattr(blob, "length", &length, sizeof(length)); 1007 CU_ASSERT(rc == 0); 1008 1009 /* Resize the blob */ 1010 rc = spdk_bs_md_resize_blob(blob, 10); 1011 CU_ASSERT(rc == 0); 1012 1013 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 1014 CU_ASSERT(g_bserrno == 0); 1015 blob = NULL; 1016 g_blob = NULL; 1017 g_blobid = SPDK_BLOBID_INVALID; 1018 1019 /* Unload the blob store */ 1020 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1021 CU_ASSERT(g_bserrno == 0); 1022 g_bs = NULL; 1023 g_blob = NULL; 1024 g_blobid = 0; 1025 1026 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 1027 CU_ASSERT(super_block->clean == 1); 1028 1029 1030 /* Load an existing blob store */ 1031 dev = init_dev(); 1032 strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH); 1033 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1034 CU_ASSERT(g_bserrno == 0); 1035 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1036 1037 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 1038 CU_ASSERT(super_block->clean == 0); 1039 1040 spdk_bs_md_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 1041 CU_ASSERT(g_bserrno == 0); 1042 CU_ASSERT(g_blob != NULL); 1043 blob = g_blob; 1044 1045 /* Get the xattrs */ 1046 value = NULL; 1047 rc = spdk_bs_md_get_xattr_value(blob, "length", &value, &value_len); 1048 CU_ASSERT(rc == 0); 1049 SPDK_CU_ASSERT_FATAL(value != NULL); 1050 CU_ASSERT(*(uint64_t *)value == length); 1051 CU_ASSERT(value_len == 8); 1052 1053 rc = spdk_bs_md_get_xattr_value(blob, "foobar", &value, &value_len); 1054 CU_ASSERT(rc == -ENOENT); 1055 1056 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 1057 1058 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 1059 CU_ASSERT(g_bserrno == 0); 1060 blob = NULL; 1061 g_blob = NULL; 1062 g_blobid = SPDK_BLOBID_INVALID; 1063 1064 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1065 CU_ASSERT(g_bserrno == 0); 1066 g_bs = NULL; 1067 g_scheduler_delay = false; 1068 } 1069 1070 static void 1071 bs_type(void) 1072 { 1073 struct spdk_bs_dev *dev; 1074 struct spdk_bs_opts opts; 1075 1076 g_scheduler_delay = true; 1077 1078 dev = init_dev(); 1079 spdk_bs_opts_init(&opts); 1080 strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH); 1081 1082 /* Initialize a new blob store */ 1083 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1084 CU_ASSERT(g_bserrno == 0); 1085 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1086 1087 /* Unload the blob store */ 1088 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1089 CU_ASSERT(g_bserrno == 0); 1090 g_bs = NULL; 1091 g_blob = NULL; 1092 g_blobid = 0; 1093 1094 /* Load non existing blobstore type */ 1095 dev = init_dev(); 1096 strncpy(opts.bstype.bstype, "NONEXISTING", SPDK_BLOBSTORE_TYPE_LENGTH); 1097 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1098 CU_ASSERT(g_bserrno != 0); 1099 1100 /* Load with empty blobstore type */ 1101 dev = init_dev(); 1102 strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH); 1103 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1104 CU_ASSERT(g_bserrno == 0); 1105 1106 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1107 CU_ASSERT(g_bserrno == 0); 1108 g_bs = NULL; 1109 1110 /* Initialize a new blob store with empty bstype */ 1111 dev = init_dev(); 1112 strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH); 1113 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1114 CU_ASSERT(g_bserrno == 0); 1115 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1116 1117 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1118 CU_ASSERT(g_bserrno == 0); 1119 g_bs = NULL; 1120 1121 /* Load non existing blobstore type */ 1122 dev = init_dev(); 1123 strncpy(opts.bstype.bstype, "NONEXISTING", SPDK_BLOBSTORE_TYPE_LENGTH); 1124 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1125 CU_ASSERT(g_bserrno != 0); 1126 1127 /* Load with empty blobstore type */ 1128 dev = init_dev(); 1129 strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH); 1130 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1131 CU_ASSERT(g_bserrno == 0); 1132 1133 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1134 CU_ASSERT(g_bserrno == 0); 1135 g_bs = NULL; 1136 g_scheduler_delay = false; 1137 } 1138 1139 static void 1140 bs_super_block(void) 1141 { 1142 struct spdk_bs_dev *dev; 1143 struct spdk_bs_super_block *super_block; 1144 struct spdk_bs_opts opts; 1145 struct spdk_bs_super_block_ver1 super_block_v1; 1146 1147 g_scheduler_delay = true; 1148 1149 dev = init_dev(); 1150 spdk_bs_opts_init(&opts); 1151 strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH); 1152 1153 /* Initialize a new blob store */ 1154 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1155 CU_ASSERT(g_bserrno == 0); 1156 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1157 1158 /* Unload the blob store */ 1159 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1160 CU_ASSERT(g_bserrno == 0); 1161 g_bs = NULL; 1162 g_blob = NULL; 1163 g_blobid = 0; 1164 1165 /* Load an existing blob store with version newer than supported */ 1166 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 1167 super_block->version++; 1168 1169 dev = init_dev(); 1170 strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH); 1171 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1172 CU_ASSERT(g_bserrno != 0); 1173 1174 /* Create a new blob store with super block version 1 */ 1175 dev = init_dev(); 1176 super_block_v1.version = 1; 1177 strncpy(super_block_v1.signature, "SPDKBLOB", sizeof(super_block_v1.signature)); 1178 super_block_v1.length = 0x1000; 1179 super_block_v1.clean = 1; 1180 super_block_v1.super_blob = 0xFFFFFFFFFFFFFFFF; 1181 super_block_v1.cluster_size = 0x100000; 1182 super_block_v1.used_page_mask_start = 0x01; 1183 super_block_v1.used_page_mask_len = 0x01; 1184 super_block_v1.used_cluster_mask_start = 0x02; 1185 super_block_v1.used_cluster_mask_len = 0x01; 1186 super_block_v1.md_start = 0x03; 1187 super_block_v1.md_len = 0x40; 1188 memset(super_block_v1.reserved, 0, 4036); 1189 super_block_v1.crc = _spdk_blob_md_page_calc_crc(&super_block_v1); 1190 memcpy(g_dev_buffer, &super_block_v1, sizeof(struct spdk_bs_super_block_ver1)); 1191 1192 strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH); 1193 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1194 CU_ASSERT(g_bserrno == 0); 1195 1196 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1197 CU_ASSERT(g_bserrno == 0); 1198 g_bs = NULL; 1199 g_scheduler_delay = false; 1200 } 1201 1202 /* 1203 * Create a blobstore and then unload it. 1204 */ 1205 static void 1206 bs_unload(void) 1207 { 1208 struct spdk_bs_dev *dev; 1209 struct spdk_blob_store *bs; 1210 spdk_blob_id blobid; 1211 struct spdk_blob *blob; 1212 1213 dev = init_dev(); 1214 1215 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1216 CU_ASSERT(g_bserrno == 0); 1217 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1218 bs = g_bs; 1219 1220 /* Create a blob and open it. */ 1221 g_bserrno = -1; 1222 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 1223 CU_ASSERT(g_bserrno == 0); 1224 CU_ASSERT(g_blobid > 0); 1225 blobid = g_blobid; 1226 1227 g_bserrno = -1; 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 /* Try to unload blobstore, should fail with open blob */ 1234 g_bserrno = -1; 1235 spdk_bs_unload(bs, bs_op_complete, NULL); 1236 CU_ASSERT(g_bserrno == -EBUSY); 1237 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1238 1239 /* Close the blob, then successfully unload blobstore */ 1240 g_bserrno = -1; 1241 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 1242 CU_ASSERT(g_bserrno == 0); 1243 CU_ASSERT(blob == NULL); 1244 1245 g_bserrno = -1; 1246 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1247 CU_ASSERT(g_bserrno == 0); 1248 g_bs = NULL; 1249 } 1250 1251 /* 1252 * Create a blobstore with a cluster size different than the default, and ensure it is 1253 * persisted. 1254 */ 1255 static void 1256 bs_cluster_sz(void) 1257 { 1258 struct spdk_bs_dev *dev; 1259 struct spdk_bs_opts opts; 1260 uint32_t cluster_sz; 1261 1262 /* Set cluster size to zero */ 1263 dev = init_dev(); 1264 spdk_bs_opts_init(&opts); 1265 opts.cluster_sz = 0; 1266 1267 /* Initialize a new blob store */ 1268 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1269 CU_ASSERT(g_bserrno == -EINVAL); 1270 SPDK_CU_ASSERT_FATAL(g_bs == NULL); 1271 1272 /* 1273 * Set cluster size to blobstore page size, 1274 * to work it is required to be at least twice the blobstore page size. 1275 */ 1276 dev = init_dev(); 1277 spdk_bs_opts_init(&opts); 1278 opts.cluster_sz = SPDK_BS_PAGE_SIZE; 1279 1280 /* Initialize a new blob store */ 1281 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1282 CU_ASSERT(g_bserrno == -ENOMEM); 1283 SPDK_CU_ASSERT_FATAL(g_bs == NULL); 1284 1285 /* 1286 * Set cluster size to lower than page size, 1287 * to work it is required to be at least twice the blobstore page size. 1288 */ 1289 dev = init_dev(); 1290 spdk_bs_opts_init(&opts); 1291 opts.cluster_sz = SPDK_BS_PAGE_SIZE - 1; 1292 1293 /* Initialize a new blob store */ 1294 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1295 CU_ASSERT(g_bserrno == -ENOMEM); 1296 SPDK_CU_ASSERT_FATAL(g_bs == NULL); 1297 1298 /* Set cluster size to twice the default */ 1299 dev = init_dev(); 1300 spdk_bs_opts_init(&opts); 1301 opts.cluster_sz *= 2; 1302 cluster_sz = opts.cluster_sz; 1303 1304 /* Initialize a new blob store */ 1305 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1306 CU_ASSERT(g_bserrno == 0); 1307 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1308 1309 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 1310 1311 /* Unload the blob store */ 1312 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1313 CU_ASSERT(g_bserrno == 0); 1314 g_bs = NULL; 1315 g_blob = NULL; 1316 g_blobid = 0; 1317 1318 dev = init_dev(); 1319 /* Load an existing blob store */ 1320 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1321 CU_ASSERT(g_bserrno == 0); 1322 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1323 1324 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 1325 1326 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1327 CU_ASSERT(g_bserrno == 0); 1328 g_bs = NULL; 1329 } 1330 1331 /* 1332 * Create a blobstore, reload it and ensure total usable cluster count 1333 * stays the same. 1334 */ 1335 static void 1336 bs_usable_clusters(void) 1337 { 1338 struct spdk_bs_dev *dev; 1339 struct spdk_bs_opts opts; 1340 uint32_t clusters; 1341 int i, rc; 1342 1343 /* Init blobstore */ 1344 dev = init_dev(); 1345 spdk_bs_opts_init(&opts); 1346 1347 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1348 CU_ASSERT(g_bserrno == 0); 1349 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1350 1351 clusters = spdk_bs_total_data_cluster_count(g_bs); 1352 1353 /* Unload the blob store */ 1354 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1355 CU_ASSERT(g_bserrno == 0); 1356 g_bs = NULL; 1357 1358 dev = init_dev(); 1359 /* Load an existing blob store */ 1360 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1361 CU_ASSERT(g_bserrno == 0); 1362 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1363 1364 CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters); 1365 1366 /* Create and resize blobs to make sure that useable cluster count won't change */ 1367 for (i = 0; i < 4; i++) { 1368 g_bserrno = -1; 1369 g_blobid = SPDK_BLOBID_INVALID; 1370 spdk_bs_md_create_blob(g_bs, blob_op_with_id_complete, NULL); 1371 CU_ASSERT(g_bserrno == 0); 1372 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1373 1374 g_bserrno = -1; 1375 g_blob = NULL; 1376 spdk_bs_md_open_blob(g_bs, g_blobid, blob_op_with_handle_complete, NULL); 1377 CU_ASSERT(g_bserrno == 0); 1378 CU_ASSERT(g_blob != NULL); 1379 1380 rc = spdk_bs_md_resize_blob(g_blob, 10); 1381 CU_ASSERT(rc == 0); 1382 1383 g_bserrno = -1; 1384 spdk_bs_md_close_blob(&g_blob, blob_op_complete, NULL); 1385 CU_ASSERT(g_bserrno == 0); 1386 1387 CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters); 1388 } 1389 1390 /* Reload the blob store to make sure that nothing changed */ 1391 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1392 CU_ASSERT(g_bserrno == 0); 1393 g_bs = NULL; 1394 1395 dev = init_dev(); 1396 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1397 CU_ASSERT(g_bserrno == 0); 1398 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1399 1400 CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters); 1401 1402 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1403 CU_ASSERT(g_bserrno == 0); 1404 g_bs = NULL; 1405 } 1406 1407 /* 1408 * Test resizing of the metadata blob. This requires creating enough blobs 1409 * so that one cluster is not enough to fit the metadata for those blobs. 1410 * To induce this condition to happen more quickly, we reduce the cluster 1411 * size to 16KB, which means only 4 4KB blob metadata pages can fit. 1412 */ 1413 static void 1414 bs_resize_md(void) 1415 { 1416 const int CLUSTER_PAGE_COUNT = 4; 1417 const int NUM_BLOBS = CLUSTER_PAGE_COUNT * 4; 1418 struct spdk_bs_dev *dev; 1419 struct spdk_bs_opts opts; 1420 uint32_t cluster_sz; 1421 spdk_blob_id blobids[NUM_BLOBS]; 1422 int i; 1423 1424 1425 dev = init_dev(); 1426 spdk_bs_opts_init(&opts); 1427 opts.cluster_sz = CLUSTER_PAGE_COUNT * 4096; 1428 cluster_sz = opts.cluster_sz; 1429 1430 /* Initialize a new blob store */ 1431 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1432 CU_ASSERT(g_bserrno == 0); 1433 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1434 1435 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 1436 1437 for (i = 0; i < NUM_BLOBS; i++) { 1438 g_bserrno = -1; 1439 g_blobid = SPDK_BLOBID_INVALID; 1440 spdk_bs_md_create_blob(g_bs, 1441 blob_op_with_id_complete, NULL); 1442 CU_ASSERT(g_bserrno == 0); 1443 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1444 blobids[i] = g_blobid; 1445 } 1446 1447 /* Unload the blob store */ 1448 g_bserrno = -1; 1449 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1450 CU_ASSERT(g_bserrno == 0); 1451 1452 /* Load an existing blob store */ 1453 g_bserrno = -1; 1454 g_bs = NULL; 1455 dev = init_dev(); 1456 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1457 CU_ASSERT(g_bserrno == 0); 1458 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1459 1460 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 1461 1462 for (i = 0; i < NUM_BLOBS; i++) { 1463 g_bserrno = -1; 1464 g_blob = NULL; 1465 spdk_bs_md_open_blob(g_bs, blobids[i], blob_op_with_handle_complete, NULL); 1466 CU_ASSERT(g_bserrno == 0); 1467 CU_ASSERT(g_blob != NULL); 1468 g_bserrno = -1; 1469 spdk_bs_md_close_blob(&g_blob, blob_op_complete, NULL); 1470 CU_ASSERT(g_bserrno == 0); 1471 } 1472 1473 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1474 CU_ASSERT(g_bserrno == 0); 1475 g_bs = NULL; 1476 } 1477 1478 static void 1479 bs_destroy(void) 1480 { 1481 struct spdk_bs_dev *dev; 1482 struct spdk_bs_opts opts; 1483 1484 g_scheduler_delay = true; 1485 1486 _bs_flush_scheduler(); 1487 CU_ASSERT(TAILQ_EMPTY(&g_scheduled_ops)); 1488 1489 /* Initialize a new blob store */ 1490 dev = init_dev(); 1491 spdk_bs_opts_init(&opts); 1492 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1493 CU_ASSERT(g_bserrno == 0); 1494 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1495 1496 /* Destroy the blob store */ 1497 g_bserrno = -1; 1498 spdk_bs_destroy(g_bs, bs_op_complete, NULL); 1499 /* Callback is called after device is destroyed in next scheduler run. */ 1500 _bs_flush_scheduler(); 1501 CU_ASSERT(TAILQ_EMPTY(&g_scheduled_ops)); 1502 CU_ASSERT(g_bserrno == 0); 1503 1504 /* Loading an non-existent blob store should fail. */ 1505 g_bserrno = -1; 1506 g_bs = NULL; 1507 dev = init_dev(); 1508 1509 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1510 CU_ASSERT(g_bserrno != 0); 1511 g_scheduler_delay = false; 1512 } 1513 1514 /* Try to hit all of the corner cases associated with serializing 1515 * a blob to disk 1516 */ 1517 static void 1518 blob_serialize(void) 1519 { 1520 struct spdk_bs_dev *dev; 1521 struct spdk_bs_opts opts; 1522 struct spdk_blob_store *bs; 1523 spdk_blob_id blobid[2]; 1524 struct spdk_blob *blob[2]; 1525 uint64_t i; 1526 char *value; 1527 int rc; 1528 1529 dev = init_dev(); 1530 1531 /* Initialize a new blobstore with very small clusters */ 1532 spdk_bs_opts_init(&opts); 1533 opts.cluster_sz = dev->blocklen * 8; 1534 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1535 CU_ASSERT(g_bserrno == 0); 1536 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1537 bs = g_bs; 1538 1539 /* Create and open two blobs */ 1540 for (i = 0; i < 2; i++) { 1541 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 1542 CU_ASSERT(g_bserrno == 0); 1543 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1544 blobid[i] = g_blobid; 1545 1546 /* Open a blob */ 1547 spdk_bs_md_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL); 1548 CU_ASSERT(g_bserrno == 0); 1549 CU_ASSERT(g_blob != NULL); 1550 blob[i] = g_blob; 1551 1552 /* Set a fairly large xattr on both blobs to eat up 1553 * metadata space 1554 */ 1555 value = calloc(dev->blocklen - 64, sizeof(char)); 1556 SPDK_CU_ASSERT_FATAL(value != NULL); 1557 memset(value, i, dev->blocklen / 2); 1558 rc = spdk_blob_md_set_xattr(blob[i], "name", value, dev->blocklen - 64); 1559 CU_ASSERT(rc == 0); 1560 free(value); 1561 } 1562 1563 /* Resize the blobs, alternating 1 cluster at a time. 1564 * This thwarts run length encoding and will cause spill 1565 * over of the extents. 1566 */ 1567 for (i = 0; i < 6; i++) { 1568 rc = spdk_bs_md_resize_blob(blob[i % 2], (i / 2) + 1); 1569 CU_ASSERT(rc == 0); 1570 } 1571 1572 for (i = 0; i < 2; i++) { 1573 spdk_bs_md_sync_blob(blob[i], blob_op_complete, NULL); 1574 CU_ASSERT(g_bserrno == 0); 1575 } 1576 1577 /* Close the blobs */ 1578 for (i = 0; i < 2; i++) { 1579 spdk_bs_md_close_blob(&blob[i], blob_op_complete, NULL); 1580 CU_ASSERT(g_bserrno == 0); 1581 } 1582 1583 /* Unload the blobstore */ 1584 spdk_bs_unload(bs, bs_op_complete, NULL); 1585 CU_ASSERT(g_bserrno == 0); 1586 g_bs = NULL; 1587 g_blob = NULL; 1588 g_blobid = 0; 1589 bs = NULL; 1590 1591 dev = init_dev(); 1592 /* Load an existing blob store */ 1593 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1594 CU_ASSERT(g_bserrno == 0); 1595 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1596 bs = g_bs; 1597 1598 for (i = 0; i < 2; i++) { 1599 blob[i] = NULL; 1600 1601 spdk_bs_md_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL); 1602 CU_ASSERT(g_bserrno == 0); 1603 CU_ASSERT(g_blob != NULL); 1604 blob[i] = g_blob; 1605 1606 CU_ASSERT(spdk_blob_get_num_clusters(blob[i]) == 3); 1607 1608 spdk_bs_md_close_blob(&blob[i], blob_op_complete, NULL); 1609 CU_ASSERT(g_bserrno == 0); 1610 } 1611 1612 spdk_bs_unload(bs, bs_op_complete, NULL); 1613 CU_ASSERT(g_bserrno == 0); 1614 g_bs = NULL; 1615 } 1616 1617 static void 1618 blob_crc(void) 1619 { 1620 struct spdk_blob_store *bs; 1621 struct spdk_bs_dev *dev; 1622 struct spdk_blob *blob; 1623 spdk_blob_id blobid; 1624 uint32_t page_num; 1625 int index; 1626 struct spdk_blob_md_page *page; 1627 1628 dev = init_dev(); 1629 1630 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1631 CU_ASSERT(g_bserrno == 0); 1632 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1633 bs = g_bs; 1634 1635 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 1636 CU_ASSERT(g_bserrno == 0); 1637 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1638 blobid = g_blobid; 1639 1640 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1641 CU_ASSERT(g_bserrno == 0); 1642 CU_ASSERT(g_blob != NULL); 1643 blob = g_blob; 1644 1645 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 1646 CU_ASSERT(g_bserrno == 0); 1647 CU_ASSERT(blob == NULL); 1648 1649 page_num = _spdk_bs_blobid_to_page(blobid); 1650 index = DEV_BUFFER_BLOCKLEN * (bs->md_start + page_num); 1651 page = (struct spdk_blob_md_page *)&g_dev_buffer[index]; 1652 page->crc = 0; 1653 1654 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1655 CU_ASSERT(g_bserrno == -EINVAL); 1656 CU_ASSERT(g_blob == NULL); 1657 g_bserrno = 0; 1658 1659 spdk_bs_md_delete_blob(bs, blobid, blob_op_complete, NULL); 1660 CU_ASSERT(g_bserrno == -EINVAL); 1661 1662 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1663 CU_ASSERT(g_bserrno == 0); 1664 g_bs = NULL; 1665 } 1666 1667 static void 1668 super_block_crc(void) 1669 { 1670 struct spdk_bs_dev *dev; 1671 struct spdk_bs_super_block *super_block; 1672 struct spdk_bs_opts opts; 1673 1674 dev = init_dev(); 1675 spdk_bs_opts_init(&opts); 1676 1677 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1678 CU_ASSERT(g_bserrno == 0); 1679 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1680 1681 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1682 CU_ASSERT(g_bserrno == 0); 1683 g_bs = NULL; 1684 1685 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 1686 super_block->crc = 0; 1687 dev = init_dev(); 1688 1689 g_scheduler_delay = true; 1690 /* Load an existing blob store */ 1691 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1692 1693 CU_ASSERT(g_bserrno == -EILSEQ); 1694 _bs_flush_scheduler(); 1695 CU_ASSERT(TAILQ_EMPTY(&g_scheduled_ops)); 1696 1697 g_scheduler_delay = false; 1698 } 1699 1700 /* For blob dirty shutdown test case we do the following sub-test cases: 1701 * 1 Initialize new blob store and create 1 blob with some xattrs, then we 1702 * dirty shutdown and reload the blob store and verify the xattrs. 1703 * 2 Resize the blob from 10 clusters to 20 clusters and then dirty shutdown, 1704 * reload the blob store and verify the clusters number. 1705 * 3 Create the second blob and then dirty shutdown, reload the blob store 1706 * and verify the second blob. 1707 * 4 Delete the second blob and then dirty shutdown, reload teh blob store 1708 * and verify the second blob is invalid. 1709 * 5 Create the second blob again and also create the third blob, modify the 1710 * md of second blob which makes the md invalid, and then dirty shutdown, 1711 * reload the blob store verify the second blob, it should invalid and also 1712 * verify the third blob, it should correct. 1713 */ 1714 static void 1715 blob_dirty_shutdown(void) 1716 { 1717 int rc; 1718 int index; 1719 struct spdk_bs_dev *dev; 1720 spdk_blob_id blobid1, blobid2, blobid3; 1721 struct spdk_blob *blob; 1722 uint64_t length; 1723 const void *value; 1724 size_t value_len; 1725 uint32_t page_num; 1726 struct spdk_blob_md_page *page; 1727 struct spdk_bs_opts opts; 1728 1729 dev = init_dev(); 1730 spdk_bs_opts_init(&opts); 1731 /* Initialize a new blob store */ 1732 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1733 CU_ASSERT(g_bserrno == 0); 1734 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1735 1736 /* Create first blob */ 1737 spdk_bs_md_create_blob(g_bs, blob_op_with_id_complete, NULL); 1738 CU_ASSERT(g_bserrno == 0); 1739 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1740 blobid1 = g_blobid; 1741 1742 spdk_bs_md_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 1743 CU_ASSERT(g_bserrno == 0); 1744 CU_ASSERT(g_blob != NULL); 1745 blob = g_blob; 1746 1747 /* Set some xattrs */ 1748 rc = spdk_blob_md_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 1749 CU_ASSERT(rc == 0); 1750 1751 length = 2345; 1752 rc = spdk_blob_md_set_xattr(blob, "length", &length, sizeof(length)); 1753 CU_ASSERT(rc == 0); 1754 1755 /* Resize the blob */ 1756 rc = spdk_bs_md_resize_blob(blob, 10); 1757 CU_ASSERT(rc == 0); 1758 1759 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 1760 blob = NULL; 1761 g_blob = NULL; 1762 g_blobid = SPDK_BLOBID_INVALID; 1763 1764 /* Dirty shutdown */ 1765 _spdk_bs_free(g_bs); 1766 1767 /* reload blobstore */ 1768 dev = init_dev(); 1769 spdk_bs_opts_init(&opts); 1770 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1771 CU_ASSERT(g_bserrno == 0); 1772 1773 spdk_bs_md_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 1774 CU_ASSERT(g_bserrno == 0); 1775 CU_ASSERT(g_blob != NULL); 1776 blob = g_blob; 1777 1778 /* Get the xattrs */ 1779 value = NULL; 1780 rc = spdk_bs_md_get_xattr_value(blob, "length", &value, &value_len); 1781 CU_ASSERT(rc == 0); 1782 SPDK_CU_ASSERT_FATAL(value != NULL); 1783 CU_ASSERT(*(uint64_t *)value == length); 1784 CU_ASSERT(value_len == 8); 1785 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 1786 1787 /* Resize the blob */ 1788 rc = spdk_bs_md_resize_blob(blob, 20); 1789 CU_ASSERT(rc == 0); 1790 1791 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 1792 CU_ASSERT(g_bserrno == 0); 1793 blob = NULL; 1794 g_blob = NULL; 1795 g_blobid = SPDK_BLOBID_INVALID; 1796 1797 /* Dirty shutdown */ 1798 _spdk_bs_free(g_bs); 1799 1800 /* reload the blobstore */ 1801 dev = init_dev(); 1802 spdk_bs_opts_init(&opts); 1803 /* Load an existing blob store */ 1804 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1805 CU_ASSERT(g_bserrno == 0); 1806 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1807 spdk_bs_md_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 1808 CU_ASSERT(g_bserrno == 0); 1809 CU_ASSERT(g_blob != NULL); 1810 blob = g_blob; 1811 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 20); 1812 1813 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 1814 CU_ASSERT(g_bserrno == 0); 1815 blob = NULL; 1816 g_blob = NULL; 1817 g_blobid = SPDK_BLOBID_INVALID; 1818 1819 /* Create second blob */ 1820 spdk_bs_md_create_blob(g_bs, blob_op_with_id_complete, NULL); 1821 CU_ASSERT(g_bserrno == 0); 1822 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1823 blobid2 = g_blobid; 1824 1825 spdk_bs_md_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 1826 CU_ASSERT(g_bserrno == 0); 1827 CU_ASSERT(g_blob != NULL); 1828 blob = g_blob; 1829 1830 /* Set some xattrs */ 1831 rc = spdk_blob_md_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1); 1832 CU_ASSERT(rc == 0); 1833 1834 length = 5432; 1835 rc = spdk_blob_md_set_xattr(blob, "length", &length, sizeof(length)); 1836 CU_ASSERT(rc == 0); 1837 1838 /* Resize the blob */ 1839 rc = spdk_bs_md_resize_blob(blob, 10); 1840 CU_ASSERT(rc == 0); 1841 1842 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 1843 blob = NULL; 1844 g_blob = NULL; 1845 g_blobid = SPDK_BLOBID_INVALID; 1846 1847 /* Dirty shutdown */ 1848 _spdk_bs_free(g_bs); 1849 1850 /* reload the blobstore */ 1851 dev = init_dev(); 1852 spdk_bs_opts_init(&opts); 1853 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1854 CU_ASSERT(g_bserrno == 0); 1855 1856 spdk_bs_md_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 1857 CU_ASSERT(g_bserrno == 0); 1858 CU_ASSERT(g_blob != NULL); 1859 blob = g_blob; 1860 1861 /* Get the xattrs */ 1862 value = NULL; 1863 rc = spdk_bs_md_get_xattr_value(blob, "length", &value, &value_len); 1864 CU_ASSERT(rc == 0); 1865 SPDK_CU_ASSERT_FATAL(value != NULL); 1866 CU_ASSERT(*(uint64_t *)value == length); 1867 CU_ASSERT(value_len == 8); 1868 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 1869 1870 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 1871 CU_ASSERT(g_bserrno == 0); 1872 spdk_bs_md_delete_blob(g_bs, blobid2, blob_op_complete, NULL); 1873 CU_ASSERT(g_bserrno == 0); 1874 1875 /* Dirty shutdown */ 1876 _spdk_bs_free(g_bs); 1877 /* reload the blobstore */ 1878 dev = init_dev(); 1879 spdk_bs_opts_init(&opts); 1880 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1881 CU_ASSERT(g_bserrno == 0); 1882 1883 spdk_bs_md_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 1884 CU_ASSERT(g_bserrno != 0); 1885 CU_ASSERT(g_blob == NULL); 1886 1887 spdk_bs_md_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 1888 CU_ASSERT(g_bserrno == 0); 1889 CU_ASSERT(g_blob != NULL); 1890 spdk_bs_md_close_blob(&g_blob, blob_op_complete, NULL); 1891 CU_ASSERT(g_bserrno == 0); 1892 1893 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1894 CU_ASSERT(g_bserrno == 0); 1895 g_bs = NULL; 1896 1897 /* reload the blobstore */ 1898 dev = init_dev(); 1899 spdk_bs_opts_init(&opts); 1900 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1901 CU_ASSERT(g_bserrno == 0); 1902 1903 /* Create second blob */ 1904 spdk_bs_md_create_blob(g_bs, blob_op_with_id_complete, NULL); 1905 CU_ASSERT(g_bserrno == 0); 1906 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1907 blobid2 = g_blobid; 1908 1909 /* Create third blob */ 1910 spdk_bs_md_create_blob(g_bs, blob_op_with_id_complete, NULL); 1911 CU_ASSERT(g_bserrno == 0); 1912 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1913 blobid3 = g_blobid; 1914 1915 spdk_bs_md_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 1916 CU_ASSERT(g_bserrno == 0); 1917 CU_ASSERT(g_blob != NULL); 1918 blob = g_blob; 1919 1920 /* Set some xattrs for second blob */ 1921 rc = spdk_blob_md_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1); 1922 CU_ASSERT(rc == 0); 1923 1924 length = 5432; 1925 rc = spdk_blob_md_set_xattr(blob, "length", &length, sizeof(length)); 1926 CU_ASSERT(rc == 0); 1927 1928 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 1929 blob = NULL; 1930 g_blob = NULL; 1931 g_blobid = SPDK_BLOBID_INVALID; 1932 1933 spdk_bs_md_open_blob(g_bs, blobid3, blob_op_with_handle_complete, NULL); 1934 CU_ASSERT(g_bserrno == 0); 1935 CU_ASSERT(g_blob != NULL); 1936 blob = g_blob; 1937 1938 /* Set some xattrs for third blob */ 1939 rc = spdk_blob_md_set_xattr(blob, "name", "log2.txt", strlen("log2.txt") + 1); 1940 CU_ASSERT(rc == 0); 1941 1942 length = 5432; 1943 rc = spdk_blob_md_set_xattr(blob, "length", &length, sizeof(length)); 1944 CU_ASSERT(rc == 0); 1945 1946 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 1947 blob = NULL; 1948 g_blob = NULL; 1949 g_blobid = SPDK_BLOBID_INVALID; 1950 1951 /* Mark second blob as invalid */ 1952 page_num = _spdk_bs_blobid_to_page(blobid2); 1953 1954 index = DEV_BUFFER_BLOCKLEN * (g_bs->md_start + page_num); 1955 page = (struct spdk_blob_md_page *)&g_dev_buffer[index]; 1956 page->sequence_num = 1; 1957 page->crc = _spdk_blob_md_page_calc_crc(page); 1958 1959 /* Dirty shutdown */ 1960 _spdk_bs_free(g_bs); 1961 /* reload the blobstore */ 1962 dev = init_dev(); 1963 spdk_bs_opts_init(&opts); 1964 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1965 CU_ASSERT(g_bserrno == 0); 1966 1967 spdk_bs_md_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 1968 CU_ASSERT(g_bserrno != 0); 1969 CU_ASSERT(g_blob == NULL); 1970 1971 spdk_bs_md_open_blob(g_bs, blobid3, blob_op_with_handle_complete, NULL); 1972 CU_ASSERT(g_bserrno == 0); 1973 CU_ASSERT(g_blob != NULL); 1974 blob = g_blob; 1975 1976 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 1977 blob = NULL; 1978 g_blob = NULL; 1979 g_blobid = SPDK_BLOBID_INVALID; 1980 1981 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1982 CU_ASSERT(g_bserrno == 0); 1983 g_bs = NULL; 1984 } 1985 1986 static void 1987 blob_flags(void) 1988 { 1989 struct spdk_bs_dev *dev; 1990 spdk_blob_id blobid_invalid, blobid_data_ro, blobid_md_ro; 1991 struct spdk_blob *blob_invalid, *blob_data_ro, *blob_md_ro; 1992 struct spdk_bs_opts opts; 1993 1994 dev = init_dev(); 1995 spdk_bs_opts_init(&opts); 1996 1997 /* Initialize a new blob store */ 1998 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1999 CU_ASSERT(g_bserrno == 0); 2000 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2001 2002 /* Create three blobs - one each for testing invalid, data_ro and md_ro flags. */ 2003 spdk_bs_md_create_blob(g_bs, blob_op_with_id_complete, NULL); 2004 CU_ASSERT(g_bserrno == 0); 2005 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2006 blobid_invalid = g_blobid; 2007 2008 spdk_bs_md_create_blob(g_bs, blob_op_with_id_complete, NULL); 2009 CU_ASSERT(g_bserrno == 0); 2010 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2011 blobid_data_ro = g_blobid; 2012 2013 spdk_bs_md_create_blob(g_bs, blob_op_with_id_complete, NULL); 2014 CU_ASSERT(g_bserrno == 0); 2015 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2016 blobid_md_ro = g_blobid; 2017 2018 spdk_bs_md_open_blob(g_bs, blobid_invalid, blob_op_with_handle_complete, NULL); 2019 CU_ASSERT(g_bserrno == 0); 2020 CU_ASSERT(g_blob != NULL); 2021 blob_invalid = g_blob; 2022 2023 spdk_bs_md_open_blob(g_bs, blobid_data_ro, blob_op_with_handle_complete, NULL); 2024 CU_ASSERT(g_bserrno == 0); 2025 CU_ASSERT(g_blob != NULL); 2026 blob_data_ro = g_blob; 2027 2028 spdk_bs_md_open_blob(g_bs, blobid_md_ro, blob_op_with_handle_complete, NULL); 2029 CU_ASSERT(g_bserrno == 0); 2030 CU_ASSERT(g_blob != NULL); 2031 blob_md_ro = g_blob; 2032 2033 blob_invalid->invalid_flags = (1ULL << 63); 2034 blob_invalid->state = SPDK_BLOB_STATE_DIRTY; 2035 blob_data_ro->data_ro_flags = (1ULL << 62); 2036 blob_data_ro->state = SPDK_BLOB_STATE_DIRTY; 2037 blob_md_ro->md_ro_flags = (1ULL << 61); 2038 blob_md_ro->state = SPDK_BLOB_STATE_DIRTY; 2039 2040 g_bserrno = -1; 2041 spdk_bs_md_sync_blob(blob_invalid, blob_op_complete, NULL); 2042 CU_ASSERT(g_bserrno == 0); 2043 g_bserrno = -1; 2044 spdk_bs_md_sync_blob(blob_data_ro, blob_op_complete, NULL); 2045 CU_ASSERT(g_bserrno == 0); 2046 g_bserrno = -1; 2047 spdk_bs_md_sync_blob(blob_md_ro, blob_op_complete, NULL); 2048 CU_ASSERT(g_bserrno == 0); 2049 2050 g_bserrno = -1; 2051 spdk_bs_md_close_blob(&blob_invalid, blob_op_complete, NULL); 2052 CU_ASSERT(g_bserrno == 0); 2053 blob_invalid = NULL; 2054 g_bserrno = -1; 2055 spdk_bs_md_close_blob(&blob_data_ro, blob_op_complete, NULL); 2056 CU_ASSERT(g_bserrno == 0); 2057 blob_data_ro = NULL; 2058 g_bserrno = -1; 2059 spdk_bs_md_close_blob(&blob_md_ro, blob_op_complete, NULL); 2060 CU_ASSERT(g_bserrno == 0); 2061 blob_md_ro = NULL; 2062 2063 g_blob = NULL; 2064 g_blobid = SPDK_BLOBID_INVALID; 2065 2066 /* Unload the blob store */ 2067 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2068 CU_ASSERT(g_bserrno == 0); 2069 g_bs = NULL; 2070 2071 /* Load an existing blob store */ 2072 dev = init_dev(); 2073 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2074 CU_ASSERT(g_bserrno == 0); 2075 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2076 2077 g_blob = NULL; 2078 g_bserrno = 0; 2079 spdk_bs_md_open_blob(g_bs, blobid_invalid, blob_op_with_handle_complete, NULL); 2080 CU_ASSERT(g_bserrno != 0); 2081 CU_ASSERT(g_blob == NULL); 2082 2083 g_blob = NULL; 2084 g_bserrno = -1; 2085 spdk_bs_md_open_blob(g_bs, blobid_data_ro, blob_op_with_handle_complete, NULL); 2086 CU_ASSERT(g_bserrno == 0); 2087 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2088 blob_data_ro = g_blob; 2089 /* If an unknown data_ro flag was found, the blob should be marked both data and md read-only. */ 2090 CU_ASSERT(blob_data_ro->data_ro == true); 2091 CU_ASSERT(blob_data_ro->md_ro == true); 2092 2093 g_blob = NULL; 2094 g_bserrno = -1; 2095 spdk_bs_md_open_blob(g_bs, blobid_md_ro, blob_op_with_handle_complete, NULL); 2096 CU_ASSERT(g_bserrno == 0); 2097 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2098 blob_md_ro = g_blob; 2099 CU_ASSERT(blob_md_ro->data_ro == false); 2100 CU_ASSERT(blob_md_ro->md_ro == true); 2101 2102 spdk_bs_md_close_blob(&blob_data_ro, blob_op_complete, NULL); 2103 CU_ASSERT(g_bserrno == 0); 2104 spdk_bs_md_close_blob(&blob_md_ro, blob_op_complete, NULL); 2105 CU_ASSERT(g_bserrno == 0); 2106 2107 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2108 CU_ASSERT(g_bserrno == 0); 2109 } 2110 2111 int main(int argc, char **argv) 2112 { 2113 CU_pSuite suite = NULL; 2114 unsigned int num_failures; 2115 2116 if (CU_initialize_registry() != CUE_SUCCESS) { 2117 return CU_get_error(); 2118 } 2119 2120 suite = CU_add_suite("blob", NULL, NULL); 2121 if (suite == NULL) { 2122 CU_cleanup_registry(); 2123 return CU_get_error(); 2124 } 2125 2126 if ( 2127 CU_add_test(suite, "blob_init", blob_init) == NULL || 2128 CU_add_test(suite, "blob_open", blob_open) == NULL || 2129 CU_add_test(suite, "blob_delete", blob_delete) == NULL || 2130 CU_add_test(suite, "blob_resize", blob_resize) == NULL || 2131 CU_add_test(suite, "channel_ops", channel_ops) == NULL || 2132 CU_add_test(suite, "blob_super", blob_super) == NULL || 2133 CU_add_test(suite, "blob_write", blob_write) == NULL || 2134 CU_add_test(suite, "blob_read", blob_read) == NULL || 2135 CU_add_test(suite, "blob_rw_verify", blob_rw_verify) == NULL || 2136 CU_add_test(suite, "blob_rw_verify_iov", blob_rw_verify_iov) == NULL || 2137 CU_add_test(suite, "blob_rw_verify_iov_nomem", blob_rw_verify_iov_nomem) == NULL || 2138 CU_add_test(suite, "blob_rw_iov_read_only", blob_rw_iov_read_only) == NULL || 2139 CU_add_test(suite, "blob_iter", blob_iter) == NULL || 2140 CU_add_test(suite, "blob_xattr", blob_xattr) == NULL || 2141 CU_add_test(suite, "bs_load", bs_load) == NULL || 2142 CU_add_test(suite, "bs_unload", bs_unload) == NULL || 2143 CU_add_test(suite, "bs_cluster_sz", bs_cluster_sz) == NULL || 2144 CU_add_test(suite, "bs_usable_clusters", bs_usable_clusters) == NULL || 2145 CU_add_test(suite, "bs_resize_md", bs_resize_md) == NULL || 2146 CU_add_test(suite, "bs_destroy", bs_destroy) == NULL || 2147 CU_add_test(suite, "bs_type", bs_type) == NULL || 2148 CU_add_test(suite, "bs_super_block", bs_super_block) == NULL || 2149 CU_add_test(suite, "blob_serialize", blob_serialize) == NULL || 2150 CU_add_test(suite, "blob_crc", blob_crc) == NULL || 2151 CU_add_test(suite, "super_block_crc", super_block_crc) == NULL || 2152 CU_add_test(suite, "blob_dirty_shutdown", blob_dirty_shutdown) == NULL || 2153 CU_add_test(suite, "blob_flags", blob_flags) == NULL 2154 ) { 2155 CU_cleanup_registry(); 2156 return CU_get_error(); 2157 } 2158 2159 g_dev_buffer = calloc(1, DEV_BUFFER_SIZE); 2160 spdk_allocate_thread(_bs_send_msg, NULL, NULL, NULL, "thread0"); 2161 CU_basic_set_mode(CU_BRM_VERBOSE); 2162 CU_basic_run_tests(); 2163 num_failures = CU_get_number_of_failures(); 2164 CU_cleanup_registry(); 2165 spdk_free_thread(); 2166 free(g_dev_buffer); 2167 return num_failures; 2168 } 2169