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