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