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_iter(void) 1070 { 1071 struct spdk_blob_store *bs; 1072 struct spdk_bs_dev *dev; 1073 struct spdk_blob *blob; 1074 spdk_blob_id blobid; 1075 1076 dev = init_dev(); 1077 1078 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1079 CU_ASSERT(g_bserrno == 0); 1080 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1081 bs = g_bs; 1082 1083 spdk_bs_iter_first(bs, blob_op_with_handle_complete, NULL); 1084 CU_ASSERT(g_blob == NULL); 1085 CU_ASSERT(g_bserrno == -ENOENT); 1086 1087 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1088 CU_ASSERT(g_bserrno == 0); 1089 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1090 blobid = g_blobid; 1091 1092 spdk_bs_iter_first(bs, blob_op_with_handle_complete, NULL); 1093 CU_ASSERT(g_blob != NULL); 1094 CU_ASSERT(g_bserrno == 0); 1095 blob = g_blob; 1096 CU_ASSERT(spdk_blob_get_id(blob) == blobid); 1097 1098 spdk_bs_iter_next(bs, blob, blob_op_with_handle_complete, NULL); 1099 CU_ASSERT(g_blob == NULL); 1100 CU_ASSERT(g_bserrno == -ENOENT); 1101 1102 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1103 CU_ASSERT(g_bserrno == 0); 1104 g_bs = NULL; 1105 } 1106 1107 static void 1108 blob_xattr(void) 1109 { 1110 struct spdk_blob_store *bs; 1111 struct spdk_bs_dev *dev; 1112 struct spdk_blob *blob; 1113 spdk_blob_id blobid; 1114 uint64_t length; 1115 int rc; 1116 const char *name1, *name2; 1117 const void *value; 1118 size_t value_len; 1119 struct spdk_xattr_names *names; 1120 1121 dev = init_dev(); 1122 1123 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1124 CU_ASSERT(g_bserrno == 0); 1125 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1126 bs = g_bs; 1127 1128 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1129 CU_ASSERT(g_bserrno == 0); 1130 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1131 blobid = g_blobid; 1132 1133 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1134 CU_ASSERT(g_bserrno == 0); 1135 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1136 blob = g_blob; 1137 1138 /* Test that set_xattr fails if md_ro flag is set. */ 1139 __blob_to_data(blob)->md_ro = true; 1140 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 1141 CU_ASSERT(rc == -EPERM); 1142 1143 __blob_to_data(blob)->md_ro = false; 1144 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 1145 CU_ASSERT(rc == 0); 1146 1147 length = 2345; 1148 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 1149 CU_ASSERT(rc == 0); 1150 1151 /* Overwrite "length" xattr. */ 1152 length = 3456; 1153 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 1154 CU_ASSERT(rc == 0); 1155 1156 /* get_xattr should still work even if md_ro flag is set. */ 1157 value = NULL; 1158 __blob_to_data(blob)->md_ro = true; 1159 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 1160 CU_ASSERT(rc == 0); 1161 SPDK_CU_ASSERT_FATAL(value != NULL); 1162 CU_ASSERT(*(uint64_t *)value == length); 1163 CU_ASSERT(value_len == 8); 1164 __blob_to_data(blob)->md_ro = false; 1165 1166 rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len); 1167 CU_ASSERT(rc == -ENOENT); 1168 1169 names = NULL; 1170 rc = spdk_blob_get_xattr_names(blob, &names); 1171 CU_ASSERT(rc == 0); 1172 SPDK_CU_ASSERT_FATAL(names != NULL); 1173 CU_ASSERT(spdk_xattr_names_get_count(names) == 2); 1174 name1 = spdk_xattr_names_get_name(names, 0); 1175 SPDK_CU_ASSERT_FATAL(name1 != NULL); 1176 CU_ASSERT(!strcmp(name1, "name") || !strcmp(name1, "length")); 1177 name2 = spdk_xattr_names_get_name(names, 1); 1178 SPDK_CU_ASSERT_FATAL(name2 != NULL); 1179 CU_ASSERT(!strcmp(name2, "name") || !strcmp(name2, "length")); 1180 CU_ASSERT(strcmp(name1, name2)); 1181 spdk_xattr_names_free(names); 1182 1183 /* Confirm that remove_xattr fails if md_ro is set to true. */ 1184 __blob_to_data(blob)->md_ro = true; 1185 rc = spdk_blob_remove_xattr(blob, "name"); 1186 CU_ASSERT(rc == -EPERM); 1187 1188 __blob_to_data(blob)->md_ro = false; 1189 rc = spdk_blob_remove_xattr(blob, "name"); 1190 CU_ASSERT(rc == 0); 1191 1192 rc = spdk_blob_remove_xattr(blob, "foobar"); 1193 CU_ASSERT(rc == -ENOENT); 1194 1195 spdk_blob_close(blob, blob_op_complete, NULL); 1196 1197 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1198 CU_ASSERT(g_bserrno == 0); 1199 g_bs = NULL; 1200 } 1201 1202 static void 1203 bs_load(void) 1204 { 1205 struct spdk_bs_dev *dev; 1206 spdk_blob_id blobid; 1207 struct spdk_blob *blob; 1208 struct spdk_bs_super_block *super_block; 1209 uint64_t length; 1210 int rc; 1211 const void *value; 1212 size_t value_len; 1213 struct spdk_bs_opts opts; 1214 1215 g_scheduler_delay = true; 1216 1217 dev = init_dev(); 1218 spdk_bs_opts_init(&opts); 1219 strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH); 1220 1221 /* Initialize a new blob store */ 1222 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1223 CU_ASSERT(g_bserrno == 0); 1224 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1225 1226 /* Try to open a blobid that does not exist */ 1227 spdk_bs_open_blob(g_bs, 0, blob_op_with_handle_complete, NULL); 1228 CU_ASSERT(g_bserrno == -ENOENT); 1229 CU_ASSERT(g_blob == NULL); 1230 1231 /* Create a blob */ 1232 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 1233 CU_ASSERT(g_bserrno == 0); 1234 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1235 blobid = g_blobid; 1236 1237 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 1238 CU_ASSERT(g_bserrno == 0); 1239 CU_ASSERT(g_blob != NULL); 1240 blob = g_blob; 1241 1242 /* Try again to open valid blob but without the upper bit set */ 1243 spdk_bs_open_blob(g_bs, blobid & 0xFFFFFFFF, blob_op_with_handle_complete, NULL); 1244 CU_ASSERT(g_bserrno == -ENOENT); 1245 CU_ASSERT(g_blob == NULL); 1246 1247 /* Set some xattrs */ 1248 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 1249 CU_ASSERT(rc == 0); 1250 1251 length = 2345; 1252 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 1253 CU_ASSERT(rc == 0); 1254 1255 /* Resize the blob */ 1256 rc = spdk_blob_resize(blob, 10); 1257 CU_ASSERT(rc == 0); 1258 1259 spdk_blob_close(blob, blob_op_complete, NULL); 1260 CU_ASSERT(g_bserrno == 0); 1261 blob = NULL; 1262 g_blob = NULL; 1263 g_blobid = SPDK_BLOBID_INVALID; 1264 1265 /* Unload the blob store */ 1266 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1267 CU_ASSERT(g_bserrno == 0); 1268 g_bs = NULL; 1269 g_blob = NULL; 1270 g_blobid = 0; 1271 1272 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 1273 CU_ASSERT(super_block->clean == 1); 1274 1275 1276 /* Load an existing blob store */ 1277 dev = init_dev(); 1278 strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH); 1279 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1280 CU_ASSERT(g_bserrno == 0); 1281 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1282 1283 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 1284 CU_ASSERT(super_block->clean == 0); 1285 1286 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 1287 CU_ASSERT(g_bserrno == 0); 1288 CU_ASSERT(g_blob != NULL); 1289 blob = g_blob; 1290 1291 /* Get the xattrs */ 1292 value = NULL; 1293 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 1294 CU_ASSERT(rc == 0); 1295 SPDK_CU_ASSERT_FATAL(value != NULL); 1296 CU_ASSERT(*(uint64_t *)value == length); 1297 CU_ASSERT(value_len == 8); 1298 1299 rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len); 1300 CU_ASSERT(rc == -ENOENT); 1301 1302 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 1303 1304 spdk_blob_close(blob, blob_op_complete, NULL); 1305 CU_ASSERT(g_bserrno == 0); 1306 blob = NULL; 1307 g_blob = NULL; 1308 g_blobid = SPDK_BLOBID_INVALID; 1309 1310 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1311 CU_ASSERT(g_bserrno == 0); 1312 g_bs = NULL; 1313 g_scheduler_delay = false; 1314 } 1315 1316 static void 1317 bs_type(void) 1318 { 1319 struct spdk_bs_dev *dev; 1320 struct spdk_bs_opts opts; 1321 1322 g_scheduler_delay = true; 1323 1324 dev = init_dev(); 1325 spdk_bs_opts_init(&opts); 1326 strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH); 1327 1328 /* Initialize a new blob store */ 1329 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1330 CU_ASSERT(g_bserrno == 0); 1331 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1332 1333 /* Unload the blob store */ 1334 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1335 CU_ASSERT(g_bserrno == 0); 1336 g_bs = NULL; 1337 g_blob = NULL; 1338 g_blobid = 0; 1339 1340 /* Load non existing blobstore type */ 1341 dev = init_dev(); 1342 strncpy(opts.bstype.bstype, "NONEXISTING", SPDK_BLOBSTORE_TYPE_LENGTH); 1343 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1344 CU_ASSERT(g_bserrno != 0); 1345 1346 /* Load with empty blobstore type */ 1347 dev = init_dev(); 1348 strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH); 1349 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1350 CU_ASSERT(g_bserrno == 0); 1351 1352 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1353 CU_ASSERT(g_bserrno == 0); 1354 g_bs = NULL; 1355 1356 /* Initialize a new blob store with empty bstype */ 1357 dev = init_dev(); 1358 strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH); 1359 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1360 CU_ASSERT(g_bserrno == 0); 1361 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1362 1363 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1364 CU_ASSERT(g_bserrno == 0); 1365 g_bs = NULL; 1366 1367 /* Load non existing blobstore type */ 1368 dev = init_dev(); 1369 strncpy(opts.bstype.bstype, "NONEXISTING", SPDK_BLOBSTORE_TYPE_LENGTH); 1370 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1371 CU_ASSERT(g_bserrno != 0); 1372 1373 /* Load with empty blobstore type */ 1374 dev = init_dev(); 1375 strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH); 1376 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1377 CU_ASSERT(g_bserrno == 0); 1378 1379 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1380 CU_ASSERT(g_bserrno == 0); 1381 g_bs = NULL; 1382 g_scheduler_delay = false; 1383 } 1384 1385 static void 1386 bs_super_block(void) 1387 { 1388 struct spdk_bs_dev *dev; 1389 struct spdk_bs_super_block *super_block; 1390 struct spdk_bs_opts opts; 1391 struct spdk_bs_super_block_ver1 super_block_v1; 1392 1393 g_scheduler_delay = true; 1394 1395 dev = init_dev(); 1396 spdk_bs_opts_init(&opts); 1397 strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH); 1398 1399 /* Initialize a new blob store */ 1400 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1401 CU_ASSERT(g_bserrno == 0); 1402 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1403 1404 /* Unload the blob store */ 1405 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1406 CU_ASSERT(g_bserrno == 0); 1407 g_bs = NULL; 1408 g_blob = NULL; 1409 g_blobid = 0; 1410 1411 /* Load an existing blob store with version newer than supported */ 1412 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 1413 super_block->version++; 1414 1415 dev = init_dev(); 1416 strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH); 1417 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1418 CU_ASSERT(g_bserrno != 0); 1419 1420 /* Create a new blob store with super block version 1 */ 1421 dev = init_dev(); 1422 super_block_v1.version = 1; 1423 strncpy(super_block_v1.signature, "SPDKBLOB", sizeof(super_block_v1.signature)); 1424 super_block_v1.length = 0x1000; 1425 super_block_v1.clean = 1; 1426 super_block_v1.super_blob = 0xFFFFFFFFFFFFFFFF; 1427 super_block_v1.cluster_size = 0x100000; 1428 super_block_v1.used_page_mask_start = 0x01; 1429 super_block_v1.used_page_mask_len = 0x01; 1430 super_block_v1.used_cluster_mask_start = 0x02; 1431 super_block_v1.used_cluster_mask_len = 0x01; 1432 super_block_v1.md_start = 0x03; 1433 super_block_v1.md_len = 0x40; 1434 memset(super_block_v1.reserved, 0, 4036); 1435 super_block_v1.crc = _spdk_blob_md_page_calc_crc(&super_block_v1); 1436 memcpy(g_dev_buffer, &super_block_v1, sizeof(struct spdk_bs_super_block_ver1)); 1437 1438 strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH); 1439 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1440 CU_ASSERT(g_bserrno == 0); 1441 1442 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1443 CU_ASSERT(g_bserrno == 0); 1444 g_bs = NULL; 1445 g_scheduler_delay = false; 1446 } 1447 1448 /* 1449 * Create a blobstore and then unload it. 1450 */ 1451 static void 1452 bs_unload(void) 1453 { 1454 struct spdk_bs_dev *dev; 1455 struct spdk_blob_store *bs; 1456 spdk_blob_id blobid; 1457 struct spdk_blob *blob; 1458 1459 dev = init_dev(); 1460 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 bs = g_bs; 1465 1466 /* Create a blob and open it. */ 1467 g_bserrno = -1; 1468 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1469 CU_ASSERT(g_bserrno == 0); 1470 CU_ASSERT(g_blobid > 0); 1471 blobid = g_blobid; 1472 1473 g_bserrno = -1; 1474 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1475 CU_ASSERT(g_bserrno == 0); 1476 CU_ASSERT(g_blob != NULL); 1477 blob = g_blob; 1478 1479 /* Try to unload blobstore, should fail with open blob */ 1480 g_bserrno = -1; 1481 spdk_bs_unload(bs, bs_op_complete, NULL); 1482 CU_ASSERT(g_bserrno == -EBUSY); 1483 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1484 1485 /* Close the blob, then successfully unload blobstore */ 1486 g_bserrno = -1; 1487 spdk_blob_close(blob, blob_op_complete, NULL); 1488 CU_ASSERT(g_bserrno == 0); 1489 1490 g_bserrno = -1; 1491 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1492 CU_ASSERT(g_bserrno == 0); 1493 g_bs = NULL; 1494 } 1495 1496 /* 1497 * Create a blobstore with a cluster size different than the default, and ensure it is 1498 * persisted. 1499 */ 1500 static void 1501 bs_cluster_sz(void) 1502 { 1503 struct spdk_bs_dev *dev; 1504 struct spdk_bs_opts opts; 1505 uint32_t cluster_sz; 1506 1507 /* Set cluster size to zero */ 1508 dev = init_dev(); 1509 spdk_bs_opts_init(&opts); 1510 opts.cluster_sz = 0; 1511 1512 /* Initialize a new blob store */ 1513 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1514 CU_ASSERT(g_bserrno == -EINVAL); 1515 SPDK_CU_ASSERT_FATAL(g_bs == NULL); 1516 1517 /* 1518 * Set cluster size to blobstore page size, 1519 * to work it is required to be at least twice the blobstore page size. 1520 */ 1521 dev = init_dev(); 1522 spdk_bs_opts_init(&opts); 1523 opts.cluster_sz = SPDK_BS_PAGE_SIZE; 1524 1525 /* Initialize a new blob store */ 1526 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1527 CU_ASSERT(g_bserrno == -ENOMEM); 1528 SPDK_CU_ASSERT_FATAL(g_bs == NULL); 1529 1530 /* 1531 * Set cluster size to lower than page size, 1532 * to work it is required to be at least twice the blobstore page size. 1533 */ 1534 dev = init_dev(); 1535 spdk_bs_opts_init(&opts); 1536 opts.cluster_sz = SPDK_BS_PAGE_SIZE - 1; 1537 1538 /* Initialize a new blob store */ 1539 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1540 CU_ASSERT(g_bserrno == -ENOMEM); 1541 SPDK_CU_ASSERT_FATAL(g_bs == NULL); 1542 1543 /* Set cluster size to twice the default */ 1544 dev = init_dev(); 1545 spdk_bs_opts_init(&opts); 1546 opts.cluster_sz *= 2; 1547 cluster_sz = opts.cluster_sz; 1548 1549 /* Initialize a new blob store */ 1550 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1551 CU_ASSERT(g_bserrno == 0); 1552 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1553 1554 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 1555 1556 /* Unload the blob store */ 1557 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1558 CU_ASSERT(g_bserrno == 0); 1559 g_bs = NULL; 1560 g_blob = NULL; 1561 g_blobid = 0; 1562 1563 dev = init_dev(); 1564 /* Load an existing blob store */ 1565 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1566 CU_ASSERT(g_bserrno == 0); 1567 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1568 1569 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 1570 1571 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1572 CU_ASSERT(g_bserrno == 0); 1573 g_bs = NULL; 1574 } 1575 1576 /* 1577 * Create a blobstore, reload it and ensure total usable cluster count 1578 * stays the same. 1579 */ 1580 static void 1581 bs_usable_clusters(void) 1582 { 1583 struct spdk_bs_dev *dev; 1584 struct spdk_bs_opts opts; 1585 uint32_t clusters; 1586 int i, rc; 1587 1588 /* Init blobstore */ 1589 dev = init_dev(); 1590 spdk_bs_opts_init(&opts); 1591 1592 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1593 CU_ASSERT(g_bserrno == 0); 1594 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1595 1596 clusters = spdk_bs_total_data_cluster_count(g_bs); 1597 1598 /* Unload the blob store */ 1599 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1600 CU_ASSERT(g_bserrno == 0); 1601 g_bs = NULL; 1602 1603 dev = init_dev(); 1604 /* Load an existing blob store */ 1605 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1606 CU_ASSERT(g_bserrno == 0); 1607 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1608 1609 CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters); 1610 1611 /* Create and resize blobs to make sure that useable cluster count won't change */ 1612 for (i = 0; i < 4; i++) { 1613 g_bserrno = -1; 1614 g_blobid = SPDK_BLOBID_INVALID; 1615 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 1616 CU_ASSERT(g_bserrno == 0); 1617 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1618 1619 g_bserrno = -1; 1620 g_blob = NULL; 1621 spdk_bs_open_blob(g_bs, g_blobid, blob_op_with_handle_complete, NULL); 1622 CU_ASSERT(g_bserrno == 0); 1623 CU_ASSERT(g_blob != NULL); 1624 1625 rc = spdk_blob_resize(g_blob, 10); 1626 CU_ASSERT(rc == 0); 1627 1628 g_bserrno = -1; 1629 spdk_blob_close(g_blob, blob_op_complete, NULL); 1630 CU_ASSERT(g_bserrno == 0); 1631 1632 CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters); 1633 } 1634 1635 /* Reload the blob store to make sure that nothing changed */ 1636 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1637 CU_ASSERT(g_bserrno == 0); 1638 g_bs = NULL; 1639 1640 dev = init_dev(); 1641 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1642 CU_ASSERT(g_bserrno == 0); 1643 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1644 1645 CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters); 1646 1647 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1648 CU_ASSERT(g_bserrno == 0); 1649 g_bs = NULL; 1650 } 1651 1652 /* 1653 * Test resizing of the metadata blob. This requires creating enough blobs 1654 * so that one cluster is not enough to fit the metadata for those blobs. 1655 * To induce this condition to happen more quickly, we reduce the cluster 1656 * size to 16KB, which means only 4 4KB blob metadata pages can fit. 1657 */ 1658 static void 1659 bs_resize_md(void) 1660 { 1661 const int CLUSTER_PAGE_COUNT = 4; 1662 const int NUM_BLOBS = CLUSTER_PAGE_COUNT * 4; 1663 struct spdk_bs_dev *dev; 1664 struct spdk_bs_opts opts; 1665 uint32_t cluster_sz; 1666 spdk_blob_id blobids[NUM_BLOBS]; 1667 int i; 1668 1669 1670 dev = init_dev(); 1671 spdk_bs_opts_init(&opts); 1672 opts.cluster_sz = CLUSTER_PAGE_COUNT * 4096; 1673 cluster_sz = opts.cluster_sz; 1674 1675 /* Initialize a new blob store */ 1676 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1677 CU_ASSERT(g_bserrno == 0); 1678 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1679 1680 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 1681 1682 for (i = 0; i < NUM_BLOBS; i++) { 1683 g_bserrno = -1; 1684 g_blobid = SPDK_BLOBID_INVALID; 1685 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 1686 CU_ASSERT(g_bserrno == 0); 1687 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1688 blobids[i] = g_blobid; 1689 } 1690 1691 /* Unload the blob store */ 1692 g_bserrno = -1; 1693 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1694 CU_ASSERT(g_bserrno == 0); 1695 1696 /* Load an existing blob store */ 1697 g_bserrno = -1; 1698 g_bs = NULL; 1699 dev = init_dev(); 1700 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1701 CU_ASSERT(g_bserrno == 0); 1702 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1703 1704 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 1705 1706 for (i = 0; i < NUM_BLOBS; i++) { 1707 g_bserrno = -1; 1708 g_blob = NULL; 1709 spdk_bs_open_blob(g_bs, blobids[i], blob_op_with_handle_complete, NULL); 1710 CU_ASSERT(g_bserrno == 0); 1711 CU_ASSERT(g_blob != NULL); 1712 g_bserrno = -1; 1713 spdk_blob_close(g_blob, blob_op_complete, NULL); 1714 CU_ASSERT(g_bserrno == 0); 1715 } 1716 1717 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1718 CU_ASSERT(g_bserrno == 0); 1719 g_bs = NULL; 1720 } 1721 1722 static void 1723 bs_destroy(void) 1724 { 1725 struct spdk_bs_dev *dev; 1726 struct spdk_bs_opts opts; 1727 1728 g_scheduler_delay = true; 1729 1730 _bs_flush_scheduler(); 1731 CU_ASSERT(TAILQ_EMPTY(&g_scheduled_ops)); 1732 1733 /* Initialize a new blob store */ 1734 dev = init_dev(); 1735 spdk_bs_opts_init(&opts); 1736 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1737 CU_ASSERT(g_bserrno == 0); 1738 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1739 1740 /* Destroy the blob store */ 1741 g_bserrno = -1; 1742 spdk_bs_destroy(g_bs, bs_op_complete, NULL); 1743 /* Callback is called after device is destroyed in next scheduler run. */ 1744 _bs_flush_scheduler(); 1745 CU_ASSERT(TAILQ_EMPTY(&g_scheduled_ops)); 1746 CU_ASSERT(g_bserrno == 0); 1747 1748 /* Loading an non-existent blob store should fail. */ 1749 g_bserrno = -1; 1750 g_bs = NULL; 1751 dev = init_dev(); 1752 1753 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1754 CU_ASSERT(g_bserrno != 0); 1755 g_scheduler_delay = false; 1756 } 1757 1758 /* Try to hit all of the corner cases associated with serializing 1759 * a blob to disk 1760 */ 1761 static void 1762 blob_serialize(void) 1763 { 1764 struct spdk_bs_dev *dev; 1765 struct spdk_bs_opts opts; 1766 struct spdk_blob_store *bs; 1767 spdk_blob_id blobid[2]; 1768 struct spdk_blob *blob[2]; 1769 uint64_t i; 1770 char *value; 1771 int rc; 1772 1773 dev = init_dev(); 1774 1775 /* Initialize a new blobstore with very small clusters */ 1776 spdk_bs_opts_init(&opts); 1777 opts.cluster_sz = dev->blocklen * 8; 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 bs = g_bs; 1782 1783 /* Create and open two blobs */ 1784 for (i = 0; i < 2; i++) { 1785 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1786 CU_ASSERT(g_bserrno == 0); 1787 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1788 blobid[i] = g_blobid; 1789 1790 /* Open a blob */ 1791 spdk_bs_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL); 1792 CU_ASSERT(g_bserrno == 0); 1793 CU_ASSERT(g_blob != NULL); 1794 blob[i] = g_blob; 1795 1796 /* Set a fairly large xattr on both blobs to eat up 1797 * metadata space 1798 */ 1799 value = calloc(dev->blocklen - 64, sizeof(char)); 1800 SPDK_CU_ASSERT_FATAL(value != NULL); 1801 memset(value, i, dev->blocklen / 2); 1802 rc = spdk_blob_set_xattr(blob[i], "name", value, dev->blocklen - 64); 1803 CU_ASSERT(rc == 0); 1804 free(value); 1805 } 1806 1807 /* Resize the blobs, alternating 1 cluster at a time. 1808 * This thwarts run length encoding and will cause spill 1809 * over of the extents. 1810 */ 1811 for (i = 0; i < 6; i++) { 1812 rc = spdk_blob_resize(blob[i % 2], (i / 2) + 1); 1813 CU_ASSERT(rc == 0); 1814 } 1815 1816 for (i = 0; i < 2; i++) { 1817 spdk_blob_sync_md(blob[i], blob_op_complete, NULL); 1818 CU_ASSERT(g_bserrno == 0); 1819 } 1820 1821 /* Close the blobs */ 1822 for (i = 0; i < 2; i++) { 1823 spdk_blob_close(blob[i], blob_op_complete, NULL); 1824 CU_ASSERT(g_bserrno == 0); 1825 } 1826 1827 /* Unload the blobstore */ 1828 spdk_bs_unload(bs, bs_op_complete, NULL); 1829 CU_ASSERT(g_bserrno == 0); 1830 g_bs = NULL; 1831 g_blob = NULL; 1832 g_blobid = 0; 1833 bs = NULL; 1834 1835 dev = init_dev(); 1836 /* Load an existing blob store */ 1837 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1838 CU_ASSERT(g_bserrno == 0); 1839 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1840 bs = g_bs; 1841 1842 for (i = 0; i < 2; i++) { 1843 blob[i] = NULL; 1844 1845 spdk_bs_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL); 1846 CU_ASSERT(g_bserrno == 0); 1847 CU_ASSERT(g_blob != NULL); 1848 blob[i] = g_blob; 1849 1850 CU_ASSERT(spdk_blob_get_num_clusters(blob[i]) == 3); 1851 1852 spdk_blob_close(blob[i], blob_op_complete, NULL); 1853 CU_ASSERT(g_bserrno == 0); 1854 } 1855 1856 spdk_bs_unload(bs, bs_op_complete, NULL); 1857 CU_ASSERT(g_bserrno == 0); 1858 g_bs = NULL; 1859 } 1860 1861 static void 1862 blob_crc(void) 1863 { 1864 struct spdk_blob_store *bs; 1865 struct spdk_bs_dev *dev; 1866 struct spdk_blob *blob; 1867 spdk_blob_id blobid; 1868 uint32_t page_num; 1869 int index; 1870 struct spdk_blob_md_page *page; 1871 1872 dev = init_dev(); 1873 1874 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1875 CU_ASSERT(g_bserrno == 0); 1876 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1877 bs = g_bs; 1878 1879 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1880 CU_ASSERT(g_bserrno == 0); 1881 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1882 blobid = g_blobid; 1883 1884 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1885 CU_ASSERT(g_bserrno == 0); 1886 CU_ASSERT(g_blob != NULL); 1887 blob = g_blob; 1888 1889 spdk_blob_close(blob, blob_op_complete, NULL); 1890 CU_ASSERT(g_bserrno == 0); 1891 1892 page_num = _spdk_bs_blobid_to_page(blobid); 1893 index = DEV_BUFFER_BLOCKLEN * (bs->md_start + page_num); 1894 page = (struct spdk_blob_md_page *)&g_dev_buffer[index]; 1895 page->crc = 0; 1896 1897 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1898 CU_ASSERT(g_bserrno == -EINVAL); 1899 CU_ASSERT(g_blob == NULL); 1900 g_bserrno = 0; 1901 1902 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 1903 CU_ASSERT(g_bserrno == -EINVAL); 1904 1905 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1906 CU_ASSERT(g_bserrno == 0); 1907 g_bs = NULL; 1908 } 1909 1910 static void 1911 super_block_crc(void) 1912 { 1913 struct spdk_bs_dev *dev; 1914 struct spdk_bs_super_block *super_block; 1915 struct spdk_bs_opts opts; 1916 1917 dev = init_dev(); 1918 spdk_bs_opts_init(&opts); 1919 1920 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1921 CU_ASSERT(g_bserrno == 0); 1922 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1923 1924 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1925 CU_ASSERT(g_bserrno == 0); 1926 g_bs = NULL; 1927 1928 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 1929 super_block->crc = 0; 1930 dev = init_dev(); 1931 1932 g_scheduler_delay = true; 1933 /* Load an existing blob store */ 1934 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1935 1936 CU_ASSERT(g_bserrno == -EILSEQ); 1937 _bs_flush_scheduler(); 1938 CU_ASSERT(TAILQ_EMPTY(&g_scheduled_ops)); 1939 1940 g_scheduler_delay = false; 1941 } 1942 1943 /* For blob dirty shutdown test case we do the following sub-test cases: 1944 * 1 Initialize new blob store and create 1 blob with some xattrs, then we 1945 * dirty shutdown and reload the blob store and verify the xattrs. 1946 * 2 Resize the blob from 10 clusters to 20 clusters and then dirty shutdown, 1947 * reload the blob store and verify the clusters number. 1948 * 3 Create the second blob and then dirty shutdown, reload the blob store 1949 * and verify the second blob. 1950 * 4 Delete the second blob and then dirty shutdown, reload teh blob store 1951 * and verify the second blob is invalid. 1952 * 5 Create the second blob again and also create the third blob, modify the 1953 * md of second blob which makes the md invalid, and then dirty shutdown, 1954 * reload the blob store verify the second blob, it should invalid and also 1955 * verify the third blob, it should correct. 1956 */ 1957 static void 1958 blob_dirty_shutdown(void) 1959 { 1960 int rc; 1961 int index; 1962 struct spdk_bs_dev *dev; 1963 spdk_blob_id blobid1, blobid2, blobid3; 1964 struct spdk_blob *blob; 1965 uint64_t length; 1966 uint64_t free_clusters; 1967 const void *value; 1968 size_t value_len; 1969 uint32_t page_num; 1970 struct spdk_blob_md_page *page; 1971 struct spdk_bs_opts opts; 1972 1973 dev = init_dev(); 1974 spdk_bs_opts_init(&opts); 1975 /* Initialize a new blob store */ 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 1980 /* Create first blob */ 1981 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 1982 CU_ASSERT(g_bserrno == 0); 1983 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1984 blobid1 = g_blobid; 1985 1986 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 1987 CU_ASSERT(g_bserrno == 0); 1988 CU_ASSERT(g_blob != NULL); 1989 blob = g_blob; 1990 1991 /* Set some xattrs */ 1992 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 1993 CU_ASSERT(rc == 0); 1994 1995 length = 2345; 1996 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 1997 CU_ASSERT(rc == 0); 1998 1999 /* Resize the blob */ 2000 rc = spdk_blob_resize(blob, 10); 2001 CU_ASSERT(rc == 0); 2002 2003 free_clusters = spdk_bs_free_cluster_count(g_bs); 2004 2005 spdk_blob_close(blob, blob_op_complete, NULL); 2006 blob = NULL; 2007 g_blob = NULL; 2008 g_blobid = SPDK_BLOBID_INVALID; 2009 2010 /* Dirty shutdown */ 2011 _spdk_bs_free(g_bs); 2012 2013 /* reload blobstore */ 2014 dev = init_dev(); 2015 spdk_bs_opts_init(&opts); 2016 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2017 CU_ASSERT(g_bserrno == 0); 2018 2019 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 2020 CU_ASSERT(g_bserrno == 0); 2021 CU_ASSERT(g_blob != NULL); 2022 blob = g_blob; 2023 2024 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 2025 2026 /* Get the xattrs */ 2027 value = NULL; 2028 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 2029 CU_ASSERT(rc == 0); 2030 SPDK_CU_ASSERT_FATAL(value != NULL); 2031 CU_ASSERT(*(uint64_t *)value == length); 2032 CU_ASSERT(value_len == 8); 2033 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 2034 2035 /* Resize the blob */ 2036 rc = spdk_blob_resize(blob, 20); 2037 CU_ASSERT(rc == 0); 2038 2039 free_clusters = spdk_bs_free_cluster_count(g_bs); 2040 2041 spdk_blob_close(blob, blob_op_complete, NULL); 2042 CU_ASSERT(g_bserrno == 0); 2043 blob = NULL; 2044 g_blob = NULL; 2045 g_blobid = SPDK_BLOBID_INVALID; 2046 2047 /* Dirty shutdown */ 2048 _spdk_bs_free(g_bs); 2049 2050 /* reload the blobstore */ 2051 dev = init_dev(); 2052 spdk_bs_opts_init(&opts); 2053 /* Load an existing blob store */ 2054 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2055 CU_ASSERT(g_bserrno == 0); 2056 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2057 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 2058 CU_ASSERT(g_bserrno == 0); 2059 CU_ASSERT(g_blob != NULL); 2060 blob = g_blob; 2061 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 20); 2062 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 2063 2064 spdk_blob_close(blob, blob_op_complete, NULL); 2065 CU_ASSERT(g_bserrno == 0); 2066 blob = NULL; 2067 g_blob = NULL; 2068 g_blobid = SPDK_BLOBID_INVALID; 2069 2070 /* Create second blob */ 2071 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2072 CU_ASSERT(g_bserrno == 0); 2073 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2074 blobid2 = g_blobid; 2075 2076 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 2077 CU_ASSERT(g_bserrno == 0); 2078 CU_ASSERT(g_blob != NULL); 2079 blob = g_blob; 2080 2081 /* Set some xattrs */ 2082 rc = spdk_blob_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1); 2083 CU_ASSERT(rc == 0); 2084 2085 length = 5432; 2086 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 2087 CU_ASSERT(rc == 0); 2088 2089 /* Resize the blob */ 2090 rc = spdk_blob_resize(blob, 10); 2091 CU_ASSERT(rc == 0); 2092 2093 free_clusters = spdk_bs_free_cluster_count(g_bs); 2094 2095 spdk_blob_close(blob, blob_op_complete, NULL); 2096 blob = NULL; 2097 g_blob = NULL; 2098 g_blobid = SPDK_BLOBID_INVALID; 2099 2100 /* Dirty shutdown */ 2101 _spdk_bs_free(g_bs); 2102 2103 /* reload the blobstore */ 2104 dev = init_dev(); 2105 spdk_bs_opts_init(&opts); 2106 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2107 CU_ASSERT(g_bserrno == 0); 2108 2109 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 2110 CU_ASSERT(g_bserrno == 0); 2111 CU_ASSERT(g_blob != NULL); 2112 blob = g_blob; 2113 2114 /* Get the xattrs */ 2115 value = NULL; 2116 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 2117 CU_ASSERT(rc == 0); 2118 SPDK_CU_ASSERT_FATAL(value != NULL); 2119 CU_ASSERT(*(uint64_t *)value == length); 2120 CU_ASSERT(value_len == 8); 2121 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 2122 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 2123 2124 spdk_blob_close(blob, blob_op_complete, NULL); 2125 CU_ASSERT(g_bserrno == 0); 2126 spdk_bs_delete_blob(g_bs, blobid2, blob_op_complete, NULL); 2127 CU_ASSERT(g_bserrno == 0); 2128 2129 free_clusters = spdk_bs_free_cluster_count(g_bs); 2130 2131 /* Dirty shutdown */ 2132 _spdk_bs_free(g_bs); 2133 /* reload the blobstore */ 2134 dev = init_dev(); 2135 spdk_bs_opts_init(&opts); 2136 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2137 CU_ASSERT(g_bserrno == 0); 2138 2139 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 2140 CU_ASSERT(g_bserrno != 0); 2141 CU_ASSERT(g_blob == NULL); 2142 2143 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 2144 CU_ASSERT(g_bserrno == 0); 2145 CU_ASSERT(g_blob != NULL); 2146 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 2147 spdk_blob_close(g_blob, blob_op_complete, NULL); 2148 CU_ASSERT(g_bserrno == 0); 2149 2150 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2151 CU_ASSERT(g_bserrno == 0); 2152 g_bs = NULL; 2153 2154 /* reload the blobstore */ 2155 dev = init_dev(); 2156 spdk_bs_opts_init(&opts); 2157 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2158 CU_ASSERT(g_bserrno == 0); 2159 2160 /* Create second blob */ 2161 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2162 CU_ASSERT(g_bserrno == 0); 2163 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2164 blobid2 = g_blobid; 2165 2166 /* Create third blob */ 2167 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2168 CU_ASSERT(g_bserrno == 0); 2169 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2170 blobid3 = g_blobid; 2171 2172 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 2173 CU_ASSERT(g_bserrno == 0); 2174 CU_ASSERT(g_blob != NULL); 2175 blob = g_blob; 2176 2177 /* Set some xattrs for second blob */ 2178 rc = spdk_blob_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1); 2179 CU_ASSERT(rc == 0); 2180 2181 length = 5432; 2182 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 2183 CU_ASSERT(rc == 0); 2184 2185 spdk_blob_close(blob, blob_op_complete, NULL); 2186 blob = NULL; 2187 g_blob = NULL; 2188 g_blobid = SPDK_BLOBID_INVALID; 2189 2190 spdk_bs_open_blob(g_bs, blobid3, blob_op_with_handle_complete, NULL); 2191 CU_ASSERT(g_bserrno == 0); 2192 CU_ASSERT(g_blob != NULL); 2193 blob = g_blob; 2194 2195 /* Set some xattrs for third blob */ 2196 rc = spdk_blob_set_xattr(blob, "name", "log2.txt", strlen("log2.txt") + 1); 2197 CU_ASSERT(rc == 0); 2198 2199 length = 5432; 2200 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 2201 CU_ASSERT(rc == 0); 2202 2203 spdk_blob_close(blob, blob_op_complete, NULL); 2204 blob = NULL; 2205 g_blob = NULL; 2206 g_blobid = SPDK_BLOBID_INVALID; 2207 2208 /* Mark second blob as invalid */ 2209 page_num = _spdk_bs_blobid_to_page(blobid2); 2210 2211 index = DEV_BUFFER_BLOCKLEN * (g_bs->md_start + page_num); 2212 page = (struct spdk_blob_md_page *)&g_dev_buffer[index]; 2213 page->sequence_num = 1; 2214 page->crc = _spdk_blob_md_page_calc_crc(page); 2215 2216 free_clusters = spdk_bs_free_cluster_count(g_bs); 2217 2218 /* Dirty shutdown */ 2219 _spdk_bs_free(g_bs); 2220 /* reload the blobstore */ 2221 dev = init_dev(); 2222 spdk_bs_opts_init(&opts); 2223 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2224 CU_ASSERT(g_bserrno == 0); 2225 2226 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 2227 CU_ASSERT(g_bserrno != 0); 2228 CU_ASSERT(g_blob == NULL); 2229 2230 spdk_bs_open_blob(g_bs, blobid3, blob_op_with_handle_complete, NULL); 2231 CU_ASSERT(g_bserrno == 0); 2232 CU_ASSERT(g_blob != NULL); 2233 blob = g_blob; 2234 2235 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 2236 2237 spdk_blob_close(blob, blob_op_complete, NULL); 2238 blob = NULL; 2239 g_blob = NULL; 2240 g_blobid = SPDK_BLOBID_INVALID; 2241 2242 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2243 CU_ASSERT(g_bserrno == 0); 2244 g_bs = NULL; 2245 } 2246 2247 static void 2248 blob_flags(void) 2249 { 2250 struct spdk_bs_dev *dev; 2251 spdk_blob_id blobid_invalid, blobid_data_ro, blobid_md_ro; 2252 struct spdk_blob *blob_invalid, *blob_data_ro, *blob_md_ro; 2253 struct spdk_bs_opts opts; 2254 int rc; 2255 2256 dev = init_dev(); 2257 spdk_bs_opts_init(&opts); 2258 2259 /* Initialize a new blob store */ 2260 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2261 CU_ASSERT(g_bserrno == 0); 2262 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2263 2264 /* Create three blobs - one each for testing invalid, data_ro and md_ro flags. */ 2265 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2266 CU_ASSERT(g_bserrno == 0); 2267 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2268 blobid_invalid = g_blobid; 2269 2270 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2271 CU_ASSERT(g_bserrno == 0); 2272 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2273 blobid_data_ro = g_blobid; 2274 2275 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2276 CU_ASSERT(g_bserrno == 0); 2277 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2278 blobid_md_ro = g_blobid; 2279 2280 spdk_bs_open_blob(g_bs, blobid_invalid, blob_op_with_handle_complete, NULL); 2281 CU_ASSERT(g_bserrno == 0); 2282 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2283 blob_invalid = g_blob; 2284 2285 spdk_bs_open_blob(g_bs, blobid_data_ro, blob_op_with_handle_complete, NULL); 2286 CU_ASSERT(g_bserrno == 0); 2287 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2288 blob_data_ro = g_blob; 2289 2290 spdk_bs_open_blob(g_bs, blobid_md_ro, blob_op_with_handle_complete, NULL); 2291 CU_ASSERT(g_bserrno == 0); 2292 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2293 blob_md_ro = g_blob; 2294 2295 /* Change the size of blob_data_ro to check if flags are serialized 2296 * when blob has non zero number of extents */ 2297 rc = spdk_blob_resize(blob_data_ro, 10); 2298 CU_ASSERT(rc == 0); 2299 2300 /* Set the xattr to check if flags are serialized 2301 * when blob has non zero number of xattrs */ 2302 rc = spdk_blob_set_xattr(blob_md_ro, "name", "log.txt", strlen("log.txt") + 1); 2303 CU_ASSERT(rc == 0); 2304 2305 __blob_to_data(blob_invalid)->invalid_flags = (1ULL << 63); 2306 __blob_to_data(blob_invalid)->state = SPDK_BLOB_STATE_DIRTY; 2307 __blob_to_data(blob_data_ro)->data_ro_flags = (1ULL << 62); 2308 __blob_to_data(blob_data_ro)->state = SPDK_BLOB_STATE_DIRTY; 2309 __blob_to_data(blob_md_ro)->md_ro_flags = (1ULL << 61); 2310 __blob_to_data(blob_md_ro)->state = SPDK_BLOB_STATE_DIRTY; 2311 2312 g_bserrno = -1; 2313 spdk_blob_sync_md(blob_invalid, blob_op_complete, NULL); 2314 CU_ASSERT(g_bserrno == 0); 2315 g_bserrno = -1; 2316 spdk_blob_sync_md(blob_data_ro, blob_op_complete, NULL); 2317 CU_ASSERT(g_bserrno == 0); 2318 g_bserrno = -1; 2319 spdk_blob_sync_md(blob_md_ro, blob_op_complete, NULL); 2320 CU_ASSERT(g_bserrno == 0); 2321 2322 g_bserrno = -1; 2323 spdk_blob_close(blob_invalid, blob_op_complete, NULL); 2324 CU_ASSERT(g_bserrno == 0); 2325 blob_invalid = NULL; 2326 g_bserrno = -1; 2327 spdk_blob_close(blob_data_ro, blob_op_complete, NULL); 2328 CU_ASSERT(g_bserrno == 0); 2329 blob_data_ro = NULL; 2330 g_bserrno = -1; 2331 spdk_blob_close(blob_md_ro, blob_op_complete, NULL); 2332 CU_ASSERT(g_bserrno == 0); 2333 blob_md_ro = NULL; 2334 2335 g_blob = NULL; 2336 g_blobid = SPDK_BLOBID_INVALID; 2337 2338 /* Unload the blob store */ 2339 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2340 CU_ASSERT(g_bserrno == 0); 2341 g_bs = NULL; 2342 2343 /* Load an existing blob store */ 2344 dev = init_dev(); 2345 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2346 CU_ASSERT(g_bserrno == 0); 2347 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2348 2349 g_blob = NULL; 2350 g_bserrno = 0; 2351 spdk_bs_open_blob(g_bs, blobid_invalid, blob_op_with_handle_complete, NULL); 2352 CU_ASSERT(g_bserrno != 0); 2353 CU_ASSERT(g_blob == NULL); 2354 2355 g_blob = NULL; 2356 g_bserrno = -1; 2357 spdk_bs_open_blob(g_bs, blobid_data_ro, blob_op_with_handle_complete, NULL); 2358 CU_ASSERT(g_bserrno == 0); 2359 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2360 blob_data_ro = g_blob; 2361 /* If an unknown data_ro flag was found, the blob should be marked both data and md read-only. */ 2362 CU_ASSERT(__blob_to_data(blob_data_ro)->data_ro == true); 2363 CU_ASSERT(__blob_to_data(blob_data_ro)->md_ro == true); 2364 CU_ASSERT(spdk_blob_get_num_clusters(blob_data_ro) == 10); 2365 2366 g_blob = NULL; 2367 g_bserrno = -1; 2368 spdk_bs_open_blob(g_bs, blobid_md_ro, blob_op_with_handle_complete, NULL); 2369 CU_ASSERT(g_bserrno == 0); 2370 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2371 blob_md_ro = g_blob; 2372 CU_ASSERT(__blob_to_data(blob_md_ro)->data_ro == false); 2373 CU_ASSERT(__blob_to_data(blob_md_ro)->md_ro == true); 2374 2375 g_bserrno = -1; 2376 spdk_blob_sync_md(blob_md_ro, blob_op_complete, NULL); 2377 CU_ASSERT(g_bserrno == 0); 2378 2379 spdk_blob_close(blob_data_ro, blob_op_complete, NULL); 2380 CU_ASSERT(g_bserrno == 0); 2381 spdk_blob_close(blob_md_ro, blob_op_complete, NULL); 2382 CU_ASSERT(g_bserrno == 0); 2383 2384 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2385 CU_ASSERT(g_bserrno == 0); 2386 } 2387 2388 static void 2389 bs_version(void) 2390 { 2391 struct spdk_bs_super_block *super; 2392 struct spdk_bs_dev *dev; 2393 struct spdk_bs_opts opts; 2394 spdk_blob_id blobid; 2395 2396 dev = init_dev(); 2397 spdk_bs_opts_init(&opts); 2398 2399 /* Initialize a new blob store */ 2400 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2401 CU_ASSERT(g_bserrno == 0); 2402 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2403 2404 /* Unload the blob store */ 2405 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2406 CU_ASSERT(g_bserrno == 0); 2407 g_bs = NULL; 2408 2409 /* 2410 * Change the bs version on disk. This will allow us to 2411 * test that the version does not get modified automatically 2412 * when loading and unloading the blobstore. 2413 */ 2414 super = (struct spdk_bs_super_block *)&g_dev_buffer[0]; 2415 CU_ASSERT(super->version == SPDK_BS_VERSION); 2416 CU_ASSERT(super->clean == 1); 2417 super->version = 2; 2418 /* 2419 * Version 2 metadata does not have a used blobid mask, so clear 2420 * those fields in the super block and zero the corresponding 2421 * region on "disk". We will use this to ensure blob IDs are 2422 * correctly reconstructed. 2423 */ 2424 memset(&g_dev_buffer[super->used_blobid_mask_start * SPDK_BS_PAGE_SIZE], 0, 2425 super->used_blobid_mask_len * SPDK_BS_PAGE_SIZE); 2426 super->used_blobid_mask_start = 0; 2427 super->used_blobid_mask_len = 0; 2428 super->crc = _spdk_blob_md_page_calc_crc(super); 2429 2430 /* Load an existing blob store */ 2431 dev = init_dev(); 2432 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2433 CU_ASSERT(g_bserrno == 0); 2434 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2435 CU_ASSERT(super->clean == 0); 2436 2437 /* 2438 * Create a blob - just to make sure that when we unload it 2439 * results in writing the super block (since metadata pages 2440 * were allocated. 2441 */ 2442 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2443 CU_ASSERT(g_bserrno == 0); 2444 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2445 blobid = g_blobid; 2446 2447 /* Unload the blob store */ 2448 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2449 CU_ASSERT(g_bserrno == 0); 2450 g_bs = NULL; 2451 CU_ASSERT(super->version == 2); 2452 CU_ASSERT(super->used_blobid_mask_start == 0); 2453 CU_ASSERT(super->used_blobid_mask_len == 0); 2454 2455 dev = init_dev(); 2456 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2457 CU_ASSERT(g_bserrno == 0); 2458 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2459 2460 g_blob = NULL; 2461 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 2462 CU_ASSERT(g_bserrno == 0); 2463 CU_ASSERT(g_blob != NULL); 2464 2465 spdk_blob_close(g_blob, blob_op_complete, NULL); 2466 CU_ASSERT(g_bserrno == 0); 2467 2468 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2469 CU_ASSERT(g_bserrno == 0); 2470 g_bs = NULL; 2471 CU_ASSERT(super->version == 2); 2472 CU_ASSERT(super->used_blobid_mask_start == 0); 2473 CU_ASSERT(super->used_blobid_mask_len == 0); 2474 } 2475 2476 static void 2477 _get_xattr_value(void *arg, const char *name, 2478 const void **value, size_t *value_len) 2479 { 2480 uint64_t i; 2481 2482 SPDK_CU_ASSERT_FATAL(value_len != NULL); 2483 SPDK_CU_ASSERT_FATAL(value != NULL); 2484 CU_ASSERT(arg == &g_ctx) 2485 2486 for (i = 0; i < sizeof(g_xattr_names); i++) { 2487 if (!strcmp(name, g_xattr_names[i])) { 2488 *value_len = strlen(g_xattr_values[i]); 2489 *value = g_xattr_values[i]; 2490 break; 2491 } 2492 } 2493 } 2494 2495 static void 2496 _get_xattr_value_null(void *arg, const char *name, 2497 const void **value, size_t *value_len) 2498 { 2499 SPDK_CU_ASSERT_FATAL(value_len != NULL); 2500 SPDK_CU_ASSERT_FATAL(value != NULL); 2501 CU_ASSERT(arg == NULL) 2502 2503 *value_len = 0; 2504 *value = NULL; 2505 } 2506 2507 static void 2508 blob_set_xattrs(void) 2509 { 2510 struct spdk_blob_store *bs; 2511 struct spdk_bs_dev *dev; 2512 struct spdk_blob *blob; 2513 struct spdk_blob_opts opts; 2514 spdk_blob_id blobid; 2515 const void *value; 2516 size_t value_len; 2517 int rc; 2518 2519 dev = init_dev(); 2520 2521 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2522 CU_ASSERT(g_bserrno == 0); 2523 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2524 bs = g_bs; 2525 2526 /* Create blob with extra attributes */ 2527 spdk_blob_opts_init(&opts); 2528 2529 opts.xattr_names = g_xattr_names; 2530 opts.get_xattr_value = _get_xattr_value; 2531 opts.xattr_count = 3; 2532 opts.xattr_ctx = &g_ctx; 2533 2534 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 2535 CU_ASSERT(g_bserrno == 0); 2536 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2537 blobid = g_blobid; 2538 2539 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2540 CU_ASSERT(g_bserrno == 0); 2541 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2542 blob = g_blob; 2543 2544 /* Get the xattrs */ 2545 value = NULL; 2546 2547 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[0], &value, &value_len); 2548 CU_ASSERT(rc == 0); 2549 SPDK_CU_ASSERT_FATAL(value != NULL); 2550 CU_ASSERT(value_len == strlen(g_xattr_values[0])); 2551 CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len); 2552 2553 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[1], &value, &value_len); 2554 CU_ASSERT(rc == 0); 2555 SPDK_CU_ASSERT_FATAL(value != NULL); 2556 CU_ASSERT(value_len == strlen(g_xattr_values[1])); 2557 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len); 2558 2559 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[2], &value, &value_len); 2560 CU_ASSERT(rc == 0); 2561 SPDK_CU_ASSERT_FATAL(value != NULL); 2562 CU_ASSERT(value_len == strlen(g_xattr_values[2])); 2563 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len); 2564 2565 /* Try to get non existing attribute */ 2566 2567 rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len); 2568 CU_ASSERT(rc == -ENOENT); 2569 2570 spdk_blob_close(blob, blob_op_complete, NULL); 2571 CU_ASSERT(g_bserrno == 0); 2572 blob = NULL; 2573 g_blob = NULL; 2574 g_blobid = SPDK_BLOBID_INVALID; 2575 2576 /* NULL callback */ 2577 spdk_blob_opts_init(&opts); 2578 opts.xattr_names = g_xattr_names; 2579 opts.get_xattr_value = NULL; 2580 opts.xattr_count = 1; 2581 opts.xattr_ctx = &g_ctx; 2582 2583 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 2584 CU_ASSERT(g_bserrno == -EINVAL); 2585 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2586 2587 /* NULL values */ 2588 spdk_blob_opts_init(&opts); 2589 opts.xattr_names = g_xattr_names; 2590 opts.get_xattr_value = _get_xattr_value_null; 2591 opts.xattr_count = 1; 2592 opts.xattr_ctx = NULL; 2593 2594 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 2595 CU_ASSERT(g_bserrno == -EINVAL); 2596 2597 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2598 CU_ASSERT(g_bserrno == 0); 2599 g_bs = NULL; 2600 2601 } 2602 2603 static void 2604 blob_thin_prov_alloc(void) 2605 { 2606 struct spdk_blob_store *bs; 2607 struct spdk_bs_dev *dev; 2608 struct spdk_blob *blob; 2609 struct spdk_blob_data *blob_data; 2610 struct spdk_blob_opts opts; 2611 spdk_blob_id blobid; 2612 uint64_t free_clusters; 2613 int rc; 2614 2615 dev = init_dev(); 2616 2617 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2618 CU_ASSERT(g_bserrno == 0); 2619 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2620 bs = g_bs; 2621 free_clusters = spdk_bs_free_cluster_count(bs); 2622 2623 /* Set blob as thin provisioned */ 2624 spdk_blob_opts_init(&opts); 2625 opts.thin_provision = true; 2626 2627 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 2628 CU_ASSERT(g_bserrno == 0); 2629 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2630 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 2631 blobid = g_blobid; 2632 2633 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2634 CU_ASSERT(g_bserrno == 0); 2635 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2636 blob = g_blob; 2637 blob_data = __blob_to_data(blob); 2638 2639 CU_ASSERT(blob_data->active.num_clusters == 0); 2640 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0); 2641 2642 /* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */ 2643 rc = spdk_blob_resize(blob, 5); 2644 CU_ASSERT(rc == 0); 2645 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 2646 CU_ASSERT(blob_data->active.num_clusters == 5); 2647 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 2648 2649 /* Shrink the blob to 3 clusters - still unallocated */ 2650 rc = spdk_blob_resize(blob, 3); 2651 CU_ASSERT(rc == 0); 2652 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 2653 CU_ASSERT(blob_data->active.num_clusters == 3); 2654 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 3); 2655 2656 spdk_blob_sync_md(blob, blob_op_complete, NULL); 2657 CU_ASSERT(g_bserrno == 0); 2658 /* Sync must not change anything */ 2659 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 2660 CU_ASSERT(blob_data->active.num_clusters == 3); 2661 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 3); 2662 2663 spdk_blob_close(blob, blob_op_complete, NULL); 2664 CU_ASSERT(g_bserrno == 0); 2665 2666 /* Unload the blob store */ 2667 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2668 CU_ASSERT(g_bserrno == 0); 2669 g_bs = NULL; 2670 g_blob = NULL; 2671 g_blobid = 0; 2672 2673 /* Load an existing blob store */ 2674 dev = init_dev(); 2675 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 2676 CU_ASSERT(g_bserrno == 0); 2677 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2678 2679 bs = g_bs; 2680 2681 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 2682 CU_ASSERT(g_bserrno == 0); 2683 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2684 blob = g_blob; 2685 blob_data = __blob_to_data(blob); 2686 2687 /* Check that clusters allocation and size is still the same */ 2688 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 2689 CU_ASSERT(blob_data->active.num_clusters == 3); 2690 2691 spdk_blob_close(blob, blob_op_complete, NULL); 2692 CU_ASSERT(g_bserrno == 0); 2693 2694 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 2695 CU_ASSERT(g_bserrno == 0); 2696 2697 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2698 CU_ASSERT(g_bserrno == 0); 2699 g_bs = NULL; 2700 } 2701 2702 static void 2703 blob_insert_cluster_msg(void) 2704 { 2705 struct spdk_blob_store *bs; 2706 struct spdk_bs_dev *dev; 2707 struct spdk_blob *blob; 2708 struct spdk_blob_data *blob_data; 2709 struct spdk_blob_opts opts; 2710 spdk_blob_id blobid; 2711 uint64_t free_clusters; 2712 2713 dev = init_dev(); 2714 2715 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2716 CU_ASSERT(g_bserrno == 0); 2717 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2718 bs = g_bs; 2719 free_clusters = spdk_bs_free_cluster_count(bs); 2720 2721 /* Set blob as thin provisioned */ 2722 spdk_blob_opts_init(&opts); 2723 opts.thin_provision = true; 2724 opts.num_clusters = 4; 2725 2726 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 2727 CU_ASSERT(g_bserrno == 0); 2728 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2729 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 2730 blobid = g_blobid; 2731 2732 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2733 CU_ASSERT(g_bserrno == 0); 2734 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2735 blob = g_blob; 2736 blob_data = __blob_to_data(blob); 2737 2738 CU_ASSERT(blob_data->active.num_clusters == 4); 2739 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 4); 2740 CU_ASSERT(blob_data->active.clusters[1] == 0); 2741 2742 _spdk_bs_claim_cluster(bs, 0xF); 2743 _spdk_blob_insert_cluster_on_md_thread(blob_data, 1, 0xF, blob_op_complete, NULL); 2744 2745 CU_ASSERT(blob_data->active.clusters[1] != 0); 2746 2747 spdk_blob_close(blob, blob_op_complete, NULL); 2748 CU_ASSERT(g_bserrno == 0); 2749 2750 /* Unload the blob store */ 2751 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2752 CU_ASSERT(g_bserrno == 0); 2753 g_bs = NULL; 2754 g_blob = NULL; 2755 g_blobid = 0; 2756 2757 /* Load an existing blob store */ 2758 dev = init_dev(); 2759 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 2760 CU_ASSERT(g_bserrno == 0); 2761 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2762 2763 bs = g_bs; 2764 2765 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 2766 CU_ASSERT(g_bserrno == 0); 2767 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2768 blob = g_blob; 2769 blob_data = __blob_to_data(blob); 2770 2771 CU_ASSERT(blob_data->active.clusters[1] != 0); 2772 2773 spdk_blob_close(blob, blob_op_complete, NULL); 2774 CU_ASSERT(g_bserrno == 0); 2775 2776 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 2777 CU_ASSERT(g_bserrno == 0); 2778 2779 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2780 CU_ASSERT(g_bserrno == 0); 2781 g_bs = NULL; 2782 } 2783 2784 static void 2785 blob_thin_prov_rw(void) 2786 { 2787 static const uint8_t zero[10 * 4096] = { 0 }; 2788 struct spdk_blob_store *bs; 2789 struct spdk_bs_dev *dev; 2790 struct spdk_blob *blob; 2791 struct spdk_blob_data *blob_data; 2792 struct spdk_io_channel *channel; 2793 struct spdk_blob_opts opts; 2794 spdk_blob_id blobid; 2795 uint64_t free_clusters; 2796 uint8_t payload_read[10 * 4096]; 2797 uint8_t payload_write[10 * 4096]; 2798 int rc; 2799 2800 dev = init_dev(); 2801 2802 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2803 CU_ASSERT(g_bserrno == 0); 2804 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2805 bs = g_bs; 2806 free_clusters = spdk_bs_free_cluster_count(bs); 2807 2808 channel = spdk_bs_alloc_io_channel(bs); 2809 CU_ASSERT(channel != NULL); 2810 2811 spdk_blob_opts_init(&opts); 2812 opts.thin_provision = true; 2813 2814 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 2815 CU_ASSERT(g_bserrno == 0); 2816 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2817 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 2818 blobid = g_blobid; 2819 2820 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2821 CU_ASSERT(g_bserrno == 0); 2822 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2823 blob = g_blob; 2824 blob_data = __blob_to_data(blob); 2825 2826 CU_ASSERT(blob_data->active.num_clusters == 0); 2827 2828 /* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */ 2829 rc = spdk_blob_resize(blob, 5); 2830 CU_ASSERT(rc == 0); 2831 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 2832 CU_ASSERT(blob_data->active.num_clusters == 5); 2833 2834 spdk_blob_sync_md(blob, blob_op_complete, NULL); 2835 CU_ASSERT(g_bserrno == 0); 2836 /* Sync must not change anything */ 2837 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 2838 CU_ASSERT(blob_data->active.num_clusters == 5); 2839 2840 /* Payload should be all zeros from unallocated clusters */ 2841 memset(payload_read, 0xFF, sizeof(payload_read)); 2842 spdk_bs_io_read_blob(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 2843 CU_ASSERT(g_bserrno == 0); 2844 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 2845 2846 memset(payload_write, 0xE5, sizeof(payload_write)); 2847 spdk_bs_io_write_blob(blob, channel, payload_write, 4, 10, blob_op_complete, NULL); 2848 CU_ASSERT(g_bserrno == 0); 2849 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 2850 2851 spdk_bs_io_read_blob(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 2852 CU_ASSERT(g_bserrno == 0); 2853 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 2854 2855 spdk_blob_close(blob, blob_op_complete, NULL); 2856 CU_ASSERT(g_bserrno == 0); 2857 2858 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 2859 CU_ASSERT(g_bserrno == 0); 2860 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 2861 2862 spdk_bs_free_io_channel(channel); 2863 2864 /* Unload the blob store */ 2865 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2866 CU_ASSERT(g_bserrno == 0); 2867 g_bs = NULL; 2868 g_blob = NULL; 2869 g_blobid = 0; 2870 } 2871 2872 static void 2873 blob_thin_prov_rw_iov(void) 2874 { 2875 static const uint8_t zero[10 * 4096] = { 0 }; 2876 struct spdk_blob_store *bs; 2877 struct spdk_bs_dev *dev; 2878 struct spdk_blob *blob; 2879 struct spdk_blob_data *blob_data; 2880 struct spdk_io_channel *channel; 2881 struct spdk_blob_opts opts; 2882 spdk_blob_id blobid; 2883 uint64_t free_clusters; 2884 uint8_t payload_read[10 * 4096]; 2885 uint8_t payload_write[10 * 4096]; 2886 struct iovec iov_read[3]; 2887 struct iovec iov_write[3]; 2888 2889 int rc; 2890 2891 dev = init_dev(); 2892 2893 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2894 CU_ASSERT(g_bserrno == 0); 2895 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2896 bs = g_bs; 2897 free_clusters = spdk_bs_free_cluster_count(bs); 2898 2899 channel = spdk_bs_alloc_io_channel(bs); 2900 CU_ASSERT(channel != NULL); 2901 2902 spdk_blob_opts_init(&opts); 2903 opts.thin_provision = true; 2904 2905 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 2906 CU_ASSERT(g_bserrno == 0); 2907 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2908 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 2909 blobid = g_blobid; 2910 2911 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2912 CU_ASSERT(g_bserrno == 0); 2913 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2914 blob = g_blob; 2915 blob_data = __blob_to_data(blob); 2916 2917 CU_ASSERT(blob_data->active.num_clusters == 0); 2918 2919 /* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */ 2920 rc = spdk_blob_resize(blob, 5); 2921 CU_ASSERT(rc == 0); 2922 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 2923 CU_ASSERT(blob_data->active.num_clusters == 5); 2924 2925 spdk_blob_sync_md(blob, blob_op_complete, NULL); 2926 CU_ASSERT(g_bserrno == 0); 2927 /* Sync must not change anything */ 2928 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 2929 CU_ASSERT(blob_data->active.num_clusters == 5); 2930 2931 /* Payload should be all zeros from unallocated clusters */ 2932 memset(payload_read, 0xAA, sizeof(payload_read)); 2933 iov_read[0].iov_base = payload_read; 2934 iov_read[0].iov_len = 3 * 4096; 2935 iov_read[1].iov_base = payload_read + 3 * 4096; 2936 iov_read[1].iov_len = 4 * 4096; 2937 iov_read[2].iov_base = payload_read + 7 * 4096; 2938 iov_read[2].iov_len = 3 * 4096; 2939 spdk_bs_io_readv_blob(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 2940 CU_ASSERT(g_bserrno == 0); 2941 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 2942 2943 memset(payload_write, 0xE5, sizeof(payload_write)); 2944 iov_write[0].iov_base = payload_write; 2945 iov_write[0].iov_len = 1 * 4096; 2946 iov_write[1].iov_base = payload_write + 1 * 4096; 2947 iov_write[1].iov_len = 5 * 4096; 2948 iov_write[2].iov_base = payload_write + 6 * 4096; 2949 iov_write[2].iov_len = 4 * 4096; 2950 2951 spdk_bs_io_writev_blob(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 2952 CU_ASSERT(g_bserrno == 0); 2953 2954 memset(payload_read, 0xAA, sizeof(payload_read)); 2955 iov_read[0].iov_base = payload_read; 2956 iov_read[0].iov_len = 3 * 4096; 2957 iov_read[1].iov_base = payload_read + 3 * 4096; 2958 iov_read[1].iov_len = 4 * 4096; 2959 iov_read[2].iov_base = payload_read + 7 * 4096; 2960 iov_read[2].iov_len = 3 * 4096; 2961 spdk_bs_io_readv_blob(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 2962 CU_ASSERT(g_bserrno == 0); 2963 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 2964 2965 spdk_blob_close(blob, blob_op_complete, NULL); 2966 CU_ASSERT(g_bserrno == 0); 2967 2968 spdk_bs_free_io_channel(channel); 2969 2970 /* Unload the blob store */ 2971 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2972 CU_ASSERT(g_bserrno == 0); 2973 g_bs = NULL; 2974 g_blob = NULL; 2975 g_blobid = 0; 2976 } 2977 2978 int main(int argc, char **argv) 2979 { 2980 CU_pSuite suite = NULL; 2981 unsigned int num_failures; 2982 2983 if (CU_initialize_registry() != CUE_SUCCESS) { 2984 return CU_get_error(); 2985 } 2986 2987 suite = CU_add_suite("blob", NULL, NULL); 2988 if (suite == NULL) { 2989 CU_cleanup_registry(); 2990 return CU_get_error(); 2991 } 2992 2993 if ( 2994 CU_add_test(suite, "blob_init", blob_init) == NULL || 2995 CU_add_test(suite, "blob_open", blob_open) == NULL || 2996 CU_add_test(suite, "blob_create", blob_create) == NULL || 2997 CU_add_test(suite, "blob_thin_provision", blob_thin_provision) == NULL || 2998 CU_add_test(suite, "blob_delete", blob_delete) == NULL || 2999 CU_add_test(suite, "blob_resize", blob_resize) == NULL || 3000 CU_add_test(suite, "blob_read_only", blob_read_only) == NULL || 3001 CU_add_test(suite, "channel_ops", channel_ops) == NULL || 3002 CU_add_test(suite, "blob_super", blob_super) == NULL || 3003 CU_add_test(suite, "blob_write", blob_write) == NULL || 3004 CU_add_test(suite, "blob_read", blob_read) == NULL || 3005 CU_add_test(suite, "blob_rw_verify", blob_rw_verify) == NULL || 3006 CU_add_test(suite, "blob_rw_verify_iov", blob_rw_verify_iov) == NULL || 3007 CU_add_test(suite, "blob_rw_verify_iov_nomem", blob_rw_verify_iov_nomem) == NULL || 3008 CU_add_test(suite, "blob_rw_iov_read_only", blob_rw_iov_read_only) == NULL || 3009 CU_add_test(suite, "blob_iter", blob_iter) == NULL || 3010 CU_add_test(suite, "blob_xattr", blob_xattr) == NULL || 3011 CU_add_test(suite, "bs_load", bs_load) == NULL || 3012 CU_add_test(suite, "bs_unload", bs_unload) == NULL || 3013 CU_add_test(suite, "bs_cluster_sz", bs_cluster_sz) == NULL || 3014 CU_add_test(suite, "bs_usable_clusters", bs_usable_clusters) == NULL || 3015 CU_add_test(suite, "bs_resize_md", bs_resize_md) == NULL || 3016 CU_add_test(suite, "bs_destroy", bs_destroy) == NULL || 3017 CU_add_test(suite, "bs_type", bs_type) == NULL || 3018 CU_add_test(suite, "bs_super_block", bs_super_block) == NULL || 3019 CU_add_test(suite, "blob_serialize", blob_serialize) == NULL || 3020 CU_add_test(suite, "blob_crc", blob_crc) == NULL || 3021 CU_add_test(suite, "super_block_crc", super_block_crc) == NULL || 3022 CU_add_test(suite, "blob_dirty_shutdown", blob_dirty_shutdown) == NULL || 3023 CU_add_test(suite, "blob_flags", blob_flags) == NULL || 3024 CU_add_test(suite, "bs_version", bs_version) == NULL || 3025 CU_add_test(suite, "blob_set_xattrs", blob_set_xattrs) == NULL || 3026 CU_add_test(suite, "blob_thin_prov_alloc", blob_thin_prov_alloc) == NULL || 3027 CU_add_test(suite, "blob_insert_cluster_msg", blob_insert_cluster_msg) == NULL || 3028 CU_add_test(suite, "blob_thin_prov_rw", blob_thin_prov_rw) == NULL || 3029 CU_add_test(suite, "blob_thin_prov_rw_iov", blob_thin_prov_rw_iov) == NULL 3030 ) { 3031 CU_cleanup_registry(); 3032 return CU_get_error(); 3033 } 3034 3035 g_dev_buffer = calloc(1, DEV_BUFFER_SIZE); 3036 spdk_allocate_thread(_bs_send_msg, NULL, NULL, NULL, "thread0"); 3037 CU_basic_set_mode(CU_BRM_VERBOSE); 3038 CU_basic_run_tests(); 3039 num_failures = CU_get_number_of_failures(); 3040 CU_cleanup_registry(); 3041 spdk_free_thread(); 3042 free(g_dev_buffer); 3043 return num_failures; 3044 } 3045