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 == 1); 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 /* Verify that blobstore is marked dirty after first metadata sync */ 1874 spdk_blob_sync_md(blob, blob_op_complete, NULL); 1875 CU_ASSERT(super_block->clean == 1); 1876 1877 /* Get the xattrs */ 1878 value = NULL; 1879 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 1880 CU_ASSERT(rc == 0); 1881 SPDK_CU_ASSERT_FATAL(value != NULL); 1882 CU_ASSERT(*(uint64_t *)value == length); 1883 CU_ASSERT(value_len == 8); 1884 1885 rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len); 1886 CU_ASSERT(rc == -ENOENT); 1887 1888 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 1889 1890 spdk_blob_close(blob, blob_op_complete, NULL); 1891 CU_ASSERT(g_bserrno == 0); 1892 blob = NULL; 1893 g_blob = NULL; 1894 g_blobid = SPDK_BLOBID_INVALID; 1895 1896 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1897 CU_ASSERT(g_bserrno == 0); 1898 g_bs = NULL; 1899 } 1900 1901 static void 1902 bs_type(void) 1903 { 1904 struct spdk_bs_dev *dev; 1905 struct spdk_bs_opts opts; 1906 1907 dev = init_dev(); 1908 spdk_bs_opts_init(&opts); 1909 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 1910 1911 /* Initialize a new blob store */ 1912 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1913 CU_ASSERT(g_bserrno == 0); 1914 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1915 1916 /* Unload the blob store */ 1917 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1918 CU_ASSERT(g_bserrno == 0); 1919 g_bs = NULL; 1920 g_blob = NULL; 1921 g_blobid = 0; 1922 1923 /* Load non existing blobstore type */ 1924 dev = init_dev(); 1925 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "NONEXISTING"); 1926 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1927 CU_ASSERT(g_bserrno != 0); 1928 1929 /* Load with empty blobstore type */ 1930 dev = init_dev(); 1931 memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype)); 1932 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1933 CU_ASSERT(g_bserrno == 0); 1934 1935 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1936 CU_ASSERT(g_bserrno == 0); 1937 g_bs = NULL; 1938 1939 /* Initialize a new blob store with empty bstype */ 1940 dev = init_dev(); 1941 memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype)); 1942 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1943 CU_ASSERT(g_bserrno == 0); 1944 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1945 1946 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1947 CU_ASSERT(g_bserrno == 0); 1948 g_bs = NULL; 1949 1950 /* Load non existing blobstore type */ 1951 dev = init_dev(); 1952 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "NONEXISTING"); 1953 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1954 CU_ASSERT(g_bserrno != 0); 1955 1956 /* Load with empty blobstore type */ 1957 dev = init_dev(); 1958 memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype)); 1959 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1960 CU_ASSERT(g_bserrno == 0); 1961 1962 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1963 CU_ASSERT(g_bserrno == 0); 1964 g_bs = NULL; 1965 } 1966 1967 static void 1968 bs_super_block(void) 1969 { 1970 struct spdk_bs_dev *dev; 1971 struct spdk_bs_super_block *super_block; 1972 struct spdk_bs_opts opts; 1973 struct spdk_bs_super_block_ver1 super_block_v1; 1974 1975 dev = init_dev(); 1976 spdk_bs_opts_init(&opts); 1977 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 1978 1979 /* Initialize a new blob store */ 1980 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1981 CU_ASSERT(g_bserrno == 0); 1982 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1983 1984 /* Unload the blob store */ 1985 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1986 CU_ASSERT(g_bserrno == 0); 1987 g_bs = NULL; 1988 g_blob = NULL; 1989 g_blobid = 0; 1990 1991 /* Load an existing blob store with version newer than supported */ 1992 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 1993 super_block->version++; 1994 1995 dev = init_dev(); 1996 memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype)); 1997 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1998 CU_ASSERT(g_bserrno != 0); 1999 2000 /* Create a new blob store with super block version 1 */ 2001 dev = init_dev(); 2002 super_block_v1.version = 1; 2003 memcpy(super_block_v1.signature, "SPDKBLOB", sizeof(super_block_v1.signature)); 2004 super_block_v1.length = 0x1000; 2005 super_block_v1.clean = 1; 2006 super_block_v1.super_blob = 0xFFFFFFFFFFFFFFFF; 2007 super_block_v1.cluster_size = 0x100000; 2008 super_block_v1.used_page_mask_start = 0x01; 2009 super_block_v1.used_page_mask_len = 0x01; 2010 super_block_v1.used_cluster_mask_start = 0x02; 2011 super_block_v1.used_cluster_mask_len = 0x01; 2012 super_block_v1.md_start = 0x03; 2013 super_block_v1.md_len = 0x40; 2014 memset(super_block_v1.reserved, 0, 4036); 2015 super_block_v1.crc = _spdk_blob_md_page_calc_crc(&super_block_v1); 2016 memcpy(g_dev_buffer, &super_block_v1, sizeof(struct spdk_bs_super_block_ver1)); 2017 2018 memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype)); 2019 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2020 CU_ASSERT(g_bserrno == 0); 2021 2022 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2023 CU_ASSERT(g_bserrno == 0); 2024 g_bs = NULL; 2025 } 2026 2027 /* 2028 * Create a blobstore and then unload it. 2029 */ 2030 static void 2031 bs_unload(void) 2032 { 2033 struct spdk_bs_dev *dev; 2034 struct spdk_blob_store *bs; 2035 spdk_blob_id blobid; 2036 struct spdk_blob *blob; 2037 2038 dev = init_dev(); 2039 2040 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2041 CU_ASSERT(g_bserrno == 0); 2042 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2043 bs = g_bs; 2044 2045 /* Create a blob and open it. */ 2046 g_bserrno = -1; 2047 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 2048 CU_ASSERT(g_bserrno == 0); 2049 CU_ASSERT(g_blobid > 0); 2050 blobid = g_blobid; 2051 2052 g_bserrno = -1; 2053 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2054 CU_ASSERT(g_bserrno == 0); 2055 CU_ASSERT(g_blob != NULL); 2056 blob = g_blob; 2057 2058 /* Try to unload blobstore, should fail with open blob */ 2059 g_bserrno = -1; 2060 spdk_bs_unload(bs, bs_op_complete, NULL); 2061 CU_ASSERT(g_bserrno == -EBUSY); 2062 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2063 2064 /* Close the blob, then successfully unload blobstore */ 2065 g_bserrno = -1; 2066 spdk_blob_close(blob, blob_op_complete, NULL); 2067 CU_ASSERT(g_bserrno == 0); 2068 2069 g_bserrno = -1; 2070 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2071 CU_ASSERT(g_bserrno == 0); 2072 g_bs = NULL; 2073 } 2074 2075 /* 2076 * Create a blobstore with a cluster size different than the default, and ensure it is 2077 * persisted. 2078 */ 2079 static void 2080 bs_cluster_sz(void) 2081 { 2082 struct spdk_bs_dev *dev; 2083 struct spdk_bs_opts opts; 2084 uint32_t cluster_sz; 2085 2086 /* Set cluster size to zero */ 2087 dev = init_dev(); 2088 spdk_bs_opts_init(&opts); 2089 opts.cluster_sz = 0; 2090 2091 /* Initialize a new blob store */ 2092 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2093 CU_ASSERT(g_bserrno == -EINVAL); 2094 SPDK_CU_ASSERT_FATAL(g_bs == NULL); 2095 2096 /* 2097 * Set cluster size to blobstore page size, 2098 * to work it is required to be at least twice the blobstore page size. 2099 */ 2100 dev = init_dev(); 2101 spdk_bs_opts_init(&opts); 2102 opts.cluster_sz = SPDK_BS_PAGE_SIZE; 2103 2104 /* Initialize a new blob store */ 2105 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2106 CU_ASSERT(g_bserrno == -ENOMEM); 2107 SPDK_CU_ASSERT_FATAL(g_bs == NULL); 2108 2109 /* 2110 * Set cluster size to lower than page size, 2111 * to work it is required to be at least twice the blobstore page size. 2112 */ 2113 dev = init_dev(); 2114 spdk_bs_opts_init(&opts); 2115 opts.cluster_sz = SPDK_BS_PAGE_SIZE - 1; 2116 2117 /* Initialize a new blob store */ 2118 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2119 CU_ASSERT(g_bserrno == -ENOMEM); 2120 SPDK_CU_ASSERT_FATAL(g_bs == NULL); 2121 2122 /* Set cluster size to twice the default */ 2123 dev = init_dev(); 2124 spdk_bs_opts_init(&opts); 2125 opts.cluster_sz *= 2; 2126 cluster_sz = opts.cluster_sz; 2127 2128 /* Initialize a new blob store */ 2129 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2130 CU_ASSERT(g_bserrno == 0); 2131 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2132 2133 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 2134 2135 /* Unload the blob store */ 2136 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2137 CU_ASSERT(g_bserrno == 0); 2138 g_bs = NULL; 2139 g_blob = NULL; 2140 g_blobid = 0; 2141 2142 dev = init_dev(); 2143 /* Load an existing blob store */ 2144 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2145 CU_ASSERT(g_bserrno == 0); 2146 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2147 2148 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 2149 2150 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2151 CU_ASSERT(g_bserrno == 0); 2152 g_bs = NULL; 2153 } 2154 2155 /* 2156 * Create a blobstore, reload it and ensure total usable cluster count 2157 * stays the same. 2158 */ 2159 static void 2160 bs_usable_clusters(void) 2161 { 2162 struct spdk_bs_dev *dev; 2163 struct spdk_bs_opts opts; 2164 uint32_t clusters; 2165 int i; 2166 2167 /* Init blobstore */ 2168 dev = init_dev(); 2169 spdk_bs_opts_init(&opts); 2170 2171 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2172 CU_ASSERT(g_bserrno == 0); 2173 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2174 2175 clusters = spdk_bs_total_data_cluster_count(g_bs); 2176 2177 /* Unload the blob store */ 2178 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2179 CU_ASSERT(g_bserrno == 0); 2180 g_bs = NULL; 2181 2182 dev = init_dev(); 2183 /* Load an existing blob store */ 2184 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2185 CU_ASSERT(g_bserrno == 0); 2186 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2187 2188 CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters); 2189 2190 /* Create and resize blobs to make sure that useable cluster count won't change */ 2191 for (i = 0; i < 4; i++) { 2192 g_bserrno = -1; 2193 g_blobid = SPDK_BLOBID_INVALID; 2194 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2195 CU_ASSERT(g_bserrno == 0); 2196 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2197 2198 g_bserrno = -1; 2199 g_blob = NULL; 2200 spdk_bs_open_blob(g_bs, g_blobid, blob_op_with_handle_complete, NULL); 2201 CU_ASSERT(g_bserrno == 0); 2202 CU_ASSERT(g_blob != NULL); 2203 2204 spdk_blob_resize(g_blob, 10, blob_op_complete, NULL); 2205 CU_ASSERT(g_bserrno == 0); 2206 2207 g_bserrno = -1; 2208 spdk_blob_close(g_blob, blob_op_complete, NULL); 2209 CU_ASSERT(g_bserrno == 0); 2210 2211 CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters); 2212 } 2213 2214 /* Reload the blob store to make sure that nothing changed */ 2215 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2216 CU_ASSERT(g_bserrno == 0); 2217 g_bs = NULL; 2218 2219 dev = init_dev(); 2220 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2221 CU_ASSERT(g_bserrno == 0); 2222 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2223 2224 CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters); 2225 2226 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2227 CU_ASSERT(g_bserrno == 0); 2228 g_bs = NULL; 2229 } 2230 2231 /* 2232 * Test resizing of the metadata blob. This requires creating enough blobs 2233 * so that one cluster is not enough to fit the metadata for those blobs. 2234 * To induce this condition to happen more quickly, we reduce the cluster 2235 * size to 16KB, which means only 4 4KB blob metadata pages can fit. 2236 */ 2237 static void 2238 bs_resize_md(void) 2239 { 2240 const int CLUSTER_PAGE_COUNT = 4; 2241 const int NUM_BLOBS = CLUSTER_PAGE_COUNT * 4; 2242 struct spdk_bs_dev *dev; 2243 struct spdk_bs_opts opts; 2244 uint32_t cluster_sz; 2245 spdk_blob_id blobids[NUM_BLOBS]; 2246 int i; 2247 2248 2249 dev = init_dev(); 2250 spdk_bs_opts_init(&opts); 2251 opts.cluster_sz = CLUSTER_PAGE_COUNT * 4096; 2252 cluster_sz = opts.cluster_sz; 2253 2254 /* Initialize a new blob store */ 2255 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2256 CU_ASSERT(g_bserrno == 0); 2257 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2258 2259 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 2260 2261 for (i = 0; i < NUM_BLOBS; i++) { 2262 g_bserrno = -1; 2263 g_blobid = SPDK_BLOBID_INVALID; 2264 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2265 CU_ASSERT(g_bserrno == 0); 2266 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2267 blobids[i] = g_blobid; 2268 } 2269 2270 /* Unload the blob store */ 2271 g_bserrno = -1; 2272 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2273 CU_ASSERT(g_bserrno == 0); 2274 2275 /* Load an existing blob store */ 2276 g_bserrno = -1; 2277 g_bs = NULL; 2278 dev = init_dev(); 2279 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2280 CU_ASSERT(g_bserrno == 0); 2281 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2282 2283 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 2284 2285 for (i = 0; i < NUM_BLOBS; i++) { 2286 g_bserrno = -1; 2287 g_blob = NULL; 2288 spdk_bs_open_blob(g_bs, blobids[i], blob_op_with_handle_complete, NULL); 2289 CU_ASSERT(g_bserrno == 0); 2290 CU_ASSERT(g_blob != NULL); 2291 g_bserrno = -1; 2292 spdk_blob_close(g_blob, blob_op_complete, NULL); 2293 CU_ASSERT(g_bserrno == 0); 2294 } 2295 2296 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2297 CU_ASSERT(g_bserrno == 0); 2298 g_bs = NULL; 2299 } 2300 2301 static void 2302 bs_destroy(void) 2303 { 2304 struct spdk_bs_dev *dev; 2305 struct spdk_bs_opts opts; 2306 2307 /* Initialize a new blob store */ 2308 dev = init_dev(); 2309 spdk_bs_opts_init(&opts); 2310 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2311 CU_ASSERT(g_bserrno == 0); 2312 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2313 2314 /* Destroy the blob store */ 2315 g_bserrno = -1; 2316 spdk_bs_destroy(g_bs, bs_op_complete, NULL); 2317 CU_ASSERT(g_bserrno == 0); 2318 2319 /* Loading an non-existent blob store should fail. */ 2320 g_bs = NULL; 2321 dev = init_dev(); 2322 2323 g_bserrno = 0; 2324 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2325 CU_ASSERT(g_bserrno != 0); 2326 } 2327 2328 /* Try to hit all of the corner cases associated with serializing 2329 * a blob to disk 2330 */ 2331 static void 2332 blob_serialize(void) 2333 { 2334 struct spdk_bs_dev *dev; 2335 struct spdk_bs_opts opts; 2336 struct spdk_blob_store *bs; 2337 spdk_blob_id blobid[2]; 2338 struct spdk_blob *blob[2]; 2339 uint64_t i; 2340 char *value; 2341 int rc; 2342 2343 dev = init_dev(); 2344 2345 /* Initialize a new blobstore with very small clusters */ 2346 spdk_bs_opts_init(&opts); 2347 opts.cluster_sz = dev->blocklen * 8; 2348 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2349 CU_ASSERT(g_bserrno == 0); 2350 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2351 bs = g_bs; 2352 2353 /* Create and open two blobs */ 2354 for (i = 0; i < 2; i++) { 2355 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 2356 CU_ASSERT(g_bserrno == 0); 2357 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2358 blobid[i] = g_blobid; 2359 2360 /* Open a blob */ 2361 spdk_bs_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL); 2362 CU_ASSERT(g_bserrno == 0); 2363 CU_ASSERT(g_blob != NULL); 2364 blob[i] = g_blob; 2365 2366 /* Set a fairly large xattr on both blobs to eat up 2367 * metadata space 2368 */ 2369 value = calloc(dev->blocklen - 64, sizeof(char)); 2370 SPDK_CU_ASSERT_FATAL(value != NULL); 2371 memset(value, i, dev->blocklen / 2); 2372 rc = spdk_blob_set_xattr(blob[i], "name", value, dev->blocklen - 64); 2373 CU_ASSERT(rc == 0); 2374 free(value); 2375 } 2376 2377 /* Resize the blobs, alternating 1 cluster at a time. 2378 * This thwarts run length encoding and will cause spill 2379 * over of the extents. 2380 */ 2381 for (i = 0; i < 6; i++) { 2382 spdk_blob_resize(blob[i % 2], (i / 2) + 1, blob_op_complete, NULL); 2383 CU_ASSERT(g_bserrno == 0); 2384 } 2385 2386 for (i = 0; i < 2; i++) { 2387 spdk_blob_sync_md(blob[i], blob_op_complete, NULL); 2388 CU_ASSERT(g_bserrno == 0); 2389 } 2390 2391 /* Close the blobs */ 2392 for (i = 0; i < 2; i++) { 2393 spdk_blob_close(blob[i], blob_op_complete, NULL); 2394 CU_ASSERT(g_bserrno == 0); 2395 } 2396 2397 /* Unload the blobstore */ 2398 spdk_bs_unload(bs, bs_op_complete, NULL); 2399 CU_ASSERT(g_bserrno == 0); 2400 g_bs = NULL; 2401 g_blob = NULL; 2402 g_blobid = 0; 2403 bs = NULL; 2404 2405 dev = init_dev(); 2406 /* Load an existing blob store */ 2407 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2408 CU_ASSERT(g_bserrno == 0); 2409 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2410 bs = g_bs; 2411 2412 for (i = 0; i < 2; i++) { 2413 blob[i] = NULL; 2414 2415 spdk_bs_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL); 2416 CU_ASSERT(g_bserrno == 0); 2417 CU_ASSERT(g_blob != NULL); 2418 blob[i] = g_blob; 2419 2420 CU_ASSERT(spdk_blob_get_num_clusters(blob[i]) == 3); 2421 2422 spdk_blob_close(blob[i], blob_op_complete, NULL); 2423 CU_ASSERT(g_bserrno == 0); 2424 } 2425 2426 spdk_bs_unload(bs, bs_op_complete, NULL); 2427 CU_ASSERT(g_bserrno == 0); 2428 g_bs = NULL; 2429 } 2430 2431 static void 2432 blob_crc(void) 2433 { 2434 struct spdk_blob_store *bs; 2435 struct spdk_bs_dev *dev; 2436 struct spdk_blob *blob; 2437 spdk_blob_id blobid; 2438 uint32_t page_num; 2439 int index; 2440 struct spdk_blob_md_page *page; 2441 2442 dev = init_dev(); 2443 2444 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2445 CU_ASSERT(g_bserrno == 0); 2446 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2447 bs = g_bs; 2448 2449 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 2450 CU_ASSERT(g_bserrno == 0); 2451 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2452 blobid = g_blobid; 2453 2454 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2455 CU_ASSERT(g_bserrno == 0); 2456 CU_ASSERT(g_blob != NULL); 2457 blob = g_blob; 2458 2459 spdk_blob_close(blob, blob_op_complete, NULL); 2460 CU_ASSERT(g_bserrno == 0); 2461 2462 page_num = _spdk_bs_blobid_to_page(blobid); 2463 index = DEV_BUFFER_BLOCKLEN * (bs->md_start + page_num); 2464 page = (struct spdk_blob_md_page *)&g_dev_buffer[index]; 2465 page->crc = 0; 2466 2467 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2468 CU_ASSERT(g_bserrno == -EINVAL); 2469 CU_ASSERT(g_blob == NULL); 2470 g_bserrno = 0; 2471 2472 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 2473 CU_ASSERT(g_bserrno == -EINVAL); 2474 2475 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2476 CU_ASSERT(g_bserrno == 0); 2477 g_bs = NULL; 2478 } 2479 2480 static void 2481 super_block_crc(void) 2482 { 2483 struct spdk_bs_dev *dev; 2484 struct spdk_bs_super_block *super_block; 2485 struct spdk_bs_opts opts; 2486 2487 dev = init_dev(); 2488 spdk_bs_opts_init(&opts); 2489 2490 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2491 CU_ASSERT(g_bserrno == 0); 2492 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2493 2494 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2495 CU_ASSERT(g_bserrno == 0); 2496 g_bs = NULL; 2497 2498 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 2499 super_block->crc = 0; 2500 dev = init_dev(); 2501 2502 /* Load an existing blob store */ 2503 g_bserrno = 0; 2504 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2505 CU_ASSERT(g_bserrno == -EILSEQ); 2506 } 2507 2508 /* For blob dirty shutdown test case we do the following sub-test cases: 2509 * 1 Initialize new blob store and create 1 super blob with some xattrs, then we 2510 * dirty shutdown and reload the blob store and verify the xattrs. 2511 * 2 Resize the blob from 10 clusters to 20 clusters and then dirty shutdown, 2512 * reload the blob store and verify the clusters number. 2513 * 3 Create the second blob and then dirty shutdown, reload the blob store 2514 * and verify the second blob. 2515 * 4 Delete the second blob and then dirty shutdown, reload the blob store 2516 * and verify the second blob is invalid. 2517 * 5 Create the second blob again and also create the third blob, modify the 2518 * md of second blob which makes the md invalid, and then dirty shutdown, 2519 * reload the blob store verify the second blob, it should invalid and also 2520 * verify the third blob, it should correct. 2521 */ 2522 static void 2523 blob_dirty_shutdown(void) 2524 { 2525 int rc; 2526 int index; 2527 struct spdk_bs_dev *dev; 2528 spdk_blob_id blobid1, blobid2, blobid3; 2529 struct spdk_blob *blob; 2530 uint64_t length; 2531 uint64_t free_clusters; 2532 const void *value; 2533 size_t value_len; 2534 uint32_t page_num; 2535 struct spdk_blob_md_page *page; 2536 struct spdk_bs_opts opts; 2537 2538 dev = init_dev(); 2539 spdk_bs_opts_init(&opts); 2540 /* Initialize a new blob store */ 2541 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2542 CU_ASSERT(g_bserrno == 0); 2543 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2544 2545 /* Create first blob */ 2546 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2547 CU_ASSERT(g_bserrno == 0); 2548 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2549 blobid1 = g_blobid; 2550 2551 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 2552 CU_ASSERT(g_bserrno == 0); 2553 CU_ASSERT(g_blob != NULL); 2554 blob = g_blob; 2555 2556 /* Set some xattrs */ 2557 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 2558 CU_ASSERT(rc == 0); 2559 2560 length = 2345; 2561 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 2562 CU_ASSERT(rc == 0); 2563 2564 /* Resize the blob */ 2565 spdk_blob_resize(blob, 10, blob_op_complete, NULL); 2566 CU_ASSERT(g_bserrno == 0); 2567 2568 /* Set the blob as the super blob */ 2569 spdk_bs_set_super(g_bs, blobid1, blob_op_complete, NULL); 2570 CU_ASSERT(g_bserrno == 0); 2571 2572 free_clusters = spdk_bs_free_cluster_count(g_bs); 2573 2574 spdk_blob_close(blob, blob_op_complete, NULL); 2575 blob = NULL; 2576 g_blob = NULL; 2577 g_blobid = SPDK_BLOBID_INVALID; 2578 2579 /* Dirty shutdown */ 2580 _spdk_bs_free(g_bs); 2581 2582 /* reload blobstore */ 2583 dev = init_dev(); 2584 spdk_bs_opts_init(&opts); 2585 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2586 CU_ASSERT(g_bserrno == 0); 2587 2588 /* Get the super blob */ 2589 spdk_bs_get_super(g_bs, blob_op_with_id_complete, NULL); 2590 CU_ASSERT(g_bserrno == 0); 2591 CU_ASSERT(blobid1 == g_blobid); 2592 2593 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 2594 CU_ASSERT(g_bserrno == 0); 2595 CU_ASSERT(g_blob != NULL); 2596 blob = g_blob; 2597 2598 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 2599 2600 /* Get the xattrs */ 2601 value = NULL; 2602 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 2603 CU_ASSERT(rc == 0); 2604 SPDK_CU_ASSERT_FATAL(value != NULL); 2605 CU_ASSERT(*(uint64_t *)value == length); 2606 CU_ASSERT(value_len == 8); 2607 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 2608 2609 /* Resize the blob */ 2610 spdk_blob_resize(blob, 20, blob_op_complete, NULL); 2611 CU_ASSERT(g_bserrno == 0); 2612 2613 free_clusters = spdk_bs_free_cluster_count(g_bs); 2614 2615 spdk_blob_close(blob, blob_op_complete, NULL); 2616 CU_ASSERT(g_bserrno == 0); 2617 blob = NULL; 2618 g_blob = NULL; 2619 g_blobid = SPDK_BLOBID_INVALID; 2620 2621 /* Dirty shutdown */ 2622 _spdk_bs_free(g_bs); 2623 2624 /* reload the blobstore */ 2625 dev = init_dev(); 2626 spdk_bs_opts_init(&opts); 2627 /* Load an existing blob store */ 2628 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2629 CU_ASSERT(g_bserrno == 0); 2630 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2631 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 2632 CU_ASSERT(g_bserrno == 0); 2633 CU_ASSERT(g_blob != NULL); 2634 blob = g_blob; 2635 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 20); 2636 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 2637 2638 spdk_blob_close(blob, blob_op_complete, NULL); 2639 CU_ASSERT(g_bserrno == 0); 2640 blob = NULL; 2641 g_blob = NULL; 2642 g_blobid = SPDK_BLOBID_INVALID; 2643 2644 /* Create second blob */ 2645 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2646 CU_ASSERT(g_bserrno == 0); 2647 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2648 blobid2 = g_blobid; 2649 2650 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 2651 CU_ASSERT(g_bserrno == 0); 2652 CU_ASSERT(g_blob != NULL); 2653 blob = g_blob; 2654 2655 /* Set some xattrs */ 2656 rc = spdk_blob_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1); 2657 CU_ASSERT(rc == 0); 2658 2659 length = 5432; 2660 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 2661 CU_ASSERT(rc == 0); 2662 2663 /* Resize the blob */ 2664 spdk_blob_resize(blob, 10, blob_op_complete, NULL); 2665 CU_ASSERT(g_bserrno == 0); 2666 2667 free_clusters = spdk_bs_free_cluster_count(g_bs); 2668 2669 spdk_blob_close(blob, blob_op_complete, NULL); 2670 blob = NULL; 2671 g_blob = NULL; 2672 g_blobid = SPDK_BLOBID_INVALID; 2673 2674 /* Dirty shutdown */ 2675 _spdk_bs_free(g_bs); 2676 2677 /* reload the blobstore */ 2678 dev = init_dev(); 2679 spdk_bs_opts_init(&opts); 2680 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2681 CU_ASSERT(g_bserrno == 0); 2682 2683 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 2684 CU_ASSERT(g_bserrno == 0); 2685 CU_ASSERT(g_blob != NULL); 2686 blob = g_blob; 2687 2688 /* Get the xattrs */ 2689 value = NULL; 2690 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 2691 CU_ASSERT(rc == 0); 2692 SPDK_CU_ASSERT_FATAL(value != NULL); 2693 CU_ASSERT(*(uint64_t *)value == length); 2694 CU_ASSERT(value_len == 8); 2695 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 2696 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 2697 2698 spdk_blob_close(blob, blob_op_complete, NULL); 2699 CU_ASSERT(g_bserrno == 0); 2700 spdk_bs_delete_blob(g_bs, blobid2, blob_op_complete, NULL); 2701 CU_ASSERT(g_bserrno == 0); 2702 2703 free_clusters = spdk_bs_free_cluster_count(g_bs); 2704 2705 /* Dirty shutdown */ 2706 _spdk_bs_free(g_bs); 2707 /* reload the blobstore */ 2708 dev = init_dev(); 2709 spdk_bs_opts_init(&opts); 2710 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2711 CU_ASSERT(g_bserrno == 0); 2712 2713 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 2714 CU_ASSERT(g_bserrno != 0); 2715 CU_ASSERT(g_blob == NULL); 2716 2717 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 2718 CU_ASSERT(g_bserrno == 0); 2719 CU_ASSERT(g_blob != NULL); 2720 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 2721 spdk_blob_close(g_blob, blob_op_complete, NULL); 2722 CU_ASSERT(g_bserrno == 0); 2723 2724 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2725 CU_ASSERT(g_bserrno == 0); 2726 g_bs = NULL; 2727 2728 /* reload the blobstore */ 2729 dev = init_dev(); 2730 spdk_bs_opts_init(&opts); 2731 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2732 CU_ASSERT(g_bserrno == 0); 2733 2734 /* Create second blob */ 2735 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2736 CU_ASSERT(g_bserrno == 0); 2737 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2738 blobid2 = g_blobid; 2739 2740 /* Create third blob */ 2741 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2742 CU_ASSERT(g_bserrno == 0); 2743 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2744 blobid3 = g_blobid; 2745 2746 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 2747 CU_ASSERT(g_bserrno == 0); 2748 CU_ASSERT(g_blob != NULL); 2749 blob = g_blob; 2750 2751 /* Set some xattrs for second blob */ 2752 rc = spdk_blob_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1); 2753 CU_ASSERT(rc == 0); 2754 2755 length = 5432; 2756 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 2757 CU_ASSERT(rc == 0); 2758 2759 spdk_blob_close(blob, blob_op_complete, NULL); 2760 blob = NULL; 2761 g_blob = NULL; 2762 g_blobid = SPDK_BLOBID_INVALID; 2763 2764 spdk_bs_open_blob(g_bs, blobid3, blob_op_with_handle_complete, NULL); 2765 CU_ASSERT(g_bserrno == 0); 2766 CU_ASSERT(g_blob != NULL); 2767 blob = g_blob; 2768 2769 /* Set some xattrs for third blob */ 2770 rc = spdk_blob_set_xattr(blob, "name", "log2.txt", strlen("log2.txt") + 1); 2771 CU_ASSERT(rc == 0); 2772 2773 length = 5432; 2774 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 2775 CU_ASSERT(rc == 0); 2776 2777 spdk_blob_close(blob, blob_op_complete, NULL); 2778 blob = NULL; 2779 g_blob = NULL; 2780 g_blobid = SPDK_BLOBID_INVALID; 2781 2782 /* Mark second blob as invalid */ 2783 page_num = _spdk_bs_blobid_to_page(blobid2); 2784 2785 index = DEV_BUFFER_BLOCKLEN * (g_bs->md_start + page_num); 2786 page = (struct spdk_blob_md_page *)&g_dev_buffer[index]; 2787 page->sequence_num = 1; 2788 page->crc = _spdk_blob_md_page_calc_crc(page); 2789 2790 free_clusters = spdk_bs_free_cluster_count(g_bs); 2791 2792 /* Dirty shutdown */ 2793 _spdk_bs_free(g_bs); 2794 /* reload the blobstore */ 2795 dev = init_dev(); 2796 spdk_bs_opts_init(&opts); 2797 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2798 CU_ASSERT(g_bserrno == 0); 2799 2800 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 2801 CU_ASSERT(g_bserrno != 0); 2802 CU_ASSERT(g_blob == NULL); 2803 2804 spdk_bs_open_blob(g_bs, blobid3, blob_op_with_handle_complete, NULL); 2805 CU_ASSERT(g_bserrno == 0); 2806 CU_ASSERT(g_blob != NULL); 2807 blob = g_blob; 2808 2809 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 2810 2811 spdk_blob_close(blob, blob_op_complete, NULL); 2812 blob = NULL; 2813 g_blob = NULL; 2814 g_blobid = SPDK_BLOBID_INVALID; 2815 2816 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2817 CU_ASSERT(g_bserrno == 0); 2818 g_bs = NULL; 2819 } 2820 2821 static void 2822 blob_flags(void) 2823 { 2824 struct spdk_bs_dev *dev; 2825 spdk_blob_id blobid_invalid, blobid_data_ro, blobid_md_ro; 2826 struct spdk_blob *blob_invalid, *blob_data_ro, *blob_md_ro; 2827 struct spdk_bs_opts opts; 2828 int rc; 2829 2830 dev = init_dev(); 2831 spdk_bs_opts_init(&opts); 2832 2833 /* Initialize a new blob store */ 2834 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2835 CU_ASSERT(g_bserrno == 0); 2836 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2837 2838 /* Create three blobs - one each for testing invalid, data_ro and md_ro flags. */ 2839 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2840 CU_ASSERT(g_bserrno == 0); 2841 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2842 blobid_invalid = g_blobid; 2843 2844 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2845 CU_ASSERT(g_bserrno == 0); 2846 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2847 blobid_data_ro = g_blobid; 2848 2849 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2850 CU_ASSERT(g_bserrno == 0); 2851 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2852 blobid_md_ro = g_blobid; 2853 2854 spdk_bs_open_blob(g_bs, blobid_invalid, blob_op_with_handle_complete, NULL); 2855 CU_ASSERT(g_bserrno == 0); 2856 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2857 blob_invalid = g_blob; 2858 2859 spdk_bs_open_blob(g_bs, blobid_data_ro, blob_op_with_handle_complete, NULL); 2860 CU_ASSERT(g_bserrno == 0); 2861 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2862 blob_data_ro = g_blob; 2863 2864 spdk_bs_open_blob(g_bs, blobid_md_ro, blob_op_with_handle_complete, NULL); 2865 CU_ASSERT(g_bserrno == 0); 2866 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2867 blob_md_ro = g_blob; 2868 2869 /* Change the size of blob_data_ro to check if flags are serialized 2870 * when blob has non zero number of extents */ 2871 spdk_blob_resize(blob_data_ro, 10, blob_op_complete, NULL); 2872 CU_ASSERT(g_bserrno == 0); 2873 2874 /* Set the xattr to check if flags are serialized 2875 * when blob has non zero number of xattrs */ 2876 rc = spdk_blob_set_xattr(blob_md_ro, "name", "log.txt", strlen("log.txt") + 1); 2877 CU_ASSERT(rc == 0); 2878 2879 blob_invalid->invalid_flags = (1ULL << 63); 2880 blob_invalid->state = SPDK_BLOB_STATE_DIRTY; 2881 blob_data_ro->data_ro_flags = (1ULL << 62); 2882 blob_data_ro->state = SPDK_BLOB_STATE_DIRTY; 2883 blob_md_ro->md_ro_flags = (1ULL << 61); 2884 blob_md_ro->state = SPDK_BLOB_STATE_DIRTY; 2885 2886 g_bserrno = -1; 2887 spdk_blob_sync_md(blob_invalid, blob_op_complete, NULL); 2888 CU_ASSERT(g_bserrno == 0); 2889 g_bserrno = -1; 2890 spdk_blob_sync_md(blob_data_ro, blob_op_complete, NULL); 2891 CU_ASSERT(g_bserrno == 0); 2892 g_bserrno = -1; 2893 spdk_blob_sync_md(blob_md_ro, blob_op_complete, NULL); 2894 CU_ASSERT(g_bserrno == 0); 2895 2896 g_bserrno = -1; 2897 spdk_blob_close(blob_invalid, blob_op_complete, NULL); 2898 CU_ASSERT(g_bserrno == 0); 2899 blob_invalid = NULL; 2900 g_bserrno = -1; 2901 spdk_blob_close(blob_data_ro, blob_op_complete, NULL); 2902 CU_ASSERT(g_bserrno == 0); 2903 blob_data_ro = NULL; 2904 g_bserrno = -1; 2905 spdk_blob_close(blob_md_ro, blob_op_complete, NULL); 2906 CU_ASSERT(g_bserrno == 0); 2907 blob_md_ro = NULL; 2908 2909 g_blob = NULL; 2910 g_blobid = SPDK_BLOBID_INVALID; 2911 2912 /* Unload the blob store */ 2913 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2914 CU_ASSERT(g_bserrno == 0); 2915 g_bs = NULL; 2916 2917 /* Load an existing blob store */ 2918 dev = init_dev(); 2919 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2920 CU_ASSERT(g_bserrno == 0); 2921 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2922 2923 g_blob = NULL; 2924 g_bserrno = 0; 2925 spdk_bs_open_blob(g_bs, blobid_invalid, blob_op_with_handle_complete, NULL); 2926 CU_ASSERT(g_bserrno != 0); 2927 CU_ASSERT(g_blob == NULL); 2928 2929 g_blob = NULL; 2930 g_bserrno = -1; 2931 spdk_bs_open_blob(g_bs, blobid_data_ro, blob_op_with_handle_complete, NULL); 2932 CU_ASSERT(g_bserrno == 0); 2933 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2934 blob_data_ro = g_blob; 2935 /* If an unknown data_ro flag was found, the blob should be marked both data and md read-only. */ 2936 CU_ASSERT(blob_data_ro->data_ro == true); 2937 CU_ASSERT(blob_data_ro->md_ro == true); 2938 CU_ASSERT(spdk_blob_get_num_clusters(blob_data_ro) == 10); 2939 2940 g_blob = NULL; 2941 g_bserrno = -1; 2942 spdk_bs_open_blob(g_bs, blobid_md_ro, blob_op_with_handle_complete, NULL); 2943 CU_ASSERT(g_bserrno == 0); 2944 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2945 blob_md_ro = g_blob; 2946 CU_ASSERT(blob_md_ro->data_ro == false); 2947 CU_ASSERT(blob_md_ro->md_ro == true); 2948 2949 g_bserrno = -1; 2950 spdk_blob_sync_md(blob_md_ro, blob_op_complete, NULL); 2951 CU_ASSERT(g_bserrno == 0); 2952 2953 spdk_blob_close(blob_data_ro, blob_op_complete, NULL); 2954 CU_ASSERT(g_bserrno == 0); 2955 spdk_blob_close(blob_md_ro, blob_op_complete, NULL); 2956 CU_ASSERT(g_bserrno == 0); 2957 2958 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2959 CU_ASSERT(g_bserrno == 0); 2960 } 2961 2962 static void 2963 bs_version(void) 2964 { 2965 struct spdk_bs_super_block *super; 2966 struct spdk_bs_dev *dev; 2967 struct spdk_bs_opts opts; 2968 spdk_blob_id blobid; 2969 2970 dev = init_dev(); 2971 spdk_bs_opts_init(&opts); 2972 2973 /* Initialize a new blob store */ 2974 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2975 CU_ASSERT(g_bserrno == 0); 2976 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2977 2978 /* Unload the blob store */ 2979 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2980 CU_ASSERT(g_bserrno == 0); 2981 g_bs = NULL; 2982 2983 /* 2984 * Change the bs version on disk. This will allow us to 2985 * test that the version does not get modified automatically 2986 * when loading and unloading the blobstore. 2987 */ 2988 super = (struct spdk_bs_super_block *)&g_dev_buffer[0]; 2989 CU_ASSERT(super->version == SPDK_BS_VERSION); 2990 CU_ASSERT(super->clean == 1); 2991 super->version = 2; 2992 /* 2993 * Version 2 metadata does not have a used blobid mask, so clear 2994 * those fields in the super block and zero the corresponding 2995 * region on "disk". We will use this to ensure blob IDs are 2996 * correctly reconstructed. 2997 */ 2998 memset(&g_dev_buffer[super->used_blobid_mask_start * SPDK_BS_PAGE_SIZE], 0, 2999 super->used_blobid_mask_len * SPDK_BS_PAGE_SIZE); 3000 super->used_blobid_mask_start = 0; 3001 super->used_blobid_mask_len = 0; 3002 super->crc = _spdk_blob_md_page_calc_crc(super); 3003 3004 /* Load an existing blob store */ 3005 dev = init_dev(); 3006 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3007 CU_ASSERT(g_bserrno == 0); 3008 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3009 CU_ASSERT(super->clean == 0); 3010 3011 /* 3012 * Create a blob - just to make sure that when we unload it 3013 * results in writing the super block (since metadata pages 3014 * were allocated. 3015 */ 3016 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 3017 CU_ASSERT(g_bserrno == 0); 3018 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3019 blobid = g_blobid; 3020 3021 /* Unload the blob store */ 3022 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3023 CU_ASSERT(g_bserrno == 0); 3024 g_bs = NULL; 3025 CU_ASSERT(super->version == 2); 3026 CU_ASSERT(super->used_blobid_mask_start == 0); 3027 CU_ASSERT(super->used_blobid_mask_len == 0); 3028 3029 dev = init_dev(); 3030 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3031 CU_ASSERT(g_bserrno == 0); 3032 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3033 3034 g_blob = NULL; 3035 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 3036 CU_ASSERT(g_bserrno == 0); 3037 CU_ASSERT(g_blob != NULL); 3038 3039 spdk_blob_close(g_blob, blob_op_complete, NULL); 3040 CU_ASSERT(g_bserrno == 0); 3041 3042 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3043 CU_ASSERT(g_bserrno == 0); 3044 g_bs = NULL; 3045 CU_ASSERT(super->version == 2); 3046 CU_ASSERT(super->used_blobid_mask_start == 0); 3047 CU_ASSERT(super->used_blobid_mask_len == 0); 3048 } 3049 3050 static void 3051 blob_set_xattrs(void) 3052 { 3053 struct spdk_blob_store *bs; 3054 struct spdk_bs_dev *dev; 3055 struct spdk_blob *blob; 3056 struct spdk_blob_opts opts; 3057 spdk_blob_id blobid; 3058 const void *value; 3059 size_t value_len; 3060 int rc; 3061 3062 dev = init_dev(); 3063 3064 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3065 CU_ASSERT(g_bserrno == 0); 3066 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3067 bs = g_bs; 3068 3069 /* Create blob with extra attributes */ 3070 spdk_blob_opts_init(&opts); 3071 3072 opts.xattrs.names = g_xattr_names; 3073 opts.xattrs.get_value = _get_xattr_value; 3074 opts.xattrs.count = 3; 3075 opts.xattrs.ctx = &g_ctx; 3076 3077 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 3078 CU_ASSERT(g_bserrno == 0); 3079 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3080 blobid = g_blobid; 3081 3082 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3083 CU_ASSERT(g_bserrno == 0); 3084 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3085 blob = g_blob; 3086 3087 /* Get the xattrs */ 3088 value = NULL; 3089 3090 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[0], &value, &value_len); 3091 CU_ASSERT(rc == 0); 3092 SPDK_CU_ASSERT_FATAL(value != NULL); 3093 CU_ASSERT(value_len == strlen(g_xattr_values[0])); 3094 CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len); 3095 3096 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[1], &value, &value_len); 3097 CU_ASSERT(rc == 0); 3098 SPDK_CU_ASSERT_FATAL(value != NULL); 3099 CU_ASSERT(value_len == strlen(g_xattr_values[1])); 3100 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len); 3101 3102 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[2], &value, &value_len); 3103 CU_ASSERT(rc == 0); 3104 SPDK_CU_ASSERT_FATAL(value != NULL); 3105 CU_ASSERT(value_len == strlen(g_xattr_values[2])); 3106 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len); 3107 3108 /* Try to get non existing attribute */ 3109 3110 rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len); 3111 CU_ASSERT(rc == -ENOENT); 3112 3113 spdk_blob_close(blob, blob_op_complete, NULL); 3114 CU_ASSERT(g_bserrno == 0); 3115 blob = NULL; 3116 g_blob = NULL; 3117 g_blobid = SPDK_BLOBID_INVALID; 3118 3119 /* NULL callback */ 3120 spdk_blob_opts_init(&opts); 3121 opts.xattrs.names = g_xattr_names; 3122 opts.xattrs.get_value = NULL; 3123 opts.xattrs.count = 1; 3124 opts.xattrs.ctx = &g_ctx; 3125 3126 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 3127 CU_ASSERT(g_bserrno == -EINVAL); 3128 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3129 3130 /* NULL values */ 3131 spdk_blob_opts_init(&opts); 3132 opts.xattrs.names = g_xattr_names; 3133 opts.xattrs.get_value = _get_xattr_value_null; 3134 opts.xattrs.count = 1; 3135 opts.xattrs.ctx = NULL; 3136 3137 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 3138 CU_ASSERT(g_bserrno == -EINVAL); 3139 3140 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3141 CU_ASSERT(g_bserrno == 0); 3142 g_bs = NULL; 3143 3144 } 3145 3146 static void 3147 blob_thin_prov_alloc(void) 3148 { 3149 struct spdk_blob_store *bs; 3150 struct spdk_bs_dev *dev; 3151 struct spdk_blob *blob; 3152 struct spdk_blob_opts opts; 3153 spdk_blob_id blobid; 3154 uint64_t free_clusters; 3155 3156 dev = init_dev(); 3157 3158 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3159 CU_ASSERT(g_bserrno == 0); 3160 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3161 bs = g_bs; 3162 free_clusters = spdk_bs_free_cluster_count(bs); 3163 3164 /* Set blob as thin provisioned */ 3165 spdk_blob_opts_init(&opts); 3166 opts.thin_provision = true; 3167 3168 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 3169 CU_ASSERT(g_bserrno == 0); 3170 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3171 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3172 blobid = g_blobid; 3173 3174 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3175 CU_ASSERT(g_bserrno == 0); 3176 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3177 blob = g_blob; 3178 3179 CU_ASSERT(blob->active.num_clusters == 0); 3180 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0); 3181 3182 /* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */ 3183 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 3184 CU_ASSERT(g_bserrno == 0); 3185 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3186 CU_ASSERT(blob->active.num_clusters == 5); 3187 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 3188 3189 /* Shrink the blob to 3 clusters - still unallocated */ 3190 spdk_blob_resize(blob, 3, blob_op_complete, NULL); 3191 CU_ASSERT(g_bserrno == 0); 3192 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3193 CU_ASSERT(blob->active.num_clusters == 3); 3194 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 3); 3195 3196 spdk_blob_sync_md(blob, blob_op_complete, NULL); 3197 CU_ASSERT(g_bserrno == 0); 3198 /* Sync must not change anything */ 3199 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3200 CU_ASSERT(blob->active.num_clusters == 3); 3201 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 3); 3202 3203 spdk_blob_close(blob, blob_op_complete, NULL); 3204 CU_ASSERT(g_bserrno == 0); 3205 3206 /* Unload the blob store */ 3207 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3208 CU_ASSERT(g_bserrno == 0); 3209 g_bs = NULL; 3210 g_blob = NULL; 3211 g_blobid = 0; 3212 3213 /* Load an existing blob store */ 3214 dev = init_dev(); 3215 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 3216 CU_ASSERT(g_bserrno == 0); 3217 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3218 3219 bs = g_bs; 3220 3221 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 3222 CU_ASSERT(g_bserrno == 0); 3223 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3224 blob = g_blob; 3225 3226 /* Check that clusters allocation and size is still the same */ 3227 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3228 CU_ASSERT(blob->active.num_clusters == 3); 3229 3230 spdk_blob_close(blob, blob_op_complete, NULL); 3231 CU_ASSERT(g_bserrno == 0); 3232 3233 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 3234 CU_ASSERT(g_bserrno == 0); 3235 3236 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3237 CU_ASSERT(g_bserrno == 0); 3238 g_bs = NULL; 3239 } 3240 3241 static void 3242 blob_insert_cluster_msg(void) 3243 { 3244 struct spdk_blob_store *bs; 3245 struct spdk_bs_dev *dev; 3246 struct spdk_blob *blob; 3247 struct spdk_blob_opts opts; 3248 spdk_blob_id blobid; 3249 uint64_t free_clusters; 3250 3251 dev = init_dev(); 3252 3253 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3254 CU_ASSERT(g_bserrno == 0); 3255 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3256 bs = g_bs; 3257 free_clusters = spdk_bs_free_cluster_count(bs); 3258 3259 /* Set blob as thin provisioned */ 3260 spdk_blob_opts_init(&opts); 3261 opts.thin_provision = true; 3262 opts.num_clusters = 4; 3263 3264 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 3265 CU_ASSERT(g_bserrno == 0); 3266 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3267 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3268 blobid = g_blobid; 3269 3270 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3271 CU_ASSERT(g_bserrno == 0); 3272 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3273 blob = g_blob; 3274 3275 CU_ASSERT(blob->active.num_clusters == 4); 3276 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 4); 3277 CU_ASSERT(blob->active.clusters[1] == 0); 3278 3279 _spdk_bs_claim_cluster(bs, 0xF); 3280 _spdk_blob_insert_cluster_on_md_thread(blob, 1, 0xF, blob_op_complete, NULL); 3281 3282 CU_ASSERT(blob->active.clusters[1] != 0); 3283 3284 spdk_blob_close(blob, blob_op_complete, NULL); 3285 CU_ASSERT(g_bserrno == 0); 3286 3287 /* Unload the blob store */ 3288 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3289 CU_ASSERT(g_bserrno == 0); 3290 g_bs = NULL; 3291 g_blob = NULL; 3292 g_blobid = 0; 3293 3294 /* Load an existing blob store */ 3295 dev = init_dev(); 3296 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 3297 CU_ASSERT(g_bserrno == 0); 3298 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3299 3300 bs = g_bs; 3301 3302 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 3303 CU_ASSERT(g_bserrno == 0); 3304 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3305 blob = g_blob; 3306 3307 CU_ASSERT(blob->active.clusters[1] != 0); 3308 3309 spdk_blob_close(blob, blob_op_complete, NULL); 3310 CU_ASSERT(g_bserrno == 0); 3311 3312 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 3313 CU_ASSERT(g_bserrno == 0); 3314 3315 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3316 CU_ASSERT(g_bserrno == 0); 3317 g_bs = NULL; 3318 } 3319 3320 static void 3321 blob_thin_prov_rw(void) 3322 { 3323 static const uint8_t zero[10 * 4096] = { 0 }; 3324 struct spdk_blob_store *bs; 3325 struct spdk_bs_dev *dev; 3326 struct spdk_blob *blob; 3327 struct spdk_io_channel *channel; 3328 struct spdk_blob_opts opts; 3329 spdk_blob_id blobid; 3330 uint64_t free_clusters; 3331 uint8_t payload_read[10 * 4096]; 3332 uint8_t payload_write[10 * 4096]; 3333 3334 dev = init_dev(); 3335 3336 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3337 CU_ASSERT(g_bserrno == 0); 3338 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3339 bs = g_bs; 3340 free_clusters = spdk_bs_free_cluster_count(bs); 3341 3342 channel = spdk_bs_alloc_io_channel(bs); 3343 CU_ASSERT(channel != NULL); 3344 3345 spdk_blob_opts_init(&opts); 3346 opts.thin_provision = true; 3347 3348 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 3349 CU_ASSERT(g_bserrno == 0); 3350 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3351 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3352 blobid = g_blobid; 3353 3354 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3355 CU_ASSERT(g_bserrno == 0); 3356 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3357 blob = g_blob; 3358 3359 CU_ASSERT(blob->active.num_clusters == 0); 3360 3361 /* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */ 3362 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 3363 CU_ASSERT(g_bserrno == 0); 3364 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3365 CU_ASSERT(blob->active.num_clusters == 5); 3366 3367 spdk_blob_sync_md(blob, blob_op_complete, NULL); 3368 CU_ASSERT(g_bserrno == 0); 3369 /* Sync must not change anything */ 3370 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3371 CU_ASSERT(blob->active.num_clusters == 5); 3372 3373 /* Payload should be all zeros from unallocated clusters */ 3374 memset(payload_read, 0xFF, sizeof(payload_read)); 3375 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 3376 CU_ASSERT(g_bserrno == 0); 3377 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 3378 3379 memset(payload_write, 0xE5, sizeof(payload_write)); 3380 spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL); 3381 CU_ASSERT(g_bserrno == 0); 3382 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 3383 3384 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 3385 CU_ASSERT(g_bserrno == 0); 3386 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 3387 3388 spdk_blob_close(blob, blob_op_complete, NULL); 3389 CU_ASSERT(g_bserrno == 0); 3390 3391 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 3392 CU_ASSERT(g_bserrno == 0); 3393 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3394 3395 spdk_bs_free_io_channel(channel); 3396 3397 /* Unload the blob store */ 3398 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3399 CU_ASSERT(g_bserrno == 0); 3400 g_bs = NULL; 3401 g_blob = NULL; 3402 g_blobid = 0; 3403 } 3404 3405 static void 3406 blob_thin_prov_rw_iov(void) 3407 { 3408 static const uint8_t zero[10 * 4096] = { 0 }; 3409 struct spdk_blob_store *bs; 3410 struct spdk_bs_dev *dev; 3411 struct spdk_blob *blob; 3412 struct spdk_io_channel *channel; 3413 struct spdk_blob_opts opts; 3414 spdk_blob_id blobid; 3415 uint64_t free_clusters; 3416 uint8_t payload_read[10 * 4096]; 3417 uint8_t payload_write[10 * 4096]; 3418 struct iovec iov_read[3]; 3419 struct iovec iov_write[3]; 3420 3421 dev = init_dev(); 3422 3423 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3424 CU_ASSERT(g_bserrno == 0); 3425 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3426 bs = g_bs; 3427 free_clusters = spdk_bs_free_cluster_count(bs); 3428 3429 channel = spdk_bs_alloc_io_channel(bs); 3430 CU_ASSERT(channel != NULL); 3431 3432 spdk_blob_opts_init(&opts); 3433 opts.thin_provision = true; 3434 3435 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 3436 CU_ASSERT(g_bserrno == 0); 3437 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3438 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3439 blobid = g_blobid; 3440 3441 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3442 CU_ASSERT(g_bserrno == 0); 3443 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3444 blob = g_blob; 3445 3446 CU_ASSERT(blob->active.num_clusters == 0); 3447 3448 /* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */ 3449 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 3450 CU_ASSERT(g_bserrno == 0); 3451 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3452 CU_ASSERT(blob->active.num_clusters == 5); 3453 3454 spdk_blob_sync_md(blob, blob_op_complete, NULL); 3455 CU_ASSERT(g_bserrno == 0); 3456 /* Sync must not change anything */ 3457 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3458 CU_ASSERT(blob->active.num_clusters == 5); 3459 3460 /* Payload should be all zeros from unallocated clusters */ 3461 memset(payload_read, 0xAA, sizeof(payload_read)); 3462 iov_read[0].iov_base = payload_read; 3463 iov_read[0].iov_len = 3 * 4096; 3464 iov_read[1].iov_base = payload_read + 3 * 4096; 3465 iov_read[1].iov_len = 4 * 4096; 3466 iov_read[2].iov_base = payload_read + 7 * 4096; 3467 iov_read[2].iov_len = 3 * 4096; 3468 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 3469 CU_ASSERT(g_bserrno == 0); 3470 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 3471 3472 memset(payload_write, 0xE5, sizeof(payload_write)); 3473 iov_write[0].iov_base = payload_write; 3474 iov_write[0].iov_len = 1 * 4096; 3475 iov_write[1].iov_base = payload_write + 1 * 4096; 3476 iov_write[1].iov_len = 5 * 4096; 3477 iov_write[2].iov_base = payload_write + 6 * 4096; 3478 iov_write[2].iov_len = 4 * 4096; 3479 3480 spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 3481 CU_ASSERT(g_bserrno == 0); 3482 3483 memset(payload_read, 0xAA, sizeof(payload_read)); 3484 iov_read[0].iov_base = payload_read; 3485 iov_read[0].iov_len = 3 * 4096; 3486 iov_read[1].iov_base = payload_read + 3 * 4096; 3487 iov_read[1].iov_len = 4 * 4096; 3488 iov_read[2].iov_base = payload_read + 7 * 4096; 3489 iov_read[2].iov_len = 3 * 4096; 3490 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 3491 CU_ASSERT(g_bserrno == 0); 3492 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 3493 3494 spdk_blob_close(blob, blob_op_complete, NULL); 3495 CU_ASSERT(g_bserrno == 0); 3496 3497 spdk_bs_free_io_channel(channel); 3498 3499 /* Unload the blob store */ 3500 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3501 CU_ASSERT(g_bserrno == 0); 3502 g_bs = NULL; 3503 g_blob = NULL; 3504 g_blobid = 0; 3505 } 3506 3507 struct iter_ctx { 3508 int current_iter; 3509 spdk_blob_id blobid[4]; 3510 }; 3511 3512 static void 3513 test_iter(void *arg, struct spdk_blob *blob, int bserrno) 3514 { 3515 struct iter_ctx *iter_ctx = arg; 3516 spdk_blob_id blobid; 3517 3518 CU_ASSERT(bserrno == 0); 3519 blobid = spdk_blob_get_id(blob); 3520 CU_ASSERT(blobid == iter_ctx->blobid[iter_ctx->current_iter++]); 3521 } 3522 3523 static void 3524 bs_load_iter(void) 3525 { 3526 struct spdk_bs_dev *dev; 3527 struct iter_ctx iter_ctx = { 0 }; 3528 struct spdk_blob *blob; 3529 int i, rc; 3530 struct spdk_bs_opts opts; 3531 3532 dev = init_dev(); 3533 spdk_bs_opts_init(&opts); 3534 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 3535 3536 /* Initialize a new blob store */ 3537 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 3538 CU_ASSERT(g_bserrno == 0); 3539 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3540 3541 for (i = 0; i < 4; i++) { 3542 g_bserrno = -1; 3543 g_blobid = SPDK_BLOBID_INVALID; 3544 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 3545 CU_ASSERT(g_bserrno == 0); 3546 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3547 iter_ctx.blobid[i] = g_blobid; 3548 3549 g_bserrno = -1; 3550 g_blob = NULL; 3551 spdk_bs_open_blob(g_bs, g_blobid, blob_op_with_handle_complete, NULL); 3552 CU_ASSERT(g_bserrno == 0); 3553 CU_ASSERT(g_blob != NULL); 3554 blob = g_blob; 3555 3556 /* Just save the blobid as an xattr for testing purposes. */ 3557 rc = spdk_blob_set_xattr(blob, "blobid", &g_blobid, sizeof(g_blobid)); 3558 CU_ASSERT(rc == 0); 3559 3560 /* Resize the blob */ 3561 spdk_blob_resize(blob, i, blob_op_complete, NULL); 3562 CU_ASSERT(g_bserrno == 0); 3563 3564 spdk_blob_close(blob, blob_op_complete, NULL); 3565 CU_ASSERT(g_bserrno == 0); 3566 } 3567 3568 g_bserrno = -1; 3569 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3570 CU_ASSERT(g_bserrno == 0); 3571 3572 dev = init_dev(); 3573 spdk_bs_opts_init(&opts); 3574 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 3575 opts.iter_cb_fn = test_iter; 3576 opts.iter_cb_arg = &iter_ctx; 3577 3578 /* Test blob iteration during load after a clean shutdown. */ 3579 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3580 CU_ASSERT(g_bserrno == 0); 3581 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3582 3583 /* Dirty shutdown */ 3584 _spdk_bs_free(g_bs); 3585 3586 dev = init_dev(); 3587 spdk_bs_opts_init(&opts); 3588 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 3589 opts.iter_cb_fn = test_iter; 3590 iter_ctx.current_iter = 0; 3591 opts.iter_cb_arg = &iter_ctx; 3592 3593 /* Test blob iteration during load after a dirty shutdown. */ 3594 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3595 CU_ASSERT(g_bserrno == 0); 3596 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3597 3598 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3599 CU_ASSERT(g_bserrno == 0); 3600 g_bs = NULL; 3601 } 3602 3603 static void 3604 blob_snapshot_rw(void) 3605 { 3606 static const uint8_t zero[10 * 4096] = { 0 }; 3607 struct spdk_blob_store *bs; 3608 struct spdk_bs_dev *dev; 3609 struct spdk_blob *blob, *snapshot; 3610 struct spdk_io_channel *channel; 3611 struct spdk_blob_opts opts; 3612 spdk_blob_id blobid, snapshotid; 3613 uint64_t free_clusters; 3614 uint8_t payload_read[10 * 4096]; 3615 uint8_t payload_write[10 * 4096]; 3616 3617 dev = init_dev(); 3618 3619 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3620 CU_ASSERT(g_bserrno == 0); 3621 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3622 bs = g_bs; 3623 free_clusters = spdk_bs_free_cluster_count(bs); 3624 3625 channel = spdk_bs_alloc_io_channel(bs); 3626 CU_ASSERT(channel != NULL); 3627 3628 spdk_blob_opts_init(&opts); 3629 opts.thin_provision = true; 3630 opts.num_clusters = 5; 3631 3632 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 3633 CU_ASSERT(g_bserrno == 0); 3634 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3635 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3636 blobid = g_blobid; 3637 3638 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3639 CU_ASSERT(g_bserrno == 0); 3640 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3641 blob = g_blob; 3642 3643 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 3644 3645 memset(payload_read, 0xFF, sizeof(payload_read)); 3646 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 3647 CU_ASSERT(g_bserrno == 0); 3648 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 3649 3650 memset(payload_write, 0xE5, sizeof(payload_write)); 3651 spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL); 3652 CU_ASSERT(g_bserrno == 0); 3653 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 3654 3655 /* Create snapshot from blob */ 3656 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 3657 CU_ASSERT(g_bserrno == 0); 3658 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3659 snapshotid = g_blobid; 3660 3661 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 3662 CU_ASSERT(g_bserrno == 0); 3663 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3664 snapshot = g_blob; 3665 CU_ASSERT(snapshot->data_ro == true) 3666 CU_ASSERT(snapshot->md_ro == true) 3667 3668 CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 5) 3669 3670 memset(payload_write, 0xAA, sizeof(payload_write)); 3671 spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL); 3672 CU_ASSERT(g_bserrno == 0); 3673 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 3674 3675 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 3676 CU_ASSERT(g_bserrno == 0); 3677 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 3678 3679 /* Data on snapshot should not change after write to clone */ 3680 memset(payload_write, 0xE5, sizeof(payload_write)); 3681 spdk_blob_io_read(snapshot, channel, payload_read, 4, 10, blob_op_complete, NULL); 3682 CU_ASSERT(g_bserrno == 0); 3683 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 3684 3685 spdk_blob_close(blob, blob_op_complete, NULL); 3686 CU_ASSERT(g_bserrno == 0); 3687 3688 spdk_blob_close(snapshot, blob_op_complete, NULL); 3689 CU_ASSERT(g_bserrno == 0); 3690 3691 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 3692 CU_ASSERT(g_bserrno == 0); 3693 3694 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 3695 CU_ASSERT(g_bserrno == 0); 3696 3697 spdk_bs_free_io_channel(channel); 3698 3699 /* Unload the blob store */ 3700 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3701 CU_ASSERT(g_bserrno == 0); 3702 g_bs = NULL; 3703 g_blob = NULL; 3704 g_blobid = 0; 3705 } 3706 3707 static void 3708 blob_snapshot_rw_iov(void) 3709 { 3710 static const uint8_t zero[10 * 4096] = { 0 }; 3711 struct spdk_blob_store *bs; 3712 struct spdk_bs_dev *dev; 3713 struct spdk_blob *blob, *snapshot; 3714 struct spdk_io_channel *channel; 3715 struct spdk_blob_opts opts; 3716 spdk_blob_id blobid, snapshotid; 3717 uint64_t free_clusters; 3718 uint8_t payload_read[10 * 4096]; 3719 uint8_t payload_write[10 * 4096]; 3720 struct iovec iov_read[3]; 3721 struct iovec iov_write[3]; 3722 3723 dev = init_dev(); 3724 3725 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3726 CU_ASSERT(g_bserrno == 0); 3727 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3728 bs = g_bs; 3729 free_clusters = spdk_bs_free_cluster_count(bs); 3730 3731 channel = spdk_bs_alloc_io_channel(bs); 3732 CU_ASSERT(channel != NULL); 3733 3734 spdk_blob_opts_init(&opts); 3735 opts.thin_provision = true; 3736 opts.num_clusters = 5; 3737 3738 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 3739 CU_ASSERT(g_bserrno == 0); 3740 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3741 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3742 blobid = g_blobid; 3743 3744 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3745 CU_ASSERT(g_bserrno == 0); 3746 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3747 blob = g_blob; 3748 3749 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 3750 3751 /* Create snapshot from blob */ 3752 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 3753 CU_ASSERT(g_bserrno == 0); 3754 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3755 snapshotid = g_blobid; 3756 3757 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 3758 CU_ASSERT(g_bserrno == 0); 3759 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3760 snapshot = g_blob; 3761 CU_ASSERT(snapshot->data_ro == true) 3762 CU_ASSERT(snapshot->md_ro == true) 3763 CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 5); 3764 3765 /* Payload should be all zeros from unallocated clusters */ 3766 memset(payload_read, 0xAA, sizeof(payload_read)); 3767 iov_read[0].iov_base = payload_read; 3768 iov_read[0].iov_len = 3 * 4096; 3769 iov_read[1].iov_base = payload_read + 3 * 4096; 3770 iov_read[1].iov_len = 4 * 4096; 3771 iov_read[2].iov_base = payload_read + 7 * 4096; 3772 iov_read[2].iov_len = 3 * 4096; 3773 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 3774 CU_ASSERT(g_bserrno == 0); 3775 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 3776 3777 memset(payload_write, 0xE5, sizeof(payload_write)); 3778 iov_write[0].iov_base = payload_write; 3779 iov_write[0].iov_len = 1 * 4096; 3780 iov_write[1].iov_base = payload_write + 1 * 4096; 3781 iov_write[1].iov_len = 5 * 4096; 3782 iov_write[2].iov_base = payload_write + 6 * 4096; 3783 iov_write[2].iov_len = 4 * 4096; 3784 3785 spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 3786 CU_ASSERT(g_bserrno == 0); 3787 3788 memset(payload_read, 0xAA, sizeof(payload_read)); 3789 iov_read[0].iov_base = payload_read; 3790 iov_read[0].iov_len = 3 * 4096; 3791 iov_read[1].iov_base = payload_read + 3 * 4096; 3792 iov_read[1].iov_len = 4 * 4096; 3793 iov_read[2].iov_base = payload_read + 7 * 4096; 3794 iov_read[2].iov_len = 3 * 4096; 3795 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 3796 CU_ASSERT(g_bserrno == 0); 3797 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 3798 3799 spdk_blob_close(blob, blob_op_complete, NULL); 3800 CU_ASSERT(g_bserrno == 0); 3801 3802 spdk_blob_close(snapshot, blob_op_complete, NULL); 3803 CU_ASSERT(g_bserrno == 0); 3804 3805 spdk_bs_free_io_channel(channel); 3806 3807 /* Unload the blob store */ 3808 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3809 CU_ASSERT(g_bserrno == 0); 3810 g_bs = NULL; 3811 g_blob = NULL; 3812 g_blobid = 0; 3813 } 3814 3815 static void 3816 blob_inflate_rw(void) 3817 { 3818 static uint8_t *zero; 3819 struct spdk_blob_store *bs; 3820 struct spdk_bs_dev *dev; 3821 struct spdk_blob *blob, *snapshot; 3822 struct spdk_io_channel *channel; 3823 struct spdk_blob_opts opts; 3824 spdk_blob_id blobid, snapshotid; 3825 uint64_t free_clusters; 3826 uint64_t cluster_size; 3827 3828 uint64_t payload_size; 3829 uint8_t *payload_read; 3830 uint8_t *payload_write; 3831 uint8_t *payload_clone; 3832 3833 uint64_t pages_per_cluster; 3834 uint64_t pages_per_payload; 3835 3836 int i; 3837 3838 dev = init_dev(); 3839 3840 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3841 CU_ASSERT(g_bserrno == 0); 3842 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3843 bs = g_bs; 3844 3845 free_clusters = spdk_bs_free_cluster_count(bs); 3846 cluster_size = spdk_bs_get_cluster_size(bs); 3847 pages_per_cluster = cluster_size / spdk_bs_get_page_size(bs); 3848 pages_per_payload = pages_per_cluster * 5; 3849 3850 payload_size = cluster_size * 5; 3851 3852 payload_read = malloc(payload_size); 3853 SPDK_CU_ASSERT_FATAL(payload_read != NULL); 3854 3855 payload_write = malloc(payload_size); 3856 SPDK_CU_ASSERT_FATAL(payload_write != NULL); 3857 3858 payload_clone = malloc(payload_size); 3859 SPDK_CU_ASSERT_FATAL(payload_clone != NULL); 3860 3861 zero = calloc(1, payload_size); 3862 SPDK_CU_ASSERT_FATAL(zero != NULL); 3863 3864 channel = spdk_bs_alloc_io_channel(bs); 3865 SPDK_CU_ASSERT_FATAL(channel != NULL); 3866 3867 /* Create blob */ 3868 spdk_blob_opts_init(&opts); 3869 opts.thin_provision = true; 3870 opts.num_clusters = 5; 3871 3872 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 3873 CU_ASSERT(g_bserrno == 0); 3874 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3875 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3876 blobid = g_blobid; 3877 3878 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3879 CU_ASSERT(g_bserrno == 0); 3880 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3881 blob = g_blob; 3882 3883 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 3884 3885 /* Initial read should return zeroed payload */ 3886 memset(payload_read, 0xFF, payload_size); 3887 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, blob_op_complete, NULL); 3888 CU_ASSERT(g_bserrno == 0); 3889 CU_ASSERT(memcmp(zero, payload_read, payload_size) == 0); 3890 3891 /* Fill whole blob with a pattern */ 3892 memset(payload_write, 0xE5, payload_size); 3893 spdk_blob_io_write(blob, channel, payload_write, 0, pages_per_payload, 3894 blob_op_complete, NULL); 3895 CU_ASSERT(g_bserrno == 0); 3896 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 3897 3898 /* Create snapshot from blob */ 3899 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 3900 CU_ASSERT(g_bserrno == 0); 3901 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3902 snapshotid = g_blobid; 3903 3904 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 3905 CU_ASSERT(g_bserrno == 0); 3906 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3907 snapshot = g_blob; 3908 CU_ASSERT(snapshot->data_ro == true) 3909 CU_ASSERT(snapshot->md_ro == true) 3910 3911 CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 5) 3912 3913 /* Write every second cluster with a pattern. 3914 * 3915 * payload_clone stores expected result on "blob" read at the time and 3916 * is used only to check data consistency on clone before and after 3917 * inflation. Initially we fill it with a backing snapshots pattern 3918 * used before. 3919 */ 3920 memset(payload_clone, 0xE5, payload_size); 3921 memset(payload_write, 0xAA, payload_size); 3922 for (i = 1; i < 5; i += 2) { 3923 spdk_blob_io_write(blob, channel, payload_write, i * pages_per_cluster, 3924 pages_per_cluster, blob_op_complete, NULL); 3925 CU_ASSERT(g_bserrno == 0); 3926 3927 /* Update expected result */ 3928 memcpy(payload_clone + (cluster_size * i), payload_write, 3929 cluster_size); 3930 } 3931 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 3932 3933 /* Check data consistency on clone */ 3934 memset(payload_read, 0xFF, payload_size); 3935 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, 3936 blob_op_complete, NULL); 3937 CU_ASSERT(g_bserrno == 0); 3938 CU_ASSERT(memcmp(payload_clone, payload_read, payload_size) == 0); 3939 3940 /* Close all blobs */ 3941 spdk_blob_close(blob, blob_op_complete, NULL); 3942 CU_ASSERT(g_bserrno == 0); 3943 3944 spdk_blob_close(snapshot, blob_op_complete, NULL); 3945 CU_ASSERT(g_bserrno == 0); 3946 3947 /* Inflate blob */ 3948 spdk_bs_inflate_blob(bs, channel, blobid, blob_op_complete, NULL); 3949 CU_ASSERT(g_bserrno == 0); 3950 3951 /* Try to delete snapshot (should pass) */ 3952 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 3953 CU_ASSERT(g_bserrno == 0); 3954 3955 /* Reopen blob after snapshot deletion */ 3956 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3957 CU_ASSERT(g_bserrno == 0); 3958 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3959 blob = g_blob; 3960 3961 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 3962 3963 /* Check data consistency on inflated blob */ 3964 memset(payload_read, 0xFF, payload_size); 3965 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, blob_op_complete, NULL); 3966 CU_ASSERT(g_bserrno == 0); 3967 CU_ASSERT(memcmp(payload_clone, payload_read, payload_size) == 0); 3968 3969 spdk_blob_close(blob, blob_op_complete, NULL); 3970 CU_ASSERT(g_bserrno == 0); 3971 3972 spdk_bs_free_io_channel(channel); 3973 3974 /* Unload the blob store */ 3975 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3976 CU_ASSERT(g_bserrno == 0); 3977 g_bs = NULL; 3978 g_blob = NULL; 3979 g_blobid = 0; 3980 3981 free(payload_read); 3982 free(payload_write); 3983 free(payload_clone); 3984 free(zero); 3985 } 3986 3987 /** 3988 * Snapshot-clones relation test 3989 * 3990 * snapshot 3991 * | 3992 * +----+----+ 3993 * | | 3994 * blob clone 3995 * | 3996 * clone2 3997 */ 3998 static void 3999 blob_relations(void) 4000 { 4001 struct spdk_blob_store *bs; 4002 struct spdk_bs_dev *dev; 4003 struct spdk_bs_opts bs_opts; 4004 struct spdk_blob_opts opts; 4005 struct spdk_blob *blob, *snapshot, *clone, *clone2; 4006 spdk_blob_id blobid, cloneid, snapshotid, cloneid2; 4007 int rc; 4008 size_t count; 4009 spdk_blob_id ids[10]; 4010 4011 dev = init_dev(); 4012 spdk_bs_opts_init(&bs_opts); 4013 snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE"); 4014 4015 spdk_bs_init(dev, &bs_opts, bs_op_with_handle_complete, NULL); 4016 CU_ASSERT(g_bserrno == 0); 4017 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4018 bs = g_bs; 4019 4020 /* 1. Create blob with 10 clusters */ 4021 4022 spdk_blob_opts_init(&opts); 4023 opts.num_clusters = 10; 4024 4025 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 4026 CU_ASSERT(g_bserrno == 0); 4027 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4028 blobid = g_blobid; 4029 4030 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4031 CU_ASSERT(g_bserrno == 0); 4032 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4033 blob = g_blob; 4034 4035 CU_ASSERT(!spdk_blob_is_read_only(blob)); 4036 CU_ASSERT(!spdk_blob_is_snapshot(blob)); 4037 CU_ASSERT(!spdk_blob_is_clone(blob)); 4038 CU_ASSERT(!spdk_blob_is_thin_provisioned(blob)); 4039 4040 /* blob should not have underlying snapshot nor clones */ 4041 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == SPDK_BLOBID_INVALID); 4042 count = SPDK_COUNTOF(ids); 4043 rc = spdk_blob_get_clones(bs, blobid, ids, &count); 4044 CU_ASSERT(rc == 0); 4045 CU_ASSERT(count == 0); 4046 4047 4048 /* 2. Create snapshot */ 4049 4050 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 4051 CU_ASSERT(g_bserrno == 0); 4052 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4053 snapshotid = g_blobid; 4054 4055 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 4056 CU_ASSERT(g_bserrno == 0); 4057 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4058 snapshot = g_blob; 4059 4060 CU_ASSERT(spdk_blob_is_read_only(snapshot)); 4061 CU_ASSERT(spdk_blob_is_snapshot(snapshot)); 4062 CU_ASSERT(!spdk_blob_is_clone(snapshot)); 4063 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid) == SPDK_BLOBID_INVALID); 4064 4065 /* Check if original blob is converted to the clone of snapshot */ 4066 CU_ASSERT(!spdk_blob_is_read_only(blob)); 4067 CU_ASSERT(!spdk_blob_is_snapshot(blob)); 4068 CU_ASSERT(spdk_blob_is_clone(blob)); 4069 CU_ASSERT(spdk_blob_is_thin_provisioned(blob)); 4070 4071 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid); 4072 4073 count = SPDK_COUNTOF(ids); 4074 rc = spdk_blob_get_clones(bs, snapshotid, ids, &count); 4075 CU_ASSERT(rc == 0); 4076 CU_ASSERT(count == 1); 4077 CU_ASSERT(ids[0] == blobid); 4078 4079 4080 /* 3. Create clone from snapshot */ 4081 4082 spdk_bs_create_clone(bs, snapshotid, NULL, blob_op_with_id_complete, NULL); 4083 CU_ASSERT(g_bserrno == 0); 4084 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4085 cloneid = g_blobid; 4086 4087 spdk_bs_open_blob(bs, cloneid, blob_op_with_handle_complete, NULL); 4088 CU_ASSERT(g_bserrno == 0); 4089 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4090 clone = g_blob; 4091 4092 CU_ASSERT(!spdk_blob_is_read_only(clone)); 4093 CU_ASSERT(!spdk_blob_is_snapshot(clone)); 4094 CU_ASSERT(spdk_blob_is_clone(clone)); 4095 CU_ASSERT(spdk_blob_is_thin_provisioned(clone)); 4096 4097 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid); 4098 4099 count = SPDK_COUNTOF(ids); 4100 rc = spdk_blob_get_clones(bs, cloneid, ids, &count); 4101 CU_ASSERT(rc == 0); 4102 CU_ASSERT(count == 0); 4103 4104 /* Check if clone is on the snapshot's list */ 4105 count = SPDK_COUNTOF(ids); 4106 rc = spdk_blob_get_clones(bs, snapshotid, ids, &count); 4107 CU_ASSERT(rc == 0); 4108 CU_ASSERT(ids[0] == blobid || ids[1] == blobid); 4109 CU_ASSERT(ids[0] == cloneid || ids[1] == cloneid); 4110 4111 4112 /* 4. Try to create clone from read only blob */ 4113 4114 /* Mark blob as read only */ 4115 spdk_blob_set_read_only(blob); 4116 spdk_blob_sync_md(blob, blob_op_complete, NULL); 4117 CU_ASSERT(g_bserrno == 0); 4118 4119 /* Check if previously created blob is read only clone */ 4120 CU_ASSERT(spdk_blob_is_read_only(blob)); 4121 CU_ASSERT(!spdk_blob_is_snapshot(blob)); 4122 CU_ASSERT(spdk_blob_is_clone(blob)); 4123 CU_ASSERT(spdk_blob_is_thin_provisioned(blob)); 4124 4125 /* Create clone from read only blob */ 4126 spdk_bs_create_clone(bs, blobid, NULL, blob_op_with_id_complete, NULL); 4127 CU_ASSERT(g_bserrno == 0); 4128 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4129 cloneid2 = g_blobid; 4130 4131 spdk_bs_open_blob(bs, cloneid2, blob_op_with_handle_complete, NULL); 4132 CU_ASSERT(g_bserrno == 0); 4133 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4134 clone2 = g_blob; 4135 4136 CU_ASSERT(!spdk_blob_is_read_only(clone2)); 4137 CU_ASSERT(!spdk_blob_is_snapshot(clone2)); 4138 CU_ASSERT(spdk_blob_is_clone(clone2)); 4139 CU_ASSERT(spdk_blob_is_thin_provisioned(clone2)); 4140 4141 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid2) == blobid); 4142 4143 count = SPDK_COUNTOF(ids); 4144 rc = spdk_blob_get_clones(bs, blobid, ids, &count); 4145 CU_ASSERT(rc == 0); 4146 4147 CU_ASSERT(count == 1); 4148 CU_ASSERT(ids[0] == cloneid2); 4149 4150 /* Close blobs */ 4151 4152 spdk_blob_close(clone2, blob_op_complete, NULL); 4153 CU_ASSERT(g_bserrno == 0); 4154 4155 spdk_blob_close(blob, blob_op_complete, NULL); 4156 CU_ASSERT(g_bserrno == 0); 4157 4158 spdk_blob_close(clone, blob_op_complete, NULL); 4159 CU_ASSERT(g_bserrno == 0); 4160 4161 spdk_blob_close(snapshot, blob_op_complete, NULL); 4162 CU_ASSERT(g_bserrno == 0); 4163 4164 /* Try to delete snapshot with created clones */ 4165 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 4166 CU_ASSERT(g_bserrno != 0); 4167 4168 spdk_bs_unload(bs, bs_op_complete, NULL); 4169 CU_ASSERT(g_bserrno == 0); 4170 g_bs = NULL; 4171 4172 /* Load an existing blob store */ 4173 dev = init_dev(); 4174 snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE"); 4175 4176 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 4177 CU_ASSERT(g_bserrno == 0); 4178 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4179 bs = g_bs; 4180 4181 4182 /* NULL ids array should return number of clones in count */ 4183 count = SPDK_COUNTOF(ids); 4184 rc = spdk_blob_get_clones(bs, snapshotid, NULL, &count); 4185 CU_ASSERT(rc == -ENOMEM); 4186 CU_ASSERT(count == 2); 4187 4188 /* incorrect array size */ 4189 count = 1; 4190 rc = spdk_blob_get_clones(bs, snapshotid, ids, &count); 4191 CU_ASSERT(rc == -ENOMEM); 4192 CU_ASSERT(count == 2); 4193 4194 4195 /* Verify structure of loaded blob store */ 4196 4197 /* snapshot */ 4198 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid) == SPDK_BLOBID_INVALID); 4199 4200 count = SPDK_COUNTOF(ids); 4201 rc = spdk_blob_get_clones(bs, snapshotid, ids, &count); 4202 CU_ASSERT(rc == 0); 4203 CU_ASSERT(count == 2); 4204 CU_ASSERT(ids[0] == blobid || ids[1] == blobid); 4205 CU_ASSERT(ids[0] == cloneid || ids[1] == cloneid); 4206 4207 /* blob */ 4208 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid); 4209 count = SPDK_COUNTOF(ids); 4210 rc = spdk_blob_get_clones(bs, blobid, ids, &count); 4211 CU_ASSERT(rc == 0); 4212 CU_ASSERT(count == 1); 4213 CU_ASSERT(ids[0] == cloneid2); 4214 4215 /* clone */ 4216 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid); 4217 count = SPDK_COUNTOF(ids); 4218 rc = spdk_blob_get_clones(bs, cloneid, ids, &count); 4219 CU_ASSERT(rc == 0); 4220 CU_ASSERT(count == 0); 4221 4222 /* clone2 */ 4223 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid2) == blobid); 4224 count = SPDK_COUNTOF(ids); 4225 rc = spdk_blob_get_clones(bs, cloneid2, ids, &count); 4226 CU_ASSERT(rc == 0); 4227 CU_ASSERT(count == 0); 4228 4229 /* Try to delete all blobs */ 4230 spdk_bs_delete_blob(bs, cloneid, blob_op_complete, NULL); 4231 CU_ASSERT(g_bserrno == 0); 4232 4233 /* Try to delete snapshot with clones */ 4234 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 4235 CU_ASSERT(g_bserrno != 0); 4236 4237 /* Try to delete ro blob with clones */ 4238 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 4239 CU_ASSERT(g_bserrno != 0); 4240 4241 spdk_bs_delete_blob(bs, cloneid2, blob_op_complete, NULL); 4242 CU_ASSERT(g_bserrno == 0); 4243 4244 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 4245 CU_ASSERT(g_bserrno == 0); 4246 4247 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 4248 CU_ASSERT(g_bserrno == 0); 4249 4250 spdk_bs_unload(bs, bs_op_complete, NULL); 4251 CU_ASSERT(g_bserrno == 0); 4252 4253 g_bs = NULL; 4254 } 4255 4256 int main(int argc, char **argv) 4257 { 4258 CU_pSuite suite = NULL; 4259 unsigned int num_failures; 4260 4261 if (CU_initialize_registry() != CUE_SUCCESS) { 4262 return CU_get_error(); 4263 } 4264 4265 suite = CU_add_suite("blob", NULL, NULL); 4266 if (suite == NULL) { 4267 CU_cleanup_registry(); 4268 return CU_get_error(); 4269 } 4270 4271 if ( 4272 CU_add_test(suite, "blob_init", blob_init) == NULL || 4273 CU_add_test(suite, "blob_open", blob_open) == NULL || 4274 CU_add_test(suite, "blob_create", blob_create) == NULL || 4275 CU_add_test(suite, "blob_create_internal", blob_create_internal) == NULL || 4276 CU_add_test(suite, "blob_thin_provision", blob_thin_provision) == NULL || 4277 CU_add_test(suite, "blob_snapshot", blob_snapshot) == NULL || 4278 CU_add_test(suite, "blob_clone", blob_clone) == NULL || 4279 CU_add_test(suite, "blob_inflate", blob_inflate) == NULL || 4280 CU_add_test(suite, "blob_delete", blob_delete) == NULL || 4281 CU_add_test(suite, "blob_resize", blob_resize) == NULL || 4282 CU_add_test(suite, "blob_read_only", blob_read_only) == NULL || 4283 CU_add_test(suite, "channel_ops", channel_ops) == NULL || 4284 CU_add_test(suite, "blob_super", blob_super) == NULL || 4285 CU_add_test(suite, "blob_write", blob_write) == NULL || 4286 CU_add_test(suite, "blob_read", blob_read) == NULL || 4287 CU_add_test(suite, "blob_rw_verify", blob_rw_verify) == NULL || 4288 CU_add_test(suite, "blob_rw_verify_iov", blob_rw_verify_iov) == NULL || 4289 CU_add_test(suite, "blob_rw_verify_iov_nomem", blob_rw_verify_iov_nomem) == NULL || 4290 CU_add_test(suite, "blob_rw_iov_read_only", blob_rw_iov_read_only) == NULL || 4291 CU_add_test(suite, "blob_unmap", blob_unmap) == NULL || 4292 CU_add_test(suite, "blob_iter", blob_iter) == NULL || 4293 CU_add_test(suite, "blob_xattr", blob_xattr) == NULL || 4294 CU_add_test(suite, "bs_load", bs_load) == NULL || 4295 CU_add_test(suite, "bs_unload", bs_unload) == NULL || 4296 CU_add_test(suite, "bs_cluster_sz", bs_cluster_sz) == NULL || 4297 CU_add_test(suite, "bs_usable_clusters", bs_usable_clusters) == NULL || 4298 CU_add_test(suite, "bs_resize_md", bs_resize_md) == NULL || 4299 CU_add_test(suite, "bs_destroy", bs_destroy) == NULL || 4300 CU_add_test(suite, "bs_type", bs_type) == NULL || 4301 CU_add_test(suite, "bs_super_block", bs_super_block) == NULL || 4302 CU_add_test(suite, "blob_serialize", blob_serialize) == NULL || 4303 CU_add_test(suite, "blob_crc", blob_crc) == NULL || 4304 CU_add_test(suite, "super_block_crc", super_block_crc) == NULL || 4305 CU_add_test(suite, "blob_dirty_shutdown", blob_dirty_shutdown) == NULL || 4306 CU_add_test(suite, "blob_flags", blob_flags) == NULL || 4307 CU_add_test(suite, "bs_version", bs_version) == NULL || 4308 CU_add_test(suite, "blob_set_xattrs", blob_set_xattrs) == NULL || 4309 CU_add_test(suite, "blob_thin_prov_alloc", blob_thin_prov_alloc) == NULL || 4310 CU_add_test(suite, "blob_insert_cluster_msg", blob_insert_cluster_msg) == NULL || 4311 CU_add_test(suite, "blob_thin_prov_rw", blob_thin_prov_rw) == NULL || 4312 CU_add_test(suite, "blob_thin_prov_rw_iov", blob_thin_prov_rw_iov) == NULL || 4313 CU_add_test(suite, "bs_load_iter", bs_load_iter) == NULL || 4314 CU_add_test(suite, "blob_snapshot_rw", blob_snapshot_rw) == NULL || 4315 CU_add_test(suite, "blob_snapshot_rw_iov", blob_snapshot_rw_iov) == NULL || 4316 CU_add_test(suite, "blob_inflate_rw", blob_inflate_rw) == NULL || 4317 CU_add_test(suite, "blob_relations", blob_relations) == NULL 4318 ) { 4319 CU_cleanup_registry(); 4320 return CU_get_error(); 4321 } 4322 4323 g_dev_buffer = calloc(1, DEV_BUFFER_SIZE); 4324 spdk_allocate_thread(_bs_send_msg, NULL, NULL, NULL, "thread0"); 4325 CU_basic_set_mode(CU_BRM_VERBOSE); 4326 CU_basic_run_tests(); 4327 num_failures = CU_get_number_of_failures(); 4328 CU_cleanup_registry(); 4329 spdk_free_thread(); 4330 free(g_dev_buffer); 4331 return num_failures; 4332 } 4333