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