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 #include "zeroes.c" 44 45 struct spdk_blob_store *g_bs; 46 spdk_blob_id g_blobid; 47 struct spdk_blob *g_blob; 48 int g_bserrno; 49 struct spdk_xattr_names *g_names; 50 int g_done; 51 char *g_xattr_names[] = {"first", "second", "third"}; 52 char *g_xattr_values[] = {"one", "two", "three"}; 53 uint64_t g_ctx = 1729; 54 55 bool g_scheduler_delay = false; 56 57 struct scheduled_ops { 58 spdk_thread_fn fn; 59 void *ctx; 60 61 TAILQ_ENTRY(scheduled_ops) ops_queue; 62 }; 63 64 static TAILQ_HEAD(, scheduled_ops) g_scheduled_ops = TAILQ_HEAD_INITIALIZER(g_scheduled_ops); 65 66 struct spdk_bs_super_block_ver1 { 67 uint8_t signature[8]; 68 uint32_t version; 69 uint32_t length; 70 uint32_t clean; /* If there was a clean shutdown, this is 1. */ 71 spdk_blob_id super_blob; 72 73 uint32_t cluster_size; /* In bytes */ 74 75 uint32_t used_page_mask_start; /* Offset from beginning of disk, in pages */ 76 uint32_t used_page_mask_len; /* Count, in pages */ 77 78 uint32_t used_cluster_mask_start; /* Offset from beginning of disk, in pages */ 79 uint32_t used_cluster_mask_len; /* Count, in pages */ 80 81 uint32_t md_start; /* Offset from beginning of disk, in pages */ 82 uint32_t md_len; /* Count, in pages */ 83 84 uint8_t reserved[4036]; 85 uint32_t crc; 86 } __attribute__((packed)); 87 SPDK_STATIC_ASSERT(sizeof(struct spdk_bs_super_block_ver1) == 0x1000, "Invalid super block size"); 88 89 static void 90 _bs_send_msg(spdk_thread_fn fn, void *ctx, void *thread_ctx) 91 { 92 if (g_scheduler_delay) { 93 struct scheduled_ops *ops = calloc(1, sizeof(*ops)); 94 95 SPDK_CU_ASSERT_FATAL(ops != NULL); 96 ops->fn = fn; 97 ops->ctx = ctx; 98 TAILQ_INSERT_TAIL(&g_scheduled_ops, ops, ops_queue); 99 } else { 100 fn(ctx); 101 } 102 } 103 104 static void 105 _bs_flush_scheduler(void) 106 { 107 struct scheduled_ops *ops, *tmp; 108 109 TAILQ_FOREACH_SAFE(ops, &g_scheduled_ops, ops_queue, tmp) { 110 ops->fn(ops->ctx); 111 TAILQ_REMOVE(&g_scheduled_ops, ops, ops_queue); 112 free(ops); 113 } 114 } 115 116 static void 117 bs_op_complete(void *cb_arg, int bserrno) 118 { 119 g_bserrno = bserrno; 120 } 121 122 static void 123 bs_op_with_handle_complete(void *cb_arg, struct spdk_blob_store *bs, 124 int bserrno) 125 { 126 g_bs = bs; 127 g_bserrno = bserrno; 128 } 129 130 static void 131 blob_op_complete(void *cb_arg, int bserrno) 132 { 133 g_bserrno = bserrno; 134 } 135 136 static void 137 blob_op_with_id_complete(void *cb_arg, spdk_blob_id blobid, int bserrno) 138 { 139 g_blobid = blobid; 140 g_bserrno = bserrno; 141 } 142 143 static void 144 blob_op_with_handle_complete(void *cb_arg, struct spdk_blob *blb, int bserrno) 145 { 146 g_blob = blb; 147 g_bserrno = bserrno; 148 } 149 150 static void 151 blob_init(void) 152 { 153 struct spdk_bs_dev *dev; 154 155 dev = init_dev(); 156 157 /* should fail for an unsupported blocklen */ 158 dev->blocklen = 500; 159 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 160 CU_ASSERT(g_bserrno == -EINVAL); 161 162 dev = init_dev(); 163 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 164 CU_ASSERT(g_bserrno == 0); 165 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 166 167 spdk_bs_unload(g_bs, bs_op_complete, NULL); 168 CU_ASSERT(g_bserrno == 0); 169 g_bs = NULL; 170 } 171 172 static void 173 blob_super(void) 174 { 175 struct spdk_blob_store *bs; 176 struct spdk_bs_dev *dev; 177 spdk_blob_id blobid; 178 179 dev = init_dev(); 180 181 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 182 CU_ASSERT(g_bserrno == 0); 183 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 184 bs = g_bs; 185 186 /* Get the super blob without having set one */ 187 spdk_bs_get_super(bs, blob_op_with_id_complete, NULL); 188 CU_ASSERT(g_bserrno == -ENOENT); 189 CU_ASSERT(g_blobid == SPDK_BLOBID_INVALID); 190 191 /* Create a blob */ 192 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 193 CU_ASSERT(g_bserrno == 0); 194 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 195 blobid = g_blobid; 196 197 /* Set the blob as the super blob */ 198 spdk_bs_set_super(bs, blobid, blob_op_complete, NULL); 199 CU_ASSERT(g_bserrno == 0); 200 201 /* Get the super blob */ 202 spdk_bs_get_super(bs, blob_op_with_id_complete, NULL); 203 CU_ASSERT(g_bserrno == 0); 204 CU_ASSERT(blobid == g_blobid); 205 206 spdk_bs_unload(g_bs, bs_op_complete, NULL); 207 CU_ASSERT(g_bserrno == 0); 208 g_bs = NULL; 209 } 210 211 static void 212 blob_open(void) 213 { 214 struct spdk_blob_store *bs; 215 struct spdk_bs_dev *dev; 216 struct spdk_blob *blob; 217 spdk_blob_id blobid, blobid2; 218 219 dev = init_dev(); 220 221 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 222 CU_ASSERT(g_bserrno == 0); 223 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 224 bs = g_bs; 225 226 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 227 CU_ASSERT(g_bserrno == 0); 228 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 229 blobid = g_blobid; 230 231 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 232 CU_ASSERT(g_bserrno == 0); 233 CU_ASSERT(g_blob != NULL); 234 blob = g_blob; 235 236 blobid2 = spdk_blob_get_id(blob); 237 CU_ASSERT(blobid == blobid2); 238 239 /* Try to open file again. It should return success. */ 240 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 241 CU_ASSERT(g_bserrno == 0); 242 CU_ASSERT(blob == g_blob); 243 244 spdk_blob_close(blob, blob_op_complete, NULL); 245 CU_ASSERT(g_bserrno == 0); 246 247 /* 248 * Close the file a second time, releasing the second reference. This 249 * should succeed. 250 */ 251 blob = g_blob; 252 spdk_blob_close(blob, blob_op_complete, NULL); 253 CU_ASSERT(g_bserrno == 0); 254 255 /* 256 * Try to open file again. It should succeed. This tests the case 257 * where the file is opened, closed, then re-opened again. 258 */ 259 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 260 CU_ASSERT(g_bserrno == 0); 261 CU_ASSERT(g_blob != NULL); 262 blob = g_blob; 263 264 spdk_blob_close(blob, blob_op_complete, NULL); 265 CU_ASSERT(g_bserrno == 0); 266 267 spdk_bs_unload(g_bs, bs_op_complete, NULL); 268 CU_ASSERT(g_bserrno == 0); 269 g_bs = NULL; 270 } 271 272 static void 273 blob_create(void) 274 { 275 struct spdk_blob_store *bs; 276 struct spdk_bs_dev *dev; 277 struct spdk_blob *blob; 278 struct spdk_blob_opts opts; 279 spdk_blob_id blobid; 280 281 dev = init_dev(); 282 283 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 284 CU_ASSERT(g_bserrno == 0); 285 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 286 bs = g_bs; 287 288 /* Create blob with 10 clusters */ 289 290 spdk_blob_opts_init(&opts); 291 opts.num_clusters = 10; 292 293 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 294 CU_ASSERT(g_bserrno == 0); 295 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 296 blobid = g_blobid; 297 298 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 299 CU_ASSERT(g_bserrno == 0); 300 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 301 blob = g_blob; 302 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10) 303 304 spdk_blob_close(blob, blob_op_complete, NULL); 305 CU_ASSERT(g_bserrno == 0); 306 307 /* Create blob with 0 clusters */ 308 309 spdk_blob_opts_init(&opts); 310 opts.num_clusters = 0; 311 312 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 313 CU_ASSERT(g_bserrno == 0); 314 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 315 blobid = g_blobid; 316 317 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 318 CU_ASSERT(g_bserrno == 0); 319 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 320 blob = g_blob; 321 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0) 322 323 spdk_blob_close(blob, blob_op_complete, NULL); 324 CU_ASSERT(g_bserrno == 0); 325 326 /* Create blob with default options (opts == NULL) */ 327 328 spdk_bs_create_blob_ext(bs, NULL, blob_op_with_id_complete, NULL); 329 CU_ASSERT(g_bserrno == 0); 330 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 331 blobid = g_blobid; 332 333 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 334 CU_ASSERT(g_bserrno == 0); 335 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 336 blob = g_blob; 337 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0) 338 339 spdk_blob_close(blob, blob_op_complete, NULL); 340 CU_ASSERT(g_bserrno == 0); 341 342 /* Try to create blob with size larger than blobstore */ 343 344 spdk_blob_opts_init(&opts); 345 opts.num_clusters = bs->total_clusters + 1; 346 347 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 348 CU_ASSERT(g_bserrno == -ENOSPC); 349 350 spdk_bs_unload(g_bs, bs_op_complete, NULL); 351 CU_ASSERT(g_bserrno == 0); 352 g_bs = NULL; 353 354 } 355 356 static void 357 blob_thin_provision(void) 358 { 359 struct spdk_blob_store *bs; 360 struct spdk_bs_dev *dev; 361 struct spdk_blob *blob; 362 struct spdk_blob_opts opts; 363 struct spdk_bs_opts bs_opts; 364 spdk_blob_id blobid; 365 366 dev = init_dev(); 367 spdk_bs_opts_init(&bs_opts); 368 strncpy(bs_opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH); 369 370 /* Initialize a new blob store */ 371 spdk_bs_init(dev, &bs_opts, bs_op_with_handle_complete, NULL); 372 CU_ASSERT(g_bserrno == 0); 373 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 374 375 bs = g_bs; 376 377 /* Create blob with thin provisioning enabled */ 378 379 spdk_blob_opts_init(&opts); 380 opts.thin_provision = true; 381 opts.num_clusters = 10; 382 383 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 384 CU_ASSERT(g_bserrno == 0); 385 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 386 blobid = g_blobid; 387 388 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 389 CU_ASSERT(g_bserrno == 0); 390 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 391 blob = g_blob; 392 CU_ASSERT(__blob_to_data(blob)->invalid_flags & SPDK_BLOB_THIN_PROV); 393 394 spdk_blob_close(blob, blob_op_complete, NULL); 395 CU_ASSERT(g_bserrno == 0); 396 397 spdk_bs_unload(g_bs, bs_op_complete, NULL); 398 CU_ASSERT(g_bserrno == 0); 399 g_bs = NULL; 400 401 /* Load an existing blob store and check if invalid_flags is set */ 402 dev = init_dev(); 403 strncpy(bs_opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH); 404 spdk_bs_load(dev, &bs_opts, bs_op_with_handle_complete, NULL); 405 CU_ASSERT(g_bserrno == 0); 406 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 407 408 bs = g_bs; 409 410 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 411 CU_ASSERT(g_bserrno == 0); 412 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 413 blob = g_blob; 414 CU_ASSERT(__blob_to_data(blob)->invalid_flags & SPDK_BLOB_THIN_PROV); 415 416 spdk_blob_close(blob, blob_op_complete, NULL); 417 CU_ASSERT(g_bserrno == 0); 418 419 spdk_bs_unload(g_bs, bs_op_complete, NULL); 420 CU_ASSERT(g_bserrno == 0); 421 g_bs = NULL; 422 } 423 424 static void 425 blob_delete(void) 426 { 427 struct spdk_blob_store *bs; 428 struct spdk_bs_dev *dev; 429 spdk_blob_id blobid; 430 431 dev = init_dev(); 432 433 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 434 CU_ASSERT(g_bserrno == 0); 435 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 436 bs = g_bs; 437 438 /* Create a blob and then delete it. */ 439 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 440 CU_ASSERT(g_bserrno == 0); 441 CU_ASSERT(g_blobid > 0); 442 blobid = g_blobid; 443 444 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 445 CU_ASSERT(g_bserrno == 0); 446 447 /* Try to open the blob */ 448 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 449 CU_ASSERT(g_bserrno == -ENOENT); 450 451 spdk_bs_unload(g_bs, bs_op_complete, NULL); 452 CU_ASSERT(g_bserrno == 0); 453 g_bs = NULL; 454 } 455 456 static void 457 blob_resize(void) 458 { 459 struct spdk_blob_store *bs; 460 struct spdk_bs_dev *dev; 461 struct spdk_blob *blob; 462 spdk_blob_id blobid; 463 uint64_t free_clusters; 464 int rc; 465 466 dev = init_dev(); 467 468 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 469 CU_ASSERT(g_bserrno == 0); 470 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 471 bs = g_bs; 472 free_clusters = spdk_bs_free_cluster_count(bs); 473 474 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 475 CU_ASSERT(g_bserrno == 0); 476 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 477 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 478 blobid = g_blobid; 479 480 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 481 CU_ASSERT(g_bserrno == 0); 482 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 483 blob = g_blob; 484 485 /* Confirm that resize fails if blob is marked read-only. */ 486 __blob_to_data(blob)->md_ro = true; 487 rc = spdk_blob_resize(blob, 5); 488 CU_ASSERT(rc == -EPERM); 489 __blob_to_data(blob)->md_ro = false; 490 491 /* The blob started at 0 clusters. Resize it to be 5. */ 492 rc = spdk_blob_resize(blob, 5); 493 CU_ASSERT(rc == 0); 494 CU_ASSERT((free_clusters - 5) == spdk_bs_free_cluster_count(bs)); 495 496 /* Shrink the blob to 3 clusters. This will not actually release 497 * the old clusters until the blob is synced. 498 */ 499 rc = spdk_blob_resize(blob, 3); 500 CU_ASSERT(rc == 0); 501 /* Verify there are still 5 clusters in use */ 502 CU_ASSERT((free_clusters - 5) == spdk_bs_free_cluster_count(bs)); 503 504 spdk_blob_sync_md(blob, blob_op_complete, NULL); 505 CU_ASSERT(g_bserrno == 0); 506 /* Now there are only 3 clusters in use */ 507 CU_ASSERT((free_clusters - 3) == spdk_bs_free_cluster_count(bs)); 508 509 /* Resize the blob to be 10 clusters. Growth takes effect immediately. */ 510 rc = spdk_blob_resize(blob, 10); 511 CU_ASSERT(rc == 0); 512 CU_ASSERT((free_clusters - 10) == spdk_bs_free_cluster_count(bs)); 513 514 /* Try to resize the blob to size larger than blobstore. */ 515 rc = spdk_blob_resize(blob, bs->total_clusters + 1); 516 CU_ASSERT(rc == -ENOSPC); 517 518 spdk_blob_close(blob, blob_op_complete, NULL); 519 CU_ASSERT(g_bserrno == 0); 520 521 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 522 CU_ASSERT(g_bserrno == 0); 523 524 spdk_bs_unload(g_bs, bs_op_complete, NULL); 525 CU_ASSERT(g_bserrno == 0); 526 g_bs = NULL; 527 } 528 529 static void 530 blob_read_only(void) 531 { 532 struct spdk_blob_store *bs; 533 struct spdk_bs_dev *dev; 534 struct spdk_blob *blob; 535 struct spdk_blob_data *blob_data; 536 struct spdk_bs_opts opts; 537 spdk_blob_id blobid; 538 539 dev = init_dev(); 540 spdk_bs_opts_init(&opts); 541 strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH); 542 543 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 544 CU_ASSERT(g_bserrno == 0); 545 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 546 bs = g_bs; 547 548 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 549 CU_ASSERT(g_bserrno == 0); 550 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 551 blobid = g_blobid; 552 553 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 554 CU_ASSERT(g_bserrno == 0); 555 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 556 blob = g_blob; 557 558 spdk_blob_set_read_only(blob); 559 560 blob_data = __blob_to_data(blob); 561 CU_ASSERT(blob_data->data_ro == false); 562 CU_ASSERT(blob_data->md_ro == false); 563 564 spdk_blob_sync_md(blob, bs_op_complete, NULL); 565 566 CU_ASSERT(blob_data->data_ro == true); 567 CU_ASSERT(blob_data->md_ro == true); 568 CU_ASSERT(blob_data->data_ro_flags & SPDK_BLOB_READ_ONLY); 569 570 spdk_blob_close(blob, blob_op_complete, NULL); 571 CU_ASSERT(g_bserrno == 0); 572 573 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 574 CU_ASSERT(g_bserrno == 0); 575 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 576 blob = g_blob; 577 578 blob_data = __blob_to_data(blob); 579 CU_ASSERT(blob_data->data_ro == true); 580 CU_ASSERT(blob_data->md_ro == true); 581 CU_ASSERT(blob_data->data_ro_flags & SPDK_BLOB_READ_ONLY); 582 583 spdk_blob_close(blob, blob_op_complete, NULL); 584 CU_ASSERT(g_bserrno == 0); 585 586 spdk_bs_unload(g_bs, bs_op_complete, NULL); 587 CU_ASSERT(g_bserrno == 0); 588 g_bs = NULL; 589 g_blob = NULL; 590 g_blobid = 0; 591 592 /* Load an existing blob store */ 593 dev = init_dev(); 594 strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH); 595 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 596 CU_ASSERT(g_bserrno == 0); 597 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 598 599 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 600 CU_ASSERT(g_bserrno == 0); 601 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 602 blob = g_blob; 603 604 blob_data = __blob_to_data(blob); 605 CU_ASSERT(blob_data->data_ro == true); 606 CU_ASSERT(blob_data->md_ro == true); 607 CU_ASSERT(blob_data->data_ro_flags & SPDK_BLOB_READ_ONLY); 608 609 spdk_blob_close(blob, blob_op_complete, NULL); 610 CU_ASSERT(g_bserrno == 0); 611 612 spdk_bs_unload(g_bs, bs_op_complete, NULL); 613 CU_ASSERT(g_bserrno == 0); 614 615 } 616 617 static void 618 channel_ops(void) 619 { 620 struct spdk_blob_store *bs; 621 struct spdk_bs_dev *dev; 622 struct spdk_io_channel *channel; 623 624 dev = init_dev(); 625 626 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 627 CU_ASSERT(g_bserrno == 0); 628 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 629 bs = g_bs; 630 631 channel = spdk_bs_alloc_io_channel(bs); 632 CU_ASSERT(channel != NULL); 633 634 spdk_bs_free_io_channel(channel); 635 636 spdk_bs_unload(g_bs, bs_op_complete, NULL); 637 CU_ASSERT(g_bserrno == 0); 638 g_bs = NULL; 639 } 640 641 static void 642 blob_write(void) 643 { 644 struct spdk_blob_store *bs; 645 struct spdk_bs_dev *dev; 646 struct spdk_blob *blob; 647 struct spdk_io_channel *channel; 648 spdk_blob_id blobid; 649 uint64_t pages_per_cluster; 650 uint8_t payload[10 * 4096]; 651 int rc; 652 653 dev = init_dev(); 654 655 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 656 CU_ASSERT(g_bserrno == 0); 657 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 658 bs = g_bs; 659 660 pages_per_cluster = spdk_bs_get_cluster_size(bs) / spdk_bs_get_page_size(bs); 661 662 channel = spdk_bs_alloc_io_channel(bs); 663 CU_ASSERT(channel != NULL); 664 665 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 666 CU_ASSERT(g_bserrno == 0); 667 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 668 blobid = g_blobid; 669 670 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 671 CU_ASSERT(g_bserrno == 0); 672 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 673 blob = g_blob; 674 675 /* Write to a blob with 0 size */ 676 spdk_bs_io_write_blob(blob, channel, payload, 0, 1, blob_op_complete, NULL); 677 CU_ASSERT(g_bserrno == -EINVAL); 678 679 /* Resize the blob */ 680 rc = spdk_blob_resize(blob, 5); 681 CU_ASSERT(rc == 0); 682 683 /* Confirm that write fails if blob is marked read-only. */ 684 __blob_to_data(blob)->data_ro = true; 685 spdk_bs_io_write_blob(blob, channel, payload, 0, 1, blob_op_complete, NULL); 686 CU_ASSERT(g_bserrno == -EPERM); 687 __blob_to_data(blob)->data_ro = false; 688 689 /* Write to the blob */ 690 spdk_bs_io_write_blob(blob, channel, payload, 0, 1, blob_op_complete, NULL); 691 CU_ASSERT(g_bserrno == 0); 692 693 /* Write starting beyond the end */ 694 spdk_bs_io_write_blob(blob, channel, payload, 5 * pages_per_cluster, 1, blob_op_complete, 695 NULL); 696 CU_ASSERT(g_bserrno == -EINVAL); 697 698 /* Write starting at a valid location but going off the end */ 699 spdk_bs_io_write_blob(blob, channel, payload, 4 * pages_per_cluster, pages_per_cluster + 1, 700 blob_op_complete, NULL); 701 CU_ASSERT(g_bserrno == -EINVAL); 702 703 spdk_blob_close(blob, blob_op_complete, NULL); 704 CU_ASSERT(g_bserrno == 0); 705 706 spdk_bs_free_io_channel(channel); 707 708 spdk_bs_unload(g_bs, bs_op_complete, NULL); 709 CU_ASSERT(g_bserrno == 0); 710 g_bs = NULL; 711 } 712 713 static void 714 blob_read(void) 715 { 716 struct spdk_blob_store *bs; 717 struct spdk_bs_dev *dev; 718 struct spdk_blob *blob; 719 struct spdk_io_channel *channel; 720 spdk_blob_id blobid; 721 uint64_t pages_per_cluster; 722 uint8_t payload[10 * 4096]; 723 int rc; 724 725 dev = init_dev(); 726 727 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 728 CU_ASSERT(g_bserrno == 0); 729 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 730 bs = g_bs; 731 732 pages_per_cluster = spdk_bs_get_cluster_size(bs) / spdk_bs_get_page_size(bs); 733 734 channel = spdk_bs_alloc_io_channel(bs); 735 CU_ASSERT(channel != NULL); 736 737 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 738 CU_ASSERT(g_bserrno == 0); 739 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 740 blobid = g_blobid; 741 742 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 743 CU_ASSERT(g_bserrno == 0); 744 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 745 blob = g_blob; 746 747 /* Read from a blob with 0 size */ 748 spdk_bs_io_read_blob(blob, channel, payload, 0, 1, blob_op_complete, NULL); 749 CU_ASSERT(g_bserrno == -EINVAL); 750 751 /* Resize the blob */ 752 rc = spdk_blob_resize(blob, 5); 753 CU_ASSERT(rc == 0); 754 755 /* Confirm that read passes if blob is marked read-only. */ 756 __blob_to_data(blob)->data_ro = true; 757 spdk_bs_io_read_blob(blob, channel, payload, 0, 1, blob_op_complete, NULL); 758 CU_ASSERT(g_bserrno == 0); 759 __blob_to_data(blob)->data_ro = false; 760 761 /* Read from the blob */ 762 spdk_bs_io_read_blob(blob, channel, payload, 0, 1, blob_op_complete, NULL); 763 CU_ASSERT(g_bserrno == 0); 764 765 /* Read starting beyond the end */ 766 spdk_bs_io_read_blob(blob, channel, payload, 5 * pages_per_cluster, 1, blob_op_complete, 767 NULL); 768 CU_ASSERT(g_bserrno == -EINVAL); 769 770 /* Read starting at a valid location but going off the end */ 771 spdk_bs_io_read_blob(blob, channel, payload, 4 * pages_per_cluster, pages_per_cluster + 1, 772 blob_op_complete, NULL); 773 CU_ASSERT(g_bserrno == -EINVAL); 774 775 spdk_blob_close(blob, blob_op_complete, NULL); 776 CU_ASSERT(g_bserrno == 0); 777 778 spdk_bs_free_io_channel(channel); 779 780 spdk_bs_unload(g_bs, bs_op_complete, NULL); 781 CU_ASSERT(g_bserrno == 0); 782 g_bs = NULL; 783 } 784 785 static void 786 blob_rw_verify(void) 787 { 788 struct spdk_blob_store *bs; 789 struct spdk_bs_dev *dev; 790 struct spdk_blob *blob; 791 struct spdk_io_channel *channel; 792 spdk_blob_id blobid; 793 uint8_t payload_read[10 * 4096]; 794 uint8_t payload_write[10 * 4096]; 795 int rc; 796 797 dev = init_dev(); 798 799 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 800 CU_ASSERT(g_bserrno == 0); 801 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 802 bs = g_bs; 803 804 channel = spdk_bs_alloc_io_channel(bs); 805 CU_ASSERT(channel != NULL); 806 807 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 808 CU_ASSERT(g_bserrno == 0); 809 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 810 blobid = g_blobid; 811 812 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 813 CU_ASSERT(g_bserrno == 0); 814 CU_ASSERT(g_blob != NULL); 815 blob = g_blob; 816 817 rc = spdk_blob_resize(blob, 32); 818 CU_ASSERT(rc == 0); 819 820 memset(payload_write, 0xE5, sizeof(payload_write)); 821 spdk_bs_io_write_blob(blob, channel, payload_write, 4, 10, blob_op_complete, NULL); 822 CU_ASSERT(g_bserrno == 0); 823 824 memset(payload_read, 0x00, sizeof(payload_read)); 825 spdk_bs_io_read_blob(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 826 CU_ASSERT(g_bserrno == 0); 827 CU_ASSERT(memcmp(payload_write, payload_read, 4 * 4096) == 0); 828 829 spdk_blob_close(blob, blob_op_complete, NULL); 830 CU_ASSERT(g_bserrno == 0); 831 832 spdk_bs_free_io_channel(channel); 833 834 spdk_bs_unload(g_bs, bs_op_complete, NULL); 835 CU_ASSERT(g_bserrno == 0); 836 g_bs = NULL; 837 } 838 839 static void 840 blob_rw_verify_iov(void) 841 { 842 struct spdk_blob_store *bs; 843 struct spdk_bs_dev *dev; 844 struct spdk_blob *blob; 845 struct spdk_io_channel *channel; 846 spdk_blob_id blobid; 847 uint8_t payload_read[10 * 4096]; 848 uint8_t payload_write[10 * 4096]; 849 struct iovec iov_read[3]; 850 struct iovec iov_write[3]; 851 void *buf; 852 int rc; 853 854 dev = init_dev(); 855 memset(g_dev_buffer, 0, DEV_BUFFER_SIZE); 856 857 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 858 CU_ASSERT(g_bserrno == 0); 859 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 860 bs = g_bs; 861 862 channel = spdk_bs_alloc_io_channel(bs); 863 CU_ASSERT(channel != NULL); 864 865 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 866 CU_ASSERT(g_bserrno == 0); 867 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 868 blobid = g_blobid; 869 870 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 871 CU_ASSERT(g_bserrno == 0); 872 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 873 blob = g_blob; 874 875 rc = spdk_blob_resize(blob, 2); 876 CU_ASSERT(rc == 0); 877 878 /* 879 * Manually adjust the offset of the blob's second cluster. This allows 880 * us to make sure that the readv/write code correctly accounts for I/O 881 * that cross cluster boundaries. Start by asserting that the allocated 882 * clusters are where we expect before modifying the second cluster. 883 */ 884 CU_ASSERT(__blob_to_data(blob)->active.clusters[0] == 1 * 256); 885 CU_ASSERT(__blob_to_data(blob)->active.clusters[1] == 2 * 256); 886 __blob_to_data(blob)->active.clusters[1] = 3 * 256; 887 888 memset(payload_write, 0xE5, sizeof(payload_write)); 889 iov_write[0].iov_base = payload_write; 890 iov_write[0].iov_len = 1 * 4096; 891 iov_write[1].iov_base = payload_write + 1 * 4096; 892 iov_write[1].iov_len = 5 * 4096; 893 iov_write[2].iov_base = payload_write + 6 * 4096; 894 iov_write[2].iov_len = 4 * 4096; 895 /* 896 * Choose a page offset just before the cluster boundary. The first 6 pages of payload 897 * will get written to the first cluster, the last 4 to the second cluster. 898 */ 899 spdk_bs_io_writev_blob(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 900 CU_ASSERT(g_bserrno == 0); 901 902 memset(payload_read, 0xAA, sizeof(payload_read)); 903 iov_read[0].iov_base = payload_read; 904 iov_read[0].iov_len = 3 * 4096; 905 iov_read[1].iov_base = payload_read + 3 * 4096; 906 iov_read[1].iov_len = 4 * 4096; 907 iov_read[2].iov_base = payload_read + 7 * 4096; 908 iov_read[2].iov_len = 3 * 4096; 909 spdk_bs_io_readv_blob(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 910 CU_ASSERT(g_bserrno == 0); 911 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 912 913 buf = calloc(1, 256 * 4096); 914 SPDK_CU_ASSERT_FATAL(buf != NULL); 915 /* Check that cluster 2 on "disk" was not modified. */ 916 CU_ASSERT(memcmp(buf, &g_dev_buffer[512 * 4096], 256 * 4096) == 0); 917 free(buf); 918 919 spdk_blob_close(blob, blob_op_complete, NULL); 920 CU_ASSERT(g_bserrno == 0); 921 922 spdk_bs_free_io_channel(channel); 923 924 spdk_bs_unload(g_bs, bs_op_complete, NULL); 925 CU_ASSERT(g_bserrno == 0); 926 g_bs = NULL; 927 } 928 929 static uint32_t 930 bs_channel_get_req_count(struct spdk_io_channel *_channel) 931 { 932 struct spdk_bs_channel *channel = spdk_io_channel_get_ctx(_channel); 933 struct spdk_bs_request_set *set; 934 uint32_t count = 0; 935 936 TAILQ_FOREACH(set, &channel->reqs, link) { 937 count++; 938 } 939 940 return count; 941 } 942 943 static void 944 blob_rw_verify_iov_nomem(void) 945 { 946 struct spdk_blob_store *bs; 947 struct spdk_bs_dev *dev; 948 struct spdk_blob *blob; 949 struct spdk_io_channel *channel; 950 spdk_blob_id blobid; 951 uint8_t payload_write[10 * 4096]; 952 struct iovec iov_write[3]; 953 uint32_t req_count; 954 int rc; 955 956 dev = init_dev(); 957 memset(g_dev_buffer, 0, DEV_BUFFER_SIZE); 958 959 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 960 CU_ASSERT(g_bserrno == 0); 961 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 962 bs = g_bs; 963 964 channel = spdk_bs_alloc_io_channel(bs); 965 CU_ASSERT(channel != NULL); 966 967 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 968 CU_ASSERT(g_bserrno == 0); 969 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 970 blobid = g_blobid; 971 972 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 973 CU_ASSERT(g_bserrno == 0); 974 CU_ASSERT(g_blob != NULL); 975 blob = g_blob; 976 977 rc = spdk_blob_resize(blob, 2); 978 CU_ASSERT(rc == 0); 979 980 /* 981 * Choose a page offset just before the cluster boundary. The first 6 pages of payload 982 * will get written to the first cluster, the last 4 to the second cluster. 983 */ 984 iov_write[0].iov_base = payload_write; 985 iov_write[0].iov_len = 1 * 4096; 986 iov_write[1].iov_base = payload_write + 1 * 4096; 987 iov_write[1].iov_len = 5 * 4096; 988 iov_write[2].iov_base = payload_write + 6 * 4096; 989 iov_write[2].iov_len = 4 * 4096; 990 MOCK_SET(calloc, void *, NULL); 991 req_count = bs_channel_get_req_count(channel); 992 spdk_bs_io_writev_blob(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 993 CU_ASSERT(g_bserrno = -ENOMEM); 994 CU_ASSERT(req_count == bs_channel_get_req_count(channel)); 995 MOCK_SET(calloc, void *, (void *)MOCK_PASS_THRU); 996 997 spdk_blob_close(blob, blob_op_complete, NULL); 998 CU_ASSERT(g_bserrno == 0); 999 1000 spdk_bs_free_io_channel(channel); 1001 1002 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1003 CU_ASSERT(g_bserrno == 0); 1004 g_bs = NULL; 1005 } 1006 1007 static void 1008 blob_rw_iov_read_only(void) 1009 { 1010 struct spdk_blob_store *bs; 1011 struct spdk_bs_dev *dev; 1012 struct spdk_blob *blob; 1013 struct spdk_io_channel *channel; 1014 spdk_blob_id blobid; 1015 uint8_t payload_read[4096]; 1016 uint8_t payload_write[4096]; 1017 struct iovec iov_read; 1018 struct iovec iov_write; 1019 int rc; 1020 1021 dev = init_dev(); 1022 memset(g_dev_buffer, 0, DEV_BUFFER_SIZE); 1023 1024 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1025 CU_ASSERT(g_bserrno == 0); 1026 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1027 bs = g_bs; 1028 1029 channel = spdk_bs_alloc_io_channel(bs); 1030 CU_ASSERT(channel != NULL); 1031 1032 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1033 CU_ASSERT(g_bserrno == 0); 1034 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1035 blobid = g_blobid; 1036 1037 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1038 CU_ASSERT(g_bserrno == 0); 1039 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1040 blob = g_blob; 1041 1042 rc = spdk_blob_resize(blob, 2); 1043 CU_ASSERT(rc == 0); 1044 1045 /* Verify that writev failed if read_only flag is set. */ 1046 __blob_to_data(blob)->data_ro = true; 1047 iov_write.iov_base = payload_write; 1048 iov_write.iov_len = sizeof(payload_write); 1049 spdk_bs_io_writev_blob(blob, channel, &iov_write, 1, 0, 1, blob_op_complete, NULL); 1050 CU_ASSERT(g_bserrno == -EPERM); 1051 1052 /* Verify that reads pass if data_ro flag is set. */ 1053 iov_read.iov_base = payload_read; 1054 iov_read.iov_len = sizeof(payload_read); 1055 spdk_bs_io_readv_blob(blob, channel, &iov_read, 1, 0, 1, blob_op_complete, NULL); 1056 CU_ASSERT(g_bserrno == 0); 1057 1058 spdk_blob_close(blob, blob_op_complete, NULL); 1059 CU_ASSERT(g_bserrno == 0); 1060 1061 spdk_bs_free_io_channel(channel); 1062 1063 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1064 CU_ASSERT(g_bserrno == 0); 1065 g_bs = NULL; 1066 } 1067 1068 static void 1069 blob_unmap(void) 1070 { 1071 struct spdk_blob_store *bs; 1072 struct spdk_bs_dev *dev; 1073 struct spdk_blob *blob; 1074 struct spdk_blob_data *_blob; 1075 struct spdk_io_channel *channel; 1076 spdk_blob_id blobid; 1077 struct spdk_blob_opts opts; 1078 uint8_t payload[4096]; 1079 int rc; 1080 int i; 1081 1082 dev = init_dev(); 1083 1084 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1085 CU_ASSERT(g_bserrno == 0); 1086 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1087 bs = g_bs; 1088 1089 channel = spdk_bs_alloc_io_channel(bs); 1090 CU_ASSERT(channel != NULL); 1091 1092 spdk_blob_opts_init(&opts); 1093 opts.num_clusters = 10; 1094 1095 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 1096 CU_ASSERT(g_bserrno == 0); 1097 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1098 blobid = g_blobid; 1099 1100 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1101 CU_ASSERT(g_bserrno == 0); 1102 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1103 blob = g_blob; 1104 _blob = __blob_to_data(blob); 1105 1106 rc = spdk_blob_resize(blob, 10); 1107 CU_ASSERT(rc == 0); 1108 1109 memset(payload, 0, sizeof(payload)); 1110 payload[0] = 0xFF; 1111 1112 /* 1113 * Set first byte of every cluster to 0xFF. 1114 * First cluster on device is reserved so let's start from cluster number 1 1115 */ 1116 for (i = 1; i < 11; i++) { 1117 g_dev_buffer[i * SPDK_BLOB_OPTS_CLUSTER_SZ] = 0xFF; 1118 } 1119 1120 /* Confirm writes */ 1121 for (i = 0; i < 10; i++) { 1122 payload[0] = 0; 1123 spdk_bs_io_read_blob(blob, channel, &payload, i * SPDK_BLOB_OPTS_CLUSTER_SZ / 4096, 1, 1124 blob_op_complete, NULL); 1125 CU_ASSERT(g_bserrno == 0); 1126 CU_ASSERT(payload[0] == 0xFF); 1127 } 1128 1129 /* Mark some clusters as unallocated */ 1130 _blob->active.clusters[1] = 0; 1131 _blob->active.clusters[2] = 0; 1132 _blob->active.clusters[3] = 0; 1133 _blob->active.clusters[6] = 0; 1134 _blob->active.clusters[8] = 0; 1135 1136 /* Unmap clusters by resizing to 0 */ 1137 rc = spdk_blob_resize(blob, 0); 1138 CU_ASSERT(rc == 0); 1139 1140 spdk_blob_sync_md(blob, blob_op_complete, NULL); 1141 CU_ASSERT(g_bserrno == 0); 1142 1143 /* Confirm that only 'allocated' clusters were unmaped */ 1144 for (i = 1; i < 11; i++) { 1145 switch (i) { 1146 case 2: 1147 case 3: 1148 case 4: 1149 case 7: 1150 case 9: 1151 CU_ASSERT(g_dev_buffer[i * SPDK_BLOB_OPTS_CLUSTER_SZ] == 0xFF); 1152 break; 1153 default: 1154 CU_ASSERT(g_dev_buffer[i * SPDK_BLOB_OPTS_CLUSTER_SZ] == 0); 1155 break; 1156 } 1157 } 1158 1159 spdk_blob_close(blob, blob_op_complete, NULL); 1160 CU_ASSERT(g_bserrno == 0); 1161 1162 spdk_bs_free_io_channel(channel); 1163 1164 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1165 CU_ASSERT(g_bserrno == 0); 1166 g_bs = NULL; 1167 } 1168 1169 1170 static void 1171 blob_iter(void) 1172 { 1173 struct spdk_blob_store *bs; 1174 struct spdk_bs_dev *dev; 1175 struct spdk_blob *blob; 1176 spdk_blob_id blobid; 1177 1178 dev = init_dev(); 1179 1180 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1181 CU_ASSERT(g_bserrno == 0); 1182 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1183 bs = g_bs; 1184 1185 spdk_bs_iter_first(bs, blob_op_with_handle_complete, NULL); 1186 CU_ASSERT(g_blob == NULL); 1187 CU_ASSERT(g_bserrno == -ENOENT); 1188 1189 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1190 CU_ASSERT(g_bserrno == 0); 1191 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1192 blobid = g_blobid; 1193 1194 spdk_bs_iter_first(bs, blob_op_with_handle_complete, NULL); 1195 CU_ASSERT(g_blob != NULL); 1196 CU_ASSERT(g_bserrno == 0); 1197 blob = g_blob; 1198 CU_ASSERT(spdk_blob_get_id(blob) == blobid); 1199 1200 spdk_bs_iter_next(bs, blob, blob_op_with_handle_complete, NULL); 1201 CU_ASSERT(g_blob == NULL); 1202 CU_ASSERT(g_bserrno == -ENOENT); 1203 1204 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1205 CU_ASSERT(g_bserrno == 0); 1206 g_bs = NULL; 1207 } 1208 1209 static void 1210 blob_xattr(void) 1211 { 1212 struct spdk_blob_store *bs; 1213 struct spdk_bs_dev *dev; 1214 struct spdk_blob *blob; 1215 spdk_blob_id blobid; 1216 uint64_t length; 1217 int rc; 1218 const char *name1, *name2; 1219 const void *value; 1220 size_t value_len; 1221 struct spdk_xattr_names *names; 1222 1223 dev = init_dev(); 1224 1225 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1226 CU_ASSERT(g_bserrno == 0); 1227 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1228 bs = g_bs; 1229 1230 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1231 CU_ASSERT(g_bserrno == 0); 1232 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1233 blobid = g_blobid; 1234 1235 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1236 CU_ASSERT(g_bserrno == 0); 1237 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1238 blob = g_blob; 1239 1240 /* Test that set_xattr fails if md_ro flag is set. */ 1241 __blob_to_data(blob)->md_ro = true; 1242 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 1243 CU_ASSERT(rc == -EPERM); 1244 1245 __blob_to_data(blob)->md_ro = false; 1246 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 1247 CU_ASSERT(rc == 0); 1248 1249 length = 2345; 1250 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 1251 CU_ASSERT(rc == 0); 1252 1253 /* Overwrite "length" xattr. */ 1254 length = 3456; 1255 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 1256 CU_ASSERT(rc == 0); 1257 1258 /* get_xattr should still work even if md_ro flag is set. */ 1259 value = NULL; 1260 __blob_to_data(blob)->md_ro = true; 1261 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 1262 CU_ASSERT(rc == 0); 1263 SPDK_CU_ASSERT_FATAL(value != NULL); 1264 CU_ASSERT(*(uint64_t *)value == length); 1265 CU_ASSERT(value_len == 8); 1266 __blob_to_data(blob)->md_ro = false; 1267 1268 rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len); 1269 CU_ASSERT(rc == -ENOENT); 1270 1271 names = NULL; 1272 rc = spdk_blob_get_xattr_names(blob, &names); 1273 CU_ASSERT(rc == 0); 1274 SPDK_CU_ASSERT_FATAL(names != NULL); 1275 CU_ASSERT(spdk_xattr_names_get_count(names) == 2); 1276 name1 = spdk_xattr_names_get_name(names, 0); 1277 SPDK_CU_ASSERT_FATAL(name1 != NULL); 1278 CU_ASSERT(!strcmp(name1, "name") || !strcmp(name1, "length")); 1279 name2 = spdk_xattr_names_get_name(names, 1); 1280 SPDK_CU_ASSERT_FATAL(name2 != NULL); 1281 CU_ASSERT(!strcmp(name2, "name") || !strcmp(name2, "length")); 1282 CU_ASSERT(strcmp(name1, name2)); 1283 spdk_xattr_names_free(names); 1284 1285 /* Confirm that remove_xattr fails if md_ro is set to true. */ 1286 __blob_to_data(blob)->md_ro = true; 1287 rc = spdk_blob_remove_xattr(blob, "name"); 1288 CU_ASSERT(rc == -EPERM); 1289 1290 __blob_to_data(blob)->md_ro = false; 1291 rc = spdk_blob_remove_xattr(blob, "name"); 1292 CU_ASSERT(rc == 0); 1293 1294 rc = spdk_blob_remove_xattr(blob, "foobar"); 1295 CU_ASSERT(rc == -ENOENT); 1296 1297 spdk_blob_close(blob, blob_op_complete, NULL); 1298 1299 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1300 CU_ASSERT(g_bserrno == 0); 1301 g_bs = NULL; 1302 } 1303 1304 static void 1305 bs_load(void) 1306 { 1307 struct spdk_bs_dev *dev; 1308 spdk_blob_id blobid; 1309 struct spdk_blob *blob; 1310 struct spdk_bs_super_block *super_block; 1311 uint64_t length; 1312 int rc; 1313 const void *value; 1314 size_t value_len; 1315 struct spdk_bs_opts opts; 1316 1317 g_scheduler_delay = true; 1318 1319 dev = init_dev(); 1320 spdk_bs_opts_init(&opts); 1321 strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH); 1322 1323 /* Initialize a new blob store */ 1324 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1325 CU_ASSERT(g_bserrno == 0); 1326 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1327 1328 /* Try to open a blobid that does not exist */ 1329 spdk_bs_open_blob(g_bs, 0, blob_op_with_handle_complete, NULL); 1330 CU_ASSERT(g_bserrno == -ENOENT); 1331 CU_ASSERT(g_blob == NULL); 1332 1333 /* Create a blob */ 1334 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 1335 CU_ASSERT(g_bserrno == 0); 1336 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1337 blobid = g_blobid; 1338 1339 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 1340 CU_ASSERT(g_bserrno == 0); 1341 CU_ASSERT(g_blob != NULL); 1342 blob = g_blob; 1343 1344 /* Try again to open valid blob but without the upper bit set */ 1345 spdk_bs_open_blob(g_bs, blobid & 0xFFFFFFFF, blob_op_with_handle_complete, NULL); 1346 CU_ASSERT(g_bserrno == -ENOENT); 1347 CU_ASSERT(g_blob == NULL); 1348 1349 /* Set some xattrs */ 1350 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 1351 CU_ASSERT(rc == 0); 1352 1353 length = 2345; 1354 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 1355 CU_ASSERT(rc == 0); 1356 1357 /* Resize the blob */ 1358 rc = spdk_blob_resize(blob, 10); 1359 CU_ASSERT(rc == 0); 1360 1361 spdk_blob_close(blob, blob_op_complete, NULL); 1362 CU_ASSERT(g_bserrno == 0); 1363 blob = NULL; 1364 g_blob = NULL; 1365 g_blobid = SPDK_BLOBID_INVALID; 1366 1367 /* Unload the blob store */ 1368 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1369 CU_ASSERT(g_bserrno == 0); 1370 g_bs = NULL; 1371 g_blob = NULL; 1372 g_blobid = 0; 1373 1374 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 1375 CU_ASSERT(super_block->clean == 1); 1376 1377 1378 /* Load an existing blob store */ 1379 dev = init_dev(); 1380 strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH); 1381 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1382 CU_ASSERT(g_bserrno == 0); 1383 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1384 1385 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 1386 CU_ASSERT(super_block->clean == 0); 1387 1388 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 1389 CU_ASSERT(g_bserrno == 0); 1390 CU_ASSERT(g_blob != NULL); 1391 blob = g_blob; 1392 1393 /* Get the xattrs */ 1394 value = NULL; 1395 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 1396 CU_ASSERT(rc == 0); 1397 SPDK_CU_ASSERT_FATAL(value != NULL); 1398 CU_ASSERT(*(uint64_t *)value == length); 1399 CU_ASSERT(value_len == 8); 1400 1401 rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len); 1402 CU_ASSERT(rc == -ENOENT); 1403 1404 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 1405 1406 spdk_blob_close(blob, blob_op_complete, NULL); 1407 CU_ASSERT(g_bserrno == 0); 1408 blob = NULL; 1409 g_blob = NULL; 1410 g_blobid = SPDK_BLOBID_INVALID; 1411 1412 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1413 CU_ASSERT(g_bserrno == 0); 1414 g_bs = NULL; 1415 g_scheduler_delay = false; 1416 } 1417 1418 static void 1419 bs_type(void) 1420 { 1421 struct spdk_bs_dev *dev; 1422 struct spdk_bs_opts opts; 1423 1424 g_scheduler_delay = true; 1425 1426 dev = init_dev(); 1427 spdk_bs_opts_init(&opts); 1428 strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH); 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 /* Unload the blob store */ 1436 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1437 CU_ASSERT(g_bserrno == 0); 1438 g_bs = NULL; 1439 g_blob = NULL; 1440 g_blobid = 0; 1441 1442 /* Load non existing blobstore type */ 1443 dev = init_dev(); 1444 strncpy(opts.bstype.bstype, "NONEXISTING", SPDK_BLOBSTORE_TYPE_LENGTH); 1445 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1446 CU_ASSERT(g_bserrno != 0); 1447 1448 /* Load with empty blobstore type */ 1449 dev = init_dev(); 1450 strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH); 1451 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1452 CU_ASSERT(g_bserrno == 0); 1453 1454 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1455 CU_ASSERT(g_bserrno == 0); 1456 g_bs = NULL; 1457 1458 /* Initialize a new blob store with empty bstype */ 1459 dev = init_dev(); 1460 strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH); 1461 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1462 CU_ASSERT(g_bserrno == 0); 1463 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1464 1465 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1466 CU_ASSERT(g_bserrno == 0); 1467 g_bs = NULL; 1468 1469 /* Load non existing blobstore type */ 1470 dev = init_dev(); 1471 strncpy(opts.bstype.bstype, "NONEXISTING", SPDK_BLOBSTORE_TYPE_LENGTH); 1472 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1473 CU_ASSERT(g_bserrno != 0); 1474 1475 /* Load with empty blobstore type */ 1476 dev = init_dev(); 1477 strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH); 1478 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1479 CU_ASSERT(g_bserrno == 0); 1480 1481 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1482 CU_ASSERT(g_bserrno == 0); 1483 g_bs = NULL; 1484 g_scheduler_delay = false; 1485 } 1486 1487 static void 1488 bs_super_block(void) 1489 { 1490 struct spdk_bs_dev *dev; 1491 struct spdk_bs_super_block *super_block; 1492 struct spdk_bs_opts opts; 1493 struct spdk_bs_super_block_ver1 super_block_v1; 1494 1495 g_scheduler_delay = true; 1496 1497 dev = init_dev(); 1498 spdk_bs_opts_init(&opts); 1499 strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH); 1500 1501 /* Initialize a new blob store */ 1502 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1503 CU_ASSERT(g_bserrno == 0); 1504 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1505 1506 /* Unload the blob store */ 1507 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1508 CU_ASSERT(g_bserrno == 0); 1509 g_bs = NULL; 1510 g_blob = NULL; 1511 g_blobid = 0; 1512 1513 /* Load an existing blob store with version newer than supported */ 1514 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 1515 super_block->version++; 1516 1517 dev = init_dev(); 1518 strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH); 1519 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1520 CU_ASSERT(g_bserrno != 0); 1521 1522 /* Create a new blob store with super block version 1 */ 1523 dev = init_dev(); 1524 super_block_v1.version = 1; 1525 strncpy(super_block_v1.signature, "SPDKBLOB", sizeof(super_block_v1.signature)); 1526 super_block_v1.length = 0x1000; 1527 super_block_v1.clean = 1; 1528 super_block_v1.super_blob = 0xFFFFFFFFFFFFFFFF; 1529 super_block_v1.cluster_size = 0x100000; 1530 super_block_v1.used_page_mask_start = 0x01; 1531 super_block_v1.used_page_mask_len = 0x01; 1532 super_block_v1.used_cluster_mask_start = 0x02; 1533 super_block_v1.used_cluster_mask_len = 0x01; 1534 super_block_v1.md_start = 0x03; 1535 super_block_v1.md_len = 0x40; 1536 memset(super_block_v1.reserved, 0, 4036); 1537 super_block_v1.crc = _spdk_blob_md_page_calc_crc(&super_block_v1); 1538 memcpy(g_dev_buffer, &super_block_v1, sizeof(struct spdk_bs_super_block_ver1)); 1539 1540 strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH); 1541 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1542 CU_ASSERT(g_bserrno == 0); 1543 1544 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1545 CU_ASSERT(g_bserrno == 0); 1546 g_bs = NULL; 1547 g_scheduler_delay = false; 1548 } 1549 1550 /* 1551 * Create a blobstore and then unload it. 1552 */ 1553 static void 1554 bs_unload(void) 1555 { 1556 struct spdk_bs_dev *dev; 1557 struct spdk_blob_store *bs; 1558 spdk_blob_id blobid; 1559 struct spdk_blob *blob; 1560 1561 dev = init_dev(); 1562 1563 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1564 CU_ASSERT(g_bserrno == 0); 1565 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1566 bs = g_bs; 1567 1568 /* Create a blob and open it. */ 1569 g_bserrno = -1; 1570 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1571 CU_ASSERT(g_bserrno == 0); 1572 CU_ASSERT(g_blobid > 0); 1573 blobid = g_blobid; 1574 1575 g_bserrno = -1; 1576 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1577 CU_ASSERT(g_bserrno == 0); 1578 CU_ASSERT(g_blob != NULL); 1579 blob = g_blob; 1580 1581 /* Try to unload blobstore, should fail with open blob */ 1582 g_bserrno = -1; 1583 spdk_bs_unload(bs, bs_op_complete, NULL); 1584 CU_ASSERT(g_bserrno == -EBUSY); 1585 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1586 1587 /* Close the blob, then successfully unload blobstore */ 1588 g_bserrno = -1; 1589 spdk_blob_close(blob, blob_op_complete, NULL); 1590 CU_ASSERT(g_bserrno == 0); 1591 1592 g_bserrno = -1; 1593 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1594 CU_ASSERT(g_bserrno == 0); 1595 g_bs = NULL; 1596 } 1597 1598 /* 1599 * Create a blobstore with a cluster size different than the default, and ensure it is 1600 * persisted. 1601 */ 1602 static void 1603 bs_cluster_sz(void) 1604 { 1605 struct spdk_bs_dev *dev; 1606 struct spdk_bs_opts opts; 1607 uint32_t cluster_sz; 1608 1609 /* Set cluster size to zero */ 1610 dev = init_dev(); 1611 spdk_bs_opts_init(&opts); 1612 opts.cluster_sz = 0; 1613 1614 /* Initialize a new blob store */ 1615 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1616 CU_ASSERT(g_bserrno == -EINVAL); 1617 SPDK_CU_ASSERT_FATAL(g_bs == NULL); 1618 1619 /* 1620 * Set cluster size to blobstore page size, 1621 * to work it is required to be at least twice the blobstore page size. 1622 */ 1623 dev = init_dev(); 1624 spdk_bs_opts_init(&opts); 1625 opts.cluster_sz = SPDK_BS_PAGE_SIZE; 1626 1627 /* Initialize a new blob store */ 1628 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1629 CU_ASSERT(g_bserrno == -ENOMEM); 1630 SPDK_CU_ASSERT_FATAL(g_bs == NULL); 1631 1632 /* 1633 * Set cluster size to lower than page size, 1634 * to work it is required to be at least twice the blobstore page size. 1635 */ 1636 dev = init_dev(); 1637 spdk_bs_opts_init(&opts); 1638 opts.cluster_sz = SPDK_BS_PAGE_SIZE - 1; 1639 1640 /* Initialize a new blob store */ 1641 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1642 CU_ASSERT(g_bserrno == -ENOMEM); 1643 SPDK_CU_ASSERT_FATAL(g_bs == NULL); 1644 1645 /* Set cluster size to twice the default */ 1646 dev = init_dev(); 1647 spdk_bs_opts_init(&opts); 1648 opts.cluster_sz *= 2; 1649 cluster_sz = opts.cluster_sz; 1650 1651 /* Initialize a new blob store */ 1652 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1653 CU_ASSERT(g_bserrno == 0); 1654 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1655 1656 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 1657 1658 /* Unload the blob store */ 1659 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1660 CU_ASSERT(g_bserrno == 0); 1661 g_bs = NULL; 1662 g_blob = NULL; 1663 g_blobid = 0; 1664 1665 dev = init_dev(); 1666 /* Load an existing blob store */ 1667 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1668 CU_ASSERT(g_bserrno == 0); 1669 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1670 1671 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 1672 1673 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1674 CU_ASSERT(g_bserrno == 0); 1675 g_bs = NULL; 1676 } 1677 1678 /* 1679 * Create a blobstore, reload it and ensure total usable cluster count 1680 * stays the same. 1681 */ 1682 static void 1683 bs_usable_clusters(void) 1684 { 1685 struct spdk_bs_dev *dev; 1686 struct spdk_bs_opts opts; 1687 uint32_t clusters; 1688 int i, rc; 1689 1690 /* Init blobstore */ 1691 dev = init_dev(); 1692 spdk_bs_opts_init(&opts); 1693 1694 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1695 CU_ASSERT(g_bserrno == 0); 1696 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1697 1698 clusters = spdk_bs_total_data_cluster_count(g_bs); 1699 1700 /* Unload the blob store */ 1701 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1702 CU_ASSERT(g_bserrno == 0); 1703 g_bs = NULL; 1704 1705 dev = init_dev(); 1706 /* Load an existing blob store */ 1707 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1708 CU_ASSERT(g_bserrno == 0); 1709 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1710 1711 CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters); 1712 1713 /* Create and resize blobs to make sure that useable cluster count won't change */ 1714 for (i = 0; i < 4; i++) { 1715 g_bserrno = -1; 1716 g_blobid = SPDK_BLOBID_INVALID; 1717 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 1718 CU_ASSERT(g_bserrno == 0); 1719 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1720 1721 g_bserrno = -1; 1722 g_blob = NULL; 1723 spdk_bs_open_blob(g_bs, g_blobid, blob_op_with_handle_complete, NULL); 1724 CU_ASSERT(g_bserrno == 0); 1725 CU_ASSERT(g_blob != NULL); 1726 1727 rc = spdk_blob_resize(g_blob, 10); 1728 CU_ASSERT(rc == 0); 1729 1730 g_bserrno = -1; 1731 spdk_blob_close(g_blob, blob_op_complete, NULL); 1732 CU_ASSERT(g_bserrno == 0); 1733 1734 CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters); 1735 } 1736 1737 /* Reload the blob store to make sure that nothing changed */ 1738 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1739 CU_ASSERT(g_bserrno == 0); 1740 g_bs = NULL; 1741 1742 dev = init_dev(); 1743 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1744 CU_ASSERT(g_bserrno == 0); 1745 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1746 1747 CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters); 1748 1749 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1750 CU_ASSERT(g_bserrno == 0); 1751 g_bs = NULL; 1752 } 1753 1754 /* 1755 * Test resizing of the metadata blob. This requires creating enough blobs 1756 * so that one cluster is not enough to fit the metadata for those blobs. 1757 * To induce this condition to happen more quickly, we reduce the cluster 1758 * size to 16KB, which means only 4 4KB blob metadata pages can fit. 1759 */ 1760 static void 1761 bs_resize_md(void) 1762 { 1763 const int CLUSTER_PAGE_COUNT = 4; 1764 const int NUM_BLOBS = CLUSTER_PAGE_COUNT * 4; 1765 struct spdk_bs_dev *dev; 1766 struct spdk_bs_opts opts; 1767 uint32_t cluster_sz; 1768 spdk_blob_id blobids[NUM_BLOBS]; 1769 int i; 1770 1771 1772 dev = init_dev(); 1773 spdk_bs_opts_init(&opts); 1774 opts.cluster_sz = CLUSTER_PAGE_COUNT * 4096; 1775 cluster_sz = opts.cluster_sz; 1776 1777 /* Initialize a new blob store */ 1778 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1779 CU_ASSERT(g_bserrno == 0); 1780 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1781 1782 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 1783 1784 for (i = 0; i < NUM_BLOBS; i++) { 1785 g_bserrno = -1; 1786 g_blobid = SPDK_BLOBID_INVALID; 1787 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 1788 CU_ASSERT(g_bserrno == 0); 1789 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1790 blobids[i] = g_blobid; 1791 } 1792 1793 /* Unload the blob store */ 1794 g_bserrno = -1; 1795 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1796 CU_ASSERT(g_bserrno == 0); 1797 1798 /* Load an existing blob store */ 1799 g_bserrno = -1; 1800 g_bs = NULL; 1801 dev = init_dev(); 1802 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1803 CU_ASSERT(g_bserrno == 0); 1804 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1805 1806 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 1807 1808 for (i = 0; i < NUM_BLOBS; i++) { 1809 g_bserrno = -1; 1810 g_blob = NULL; 1811 spdk_bs_open_blob(g_bs, blobids[i], blob_op_with_handle_complete, NULL); 1812 CU_ASSERT(g_bserrno == 0); 1813 CU_ASSERT(g_blob != NULL); 1814 g_bserrno = -1; 1815 spdk_blob_close(g_blob, blob_op_complete, NULL); 1816 CU_ASSERT(g_bserrno == 0); 1817 } 1818 1819 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1820 CU_ASSERT(g_bserrno == 0); 1821 g_bs = NULL; 1822 } 1823 1824 static void 1825 bs_destroy(void) 1826 { 1827 struct spdk_bs_dev *dev; 1828 struct spdk_bs_opts opts; 1829 1830 g_scheduler_delay = true; 1831 1832 _bs_flush_scheduler(); 1833 CU_ASSERT(TAILQ_EMPTY(&g_scheduled_ops)); 1834 1835 /* Initialize a new blob store */ 1836 dev = init_dev(); 1837 spdk_bs_opts_init(&opts); 1838 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1839 CU_ASSERT(g_bserrno == 0); 1840 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1841 1842 /* Destroy the blob store */ 1843 g_bserrno = -1; 1844 spdk_bs_destroy(g_bs, bs_op_complete, NULL); 1845 /* Callback is called after device is destroyed in next scheduler run. */ 1846 _bs_flush_scheduler(); 1847 CU_ASSERT(TAILQ_EMPTY(&g_scheduled_ops)); 1848 CU_ASSERT(g_bserrno == 0); 1849 1850 /* Loading an non-existent blob store should fail. */ 1851 g_bserrno = -1; 1852 g_bs = NULL; 1853 dev = init_dev(); 1854 1855 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1856 CU_ASSERT(g_bserrno != 0); 1857 g_scheduler_delay = false; 1858 } 1859 1860 /* Try to hit all of the corner cases associated with serializing 1861 * a blob to disk 1862 */ 1863 static void 1864 blob_serialize(void) 1865 { 1866 struct spdk_bs_dev *dev; 1867 struct spdk_bs_opts opts; 1868 struct spdk_blob_store *bs; 1869 spdk_blob_id blobid[2]; 1870 struct spdk_blob *blob[2]; 1871 uint64_t i; 1872 char *value; 1873 int rc; 1874 1875 dev = init_dev(); 1876 1877 /* Initialize a new blobstore with very small clusters */ 1878 spdk_bs_opts_init(&opts); 1879 opts.cluster_sz = dev->blocklen * 8; 1880 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1881 CU_ASSERT(g_bserrno == 0); 1882 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1883 bs = g_bs; 1884 1885 /* Create and open two blobs */ 1886 for (i = 0; i < 2; i++) { 1887 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1888 CU_ASSERT(g_bserrno == 0); 1889 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1890 blobid[i] = g_blobid; 1891 1892 /* Open a blob */ 1893 spdk_bs_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL); 1894 CU_ASSERT(g_bserrno == 0); 1895 CU_ASSERT(g_blob != NULL); 1896 blob[i] = g_blob; 1897 1898 /* Set a fairly large xattr on both blobs to eat up 1899 * metadata space 1900 */ 1901 value = calloc(dev->blocklen - 64, sizeof(char)); 1902 SPDK_CU_ASSERT_FATAL(value != NULL); 1903 memset(value, i, dev->blocklen / 2); 1904 rc = spdk_blob_set_xattr(blob[i], "name", value, dev->blocklen - 64); 1905 CU_ASSERT(rc == 0); 1906 free(value); 1907 } 1908 1909 /* Resize the blobs, alternating 1 cluster at a time. 1910 * This thwarts run length encoding and will cause spill 1911 * over of the extents. 1912 */ 1913 for (i = 0; i < 6; i++) { 1914 rc = spdk_blob_resize(blob[i % 2], (i / 2) + 1); 1915 CU_ASSERT(rc == 0); 1916 } 1917 1918 for (i = 0; i < 2; i++) { 1919 spdk_blob_sync_md(blob[i], blob_op_complete, NULL); 1920 CU_ASSERT(g_bserrno == 0); 1921 } 1922 1923 /* Close the blobs */ 1924 for (i = 0; i < 2; i++) { 1925 spdk_blob_close(blob[i], blob_op_complete, NULL); 1926 CU_ASSERT(g_bserrno == 0); 1927 } 1928 1929 /* Unload the blobstore */ 1930 spdk_bs_unload(bs, bs_op_complete, NULL); 1931 CU_ASSERT(g_bserrno == 0); 1932 g_bs = NULL; 1933 g_blob = NULL; 1934 g_blobid = 0; 1935 bs = NULL; 1936 1937 dev = init_dev(); 1938 /* Load an existing blob store */ 1939 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1940 CU_ASSERT(g_bserrno == 0); 1941 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1942 bs = g_bs; 1943 1944 for (i = 0; i < 2; i++) { 1945 blob[i] = NULL; 1946 1947 spdk_bs_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL); 1948 CU_ASSERT(g_bserrno == 0); 1949 CU_ASSERT(g_blob != NULL); 1950 blob[i] = g_blob; 1951 1952 CU_ASSERT(spdk_blob_get_num_clusters(blob[i]) == 3); 1953 1954 spdk_blob_close(blob[i], blob_op_complete, NULL); 1955 CU_ASSERT(g_bserrno == 0); 1956 } 1957 1958 spdk_bs_unload(bs, bs_op_complete, NULL); 1959 CU_ASSERT(g_bserrno == 0); 1960 g_bs = NULL; 1961 } 1962 1963 static void 1964 blob_crc(void) 1965 { 1966 struct spdk_blob_store *bs; 1967 struct spdk_bs_dev *dev; 1968 struct spdk_blob *blob; 1969 spdk_blob_id blobid; 1970 uint32_t page_num; 1971 int index; 1972 struct spdk_blob_md_page *page; 1973 1974 dev = init_dev(); 1975 1976 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1977 CU_ASSERT(g_bserrno == 0); 1978 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1979 bs = g_bs; 1980 1981 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1982 CU_ASSERT(g_bserrno == 0); 1983 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1984 blobid = g_blobid; 1985 1986 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1987 CU_ASSERT(g_bserrno == 0); 1988 CU_ASSERT(g_blob != NULL); 1989 blob = g_blob; 1990 1991 spdk_blob_close(blob, blob_op_complete, NULL); 1992 CU_ASSERT(g_bserrno == 0); 1993 1994 page_num = _spdk_bs_blobid_to_page(blobid); 1995 index = DEV_BUFFER_BLOCKLEN * (bs->md_start + page_num); 1996 page = (struct spdk_blob_md_page *)&g_dev_buffer[index]; 1997 page->crc = 0; 1998 1999 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2000 CU_ASSERT(g_bserrno == -EINVAL); 2001 CU_ASSERT(g_blob == NULL); 2002 g_bserrno = 0; 2003 2004 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 2005 CU_ASSERT(g_bserrno == -EINVAL); 2006 2007 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2008 CU_ASSERT(g_bserrno == 0); 2009 g_bs = NULL; 2010 } 2011 2012 static void 2013 super_block_crc(void) 2014 { 2015 struct spdk_bs_dev *dev; 2016 struct spdk_bs_super_block *super_block; 2017 struct spdk_bs_opts opts; 2018 2019 dev = init_dev(); 2020 spdk_bs_opts_init(&opts); 2021 2022 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2023 CU_ASSERT(g_bserrno == 0); 2024 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2025 2026 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2027 CU_ASSERT(g_bserrno == 0); 2028 g_bs = NULL; 2029 2030 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 2031 super_block->crc = 0; 2032 dev = init_dev(); 2033 2034 g_scheduler_delay = true; 2035 /* Load an existing blob store */ 2036 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2037 2038 CU_ASSERT(g_bserrno == -EILSEQ); 2039 _bs_flush_scheduler(); 2040 CU_ASSERT(TAILQ_EMPTY(&g_scheduled_ops)); 2041 2042 g_scheduler_delay = false; 2043 } 2044 2045 /* For blob dirty shutdown test case we do the following sub-test cases: 2046 * 1 Initialize new blob store and create 1 blob with some xattrs, then we 2047 * dirty shutdown and reload the blob store and verify the xattrs. 2048 * 2 Resize the blob from 10 clusters to 20 clusters and then dirty shutdown, 2049 * reload the blob store and verify the clusters number. 2050 * 3 Create the second blob and then dirty shutdown, reload the blob store 2051 * and verify the second blob. 2052 * 4 Delete the second blob and then dirty shutdown, reload teh blob store 2053 * and verify the second blob is invalid. 2054 * 5 Create the second blob again and also create the third blob, modify the 2055 * md of second blob which makes the md invalid, and then dirty shutdown, 2056 * reload the blob store verify the second blob, it should invalid and also 2057 * verify the third blob, it should correct. 2058 */ 2059 static void 2060 blob_dirty_shutdown(void) 2061 { 2062 int rc; 2063 int index; 2064 struct spdk_bs_dev *dev; 2065 spdk_blob_id blobid1, blobid2, blobid3; 2066 struct spdk_blob *blob; 2067 uint64_t length; 2068 uint64_t free_clusters; 2069 const void *value; 2070 size_t value_len; 2071 uint32_t page_num; 2072 struct spdk_blob_md_page *page; 2073 struct spdk_bs_opts opts; 2074 2075 dev = init_dev(); 2076 spdk_bs_opts_init(&opts); 2077 /* Initialize a new blob store */ 2078 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2079 CU_ASSERT(g_bserrno == 0); 2080 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2081 2082 /* Create first blob */ 2083 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2084 CU_ASSERT(g_bserrno == 0); 2085 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2086 blobid1 = g_blobid; 2087 2088 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 2089 CU_ASSERT(g_bserrno == 0); 2090 CU_ASSERT(g_blob != NULL); 2091 blob = g_blob; 2092 2093 /* Set some xattrs */ 2094 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 2095 CU_ASSERT(rc == 0); 2096 2097 length = 2345; 2098 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 2099 CU_ASSERT(rc == 0); 2100 2101 /* Resize the blob */ 2102 rc = spdk_blob_resize(blob, 10); 2103 CU_ASSERT(rc == 0); 2104 2105 free_clusters = spdk_bs_free_cluster_count(g_bs); 2106 2107 spdk_blob_close(blob, blob_op_complete, NULL); 2108 blob = NULL; 2109 g_blob = NULL; 2110 g_blobid = SPDK_BLOBID_INVALID; 2111 2112 /* Dirty shutdown */ 2113 _spdk_bs_free(g_bs); 2114 2115 /* reload blobstore */ 2116 dev = init_dev(); 2117 spdk_bs_opts_init(&opts); 2118 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2119 CU_ASSERT(g_bserrno == 0); 2120 2121 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 2122 CU_ASSERT(g_bserrno == 0); 2123 CU_ASSERT(g_blob != NULL); 2124 blob = g_blob; 2125 2126 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 2127 2128 /* Get the xattrs */ 2129 value = NULL; 2130 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 2131 CU_ASSERT(rc == 0); 2132 SPDK_CU_ASSERT_FATAL(value != NULL); 2133 CU_ASSERT(*(uint64_t *)value == length); 2134 CU_ASSERT(value_len == 8); 2135 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 2136 2137 /* Resize the blob */ 2138 rc = spdk_blob_resize(blob, 20); 2139 CU_ASSERT(rc == 0); 2140 2141 free_clusters = spdk_bs_free_cluster_count(g_bs); 2142 2143 spdk_blob_close(blob, blob_op_complete, NULL); 2144 CU_ASSERT(g_bserrno == 0); 2145 blob = NULL; 2146 g_blob = NULL; 2147 g_blobid = SPDK_BLOBID_INVALID; 2148 2149 /* Dirty shutdown */ 2150 _spdk_bs_free(g_bs); 2151 2152 /* reload the blobstore */ 2153 dev = init_dev(); 2154 spdk_bs_opts_init(&opts); 2155 /* Load an existing blob store */ 2156 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2157 CU_ASSERT(g_bserrno == 0); 2158 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2159 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 2160 CU_ASSERT(g_bserrno == 0); 2161 CU_ASSERT(g_blob != NULL); 2162 blob = g_blob; 2163 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 20); 2164 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 2165 2166 spdk_blob_close(blob, blob_op_complete, NULL); 2167 CU_ASSERT(g_bserrno == 0); 2168 blob = NULL; 2169 g_blob = NULL; 2170 g_blobid = SPDK_BLOBID_INVALID; 2171 2172 /* Create second blob */ 2173 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2174 CU_ASSERT(g_bserrno == 0); 2175 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2176 blobid2 = g_blobid; 2177 2178 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 2179 CU_ASSERT(g_bserrno == 0); 2180 CU_ASSERT(g_blob != NULL); 2181 blob = g_blob; 2182 2183 /* Set some xattrs */ 2184 rc = spdk_blob_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1); 2185 CU_ASSERT(rc == 0); 2186 2187 length = 5432; 2188 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 2189 CU_ASSERT(rc == 0); 2190 2191 /* Resize the blob */ 2192 rc = spdk_blob_resize(blob, 10); 2193 CU_ASSERT(rc == 0); 2194 2195 free_clusters = spdk_bs_free_cluster_count(g_bs); 2196 2197 spdk_blob_close(blob, blob_op_complete, NULL); 2198 blob = NULL; 2199 g_blob = NULL; 2200 g_blobid = SPDK_BLOBID_INVALID; 2201 2202 /* Dirty shutdown */ 2203 _spdk_bs_free(g_bs); 2204 2205 /* reload the blobstore */ 2206 dev = init_dev(); 2207 spdk_bs_opts_init(&opts); 2208 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2209 CU_ASSERT(g_bserrno == 0); 2210 2211 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 2212 CU_ASSERT(g_bserrno == 0); 2213 CU_ASSERT(g_blob != NULL); 2214 blob = g_blob; 2215 2216 /* Get the xattrs */ 2217 value = NULL; 2218 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 2219 CU_ASSERT(rc == 0); 2220 SPDK_CU_ASSERT_FATAL(value != NULL); 2221 CU_ASSERT(*(uint64_t *)value == length); 2222 CU_ASSERT(value_len == 8); 2223 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 2224 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 2225 2226 spdk_blob_close(blob, blob_op_complete, NULL); 2227 CU_ASSERT(g_bserrno == 0); 2228 spdk_bs_delete_blob(g_bs, blobid2, blob_op_complete, NULL); 2229 CU_ASSERT(g_bserrno == 0); 2230 2231 free_clusters = spdk_bs_free_cluster_count(g_bs); 2232 2233 /* Dirty shutdown */ 2234 _spdk_bs_free(g_bs); 2235 /* reload the blobstore */ 2236 dev = init_dev(); 2237 spdk_bs_opts_init(&opts); 2238 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2239 CU_ASSERT(g_bserrno == 0); 2240 2241 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 2242 CU_ASSERT(g_bserrno != 0); 2243 CU_ASSERT(g_blob == NULL); 2244 2245 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 2246 CU_ASSERT(g_bserrno == 0); 2247 CU_ASSERT(g_blob != NULL); 2248 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 2249 spdk_blob_close(g_blob, blob_op_complete, NULL); 2250 CU_ASSERT(g_bserrno == 0); 2251 2252 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2253 CU_ASSERT(g_bserrno == 0); 2254 g_bs = NULL; 2255 2256 /* reload the blobstore */ 2257 dev = init_dev(); 2258 spdk_bs_opts_init(&opts); 2259 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2260 CU_ASSERT(g_bserrno == 0); 2261 2262 /* Create second blob */ 2263 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2264 CU_ASSERT(g_bserrno == 0); 2265 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2266 blobid2 = g_blobid; 2267 2268 /* Create third blob */ 2269 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2270 CU_ASSERT(g_bserrno == 0); 2271 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2272 blobid3 = g_blobid; 2273 2274 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 2275 CU_ASSERT(g_bserrno == 0); 2276 CU_ASSERT(g_blob != NULL); 2277 blob = g_blob; 2278 2279 /* Set some xattrs for second blob */ 2280 rc = spdk_blob_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1); 2281 CU_ASSERT(rc == 0); 2282 2283 length = 5432; 2284 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 2285 CU_ASSERT(rc == 0); 2286 2287 spdk_blob_close(blob, blob_op_complete, NULL); 2288 blob = NULL; 2289 g_blob = NULL; 2290 g_blobid = SPDK_BLOBID_INVALID; 2291 2292 spdk_bs_open_blob(g_bs, blobid3, blob_op_with_handle_complete, NULL); 2293 CU_ASSERT(g_bserrno == 0); 2294 CU_ASSERT(g_blob != NULL); 2295 blob = g_blob; 2296 2297 /* Set some xattrs for third blob */ 2298 rc = spdk_blob_set_xattr(blob, "name", "log2.txt", strlen("log2.txt") + 1); 2299 CU_ASSERT(rc == 0); 2300 2301 length = 5432; 2302 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 2303 CU_ASSERT(rc == 0); 2304 2305 spdk_blob_close(blob, blob_op_complete, NULL); 2306 blob = NULL; 2307 g_blob = NULL; 2308 g_blobid = SPDK_BLOBID_INVALID; 2309 2310 /* Mark second blob as invalid */ 2311 page_num = _spdk_bs_blobid_to_page(blobid2); 2312 2313 index = DEV_BUFFER_BLOCKLEN * (g_bs->md_start + page_num); 2314 page = (struct spdk_blob_md_page *)&g_dev_buffer[index]; 2315 page->sequence_num = 1; 2316 page->crc = _spdk_blob_md_page_calc_crc(page); 2317 2318 free_clusters = spdk_bs_free_cluster_count(g_bs); 2319 2320 /* Dirty shutdown */ 2321 _spdk_bs_free(g_bs); 2322 /* reload the blobstore */ 2323 dev = init_dev(); 2324 spdk_bs_opts_init(&opts); 2325 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2326 CU_ASSERT(g_bserrno == 0); 2327 2328 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 2329 CU_ASSERT(g_bserrno != 0); 2330 CU_ASSERT(g_blob == NULL); 2331 2332 spdk_bs_open_blob(g_bs, blobid3, blob_op_with_handle_complete, NULL); 2333 CU_ASSERT(g_bserrno == 0); 2334 CU_ASSERT(g_blob != NULL); 2335 blob = g_blob; 2336 2337 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 2338 2339 spdk_blob_close(blob, blob_op_complete, NULL); 2340 blob = NULL; 2341 g_blob = NULL; 2342 g_blobid = SPDK_BLOBID_INVALID; 2343 2344 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2345 CU_ASSERT(g_bserrno == 0); 2346 g_bs = NULL; 2347 } 2348 2349 static void 2350 blob_flags(void) 2351 { 2352 struct spdk_bs_dev *dev; 2353 spdk_blob_id blobid_invalid, blobid_data_ro, blobid_md_ro; 2354 struct spdk_blob *blob_invalid, *blob_data_ro, *blob_md_ro; 2355 struct spdk_bs_opts opts; 2356 int rc; 2357 2358 dev = init_dev(); 2359 spdk_bs_opts_init(&opts); 2360 2361 /* Initialize a new blob store */ 2362 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2363 CU_ASSERT(g_bserrno == 0); 2364 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2365 2366 /* Create three blobs - one each for testing invalid, data_ro and md_ro flags. */ 2367 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2368 CU_ASSERT(g_bserrno == 0); 2369 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2370 blobid_invalid = g_blobid; 2371 2372 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2373 CU_ASSERT(g_bserrno == 0); 2374 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2375 blobid_data_ro = g_blobid; 2376 2377 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2378 CU_ASSERT(g_bserrno == 0); 2379 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2380 blobid_md_ro = g_blobid; 2381 2382 spdk_bs_open_blob(g_bs, blobid_invalid, blob_op_with_handle_complete, NULL); 2383 CU_ASSERT(g_bserrno == 0); 2384 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2385 blob_invalid = g_blob; 2386 2387 spdk_bs_open_blob(g_bs, blobid_data_ro, blob_op_with_handle_complete, NULL); 2388 CU_ASSERT(g_bserrno == 0); 2389 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2390 blob_data_ro = g_blob; 2391 2392 spdk_bs_open_blob(g_bs, blobid_md_ro, blob_op_with_handle_complete, NULL); 2393 CU_ASSERT(g_bserrno == 0); 2394 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2395 blob_md_ro = g_blob; 2396 2397 /* Change the size of blob_data_ro to check if flags are serialized 2398 * when blob has non zero number of extents */ 2399 rc = spdk_blob_resize(blob_data_ro, 10); 2400 CU_ASSERT(rc == 0); 2401 2402 /* Set the xattr to check if flags are serialized 2403 * when blob has non zero number of xattrs */ 2404 rc = spdk_blob_set_xattr(blob_md_ro, "name", "log.txt", strlen("log.txt") + 1); 2405 CU_ASSERT(rc == 0); 2406 2407 __blob_to_data(blob_invalid)->invalid_flags = (1ULL << 63); 2408 __blob_to_data(blob_invalid)->state = SPDK_BLOB_STATE_DIRTY; 2409 __blob_to_data(blob_data_ro)->data_ro_flags = (1ULL << 62); 2410 __blob_to_data(blob_data_ro)->state = SPDK_BLOB_STATE_DIRTY; 2411 __blob_to_data(blob_md_ro)->md_ro_flags = (1ULL << 61); 2412 __blob_to_data(blob_md_ro)->state = SPDK_BLOB_STATE_DIRTY; 2413 2414 g_bserrno = -1; 2415 spdk_blob_sync_md(blob_invalid, blob_op_complete, NULL); 2416 CU_ASSERT(g_bserrno == 0); 2417 g_bserrno = -1; 2418 spdk_blob_sync_md(blob_data_ro, blob_op_complete, NULL); 2419 CU_ASSERT(g_bserrno == 0); 2420 g_bserrno = -1; 2421 spdk_blob_sync_md(blob_md_ro, blob_op_complete, NULL); 2422 CU_ASSERT(g_bserrno == 0); 2423 2424 g_bserrno = -1; 2425 spdk_blob_close(blob_invalid, blob_op_complete, NULL); 2426 CU_ASSERT(g_bserrno == 0); 2427 blob_invalid = NULL; 2428 g_bserrno = -1; 2429 spdk_blob_close(blob_data_ro, blob_op_complete, NULL); 2430 CU_ASSERT(g_bserrno == 0); 2431 blob_data_ro = NULL; 2432 g_bserrno = -1; 2433 spdk_blob_close(blob_md_ro, blob_op_complete, NULL); 2434 CU_ASSERT(g_bserrno == 0); 2435 blob_md_ro = NULL; 2436 2437 g_blob = NULL; 2438 g_blobid = SPDK_BLOBID_INVALID; 2439 2440 /* Unload the blob store */ 2441 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2442 CU_ASSERT(g_bserrno == 0); 2443 g_bs = NULL; 2444 2445 /* Load an existing blob store */ 2446 dev = init_dev(); 2447 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2448 CU_ASSERT(g_bserrno == 0); 2449 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2450 2451 g_blob = NULL; 2452 g_bserrno = 0; 2453 spdk_bs_open_blob(g_bs, blobid_invalid, blob_op_with_handle_complete, NULL); 2454 CU_ASSERT(g_bserrno != 0); 2455 CU_ASSERT(g_blob == NULL); 2456 2457 g_blob = NULL; 2458 g_bserrno = -1; 2459 spdk_bs_open_blob(g_bs, blobid_data_ro, blob_op_with_handle_complete, NULL); 2460 CU_ASSERT(g_bserrno == 0); 2461 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2462 blob_data_ro = g_blob; 2463 /* If an unknown data_ro flag was found, the blob should be marked both data and md read-only. */ 2464 CU_ASSERT(__blob_to_data(blob_data_ro)->data_ro == true); 2465 CU_ASSERT(__blob_to_data(blob_data_ro)->md_ro == true); 2466 CU_ASSERT(spdk_blob_get_num_clusters(blob_data_ro) == 10); 2467 2468 g_blob = NULL; 2469 g_bserrno = -1; 2470 spdk_bs_open_blob(g_bs, blobid_md_ro, blob_op_with_handle_complete, NULL); 2471 CU_ASSERT(g_bserrno == 0); 2472 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2473 blob_md_ro = g_blob; 2474 CU_ASSERT(__blob_to_data(blob_md_ro)->data_ro == false); 2475 CU_ASSERT(__blob_to_data(blob_md_ro)->md_ro == true); 2476 2477 g_bserrno = -1; 2478 spdk_blob_sync_md(blob_md_ro, blob_op_complete, NULL); 2479 CU_ASSERT(g_bserrno == 0); 2480 2481 spdk_blob_close(blob_data_ro, blob_op_complete, NULL); 2482 CU_ASSERT(g_bserrno == 0); 2483 spdk_blob_close(blob_md_ro, blob_op_complete, NULL); 2484 CU_ASSERT(g_bserrno == 0); 2485 2486 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2487 CU_ASSERT(g_bserrno == 0); 2488 } 2489 2490 static void 2491 bs_version(void) 2492 { 2493 struct spdk_bs_super_block *super; 2494 struct spdk_bs_dev *dev; 2495 struct spdk_bs_opts opts; 2496 spdk_blob_id blobid; 2497 2498 dev = init_dev(); 2499 spdk_bs_opts_init(&opts); 2500 2501 /* Initialize a new blob store */ 2502 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2503 CU_ASSERT(g_bserrno == 0); 2504 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2505 2506 /* Unload the blob store */ 2507 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2508 CU_ASSERT(g_bserrno == 0); 2509 g_bs = NULL; 2510 2511 /* 2512 * Change the bs version on disk. This will allow us to 2513 * test that the version does not get modified automatically 2514 * when loading and unloading the blobstore. 2515 */ 2516 super = (struct spdk_bs_super_block *)&g_dev_buffer[0]; 2517 CU_ASSERT(super->version == SPDK_BS_VERSION); 2518 CU_ASSERT(super->clean == 1); 2519 super->version = 2; 2520 /* 2521 * Version 2 metadata does not have a used blobid mask, so clear 2522 * those fields in the super block and zero the corresponding 2523 * region on "disk". We will use this to ensure blob IDs are 2524 * correctly reconstructed. 2525 */ 2526 memset(&g_dev_buffer[super->used_blobid_mask_start * SPDK_BS_PAGE_SIZE], 0, 2527 super->used_blobid_mask_len * SPDK_BS_PAGE_SIZE); 2528 super->used_blobid_mask_start = 0; 2529 super->used_blobid_mask_len = 0; 2530 super->crc = _spdk_blob_md_page_calc_crc(super); 2531 2532 /* Load an existing blob store */ 2533 dev = init_dev(); 2534 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2535 CU_ASSERT(g_bserrno == 0); 2536 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2537 CU_ASSERT(super->clean == 0); 2538 2539 /* 2540 * Create a blob - just to make sure that when we unload it 2541 * results in writing the super block (since metadata pages 2542 * were allocated. 2543 */ 2544 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2545 CU_ASSERT(g_bserrno == 0); 2546 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2547 blobid = g_blobid; 2548 2549 /* Unload the blob store */ 2550 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2551 CU_ASSERT(g_bserrno == 0); 2552 g_bs = NULL; 2553 CU_ASSERT(super->version == 2); 2554 CU_ASSERT(super->used_blobid_mask_start == 0); 2555 CU_ASSERT(super->used_blobid_mask_len == 0); 2556 2557 dev = init_dev(); 2558 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2559 CU_ASSERT(g_bserrno == 0); 2560 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2561 2562 g_blob = NULL; 2563 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 2564 CU_ASSERT(g_bserrno == 0); 2565 CU_ASSERT(g_blob != NULL); 2566 2567 spdk_blob_close(g_blob, blob_op_complete, NULL); 2568 CU_ASSERT(g_bserrno == 0); 2569 2570 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2571 CU_ASSERT(g_bserrno == 0); 2572 g_bs = NULL; 2573 CU_ASSERT(super->version == 2); 2574 CU_ASSERT(super->used_blobid_mask_start == 0); 2575 CU_ASSERT(super->used_blobid_mask_len == 0); 2576 } 2577 2578 static void 2579 _get_xattr_value(void *arg, const char *name, 2580 const void **value, size_t *value_len) 2581 { 2582 uint64_t i; 2583 2584 SPDK_CU_ASSERT_FATAL(value_len != NULL); 2585 SPDK_CU_ASSERT_FATAL(value != NULL); 2586 CU_ASSERT(arg == &g_ctx) 2587 2588 for (i = 0; i < sizeof(g_xattr_names); i++) { 2589 if (!strcmp(name, g_xattr_names[i])) { 2590 *value_len = strlen(g_xattr_values[i]); 2591 *value = g_xattr_values[i]; 2592 break; 2593 } 2594 } 2595 } 2596 2597 static void 2598 _get_xattr_value_null(void *arg, const char *name, 2599 const void **value, size_t *value_len) 2600 { 2601 SPDK_CU_ASSERT_FATAL(value_len != NULL); 2602 SPDK_CU_ASSERT_FATAL(value != NULL); 2603 CU_ASSERT(arg == NULL) 2604 2605 *value_len = 0; 2606 *value = NULL; 2607 } 2608 2609 static void 2610 blob_set_xattrs(void) 2611 { 2612 struct spdk_blob_store *bs; 2613 struct spdk_bs_dev *dev; 2614 struct spdk_blob *blob; 2615 struct spdk_blob_opts opts; 2616 spdk_blob_id blobid; 2617 const void *value; 2618 size_t value_len; 2619 int rc; 2620 2621 dev = init_dev(); 2622 2623 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2624 CU_ASSERT(g_bserrno == 0); 2625 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2626 bs = g_bs; 2627 2628 /* Create blob with extra attributes */ 2629 spdk_blob_opts_init(&opts); 2630 2631 opts.xattrs.names = g_xattr_names; 2632 opts.xattrs.get_value = _get_xattr_value; 2633 opts.xattrs.count = 3; 2634 opts.xattrs.ctx = &g_ctx; 2635 2636 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 2637 CU_ASSERT(g_bserrno == 0); 2638 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2639 blobid = g_blobid; 2640 2641 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2642 CU_ASSERT(g_bserrno == 0); 2643 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2644 blob = g_blob; 2645 2646 /* Get the xattrs */ 2647 value = NULL; 2648 2649 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[0], &value, &value_len); 2650 CU_ASSERT(rc == 0); 2651 SPDK_CU_ASSERT_FATAL(value != NULL); 2652 CU_ASSERT(value_len == strlen(g_xattr_values[0])); 2653 CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len); 2654 2655 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[1], &value, &value_len); 2656 CU_ASSERT(rc == 0); 2657 SPDK_CU_ASSERT_FATAL(value != NULL); 2658 CU_ASSERT(value_len == strlen(g_xattr_values[1])); 2659 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len); 2660 2661 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[2], &value, &value_len); 2662 CU_ASSERT(rc == 0); 2663 SPDK_CU_ASSERT_FATAL(value != NULL); 2664 CU_ASSERT(value_len == strlen(g_xattr_values[2])); 2665 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len); 2666 2667 /* Try to get non existing attribute */ 2668 2669 rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len); 2670 CU_ASSERT(rc == -ENOENT); 2671 2672 spdk_blob_close(blob, blob_op_complete, NULL); 2673 CU_ASSERT(g_bserrno == 0); 2674 blob = NULL; 2675 g_blob = NULL; 2676 g_blobid = SPDK_BLOBID_INVALID; 2677 2678 /* NULL callback */ 2679 spdk_blob_opts_init(&opts); 2680 opts.xattrs.names = g_xattr_names; 2681 opts.xattrs.get_value = NULL; 2682 opts.xattrs.count = 1; 2683 opts.xattrs.ctx = &g_ctx; 2684 2685 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 2686 CU_ASSERT(g_bserrno == -EINVAL); 2687 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2688 2689 /* NULL values */ 2690 spdk_blob_opts_init(&opts); 2691 opts.xattrs.names = g_xattr_names; 2692 opts.xattrs.get_value = _get_xattr_value_null; 2693 opts.xattrs.count = 1; 2694 opts.xattrs.ctx = NULL; 2695 2696 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 2697 CU_ASSERT(g_bserrno == -EINVAL); 2698 2699 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2700 CU_ASSERT(g_bserrno == 0); 2701 g_bs = NULL; 2702 2703 } 2704 2705 static void 2706 blob_thin_prov_alloc(void) 2707 { 2708 struct spdk_blob_store *bs; 2709 struct spdk_bs_dev *dev; 2710 struct spdk_blob *blob; 2711 struct spdk_blob_data *blob_data; 2712 struct spdk_blob_opts opts; 2713 spdk_blob_id blobid; 2714 uint64_t free_clusters; 2715 int rc; 2716 2717 dev = init_dev(); 2718 2719 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2720 CU_ASSERT(g_bserrno == 0); 2721 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2722 bs = g_bs; 2723 free_clusters = spdk_bs_free_cluster_count(bs); 2724 2725 /* Set blob as thin provisioned */ 2726 spdk_blob_opts_init(&opts); 2727 opts.thin_provision = true; 2728 2729 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 2730 CU_ASSERT(g_bserrno == 0); 2731 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2732 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 2733 blobid = g_blobid; 2734 2735 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2736 CU_ASSERT(g_bserrno == 0); 2737 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2738 blob = g_blob; 2739 blob_data = __blob_to_data(blob); 2740 2741 CU_ASSERT(blob_data->active.num_clusters == 0); 2742 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0); 2743 2744 /* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */ 2745 rc = spdk_blob_resize(blob, 5); 2746 CU_ASSERT(rc == 0); 2747 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 2748 CU_ASSERT(blob_data->active.num_clusters == 5); 2749 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 2750 2751 /* Shrink the blob to 3 clusters - still unallocated */ 2752 rc = spdk_blob_resize(blob, 3); 2753 CU_ASSERT(rc == 0); 2754 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 2755 CU_ASSERT(blob_data->active.num_clusters == 3); 2756 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 3); 2757 2758 spdk_blob_sync_md(blob, blob_op_complete, NULL); 2759 CU_ASSERT(g_bserrno == 0); 2760 /* Sync must not change anything */ 2761 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 2762 CU_ASSERT(blob_data->active.num_clusters == 3); 2763 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 3); 2764 2765 spdk_blob_close(blob, blob_op_complete, NULL); 2766 CU_ASSERT(g_bserrno == 0); 2767 2768 /* Unload the blob store */ 2769 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2770 CU_ASSERT(g_bserrno == 0); 2771 g_bs = NULL; 2772 g_blob = NULL; 2773 g_blobid = 0; 2774 2775 /* Load an existing blob store */ 2776 dev = init_dev(); 2777 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 2778 CU_ASSERT(g_bserrno == 0); 2779 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2780 2781 bs = g_bs; 2782 2783 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 2784 CU_ASSERT(g_bserrno == 0); 2785 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2786 blob = g_blob; 2787 blob_data = __blob_to_data(blob); 2788 2789 /* Check that clusters allocation and size is still the same */ 2790 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 2791 CU_ASSERT(blob_data->active.num_clusters == 3); 2792 2793 spdk_blob_close(blob, blob_op_complete, NULL); 2794 CU_ASSERT(g_bserrno == 0); 2795 2796 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 2797 CU_ASSERT(g_bserrno == 0); 2798 2799 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2800 CU_ASSERT(g_bserrno == 0); 2801 g_bs = NULL; 2802 } 2803 2804 static void 2805 blob_insert_cluster_msg(void) 2806 { 2807 struct spdk_blob_store *bs; 2808 struct spdk_bs_dev *dev; 2809 struct spdk_blob *blob; 2810 struct spdk_blob_data *blob_data; 2811 struct spdk_blob_opts opts; 2812 spdk_blob_id blobid; 2813 uint64_t free_clusters; 2814 2815 dev = init_dev(); 2816 2817 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2818 CU_ASSERT(g_bserrno == 0); 2819 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2820 bs = g_bs; 2821 free_clusters = spdk_bs_free_cluster_count(bs); 2822 2823 /* Set blob as thin provisioned */ 2824 spdk_blob_opts_init(&opts); 2825 opts.thin_provision = true; 2826 opts.num_clusters = 4; 2827 2828 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 2829 CU_ASSERT(g_bserrno == 0); 2830 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2831 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 2832 blobid = g_blobid; 2833 2834 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2835 CU_ASSERT(g_bserrno == 0); 2836 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2837 blob = g_blob; 2838 blob_data = __blob_to_data(blob); 2839 2840 CU_ASSERT(blob_data->active.num_clusters == 4); 2841 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 4); 2842 CU_ASSERT(blob_data->active.clusters[1] == 0); 2843 2844 _spdk_bs_claim_cluster(bs, 0xF); 2845 _spdk_blob_insert_cluster_on_md_thread(blob_data, 1, 0xF, blob_op_complete, NULL); 2846 2847 CU_ASSERT(blob_data->active.clusters[1] != 0); 2848 2849 spdk_blob_close(blob, blob_op_complete, NULL); 2850 CU_ASSERT(g_bserrno == 0); 2851 2852 /* Unload the blob store */ 2853 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2854 CU_ASSERT(g_bserrno == 0); 2855 g_bs = NULL; 2856 g_blob = NULL; 2857 g_blobid = 0; 2858 2859 /* Load an existing blob store */ 2860 dev = init_dev(); 2861 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 2862 CU_ASSERT(g_bserrno == 0); 2863 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2864 2865 bs = g_bs; 2866 2867 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 2868 CU_ASSERT(g_bserrno == 0); 2869 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2870 blob = g_blob; 2871 blob_data = __blob_to_data(blob); 2872 2873 CU_ASSERT(blob_data->active.clusters[1] != 0); 2874 2875 spdk_blob_close(blob, blob_op_complete, NULL); 2876 CU_ASSERT(g_bserrno == 0); 2877 2878 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 2879 CU_ASSERT(g_bserrno == 0); 2880 2881 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2882 CU_ASSERT(g_bserrno == 0); 2883 g_bs = NULL; 2884 } 2885 2886 static void 2887 blob_thin_prov_rw(void) 2888 { 2889 static const uint8_t zero[10 * 4096] = { 0 }; 2890 struct spdk_blob_store *bs; 2891 struct spdk_bs_dev *dev; 2892 struct spdk_blob *blob; 2893 struct spdk_blob_data *blob_data; 2894 struct spdk_io_channel *channel; 2895 struct spdk_blob_opts opts; 2896 spdk_blob_id blobid; 2897 uint64_t free_clusters; 2898 uint8_t payload_read[10 * 4096]; 2899 uint8_t payload_write[10 * 4096]; 2900 int rc; 2901 2902 dev = init_dev(); 2903 2904 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2905 CU_ASSERT(g_bserrno == 0); 2906 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2907 bs = g_bs; 2908 free_clusters = spdk_bs_free_cluster_count(bs); 2909 2910 channel = spdk_bs_alloc_io_channel(bs); 2911 CU_ASSERT(channel != NULL); 2912 2913 spdk_blob_opts_init(&opts); 2914 opts.thin_provision = true; 2915 2916 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 2917 CU_ASSERT(g_bserrno == 0); 2918 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2919 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 2920 blobid = g_blobid; 2921 2922 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2923 CU_ASSERT(g_bserrno == 0); 2924 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2925 blob = g_blob; 2926 blob_data = __blob_to_data(blob); 2927 2928 CU_ASSERT(blob_data->active.num_clusters == 0); 2929 2930 /* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */ 2931 rc = spdk_blob_resize(blob, 5); 2932 CU_ASSERT(rc == 0); 2933 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 2934 CU_ASSERT(blob_data->active.num_clusters == 5); 2935 2936 spdk_blob_sync_md(blob, blob_op_complete, NULL); 2937 CU_ASSERT(g_bserrno == 0); 2938 /* Sync must not change anything */ 2939 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 2940 CU_ASSERT(blob_data->active.num_clusters == 5); 2941 2942 /* Payload should be all zeros from unallocated clusters */ 2943 memset(payload_read, 0xFF, sizeof(payload_read)); 2944 spdk_bs_io_read_blob(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 2945 CU_ASSERT(g_bserrno == 0); 2946 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 2947 2948 memset(payload_write, 0xE5, sizeof(payload_write)); 2949 spdk_bs_io_write_blob(blob, channel, payload_write, 4, 10, blob_op_complete, NULL); 2950 CU_ASSERT(g_bserrno == 0); 2951 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 2952 2953 spdk_bs_io_read_blob(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 2954 CU_ASSERT(g_bserrno == 0); 2955 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 2956 2957 spdk_blob_close(blob, blob_op_complete, NULL); 2958 CU_ASSERT(g_bserrno == 0); 2959 2960 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 2961 CU_ASSERT(g_bserrno == 0); 2962 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 2963 2964 spdk_bs_free_io_channel(channel); 2965 2966 /* Unload the blob store */ 2967 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2968 CU_ASSERT(g_bserrno == 0); 2969 g_bs = NULL; 2970 g_blob = NULL; 2971 g_blobid = 0; 2972 } 2973 2974 static void 2975 blob_thin_prov_rw_iov(void) 2976 { 2977 static const uint8_t zero[10 * 4096] = { 0 }; 2978 struct spdk_blob_store *bs; 2979 struct spdk_bs_dev *dev; 2980 struct spdk_blob *blob; 2981 struct spdk_blob_data *blob_data; 2982 struct spdk_io_channel *channel; 2983 struct spdk_blob_opts opts; 2984 spdk_blob_id blobid; 2985 uint64_t free_clusters; 2986 uint8_t payload_read[10 * 4096]; 2987 uint8_t payload_write[10 * 4096]; 2988 struct iovec iov_read[3]; 2989 struct iovec iov_write[3]; 2990 2991 int rc; 2992 2993 dev = init_dev(); 2994 2995 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2996 CU_ASSERT(g_bserrno == 0); 2997 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2998 bs = g_bs; 2999 free_clusters = spdk_bs_free_cluster_count(bs); 3000 3001 channel = spdk_bs_alloc_io_channel(bs); 3002 CU_ASSERT(channel != NULL); 3003 3004 spdk_blob_opts_init(&opts); 3005 opts.thin_provision = true; 3006 3007 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 3008 CU_ASSERT(g_bserrno == 0); 3009 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3010 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3011 blobid = g_blobid; 3012 3013 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3014 CU_ASSERT(g_bserrno == 0); 3015 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3016 blob = g_blob; 3017 blob_data = __blob_to_data(blob); 3018 3019 CU_ASSERT(blob_data->active.num_clusters == 0); 3020 3021 /* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */ 3022 rc = spdk_blob_resize(blob, 5); 3023 CU_ASSERT(rc == 0); 3024 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3025 CU_ASSERT(blob_data->active.num_clusters == 5); 3026 3027 spdk_blob_sync_md(blob, blob_op_complete, NULL); 3028 CU_ASSERT(g_bserrno == 0); 3029 /* Sync must not change anything */ 3030 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3031 CU_ASSERT(blob_data->active.num_clusters == 5); 3032 3033 /* Payload should be all zeros from unallocated clusters */ 3034 memset(payload_read, 0xAA, sizeof(payload_read)); 3035 iov_read[0].iov_base = payload_read; 3036 iov_read[0].iov_len = 3 * 4096; 3037 iov_read[1].iov_base = payload_read + 3 * 4096; 3038 iov_read[1].iov_len = 4 * 4096; 3039 iov_read[2].iov_base = payload_read + 7 * 4096; 3040 iov_read[2].iov_len = 3 * 4096; 3041 spdk_bs_io_readv_blob(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 3042 CU_ASSERT(g_bserrno == 0); 3043 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 3044 3045 memset(payload_write, 0xE5, sizeof(payload_write)); 3046 iov_write[0].iov_base = payload_write; 3047 iov_write[0].iov_len = 1 * 4096; 3048 iov_write[1].iov_base = payload_write + 1 * 4096; 3049 iov_write[1].iov_len = 5 * 4096; 3050 iov_write[2].iov_base = payload_write + 6 * 4096; 3051 iov_write[2].iov_len = 4 * 4096; 3052 3053 spdk_bs_io_writev_blob(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 3054 CU_ASSERT(g_bserrno == 0); 3055 3056 memset(payload_read, 0xAA, sizeof(payload_read)); 3057 iov_read[0].iov_base = payload_read; 3058 iov_read[0].iov_len = 3 * 4096; 3059 iov_read[1].iov_base = payload_read + 3 * 4096; 3060 iov_read[1].iov_len = 4 * 4096; 3061 iov_read[2].iov_base = payload_read + 7 * 4096; 3062 iov_read[2].iov_len = 3 * 4096; 3063 spdk_bs_io_readv_blob(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 3064 CU_ASSERT(g_bserrno == 0); 3065 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 3066 3067 spdk_blob_close(blob, blob_op_complete, NULL); 3068 CU_ASSERT(g_bserrno == 0); 3069 3070 spdk_bs_free_io_channel(channel); 3071 3072 /* Unload the blob store */ 3073 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3074 CU_ASSERT(g_bserrno == 0); 3075 g_bs = NULL; 3076 g_blob = NULL; 3077 g_blobid = 0; 3078 } 3079 3080 int main(int argc, char **argv) 3081 { 3082 CU_pSuite suite = NULL; 3083 unsigned int num_failures; 3084 3085 if (CU_initialize_registry() != CUE_SUCCESS) { 3086 return CU_get_error(); 3087 } 3088 3089 suite = CU_add_suite("blob", NULL, NULL); 3090 if (suite == NULL) { 3091 CU_cleanup_registry(); 3092 return CU_get_error(); 3093 } 3094 3095 if ( 3096 CU_add_test(suite, "blob_init", blob_init) == NULL || 3097 CU_add_test(suite, "blob_open", blob_open) == NULL || 3098 CU_add_test(suite, "blob_create", blob_create) == NULL || 3099 CU_add_test(suite, "blob_thin_provision", blob_thin_provision) == NULL || 3100 CU_add_test(suite, "blob_delete", blob_delete) == NULL || 3101 CU_add_test(suite, "blob_resize", blob_resize) == NULL || 3102 CU_add_test(suite, "blob_read_only", blob_read_only) == NULL || 3103 CU_add_test(suite, "channel_ops", channel_ops) == NULL || 3104 CU_add_test(suite, "blob_super", blob_super) == NULL || 3105 CU_add_test(suite, "blob_write", blob_write) == NULL || 3106 CU_add_test(suite, "blob_read", blob_read) == NULL || 3107 CU_add_test(suite, "blob_rw_verify", blob_rw_verify) == NULL || 3108 CU_add_test(suite, "blob_rw_verify_iov", blob_rw_verify_iov) == NULL || 3109 CU_add_test(suite, "blob_rw_verify_iov_nomem", blob_rw_verify_iov_nomem) == NULL || 3110 CU_add_test(suite, "blob_rw_iov_read_only", blob_rw_iov_read_only) == NULL || 3111 CU_add_test(suite, "blob_unmap", blob_unmap) == NULL || 3112 CU_add_test(suite, "blob_iter", blob_iter) == NULL || 3113 CU_add_test(suite, "blob_xattr", blob_xattr) == NULL || 3114 CU_add_test(suite, "bs_load", bs_load) == NULL || 3115 CU_add_test(suite, "bs_unload", bs_unload) == NULL || 3116 CU_add_test(suite, "bs_cluster_sz", bs_cluster_sz) == NULL || 3117 CU_add_test(suite, "bs_usable_clusters", bs_usable_clusters) == NULL || 3118 CU_add_test(suite, "bs_resize_md", bs_resize_md) == NULL || 3119 CU_add_test(suite, "bs_destroy", bs_destroy) == NULL || 3120 CU_add_test(suite, "bs_type", bs_type) == NULL || 3121 CU_add_test(suite, "bs_super_block", bs_super_block) == NULL || 3122 CU_add_test(suite, "blob_serialize", blob_serialize) == NULL || 3123 CU_add_test(suite, "blob_crc", blob_crc) == NULL || 3124 CU_add_test(suite, "super_block_crc", super_block_crc) == NULL || 3125 CU_add_test(suite, "blob_dirty_shutdown", blob_dirty_shutdown) == NULL || 3126 CU_add_test(suite, "blob_flags", blob_flags) == NULL || 3127 CU_add_test(suite, "bs_version", bs_version) == NULL || 3128 CU_add_test(suite, "blob_set_xattrs", blob_set_xattrs) == NULL || 3129 CU_add_test(suite, "blob_thin_prov_alloc", blob_thin_prov_alloc) == NULL || 3130 CU_add_test(suite, "blob_insert_cluster_msg", blob_insert_cluster_msg) == NULL || 3131 CU_add_test(suite, "blob_thin_prov_rw", blob_thin_prov_rw) == NULL || 3132 CU_add_test(suite, "blob_thin_prov_rw_iov", blob_thin_prov_rw_iov) == NULL 3133 ) { 3134 CU_cleanup_registry(); 3135 return CU_get_error(); 3136 } 3137 3138 g_dev_buffer = calloc(1, DEV_BUFFER_SIZE); 3139 spdk_allocate_thread(_bs_send_msg, NULL, NULL, NULL, "thread0"); 3140 CU_basic_set_mode(CU_BRM_VERBOSE); 3141 CU_basic_run_tests(); 3142 num_failures = CU_get_number_of_failures(); 3143 CU_cleanup_registry(); 3144 spdk_free_thread(); 3145 free(g_dev_buffer); 3146 return num_failures; 3147 } 3148