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