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 #include "spdk/string.h" 39 40 #include "common/lib/test_env.c" 41 #include "../bs_dev_common.c" 42 #include "blob/blobstore.c" 43 #include "blob/request.c" 44 #include "blob/zeroes.c" 45 #include "blob/blob_bs_dev.c" 46 47 struct spdk_blob_store *g_bs; 48 spdk_blob_id g_blobid; 49 struct spdk_blob *g_blob; 50 int g_bserrno; 51 struct spdk_xattr_names *g_names; 52 int g_done; 53 char *g_xattr_names[] = {"first", "second", "third"}; 54 char *g_xattr_values[] = {"one", "two", "three"}; 55 uint64_t g_ctx = 1729; 56 57 struct spdk_bs_super_block_ver1 { 58 uint8_t signature[8]; 59 uint32_t version; 60 uint32_t length; 61 uint32_t clean; /* If there was a clean shutdown, this is 1. */ 62 spdk_blob_id super_blob; 63 64 uint32_t cluster_size; /* In bytes */ 65 66 uint32_t used_page_mask_start; /* Offset from beginning of disk, in pages */ 67 uint32_t used_page_mask_len; /* Count, in pages */ 68 69 uint32_t used_cluster_mask_start; /* Offset from beginning of disk, in pages */ 70 uint32_t used_cluster_mask_len; /* Count, in pages */ 71 72 uint32_t md_start; /* Offset from beginning of disk, in pages */ 73 uint32_t md_len; /* Count, in pages */ 74 75 uint8_t reserved[4036]; 76 uint32_t crc; 77 } __attribute__((packed)); 78 SPDK_STATIC_ASSERT(sizeof(struct spdk_bs_super_block_ver1) == 0x1000, "Invalid super block size"); 79 80 81 static void 82 _get_xattr_value(void *arg, const char *name, 83 const void **value, size_t *value_len) 84 { 85 uint64_t i; 86 87 SPDK_CU_ASSERT_FATAL(value_len != NULL); 88 SPDK_CU_ASSERT_FATAL(value != NULL); 89 CU_ASSERT(arg == &g_ctx) 90 91 for (i = 0; i < sizeof(g_xattr_names); i++) { 92 if (!strcmp(name, g_xattr_names[i])) { 93 *value_len = strlen(g_xattr_values[i]); 94 *value = g_xattr_values[i]; 95 break; 96 } 97 } 98 } 99 100 static void 101 _get_xattr_value_null(void *arg, const char *name, 102 const void **value, size_t *value_len) 103 { 104 SPDK_CU_ASSERT_FATAL(value_len != NULL); 105 SPDK_CU_ASSERT_FATAL(value != NULL); 106 CU_ASSERT(arg == NULL) 107 108 *value_len = 0; 109 *value = NULL; 110 } 111 112 113 114 static void 115 bs_op_complete(void *cb_arg, int bserrno) 116 { 117 g_bserrno = bserrno; 118 } 119 120 static void 121 bs_op_with_handle_complete(void *cb_arg, struct spdk_blob_store *bs, 122 int bserrno) 123 { 124 g_bs = bs; 125 g_bserrno = bserrno; 126 } 127 128 static void 129 blob_op_complete(void *cb_arg, int bserrno) 130 { 131 g_bserrno = bserrno; 132 } 133 134 static void 135 blob_op_with_id_complete(void *cb_arg, spdk_blob_id blobid, int bserrno) 136 { 137 g_blobid = blobid; 138 g_bserrno = bserrno; 139 } 140 141 static void 142 blob_op_with_handle_complete(void *cb_arg, struct spdk_blob *blb, int bserrno) 143 { 144 g_blob = blb; 145 g_bserrno = bserrno; 146 } 147 148 static void 149 blob_init(void) 150 { 151 struct spdk_bs_dev *dev; 152 153 dev = init_dev(); 154 155 /* should fail for an unsupported blocklen */ 156 dev->blocklen = 500; 157 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 158 CU_ASSERT(g_bserrno == -EINVAL); 159 160 dev = init_dev(); 161 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 162 CU_ASSERT(g_bserrno == 0); 163 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 164 165 spdk_bs_unload(g_bs, bs_op_complete, NULL); 166 CU_ASSERT(g_bserrno == 0); 167 g_bs = NULL; 168 } 169 170 static void 171 blob_super(void) 172 { 173 struct spdk_blob_store *bs; 174 struct spdk_bs_dev *dev; 175 spdk_blob_id blobid; 176 177 dev = init_dev(); 178 179 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 180 CU_ASSERT(g_bserrno == 0); 181 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 182 bs = g_bs; 183 184 /* Get the super blob without having set one */ 185 spdk_bs_get_super(bs, blob_op_with_id_complete, NULL); 186 CU_ASSERT(g_bserrno == -ENOENT); 187 CU_ASSERT(g_blobid == SPDK_BLOBID_INVALID); 188 189 /* Create a blob */ 190 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 191 CU_ASSERT(g_bserrno == 0); 192 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 193 blobid = g_blobid; 194 195 /* Set the blob as the super blob */ 196 spdk_bs_set_super(bs, blobid, blob_op_complete, NULL); 197 CU_ASSERT(g_bserrno == 0); 198 199 /* Get the super blob */ 200 spdk_bs_get_super(bs, blob_op_with_id_complete, NULL); 201 CU_ASSERT(g_bserrno == 0); 202 CU_ASSERT(blobid == g_blobid); 203 204 spdk_bs_unload(g_bs, bs_op_complete, NULL); 205 CU_ASSERT(g_bserrno == 0); 206 g_bs = NULL; 207 } 208 209 static void 210 blob_open(void) 211 { 212 struct spdk_blob_store *bs; 213 struct spdk_bs_dev *dev; 214 struct spdk_blob *blob; 215 spdk_blob_id blobid, blobid2; 216 217 dev = init_dev(); 218 219 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 220 CU_ASSERT(g_bserrno == 0); 221 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 222 bs = g_bs; 223 224 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 225 CU_ASSERT(g_bserrno == 0); 226 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 227 blobid = g_blobid; 228 229 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 230 CU_ASSERT(g_bserrno == 0); 231 CU_ASSERT(g_blob != NULL); 232 blob = g_blob; 233 234 blobid2 = spdk_blob_get_id(blob); 235 CU_ASSERT(blobid == blobid2); 236 237 /* Try to open file again. It should return success. */ 238 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 239 CU_ASSERT(g_bserrno == 0); 240 CU_ASSERT(blob == g_blob); 241 242 spdk_blob_close(blob, blob_op_complete, NULL); 243 CU_ASSERT(g_bserrno == 0); 244 245 /* 246 * Close the file a second time, releasing the second reference. This 247 * should succeed. 248 */ 249 blob = g_blob; 250 spdk_blob_close(blob, blob_op_complete, NULL); 251 CU_ASSERT(g_bserrno == 0); 252 253 /* 254 * Try to open file again. It should succeed. This tests the case 255 * where the file is opened, closed, then re-opened again. 256 */ 257 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 258 CU_ASSERT(g_bserrno == 0); 259 CU_ASSERT(g_blob != NULL); 260 blob = g_blob; 261 262 spdk_blob_close(blob, blob_op_complete, NULL); 263 CU_ASSERT(g_bserrno == 0); 264 265 spdk_bs_unload(g_bs, bs_op_complete, NULL); 266 CU_ASSERT(g_bserrno == 0); 267 g_bs = NULL; 268 } 269 270 static void 271 blob_create(void) 272 { 273 struct spdk_blob_store *bs; 274 struct spdk_bs_dev *dev; 275 struct spdk_blob *blob; 276 struct spdk_blob_opts opts; 277 spdk_blob_id blobid; 278 279 dev = init_dev(); 280 281 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 282 CU_ASSERT(g_bserrno == 0); 283 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 284 bs = g_bs; 285 286 /* Create blob with 10 clusters */ 287 288 spdk_blob_opts_init(&opts); 289 opts.num_clusters = 10; 290 291 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 292 CU_ASSERT(g_bserrno == 0); 293 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 294 blobid = g_blobid; 295 296 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 297 CU_ASSERT(g_bserrno == 0); 298 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 299 blob = g_blob; 300 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10) 301 302 spdk_blob_close(blob, blob_op_complete, NULL); 303 CU_ASSERT(g_bserrno == 0); 304 305 /* Create blob with 0 clusters */ 306 307 spdk_blob_opts_init(&opts); 308 opts.num_clusters = 0; 309 310 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 311 CU_ASSERT(g_bserrno == 0); 312 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 313 blobid = g_blobid; 314 315 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 316 CU_ASSERT(g_bserrno == 0); 317 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 318 blob = g_blob; 319 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0) 320 321 spdk_blob_close(blob, blob_op_complete, NULL); 322 CU_ASSERT(g_bserrno == 0); 323 324 /* Create blob with default options (opts == NULL) */ 325 326 spdk_bs_create_blob_ext(bs, NULL, blob_op_with_id_complete, NULL); 327 CU_ASSERT(g_bserrno == 0); 328 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 329 blobid = g_blobid; 330 331 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 332 CU_ASSERT(g_bserrno == 0); 333 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 334 blob = g_blob; 335 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0) 336 337 spdk_blob_close(blob, blob_op_complete, NULL); 338 CU_ASSERT(g_bserrno == 0); 339 340 /* Try to create blob with size larger than blobstore */ 341 342 spdk_blob_opts_init(&opts); 343 opts.num_clusters = bs->total_clusters + 1; 344 345 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 346 CU_ASSERT(g_bserrno == -ENOSPC); 347 348 spdk_bs_unload(g_bs, bs_op_complete, NULL); 349 CU_ASSERT(g_bserrno == 0); 350 g_bs = NULL; 351 352 } 353 354 static void 355 blob_create_internal(void) 356 { 357 struct spdk_blob_store *bs; 358 struct spdk_bs_dev *dev; 359 struct spdk_blob *blob; 360 struct spdk_blob_opts opts; 361 struct spdk_blob_xattr_opts internal_xattrs; 362 const void *value; 363 size_t value_len; 364 spdk_blob_id blobid; 365 int rc; 366 367 dev = init_dev(); 368 369 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 370 CU_ASSERT(g_bserrno == 0); 371 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 372 bs = g_bs; 373 374 /* Create blob with custom xattrs */ 375 376 spdk_blob_opts_init(&opts); 377 _spdk_blob_xattrs_init(&internal_xattrs); 378 internal_xattrs.count = 3; 379 internal_xattrs.names = g_xattr_names; 380 internal_xattrs.get_value = _get_xattr_value; 381 internal_xattrs.ctx = &g_ctx; 382 383 _spdk_bs_create_blob(bs, &opts, &internal_xattrs, 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 393 rc = _spdk_blob_get_xattr_value(blob, g_xattr_names[0], &value, &value_len, true); 394 CU_ASSERT(rc == 0); 395 SPDK_CU_ASSERT_FATAL(value != NULL); 396 CU_ASSERT(value_len == strlen(g_xattr_values[0])); 397 CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len); 398 399 rc = _spdk_blob_get_xattr_value(blob, g_xattr_names[1], &value, &value_len, true); 400 CU_ASSERT(rc == 0); 401 SPDK_CU_ASSERT_FATAL(value != NULL); 402 CU_ASSERT(value_len == strlen(g_xattr_values[1])); 403 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len); 404 405 rc = _spdk_blob_get_xattr_value(blob, g_xattr_names[2], &value, &value_len, true); 406 CU_ASSERT(rc == 0); 407 SPDK_CU_ASSERT_FATAL(value != NULL); 408 CU_ASSERT(value_len == strlen(g_xattr_values[2])); 409 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len); 410 411 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[0], &value, &value_len); 412 CU_ASSERT(rc != 0); 413 414 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[1], &value, &value_len); 415 CU_ASSERT(rc != 0); 416 417 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[2], &value, &value_len); 418 CU_ASSERT(rc != 0); 419 420 spdk_blob_close(blob, blob_op_complete, NULL); 421 CU_ASSERT(g_bserrno == 0); 422 423 /* Create blob with NULL internal options */ 424 425 _spdk_bs_create_blob(bs, NULL, NULL, blob_op_with_id_complete, NULL); 426 CU_ASSERT(g_bserrno == 0); 427 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 428 blobid = g_blobid; 429 430 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 431 CU_ASSERT(g_bserrno == 0); 432 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 433 CU_ASSERT(TAILQ_FIRST(&g_blob->xattrs_internal) == NULL); 434 435 blob = g_blob; 436 437 spdk_blob_close(blob, blob_op_complete, NULL); 438 CU_ASSERT(g_bserrno == 0); 439 440 spdk_bs_unload(g_bs, bs_op_complete, NULL); 441 CU_ASSERT(g_bserrno == 0); 442 g_bs = NULL; 443 444 } 445 446 static void 447 blob_thin_provision(void) 448 { 449 struct spdk_blob_store *bs; 450 struct spdk_bs_dev *dev; 451 struct spdk_blob *blob; 452 struct spdk_blob_opts opts; 453 struct spdk_bs_opts bs_opts; 454 spdk_blob_id blobid; 455 456 dev = init_dev(); 457 spdk_bs_opts_init(&bs_opts); 458 snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE"); 459 460 /* Initialize a new blob store */ 461 spdk_bs_init(dev, &bs_opts, bs_op_with_handle_complete, NULL); 462 CU_ASSERT(g_bserrno == 0); 463 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 464 465 bs = g_bs; 466 467 /* Create blob with thin provisioning enabled */ 468 469 spdk_blob_opts_init(&opts); 470 opts.thin_provision = true; 471 opts.num_clusters = 10; 472 473 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 474 CU_ASSERT(g_bserrno == 0); 475 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 476 blobid = g_blobid; 477 478 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 479 CU_ASSERT(g_bserrno == 0); 480 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 481 blob = g_blob; 482 CU_ASSERT(blob->invalid_flags & SPDK_BLOB_THIN_PROV); 483 484 spdk_blob_close(blob, blob_op_complete, NULL); 485 CU_ASSERT(g_bserrno == 0); 486 487 /* Do not shut down cleanly. This makes sure that when we load again 488 * and try to recover a valid used_cluster map, that blobstore will 489 * ignore clusters with index 0 since these are unallocated clusters. 490 */ 491 492 /* Load an existing blob store and check if invalid_flags is set */ 493 dev = init_dev(); 494 snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE"); 495 spdk_bs_load(dev, &bs_opts, bs_op_with_handle_complete, NULL); 496 CU_ASSERT(g_bserrno == 0); 497 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 498 499 bs = g_bs; 500 501 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 502 CU_ASSERT(g_bserrno == 0); 503 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 504 blob = g_blob; 505 CU_ASSERT(blob->invalid_flags & SPDK_BLOB_THIN_PROV); 506 507 spdk_blob_close(blob, blob_op_complete, NULL); 508 CU_ASSERT(g_bserrno == 0); 509 510 spdk_bs_unload(g_bs, bs_op_complete, NULL); 511 CU_ASSERT(g_bserrno == 0); 512 g_bs = NULL; 513 } 514 515 static void 516 blob_snapshot(void) 517 { 518 struct spdk_blob_store *bs; 519 struct spdk_bs_dev *dev; 520 struct spdk_blob *blob; 521 struct spdk_blob *snapshot, *snapshot2; 522 struct spdk_blob_bs_dev *blob_bs_dev; 523 struct spdk_blob_opts opts; 524 struct spdk_blob_xattr_opts xattrs; 525 spdk_blob_id blobid; 526 spdk_blob_id snapshotid; 527 const void *value; 528 size_t value_len; 529 int rc; 530 531 dev = init_dev(); 532 533 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 534 CU_ASSERT(g_bserrno == 0); 535 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 536 bs = g_bs; 537 538 /* Create blob with 10 clusters */ 539 spdk_blob_opts_init(&opts); 540 opts.num_clusters = 10; 541 542 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 543 CU_ASSERT(g_bserrno == 0); 544 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 545 blobid = g_blobid; 546 547 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 548 CU_ASSERT(g_bserrno == 0); 549 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 550 blob = g_blob; 551 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10) 552 553 /* Create snapshot from blob */ 554 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 555 CU_ASSERT(g_bserrno == 0); 556 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 557 snapshotid = g_blobid; 558 559 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 560 CU_ASSERT(g_bserrno == 0); 561 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 562 snapshot = g_blob; 563 CU_ASSERT(snapshot->data_ro == true) 564 CU_ASSERT(snapshot->md_ro == true) 565 CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 10) 566 567 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10) 568 CU_ASSERT(blob->invalid_flags & SPDK_BLOB_THIN_PROV); 569 CU_ASSERT(spdk_mem_all_zero(blob->active.clusters, 570 blob->active.num_clusters * sizeof(blob->active.clusters[0]))); 571 572 /* Try to create snapshot from clone with xattrs */ 573 xattrs.names = g_xattr_names; 574 xattrs.get_value = _get_xattr_value; 575 xattrs.count = 3; 576 xattrs.ctx = &g_ctx; 577 spdk_bs_create_snapshot(bs, blobid, &xattrs, blob_op_with_id_complete, NULL); 578 CU_ASSERT(g_bserrno == 0); 579 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 580 blobid = g_blobid; 581 582 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 583 CU_ASSERT(g_bserrno == 0); 584 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 585 snapshot2 = g_blob; 586 CU_ASSERT(snapshot2->data_ro == true) 587 CU_ASSERT(snapshot2->md_ro == true) 588 CU_ASSERT(spdk_blob_get_num_clusters(snapshot2) == 10) 589 590 /* Confirm that blob is backed by snapshot2 and snapshot2 is backed by snapshot */ 591 CU_ASSERT(snapshot->back_bs_dev == NULL); 592 SPDK_CU_ASSERT_FATAL(blob->back_bs_dev != NULL); 593 SPDK_CU_ASSERT_FATAL(snapshot2->back_bs_dev != NULL); 594 595 blob_bs_dev = (struct spdk_blob_bs_dev *)blob->back_bs_dev; 596 CU_ASSERT(blob_bs_dev->blob == snapshot2); 597 598 blob_bs_dev = (struct spdk_blob_bs_dev *)snapshot2->back_bs_dev; 599 CU_ASSERT(blob_bs_dev->blob == snapshot); 600 601 rc = spdk_blob_get_xattr_value(snapshot2, g_xattr_names[0], &value, &value_len); 602 CU_ASSERT(rc == 0); 603 SPDK_CU_ASSERT_FATAL(value != NULL); 604 CU_ASSERT(value_len == strlen(g_xattr_values[0])); 605 CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len); 606 607 rc = spdk_blob_get_xattr_value(snapshot2, g_xattr_names[1], &value, &value_len); 608 CU_ASSERT(rc == 0); 609 SPDK_CU_ASSERT_FATAL(value != NULL); 610 CU_ASSERT(value_len == strlen(g_xattr_values[1])); 611 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len); 612 613 rc = spdk_blob_get_xattr_value(snapshot2, g_xattr_names[2], &value, &value_len); 614 CU_ASSERT(rc == 0); 615 SPDK_CU_ASSERT_FATAL(value != NULL); 616 CU_ASSERT(value_len == strlen(g_xattr_values[2])); 617 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len); 618 619 /* Try to create snapshot from snapshot */ 620 spdk_bs_create_snapshot(bs, snapshotid, NULL, blob_op_with_id_complete, NULL); 621 CU_ASSERT(g_bserrno == -EINVAL); 622 CU_ASSERT(g_blobid == SPDK_BLOBID_INVALID); 623 624 spdk_blob_close(blob, blob_op_complete, NULL); 625 CU_ASSERT(g_bserrno == 0); 626 627 spdk_blob_close(snapshot, blob_op_complete, NULL); 628 CU_ASSERT(g_bserrno == 0); 629 630 spdk_blob_close(snapshot2, blob_op_complete, NULL); 631 CU_ASSERT(g_bserrno == 0); 632 633 spdk_bs_unload(g_bs, bs_op_complete, NULL); 634 CU_ASSERT(g_bserrno == 0); 635 g_bs = NULL; 636 } 637 638 static void 639 blob_clone(void) 640 { 641 struct spdk_blob_store *bs; 642 struct spdk_bs_dev *dev; 643 struct spdk_blob_opts opts; 644 struct spdk_blob *blob, *snapshot, *clone; 645 spdk_blob_id blobid, cloneid, snapshotid; 646 struct spdk_blob_xattr_opts xattrs; 647 const void *value; 648 size_t value_len; 649 int rc; 650 651 dev = init_dev(); 652 653 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 654 CU_ASSERT(g_bserrno == 0); 655 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 656 bs = g_bs; 657 658 /* Create blob with 10 clusters */ 659 660 spdk_blob_opts_init(&opts); 661 opts.num_clusters = 10; 662 663 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 664 CU_ASSERT(g_bserrno == 0); 665 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 666 blobid = g_blobid; 667 668 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 669 CU_ASSERT(g_bserrno == 0); 670 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 671 blob = g_blob; 672 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10) 673 674 /* Create snapshot */ 675 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 676 CU_ASSERT(g_bserrno == 0); 677 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 678 snapshotid = g_blobid; 679 680 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 681 CU_ASSERT(g_bserrno == 0); 682 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 683 snapshot = g_blob; 684 CU_ASSERT(snapshot->data_ro == true) 685 CU_ASSERT(snapshot->md_ro == true) 686 CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 10); 687 688 spdk_blob_close(snapshot, blob_op_complete, NULL); 689 CU_ASSERT(g_bserrno == 0); 690 691 /* Create clone from snapshot with xattrs */ 692 xattrs.names = g_xattr_names; 693 xattrs.get_value = _get_xattr_value; 694 xattrs.count = 3; 695 xattrs.ctx = &g_ctx; 696 697 spdk_bs_create_clone(bs, snapshotid, &xattrs, blob_op_with_id_complete, NULL); 698 CU_ASSERT(g_bserrno == 0); 699 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 700 cloneid = g_blobid; 701 702 spdk_bs_open_blob(bs, cloneid, blob_op_with_handle_complete, NULL); 703 CU_ASSERT(g_bserrno == 0); 704 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 705 clone = g_blob; 706 CU_ASSERT(clone->data_ro == false) 707 CU_ASSERT(clone->md_ro == false) 708 CU_ASSERT(spdk_blob_get_num_clusters(clone) == 10); 709 710 rc = spdk_blob_get_xattr_value(clone, g_xattr_names[0], &value, &value_len); 711 CU_ASSERT(rc == 0); 712 SPDK_CU_ASSERT_FATAL(value != NULL); 713 CU_ASSERT(value_len == strlen(g_xattr_values[0])); 714 CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len); 715 716 rc = spdk_blob_get_xattr_value(clone, g_xattr_names[1], &value, &value_len); 717 CU_ASSERT(rc == 0); 718 SPDK_CU_ASSERT_FATAL(value != NULL); 719 CU_ASSERT(value_len == strlen(g_xattr_values[1])); 720 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len); 721 722 rc = spdk_blob_get_xattr_value(clone, g_xattr_names[2], &value, &value_len); 723 CU_ASSERT(rc == 0); 724 SPDK_CU_ASSERT_FATAL(value != NULL); 725 CU_ASSERT(value_len == strlen(g_xattr_values[2])); 726 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len); 727 728 729 spdk_blob_close(clone, blob_op_complete, NULL); 730 CU_ASSERT(g_bserrno == 0); 731 732 /* Try to create clone from not read only blob */ 733 spdk_bs_create_clone(bs, blobid, NULL, blob_op_with_id_complete, NULL); 734 CU_ASSERT(g_bserrno == -EINVAL); 735 CU_ASSERT(g_blobid == SPDK_BLOBID_INVALID); 736 737 /* Mark blob as read only */ 738 spdk_blob_set_read_only(blob); 739 spdk_blob_sync_md(blob, blob_op_complete, NULL); 740 CU_ASSERT(g_bserrno == 0); 741 742 /* Create clone from read only blob */ 743 spdk_bs_create_clone(bs, blobid, NULL, blob_op_with_id_complete, NULL); 744 CU_ASSERT(g_bserrno == 0); 745 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 746 cloneid = g_blobid; 747 748 spdk_bs_open_blob(bs, cloneid, blob_op_with_handle_complete, NULL); 749 CU_ASSERT(g_bserrno == 0); 750 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 751 clone = g_blob; 752 CU_ASSERT(clone->data_ro == false) 753 CU_ASSERT(clone->md_ro == false) 754 CU_ASSERT(spdk_blob_get_num_clusters(clone) == 10); 755 756 spdk_blob_close(clone, blob_op_complete, NULL); 757 CU_ASSERT(g_bserrno == 0); 758 759 spdk_blob_close(blob, blob_op_complete, NULL); 760 CU_ASSERT(g_bserrno == 0); 761 762 spdk_bs_unload(g_bs, bs_op_complete, NULL); 763 CU_ASSERT(g_bserrno == 0); 764 g_bs = NULL; 765 766 } 767 768 static void 769 blob_inflate(void) 770 { 771 struct spdk_blob_store *bs; 772 struct spdk_bs_dev *dev; 773 struct spdk_blob_opts opts; 774 struct spdk_blob *blob, *snapshot; 775 spdk_blob_id blobid, snapshotid; 776 struct spdk_io_channel *channel; 777 uint64_t free_clusters; 778 779 dev = init_dev(); 780 781 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 782 CU_ASSERT(g_bserrno == 0); 783 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 784 bs = g_bs; 785 786 channel = spdk_bs_alloc_io_channel(bs); 787 SPDK_CU_ASSERT_FATAL(channel != NULL); 788 789 /* Create blob with 10 clusters */ 790 791 spdk_blob_opts_init(&opts); 792 opts.num_clusters = 10; 793 794 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 795 CU_ASSERT(g_bserrno == 0); 796 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 797 blobid = g_blobid; 798 799 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 800 CU_ASSERT(g_bserrno == 0); 801 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 802 blob = g_blob; 803 804 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10) 805 CU_ASSERT(spdk_blob_is_thin_provisioned(blob) == false); 806 807 /* Create snapshot */ 808 809 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 810 CU_ASSERT(g_bserrno == 0); 811 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 812 snapshotid = g_blobid; 813 814 CU_ASSERT(spdk_blob_is_thin_provisioned(blob) == true); 815 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10) 816 817 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 818 CU_ASSERT(g_bserrno == 0); 819 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 820 snapshot = g_blob; 821 CU_ASSERT(snapshot->data_ro == true) 822 CU_ASSERT(snapshot->md_ro == true) 823 CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 10); 824 825 spdk_blob_close(snapshot, blob_op_complete, NULL); 826 CU_ASSERT(g_bserrno == 0); 827 828 free_clusters = spdk_bs_free_cluster_count(bs); 829 830 /* Inflate blob */ 831 spdk_bs_inflate_blob(bs, channel, blobid, blob_op_complete, NULL); 832 CU_ASSERT(g_bserrno == 0); 833 834 /* All 10 clusters should be allocated from blob store */ 835 CU_ASSERT(spdk_bs_free_cluster_count(bs) == free_clusters - 10); 836 837 /* Now, it should be possible to delete snapshot */ 838 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 839 CU_ASSERT(g_bserrno == 0); 840 841 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10) 842 CU_ASSERT(spdk_blob_is_thin_provisioned(blob) == false); 843 844 spdk_blob_close(blob, blob_op_complete, NULL); 845 CU_ASSERT(g_bserrno == 0); 846 847 spdk_bs_unload(g_bs, bs_op_complete, NULL); 848 CU_ASSERT(g_bserrno == 0); 849 g_bs = NULL; 850 851 spdk_bs_free_io_channel(channel); 852 } 853 854 static void 855 blob_delete(void) 856 { 857 struct spdk_blob_store *bs; 858 struct spdk_bs_dev *dev; 859 spdk_blob_id blobid; 860 861 dev = init_dev(); 862 863 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 864 CU_ASSERT(g_bserrno == 0); 865 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 866 bs = g_bs; 867 868 /* Create a blob and then delete it. */ 869 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 870 CU_ASSERT(g_bserrno == 0); 871 CU_ASSERT(g_blobid > 0); 872 blobid = g_blobid; 873 874 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 875 CU_ASSERT(g_bserrno == 0); 876 877 /* Try to open the blob */ 878 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 879 CU_ASSERT(g_bserrno == -ENOENT); 880 881 spdk_bs_unload(g_bs, bs_op_complete, NULL); 882 CU_ASSERT(g_bserrno == 0); 883 g_bs = NULL; 884 } 885 886 static void 887 blob_resize(void) 888 { 889 struct spdk_blob_store *bs; 890 struct spdk_bs_dev *dev; 891 struct spdk_blob *blob; 892 spdk_blob_id blobid; 893 uint64_t free_clusters; 894 895 dev = init_dev(); 896 897 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 898 CU_ASSERT(g_bserrno == 0); 899 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 900 bs = g_bs; 901 free_clusters = spdk_bs_free_cluster_count(bs); 902 903 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 904 CU_ASSERT(g_bserrno == 0); 905 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 906 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 907 blobid = g_blobid; 908 909 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 910 CU_ASSERT(g_bserrno == 0); 911 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 912 blob = g_blob; 913 914 /* Confirm that resize fails if blob is marked read-only. */ 915 blob->md_ro = true; 916 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 917 CU_ASSERT(g_bserrno == -EPERM); 918 blob->md_ro = false; 919 920 /* The blob started at 0 clusters. Resize it to be 5. */ 921 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 922 CU_ASSERT(g_bserrno == 0); 923 CU_ASSERT((free_clusters - 5) == spdk_bs_free_cluster_count(bs)); 924 925 /* Shrink the blob to 3 clusters. This will not actually release 926 * the old clusters until the blob is synced. 927 */ 928 spdk_blob_resize(blob, 3, blob_op_complete, NULL); 929 CU_ASSERT(g_bserrno == 0); 930 /* Verify there are still 5 clusters in use */ 931 CU_ASSERT((free_clusters - 5) == spdk_bs_free_cluster_count(bs)); 932 933 spdk_blob_sync_md(blob, blob_op_complete, NULL); 934 CU_ASSERT(g_bserrno == 0); 935 /* Now there are only 3 clusters in use */ 936 CU_ASSERT((free_clusters - 3) == spdk_bs_free_cluster_count(bs)); 937 938 /* Resize the blob to be 10 clusters. Growth takes effect immediately. */ 939 spdk_blob_resize(blob, 10, blob_op_complete, NULL); 940 CU_ASSERT(g_bserrno == 0); 941 CU_ASSERT((free_clusters - 10) == spdk_bs_free_cluster_count(bs)); 942 943 /* Try to resize the blob to size larger than blobstore. */ 944 spdk_blob_resize(blob, bs->total_clusters + 1, blob_op_complete, NULL); 945 CU_ASSERT(g_bserrno == -ENOSPC); 946 947 spdk_blob_close(blob, blob_op_complete, NULL); 948 CU_ASSERT(g_bserrno == 0); 949 950 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 951 CU_ASSERT(g_bserrno == 0); 952 953 spdk_bs_unload(g_bs, bs_op_complete, NULL); 954 CU_ASSERT(g_bserrno == 0); 955 g_bs = NULL; 956 } 957 958 static void 959 blob_read_only(void) 960 { 961 struct spdk_blob_store *bs; 962 struct spdk_bs_dev *dev; 963 struct spdk_blob *blob; 964 struct spdk_bs_opts opts; 965 spdk_blob_id blobid; 966 int rc; 967 968 dev = init_dev(); 969 spdk_bs_opts_init(&opts); 970 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 971 972 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 973 CU_ASSERT(g_bserrno == 0); 974 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 975 bs = g_bs; 976 977 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 978 CU_ASSERT(g_bserrno == 0); 979 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 980 blobid = g_blobid; 981 982 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 983 CU_ASSERT(g_bserrno == 0); 984 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 985 blob = g_blob; 986 987 rc = spdk_blob_set_read_only(blob); 988 CU_ASSERT(rc == 0); 989 990 CU_ASSERT(blob->data_ro == false); 991 CU_ASSERT(blob->md_ro == false); 992 993 spdk_blob_sync_md(blob, bs_op_complete, NULL); 994 995 CU_ASSERT(blob->data_ro == true); 996 CU_ASSERT(blob->md_ro == true); 997 CU_ASSERT(blob->data_ro_flags & SPDK_BLOB_READ_ONLY); 998 999 spdk_blob_close(blob, blob_op_complete, NULL); 1000 CU_ASSERT(g_bserrno == 0); 1001 1002 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1003 CU_ASSERT(g_bserrno == 0); 1004 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1005 blob = g_blob; 1006 1007 CU_ASSERT(blob->data_ro == true); 1008 CU_ASSERT(blob->md_ro == true); 1009 CU_ASSERT(blob->data_ro_flags & SPDK_BLOB_READ_ONLY); 1010 1011 spdk_blob_close(blob, blob_op_complete, NULL); 1012 CU_ASSERT(g_bserrno == 0); 1013 1014 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1015 CU_ASSERT(g_bserrno == 0); 1016 g_bs = NULL; 1017 g_blob = NULL; 1018 g_blobid = 0; 1019 1020 /* Load an existing blob store */ 1021 dev = init_dev(); 1022 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 1023 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1024 CU_ASSERT(g_bserrno == 0); 1025 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1026 1027 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 1028 CU_ASSERT(g_bserrno == 0); 1029 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1030 blob = g_blob; 1031 1032 CU_ASSERT(blob->data_ro == true); 1033 CU_ASSERT(blob->md_ro == true); 1034 CU_ASSERT(blob->data_ro_flags & SPDK_BLOB_READ_ONLY); 1035 1036 spdk_blob_close(blob, blob_op_complete, NULL); 1037 CU_ASSERT(g_bserrno == 0); 1038 1039 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1040 CU_ASSERT(g_bserrno == 0); 1041 1042 } 1043 1044 static void 1045 channel_ops(void) 1046 { 1047 struct spdk_blob_store *bs; 1048 struct spdk_bs_dev *dev; 1049 struct spdk_io_channel *channel; 1050 1051 dev = init_dev(); 1052 1053 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1054 CU_ASSERT(g_bserrno == 0); 1055 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1056 bs = g_bs; 1057 1058 channel = spdk_bs_alloc_io_channel(bs); 1059 CU_ASSERT(channel != NULL); 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_write(void) 1070 { 1071 struct spdk_blob_store *bs; 1072 struct spdk_bs_dev *dev; 1073 struct spdk_blob *blob; 1074 struct spdk_io_channel *channel; 1075 spdk_blob_id blobid; 1076 uint64_t pages_per_cluster; 1077 uint8_t payload[10 * 4096]; 1078 1079 dev = init_dev(); 1080 1081 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1082 CU_ASSERT(g_bserrno == 0); 1083 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1084 bs = g_bs; 1085 1086 pages_per_cluster = spdk_bs_get_cluster_size(bs) / spdk_bs_get_page_size(bs); 1087 1088 channel = spdk_bs_alloc_io_channel(bs); 1089 CU_ASSERT(channel != NULL); 1090 1091 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1092 CU_ASSERT(g_bserrno == 0); 1093 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1094 blobid = g_blobid; 1095 1096 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1097 CU_ASSERT(g_bserrno == 0); 1098 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1099 blob = g_blob; 1100 1101 /* Write to a blob with 0 size */ 1102 spdk_blob_io_write(blob, channel, payload, 0, 1, blob_op_complete, NULL); 1103 CU_ASSERT(g_bserrno == -EINVAL); 1104 1105 /* Resize the blob */ 1106 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 1107 CU_ASSERT(g_bserrno == 0); 1108 1109 /* Confirm that write fails if blob is marked read-only. */ 1110 blob->data_ro = true; 1111 spdk_blob_io_write(blob, channel, payload, 0, 1, blob_op_complete, NULL); 1112 CU_ASSERT(g_bserrno == -EPERM); 1113 blob->data_ro = false; 1114 1115 /* Write to the blob */ 1116 spdk_blob_io_write(blob, channel, payload, 0, 1, blob_op_complete, NULL); 1117 CU_ASSERT(g_bserrno == 0); 1118 1119 /* Write starting beyond the end */ 1120 spdk_blob_io_write(blob, channel, payload, 5 * pages_per_cluster, 1, blob_op_complete, 1121 NULL); 1122 CU_ASSERT(g_bserrno == -EINVAL); 1123 1124 /* Write starting at a valid location but going off the end */ 1125 spdk_blob_io_write(blob, channel, payload, 4 * pages_per_cluster, pages_per_cluster + 1, 1126 blob_op_complete, NULL); 1127 CU_ASSERT(g_bserrno == -EINVAL); 1128 1129 spdk_blob_close(blob, blob_op_complete, NULL); 1130 CU_ASSERT(g_bserrno == 0); 1131 1132 spdk_bs_free_io_channel(channel); 1133 1134 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1135 CU_ASSERT(g_bserrno == 0); 1136 g_bs = NULL; 1137 } 1138 1139 static void 1140 blob_read(void) 1141 { 1142 struct spdk_blob_store *bs; 1143 struct spdk_bs_dev *dev; 1144 struct spdk_blob *blob; 1145 struct spdk_io_channel *channel; 1146 spdk_blob_id blobid; 1147 uint64_t pages_per_cluster; 1148 uint8_t payload[10 * 4096]; 1149 1150 dev = init_dev(); 1151 1152 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1153 CU_ASSERT(g_bserrno == 0); 1154 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1155 bs = g_bs; 1156 1157 pages_per_cluster = spdk_bs_get_cluster_size(bs) / spdk_bs_get_page_size(bs); 1158 1159 channel = spdk_bs_alloc_io_channel(bs); 1160 CU_ASSERT(channel != NULL); 1161 1162 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1163 CU_ASSERT(g_bserrno == 0); 1164 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1165 blobid = g_blobid; 1166 1167 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1168 CU_ASSERT(g_bserrno == 0); 1169 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1170 blob = g_blob; 1171 1172 /* Read from a blob with 0 size */ 1173 spdk_blob_io_read(blob, channel, payload, 0, 1, blob_op_complete, NULL); 1174 CU_ASSERT(g_bserrno == -EINVAL); 1175 1176 /* Resize the blob */ 1177 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 1178 CU_ASSERT(g_bserrno == 0); 1179 1180 /* Confirm that read passes if blob is marked read-only. */ 1181 blob->data_ro = true; 1182 spdk_blob_io_read(blob, channel, payload, 0, 1, blob_op_complete, NULL); 1183 CU_ASSERT(g_bserrno == 0); 1184 blob->data_ro = false; 1185 1186 /* Read from the blob */ 1187 spdk_blob_io_read(blob, channel, payload, 0, 1, blob_op_complete, NULL); 1188 CU_ASSERT(g_bserrno == 0); 1189 1190 /* Read starting beyond the end */ 1191 spdk_blob_io_read(blob, channel, payload, 5 * pages_per_cluster, 1, blob_op_complete, 1192 NULL); 1193 CU_ASSERT(g_bserrno == -EINVAL); 1194 1195 /* Read starting at a valid location but going off the end */ 1196 spdk_blob_io_read(blob, channel, payload, 4 * pages_per_cluster, pages_per_cluster + 1, 1197 blob_op_complete, NULL); 1198 CU_ASSERT(g_bserrno == -EINVAL); 1199 1200 spdk_blob_close(blob, blob_op_complete, NULL); 1201 CU_ASSERT(g_bserrno == 0); 1202 1203 spdk_bs_free_io_channel(channel); 1204 1205 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1206 CU_ASSERT(g_bserrno == 0); 1207 g_bs = NULL; 1208 } 1209 1210 static void 1211 blob_rw_verify(void) 1212 { 1213 struct spdk_blob_store *bs; 1214 struct spdk_bs_dev *dev; 1215 struct spdk_blob *blob; 1216 struct spdk_io_channel *channel; 1217 spdk_blob_id blobid; 1218 uint8_t payload_read[10 * 4096]; 1219 uint8_t payload_write[10 * 4096]; 1220 1221 dev = init_dev(); 1222 1223 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1224 CU_ASSERT(g_bserrno == 0); 1225 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1226 bs = g_bs; 1227 1228 channel = spdk_bs_alloc_io_channel(bs); 1229 CU_ASSERT(channel != NULL); 1230 1231 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1232 CU_ASSERT(g_bserrno == 0); 1233 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1234 blobid = g_blobid; 1235 1236 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1237 CU_ASSERT(g_bserrno == 0); 1238 CU_ASSERT(g_blob != NULL); 1239 blob = g_blob; 1240 1241 spdk_blob_resize(blob, 32, blob_op_complete, NULL); 1242 CU_ASSERT(g_bserrno == 0); 1243 1244 memset(payload_write, 0xE5, sizeof(payload_write)); 1245 spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL); 1246 CU_ASSERT(g_bserrno == 0); 1247 1248 memset(payload_read, 0x00, sizeof(payload_read)); 1249 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 1250 CU_ASSERT(g_bserrno == 0); 1251 CU_ASSERT(memcmp(payload_write, payload_read, 4 * 4096) == 0); 1252 1253 spdk_blob_close(blob, blob_op_complete, NULL); 1254 CU_ASSERT(g_bserrno == 0); 1255 1256 spdk_bs_free_io_channel(channel); 1257 1258 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1259 CU_ASSERT(g_bserrno == 0); 1260 g_bs = NULL; 1261 } 1262 1263 static void 1264 blob_rw_verify_iov(void) 1265 { 1266 struct spdk_blob_store *bs; 1267 struct spdk_bs_dev *dev; 1268 struct spdk_blob *blob; 1269 struct spdk_io_channel *channel; 1270 spdk_blob_id blobid; 1271 uint8_t payload_read[10 * 4096]; 1272 uint8_t payload_write[10 * 4096]; 1273 struct iovec iov_read[3]; 1274 struct iovec iov_write[3]; 1275 void *buf; 1276 1277 dev = init_dev(); 1278 memset(g_dev_buffer, 0, DEV_BUFFER_SIZE); 1279 1280 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1281 CU_ASSERT(g_bserrno == 0); 1282 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1283 bs = g_bs; 1284 1285 channel = spdk_bs_alloc_io_channel(bs); 1286 CU_ASSERT(channel != NULL); 1287 1288 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1289 CU_ASSERT(g_bserrno == 0); 1290 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1291 blobid = g_blobid; 1292 1293 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1294 CU_ASSERT(g_bserrno == 0); 1295 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1296 blob = g_blob; 1297 1298 spdk_blob_resize(blob, 2, blob_op_complete, NULL); 1299 CU_ASSERT(g_bserrno == 0); 1300 1301 /* 1302 * Manually adjust the offset of the blob's second cluster. This allows 1303 * us to make sure that the readv/write code correctly accounts for I/O 1304 * that cross cluster boundaries. Start by asserting that the allocated 1305 * clusters are where we expect before modifying the second cluster. 1306 */ 1307 CU_ASSERT(blob->active.clusters[0] == 1 * 256); 1308 CU_ASSERT(blob->active.clusters[1] == 2 * 256); 1309 blob->active.clusters[1] = 3 * 256; 1310 1311 memset(payload_write, 0xE5, sizeof(payload_write)); 1312 iov_write[0].iov_base = payload_write; 1313 iov_write[0].iov_len = 1 * 4096; 1314 iov_write[1].iov_base = payload_write + 1 * 4096; 1315 iov_write[1].iov_len = 5 * 4096; 1316 iov_write[2].iov_base = payload_write + 6 * 4096; 1317 iov_write[2].iov_len = 4 * 4096; 1318 /* 1319 * Choose a page offset just before the cluster boundary. The first 6 pages of payload 1320 * will get written to the first cluster, the last 4 to the second cluster. 1321 */ 1322 spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 1323 CU_ASSERT(g_bserrno == 0); 1324 1325 memset(payload_read, 0xAA, sizeof(payload_read)); 1326 iov_read[0].iov_base = payload_read; 1327 iov_read[0].iov_len = 3 * 4096; 1328 iov_read[1].iov_base = payload_read + 3 * 4096; 1329 iov_read[1].iov_len = 4 * 4096; 1330 iov_read[2].iov_base = payload_read + 7 * 4096; 1331 iov_read[2].iov_len = 3 * 4096; 1332 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 1333 CU_ASSERT(g_bserrno == 0); 1334 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 1335 1336 buf = calloc(1, 256 * 4096); 1337 SPDK_CU_ASSERT_FATAL(buf != NULL); 1338 /* Check that cluster 2 on "disk" was not modified. */ 1339 CU_ASSERT(memcmp(buf, &g_dev_buffer[512 * 4096], 256 * 4096) == 0); 1340 free(buf); 1341 1342 spdk_blob_close(blob, blob_op_complete, NULL); 1343 CU_ASSERT(g_bserrno == 0); 1344 1345 spdk_bs_free_io_channel(channel); 1346 1347 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1348 CU_ASSERT(g_bserrno == 0); 1349 g_bs = NULL; 1350 } 1351 1352 static uint32_t 1353 bs_channel_get_req_count(struct spdk_io_channel *_channel) 1354 { 1355 struct spdk_bs_channel *channel = spdk_io_channel_get_ctx(_channel); 1356 struct spdk_bs_request_set *set; 1357 uint32_t count = 0; 1358 1359 TAILQ_FOREACH(set, &channel->reqs, link) { 1360 count++; 1361 } 1362 1363 return count; 1364 } 1365 1366 static void 1367 blob_rw_verify_iov_nomem(void) 1368 { 1369 struct spdk_blob_store *bs; 1370 struct spdk_bs_dev *dev; 1371 struct spdk_blob *blob; 1372 struct spdk_io_channel *channel; 1373 spdk_blob_id blobid; 1374 uint8_t payload_write[10 * 4096]; 1375 struct iovec iov_write[3]; 1376 uint32_t req_count; 1377 1378 dev = init_dev(); 1379 memset(g_dev_buffer, 0, DEV_BUFFER_SIZE); 1380 1381 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1382 CU_ASSERT(g_bserrno == 0); 1383 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1384 bs = g_bs; 1385 1386 channel = spdk_bs_alloc_io_channel(bs); 1387 CU_ASSERT(channel != NULL); 1388 1389 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1390 CU_ASSERT(g_bserrno == 0); 1391 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1392 blobid = g_blobid; 1393 1394 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1395 CU_ASSERT(g_bserrno == 0); 1396 CU_ASSERT(g_blob != NULL); 1397 blob = g_blob; 1398 1399 spdk_blob_resize(blob, 2, blob_op_complete, NULL); 1400 CU_ASSERT(g_bserrno == 0); 1401 1402 /* 1403 * Choose a page offset just before the cluster boundary. The first 6 pages of payload 1404 * will get written to the first cluster, the last 4 to the second cluster. 1405 */ 1406 iov_write[0].iov_base = payload_write; 1407 iov_write[0].iov_len = 1 * 4096; 1408 iov_write[1].iov_base = payload_write + 1 * 4096; 1409 iov_write[1].iov_len = 5 * 4096; 1410 iov_write[2].iov_base = payload_write + 6 * 4096; 1411 iov_write[2].iov_len = 4 * 4096; 1412 MOCK_SET(calloc, void *, NULL); 1413 req_count = bs_channel_get_req_count(channel); 1414 spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 1415 CU_ASSERT(g_bserrno = -ENOMEM); 1416 CU_ASSERT(req_count == bs_channel_get_req_count(channel)); 1417 MOCK_SET(calloc, void *, (void *)MOCK_PASS_THRU); 1418 1419 spdk_blob_close(blob, blob_op_complete, NULL); 1420 CU_ASSERT(g_bserrno == 0); 1421 1422 spdk_bs_free_io_channel(channel); 1423 1424 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1425 CU_ASSERT(g_bserrno == 0); 1426 g_bs = NULL; 1427 } 1428 1429 static void 1430 blob_rw_iov_read_only(void) 1431 { 1432 struct spdk_blob_store *bs; 1433 struct spdk_bs_dev *dev; 1434 struct spdk_blob *blob; 1435 struct spdk_io_channel *channel; 1436 spdk_blob_id blobid; 1437 uint8_t payload_read[4096]; 1438 uint8_t payload_write[4096]; 1439 struct iovec iov_read; 1440 struct iovec iov_write; 1441 1442 dev = init_dev(); 1443 memset(g_dev_buffer, 0, DEV_BUFFER_SIZE); 1444 1445 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1446 CU_ASSERT(g_bserrno == 0); 1447 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1448 bs = g_bs; 1449 1450 channel = spdk_bs_alloc_io_channel(bs); 1451 CU_ASSERT(channel != NULL); 1452 1453 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1454 CU_ASSERT(g_bserrno == 0); 1455 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1456 blobid = g_blobid; 1457 1458 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1459 CU_ASSERT(g_bserrno == 0); 1460 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1461 blob = g_blob; 1462 1463 spdk_blob_resize(blob, 2, blob_op_complete, NULL); 1464 CU_ASSERT(g_bserrno == 0); 1465 1466 /* Verify that writev failed if read_only flag is set. */ 1467 blob->data_ro = true; 1468 iov_write.iov_base = payload_write; 1469 iov_write.iov_len = sizeof(payload_write); 1470 spdk_blob_io_writev(blob, channel, &iov_write, 1, 0, 1, blob_op_complete, NULL); 1471 CU_ASSERT(g_bserrno == -EPERM); 1472 1473 /* Verify that reads pass if data_ro flag is set. */ 1474 iov_read.iov_base = payload_read; 1475 iov_read.iov_len = sizeof(payload_read); 1476 spdk_blob_io_readv(blob, channel, &iov_read, 1, 0, 1, blob_op_complete, NULL); 1477 CU_ASSERT(g_bserrno == 0); 1478 1479 spdk_blob_close(blob, blob_op_complete, NULL); 1480 CU_ASSERT(g_bserrno == 0); 1481 1482 spdk_bs_free_io_channel(channel); 1483 1484 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1485 CU_ASSERT(g_bserrno == 0); 1486 g_bs = NULL; 1487 } 1488 1489 static void 1490 blob_unmap(void) 1491 { 1492 struct spdk_blob_store *bs; 1493 struct spdk_bs_dev *dev; 1494 struct spdk_blob *blob; 1495 struct spdk_io_channel *channel; 1496 spdk_blob_id blobid; 1497 struct spdk_blob_opts opts; 1498 uint8_t payload[4096]; 1499 int i; 1500 1501 dev = init_dev(); 1502 1503 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1504 CU_ASSERT(g_bserrno == 0); 1505 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1506 bs = g_bs; 1507 1508 channel = spdk_bs_alloc_io_channel(bs); 1509 CU_ASSERT(channel != NULL); 1510 1511 spdk_blob_opts_init(&opts); 1512 opts.num_clusters = 10; 1513 1514 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 1515 CU_ASSERT(g_bserrno == 0); 1516 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1517 blobid = g_blobid; 1518 1519 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1520 CU_ASSERT(g_bserrno == 0); 1521 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1522 blob = g_blob; 1523 1524 spdk_blob_resize(blob, 10, blob_op_complete, NULL); 1525 CU_ASSERT(g_bserrno == 0); 1526 1527 memset(payload, 0, sizeof(payload)); 1528 payload[0] = 0xFF; 1529 1530 /* 1531 * Set first byte of every cluster to 0xFF. 1532 * First cluster on device is reserved so let's start from cluster number 1 1533 */ 1534 for (i = 1; i < 11; i++) { 1535 g_dev_buffer[i * SPDK_BLOB_OPTS_CLUSTER_SZ] = 0xFF; 1536 } 1537 1538 /* Confirm writes */ 1539 for (i = 0; i < 10; i++) { 1540 payload[0] = 0; 1541 spdk_blob_io_read(blob, channel, &payload, i * SPDK_BLOB_OPTS_CLUSTER_SZ / 4096, 1, 1542 blob_op_complete, NULL); 1543 CU_ASSERT(g_bserrno == 0); 1544 CU_ASSERT(payload[0] == 0xFF); 1545 } 1546 1547 /* Mark some clusters as unallocated */ 1548 blob->active.clusters[1] = 0; 1549 blob->active.clusters[2] = 0; 1550 blob->active.clusters[3] = 0; 1551 blob->active.clusters[6] = 0; 1552 blob->active.clusters[8] = 0; 1553 1554 /* Unmap clusters by resizing to 0 */ 1555 spdk_blob_resize(blob, 0, blob_op_complete, NULL); 1556 CU_ASSERT(g_bserrno == 0); 1557 1558 spdk_blob_sync_md(blob, blob_op_complete, NULL); 1559 CU_ASSERT(g_bserrno == 0); 1560 1561 /* Confirm that only 'allocated' clusters were unmaped */ 1562 for (i = 1; i < 11; i++) { 1563 switch (i) { 1564 case 2: 1565 case 3: 1566 case 4: 1567 case 7: 1568 case 9: 1569 CU_ASSERT(g_dev_buffer[i * SPDK_BLOB_OPTS_CLUSTER_SZ] == 0xFF); 1570 break; 1571 default: 1572 CU_ASSERT(g_dev_buffer[i * SPDK_BLOB_OPTS_CLUSTER_SZ] == 0); 1573 break; 1574 } 1575 } 1576 1577 spdk_blob_close(blob, blob_op_complete, NULL); 1578 CU_ASSERT(g_bserrno == 0); 1579 1580 spdk_bs_free_io_channel(channel); 1581 1582 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1583 CU_ASSERT(g_bserrno == 0); 1584 g_bs = NULL; 1585 } 1586 1587 1588 static void 1589 blob_iter(void) 1590 { 1591 struct spdk_blob_store *bs; 1592 struct spdk_bs_dev *dev; 1593 struct spdk_blob *blob; 1594 spdk_blob_id blobid; 1595 1596 dev = init_dev(); 1597 1598 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1599 CU_ASSERT(g_bserrno == 0); 1600 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1601 bs = g_bs; 1602 1603 spdk_bs_iter_first(bs, blob_op_with_handle_complete, NULL); 1604 CU_ASSERT(g_blob == NULL); 1605 CU_ASSERT(g_bserrno == -ENOENT); 1606 1607 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1608 CU_ASSERT(g_bserrno == 0); 1609 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1610 blobid = g_blobid; 1611 1612 spdk_bs_iter_first(bs, blob_op_with_handle_complete, NULL); 1613 CU_ASSERT(g_blob != NULL); 1614 CU_ASSERT(g_bserrno == 0); 1615 blob = g_blob; 1616 CU_ASSERT(spdk_blob_get_id(blob) == blobid); 1617 1618 spdk_bs_iter_next(bs, blob, blob_op_with_handle_complete, NULL); 1619 CU_ASSERT(g_blob == NULL); 1620 CU_ASSERT(g_bserrno == -ENOENT); 1621 1622 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1623 CU_ASSERT(g_bserrno == 0); 1624 g_bs = NULL; 1625 } 1626 1627 static void 1628 blob_xattr(void) 1629 { 1630 struct spdk_blob_store *bs; 1631 struct spdk_bs_dev *dev; 1632 struct spdk_blob *blob; 1633 spdk_blob_id blobid; 1634 uint64_t length; 1635 int rc; 1636 const char *name1, *name2; 1637 const void *value; 1638 size_t value_len; 1639 struct spdk_xattr_names *names; 1640 1641 dev = init_dev(); 1642 1643 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1644 CU_ASSERT(g_bserrno == 0); 1645 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1646 bs = g_bs; 1647 1648 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1649 CU_ASSERT(g_bserrno == 0); 1650 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1651 blobid = g_blobid; 1652 1653 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1654 CU_ASSERT(g_bserrno == 0); 1655 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1656 blob = g_blob; 1657 1658 /* Test that set_xattr fails if md_ro flag is set. */ 1659 blob->md_ro = true; 1660 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 1661 CU_ASSERT(rc == -EPERM); 1662 1663 blob->md_ro = false; 1664 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 1665 CU_ASSERT(rc == 0); 1666 1667 length = 2345; 1668 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 1669 CU_ASSERT(rc == 0); 1670 1671 /* Overwrite "length" xattr. */ 1672 length = 3456; 1673 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 1674 CU_ASSERT(rc == 0); 1675 1676 /* get_xattr should still work even if md_ro flag is set. */ 1677 value = NULL; 1678 blob->md_ro = true; 1679 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 1680 CU_ASSERT(rc == 0); 1681 SPDK_CU_ASSERT_FATAL(value != NULL); 1682 CU_ASSERT(*(uint64_t *)value == length); 1683 CU_ASSERT(value_len == 8); 1684 blob->md_ro = false; 1685 1686 rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len); 1687 CU_ASSERT(rc == -ENOENT); 1688 1689 names = NULL; 1690 rc = spdk_blob_get_xattr_names(blob, &names); 1691 CU_ASSERT(rc == 0); 1692 SPDK_CU_ASSERT_FATAL(names != NULL); 1693 CU_ASSERT(spdk_xattr_names_get_count(names) == 2); 1694 name1 = spdk_xattr_names_get_name(names, 0); 1695 SPDK_CU_ASSERT_FATAL(name1 != NULL); 1696 CU_ASSERT(!strcmp(name1, "name") || !strcmp(name1, "length")); 1697 name2 = spdk_xattr_names_get_name(names, 1); 1698 SPDK_CU_ASSERT_FATAL(name2 != NULL); 1699 CU_ASSERT(!strcmp(name2, "name") || !strcmp(name2, "length")); 1700 CU_ASSERT(strcmp(name1, name2)); 1701 spdk_xattr_names_free(names); 1702 1703 /* Confirm that remove_xattr fails if md_ro is set to true. */ 1704 blob->md_ro = true; 1705 rc = spdk_blob_remove_xattr(blob, "name"); 1706 CU_ASSERT(rc == -EPERM); 1707 1708 blob->md_ro = false; 1709 rc = spdk_blob_remove_xattr(blob, "name"); 1710 CU_ASSERT(rc == 0); 1711 1712 rc = spdk_blob_remove_xattr(blob, "foobar"); 1713 CU_ASSERT(rc == -ENOENT); 1714 1715 /* Set internal xattr */ 1716 length = 7898; 1717 rc = _spdk_blob_set_xattr(blob, "internal", &length, sizeof(length), true); 1718 CU_ASSERT(rc == 0); 1719 rc = _spdk_blob_get_xattr_value(blob, "internal", &value, &value_len, true); 1720 CU_ASSERT(rc == 0); 1721 CU_ASSERT(*(uint64_t *)value == length); 1722 /* try to get public xattr with same name */ 1723 rc = spdk_blob_get_xattr_value(blob, "internal", &value, &value_len); 1724 CU_ASSERT(rc != 0); 1725 rc = _spdk_blob_get_xattr_value(blob, "internal", &value, &value_len, false); 1726 CU_ASSERT(rc != 0); 1727 /* Check if SPDK_BLOB_INTERNAL_XATTR is set */ 1728 CU_ASSERT((blob->invalid_flags & SPDK_BLOB_INTERNAL_XATTR) == 1729 SPDK_BLOB_INTERNAL_XATTR) 1730 1731 spdk_blob_close(blob, blob_op_complete, NULL); 1732 1733 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1734 1735 /* Check if xattrs are persisted */ 1736 dev = init_dev(); 1737 1738 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 1739 CU_ASSERT(g_bserrno == 0); 1740 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1741 1742 bs = g_bs; 1743 1744 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1745 CU_ASSERT(g_bserrno == 0); 1746 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1747 blob = g_blob; 1748 1749 rc = _spdk_blob_get_xattr_value(blob, "internal", &value, &value_len, true); 1750 CU_ASSERT(rc == 0); 1751 CU_ASSERT(*(uint64_t *)value == length); 1752 1753 /* try to get internal xattr trough public call */ 1754 rc = spdk_blob_get_xattr_value(blob, "internal", &value, &value_len); 1755 CU_ASSERT(rc != 0); 1756 1757 rc = _spdk_blob_remove_xattr(blob, "internal", true); 1758 CU_ASSERT(rc == 0); 1759 1760 CU_ASSERT((blob->invalid_flags & SPDK_BLOB_INTERNAL_XATTR) == 0); 1761 1762 CU_ASSERT(g_bserrno == 0); 1763 g_bs = NULL; 1764 } 1765 1766 static void 1767 bs_load(void) 1768 { 1769 struct spdk_bs_dev *dev; 1770 spdk_blob_id blobid; 1771 struct spdk_blob *blob; 1772 struct spdk_bs_super_block *super_block; 1773 uint64_t length; 1774 int rc; 1775 const void *value; 1776 size_t value_len; 1777 struct spdk_bs_opts opts; 1778 1779 dev = init_dev(); 1780 spdk_bs_opts_init(&opts); 1781 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 1782 1783 /* Initialize a new blob store */ 1784 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1785 CU_ASSERT(g_bserrno == 0); 1786 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1787 1788 /* Try to open a blobid that does not exist */ 1789 spdk_bs_open_blob(g_bs, 0, blob_op_with_handle_complete, NULL); 1790 CU_ASSERT(g_bserrno == -ENOENT); 1791 CU_ASSERT(g_blob == NULL); 1792 1793 /* Create a blob */ 1794 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 1795 CU_ASSERT(g_bserrno == 0); 1796 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1797 blobid = g_blobid; 1798 1799 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 1800 CU_ASSERT(g_bserrno == 0); 1801 CU_ASSERT(g_blob != NULL); 1802 blob = g_blob; 1803 1804 /* Try again to open valid blob but without the upper bit set */ 1805 spdk_bs_open_blob(g_bs, blobid & 0xFFFFFFFF, blob_op_with_handle_complete, NULL); 1806 CU_ASSERT(g_bserrno == -ENOENT); 1807 CU_ASSERT(g_blob == NULL); 1808 1809 /* Set some xattrs */ 1810 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 1811 CU_ASSERT(rc == 0); 1812 1813 length = 2345; 1814 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 1815 CU_ASSERT(rc == 0); 1816 1817 /* Resize the blob */ 1818 spdk_blob_resize(blob, 10, blob_op_complete, NULL); 1819 CU_ASSERT(g_bserrno == 0); 1820 1821 spdk_blob_close(blob, blob_op_complete, NULL); 1822 CU_ASSERT(g_bserrno == 0); 1823 blob = NULL; 1824 g_blob = NULL; 1825 g_blobid = SPDK_BLOBID_INVALID; 1826 1827 /* Unload the blob store */ 1828 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1829 CU_ASSERT(g_bserrno == 0); 1830 g_bs = NULL; 1831 g_blob = NULL; 1832 g_blobid = 0; 1833 1834 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 1835 CU_ASSERT(super_block->clean == 1); 1836 1837 /* Load should fail for device with an unsupported blocklen */ 1838 dev = init_dev(); 1839 dev->blocklen = SPDK_BS_PAGE_SIZE * 2; 1840 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 1841 CU_ASSERT(g_bserrno == -EINVAL); 1842 1843 /* Load should when max_md_ops is set to zero */ 1844 dev = init_dev(); 1845 spdk_bs_opts_init(&opts); 1846 opts.max_md_ops = 0; 1847 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1848 CU_ASSERT(g_bserrno == -EINVAL); 1849 1850 /* Load should when max_channel_ops is set to zero */ 1851 dev = init_dev(); 1852 spdk_bs_opts_init(&opts); 1853 opts.max_channel_ops = 0; 1854 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1855 CU_ASSERT(g_bserrno == -EINVAL); 1856 1857 /* Load an existing blob store */ 1858 dev = init_dev(); 1859 spdk_bs_opts_init(&opts); 1860 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 1861 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1862 CU_ASSERT(g_bserrno == 0); 1863 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1864 1865 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 1866 CU_ASSERT(super_block->clean == 0); 1867 1868 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 1869 CU_ASSERT(g_bserrno == 0); 1870 CU_ASSERT(g_blob != NULL); 1871 blob = g_blob; 1872 1873 /* Get the xattrs */ 1874 value = NULL; 1875 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 1876 CU_ASSERT(rc == 0); 1877 SPDK_CU_ASSERT_FATAL(value != NULL); 1878 CU_ASSERT(*(uint64_t *)value == length); 1879 CU_ASSERT(value_len == 8); 1880 1881 rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len); 1882 CU_ASSERT(rc == -ENOENT); 1883 1884 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 1885 1886 spdk_blob_close(blob, blob_op_complete, NULL); 1887 CU_ASSERT(g_bserrno == 0); 1888 blob = NULL; 1889 g_blob = NULL; 1890 g_blobid = SPDK_BLOBID_INVALID; 1891 1892 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1893 CU_ASSERT(g_bserrno == 0); 1894 g_bs = NULL; 1895 } 1896 1897 static void 1898 bs_type(void) 1899 { 1900 struct spdk_bs_dev *dev; 1901 struct spdk_bs_opts opts; 1902 1903 dev = init_dev(); 1904 spdk_bs_opts_init(&opts); 1905 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 1906 1907 /* Initialize a new blob store */ 1908 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1909 CU_ASSERT(g_bserrno == 0); 1910 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1911 1912 /* Unload the blob store */ 1913 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1914 CU_ASSERT(g_bserrno == 0); 1915 g_bs = NULL; 1916 g_blob = NULL; 1917 g_blobid = 0; 1918 1919 /* Load non existing blobstore type */ 1920 dev = init_dev(); 1921 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "NONEXISTING"); 1922 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1923 CU_ASSERT(g_bserrno != 0); 1924 1925 /* Load with empty blobstore type */ 1926 dev = init_dev(); 1927 memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype)); 1928 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1929 CU_ASSERT(g_bserrno == 0); 1930 1931 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1932 CU_ASSERT(g_bserrno == 0); 1933 g_bs = NULL; 1934 1935 /* Initialize a new blob store with empty bstype */ 1936 dev = init_dev(); 1937 memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype)); 1938 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1939 CU_ASSERT(g_bserrno == 0); 1940 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1941 1942 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1943 CU_ASSERT(g_bserrno == 0); 1944 g_bs = NULL; 1945 1946 /* Load non existing blobstore type */ 1947 dev = init_dev(); 1948 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "NONEXISTING"); 1949 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1950 CU_ASSERT(g_bserrno != 0); 1951 1952 /* Load with empty blobstore type */ 1953 dev = init_dev(); 1954 memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype)); 1955 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1956 CU_ASSERT(g_bserrno == 0); 1957 1958 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1959 CU_ASSERT(g_bserrno == 0); 1960 g_bs = NULL; 1961 } 1962 1963 static void 1964 bs_super_block(void) 1965 { 1966 struct spdk_bs_dev *dev; 1967 struct spdk_bs_super_block *super_block; 1968 struct spdk_bs_opts opts; 1969 struct spdk_bs_super_block_ver1 super_block_v1; 1970 1971 dev = init_dev(); 1972 spdk_bs_opts_init(&opts); 1973 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 1974 1975 /* Initialize a new blob store */ 1976 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1977 CU_ASSERT(g_bserrno == 0); 1978 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1979 1980 /* Unload the blob store */ 1981 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1982 CU_ASSERT(g_bserrno == 0); 1983 g_bs = NULL; 1984 g_blob = NULL; 1985 g_blobid = 0; 1986 1987 /* Load an existing blob store with version newer than supported */ 1988 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 1989 super_block->version++; 1990 1991 dev = init_dev(); 1992 memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype)); 1993 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1994 CU_ASSERT(g_bserrno != 0); 1995 1996 /* Create a new blob store with super block version 1 */ 1997 dev = init_dev(); 1998 super_block_v1.version = 1; 1999 memcpy(super_block_v1.signature, "SPDKBLOB", sizeof(super_block_v1.signature)); 2000 super_block_v1.length = 0x1000; 2001 super_block_v1.clean = 1; 2002 super_block_v1.super_blob = 0xFFFFFFFFFFFFFFFF; 2003 super_block_v1.cluster_size = 0x100000; 2004 super_block_v1.used_page_mask_start = 0x01; 2005 super_block_v1.used_page_mask_len = 0x01; 2006 super_block_v1.used_cluster_mask_start = 0x02; 2007 super_block_v1.used_cluster_mask_len = 0x01; 2008 super_block_v1.md_start = 0x03; 2009 super_block_v1.md_len = 0x40; 2010 memset(super_block_v1.reserved, 0, 4036); 2011 super_block_v1.crc = _spdk_blob_md_page_calc_crc(&super_block_v1); 2012 memcpy(g_dev_buffer, &super_block_v1, sizeof(struct spdk_bs_super_block_ver1)); 2013 2014 memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype)); 2015 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2016 CU_ASSERT(g_bserrno == 0); 2017 2018 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2019 CU_ASSERT(g_bserrno == 0); 2020 g_bs = NULL; 2021 } 2022 2023 /* 2024 * Create a blobstore and then unload it. 2025 */ 2026 static void 2027 bs_unload(void) 2028 { 2029 struct spdk_bs_dev *dev; 2030 struct spdk_blob_store *bs; 2031 spdk_blob_id blobid; 2032 struct spdk_blob *blob; 2033 2034 dev = init_dev(); 2035 2036 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2037 CU_ASSERT(g_bserrno == 0); 2038 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2039 bs = g_bs; 2040 2041 /* Create a blob and open it. */ 2042 g_bserrno = -1; 2043 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 2044 CU_ASSERT(g_bserrno == 0); 2045 CU_ASSERT(g_blobid > 0); 2046 blobid = g_blobid; 2047 2048 g_bserrno = -1; 2049 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2050 CU_ASSERT(g_bserrno == 0); 2051 CU_ASSERT(g_blob != NULL); 2052 blob = g_blob; 2053 2054 /* Try to unload blobstore, should fail with open blob */ 2055 g_bserrno = -1; 2056 spdk_bs_unload(bs, bs_op_complete, NULL); 2057 CU_ASSERT(g_bserrno == -EBUSY); 2058 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2059 2060 /* Close the blob, then successfully unload blobstore */ 2061 g_bserrno = -1; 2062 spdk_blob_close(blob, blob_op_complete, NULL); 2063 CU_ASSERT(g_bserrno == 0); 2064 2065 g_bserrno = -1; 2066 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2067 CU_ASSERT(g_bserrno == 0); 2068 g_bs = NULL; 2069 } 2070 2071 /* 2072 * Create a blobstore with a cluster size different than the default, and ensure it is 2073 * persisted. 2074 */ 2075 static void 2076 bs_cluster_sz(void) 2077 { 2078 struct spdk_bs_dev *dev; 2079 struct spdk_bs_opts opts; 2080 uint32_t cluster_sz; 2081 2082 /* Set cluster size to zero */ 2083 dev = init_dev(); 2084 spdk_bs_opts_init(&opts); 2085 opts.cluster_sz = 0; 2086 2087 /* Initialize a new blob store */ 2088 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2089 CU_ASSERT(g_bserrno == -EINVAL); 2090 SPDK_CU_ASSERT_FATAL(g_bs == NULL); 2091 2092 /* 2093 * Set cluster size to blobstore page size, 2094 * to work it is required to be at least twice the blobstore page size. 2095 */ 2096 dev = init_dev(); 2097 spdk_bs_opts_init(&opts); 2098 opts.cluster_sz = SPDK_BS_PAGE_SIZE; 2099 2100 /* Initialize a new blob store */ 2101 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2102 CU_ASSERT(g_bserrno == -ENOMEM); 2103 SPDK_CU_ASSERT_FATAL(g_bs == NULL); 2104 2105 /* 2106 * Set cluster size to lower than page size, 2107 * to work it is required to be at least twice the blobstore page size. 2108 */ 2109 dev = init_dev(); 2110 spdk_bs_opts_init(&opts); 2111 opts.cluster_sz = SPDK_BS_PAGE_SIZE - 1; 2112 2113 /* Initialize a new blob store */ 2114 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2115 CU_ASSERT(g_bserrno == -ENOMEM); 2116 SPDK_CU_ASSERT_FATAL(g_bs == NULL); 2117 2118 /* Set cluster size to twice the default */ 2119 dev = init_dev(); 2120 spdk_bs_opts_init(&opts); 2121 opts.cluster_sz *= 2; 2122 cluster_sz = opts.cluster_sz; 2123 2124 /* Initialize a new blob store */ 2125 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2126 CU_ASSERT(g_bserrno == 0); 2127 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2128 2129 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 2130 2131 /* Unload the blob store */ 2132 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2133 CU_ASSERT(g_bserrno == 0); 2134 g_bs = NULL; 2135 g_blob = NULL; 2136 g_blobid = 0; 2137 2138 dev = init_dev(); 2139 /* Load an existing blob store */ 2140 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2141 CU_ASSERT(g_bserrno == 0); 2142 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2143 2144 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 2145 2146 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2147 CU_ASSERT(g_bserrno == 0); 2148 g_bs = NULL; 2149 } 2150 2151 /* 2152 * Create a blobstore, reload it and ensure total usable cluster count 2153 * stays the same. 2154 */ 2155 static void 2156 bs_usable_clusters(void) 2157 { 2158 struct spdk_bs_dev *dev; 2159 struct spdk_bs_opts opts; 2160 uint32_t clusters; 2161 int i; 2162 2163 /* Init blobstore */ 2164 dev = init_dev(); 2165 spdk_bs_opts_init(&opts); 2166 2167 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2168 CU_ASSERT(g_bserrno == 0); 2169 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2170 2171 clusters = spdk_bs_total_data_cluster_count(g_bs); 2172 2173 /* Unload the blob store */ 2174 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2175 CU_ASSERT(g_bserrno == 0); 2176 g_bs = NULL; 2177 2178 dev = init_dev(); 2179 /* Load an existing blob store */ 2180 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2181 CU_ASSERT(g_bserrno == 0); 2182 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2183 2184 CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters); 2185 2186 /* Create and resize blobs to make sure that useable cluster count won't change */ 2187 for (i = 0; i < 4; i++) { 2188 g_bserrno = -1; 2189 g_blobid = SPDK_BLOBID_INVALID; 2190 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2191 CU_ASSERT(g_bserrno == 0); 2192 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2193 2194 g_bserrno = -1; 2195 g_blob = NULL; 2196 spdk_bs_open_blob(g_bs, g_blobid, blob_op_with_handle_complete, NULL); 2197 CU_ASSERT(g_bserrno == 0); 2198 CU_ASSERT(g_blob != NULL); 2199 2200 spdk_blob_resize(g_blob, 10, blob_op_complete, NULL); 2201 CU_ASSERT(g_bserrno == 0); 2202 2203 g_bserrno = -1; 2204 spdk_blob_close(g_blob, blob_op_complete, NULL); 2205 CU_ASSERT(g_bserrno == 0); 2206 2207 CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters); 2208 } 2209 2210 /* Reload the blob store to make sure that nothing changed */ 2211 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2212 CU_ASSERT(g_bserrno == 0); 2213 g_bs = NULL; 2214 2215 dev = init_dev(); 2216 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2217 CU_ASSERT(g_bserrno == 0); 2218 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2219 2220 CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters); 2221 2222 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2223 CU_ASSERT(g_bserrno == 0); 2224 g_bs = NULL; 2225 } 2226 2227 /* 2228 * Test resizing of the metadata blob. This requires creating enough blobs 2229 * so that one cluster is not enough to fit the metadata for those blobs. 2230 * To induce this condition to happen more quickly, we reduce the cluster 2231 * size to 16KB, which means only 4 4KB blob metadata pages can fit. 2232 */ 2233 static void 2234 bs_resize_md(void) 2235 { 2236 const int CLUSTER_PAGE_COUNT = 4; 2237 const int NUM_BLOBS = CLUSTER_PAGE_COUNT * 4; 2238 struct spdk_bs_dev *dev; 2239 struct spdk_bs_opts opts; 2240 uint32_t cluster_sz; 2241 spdk_blob_id blobids[NUM_BLOBS]; 2242 int i; 2243 2244 2245 dev = init_dev(); 2246 spdk_bs_opts_init(&opts); 2247 opts.cluster_sz = CLUSTER_PAGE_COUNT * 4096; 2248 cluster_sz = opts.cluster_sz; 2249 2250 /* Initialize a new blob store */ 2251 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2252 CU_ASSERT(g_bserrno == 0); 2253 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2254 2255 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 2256 2257 for (i = 0; i < NUM_BLOBS; i++) { 2258 g_bserrno = -1; 2259 g_blobid = SPDK_BLOBID_INVALID; 2260 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2261 CU_ASSERT(g_bserrno == 0); 2262 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2263 blobids[i] = g_blobid; 2264 } 2265 2266 /* Unload the blob store */ 2267 g_bserrno = -1; 2268 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2269 CU_ASSERT(g_bserrno == 0); 2270 2271 /* Load an existing blob store */ 2272 g_bserrno = -1; 2273 g_bs = NULL; 2274 dev = init_dev(); 2275 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2276 CU_ASSERT(g_bserrno == 0); 2277 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2278 2279 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 2280 2281 for (i = 0; i < NUM_BLOBS; i++) { 2282 g_bserrno = -1; 2283 g_blob = NULL; 2284 spdk_bs_open_blob(g_bs, blobids[i], blob_op_with_handle_complete, NULL); 2285 CU_ASSERT(g_bserrno == 0); 2286 CU_ASSERT(g_blob != NULL); 2287 g_bserrno = -1; 2288 spdk_blob_close(g_blob, blob_op_complete, NULL); 2289 CU_ASSERT(g_bserrno == 0); 2290 } 2291 2292 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2293 CU_ASSERT(g_bserrno == 0); 2294 g_bs = NULL; 2295 } 2296 2297 static void 2298 bs_destroy(void) 2299 { 2300 struct spdk_bs_dev *dev; 2301 struct spdk_bs_opts opts; 2302 2303 /* Initialize a new blob store */ 2304 dev = init_dev(); 2305 spdk_bs_opts_init(&opts); 2306 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2307 CU_ASSERT(g_bserrno == 0); 2308 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2309 2310 /* Destroy the blob store */ 2311 g_bserrno = -1; 2312 spdk_bs_destroy(g_bs, bs_op_complete, NULL); 2313 CU_ASSERT(g_bserrno == 0); 2314 2315 /* Loading an non-existent blob store should fail. */ 2316 g_bs = NULL; 2317 dev = init_dev(); 2318 2319 g_bserrno = 0; 2320 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2321 CU_ASSERT(g_bserrno != 0); 2322 } 2323 2324 /* Try to hit all of the corner cases associated with serializing 2325 * a blob to disk 2326 */ 2327 static void 2328 blob_serialize(void) 2329 { 2330 struct spdk_bs_dev *dev; 2331 struct spdk_bs_opts opts; 2332 struct spdk_blob_store *bs; 2333 spdk_blob_id blobid[2]; 2334 struct spdk_blob *blob[2]; 2335 uint64_t i; 2336 char *value; 2337 int rc; 2338 2339 dev = init_dev(); 2340 2341 /* Initialize a new blobstore with very small clusters */ 2342 spdk_bs_opts_init(&opts); 2343 opts.cluster_sz = dev->blocklen * 8; 2344 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2345 CU_ASSERT(g_bserrno == 0); 2346 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2347 bs = g_bs; 2348 2349 /* Create and open two blobs */ 2350 for (i = 0; i < 2; i++) { 2351 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 2352 CU_ASSERT(g_bserrno == 0); 2353 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2354 blobid[i] = g_blobid; 2355 2356 /* Open a blob */ 2357 spdk_bs_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL); 2358 CU_ASSERT(g_bserrno == 0); 2359 CU_ASSERT(g_blob != NULL); 2360 blob[i] = g_blob; 2361 2362 /* Set a fairly large xattr on both blobs to eat up 2363 * metadata space 2364 */ 2365 value = calloc(dev->blocklen - 64, sizeof(char)); 2366 SPDK_CU_ASSERT_FATAL(value != NULL); 2367 memset(value, i, dev->blocklen / 2); 2368 rc = spdk_blob_set_xattr(blob[i], "name", value, dev->blocklen - 64); 2369 CU_ASSERT(rc == 0); 2370 free(value); 2371 } 2372 2373 /* Resize the blobs, alternating 1 cluster at a time. 2374 * This thwarts run length encoding and will cause spill 2375 * over of the extents. 2376 */ 2377 for (i = 0; i < 6; i++) { 2378 spdk_blob_resize(blob[i % 2], (i / 2) + 1, blob_op_complete, NULL); 2379 CU_ASSERT(g_bserrno == 0); 2380 } 2381 2382 for (i = 0; i < 2; i++) { 2383 spdk_blob_sync_md(blob[i], blob_op_complete, NULL); 2384 CU_ASSERT(g_bserrno == 0); 2385 } 2386 2387 /* Close the blobs */ 2388 for (i = 0; i < 2; i++) { 2389 spdk_blob_close(blob[i], blob_op_complete, NULL); 2390 CU_ASSERT(g_bserrno == 0); 2391 } 2392 2393 /* Unload the blobstore */ 2394 spdk_bs_unload(bs, bs_op_complete, NULL); 2395 CU_ASSERT(g_bserrno == 0); 2396 g_bs = NULL; 2397 g_blob = NULL; 2398 g_blobid = 0; 2399 bs = NULL; 2400 2401 dev = init_dev(); 2402 /* Load an existing blob store */ 2403 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2404 CU_ASSERT(g_bserrno == 0); 2405 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2406 bs = g_bs; 2407 2408 for (i = 0; i < 2; i++) { 2409 blob[i] = NULL; 2410 2411 spdk_bs_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL); 2412 CU_ASSERT(g_bserrno == 0); 2413 CU_ASSERT(g_blob != NULL); 2414 blob[i] = g_blob; 2415 2416 CU_ASSERT(spdk_blob_get_num_clusters(blob[i]) == 3); 2417 2418 spdk_blob_close(blob[i], blob_op_complete, NULL); 2419 CU_ASSERT(g_bserrno == 0); 2420 } 2421 2422 spdk_bs_unload(bs, bs_op_complete, NULL); 2423 CU_ASSERT(g_bserrno == 0); 2424 g_bs = NULL; 2425 } 2426 2427 static void 2428 blob_crc(void) 2429 { 2430 struct spdk_blob_store *bs; 2431 struct spdk_bs_dev *dev; 2432 struct spdk_blob *blob; 2433 spdk_blob_id blobid; 2434 uint32_t page_num; 2435 int index; 2436 struct spdk_blob_md_page *page; 2437 2438 dev = init_dev(); 2439 2440 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2441 CU_ASSERT(g_bserrno == 0); 2442 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2443 bs = g_bs; 2444 2445 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 2446 CU_ASSERT(g_bserrno == 0); 2447 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2448 blobid = g_blobid; 2449 2450 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2451 CU_ASSERT(g_bserrno == 0); 2452 CU_ASSERT(g_blob != NULL); 2453 blob = g_blob; 2454 2455 spdk_blob_close(blob, blob_op_complete, NULL); 2456 CU_ASSERT(g_bserrno == 0); 2457 2458 page_num = _spdk_bs_blobid_to_page(blobid); 2459 index = DEV_BUFFER_BLOCKLEN * (bs->md_start + page_num); 2460 page = (struct spdk_blob_md_page *)&g_dev_buffer[index]; 2461 page->crc = 0; 2462 2463 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2464 CU_ASSERT(g_bserrno == -EINVAL); 2465 CU_ASSERT(g_blob == NULL); 2466 g_bserrno = 0; 2467 2468 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 2469 CU_ASSERT(g_bserrno == -EINVAL); 2470 2471 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2472 CU_ASSERT(g_bserrno == 0); 2473 g_bs = NULL; 2474 } 2475 2476 static void 2477 super_block_crc(void) 2478 { 2479 struct spdk_bs_dev *dev; 2480 struct spdk_bs_super_block *super_block; 2481 struct spdk_bs_opts opts; 2482 2483 dev = init_dev(); 2484 spdk_bs_opts_init(&opts); 2485 2486 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2487 CU_ASSERT(g_bserrno == 0); 2488 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2489 2490 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2491 CU_ASSERT(g_bserrno == 0); 2492 g_bs = NULL; 2493 2494 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 2495 super_block->crc = 0; 2496 dev = init_dev(); 2497 2498 /* Load an existing blob store */ 2499 g_bserrno = 0; 2500 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2501 CU_ASSERT(g_bserrno == -EILSEQ); 2502 } 2503 2504 /* For blob dirty shutdown test case we do the following sub-test cases: 2505 * 1 Initialize new blob store and create 1 super blob with some xattrs, then we 2506 * dirty shutdown and reload the blob store and verify the xattrs. 2507 * 2 Resize the blob from 10 clusters to 20 clusters and then dirty shutdown, 2508 * reload the blob store and verify the clusters number. 2509 * 3 Create the second blob and then dirty shutdown, reload the blob store 2510 * and verify the second blob. 2511 * 4 Delete the second blob and then dirty shutdown, reload the blob store 2512 * and verify the second blob is invalid. 2513 * 5 Create the second blob again and also create the third blob, modify the 2514 * md of second blob which makes the md invalid, and then dirty shutdown, 2515 * reload the blob store verify the second blob, it should invalid and also 2516 * verify the third blob, it should correct. 2517 */ 2518 static void 2519 blob_dirty_shutdown(void) 2520 { 2521 int rc; 2522 int index; 2523 struct spdk_bs_dev *dev; 2524 spdk_blob_id blobid1, blobid2, blobid3; 2525 struct spdk_blob *blob; 2526 uint64_t length; 2527 uint64_t free_clusters; 2528 const void *value; 2529 size_t value_len; 2530 uint32_t page_num; 2531 struct spdk_blob_md_page *page; 2532 struct spdk_bs_opts opts; 2533 2534 dev = init_dev(); 2535 spdk_bs_opts_init(&opts); 2536 /* Initialize a new blob store */ 2537 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2538 CU_ASSERT(g_bserrno == 0); 2539 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2540 2541 /* Create first blob */ 2542 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2543 CU_ASSERT(g_bserrno == 0); 2544 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2545 blobid1 = g_blobid; 2546 2547 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 2548 CU_ASSERT(g_bserrno == 0); 2549 CU_ASSERT(g_blob != NULL); 2550 blob = g_blob; 2551 2552 /* Set some xattrs */ 2553 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 2554 CU_ASSERT(rc == 0); 2555 2556 length = 2345; 2557 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 2558 CU_ASSERT(rc == 0); 2559 2560 /* Resize the blob */ 2561 spdk_blob_resize(blob, 10, blob_op_complete, NULL); 2562 CU_ASSERT(g_bserrno == 0); 2563 2564 /* Set the blob as the super blob */ 2565 spdk_bs_set_super(g_bs, blobid1, blob_op_complete, NULL); 2566 CU_ASSERT(g_bserrno == 0); 2567 2568 free_clusters = spdk_bs_free_cluster_count(g_bs); 2569 2570 spdk_blob_close(blob, blob_op_complete, NULL); 2571 blob = NULL; 2572 g_blob = NULL; 2573 g_blobid = SPDK_BLOBID_INVALID; 2574 2575 /* Dirty shutdown */ 2576 _spdk_bs_free(g_bs); 2577 2578 /* reload blobstore */ 2579 dev = init_dev(); 2580 spdk_bs_opts_init(&opts); 2581 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2582 CU_ASSERT(g_bserrno == 0); 2583 2584 /* Get the super blob */ 2585 spdk_bs_get_super(g_bs, blob_op_with_id_complete, NULL); 2586 CU_ASSERT(g_bserrno == 0); 2587 CU_ASSERT(blobid1 == g_blobid); 2588 2589 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 2590 CU_ASSERT(g_bserrno == 0); 2591 CU_ASSERT(g_blob != NULL); 2592 blob = g_blob; 2593 2594 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 2595 2596 /* Get the xattrs */ 2597 value = NULL; 2598 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 2599 CU_ASSERT(rc == 0); 2600 SPDK_CU_ASSERT_FATAL(value != NULL); 2601 CU_ASSERT(*(uint64_t *)value == length); 2602 CU_ASSERT(value_len == 8); 2603 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 2604 2605 /* Resize the blob */ 2606 spdk_blob_resize(blob, 20, blob_op_complete, NULL); 2607 CU_ASSERT(g_bserrno == 0); 2608 2609 free_clusters = spdk_bs_free_cluster_count(g_bs); 2610 2611 spdk_blob_close(blob, blob_op_complete, NULL); 2612 CU_ASSERT(g_bserrno == 0); 2613 blob = NULL; 2614 g_blob = NULL; 2615 g_blobid = SPDK_BLOBID_INVALID; 2616 2617 /* Dirty shutdown */ 2618 _spdk_bs_free(g_bs); 2619 2620 /* reload the blobstore */ 2621 dev = init_dev(); 2622 spdk_bs_opts_init(&opts); 2623 /* Load an existing blob store */ 2624 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2625 CU_ASSERT(g_bserrno == 0); 2626 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2627 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 2628 CU_ASSERT(g_bserrno == 0); 2629 CU_ASSERT(g_blob != NULL); 2630 blob = g_blob; 2631 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 20); 2632 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 2633 2634 spdk_blob_close(blob, blob_op_complete, NULL); 2635 CU_ASSERT(g_bserrno == 0); 2636 blob = NULL; 2637 g_blob = NULL; 2638 g_blobid = SPDK_BLOBID_INVALID; 2639 2640 /* Create second blob */ 2641 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2642 CU_ASSERT(g_bserrno == 0); 2643 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2644 blobid2 = g_blobid; 2645 2646 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 2647 CU_ASSERT(g_bserrno == 0); 2648 CU_ASSERT(g_blob != NULL); 2649 blob = g_blob; 2650 2651 /* Set some xattrs */ 2652 rc = spdk_blob_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1); 2653 CU_ASSERT(rc == 0); 2654 2655 length = 5432; 2656 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 2657 CU_ASSERT(rc == 0); 2658 2659 /* Resize the blob */ 2660 spdk_blob_resize(blob, 10, blob_op_complete, NULL); 2661 CU_ASSERT(g_bserrno == 0); 2662 2663 free_clusters = spdk_bs_free_cluster_count(g_bs); 2664 2665 spdk_blob_close(blob, blob_op_complete, NULL); 2666 blob = NULL; 2667 g_blob = NULL; 2668 g_blobid = SPDK_BLOBID_INVALID; 2669 2670 /* Dirty shutdown */ 2671 _spdk_bs_free(g_bs); 2672 2673 /* reload the blobstore */ 2674 dev = init_dev(); 2675 spdk_bs_opts_init(&opts); 2676 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2677 CU_ASSERT(g_bserrno == 0); 2678 2679 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 2680 CU_ASSERT(g_bserrno == 0); 2681 CU_ASSERT(g_blob != NULL); 2682 blob = g_blob; 2683 2684 /* Get the xattrs */ 2685 value = NULL; 2686 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 2687 CU_ASSERT(rc == 0); 2688 SPDK_CU_ASSERT_FATAL(value != NULL); 2689 CU_ASSERT(*(uint64_t *)value == length); 2690 CU_ASSERT(value_len == 8); 2691 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 2692 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 2693 2694 spdk_blob_close(blob, blob_op_complete, NULL); 2695 CU_ASSERT(g_bserrno == 0); 2696 spdk_bs_delete_blob(g_bs, blobid2, blob_op_complete, NULL); 2697 CU_ASSERT(g_bserrno == 0); 2698 2699 free_clusters = spdk_bs_free_cluster_count(g_bs); 2700 2701 /* Dirty shutdown */ 2702 _spdk_bs_free(g_bs); 2703 /* reload the blobstore */ 2704 dev = init_dev(); 2705 spdk_bs_opts_init(&opts); 2706 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2707 CU_ASSERT(g_bserrno == 0); 2708 2709 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 2710 CU_ASSERT(g_bserrno != 0); 2711 CU_ASSERT(g_blob == NULL); 2712 2713 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 2714 CU_ASSERT(g_bserrno == 0); 2715 CU_ASSERT(g_blob != NULL); 2716 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 2717 spdk_blob_close(g_blob, blob_op_complete, NULL); 2718 CU_ASSERT(g_bserrno == 0); 2719 2720 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2721 CU_ASSERT(g_bserrno == 0); 2722 g_bs = NULL; 2723 2724 /* reload the blobstore */ 2725 dev = init_dev(); 2726 spdk_bs_opts_init(&opts); 2727 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2728 CU_ASSERT(g_bserrno == 0); 2729 2730 /* Create second blob */ 2731 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2732 CU_ASSERT(g_bserrno == 0); 2733 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2734 blobid2 = g_blobid; 2735 2736 /* Create third blob */ 2737 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2738 CU_ASSERT(g_bserrno == 0); 2739 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2740 blobid3 = g_blobid; 2741 2742 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 2743 CU_ASSERT(g_bserrno == 0); 2744 CU_ASSERT(g_blob != NULL); 2745 blob = g_blob; 2746 2747 /* Set some xattrs for second blob */ 2748 rc = spdk_blob_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1); 2749 CU_ASSERT(rc == 0); 2750 2751 length = 5432; 2752 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 2753 CU_ASSERT(rc == 0); 2754 2755 spdk_blob_close(blob, blob_op_complete, NULL); 2756 blob = NULL; 2757 g_blob = NULL; 2758 g_blobid = SPDK_BLOBID_INVALID; 2759 2760 spdk_bs_open_blob(g_bs, blobid3, blob_op_with_handle_complete, NULL); 2761 CU_ASSERT(g_bserrno == 0); 2762 CU_ASSERT(g_blob != NULL); 2763 blob = g_blob; 2764 2765 /* Set some xattrs for third blob */ 2766 rc = spdk_blob_set_xattr(blob, "name", "log2.txt", strlen("log2.txt") + 1); 2767 CU_ASSERT(rc == 0); 2768 2769 length = 5432; 2770 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 2771 CU_ASSERT(rc == 0); 2772 2773 spdk_blob_close(blob, blob_op_complete, NULL); 2774 blob = NULL; 2775 g_blob = NULL; 2776 g_blobid = SPDK_BLOBID_INVALID; 2777 2778 /* Mark second blob as invalid */ 2779 page_num = _spdk_bs_blobid_to_page(blobid2); 2780 2781 index = DEV_BUFFER_BLOCKLEN * (g_bs->md_start + page_num); 2782 page = (struct spdk_blob_md_page *)&g_dev_buffer[index]; 2783 page->sequence_num = 1; 2784 page->crc = _spdk_blob_md_page_calc_crc(page); 2785 2786 free_clusters = spdk_bs_free_cluster_count(g_bs); 2787 2788 /* Dirty shutdown */ 2789 _spdk_bs_free(g_bs); 2790 /* reload the blobstore */ 2791 dev = init_dev(); 2792 spdk_bs_opts_init(&opts); 2793 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2794 CU_ASSERT(g_bserrno == 0); 2795 2796 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 2797 CU_ASSERT(g_bserrno != 0); 2798 CU_ASSERT(g_blob == NULL); 2799 2800 spdk_bs_open_blob(g_bs, blobid3, blob_op_with_handle_complete, NULL); 2801 CU_ASSERT(g_bserrno == 0); 2802 CU_ASSERT(g_blob != NULL); 2803 blob = g_blob; 2804 2805 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 2806 2807 spdk_blob_close(blob, blob_op_complete, NULL); 2808 blob = NULL; 2809 g_blob = NULL; 2810 g_blobid = SPDK_BLOBID_INVALID; 2811 2812 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2813 CU_ASSERT(g_bserrno == 0); 2814 g_bs = NULL; 2815 } 2816 2817 static void 2818 blob_flags(void) 2819 { 2820 struct spdk_bs_dev *dev; 2821 spdk_blob_id blobid_invalid, blobid_data_ro, blobid_md_ro; 2822 struct spdk_blob *blob_invalid, *blob_data_ro, *blob_md_ro; 2823 struct spdk_bs_opts opts; 2824 int rc; 2825 2826 dev = init_dev(); 2827 spdk_bs_opts_init(&opts); 2828 2829 /* Initialize a new blob store */ 2830 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2831 CU_ASSERT(g_bserrno == 0); 2832 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2833 2834 /* Create three blobs - one each for testing invalid, data_ro and md_ro flags. */ 2835 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2836 CU_ASSERT(g_bserrno == 0); 2837 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2838 blobid_invalid = g_blobid; 2839 2840 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2841 CU_ASSERT(g_bserrno == 0); 2842 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2843 blobid_data_ro = g_blobid; 2844 2845 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2846 CU_ASSERT(g_bserrno == 0); 2847 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2848 blobid_md_ro = g_blobid; 2849 2850 spdk_bs_open_blob(g_bs, blobid_invalid, blob_op_with_handle_complete, NULL); 2851 CU_ASSERT(g_bserrno == 0); 2852 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2853 blob_invalid = g_blob; 2854 2855 spdk_bs_open_blob(g_bs, blobid_data_ro, blob_op_with_handle_complete, NULL); 2856 CU_ASSERT(g_bserrno == 0); 2857 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2858 blob_data_ro = g_blob; 2859 2860 spdk_bs_open_blob(g_bs, blobid_md_ro, blob_op_with_handle_complete, NULL); 2861 CU_ASSERT(g_bserrno == 0); 2862 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2863 blob_md_ro = g_blob; 2864 2865 /* Change the size of blob_data_ro to check if flags are serialized 2866 * when blob has non zero number of extents */ 2867 spdk_blob_resize(blob_data_ro, 10, blob_op_complete, NULL); 2868 CU_ASSERT(g_bserrno == 0); 2869 2870 /* Set the xattr to check if flags are serialized 2871 * when blob has non zero number of xattrs */ 2872 rc = spdk_blob_set_xattr(blob_md_ro, "name", "log.txt", strlen("log.txt") + 1); 2873 CU_ASSERT(rc == 0); 2874 2875 blob_invalid->invalid_flags = (1ULL << 63); 2876 blob_invalid->state = SPDK_BLOB_STATE_DIRTY; 2877 blob_data_ro->data_ro_flags = (1ULL << 62); 2878 blob_data_ro->state = SPDK_BLOB_STATE_DIRTY; 2879 blob_md_ro->md_ro_flags = (1ULL << 61); 2880 blob_md_ro->state = SPDK_BLOB_STATE_DIRTY; 2881 2882 g_bserrno = -1; 2883 spdk_blob_sync_md(blob_invalid, blob_op_complete, NULL); 2884 CU_ASSERT(g_bserrno == 0); 2885 g_bserrno = -1; 2886 spdk_blob_sync_md(blob_data_ro, blob_op_complete, NULL); 2887 CU_ASSERT(g_bserrno == 0); 2888 g_bserrno = -1; 2889 spdk_blob_sync_md(blob_md_ro, blob_op_complete, NULL); 2890 CU_ASSERT(g_bserrno == 0); 2891 2892 g_bserrno = -1; 2893 spdk_blob_close(blob_invalid, blob_op_complete, NULL); 2894 CU_ASSERT(g_bserrno == 0); 2895 blob_invalid = NULL; 2896 g_bserrno = -1; 2897 spdk_blob_close(blob_data_ro, blob_op_complete, NULL); 2898 CU_ASSERT(g_bserrno == 0); 2899 blob_data_ro = NULL; 2900 g_bserrno = -1; 2901 spdk_blob_close(blob_md_ro, blob_op_complete, NULL); 2902 CU_ASSERT(g_bserrno == 0); 2903 blob_md_ro = NULL; 2904 2905 g_blob = NULL; 2906 g_blobid = SPDK_BLOBID_INVALID; 2907 2908 /* Unload the blob store */ 2909 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2910 CU_ASSERT(g_bserrno == 0); 2911 g_bs = NULL; 2912 2913 /* Load an existing blob store */ 2914 dev = init_dev(); 2915 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2916 CU_ASSERT(g_bserrno == 0); 2917 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2918 2919 g_blob = NULL; 2920 g_bserrno = 0; 2921 spdk_bs_open_blob(g_bs, blobid_invalid, blob_op_with_handle_complete, NULL); 2922 CU_ASSERT(g_bserrno != 0); 2923 CU_ASSERT(g_blob == NULL); 2924 2925 g_blob = NULL; 2926 g_bserrno = -1; 2927 spdk_bs_open_blob(g_bs, blobid_data_ro, blob_op_with_handle_complete, NULL); 2928 CU_ASSERT(g_bserrno == 0); 2929 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2930 blob_data_ro = g_blob; 2931 /* If an unknown data_ro flag was found, the blob should be marked both data and md read-only. */ 2932 CU_ASSERT(blob_data_ro->data_ro == true); 2933 CU_ASSERT(blob_data_ro->md_ro == true); 2934 CU_ASSERT(spdk_blob_get_num_clusters(blob_data_ro) == 10); 2935 2936 g_blob = NULL; 2937 g_bserrno = -1; 2938 spdk_bs_open_blob(g_bs, blobid_md_ro, blob_op_with_handle_complete, NULL); 2939 CU_ASSERT(g_bserrno == 0); 2940 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2941 blob_md_ro = g_blob; 2942 CU_ASSERT(blob_md_ro->data_ro == false); 2943 CU_ASSERT(blob_md_ro->md_ro == true); 2944 2945 g_bserrno = -1; 2946 spdk_blob_sync_md(blob_md_ro, blob_op_complete, NULL); 2947 CU_ASSERT(g_bserrno == 0); 2948 2949 spdk_blob_close(blob_data_ro, blob_op_complete, NULL); 2950 CU_ASSERT(g_bserrno == 0); 2951 spdk_blob_close(blob_md_ro, blob_op_complete, NULL); 2952 CU_ASSERT(g_bserrno == 0); 2953 2954 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2955 CU_ASSERT(g_bserrno == 0); 2956 } 2957 2958 static void 2959 bs_version(void) 2960 { 2961 struct spdk_bs_super_block *super; 2962 struct spdk_bs_dev *dev; 2963 struct spdk_bs_opts opts; 2964 spdk_blob_id blobid; 2965 2966 dev = init_dev(); 2967 spdk_bs_opts_init(&opts); 2968 2969 /* Initialize a new blob store */ 2970 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2971 CU_ASSERT(g_bserrno == 0); 2972 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2973 2974 /* Unload the blob store */ 2975 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2976 CU_ASSERT(g_bserrno == 0); 2977 g_bs = NULL; 2978 2979 /* 2980 * Change the bs version on disk. This will allow us to 2981 * test that the version does not get modified automatically 2982 * when loading and unloading the blobstore. 2983 */ 2984 super = (struct spdk_bs_super_block *)&g_dev_buffer[0]; 2985 CU_ASSERT(super->version == SPDK_BS_VERSION); 2986 CU_ASSERT(super->clean == 1); 2987 super->version = 2; 2988 /* 2989 * Version 2 metadata does not have a used blobid mask, so clear 2990 * those fields in the super block and zero the corresponding 2991 * region on "disk". We will use this to ensure blob IDs are 2992 * correctly reconstructed. 2993 */ 2994 memset(&g_dev_buffer[super->used_blobid_mask_start * SPDK_BS_PAGE_SIZE], 0, 2995 super->used_blobid_mask_len * SPDK_BS_PAGE_SIZE); 2996 super->used_blobid_mask_start = 0; 2997 super->used_blobid_mask_len = 0; 2998 super->crc = _spdk_blob_md_page_calc_crc(super); 2999 3000 /* Load an existing blob store */ 3001 dev = init_dev(); 3002 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3003 CU_ASSERT(g_bserrno == 0); 3004 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3005 CU_ASSERT(super->clean == 0); 3006 3007 /* 3008 * Create a blob - just to make sure that when we unload it 3009 * results in writing the super block (since metadata pages 3010 * were allocated. 3011 */ 3012 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 3013 CU_ASSERT(g_bserrno == 0); 3014 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3015 blobid = g_blobid; 3016 3017 /* Unload the blob store */ 3018 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3019 CU_ASSERT(g_bserrno == 0); 3020 g_bs = NULL; 3021 CU_ASSERT(super->version == 2); 3022 CU_ASSERT(super->used_blobid_mask_start == 0); 3023 CU_ASSERT(super->used_blobid_mask_len == 0); 3024 3025 dev = init_dev(); 3026 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3027 CU_ASSERT(g_bserrno == 0); 3028 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3029 3030 g_blob = NULL; 3031 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 3032 CU_ASSERT(g_bserrno == 0); 3033 CU_ASSERT(g_blob != NULL); 3034 3035 spdk_blob_close(g_blob, blob_op_complete, NULL); 3036 CU_ASSERT(g_bserrno == 0); 3037 3038 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3039 CU_ASSERT(g_bserrno == 0); 3040 g_bs = NULL; 3041 CU_ASSERT(super->version == 2); 3042 CU_ASSERT(super->used_blobid_mask_start == 0); 3043 CU_ASSERT(super->used_blobid_mask_len == 0); 3044 } 3045 3046 static void 3047 blob_set_xattrs(void) 3048 { 3049 struct spdk_blob_store *bs; 3050 struct spdk_bs_dev *dev; 3051 struct spdk_blob *blob; 3052 struct spdk_blob_opts opts; 3053 spdk_blob_id blobid; 3054 const void *value; 3055 size_t value_len; 3056 int rc; 3057 3058 dev = init_dev(); 3059 3060 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3061 CU_ASSERT(g_bserrno == 0); 3062 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3063 bs = g_bs; 3064 3065 /* Create blob with extra attributes */ 3066 spdk_blob_opts_init(&opts); 3067 3068 opts.xattrs.names = g_xattr_names; 3069 opts.xattrs.get_value = _get_xattr_value; 3070 opts.xattrs.count = 3; 3071 opts.xattrs.ctx = &g_ctx; 3072 3073 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 3074 CU_ASSERT(g_bserrno == 0); 3075 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3076 blobid = g_blobid; 3077 3078 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3079 CU_ASSERT(g_bserrno == 0); 3080 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3081 blob = g_blob; 3082 3083 /* Get the xattrs */ 3084 value = NULL; 3085 3086 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[0], &value, &value_len); 3087 CU_ASSERT(rc == 0); 3088 SPDK_CU_ASSERT_FATAL(value != NULL); 3089 CU_ASSERT(value_len == strlen(g_xattr_values[0])); 3090 CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len); 3091 3092 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[1], &value, &value_len); 3093 CU_ASSERT(rc == 0); 3094 SPDK_CU_ASSERT_FATAL(value != NULL); 3095 CU_ASSERT(value_len == strlen(g_xattr_values[1])); 3096 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len); 3097 3098 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[2], &value, &value_len); 3099 CU_ASSERT(rc == 0); 3100 SPDK_CU_ASSERT_FATAL(value != NULL); 3101 CU_ASSERT(value_len == strlen(g_xattr_values[2])); 3102 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len); 3103 3104 /* Try to get non existing attribute */ 3105 3106 rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len); 3107 CU_ASSERT(rc == -ENOENT); 3108 3109 spdk_blob_close(blob, blob_op_complete, NULL); 3110 CU_ASSERT(g_bserrno == 0); 3111 blob = NULL; 3112 g_blob = NULL; 3113 g_blobid = SPDK_BLOBID_INVALID; 3114 3115 /* NULL callback */ 3116 spdk_blob_opts_init(&opts); 3117 opts.xattrs.names = g_xattr_names; 3118 opts.xattrs.get_value = NULL; 3119 opts.xattrs.count = 1; 3120 opts.xattrs.ctx = &g_ctx; 3121 3122 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 3123 CU_ASSERT(g_bserrno == -EINVAL); 3124 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3125 3126 /* NULL values */ 3127 spdk_blob_opts_init(&opts); 3128 opts.xattrs.names = g_xattr_names; 3129 opts.xattrs.get_value = _get_xattr_value_null; 3130 opts.xattrs.count = 1; 3131 opts.xattrs.ctx = NULL; 3132 3133 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 3134 CU_ASSERT(g_bserrno == -EINVAL); 3135 3136 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3137 CU_ASSERT(g_bserrno == 0); 3138 g_bs = NULL; 3139 3140 } 3141 3142 static void 3143 blob_thin_prov_alloc(void) 3144 { 3145 struct spdk_blob_store *bs; 3146 struct spdk_bs_dev *dev; 3147 struct spdk_blob *blob; 3148 struct spdk_blob_opts opts; 3149 spdk_blob_id blobid; 3150 uint64_t free_clusters; 3151 3152 dev = init_dev(); 3153 3154 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3155 CU_ASSERT(g_bserrno == 0); 3156 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3157 bs = g_bs; 3158 free_clusters = spdk_bs_free_cluster_count(bs); 3159 3160 /* Set blob as thin provisioned */ 3161 spdk_blob_opts_init(&opts); 3162 opts.thin_provision = true; 3163 3164 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 3165 CU_ASSERT(g_bserrno == 0); 3166 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3167 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3168 blobid = g_blobid; 3169 3170 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3171 CU_ASSERT(g_bserrno == 0); 3172 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3173 blob = g_blob; 3174 3175 CU_ASSERT(blob->active.num_clusters == 0); 3176 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0); 3177 3178 /* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */ 3179 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 3180 CU_ASSERT(g_bserrno == 0); 3181 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3182 CU_ASSERT(blob->active.num_clusters == 5); 3183 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 3184 3185 /* Shrink the blob to 3 clusters - still unallocated */ 3186 spdk_blob_resize(blob, 3, blob_op_complete, NULL); 3187 CU_ASSERT(g_bserrno == 0); 3188 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3189 CU_ASSERT(blob->active.num_clusters == 3); 3190 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 3); 3191 3192 spdk_blob_sync_md(blob, blob_op_complete, NULL); 3193 CU_ASSERT(g_bserrno == 0); 3194 /* Sync must not change anything */ 3195 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3196 CU_ASSERT(blob->active.num_clusters == 3); 3197 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 3); 3198 3199 spdk_blob_close(blob, blob_op_complete, NULL); 3200 CU_ASSERT(g_bserrno == 0); 3201 3202 /* Unload the blob store */ 3203 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3204 CU_ASSERT(g_bserrno == 0); 3205 g_bs = NULL; 3206 g_blob = NULL; 3207 g_blobid = 0; 3208 3209 /* Load an existing blob store */ 3210 dev = init_dev(); 3211 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 3212 CU_ASSERT(g_bserrno == 0); 3213 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3214 3215 bs = g_bs; 3216 3217 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 3218 CU_ASSERT(g_bserrno == 0); 3219 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3220 blob = g_blob; 3221 3222 /* Check that clusters allocation and size is still the same */ 3223 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3224 CU_ASSERT(blob->active.num_clusters == 3); 3225 3226 spdk_blob_close(blob, blob_op_complete, NULL); 3227 CU_ASSERT(g_bserrno == 0); 3228 3229 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 3230 CU_ASSERT(g_bserrno == 0); 3231 3232 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3233 CU_ASSERT(g_bserrno == 0); 3234 g_bs = NULL; 3235 } 3236 3237 static void 3238 blob_insert_cluster_msg(void) 3239 { 3240 struct spdk_blob_store *bs; 3241 struct spdk_bs_dev *dev; 3242 struct spdk_blob *blob; 3243 struct spdk_blob_opts opts; 3244 spdk_blob_id blobid; 3245 uint64_t free_clusters; 3246 3247 dev = init_dev(); 3248 3249 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3250 CU_ASSERT(g_bserrno == 0); 3251 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3252 bs = g_bs; 3253 free_clusters = spdk_bs_free_cluster_count(bs); 3254 3255 /* Set blob as thin provisioned */ 3256 spdk_blob_opts_init(&opts); 3257 opts.thin_provision = true; 3258 opts.num_clusters = 4; 3259 3260 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 3261 CU_ASSERT(g_bserrno == 0); 3262 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3263 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3264 blobid = g_blobid; 3265 3266 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3267 CU_ASSERT(g_bserrno == 0); 3268 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3269 blob = g_blob; 3270 3271 CU_ASSERT(blob->active.num_clusters == 4); 3272 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 4); 3273 CU_ASSERT(blob->active.clusters[1] == 0); 3274 3275 _spdk_bs_claim_cluster(bs, 0xF); 3276 _spdk_blob_insert_cluster_on_md_thread(blob, 1, 0xF, blob_op_complete, NULL); 3277 3278 CU_ASSERT(blob->active.clusters[1] != 0); 3279 3280 spdk_blob_close(blob, blob_op_complete, NULL); 3281 CU_ASSERT(g_bserrno == 0); 3282 3283 /* Unload the blob store */ 3284 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3285 CU_ASSERT(g_bserrno == 0); 3286 g_bs = NULL; 3287 g_blob = NULL; 3288 g_blobid = 0; 3289 3290 /* Load an existing blob store */ 3291 dev = init_dev(); 3292 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 3293 CU_ASSERT(g_bserrno == 0); 3294 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3295 3296 bs = g_bs; 3297 3298 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 3299 CU_ASSERT(g_bserrno == 0); 3300 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3301 blob = g_blob; 3302 3303 CU_ASSERT(blob->active.clusters[1] != 0); 3304 3305 spdk_blob_close(blob, blob_op_complete, NULL); 3306 CU_ASSERT(g_bserrno == 0); 3307 3308 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 3309 CU_ASSERT(g_bserrno == 0); 3310 3311 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3312 CU_ASSERT(g_bserrno == 0); 3313 g_bs = NULL; 3314 } 3315 3316 static void 3317 blob_thin_prov_rw(void) 3318 { 3319 static const uint8_t zero[10 * 4096] = { 0 }; 3320 struct spdk_blob_store *bs; 3321 struct spdk_bs_dev *dev; 3322 struct spdk_blob *blob; 3323 struct spdk_io_channel *channel; 3324 struct spdk_blob_opts opts; 3325 spdk_blob_id blobid; 3326 uint64_t free_clusters; 3327 uint8_t payload_read[10 * 4096]; 3328 uint8_t payload_write[10 * 4096]; 3329 3330 dev = init_dev(); 3331 3332 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3333 CU_ASSERT(g_bserrno == 0); 3334 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3335 bs = g_bs; 3336 free_clusters = spdk_bs_free_cluster_count(bs); 3337 3338 channel = spdk_bs_alloc_io_channel(bs); 3339 CU_ASSERT(channel != NULL); 3340 3341 spdk_blob_opts_init(&opts); 3342 opts.thin_provision = true; 3343 3344 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 3345 CU_ASSERT(g_bserrno == 0); 3346 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3347 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3348 blobid = g_blobid; 3349 3350 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3351 CU_ASSERT(g_bserrno == 0); 3352 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3353 blob = g_blob; 3354 3355 CU_ASSERT(blob->active.num_clusters == 0); 3356 3357 /* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */ 3358 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 3359 CU_ASSERT(g_bserrno == 0); 3360 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3361 CU_ASSERT(blob->active.num_clusters == 5); 3362 3363 spdk_blob_sync_md(blob, blob_op_complete, NULL); 3364 CU_ASSERT(g_bserrno == 0); 3365 /* Sync must not change anything */ 3366 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3367 CU_ASSERT(blob->active.num_clusters == 5); 3368 3369 /* Payload should be all zeros from unallocated clusters */ 3370 memset(payload_read, 0xFF, sizeof(payload_read)); 3371 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 3372 CU_ASSERT(g_bserrno == 0); 3373 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 3374 3375 memset(payload_write, 0xE5, sizeof(payload_write)); 3376 spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL); 3377 CU_ASSERT(g_bserrno == 0); 3378 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 3379 3380 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 3381 CU_ASSERT(g_bserrno == 0); 3382 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 3383 3384 spdk_blob_close(blob, blob_op_complete, NULL); 3385 CU_ASSERT(g_bserrno == 0); 3386 3387 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 3388 CU_ASSERT(g_bserrno == 0); 3389 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3390 3391 spdk_bs_free_io_channel(channel); 3392 3393 /* Unload the blob store */ 3394 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3395 CU_ASSERT(g_bserrno == 0); 3396 g_bs = NULL; 3397 g_blob = NULL; 3398 g_blobid = 0; 3399 } 3400 3401 static void 3402 blob_thin_prov_rw_iov(void) 3403 { 3404 static const uint8_t zero[10 * 4096] = { 0 }; 3405 struct spdk_blob_store *bs; 3406 struct spdk_bs_dev *dev; 3407 struct spdk_blob *blob; 3408 struct spdk_io_channel *channel; 3409 struct spdk_blob_opts opts; 3410 spdk_blob_id blobid; 3411 uint64_t free_clusters; 3412 uint8_t payload_read[10 * 4096]; 3413 uint8_t payload_write[10 * 4096]; 3414 struct iovec iov_read[3]; 3415 struct iovec iov_write[3]; 3416 3417 dev = init_dev(); 3418 3419 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3420 CU_ASSERT(g_bserrno == 0); 3421 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3422 bs = g_bs; 3423 free_clusters = spdk_bs_free_cluster_count(bs); 3424 3425 channel = spdk_bs_alloc_io_channel(bs); 3426 CU_ASSERT(channel != NULL); 3427 3428 spdk_blob_opts_init(&opts); 3429 opts.thin_provision = true; 3430 3431 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 3432 CU_ASSERT(g_bserrno == 0); 3433 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3434 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3435 blobid = g_blobid; 3436 3437 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3438 CU_ASSERT(g_bserrno == 0); 3439 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3440 blob = g_blob; 3441 3442 CU_ASSERT(blob->active.num_clusters == 0); 3443 3444 /* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */ 3445 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 3446 CU_ASSERT(g_bserrno == 0); 3447 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3448 CU_ASSERT(blob->active.num_clusters == 5); 3449 3450 spdk_blob_sync_md(blob, blob_op_complete, NULL); 3451 CU_ASSERT(g_bserrno == 0); 3452 /* Sync must not change anything */ 3453 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3454 CU_ASSERT(blob->active.num_clusters == 5); 3455 3456 /* Payload should be all zeros from unallocated clusters */ 3457 memset(payload_read, 0xAA, sizeof(payload_read)); 3458 iov_read[0].iov_base = payload_read; 3459 iov_read[0].iov_len = 3 * 4096; 3460 iov_read[1].iov_base = payload_read + 3 * 4096; 3461 iov_read[1].iov_len = 4 * 4096; 3462 iov_read[2].iov_base = payload_read + 7 * 4096; 3463 iov_read[2].iov_len = 3 * 4096; 3464 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 3465 CU_ASSERT(g_bserrno == 0); 3466 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 3467 3468 memset(payload_write, 0xE5, sizeof(payload_write)); 3469 iov_write[0].iov_base = payload_write; 3470 iov_write[0].iov_len = 1 * 4096; 3471 iov_write[1].iov_base = payload_write + 1 * 4096; 3472 iov_write[1].iov_len = 5 * 4096; 3473 iov_write[2].iov_base = payload_write + 6 * 4096; 3474 iov_write[2].iov_len = 4 * 4096; 3475 3476 spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 3477 CU_ASSERT(g_bserrno == 0); 3478 3479 memset(payload_read, 0xAA, sizeof(payload_read)); 3480 iov_read[0].iov_base = payload_read; 3481 iov_read[0].iov_len = 3 * 4096; 3482 iov_read[1].iov_base = payload_read + 3 * 4096; 3483 iov_read[1].iov_len = 4 * 4096; 3484 iov_read[2].iov_base = payload_read + 7 * 4096; 3485 iov_read[2].iov_len = 3 * 4096; 3486 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 3487 CU_ASSERT(g_bserrno == 0); 3488 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 3489 3490 spdk_blob_close(blob, blob_op_complete, NULL); 3491 CU_ASSERT(g_bserrno == 0); 3492 3493 spdk_bs_free_io_channel(channel); 3494 3495 /* Unload the blob store */ 3496 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3497 CU_ASSERT(g_bserrno == 0); 3498 g_bs = NULL; 3499 g_blob = NULL; 3500 g_blobid = 0; 3501 } 3502 3503 struct iter_ctx { 3504 int current_iter; 3505 spdk_blob_id blobid[4]; 3506 }; 3507 3508 static void 3509 test_iter(void *arg, struct spdk_blob *blob, int bserrno) 3510 { 3511 struct iter_ctx *iter_ctx = arg; 3512 spdk_blob_id blobid; 3513 3514 CU_ASSERT(bserrno == 0); 3515 blobid = spdk_blob_get_id(blob); 3516 CU_ASSERT(blobid == iter_ctx->blobid[iter_ctx->current_iter++]); 3517 } 3518 3519 static void 3520 bs_load_iter(void) 3521 { 3522 struct spdk_bs_dev *dev; 3523 struct iter_ctx iter_ctx = { 0 }; 3524 struct spdk_blob *blob; 3525 int i, rc; 3526 struct spdk_bs_opts opts; 3527 3528 dev = init_dev(); 3529 spdk_bs_opts_init(&opts); 3530 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 3531 3532 /* Initialize a new blob store */ 3533 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 3534 CU_ASSERT(g_bserrno == 0); 3535 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3536 3537 for (i = 0; i < 4; i++) { 3538 g_bserrno = -1; 3539 g_blobid = SPDK_BLOBID_INVALID; 3540 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 3541 CU_ASSERT(g_bserrno == 0); 3542 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3543 iter_ctx.blobid[i] = g_blobid; 3544 3545 g_bserrno = -1; 3546 g_blob = NULL; 3547 spdk_bs_open_blob(g_bs, g_blobid, blob_op_with_handle_complete, NULL); 3548 CU_ASSERT(g_bserrno == 0); 3549 CU_ASSERT(g_blob != NULL); 3550 blob = g_blob; 3551 3552 /* Just save the blobid as an xattr for testing purposes. */ 3553 rc = spdk_blob_set_xattr(blob, "blobid", &g_blobid, sizeof(g_blobid)); 3554 CU_ASSERT(rc == 0); 3555 3556 /* Resize the blob */ 3557 spdk_blob_resize(blob, i, blob_op_complete, NULL); 3558 CU_ASSERT(g_bserrno == 0); 3559 3560 spdk_blob_close(blob, blob_op_complete, NULL); 3561 CU_ASSERT(g_bserrno == 0); 3562 } 3563 3564 g_bserrno = -1; 3565 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3566 CU_ASSERT(g_bserrno == 0); 3567 3568 dev = init_dev(); 3569 spdk_bs_opts_init(&opts); 3570 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 3571 opts.iter_cb_fn = test_iter; 3572 opts.iter_cb_arg = &iter_ctx; 3573 3574 /* Test blob iteration during load after a clean shutdown. */ 3575 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3576 CU_ASSERT(g_bserrno == 0); 3577 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3578 3579 /* Dirty shutdown */ 3580 _spdk_bs_free(g_bs); 3581 3582 dev = init_dev(); 3583 spdk_bs_opts_init(&opts); 3584 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 3585 opts.iter_cb_fn = test_iter; 3586 iter_ctx.current_iter = 0; 3587 opts.iter_cb_arg = &iter_ctx; 3588 3589 /* Test blob iteration during load after a dirty shutdown. */ 3590 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3591 CU_ASSERT(g_bserrno == 0); 3592 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3593 3594 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3595 CU_ASSERT(g_bserrno == 0); 3596 g_bs = NULL; 3597 } 3598 3599 static void 3600 blob_snapshot_rw(void) 3601 { 3602 static const uint8_t zero[10 * 4096] = { 0 }; 3603 struct spdk_blob_store *bs; 3604 struct spdk_bs_dev *dev; 3605 struct spdk_blob *blob, *snapshot; 3606 struct spdk_io_channel *channel; 3607 struct spdk_blob_opts opts; 3608 spdk_blob_id blobid, snapshotid; 3609 uint64_t free_clusters; 3610 uint8_t payload_read[10 * 4096]; 3611 uint8_t payload_write[10 * 4096]; 3612 3613 dev = init_dev(); 3614 3615 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3616 CU_ASSERT(g_bserrno == 0); 3617 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3618 bs = g_bs; 3619 free_clusters = spdk_bs_free_cluster_count(bs); 3620 3621 channel = spdk_bs_alloc_io_channel(bs); 3622 CU_ASSERT(channel != NULL); 3623 3624 spdk_blob_opts_init(&opts); 3625 opts.thin_provision = true; 3626 opts.num_clusters = 5; 3627 3628 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 3629 CU_ASSERT(g_bserrno == 0); 3630 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3631 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3632 blobid = g_blobid; 3633 3634 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3635 CU_ASSERT(g_bserrno == 0); 3636 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3637 blob = g_blob; 3638 3639 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 3640 3641 memset(payload_read, 0xFF, sizeof(payload_read)); 3642 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 3643 CU_ASSERT(g_bserrno == 0); 3644 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 3645 3646 memset(payload_write, 0xE5, sizeof(payload_write)); 3647 spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL); 3648 CU_ASSERT(g_bserrno == 0); 3649 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 3650 3651 /* Create snapshot from blob */ 3652 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 3653 CU_ASSERT(g_bserrno == 0); 3654 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3655 snapshotid = g_blobid; 3656 3657 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 3658 CU_ASSERT(g_bserrno == 0); 3659 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3660 snapshot = g_blob; 3661 CU_ASSERT(snapshot->data_ro == true) 3662 CU_ASSERT(snapshot->md_ro == true) 3663 3664 CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 5) 3665 3666 memset(payload_write, 0xAA, sizeof(payload_write)); 3667 spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL); 3668 CU_ASSERT(g_bserrno == 0); 3669 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 3670 3671 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 3672 CU_ASSERT(g_bserrno == 0); 3673 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 3674 3675 /* Data on snapshot should not change after write to clone */ 3676 memset(payload_write, 0xE5, sizeof(payload_write)); 3677 spdk_blob_io_read(snapshot, channel, payload_read, 4, 10, blob_op_complete, NULL); 3678 CU_ASSERT(g_bserrno == 0); 3679 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 3680 3681 spdk_blob_close(blob, blob_op_complete, NULL); 3682 CU_ASSERT(g_bserrno == 0); 3683 3684 spdk_blob_close(snapshot, blob_op_complete, NULL); 3685 CU_ASSERT(g_bserrno == 0); 3686 3687 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 3688 CU_ASSERT(g_bserrno == 0); 3689 3690 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 3691 CU_ASSERT(g_bserrno == 0); 3692 3693 spdk_bs_free_io_channel(channel); 3694 3695 /* Unload the blob store */ 3696 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3697 CU_ASSERT(g_bserrno == 0); 3698 g_bs = NULL; 3699 g_blob = NULL; 3700 g_blobid = 0; 3701 } 3702 3703 static void 3704 blob_snapshot_rw_iov(void) 3705 { 3706 static const uint8_t zero[10 * 4096] = { 0 }; 3707 struct spdk_blob_store *bs; 3708 struct spdk_bs_dev *dev; 3709 struct spdk_blob *blob, *snapshot; 3710 struct spdk_io_channel *channel; 3711 struct spdk_blob_opts opts; 3712 spdk_blob_id blobid, snapshotid; 3713 uint64_t free_clusters; 3714 uint8_t payload_read[10 * 4096]; 3715 uint8_t payload_write[10 * 4096]; 3716 struct iovec iov_read[3]; 3717 struct iovec iov_write[3]; 3718 3719 dev = init_dev(); 3720 3721 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3722 CU_ASSERT(g_bserrno == 0); 3723 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3724 bs = g_bs; 3725 free_clusters = spdk_bs_free_cluster_count(bs); 3726 3727 channel = spdk_bs_alloc_io_channel(bs); 3728 CU_ASSERT(channel != NULL); 3729 3730 spdk_blob_opts_init(&opts); 3731 opts.thin_provision = true; 3732 opts.num_clusters = 5; 3733 3734 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 3735 CU_ASSERT(g_bserrno == 0); 3736 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3737 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3738 blobid = g_blobid; 3739 3740 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3741 CU_ASSERT(g_bserrno == 0); 3742 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3743 blob = g_blob; 3744 3745 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 3746 3747 /* Create snapshot from blob */ 3748 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 3749 CU_ASSERT(g_bserrno == 0); 3750 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3751 snapshotid = g_blobid; 3752 3753 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 3754 CU_ASSERT(g_bserrno == 0); 3755 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3756 snapshot = g_blob; 3757 CU_ASSERT(snapshot->data_ro == true) 3758 CU_ASSERT(snapshot->md_ro == true) 3759 CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 5); 3760 3761 /* Payload should be all zeros from unallocated clusters */ 3762 memset(payload_read, 0xAA, sizeof(payload_read)); 3763 iov_read[0].iov_base = payload_read; 3764 iov_read[0].iov_len = 3 * 4096; 3765 iov_read[1].iov_base = payload_read + 3 * 4096; 3766 iov_read[1].iov_len = 4 * 4096; 3767 iov_read[2].iov_base = payload_read + 7 * 4096; 3768 iov_read[2].iov_len = 3 * 4096; 3769 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 3770 CU_ASSERT(g_bserrno == 0); 3771 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 3772 3773 memset(payload_write, 0xE5, sizeof(payload_write)); 3774 iov_write[0].iov_base = payload_write; 3775 iov_write[0].iov_len = 1 * 4096; 3776 iov_write[1].iov_base = payload_write + 1 * 4096; 3777 iov_write[1].iov_len = 5 * 4096; 3778 iov_write[2].iov_base = payload_write + 6 * 4096; 3779 iov_write[2].iov_len = 4 * 4096; 3780 3781 spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 3782 CU_ASSERT(g_bserrno == 0); 3783 3784 memset(payload_read, 0xAA, sizeof(payload_read)); 3785 iov_read[0].iov_base = payload_read; 3786 iov_read[0].iov_len = 3 * 4096; 3787 iov_read[1].iov_base = payload_read + 3 * 4096; 3788 iov_read[1].iov_len = 4 * 4096; 3789 iov_read[2].iov_base = payload_read + 7 * 4096; 3790 iov_read[2].iov_len = 3 * 4096; 3791 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 3792 CU_ASSERT(g_bserrno == 0); 3793 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 3794 3795 spdk_blob_close(blob, blob_op_complete, NULL); 3796 CU_ASSERT(g_bserrno == 0); 3797 3798 spdk_blob_close(snapshot, blob_op_complete, NULL); 3799 CU_ASSERT(g_bserrno == 0); 3800 3801 spdk_bs_free_io_channel(channel); 3802 3803 /* Unload the blob store */ 3804 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3805 CU_ASSERT(g_bserrno == 0); 3806 g_bs = NULL; 3807 g_blob = NULL; 3808 g_blobid = 0; 3809 } 3810 3811 static void 3812 blob_inflate_rw(void) 3813 { 3814 static uint8_t *zero; 3815 struct spdk_blob_store *bs; 3816 struct spdk_bs_dev *dev; 3817 struct spdk_blob *blob, *snapshot; 3818 struct spdk_io_channel *channel; 3819 struct spdk_blob_opts opts; 3820 spdk_blob_id blobid, snapshotid; 3821 uint64_t free_clusters; 3822 uint64_t cluster_size; 3823 3824 uint64_t payload_size; 3825 uint8_t *payload_read; 3826 uint8_t *payload_write; 3827 uint8_t *payload_clone; 3828 3829 uint64_t pages_per_cluster; 3830 uint64_t pages_per_payload; 3831 3832 int i; 3833 3834 dev = init_dev(); 3835 3836 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3837 CU_ASSERT(g_bserrno == 0); 3838 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3839 bs = g_bs; 3840 3841 free_clusters = spdk_bs_free_cluster_count(bs); 3842 cluster_size = spdk_bs_get_cluster_size(bs); 3843 pages_per_cluster = cluster_size / spdk_bs_get_page_size(bs); 3844 pages_per_payload = pages_per_cluster * 5; 3845 3846 payload_size = cluster_size * 5; 3847 3848 payload_read = malloc(payload_size); 3849 SPDK_CU_ASSERT_FATAL(payload_read != NULL); 3850 3851 payload_write = malloc(payload_size); 3852 SPDK_CU_ASSERT_FATAL(payload_write != NULL); 3853 3854 payload_clone = malloc(payload_size); 3855 SPDK_CU_ASSERT_FATAL(payload_clone != NULL); 3856 3857 zero = calloc(1, payload_size); 3858 SPDK_CU_ASSERT_FATAL(zero != NULL); 3859 3860 channel = spdk_bs_alloc_io_channel(bs); 3861 SPDK_CU_ASSERT_FATAL(channel != NULL); 3862 3863 /* Create blob */ 3864 spdk_blob_opts_init(&opts); 3865 opts.thin_provision = true; 3866 opts.num_clusters = 5; 3867 3868 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 3869 CU_ASSERT(g_bserrno == 0); 3870 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3871 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3872 blobid = g_blobid; 3873 3874 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3875 CU_ASSERT(g_bserrno == 0); 3876 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3877 blob = g_blob; 3878 3879 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 3880 3881 /* Initial read should return zeroed payload */ 3882 memset(payload_read, 0xFF, payload_size); 3883 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, blob_op_complete, NULL); 3884 CU_ASSERT(g_bserrno == 0); 3885 CU_ASSERT(memcmp(zero, payload_read, payload_size) == 0); 3886 3887 /* Fill whole blob with a pattern */ 3888 memset(payload_write, 0xE5, payload_size); 3889 spdk_blob_io_write(blob, channel, payload_write, 0, pages_per_payload, 3890 blob_op_complete, NULL); 3891 CU_ASSERT(g_bserrno == 0); 3892 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 3893 3894 /* Create snapshot from blob */ 3895 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 3896 CU_ASSERT(g_bserrno == 0); 3897 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3898 snapshotid = g_blobid; 3899 3900 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 3901 CU_ASSERT(g_bserrno == 0); 3902 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3903 snapshot = g_blob; 3904 CU_ASSERT(snapshot->data_ro == true) 3905 CU_ASSERT(snapshot->md_ro == true) 3906 3907 CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 5) 3908 3909 /* Write every second cluster with a pattern. 3910 * 3911 * payload_clone stores expected result on "blob" read at the time and 3912 * is used only to check data consistency on clone before and after 3913 * inflation. Initially we fill it with a backing snapshots pattern 3914 * used before. 3915 */ 3916 memset(payload_clone, 0xE5, payload_size); 3917 memset(payload_write, 0xAA, payload_size); 3918 for (i = 1; i < 5; i += 2) { 3919 spdk_blob_io_write(blob, channel, payload_write, i * pages_per_cluster, 3920 pages_per_cluster, blob_op_complete, NULL); 3921 CU_ASSERT(g_bserrno == 0); 3922 3923 /* Update expected result */ 3924 memcpy(payload_clone + (cluster_size * i), payload_write, 3925 cluster_size); 3926 } 3927 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 3928 3929 /* Check data consistency on clone */ 3930 memset(payload_read, 0xFF, payload_size); 3931 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, 3932 blob_op_complete, NULL); 3933 CU_ASSERT(g_bserrno == 0); 3934 CU_ASSERT(memcmp(payload_clone, payload_read, payload_size) == 0); 3935 3936 /* Close all blobs */ 3937 spdk_blob_close(blob, blob_op_complete, NULL); 3938 CU_ASSERT(g_bserrno == 0); 3939 3940 spdk_blob_close(snapshot, blob_op_complete, NULL); 3941 CU_ASSERT(g_bserrno == 0); 3942 3943 /* Inflate blob */ 3944 spdk_bs_inflate_blob(bs, channel, blobid, blob_op_complete, NULL); 3945 CU_ASSERT(g_bserrno == 0); 3946 3947 /* Try to delete snapshot (should pass) */ 3948 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 3949 CU_ASSERT(g_bserrno == 0); 3950 3951 /* Reopen blob after snapshot deletion */ 3952 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3953 CU_ASSERT(g_bserrno == 0); 3954 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3955 blob = g_blob; 3956 3957 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 3958 3959 /* Check data consistency on inflated blob */ 3960 memset(payload_read, 0xFF, payload_size); 3961 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, blob_op_complete, NULL); 3962 CU_ASSERT(g_bserrno == 0); 3963 CU_ASSERT(memcmp(payload_clone, payload_read, payload_size) == 0); 3964 3965 spdk_blob_close(blob, blob_op_complete, NULL); 3966 CU_ASSERT(g_bserrno == 0); 3967 3968 spdk_bs_free_io_channel(channel); 3969 3970 /* Unload the blob store */ 3971 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3972 CU_ASSERT(g_bserrno == 0); 3973 g_bs = NULL; 3974 g_blob = NULL; 3975 g_blobid = 0; 3976 3977 free(payload_read); 3978 free(payload_write); 3979 free(payload_clone); 3980 free(zero); 3981 } 3982 3983 /** 3984 * Snapshot-clones relation test 3985 * 3986 * snapshot 3987 * | 3988 * +----+----+ 3989 * | | 3990 * blob clone 3991 * | 3992 * clone2 3993 */ 3994 static void 3995 blob_relations(void) 3996 { 3997 struct spdk_blob_store *bs; 3998 struct spdk_bs_dev *dev; 3999 struct spdk_bs_opts bs_opts; 4000 struct spdk_blob_opts opts; 4001 struct spdk_blob *blob, *snapshot, *clone, *clone2; 4002 spdk_blob_id blobid, cloneid, snapshotid, cloneid2; 4003 int rc; 4004 size_t count; 4005 spdk_blob_id ids[10]; 4006 4007 dev = init_dev(); 4008 spdk_bs_opts_init(&bs_opts); 4009 snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE"); 4010 4011 spdk_bs_init(dev, &bs_opts, bs_op_with_handle_complete, NULL); 4012 CU_ASSERT(g_bserrno == 0); 4013 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4014 bs = g_bs; 4015 4016 /* 1. Create blob with 10 clusters */ 4017 4018 spdk_blob_opts_init(&opts); 4019 opts.num_clusters = 10; 4020 4021 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 4022 CU_ASSERT(g_bserrno == 0); 4023 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4024 blobid = g_blobid; 4025 4026 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4027 CU_ASSERT(g_bserrno == 0); 4028 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4029 blob = g_blob; 4030 4031 CU_ASSERT(!spdk_blob_is_read_only(blob)); 4032 CU_ASSERT(!spdk_blob_is_snapshot(blob)); 4033 CU_ASSERT(!spdk_blob_is_clone(blob)); 4034 CU_ASSERT(!spdk_blob_is_thin_provisioned(blob)); 4035 4036 /* blob should not have underlying snapshot nor clones */ 4037 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == SPDK_BLOBID_INVALID); 4038 count = SPDK_COUNTOF(ids); 4039 rc = spdk_blob_get_clones(bs, blobid, ids, &count); 4040 CU_ASSERT(rc == 0); 4041 CU_ASSERT(count == 0); 4042 4043 4044 /* 2. Create snapshot */ 4045 4046 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 4047 CU_ASSERT(g_bserrno == 0); 4048 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4049 snapshotid = g_blobid; 4050 4051 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 4052 CU_ASSERT(g_bserrno == 0); 4053 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4054 snapshot = g_blob; 4055 4056 CU_ASSERT(spdk_blob_is_read_only(snapshot)); 4057 CU_ASSERT(spdk_blob_is_snapshot(snapshot)); 4058 CU_ASSERT(!spdk_blob_is_clone(snapshot)); 4059 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid) == SPDK_BLOBID_INVALID); 4060 4061 /* Check if original blob is converted to the clone of snapshot */ 4062 CU_ASSERT(!spdk_blob_is_read_only(blob)); 4063 CU_ASSERT(!spdk_blob_is_snapshot(blob)); 4064 CU_ASSERT(spdk_blob_is_clone(blob)); 4065 CU_ASSERT(spdk_blob_is_thin_provisioned(blob)); 4066 4067 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid); 4068 4069 count = SPDK_COUNTOF(ids); 4070 rc = spdk_blob_get_clones(bs, snapshotid, ids, &count); 4071 CU_ASSERT(rc == 0); 4072 CU_ASSERT(count == 1); 4073 CU_ASSERT(ids[0] == blobid); 4074 4075 4076 /* 3. Create clone from snapshot */ 4077 4078 spdk_bs_create_clone(bs, snapshotid, NULL, blob_op_with_id_complete, NULL); 4079 CU_ASSERT(g_bserrno == 0); 4080 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4081 cloneid = g_blobid; 4082 4083 spdk_bs_open_blob(bs, cloneid, blob_op_with_handle_complete, NULL); 4084 CU_ASSERT(g_bserrno == 0); 4085 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4086 clone = g_blob; 4087 4088 CU_ASSERT(!spdk_blob_is_read_only(clone)); 4089 CU_ASSERT(!spdk_blob_is_snapshot(clone)); 4090 CU_ASSERT(spdk_blob_is_clone(clone)); 4091 CU_ASSERT(spdk_blob_is_thin_provisioned(clone)); 4092 4093 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid); 4094 4095 count = SPDK_COUNTOF(ids); 4096 rc = spdk_blob_get_clones(bs, cloneid, ids, &count); 4097 CU_ASSERT(rc == 0); 4098 CU_ASSERT(count == 0); 4099 4100 /* Check if clone is on the snapshot's list */ 4101 count = SPDK_COUNTOF(ids); 4102 rc = spdk_blob_get_clones(bs, snapshotid, ids, &count); 4103 CU_ASSERT(rc == 0); 4104 CU_ASSERT(ids[0] == blobid || ids[1] == blobid); 4105 CU_ASSERT(ids[0] == cloneid || ids[1] == cloneid); 4106 4107 4108 /* 4. Try to create clone from read only blob */ 4109 4110 /* Mark blob as read only */ 4111 spdk_blob_set_read_only(blob); 4112 spdk_blob_sync_md(blob, blob_op_complete, NULL); 4113 CU_ASSERT(g_bserrno == 0); 4114 4115 /* Check if previously created blob is read only clone */ 4116 CU_ASSERT(spdk_blob_is_read_only(blob)); 4117 CU_ASSERT(!spdk_blob_is_snapshot(blob)); 4118 CU_ASSERT(spdk_blob_is_clone(blob)); 4119 CU_ASSERT(spdk_blob_is_thin_provisioned(blob)); 4120 4121 /* Create clone from read only blob */ 4122 spdk_bs_create_clone(bs, blobid, NULL, blob_op_with_id_complete, NULL); 4123 CU_ASSERT(g_bserrno == 0); 4124 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4125 cloneid2 = g_blobid; 4126 4127 spdk_bs_open_blob(bs, cloneid2, blob_op_with_handle_complete, NULL); 4128 CU_ASSERT(g_bserrno == 0); 4129 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4130 clone2 = g_blob; 4131 4132 CU_ASSERT(!spdk_blob_is_read_only(clone2)); 4133 CU_ASSERT(!spdk_blob_is_snapshot(clone2)); 4134 CU_ASSERT(spdk_blob_is_clone(clone2)); 4135 CU_ASSERT(spdk_blob_is_thin_provisioned(clone2)); 4136 4137 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid2) == blobid); 4138 4139 count = SPDK_COUNTOF(ids); 4140 rc = spdk_blob_get_clones(bs, blobid, ids, &count); 4141 CU_ASSERT(rc == 0); 4142 4143 CU_ASSERT(count == 1); 4144 CU_ASSERT(ids[0] == cloneid2); 4145 4146 /* Close blobs */ 4147 4148 spdk_blob_close(clone2, blob_op_complete, NULL); 4149 CU_ASSERT(g_bserrno == 0); 4150 4151 spdk_blob_close(blob, blob_op_complete, NULL); 4152 CU_ASSERT(g_bserrno == 0); 4153 4154 spdk_blob_close(clone, blob_op_complete, NULL); 4155 CU_ASSERT(g_bserrno == 0); 4156 4157 spdk_blob_close(snapshot, blob_op_complete, NULL); 4158 CU_ASSERT(g_bserrno == 0); 4159 4160 /* Try to delete snapshot with created clones */ 4161 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 4162 CU_ASSERT(g_bserrno != 0); 4163 4164 spdk_bs_unload(bs, bs_op_complete, NULL); 4165 CU_ASSERT(g_bserrno == 0); 4166 g_bs = NULL; 4167 4168 /* Load an existing blob store */ 4169 dev = init_dev(); 4170 snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE"); 4171 4172 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 4173 CU_ASSERT(g_bserrno == 0); 4174 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4175 bs = g_bs; 4176 4177 4178 /* NULL ids array should return number of clones in count */ 4179 count = SPDK_COUNTOF(ids); 4180 rc = spdk_blob_get_clones(bs, snapshotid, NULL, &count); 4181 CU_ASSERT(rc == -ENOMEM); 4182 CU_ASSERT(count == 2); 4183 4184 /* incorrect array size */ 4185 count = 1; 4186 rc = spdk_blob_get_clones(bs, snapshotid, ids, &count); 4187 CU_ASSERT(rc == -ENOMEM); 4188 CU_ASSERT(count == 2); 4189 4190 4191 /* Verify structure of loaded blob store */ 4192 4193 /* snapshot */ 4194 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid) == SPDK_BLOBID_INVALID); 4195 4196 count = SPDK_COUNTOF(ids); 4197 rc = spdk_blob_get_clones(bs, snapshotid, ids, &count); 4198 CU_ASSERT(rc == 0); 4199 CU_ASSERT(count == 2); 4200 CU_ASSERT(ids[0] == blobid || ids[1] == blobid); 4201 CU_ASSERT(ids[0] == cloneid || ids[1] == cloneid); 4202 4203 /* blob */ 4204 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid); 4205 count = SPDK_COUNTOF(ids); 4206 rc = spdk_blob_get_clones(bs, blobid, ids, &count); 4207 CU_ASSERT(rc == 0); 4208 CU_ASSERT(count == 1); 4209 CU_ASSERT(ids[0] == cloneid2); 4210 4211 /* clone */ 4212 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid); 4213 count = SPDK_COUNTOF(ids); 4214 rc = spdk_blob_get_clones(bs, cloneid, ids, &count); 4215 CU_ASSERT(rc == 0); 4216 CU_ASSERT(count == 0); 4217 4218 /* clone2 */ 4219 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid2) == blobid); 4220 count = SPDK_COUNTOF(ids); 4221 rc = spdk_blob_get_clones(bs, cloneid2, ids, &count); 4222 CU_ASSERT(rc == 0); 4223 CU_ASSERT(count == 0); 4224 4225 /* Try to delete all blobs */ 4226 spdk_bs_delete_blob(bs, cloneid, blob_op_complete, NULL); 4227 CU_ASSERT(g_bserrno == 0); 4228 4229 /* Try to delete snapshot with clones */ 4230 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 4231 CU_ASSERT(g_bserrno != 0); 4232 4233 /* Try to delete ro blob with clones */ 4234 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 4235 CU_ASSERT(g_bserrno != 0); 4236 4237 spdk_bs_delete_blob(bs, cloneid2, blob_op_complete, NULL); 4238 CU_ASSERT(g_bserrno == 0); 4239 4240 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 4241 CU_ASSERT(g_bserrno == 0); 4242 4243 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 4244 CU_ASSERT(g_bserrno == 0); 4245 4246 spdk_bs_unload(bs, bs_op_complete, NULL); 4247 CU_ASSERT(g_bserrno == 0); 4248 4249 g_bs = NULL; 4250 } 4251 4252 int main(int argc, char **argv) 4253 { 4254 CU_pSuite suite = NULL; 4255 unsigned int num_failures; 4256 4257 if (CU_initialize_registry() != CUE_SUCCESS) { 4258 return CU_get_error(); 4259 } 4260 4261 suite = CU_add_suite("blob", NULL, NULL); 4262 if (suite == NULL) { 4263 CU_cleanup_registry(); 4264 return CU_get_error(); 4265 } 4266 4267 if ( 4268 CU_add_test(suite, "blob_init", blob_init) == NULL || 4269 CU_add_test(suite, "blob_open", blob_open) == NULL || 4270 CU_add_test(suite, "blob_create", blob_create) == NULL || 4271 CU_add_test(suite, "blob_create_internal", blob_create_internal) == NULL || 4272 CU_add_test(suite, "blob_thin_provision", blob_thin_provision) == NULL || 4273 CU_add_test(suite, "blob_snapshot", blob_snapshot) == NULL || 4274 CU_add_test(suite, "blob_clone", blob_clone) == NULL || 4275 CU_add_test(suite, "blob_inflate", blob_inflate) == NULL || 4276 CU_add_test(suite, "blob_delete", blob_delete) == NULL || 4277 CU_add_test(suite, "blob_resize", blob_resize) == NULL || 4278 CU_add_test(suite, "blob_read_only", blob_read_only) == NULL || 4279 CU_add_test(suite, "channel_ops", channel_ops) == NULL || 4280 CU_add_test(suite, "blob_super", blob_super) == NULL || 4281 CU_add_test(suite, "blob_write", blob_write) == NULL || 4282 CU_add_test(suite, "blob_read", blob_read) == NULL || 4283 CU_add_test(suite, "blob_rw_verify", blob_rw_verify) == NULL || 4284 CU_add_test(suite, "blob_rw_verify_iov", blob_rw_verify_iov) == NULL || 4285 CU_add_test(suite, "blob_rw_verify_iov_nomem", blob_rw_verify_iov_nomem) == NULL || 4286 CU_add_test(suite, "blob_rw_iov_read_only", blob_rw_iov_read_only) == NULL || 4287 CU_add_test(suite, "blob_unmap", blob_unmap) == NULL || 4288 CU_add_test(suite, "blob_iter", blob_iter) == NULL || 4289 CU_add_test(suite, "blob_xattr", blob_xattr) == NULL || 4290 CU_add_test(suite, "bs_load", bs_load) == NULL || 4291 CU_add_test(suite, "bs_unload", bs_unload) == NULL || 4292 CU_add_test(suite, "bs_cluster_sz", bs_cluster_sz) == NULL || 4293 CU_add_test(suite, "bs_usable_clusters", bs_usable_clusters) == NULL || 4294 CU_add_test(suite, "bs_resize_md", bs_resize_md) == NULL || 4295 CU_add_test(suite, "bs_destroy", bs_destroy) == NULL || 4296 CU_add_test(suite, "bs_type", bs_type) == NULL || 4297 CU_add_test(suite, "bs_super_block", bs_super_block) == NULL || 4298 CU_add_test(suite, "blob_serialize", blob_serialize) == NULL || 4299 CU_add_test(suite, "blob_crc", blob_crc) == NULL || 4300 CU_add_test(suite, "super_block_crc", super_block_crc) == NULL || 4301 CU_add_test(suite, "blob_dirty_shutdown", blob_dirty_shutdown) == NULL || 4302 CU_add_test(suite, "blob_flags", blob_flags) == NULL || 4303 CU_add_test(suite, "bs_version", bs_version) == NULL || 4304 CU_add_test(suite, "blob_set_xattrs", blob_set_xattrs) == NULL || 4305 CU_add_test(suite, "blob_thin_prov_alloc", blob_thin_prov_alloc) == NULL || 4306 CU_add_test(suite, "blob_insert_cluster_msg", blob_insert_cluster_msg) == NULL || 4307 CU_add_test(suite, "blob_thin_prov_rw", blob_thin_prov_rw) == NULL || 4308 CU_add_test(suite, "blob_thin_prov_rw_iov", blob_thin_prov_rw_iov) == NULL || 4309 CU_add_test(suite, "bs_load_iter", bs_load_iter) == NULL || 4310 CU_add_test(suite, "blob_snapshot_rw", blob_snapshot_rw) == NULL || 4311 CU_add_test(suite, "blob_snapshot_rw_iov", blob_snapshot_rw_iov) == NULL || 4312 CU_add_test(suite, "blob_inflate_rw", blob_inflate_rw) == NULL || 4313 CU_add_test(suite, "blob_relations", blob_relations) == NULL 4314 ) { 4315 CU_cleanup_registry(); 4316 return CU_get_error(); 4317 } 4318 4319 g_dev_buffer = calloc(1, DEV_BUFFER_SIZE); 4320 spdk_allocate_thread(_bs_send_msg, NULL, NULL, NULL, "thread0"); 4321 CU_basic_set_mode(CU_BRM_VERBOSE); 4322 CU_basic_run_tests(); 4323 num_failures = CU_get_number_of_failures(); 4324 CU_cleanup_registry(); 4325 spdk_free_thread(); 4326 free(g_dev_buffer); 4327 return num_failures; 4328 } 4329