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, 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_CLEAR(calloc); 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_io_read_no_split(struct spdk_blob *blob, struct spdk_io_channel *channel, 1618 uint8_t *payload, uint64_t offset, uint64_t length, 1619 spdk_blob_op_complete cb_fn, void *cb_arg) 1620 { 1621 uint64_t i; 1622 uint8_t *buf; 1623 uint64_t page_size = spdk_bs_get_page_size(blob->bs); 1624 1625 /* To be sure that operation is NOT splitted, read one page at the time */ 1626 buf = payload; 1627 for (i = 0; i < length; i++) { 1628 spdk_blob_io_read(blob, channel, buf, i + offset, 1, blob_op_complete, NULL); 1629 if (g_bserrno != 0) { 1630 /* Pass the error code up */ 1631 break; 1632 } 1633 buf += page_size; 1634 } 1635 1636 cb_fn(cb_arg, g_bserrno); 1637 } 1638 1639 static void 1640 _blob_io_write_no_split(struct spdk_blob *blob, struct spdk_io_channel *channel, 1641 uint8_t *payload, uint64_t offset, uint64_t length, 1642 spdk_blob_op_complete cb_fn, void *cb_arg) 1643 { 1644 uint64_t i; 1645 uint8_t *buf; 1646 uint64_t page_size = spdk_bs_get_page_size(blob->bs); 1647 1648 /* To be sure that operation is NOT splitted, write one page at the time */ 1649 buf = payload; 1650 for (i = 0; i < length; i++) { 1651 spdk_blob_io_write(blob, channel, buf, i + offset, 1, blob_op_complete, NULL); 1652 if (g_bserrno != 0) { 1653 /* Pass the error code up */ 1654 break; 1655 } 1656 buf += page_size; 1657 } 1658 1659 cb_fn(cb_arg, g_bserrno); 1660 } 1661 1662 static void 1663 blob_operation_split_rw(void) 1664 { 1665 struct spdk_blob_store *bs; 1666 struct spdk_bs_dev *dev; 1667 struct spdk_blob *blob; 1668 struct spdk_io_channel *channel; 1669 struct spdk_blob_opts opts; 1670 spdk_blob_id blobid; 1671 uint64_t cluster_size; 1672 1673 uint64_t payload_size; 1674 uint8_t *payload_read; 1675 uint8_t *payload_write; 1676 uint8_t *payload_pattern; 1677 1678 uint64_t page_size; 1679 uint64_t pages_per_cluster; 1680 uint64_t pages_per_payload; 1681 1682 uint64_t i; 1683 1684 dev = init_dev(); 1685 1686 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1687 CU_ASSERT(g_bserrno == 0); 1688 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1689 bs = g_bs; 1690 1691 cluster_size = spdk_bs_get_cluster_size(bs); 1692 page_size = spdk_bs_get_page_size(bs); 1693 pages_per_cluster = cluster_size / page_size; 1694 pages_per_payload = pages_per_cluster * 5; 1695 payload_size = cluster_size * 5; 1696 1697 payload_read = malloc(payload_size); 1698 SPDK_CU_ASSERT_FATAL(payload_read != NULL); 1699 1700 payload_write = malloc(payload_size); 1701 SPDK_CU_ASSERT_FATAL(payload_write != NULL); 1702 1703 payload_pattern = malloc(payload_size); 1704 SPDK_CU_ASSERT_FATAL(payload_pattern != NULL); 1705 1706 /* Prepare random pattern to write */ 1707 memset(payload_pattern, 0xFF, payload_size); 1708 for (i = 0; i < pages_per_payload; i++) { 1709 *((uint64_t *)(payload_pattern + page_size * i)) = (i + 1); 1710 } 1711 1712 channel = spdk_bs_alloc_io_channel(bs); 1713 SPDK_CU_ASSERT_FATAL(channel != NULL); 1714 1715 /* Create blob */ 1716 spdk_blob_opts_init(&opts); 1717 opts.thin_provision = false; 1718 opts.num_clusters = 5; 1719 1720 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 1721 CU_ASSERT(g_bserrno == 0); 1722 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1723 blobid = g_blobid; 1724 1725 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1726 CU_ASSERT(g_bserrno == 0); 1727 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1728 blob = g_blob; 1729 1730 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 1731 1732 /* Initial read should return zeroed payload */ 1733 memset(payload_read, 0xFF, payload_size); 1734 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, blob_op_complete, NULL); 1735 CU_ASSERT(g_bserrno == 0); 1736 CU_ASSERT(spdk_mem_all_zero(payload_read, payload_size)); 1737 1738 /* Fill whole blob except last page */ 1739 spdk_blob_io_write(blob, channel, payload_pattern, 0, pages_per_payload - 1, 1740 blob_op_complete, NULL); 1741 CU_ASSERT(g_bserrno == 0); 1742 1743 /* Write last page with a pattern */ 1744 spdk_blob_io_write(blob, channel, payload_pattern, pages_per_payload - 1, 1, 1745 blob_op_complete, NULL); 1746 CU_ASSERT(g_bserrno == 0); 1747 1748 /* Read whole blob and check consistency */ 1749 memset(payload_read, 0xFF, payload_size); 1750 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, blob_op_complete, NULL); 1751 CU_ASSERT(g_bserrno == 0); 1752 CU_ASSERT(memcmp(payload_pattern, payload_read, payload_size - page_size) == 0); 1753 CU_ASSERT(memcmp(payload_pattern, payload_read + payload_size - page_size, page_size) == 0); 1754 1755 /* Fill whole blob except first page */ 1756 spdk_blob_io_write(blob, channel, payload_pattern, 1, pages_per_payload - 1, 1757 blob_op_complete, NULL); 1758 CU_ASSERT(g_bserrno == 0); 1759 1760 /* Write first page with a pattern */ 1761 spdk_blob_io_write(blob, channel, payload_pattern, 0, 1, 1762 blob_op_complete, NULL); 1763 CU_ASSERT(g_bserrno == 0); 1764 1765 /* Read whole blob and check consistency */ 1766 memset(payload_read, 0xFF, payload_size); 1767 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, blob_op_complete, NULL); 1768 CU_ASSERT(g_bserrno == 0); 1769 CU_ASSERT(memcmp(payload_pattern, payload_read + page_size, payload_size - page_size) == 0); 1770 CU_ASSERT(memcmp(payload_pattern, payload_read, page_size) == 0); 1771 1772 1773 /* Fill whole blob with a pattern (5 clusters) */ 1774 1775 /* 1. Read test. */ 1776 _blob_io_write_no_split(blob, channel, payload_pattern, 0, pages_per_payload, 1777 blob_op_complete, NULL); 1778 CU_ASSERT(g_bserrno == 0); 1779 1780 memset(payload_read, 0xFF, payload_size); 1781 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, blob_op_complete, NULL); 1782 CU_ASSERT(g_bserrno == 0); 1783 CU_ASSERT(memcmp(payload_pattern, payload_read, payload_size) == 0); 1784 1785 /* 2. Write test. */ 1786 spdk_blob_io_write(blob, channel, payload_pattern, 0, pages_per_payload, 1787 blob_op_complete, NULL); 1788 CU_ASSERT(g_bserrno == 0); 1789 1790 memset(payload_read, 0xFF, payload_size); 1791 _blob_io_read_no_split(blob, channel, payload_read, 0, pages_per_payload, blob_op_complete, NULL); 1792 CU_ASSERT(g_bserrno == 0); 1793 CU_ASSERT(memcmp(payload_pattern, payload_read, payload_size) == 0); 1794 1795 spdk_blob_close(blob, blob_op_complete, NULL); 1796 CU_ASSERT(g_bserrno == 0); 1797 1798 spdk_bs_free_io_channel(channel); 1799 1800 /* Unload the blob store */ 1801 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1802 CU_ASSERT(g_bserrno == 0); 1803 g_bs = NULL; 1804 g_blob = NULL; 1805 g_blobid = 0; 1806 1807 free(payload_read); 1808 free(payload_write); 1809 free(payload_pattern); 1810 } 1811 1812 static void 1813 blob_operation_split_rw_iov(void) 1814 { 1815 struct spdk_blob_store *bs; 1816 struct spdk_bs_dev *dev; 1817 struct spdk_blob *blob; 1818 struct spdk_io_channel *channel; 1819 struct spdk_blob_opts opts; 1820 spdk_blob_id blobid; 1821 uint64_t cluster_size; 1822 1823 uint64_t payload_size; 1824 uint8_t *payload_read; 1825 uint8_t *payload_write; 1826 uint8_t *payload_pattern; 1827 1828 uint64_t page_size; 1829 uint64_t pages_per_cluster; 1830 uint64_t pages_per_payload; 1831 1832 struct iovec iov_read[2]; 1833 struct iovec iov_write[2]; 1834 1835 uint64_t i, j; 1836 1837 dev = init_dev(); 1838 1839 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1840 CU_ASSERT(g_bserrno == 0); 1841 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1842 bs = g_bs; 1843 1844 cluster_size = spdk_bs_get_cluster_size(bs); 1845 page_size = spdk_bs_get_page_size(bs); 1846 pages_per_cluster = cluster_size / page_size; 1847 pages_per_payload = pages_per_cluster * 5; 1848 payload_size = cluster_size * 5; 1849 1850 payload_read = malloc(payload_size); 1851 SPDK_CU_ASSERT_FATAL(payload_read != NULL); 1852 1853 payload_write = malloc(payload_size); 1854 SPDK_CU_ASSERT_FATAL(payload_write != NULL); 1855 1856 payload_pattern = malloc(payload_size); 1857 SPDK_CU_ASSERT_FATAL(payload_pattern != NULL); 1858 1859 /* Prepare random pattern to write */ 1860 for (i = 0; i < pages_per_payload; i++) { 1861 for (j = 0; j < page_size / sizeof(uint64_t); j++) { 1862 uint64_t *tmp; 1863 1864 tmp = (uint64_t *)payload_pattern; 1865 tmp += ((page_size * i) / sizeof(uint64_t)) + j; 1866 *tmp = i + 1; 1867 } 1868 } 1869 1870 channel = spdk_bs_alloc_io_channel(bs); 1871 SPDK_CU_ASSERT_FATAL(channel != NULL); 1872 1873 /* Create blob */ 1874 spdk_blob_opts_init(&opts); 1875 opts.thin_provision = false; 1876 opts.num_clusters = 5; 1877 1878 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 1879 CU_ASSERT(g_bserrno == 0); 1880 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1881 blobid = g_blobid; 1882 1883 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1884 CU_ASSERT(g_bserrno == 0); 1885 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1886 blob = g_blob; 1887 1888 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 1889 1890 /* Initial read should return zeroes payload */ 1891 memset(payload_read, 0xFF, payload_size); 1892 iov_read[0].iov_base = payload_read; 1893 iov_read[0].iov_len = cluster_size * 3; 1894 iov_read[1].iov_base = payload_read + cluster_size * 3; 1895 iov_read[1].iov_len = cluster_size * 2; 1896 spdk_blob_io_readv(blob, channel, iov_read, 2, 0, pages_per_payload, blob_op_complete, NULL); 1897 CU_ASSERT(g_bserrno == 0); 1898 CU_ASSERT(spdk_mem_all_zero(payload_read, payload_size)); 1899 1900 /* First of iovs fills whole blob except last page and second of iovs writes last page 1901 * with a pattern. */ 1902 iov_write[0].iov_base = payload_pattern; 1903 iov_write[0].iov_len = payload_size - page_size; 1904 iov_write[1].iov_base = payload_pattern; 1905 iov_write[1].iov_len = page_size; 1906 spdk_blob_io_writev(blob, channel, iov_write, 2, 0, pages_per_payload, blob_op_complete, NULL); 1907 CU_ASSERT(g_bserrno == 0); 1908 1909 /* Read whole blob and check consistency */ 1910 memset(payload_read, 0xFF, payload_size); 1911 iov_read[0].iov_base = payload_read; 1912 iov_read[0].iov_len = cluster_size * 2; 1913 iov_read[1].iov_base = payload_read + cluster_size * 2; 1914 iov_read[1].iov_len = cluster_size * 3; 1915 spdk_blob_io_readv(blob, channel, iov_read, 2, 0, pages_per_payload, blob_op_complete, NULL); 1916 CU_ASSERT(g_bserrno == 0); 1917 CU_ASSERT(memcmp(payload_pattern, payload_read, payload_size - page_size) == 0); 1918 CU_ASSERT(memcmp(payload_pattern, payload_read + payload_size - page_size, page_size) == 0); 1919 1920 /* First of iovs fills only first page and second of iovs writes whole blob except 1921 * first page with a pattern. */ 1922 iov_write[0].iov_base = payload_pattern; 1923 iov_write[0].iov_len = page_size; 1924 iov_write[1].iov_base = payload_pattern; 1925 iov_write[1].iov_len = payload_size - page_size; 1926 spdk_blob_io_writev(blob, channel, iov_write, 2, 0, pages_per_payload, blob_op_complete, NULL); 1927 CU_ASSERT(g_bserrno == 0); 1928 1929 /* Read whole blob and check consistency */ 1930 memset(payload_read, 0xFF, payload_size); 1931 iov_read[0].iov_base = payload_read; 1932 iov_read[0].iov_len = cluster_size * 4; 1933 iov_read[1].iov_base = payload_read + cluster_size * 4; 1934 iov_read[1].iov_len = cluster_size; 1935 spdk_blob_io_readv(blob, channel, iov_read, 2, 0, pages_per_payload, blob_op_complete, NULL); 1936 CU_ASSERT(g_bserrno == 0); 1937 CU_ASSERT(memcmp(payload_pattern, payload_read + page_size, payload_size - page_size) == 0); 1938 CU_ASSERT(memcmp(payload_pattern, payload_read, page_size) == 0); 1939 1940 1941 /* Fill whole blob with a pattern (5 clusters) */ 1942 1943 /* 1. Read test. */ 1944 _blob_io_write_no_split(blob, channel, payload_pattern, 0, pages_per_payload, 1945 blob_op_complete, NULL); 1946 CU_ASSERT(g_bserrno == 0); 1947 1948 memset(payload_read, 0xFF, payload_size); 1949 iov_read[0].iov_base = payload_read; 1950 iov_read[0].iov_len = cluster_size; 1951 iov_read[1].iov_base = payload_read + cluster_size; 1952 iov_read[1].iov_len = cluster_size * 4; 1953 spdk_blob_io_readv(blob, channel, iov_read, 2, 0, pages_per_payload, blob_op_complete, NULL); 1954 CU_ASSERT(g_bserrno == 0); 1955 CU_ASSERT(memcmp(payload_pattern, payload_read, payload_size) == 0); 1956 1957 /* 2. Write test. */ 1958 iov_write[0].iov_base = payload_read; 1959 iov_write[0].iov_len = cluster_size * 2; 1960 iov_write[1].iov_base = payload_read + cluster_size * 2; 1961 iov_write[1].iov_len = cluster_size * 3; 1962 spdk_blob_io_writev(blob, channel, iov_write, 2, 0, pages_per_payload, blob_op_complete, NULL); 1963 CU_ASSERT(g_bserrno == 0); 1964 1965 memset(payload_read, 0xFF, payload_size); 1966 _blob_io_read_no_split(blob, channel, payload_read, 0, pages_per_payload, blob_op_complete, NULL); 1967 CU_ASSERT(g_bserrno == 0); 1968 CU_ASSERT(memcmp(payload_pattern, payload_read, payload_size) == 0); 1969 1970 spdk_blob_close(blob, blob_op_complete, NULL); 1971 CU_ASSERT(g_bserrno == 0); 1972 1973 spdk_bs_free_io_channel(channel); 1974 1975 /* Unload the blob store */ 1976 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1977 CU_ASSERT(g_bserrno == 0); 1978 g_bs = NULL; 1979 g_blob = NULL; 1980 g_blobid = 0; 1981 1982 free(payload_read); 1983 free(payload_write); 1984 free(payload_pattern); 1985 } 1986 1987 static void 1988 blob_unmap(void) 1989 { 1990 struct spdk_blob_store *bs; 1991 struct spdk_bs_dev *dev; 1992 struct spdk_blob *blob; 1993 struct spdk_io_channel *channel; 1994 spdk_blob_id blobid; 1995 struct spdk_blob_opts opts; 1996 uint8_t payload[4096]; 1997 int i; 1998 1999 dev = init_dev(); 2000 2001 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2002 CU_ASSERT(g_bserrno == 0); 2003 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2004 bs = g_bs; 2005 2006 channel = spdk_bs_alloc_io_channel(bs); 2007 CU_ASSERT(channel != NULL); 2008 2009 spdk_blob_opts_init(&opts); 2010 opts.num_clusters = 10; 2011 2012 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 2013 CU_ASSERT(g_bserrno == 0); 2014 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2015 blobid = g_blobid; 2016 2017 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2018 CU_ASSERT(g_bserrno == 0); 2019 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2020 blob = g_blob; 2021 2022 spdk_blob_resize(blob, 10, blob_op_complete, NULL); 2023 CU_ASSERT(g_bserrno == 0); 2024 2025 memset(payload, 0, sizeof(payload)); 2026 payload[0] = 0xFF; 2027 2028 /* 2029 * Set first byte of every cluster to 0xFF. 2030 * First cluster on device is reserved so let's start from cluster number 1 2031 */ 2032 for (i = 1; i < 11; i++) { 2033 g_dev_buffer[i * SPDK_BLOB_OPTS_CLUSTER_SZ] = 0xFF; 2034 } 2035 2036 /* Confirm writes */ 2037 for (i = 0; i < 10; i++) { 2038 payload[0] = 0; 2039 spdk_blob_io_read(blob, channel, &payload, i * SPDK_BLOB_OPTS_CLUSTER_SZ / 4096, 1, 2040 blob_op_complete, NULL); 2041 CU_ASSERT(g_bserrno == 0); 2042 CU_ASSERT(payload[0] == 0xFF); 2043 } 2044 2045 /* Mark some clusters as unallocated */ 2046 blob->active.clusters[1] = 0; 2047 blob->active.clusters[2] = 0; 2048 blob->active.clusters[3] = 0; 2049 blob->active.clusters[6] = 0; 2050 blob->active.clusters[8] = 0; 2051 2052 /* Unmap clusters by resizing to 0 */ 2053 spdk_blob_resize(blob, 0, blob_op_complete, NULL); 2054 CU_ASSERT(g_bserrno == 0); 2055 2056 spdk_blob_sync_md(blob, blob_op_complete, NULL); 2057 CU_ASSERT(g_bserrno == 0); 2058 2059 /* Confirm that only 'allocated' clusters were unmapped */ 2060 for (i = 1; i < 11; i++) { 2061 switch (i) { 2062 case 2: 2063 case 3: 2064 case 4: 2065 case 7: 2066 case 9: 2067 CU_ASSERT(g_dev_buffer[i * SPDK_BLOB_OPTS_CLUSTER_SZ] == 0xFF); 2068 break; 2069 default: 2070 CU_ASSERT(g_dev_buffer[i * SPDK_BLOB_OPTS_CLUSTER_SZ] == 0); 2071 break; 2072 } 2073 } 2074 2075 spdk_blob_close(blob, blob_op_complete, NULL); 2076 CU_ASSERT(g_bserrno == 0); 2077 2078 spdk_bs_free_io_channel(channel); 2079 2080 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2081 CU_ASSERT(g_bserrno == 0); 2082 g_bs = NULL; 2083 } 2084 2085 2086 static void 2087 blob_iter(void) 2088 { 2089 struct spdk_blob_store *bs; 2090 struct spdk_bs_dev *dev; 2091 struct spdk_blob *blob; 2092 spdk_blob_id blobid; 2093 2094 dev = init_dev(); 2095 2096 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2097 CU_ASSERT(g_bserrno == 0); 2098 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2099 bs = g_bs; 2100 2101 spdk_bs_iter_first(bs, blob_op_with_handle_complete, NULL); 2102 CU_ASSERT(g_blob == NULL); 2103 CU_ASSERT(g_bserrno == -ENOENT); 2104 2105 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 2106 CU_ASSERT(g_bserrno == 0); 2107 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2108 blobid = g_blobid; 2109 2110 spdk_bs_iter_first(bs, blob_op_with_handle_complete, NULL); 2111 CU_ASSERT(g_blob != NULL); 2112 CU_ASSERT(g_bserrno == 0); 2113 blob = g_blob; 2114 CU_ASSERT(spdk_blob_get_id(blob) == blobid); 2115 2116 spdk_bs_iter_next(bs, blob, blob_op_with_handle_complete, NULL); 2117 CU_ASSERT(g_blob == NULL); 2118 CU_ASSERT(g_bserrno == -ENOENT); 2119 2120 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2121 CU_ASSERT(g_bserrno == 0); 2122 g_bs = NULL; 2123 } 2124 2125 static void 2126 blob_xattr(void) 2127 { 2128 struct spdk_blob_store *bs; 2129 struct spdk_bs_dev *dev; 2130 struct spdk_blob *blob; 2131 spdk_blob_id blobid; 2132 uint64_t length; 2133 int rc; 2134 const char *name1, *name2; 2135 const void *value; 2136 size_t value_len; 2137 struct spdk_xattr_names *names; 2138 2139 dev = init_dev(); 2140 2141 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2142 CU_ASSERT(g_bserrno == 0); 2143 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2144 bs = g_bs; 2145 2146 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 2147 CU_ASSERT(g_bserrno == 0); 2148 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2149 blobid = g_blobid; 2150 2151 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2152 CU_ASSERT(g_bserrno == 0); 2153 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2154 blob = g_blob; 2155 2156 /* Test that set_xattr fails if md_ro flag is set. */ 2157 blob->md_ro = true; 2158 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 2159 CU_ASSERT(rc == -EPERM); 2160 2161 blob->md_ro = false; 2162 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 2163 CU_ASSERT(rc == 0); 2164 2165 length = 2345; 2166 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 2167 CU_ASSERT(rc == 0); 2168 2169 /* Overwrite "length" xattr. */ 2170 length = 3456; 2171 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 2172 CU_ASSERT(rc == 0); 2173 2174 /* get_xattr should still work even if md_ro flag is set. */ 2175 value = NULL; 2176 blob->md_ro = true; 2177 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 2178 CU_ASSERT(rc == 0); 2179 SPDK_CU_ASSERT_FATAL(value != NULL); 2180 CU_ASSERT(*(uint64_t *)value == length); 2181 CU_ASSERT(value_len == 8); 2182 blob->md_ro = false; 2183 2184 rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len); 2185 CU_ASSERT(rc == -ENOENT); 2186 2187 names = NULL; 2188 rc = spdk_blob_get_xattr_names(blob, &names); 2189 CU_ASSERT(rc == 0); 2190 SPDK_CU_ASSERT_FATAL(names != NULL); 2191 CU_ASSERT(spdk_xattr_names_get_count(names) == 2); 2192 name1 = spdk_xattr_names_get_name(names, 0); 2193 SPDK_CU_ASSERT_FATAL(name1 != NULL); 2194 CU_ASSERT(!strcmp(name1, "name") || !strcmp(name1, "length")); 2195 name2 = spdk_xattr_names_get_name(names, 1); 2196 SPDK_CU_ASSERT_FATAL(name2 != NULL); 2197 CU_ASSERT(!strcmp(name2, "name") || !strcmp(name2, "length")); 2198 CU_ASSERT(strcmp(name1, name2)); 2199 spdk_xattr_names_free(names); 2200 2201 /* Confirm that remove_xattr fails if md_ro is set to true. */ 2202 blob->md_ro = true; 2203 rc = spdk_blob_remove_xattr(blob, "name"); 2204 CU_ASSERT(rc == -EPERM); 2205 2206 blob->md_ro = false; 2207 rc = spdk_blob_remove_xattr(blob, "name"); 2208 CU_ASSERT(rc == 0); 2209 2210 rc = spdk_blob_remove_xattr(blob, "foobar"); 2211 CU_ASSERT(rc == -ENOENT); 2212 2213 /* Set internal xattr */ 2214 length = 7898; 2215 rc = _spdk_blob_set_xattr(blob, "internal", &length, sizeof(length), true); 2216 CU_ASSERT(rc == 0); 2217 rc = _spdk_blob_get_xattr_value(blob, "internal", &value, &value_len, true); 2218 CU_ASSERT(rc == 0); 2219 CU_ASSERT(*(uint64_t *)value == length); 2220 /* try to get public xattr with same name */ 2221 rc = spdk_blob_get_xattr_value(blob, "internal", &value, &value_len); 2222 CU_ASSERT(rc != 0); 2223 rc = _spdk_blob_get_xattr_value(blob, "internal", &value, &value_len, false); 2224 CU_ASSERT(rc != 0); 2225 /* Check if SPDK_BLOB_INTERNAL_XATTR is set */ 2226 CU_ASSERT((blob->invalid_flags & SPDK_BLOB_INTERNAL_XATTR) == 2227 SPDK_BLOB_INTERNAL_XATTR) 2228 2229 spdk_blob_close(blob, blob_op_complete, NULL); 2230 2231 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2232 2233 /* Check if xattrs are persisted */ 2234 dev = init_dev(); 2235 2236 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 2237 CU_ASSERT(g_bserrno == 0); 2238 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2239 2240 bs = g_bs; 2241 2242 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2243 CU_ASSERT(g_bserrno == 0); 2244 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2245 blob = g_blob; 2246 2247 rc = _spdk_blob_get_xattr_value(blob, "internal", &value, &value_len, true); 2248 CU_ASSERT(rc == 0); 2249 CU_ASSERT(*(uint64_t *)value == length); 2250 2251 /* try to get internal xattr trough public call */ 2252 rc = spdk_blob_get_xattr_value(blob, "internal", &value, &value_len); 2253 CU_ASSERT(rc != 0); 2254 2255 rc = _spdk_blob_remove_xattr(blob, "internal", true); 2256 CU_ASSERT(rc == 0); 2257 2258 CU_ASSERT((blob->invalid_flags & SPDK_BLOB_INTERNAL_XATTR) == 0); 2259 2260 CU_ASSERT(g_bserrno == 0); 2261 g_bs = NULL; 2262 } 2263 2264 static void 2265 bs_load(void) 2266 { 2267 struct spdk_bs_dev *dev; 2268 spdk_blob_id blobid; 2269 struct spdk_blob *blob; 2270 struct spdk_bs_super_block *super_block; 2271 uint64_t length; 2272 int rc; 2273 const void *value; 2274 size_t value_len; 2275 struct spdk_bs_opts opts; 2276 2277 dev = init_dev(); 2278 spdk_bs_opts_init(&opts); 2279 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 2280 2281 /* Initialize a new blob store */ 2282 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2283 CU_ASSERT(g_bserrno == 0); 2284 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2285 2286 /* Try to open a blobid that does not exist */ 2287 spdk_bs_open_blob(g_bs, 0, blob_op_with_handle_complete, NULL); 2288 CU_ASSERT(g_bserrno == -ENOENT); 2289 CU_ASSERT(g_blob == NULL); 2290 2291 /* Create a blob */ 2292 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2293 CU_ASSERT(g_bserrno == 0); 2294 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2295 blobid = g_blobid; 2296 2297 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 2298 CU_ASSERT(g_bserrno == 0); 2299 CU_ASSERT(g_blob != NULL); 2300 blob = g_blob; 2301 2302 /* Try again to open valid blob but without the upper bit set */ 2303 spdk_bs_open_blob(g_bs, blobid & 0xFFFFFFFF, blob_op_with_handle_complete, NULL); 2304 CU_ASSERT(g_bserrno == -ENOENT); 2305 CU_ASSERT(g_blob == NULL); 2306 2307 /* Set some xattrs */ 2308 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 2309 CU_ASSERT(rc == 0); 2310 2311 length = 2345; 2312 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 2313 CU_ASSERT(rc == 0); 2314 2315 /* Resize the blob */ 2316 spdk_blob_resize(blob, 10, blob_op_complete, NULL); 2317 CU_ASSERT(g_bserrno == 0); 2318 2319 spdk_blob_close(blob, blob_op_complete, NULL); 2320 CU_ASSERT(g_bserrno == 0); 2321 blob = NULL; 2322 g_blob = NULL; 2323 g_blobid = SPDK_BLOBID_INVALID; 2324 2325 /* Unload the blob store */ 2326 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2327 CU_ASSERT(g_bserrno == 0); 2328 g_bs = NULL; 2329 g_blob = NULL; 2330 g_blobid = 0; 2331 2332 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 2333 CU_ASSERT(super_block->clean == 1); 2334 2335 /* Load should fail for device with an unsupported blocklen */ 2336 dev = init_dev(); 2337 dev->blocklen = SPDK_BS_PAGE_SIZE * 2; 2338 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 2339 CU_ASSERT(g_bserrno == -EINVAL); 2340 2341 /* Load should when max_md_ops is set to zero */ 2342 dev = init_dev(); 2343 spdk_bs_opts_init(&opts); 2344 opts.max_md_ops = 0; 2345 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2346 CU_ASSERT(g_bserrno == -EINVAL); 2347 2348 /* Load should when max_channel_ops is set to zero */ 2349 dev = init_dev(); 2350 spdk_bs_opts_init(&opts); 2351 opts.max_channel_ops = 0; 2352 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2353 CU_ASSERT(g_bserrno == -EINVAL); 2354 2355 /* Load an existing blob store */ 2356 dev = init_dev(); 2357 spdk_bs_opts_init(&opts); 2358 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 2359 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2360 CU_ASSERT(g_bserrno == 0); 2361 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2362 2363 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 2364 CU_ASSERT(super_block->clean == 1); 2365 CU_ASSERT(super_block->size == dev->blockcnt * dev->blocklen); 2366 2367 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 2368 CU_ASSERT(g_bserrno == 0); 2369 CU_ASSERT(g_blob != NULL); 2370 blob = g_blob; 2371 2372 /* Verify that blobstore is marked dirty after first metadata sync */ 2373 spdk_blob_sync_md(blob, blob_op_complete, NULL); 2374 CU_ASSERT(super_block->clean == 1); 2375 2376 /* Get the xattrs */ 2377 value = NULL; 2378 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 2379 CU_ASSERT(rc == 0); 2380 SPDK_CU_ASSERT_FATAL(value != NULL); 2381 CU_ASSERT(*(uint64_t *)value == length); 2382 CU_ASSERT(value_len == 8); 2383 2384 rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len); 2385 CU_ASSERT(rc == -ENOENT); 2386 2387 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 2388 2389 spdk_blob_close(blob, blob_op_complete, NULL); 2390 CU_ASSERT(g_bserrno == 0); 2391 blob = NULL; 2392 g_blob = NULL; 2393 2394 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2395 CU_ASSERT(g_bserrno == 0); 2396 g_bs = NULL; 2397 2398 /* Load should fail: bdev size < saved size */ 2399 dev = init_dev(); 2400 dev->blockcnt /= 2; 2401 2402 spdk_bs_opts_init(&opts); 2403 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 2404 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2405 2406 CU_ASSERT(g_bserrno == -EILSEQ); 2407 2408 /* Load should succeed: bdev size > saved size */ 2409 dev = init_dev(); 2410 dev->blockcnt *= 4; 2411 2412 spdk_bs_opts_init(&opts); 2413 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 2414 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2415 2416 CU_ASSERT(g_bserrno == 0); 2417 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2418 2419 2420 /* Test compatibility mode */ 2421 2422 dev = init_dev(); 2423 super_block->size = 0; 2424 super_block->crc = _spdk_blob_md_page_calc_crc(super_block); 2425 2426 spdk_bs_opts_init(&opts); 2427 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 2428 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2429 CU_ASSERT(g_bserrno == 0); 2430 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2431 2432 /* Create a blob */ 2433 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2434 CU_ASSERT(g_bserrno == 0); 2435 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2436 2437 /* Blobstore should update number of blocks in super_block */ 2438 CU_ASSERT(super_block->size == dev->blockcnt * dev->blocklen); 2439 CU_ASSERT(super_block->clean == 0); 2440 2441 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2442 CU_ASSERT(g_bserrno == 0); 2443 CU_ASSERT(super_block->clean == 1); 2444 g_bs = NULL; 2445 2446 } 2447 2448 static void 2449 bs_load_custom_cluster_size(void) 2450 { 2451 struct spdk_bs_dev *dev; 2452 struct spdk_bs_super_block *super_block; 2453 struct spdk_bs_opts opts; 2454 uint32_t custom_cluster_size = 4194304; /* 4MiB */ 2455 uint32_t cluster_sz; 2456 uint64_t total_clusters; 2457 2458 dev = init_dev(); 2459 spdk_bs_opts_init(&opts); 2460 opts.cluster_sz = custom_cluster_size; 2461 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 2462 2463 /* Initialize a new blob store */ 2464 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2465 CU_ASSERT(g_bserrno == 0); 2466 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2467 cluster_sz = g_bs->cluster_sz; 2468 total_clusters = g_bs->total_clusters; 2469 2470 /* Unload the blob store */ 2471 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2472 CU_ASSERT(g_bserrno == 0); 2473 g_bs = NULL; 2474 g_blob = NULL; 2475 g_blobid = 0; 2476 2477 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 2478 CU_ASSERT(super_block->clean == 1); 2479 2480 /* Load an existing blob store */ 2481 dev = init_dev(); 2482 spdk_bs_opts_init(&opts); 2483 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 2484 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2485 CU_ASSERT(g_bserrno == 0); 2486 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2487 /* Compare cluster size and number to one after initialization */ 2488 CU_ASSERT(cluster_sz == g_bs->cluster_sz); 2489 CU_ASSERT(total_clusters == g_bs->total_clusters); 2490 2491 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 2492 CU_ASSERT(super_block->clean == 1); 2493 CU_ASSERT(super_block->size == dev->blockcnt * dev->blocklen); 2494 2495 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2496 CU_ASSERT(g_bserrno == 0); 2497 CU_ASSERT(super_block->clean == 1); 2498 g_bs = NULL; 2499 } 2500 2501 static void 2502 bs_type(void) 2503 { 2504 struct spdk_bs_dev *dev; 2505 struct spdk_bs_opts opts; 2506 2507 dev = init_dev(); 2508 spdk_bs_opts_init(&opts); 2509 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 2510 2511 /* Initialize a new blob store */ 2512 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2513 CU_ASSERT(g_bserrno == 0); 2514 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2515 2516 /* Unload the blob store */ 2517 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2518 CU_ASSERT(g_bserrno == 0); 2519 g_bs = NULL; 2520 g_blob = NULL; 2521 g_blobid = 0; 2522 2523 /* Load non existing blobstore type */ 2524 dev = init_dev(); 2525 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "NONEXISTING"); 2526 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2527 CU_ASSERT(g_bserrno != 0); 2528 2529 /* Load with empty blobstore type */ 2530 dev = init_dev(); 2531 memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype)); 2532 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2533 CU_ASSERT(g_bserrno == 0); 2534 2535 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2536 CU_ASSERT(g_bserrno == 0); 2537 g_bs = NULL; 2538 2539 /* Initialize a new blob store with empty bstype */ 2540 dev = init_dev(); 2541 memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype)); 2542 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2543 CU_ASSERT(g_bserrno == 0); 2544 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2545 2546 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2547 CU_ASSERT(g_bserrno == 0); 2548 g_bs = NULL; 2549 2550 /* Load non existing blobstore type */ 2551 dev = init_dev(); 2552 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "NONEXISTING"); 2553 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2554 CU_ASSERT(g_bserrno != 0); 2555 2556 /* Load with empty blobstore type */ 2557 dev = init_dev(); 2558 memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype)); 2559 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2560 CU_ASSERT(g_bserrno == 0); 2561 2562 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2563 CU_ASSERT(g_bserrno == 0); 2564 g_bs = NULL; 2565 } 2566 2567 static void 2568 bs_super_block(void) 2569 { 2570 struct spdk_bs_dev *dev; 2571 struct spdk_bs_super_block *super_block; 2572 struct spdk_bs_opts opts; 2573 struct spdk_bs_super_block_ver1 super_block_v1; 2574 2575 dev = init_dev(); 2576 spdk_bs_opts_init(&opts); 2577 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 2578 2579 /* Initialize a new blob store */ 2580 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2581 CU_ASSERT(g_bserrno == 0); 2582 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2583 2584 /* Unload the blob store */ 2585 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2586 CU_ASSERT(g_bserrno == 0); 2587 g_bs = NULL; 2588 g_blob = NULL; 2589 g_blobid = 0; 2590 2591 /* Load an existing blob store with version newer than supported */ 2592 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 2593 super_block->version++; 2594 2595 dev = init_dev(); 2596 memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype)); 2597 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2598 CU_ASSERT(g_bserrno != 0); 2599 2600 /* Create a new blob store with super block version 1 */ 2601 dev = init_dev(); 2602 super_block_v1.version = 1; 2603 memcpy(super_block_v1.signature, "SPDKBLOB", sizeof(super_block_v1.signature)); 2604 super_block_v1.length = 0x1000; 2605 super_block_v1.clean = 1; 2606 super_block_v1.super_blob = 0xFFFFFFFFFFFFFFFF; 2607 super_block_v1.cluster_size = 0x100000; 2608 super_block_v1.used_page_mask_start = 0x01; 2609 super_block_v1.used_page_mask_len = 0x01; 2610 super_block_v1.used_cluster_mask_start = 0x02; 2611 super_block_v1.used_cluster_mask_len = 0x01; 2612 super_block_v1.md_start = 0x03; 2613 super_block_v1.md_len = 0x40; 2614 memset(super_block_v1.reserved, 0, 4036); 2615 super_block_v1.crc = _spdk_blob_md_page_calc_crc(&super_block_v1); 2616 memcpy(g_dev_buffer, &super_block_v1, sizeof(struct spdk_bs_super_block_ver1)); 2617 2618 memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype)); 2619 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2620 CU_ASSERT(g_bserrno == 0); 2621 2622 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2623 CU_ASSERT(g_bserrno == 0); 2624 g_bs = NULL; 2625 } 2626 2627 /* 2628 * Create a blobstore and then unload it. 2629 */ 2630 static void 2631 bs_unload(void) 2632 { 2633 struct spdk_bs_dev *dev; 2634 struct spdk_blob_store *bs; 2635 spdk_blob_id blobid; 2636 struct spdk_blob *blob; 2637 2638 dev = init_dev(); 2639 2640 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2641 CU_ASSERT(g_bserrno == 0); 2642 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2643 bs = g_bs; 2644 2645 /* Create a blob and open it. */ 2646 g_bserrno = -1; 2647 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 2648 CU_ASSERT(g_bserrno == 0); 2649 CU_ASSERT(g_blobid > 0); 2650 blobid = g_blobid; 2651 2652 g_bserrno = -1; 2653 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2654 CU_ASSERT(g_bserrno == 0); 2655 CU_ASSERT(g_blob != NULL); 2656 blob = g_blob; 2657 2658 /* Try to unload blobstore, should fail with open blob */ 2659 g_bserrno = -1; 2660 spdk_bs_unload(bs, bs_op_complete, NULL); 2661 CU_ASSERT(g_bserrno == -EBUSY); 2662 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2663 2664 /* Close the blob, then successfully unload blobstore */ 2665 g_bserrno = -1; 2666 spdk_blob_close(blob, blob_op_complete, NULL); 2667 CU_ASSERT(g_bserrno == 0); 2668 2669 g_bserrno = -1; 2670 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2671 CU_ASSERT(g_bserrno == 0); 2672 g_bs = NULL; 2673 } 2674 2675 /* 2676 * Create a blobstore with a cluster size different than the default, and ensure it is 2677 * persisted. 2678 */ 2679 static void 2680 bs_cluster_sz(void) 2681 { 2682 struct spdk_bs_dev *dev; 2683 struct spdk_bs_opts opts; 2684 uint32_t cluster_sz; 2685 2686 /* Set cluster size to zero */ 2687 dev = init_dev(); 2688 spdk_bs_opts_init(&opts); 2689 opts.cluster_sz = 0; 2690 2691 /* Initialize a new blob store */ 2692 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2693 CU_ASSERT(g_bserrno == -EINVAL); 2694 SPDK_CU_ASSERT_FATAL(g_bs == NULL); 2695 2696 /* 2697 * Set cluster size to blobstore page size, 2698 * to work it is required to be at least twice the blobstore page size. 2699 */ 2700 dev = init_dev(); 2701 spdk_bs_opts_init(&opts); 2702 opts.cluster_sz = SPDK_BS_PAGE_SIZE; 2703 2704 /* Initialize a new blob store */ 2705 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2706 CU_ASSERT(g_bserrno == -ENOMEM); 2707 SPDK_CU_ASSERT_FATAL(g_bs == NULL); 2708 2709 /* 2710 * Set cluster size to lower than page size, 2711 * to work it is required to be at least twice the blobstore page size. 2712 */ 2713 dev = init_dev(); 2714 spdk_bs_opts_init(&opts); 2715 opts.cluster_sz = SPDK_BS_PAGE_SIZE - 1; 2716 2717 /* Initialize a new blob store */ 2718 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2719 CU_ASSERT(g_bserrno == -EINVAL); 2720 SPDK_CU_ASSERT_FATAL(g_bs == NULL); 2721 2722 /* Set cluster size to twice the default */ 2723 dev = init_dev(); 2724 spdk_bs_opts_init(&opts); 2725 opts.cluster_sz *= 2; 2726 cluster_sz = opts.cluster_sz; 2727 2728 /* Initialize a new blob store */ 2729 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2730 CU_ASSERT(g_bserrno == 0); 2731 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2732 2733 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 2734 2735 /* Unload the blob store */ 2736 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2737 CU_ASSERT(g_bserrno == 0); 2738 g_bs = NULL; 2739 g_blob = NULL; 2740 g_blobid = 0; 2741 2742 dev = init_dev(); 2743 /* Load an existing blob store */ 2744 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2745 CU_ASSERT(g_bserrno == 0); 2746 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2747 2748 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 2749 2750 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2751 CU_ASSERT(g_bserrno == 0); 2752 g_bs = NULL; 2753 } 2754 2755 /* 2756 * Create a blobstore, reload it and ensure total usable cluster count 2757 * stays the same. 2758 */ 2759 static void 2760 bs_usable_clusters(void) 2761 { 2762 struct spdk_bs_dev *dev; 2763 struct spdk_bs_opts opts; 2764 uint32_t clusters; 2765 int i; 2766 2767 /* Init blobstore */ 2768 dev = init_dev(); 2769 spdk_bs_opts_init(&opts); 2770 2771 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2772 CU_ASSERT(g_bserrno == 0); 2773 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2774 2775 clusters = spdk_bs_total_data_cluster_count(g_bs); 2776 2777 /* Unload the blob store */ 2778 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2779 CU_ASSERT(g_bserrno == 0); 2780 g_bs = NULL; 2781 2782 dev = init_dev(); 2783 /* Load an existing blob store */ 2784 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2785 CU_ASSERT(g_bserrno == 0); 2786 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2787 2788 CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters); 2789 2790 /* Create and resize blobs to make sure that useable cluster count won't change */ 2791 for (i = 0; i < 4; i++) { 2792 g_bserrno = -1; 2793 g_blobid = SPDK_BLOBID_INVALID; 2794 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2795 CU_ASSERT(g_bserrno == 0); 2796 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2797 2798 g_bserrno = -1; 2799 g_blob = NULL; 2800 spdk_bs_open_blob(g_bs, g_blobid, blob_op_with_handle_complete, NULL); 2801 CU_ASSERT(g_bserrno == 0); 2802 CU_ASSERT(g_blob != NULL); 2803 2804 spdk_blob_resize(g_blob, 10, blob_op_complete, NULL); 2805 CU_ASSERT(g_bserrno == 0); 2806 2807 g_bserrno = -1; 2808 spdk_blob_close(g_blob, blob_op_complete, NULL); 2809 CU_ASSERT(g_bserrno == 0); 2810 2811 CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters); 2812 } 2813 2814 /* Reload the blob store to make sure that nothing changed */ 2815 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2816 CU_ASSERT(g_bserrno == 0); 2817 g_bs = NULL; 2818 2819 dev = init_dev(); 2820 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2821 CU_ASSERT(g_bserrno == 0); 2822 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2823 2824 CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters); 2825 2826 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2827 CU_ASSERT(g_bserrno == 0); 2828 g_bs = NULL; 2829 } 2830 2831 /* 2832 * Test resizing of the metadata blob. This requires creating enough blobs 2833 * so that one cluster is not enough to fit the metadata for those blobs. 2834 * To induce this condition to happen more quickly, we reduce the cluster 2835 * size to 16KB, which means only 4 4KB blob metadata pages can fit. 2836 */ 2837 static void 2838 bs_resize_md(void) 2839 { 2840 const int CLUSTER_PAGE_COUNT = 4; 2841 const int NUM_BLOBS = CLUSTER_PAGE_COUNT * 4; 2842 struct spdk_bs_dev *dev; 2843 struct spdk_bs_opts opts; 2844 uint32_t cluster_sz; 2845 spdk_blob_id blobids[NUM_BLOBS]; 2846 int i; 2847 2848 2849 dev = init_dev(); 2850 spdk_bs_opts_init(&opts); 2851 opts.cluster_sz = CLUSTER_PAGE_COUNT * 4096; 2852 cluster_sz = opts.cluster_sz; 2853 2854 /* Initialize a new blob store */ 2855 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2856 CU_ASSERT(g_bserrno == 0); 2857 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2858 2859 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 2860 2861 for (i = 0; i < NUM_BLOBS; i++) { 2862 g_bserrno = -1; 2863 g_blobid = SPDK_BLOBID_INVALID; 2864 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2865 CU_ASSERT(g_bserrno == 0); 2866 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2867 blobids[i] = g_blobid; 2868 } 2869 2870 /* Unload the blob store */ 2871 g_bserrno = -1; 2872 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2873 CU_ASSERT(g_bserrno == 0); 2874 2875 /* Load an existing blob store */ 2876 g_bserrno = -1; 2877 g_bs = NULL; 2878 dev = init_dev(); 2879 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2880 CU_ASSERT(g_bserrno == 0); 2881 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2882 2883 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 2884 2885 for (i = 0; i < NUM_BLOBS; i++) { 2886 g_bserrno = -1; 2887 g_blob = NULL; 2888 spdk_bs_open_blob(g_bs, blobids[i], blob_op_with_handle_complete, NULL); 2889 CU_ASSERT(g_bserrno == 0); 2890 CU_ASSERT(g_blob != NULL); 2891 g_bserrno = -1; 2892 spdk_blob_close(g_blob, blob_op_complete, NULL); 2893 CU_ASSERT(g_bserrno == 0); 2894 } 2895 2896 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2897 CU_ASSERT(g_bserrno == 0); 2898 g_bs = NULL; 2899 } 2900 2901 static void 2902 bs_destroy(void) 2903 { 2904 struct spdk_bs_dev *dev; 2905 struct spdk_bs_opts opts; 2906 2907 /* Initialize a new blob store */ 2908 dev = init_dev(); 2909 spdk_bs_opts_init(&opts); 2910 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2911 CU_ASSERT(g_bserrno == 0); 2912 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2913 2914 /* Destroy the blob store */ 2915 g_bserrno = -1; 2916 spdk_bs_destroy(g_bs, bs_op_complete, NULL); 2917 CU_ASSERT(g_bserrno == 0); 2918 2919 /* Loading an non-existent blob store should fail. */ 2920 g_bs = NULL; 2921 dev = init_dev(); 2922 2923 g_bserrno = 0; 2924 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2925 CU_ASSERT(g_bserrno != 0); 2926 } 2927 2928 /* Try to hit all of the corner cases associated with serializing 2929 * a blob to disk 2930 */ 2931 static void 2932 blob_serialize(void) 2933 { 2934 struct spdk_bs_dev *dev; 2935 struct spdk_bs_opts opts; 2936 struct spdk_blob_store *bs; 2937 spdk_blob_id blobid[2]; 2938 struct spdk_blob *blob[2]; 2939 uint64_t i; 2940 char *value; 2941 int rc; 2942 2943 dev = init_dev(); 2944 2945 /* Initialize a new blobstore with very small clusters */ 2946 spdk_bs_opts_init(&opts); 2947 opts.cluster_sz = dev->blocklen * 8; 2948 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2949 CU_ASSERT(g_bserrno == 0); 2950 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2951 bs = g_bs; 2952 2953 /* Create and open two blobs */ 2954 for (i = 0; i < 2; i++) { 2955 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 2956 CU_ASSERT(g_bserrno == 0); 2957 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2958 blobid[i] = g_blobid; 2959 2960 /* Open a blob */ 2961 spdk_bs_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL); 2962 CU_ASSERT(g_bserrno == 0); 2963 CU_ASSERT(g_blob != NULL); 2964 blob[i] = g_blob; 2965 2966 /* Set a fairly large xattr on both blobs to eat up 2967 * metadata space 2968 */ 2969 value = calloc(dev->blocklen - 64, sizeof(char)); 2970 SPDK_CU_ASSERT_FATAL(value != NULL); 2971 memset(value, i, dev->blocklen / 2); 2972 rc = spdk_blob_set_xattr(blob[i], "name", value, dev->blocklen - 64); 2973 CU_ASSERT(rc == 0); 2974 free(value); 2975 } 2976 2977 /* Resize the blobs, alternating 1 cluster at a time. 2978 * This thwarts run length encoding and will cause spill 2979 * over of the extents. 2980 */ 2981 for (i = 0; i < 6; i++) { 2982 spdk_blob_resize(blob[i % 2], (i / 2) + 1, blob_op_complete, NULL); 2983 CU_ASSERT(g_bserrno == 0); 2984 } 2985 2986 for (i = 0; i < 2; i++) { 2987 spdk_blob_sync_md(blob[i], blob_op_complete, NULL); 2988 CU_ASSERT(g_bserrno == 0); 2989 } 2990 2991 /* Close the blobs */ 2992 for (i = 0; i < 2; i++) { 2993 spdk_blob_close(blob[i], blob_op_complete, NULL); 2994 CU_ASSERT(g_bserrno == 0); 2995 } 2996 2997 /* Unload the blobstore */ 2998 spdk_bs_unload(bs, bs_op_complete, NULL); 2999 CU_ASSERT(g_bserrno == 0); 3000 g_bs = NULL; 3001 g_blob = NULL; 3002 g_blobid = 0; 3003 bs = NULL; 3004 3005 dev = init_dev(); 3006 /* Load an existing blob store */ 3007 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3008 CU_ASSERT(g_bserrno == 0); 3009 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3010 bs = g_bs; 3011 3012 for (i = 0; i < 2; i++) { 3013 blob[i] = NULL; 3014 3015 spdk_bs_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL); 3016 CU_ASSERT(g_bserrno == 0); 3017 CU_ASSERT(g_blob != NULL); 3018 blob[i] = g_blob; 3019 3020 CU_ASSERT(spdk_blob_get_num_clusters(blob[i]) == 3); 3021 3022 spdk_blob_close(blob[i], blob_op_complete, NULL); 3023 CU_ASSERT(g_bserrno == 0); 3024 } 3025 3026 spdk_bs_unload(bs, bs_op_complete, NULL); 3027 CU_ASSERT(g_bserrno == 0); 3028 g_bs = NULL; 3029 } 3030 3031 static void 3032 blob_crc(void) 3033 { 3034 struct spdk_blob_store *bs; 3035 struct spdk_bs_dev *dev; 3036 struct spdk_blob *blob; 3037 spdk_blob_id blobid; 3038 uint32_t page_num; 3039 int index; 3040 struct spdk_blob_md_page *page; 3041 3042 dev = init_dev(); 3043 3044 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3045 CU_ASSERT(g_bserrno == 0); 3046 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3047 bs = g_bs; 3048 3049 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 3050 CU_ASSERT(g_bserrno == 0); 3051 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3052 blobid = g_blobid; 3053 3054 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3055 CU_ASSERT(g_bserrno == 0); 3056 CU_ASSERT(g_blob != NULL); 3057 blob = g_blob; 3058 3059 spdk_blob_close(blob, blob_op_complete, NULL); 3060 CU_ASSERT(g_bserrno == 0); 3061 3062 page_num = _spdk_bs_blobid_to_page(blobid); 3063 index = DEV_BUFFER_BLOCKLEN * (bs->md_start + page_num); 3064 page = (struct spdk_blob_md_page *)&g_dev_buffer[index]; 3065 page->crc = 0; 3066 3067 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3068 CU_ASSERT(g_bserrno == -EINVAL); 3069 CU_ASSERT(g_blob == NULL); 3070 g_bserrno = 0; 3071 3072 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 3073 CU_ASSERT(g_bserrno == -EINVAL); 3074 3075 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3076 CU_ASSERT(g_bserrno == 0); 3077 g_bs = NULL; 3078 } 3079 3080 static void 3081 super_block_crc(void) 3082 { 3083 struct spdk_bs_dev *dev; 3084 struct spdk_bs_super_block *super_block; 3085 struct spdk_bs_opts opts; 3086 3087 dev = init_dev(); 3088 spdk_bs_opts_init(&opts); 3089 3090 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3091 CU_ASSERT(g_bserrno == 0); 3092 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3093 3094 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3095 CU_ASSERT(g_bserrno == 0); 3096 g_bs = NULL; 3097 3098 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 3099 super_block->crc = 0; 3100 dev = init_dev(); 3101 3102 /* Load an existing blob store */ 3103 g_bserrno = 0; 3104 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3105 CU_ASSERT(g_bserrno == -EILSEQ); 3106 } 3107 3108 /* For blob dirty shutdown test case we do the following sub-test cases: 3109 * 1 Initialize new blob store and create 1 super blob with some xattrs, then we 3110 * dirty shutdown and reload the blob store and verify the xattrs. 3111 * 2 Resize the blob from 10 clusters to 20 clusters and then dirty shutdown, 3112 * reload the blob store and verify the clusters number. 3113 * 3 Create the second blob and then dirty shutdown, reload the blob store 3114 * and verify the second blob. 3115 * 4 Delete the second blob and then dirty shutdown, reload the blob store 3116 * and verify the second blob is invalid. 3117 * 5 Create the second blob again and also create the third blob, modify the 3118 * md of second blob which makes the md invalid, and then dirty shutdown, 3119 * reload the blob store verify the second blob, it should invalid and also 3120 * verify the third blob, it should correct. 3121 */ 3122 static void 3123 blob_dirty_shutdown(void) 3124 { 3125 int rc; 3126 int index; 3127 struct spdk_bs_dev *dev; 3128 spdk_blob_id blobid1, blobid2, blobid3; 3129 struct spdk_blob *blob; 3130 uint64_t length; 3131 uint64_t free_clusters; 3132 const void *value; 3133 size_t value_len; 3134 uint32_t page_num; 3135 struct spdk_blob_md_page *page; 3136 struct spdk_bs_opts opts; 3137 3138 dev = init_dev(); 3139 spdk_bs_opts_init(&opts); 3140 /* Initialize a new blob store */ 3141 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3142 CU_ASSERT(g_bserrno == 0); 3143 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3144 3145 /* Create first blob */ 3146 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 3147 CU_ASSERT(g_bserrno == 0); 3148 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3149 blobid1 = g_blobid; 3150 3151 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 3152 CU_ASSERT(g_bserrno == 0); 3153 CU_ASSERT(g_blob != NULL); 3154 blob = g_blob; 3155 3156 /* Set some xattrs */ 3157 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 3158 CU_ASSERT(rc == 0); 3159 3160 length = 2345; 3161 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 3162 CU_ASSERT(rc == 0); 3163 3164 /* Resize the blob */ 3165 spdk_blob_resize(blob, 10, blob_op_complete, NULL); 3166 CU_ASSERT(g_bserrno == 0); 3167 3168 /* Set the blob as the super blob */ 3169 spdk_bs_set_super(g_bs, blobid1, blob_op_complete, NULL); 3170 CU_ASSERT(g_bserrno == 0); 3171 3172 free_clusters = spdk_bs_free_cluster_count(g_bs); 3173 3174 spdk_blob_close(blob, blob_op_complete, NULL); 3175 blob = NULL; 3176 g_blob = NULL; 3177 g_blobid = SPDK_BLOBID_INVALID; 3178 3179 /* Dirty shutdown */ 3180 _spdk_bs_free(g_bs); 3181 3182 /* reload blobstore */ 3183 dev = init_dev(); 3184 spdk_bs_opts_init(&opts); 3185 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3186 CU_ASSERT(g_bserrno == 0); 3187 3188 /* Get the super blob */ 3189 spdk_bs_get_super(g_bs, blob_op_with_id_complete, NULL); 3190 CU_ASSERT(g_bserrno == 0); 3191 CU_ASSERT(blobid1 == g_blobid); 3192 3193 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 3194 CU_ASSERT(g_bserrno == 0); 3195 CU_ASSERT(g_blob != NULL); 3196 blob = g_blob; 3197 3198 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 3199 3200 /* Get the xattrs */ 3201 value = NULL; 3202 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 3203 CU_ASSERT(rc == 0); 3204 SPDK_CU_ASSERT_FATAL(value != NULL); 3205 CU_ASSERT(*(uint64_t *)value == length); 3206 CU_ASSERT(value_len == 8); 3207 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 3208 3209 /* Resize the blob */ 3210 spdk_blob_resize(blob, 20, blob_op_complete, NULL); 3211 CU_ASSERT(g_bserrno == 0); 3212 3213 free_clusters = spdk_bs_free_cluster_count(g_bs); 3214 3215 spdk_blob_close(blob, blob_op_complete, NULL); 3216 CU_ASSERT(g_bserrno == 0); 3217 blob = NULL; 3218 g_blob = NULL; 3219 g_blobid = SPDK_BLOBID_INVALID; 3220 3221 /* Dirty shutdown */ 3222 _spdk_bs_free(g_bs); 3223 3224 /* reload the blobstore */ 3225 dev = init_dev(); 3226 spdk_bs_opts_init(&opts); 3227 /* Load an existing blob store */ 3228 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3229 CU_ASSERT(g_bserrno == 0); 3230 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3231 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 3232 CU_ASSERT(g_bserrno == 0); 3233 CU_ASSERT(g_blob != NULL); 3234 blob = g_blob; 3235 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 20); 3236 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 3237 3238 spdk_blob_close(blob, blob_op_complete, NULL); 3239 CU_ASSERT(g_bserrno == 0); 3240 blob = NULL; 3241 g_blob = NULL; 3242 g_blobid = SPDK_BLOBID_INVALID; 3243 3244 /* Create second blob */ 3245 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 3246 CU_ASSERT(g_bserrno == 0); 3247 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3248 blobid2 = g_blobid; 3249 3250 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 3251 CU_ASSERT(g_bserrno == 0); 3252 CU_ASSERT(g_blob != NULL); 3253 blob = g_blob; 3254 3255 /* Set some xattrs */ 3256 rc = spdk_blob_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1); 3257 CU_ASSERT(rc == 0); 3258 3259 length = 5432; 3260 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 3261 CU_ASSERT(rc == 0); 3262 3263 /* Resize the blob */ 3264 spdk_blob_resize(blob, 10, blob_op_complete, NULL); 3265 CU_ASSERT(g_bserrno == 0); 3266 3267 free_clusters = spdk_bs_free_cluster_count(g_bs); 3268 3269 spdk_blob_close(blob, blob_op_complete, NULL); 3270 blob = NULL; 3271 g_blob = NULL; 3272 g_blobid = SPDK_BLOBID_INVALID; 3273 3274 /* Dirty shutdown */ 3275 _spdk_bs_free(g_bs); 3276 3277 /* reload the blobstore */ 3278 dev = init_dev(); 3279 spdk_bs_opts_init(&opts); 3280 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3281 CU_ASSERT(g_bserrno == 0); 3282 3283 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 3284 CU_ASSERT(g_bserrno == 0); 3285 CU_ASSERT(g_blob != NULL); 3286 blob = g_blob; 3287 3288 /* Get the xattrs */ 3289 value = NULL; 3290 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 3291 CU_ASSERT(rc == 0); 3292 SPDK_CU_ASSERT_FATAL(value != NULL); 3293 CU_ASSERT(*(uint64_t *)value == length); 3294 CU_ASSERT(value_len == 8); 3295 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 3296 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 3297 3298 spdk_blob_close(blob, blob_op_complete, NULL); 3299 CU_ASSERT(g_bserrno == 0); 3300 spdk_bs_delete_blob(g_bs, blobid2, blob_op_complete, NULL); 3301 CU_ASSERT(g_bserrno == 0); 3302 3303 free_clusters = spdk_bs_free_cluster_count(g_bs); 3304 3305 /* Dirty shutdown */ 3306 _spdk_bs_free(g_bs); 3307 /* reload the blobstore */ 3308 dev = init_dev(); 3309 spdk_bs_opts_init(&opts); 3310 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3311 CU_ASSERT(g_bserrno == 0); 3312 3313 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 3314 CU_ASSERT(g_bserrno != 0); 3315 CU_ASSERT(g_blob == NULL); 3316 3317 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 3318 CU_ASSERT(g_bserrno == 0); 3319 CU_ASSERT(g_blob != NULL); 3320 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 3321 spdk_blob_close(g_blob, blob_op_complete, NULL); 3322 CU_ASSERT(g_bserrno == 0); 3323 3324 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3325 CU_ASSERT(g_bserrno == 0); 3326 g_bs = NULL; 3327 3328 /* reload the blobstore */ 3329 dev = init_dev(); 3330 spdk_bs_opts_init(&opts); 3331 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3332 CU_ASSERT(g_bserrno == 0); 3333 3334 /* Create second blob */ 3335 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 3336 CU_ASSERT(g_bserrno == 0); 3337 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3338 blobid2 = g_blobid; 3339 3340 /* Create third blob */ 3341 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 3342 CU_ASSERT(g_bserrno == 0); 3343 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3344 blobid3 = g_blobid; 3345 3346 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 3347 CU_ASSERT(g_bserrno == 0); 3348 CU_ASSERT(g_blob != NULL); 3349 blob = g_blob; 3350 3351 /* Set some xattrs for second blob */ 3352 rc = spdk_blob_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1); 3353 CU_ASSERT(rc == 0); 3354 3355 length = 5432; 3356 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 3357 CU_ASSERT(rc == 0); 3358 3359 spdk_blob_close(blob, blob_op_complete, NULL); 3360 blob = NULL; 3361 g_blob = NULL; 3362 g_blobid = SPDK_BLOBID_INVALID; 3363 3364 spdk_bs_open_blob(g_bs, blobid3, blob_op_with_handle_complete, NULL); 3365 CU_ASSERT(g_bserrno == 0); 3366 CU_ASSERT(g_blob != NULL); 3367 blob = g_blob; 3368 3369 /* Set some xattrs for third blob */ 3370 rc = spdk_blob_set_xattr(blob, "name", "log2.txt", strlen("log2.txt") + 1); 3371 CU_ASSERT(rc == 0); 3372 3373 length = 5432; 3374 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 3375 CU_ASSERT(rc == 0); 3376 3377 spdk_blob_close(blob, blob_op_complete, NULL); 3378 blob = NULL; 3379 g_blob = NULL; 3380 g_blobid = SPDK_BLOBID_INVALID; 3381 3382 /* Mark second blob as invalid */ 3383 page_num = _spdk_bs_blobid_to_page(blobid2); 3384 3385 index = DEV_BUFFER_BLOCKLEN * (g_bs->md_start + page_num); 3386 page = (struct spdk_blob_md_page *)&g_dev_buffer[index]; 3387 page->sequence_num = 1; 3388 page->crc = _spdk_blob_md_page_calc_crc(page); 3389 3390 free_clusters = spdk_bs_free_cluster_count(g_bs); 3391 3392 /* Dirty shutdown */ 3393 _spdk_bs_free(g_bs); 3394 /* reload the blobstore */ 3395 dev = init_dev(); 3396 spdk_bs_opts_init(&opts); 3397 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3398 CU_ASSERT(g_bserrno == 0); 3399 3400 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 3401 CU_ASSERT(g_bserrno != 0); 3402 CU_ASSERT(g_blob == NULL); 3403 3404 spdk_bs_open_blob(g_bs, blobid3, blob_op_with_handle_complete, NULL); 3405 CU_ASSERT(g_bserrno == 0); 3406 CU_ASSERT(g_blob != NULL); 3407 blob = g_blob; 3408 3409 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 3410 3411 spdk_blob_close(blob, blob_op_complete, NULL); 3412 blob = NULL; 3413 g_blob = NULL; 3414 g_blobid = SPDK_BLOBID_INVALID; 3415 3416 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3417 CU_ASSERT(g_bserrno == 0); 3418 g_bs = NULL; 3419 } 3420 3421 static void 3422 blob_flags(void) 3423 { 3424 struct spdk_bs_dev *dev; 3425 spdk_blob_id blobid_invalid, blobid_data_ro, blobid_md_ro; 3426 struct spdk_blob *blob_invalid, *blob_data_ro, *blob_md_ro; 3427 struct spdk_bs_opts opts; 3428 int rc; 3429 3430 dev = init_dev(); 3431 spdk_bs_opts_init(&opts); 3432 3433 /* Initialize a new blob store */ 3434 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 3435 CU_ASSERT(g_bserrno == 0); 3436 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3437 3438 /* Create three blobs - one each for testing invalid, data_ro and md_ro flags. */ 3439 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 3440 CU_ASSERT(g_bserrno == 0); 3441 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3442 blobid_invalid = g_blobid; 3443 3444 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 3445 CU_ASSERT(g_bserrno == 0); 3446 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3447 blobid_data_ro = g_blobid; 3448 3449 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 3450 CU_ASSERT(g_bserrno == 0); 3451 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3452 blobid_md_ro = g_blobid; 3453 3454 spdk_bs_open_blob(g_bs, blobid_invalid, blob_op_with_handle_complete, NULL); 3455 CU_ASSERT(g_bserrno == 0); 3456 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3457 blob_invalid = g_blob; 3458 3459 spdk_bs_open_blob(g_bs, blobid_data_ro, blob_op_with_handle_complete, NULL); 3460 CU_ASSERT(g_bserrno == 0); 3461 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3462 blob_data_ro = g_blob; 3463 3464 spdk_bs_open_blob(g_bs, blobid_md_ro, blob_op_with_handle_complete, NULL); 3465 CU_ASSERT(g_bserrno == 0); 3466 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3467 blob_md_ro = g_blob; 3468 3469 /* Change the size of blob_data_ro to check if flags are serialized 3470 * when blob has non zero number of extents */ 3471 spdk_blob_resize(blob_data_ro, 10, blob_op_complete, NULL); 3472 CU_ASSERT(g_bserrno == 0); 3473 3474 /* Set the xattr to check if flags are serialized 3475 * when blob has non zero number of xattrs */ 3476 rc = spdk_blob_set_xattr(blob_md_ro, "name", "log.txt", strlen("log.txt") + 1); 3477 CU_ASSERT(rc == 0); 3478 3479 blob_invalid->invalid_flags = (1ULL << 63); 3480 blob_invalid->state = SPDK_BLOB_STATE_DIRTY; 3481 blob_data_ro->data_ro_flags = (1ULL << 62); 3482 blob_data_ro->state = SPDK_BLOB_STATE_DIRTY; 3483 blob_md_ro->md_ro_flags = (1ULL << 61); 3484 blob_md_ro->state = SPDK_BLOB_STATE_DIRTY; 3485 3486 g_bserrno = -1; 3487 spdk_blob_sync_md(blob_invalid, blob_op_complete, NULL); 3488 CU_ASSERT(g_bserrno == 0); 3489 g_bserrno = -1; 3490 spdk_blob_sync_md(blob_data_ro, blob_op_complete, NULL); 3491 CU_ASSERT(g_bserrno == 0); 3492 g_bserrno = -1; 3493 spdk_blob_sync_md(blob_md_ro, blob_op_complete, NULL); 3494 CU_ASSERT(g_bserrno == 0); 3495 3496 g_bserrno = -1; 3497 spdk_blob_close(blob_invalid, blob_op_complete, NULL); 3498 CU_ASSERT(g_bserrno == 0); 3499 blob_invalid = NULL; 3500 g_bserrno = -1; 3501 spdk_blob_close(blob_data_ro, blob_op_complete, NULL); 3502 CU_ASSERT(g_bserrno == 0); 3503 blob_data_ro = NULL; 3504 g_bserrno = -1; 3505 spdk_blob_close(blob_md_ro, blob_op_complete, NULL); 3506 CU_ASSERT(g_bserrno == 0); 3507 blob_md_ro = NULL; 3508 3509 g_blob = NULL; 3510 g_blobid = SPDK_BLOBID_INVALID; 3511 3512 /* Unload the blob store */ 3513 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3514 CU_ASSERT(g_bserrno == 0); 3515 g_bs = NULL; 3516 3517 /* Load an existing blob store */ 3518 dev = init_dev(); 3519 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3520 CU_ASSERT(g_bserrno == 0); 3521 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3522 3523 g_blob = NULL; 3524 g_bserrno = 0; 3525 spdk_bs_open_blob(g_bs, blobid_invalid, blob_op_with_handle_complete, NULL); 3526 CU_ASSERT(g_bserrno != 0); 3527 CU_ASSERT(g_blob == NULL); 3528 3529 g_blob = NULL; 3530 g_bserrno = -1; 3531 spdk_bs_open_blob(g_bs, blobid_data_ro, blob_op_with_handle_complete, NULL); 3532 CU_ASSERT(g_bserrno == 0); 3533 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3534 blob_data_ro = g_blob; 3535 /* If an unknown data_ro flag was found, the blob should be marked both data and md read-only. */ 3536 CU_ASSERT(blob_data_ro->data_ro == true); 3537 CU_ASSERT(blob_data_ro->md_ro == true); 3538 CU_ASSERT(spdk_blob_get_num_clusters(blob_data_ro) == 10); 3539 3540 g_blob = NULL; 3541 g_bserrno = -1; 3542 spdk_bs_open_blob(g_bs, blobid_md_ro, blob_op_with_handle_complete, NULL); 3543 CU_ASSERT(g_bserrno == 0); 3544 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3545 blob_md_ro = g_blob; 3546 CU_ASSERT(blob_md_ro->data_ro == false); 3547 CU_ASSERT(blob_md_ro->md_ro == true); 3548 3549 g_bserrno = -1; 3550 spdk_blob_sync_md(blob_md_ro, blob_op_complete, NULL); 3551 CU_ASSERT(g_bserrno == 0); 3552 3553 spdk_blob_close(blob_data_ro, blob_op_complete, NULL); 3554 CU_ASSERT(g_bserrno == 0); 3555 spdk_blob_close(blob_md_ro, blob_op_complete, NULL); 3556 CU_ASSERT(g_bserrno == 0); 3557 3558 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3559 CU_ASSERT(g_bserrno == 0); 3560 } 3561 3562 static void 3563 bs_version(void) 3564 { 3565 struct spdk_bs_super_block *super; 3566 struct spdk_bs_dev *dev; 3567 struct spdk_bs_opts opts; 3568 spdk_blob_id blobid; 3569 3570 dev = init_dev(); 3571 spdk_bs_opts_init(&opts); 3572 3573 /* Initialize a new blob store */ 3574 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 3575 CU_ASSERT(g_bserrno == 0); 3576 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3577 3578 /* Unload the blob store */ 3579 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3580 CU_ASSERT(g_bserrno == 0); 3581 g_bs = NULL; 3582 3583 /* 3584 * Change the bs version on disk. This will allow us to 3585 * test that the version does not get modified automatically 3586 * when loading and unloading the blobstore. 3587 */ 3588 super = (struct spdk_bs_super_block *)&g_dev_buffer[0]; 3589 CU_ASSERT(super->version == SPDK_BS_VERSION); 3590 CU_ASSERT(super->clean == 1); 3591 super->version = 2; 3592 /* 3593 * Version 2 metadata does not have a used blobid mask, so clear 3594 * those fields in the super block and zero the corresponding 3595 * region on "disk". We will use this to ensure blob IDs are 3596 * correctly reconstructed. 3597 */ 3598 memset(&g_dev_buffer[super->used_blobid_mask_start * SPDK_BS_PAGE_SIZE], 0, 3599 super->used_blobid_mask_len * SPDK_BS_PAGE_SIZE); 3600 super->used_blobid_mask_start = 0; 3601 super->used_blobid_mask_len = 0; 3602 super->crc = _spdk_blob_md_page_calc_crc(super); 3603 3604 /* Load an existing blob store */ 3605 dev = init_dev(); 3606 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3607 CU_ASSERT(g_bserrno == 0); 3608 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3609 CU_ASSERT(super->clean == 1); 3610 3611 /* 3612 * Create a blob - just to make sure that when we unload it 3613 * results in writing the super block (since metadata pages 3614 * were allocated. 3615 */ 3616 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 3617 CU_ASSERT(g_bserrno == 0); 3618 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3619 blobid = g_blobid; 3620 3621 /* Unload the blob store */ 3622 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3623 CU_ASSERT(g_bserrno == 0); 3624 g_bs = NULL; 3625 CU_ASSERT(super->version == 2); 3626 CU_ASSERT(super->used_blobid_mask_start == 0); 3627 CU_ASSERT(super->used_blobid_mask_len == 0); 3628 3629 dev = init_dev(); 3630 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3631 CU_ASSERT(g_bserrno == 0); 3632 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3633 3634 g_blob = NULL; 3635 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 3636 CU_ASSERT(g_bserrno == 0); 3637 CU_ASSERT(g_blob != NULL); 3638 3639 spdk_blob_close(g_blob, blob_op_complete, NULL); 3640 CU_ASSERT(g_bserrno == 0); 3641 3642 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3643 CU_ASSERT(g_bserrno == 0); 3644 g_bs = NULL; 3645 CU_ASSERT(super->version == 2); 3646 CU_ASSERT(super->used_blobid_mask_start == 0); 3647 CU_ASSERT(super->used_blobid_mask_len == 0); 3648 } 3649 3650 static void 3651 blob_set_xattrs(void) 3652 { 3653 struct spdk_blob_store *bs; 3654 struct spdk_bs_dev *dev; 3655 struct spdk_blob *blob; 3656 struct spdk_blob_opts opts; 3657 spdk_blob_id blobid; 3658 const void *value; 3659 size_t value_len; 3660 int rc; 3661 3662 dev = init_dev(); 3663 3664 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3665 CU_ASSERT(g_bserrno == 0); 3666 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3667 bs = g_bs; 3668 3669 /* Create blob with extra attributes */ 3670 spdk_blob_opts_init(&opts); 3671 3672 opts.xattrs.names = g_xattr_names; 3673 opts.xattrs.get_value = _get_xattr_value; 3674 opts.xattrs.count = 3; 3675 opts.xattrs.ctx = &g_ctx; 3676 3677 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 3678 CU_ASSERT(g_bserrno == 0); 3679 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3680 blobid = g_blobid; 3681 3682 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3683 CU_ASSERT(g_bserrno == 0); 3684 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3685 blob = g_blob; 3686 3687 /* Get the xattrs */ 3688 value = NULL; 3689 3690 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[0], &value, &value_len); 3691 CU_ASSERT(rc == 0); 3692 SPDK_CU_ASSERT_FATAL(value != NULL); 3693 CU_ASSERT(value_len == strlen(g_xattr_values[0])); 3694 CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len); 3695 3696 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[1], &value, &value_len); 3697 CU_ASSERT(rc == 0); 3698 SPDK_CU_ASSERT_FATAL(value != NULL); 3699 CU_ASSERT(value_len == strlen(g_xattr_values[1])); 3700 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len); 3701 3702 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[2], &value, &value_len); 3703 CU_ASSERT(rc == 0); 3704 SPDK_CU_ASSERT_FATAL(value != NULL); 3705 CU_ASSERT(value_len == strlen(g_xattr_values[2])); 3706 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len); 3707 3708 /* Try to get non existing attribute */ 3709 3710 rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len); 3711 CU_ASSERT(rc == -ENOENT); 3712 3713 spdk_blob_close(blob, blob_op_complete, NULL); 3714 CU_ASSERT(g_bserrno == 0); 3715 blob = NULL; 3716 g_blob = NULL; 3717 g_blobid = SPDK_BLOBID_INVALID; 3718 3719 /* NULL callback */ 3720 spdk_blob_opts_init(&opts); 3721 opts.xattrs.names = g_xattr_names; 3722 opts.xattrs.get_value = NULL; 3723 opts.xattrs.count = 1; 3724 opts.xattrs.ctx = &g_ctx; 3725 3726 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 3727 CU_ASSERT(g_bserrno == -EINVAL); 3728 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3729 3730 /* NULL values */ 3731 spdk_blob_opts_init(&opts); 3732 opts.xattrs.names = g_xattr_names; 3733 opts.xattrs.get_value = _get_xattr_value_null; 3734 opts.xattrs.count = 1; 3735 opts.xattrs.ctx = NULL; 3736 3737 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 3738 CU_ASSERT(g_bserrno == -EINVAL); 3739 3740 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3741 CU_ASSERT(g_bserrno == 0); 3742 g_bs = NULL; 3743 3744 } 3745 3746 static void 3747 blob_thin_prov_alloc(void) 3748 { 3749 struct spdk_blob_store *bs; 3750 struct spdk_bs_dev *dev; 3751 struct spdk_blob *blob; 3752 struct spdk_blob_opts opts; 3753 spdk_blob_id blobid; 3754 uint64_t free_clusters; 3755 3756 dev = init_dev(); 3757 3758 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3759 CU_ASSERT(g_bserrno == 0); 3760 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3761 bs = g_bs; 3762 free_clusters = spdk_bs_free_cluster_count(bs); 3763 3764 /* Set blob as thin provisioned */ 3765 spdk_blob_opts_init(&opts); 3766 opts.thin_provision = true; 3767 3768 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 3769 CU_ASSERT(g_bserrno == 0); 3770 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3771 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3772 blobid = g_blobid; 3773 3774 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3775 CU_ASSERT(g_bserrno == 0); 3776 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3777 blob = g_blob; 3778 3779 CU_ASSERT(blob->active.num_clusters == 0); 3780 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0); 3781 3782 /* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */ 3783 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 3784 CU_ASSERT(g_bserrno == 0); 3785 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3786 CU_ASSERT(blob->active.num_clusters == 5); 3787 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 3788 3789 /* Grow it to 1TB - still unallocated */ 3790 spdk_blob_resize(blob, 262144, blob_op_complete, NULL); 3791 CU_ASSERT(g_bserrno == 0); 3792 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3793 CU_ASSERT(blob->active.num_clusters == 262144); 3794 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 262144); 3795 3796 spdk_blob_sync_md(blob, blob_op_complete, NULL); 3797 CU_ASSERT(g_bserrno == 0); 3798 /* Sync must not change anything */ 3799 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3800 CU_ASSERT(blob->active.num_clusters == 262144); 3801 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 262144); 3802 /* Since clusters are not allocated, 3803 * number of metadata pages is expected to be minimal. 3804 */ 3805 CU_ASSERT(blob->active.num_pages == 1); 3806 3807 /* Shrink the blob to 3 clusters - still unallocated */ 3808 spdk_blob_resize(blob, 3, blob_op_complete, NULL); 3809 CU_ASSERT(g_bserrno == 0); 3810 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3811 CU_ASSERT(blob->active.num_clusters == 3); 3812 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 3); 3813 3814 spdk_blob_sync_md(blob, blob_op_complete, NULL); 3815 CU_ASSERT(g_bserrno == 0); 3816 /* Sync must not change anything */ 3817 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3818 CU_ASSERT(blob->active.num_clusters == 3); 3819 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 3); 3820 3821 spdk_blob_close(blob, blob_op_complete, NULL); 3822 CU_ASSERT(g_bserrno == 0); 3823 3824 /* Unload the blob store */ 3825 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3826 CU_ASSERT(g_bserrno == 0); 3827 g_bs = NULL; 3828 g_blob = NULL; 3829 g_blobid = 0; 3830 3831 /* Load an existing blob store */ 3832 dev = init_dev(); 3833 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 3834 CU_ASSERT(g_bserrno == 0); 3835 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3836 3837 bs = g_bs; 3838 3839 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 3840 CU_ASSERT(g_bserrno == 0); 3841 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3842 blob = g_blob; 3843 3844 /* Check that clusters allocation and size is still the same */ 3845 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3846 CU_ASSERT(blob->active.num_clusters == 3); 3847 3848 spdk_blob_close(blob, blob_op_complete, NULL); 3849 CU_ASSERT(g_bserrno == 0); 3850 3851 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 3852 CU_ASSERT(g_bserrno == 0); 3853 3854 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3855 CU_ASSERT(g_bserrno == 0); 3856 g_bs = NULL; 3857 } 3858 3859 static void 3860 blob_insert_cluster_msg(void) 3861 { 3862 struct spdk_blob_store *bs; 3863 struct spdk_bs_dev *dev; 3864 struct spdk_blob *blob; 3865 struct spdk_blob_opts opts; 3866 spdk_blob_id blobid; 3867 uint64_t free_clusters; 3868 3869 dev = init_dev(); 3870 3871 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3872 CU_ASSERT(g_bserrno == 0); 3873 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3874 bs = g_bs; 3875 free_clusters = spdk_bs_free_cluster_count(bs); 3876 3877 /* Set blob as thin provisioned */ 3878 spdk_blob_opts_init(&opts); 3879 opts.thin_provision = true; 3880 opts.num_clusters = 4; 3881 3882 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 3883 CU_ASSERT(g_bserrno == 0); 3884 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3885 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3886 blobid = g_blobid; 3887 3888 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3889 CU_ASSERT(g_bserrno == 0); 3890 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3891 blob = g_blob; 3892 3893 CU_ASSERT(blob->active.num_clusters == 4); 3894 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 4); 3895 CU_ASSERT(blob->active.clusters[1] == 0); 3896 3897 _spdk_bs_claim_cluster(bs, 0xF); 3898 _spdk_blob_insert_cluster_on_md_thread(blob, 1, 0xF, blob_op_complete, NULL); 3899 3900 CU_ASSERT(blob->active.clusters[1] != 0); 3901 3902 spdk_blob_close(blob, blob_op_complete, NULL); 3903 CU_ASSERT(g_bserrno == 0); 3904 3905 /* Unload the blob store */ 3906 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3907 CU_ASSERT(g_bserrno == 0); 3908 g_bs = NULL; 3909 g_blob = NULL; 3910 g_blobid = 0; 3911 3912 /* Load an existing blob store */ 3913 dev = init_dev(); 3914 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 3915 CU_ASSERT(g_bserrno == 0); 3916 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3917 3918 bs = g_bs; 3919 3920 spdk_bs_open_blob(g_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(blob->active.clusters[1] != 0); 3926 3927 spdk_blob_close(blob, blob_op_complete, NULL); 3928 CU_ASSERT(g_bserrno == 0); 3929 3930 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 3931 CU_ASSERT(g_bserrno == 0); 3932 3933 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3934 CU_ASSERT(g_bserrno == 0); 3935 g_bs = NULL; 3936 } 3937 3938 static void 3939 blob_thin_prov_rw(void) 3940 { 3941 static const uint8_t zero[10 * 4096] = { 0 }; 3942 struct spdk_blob_store *bs; 3943 struct spdk_bs_dev *dev; 3944 struct spdk_blob *blob; 3945 struct spdk_io_channel *channel; 3946 struct spdk_blob_opts opts; 3947 spdk_blob_id blobid; 3948 uint64_t free_clusters; 3949 uint64_t page_size; 3950 uint8_t payload_read[10 * 4096]; 3951 uint8_t payload_write[10 * 4096]; 3952 uint64_t write_bytes; 3953 uint64_t read_bytes; 3954 3955 dev = init_dev(); 3956 3957 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3958 CU_ASSERT(g_bserrno == 0); 3959 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3960 bs = g_bs; 3961 free_clusters = spdk_bs_free_cluster_count(bs); 3962 page_size = spdk_bs_get_page_size(bs); 3963 3964 channel = spdk_bs_alloc_io_channel(bs); 3965 CU_ASSERT(channel != NULL); 3966 3967 spdk_blob_opts_init(&opts); 3968 opts.thin_provision = true; 3969 3970 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 3971 CU_ASSERT(g_bserrno == 0); 3972 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3973 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3974 blobid = g_blobid; 3975 3976 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3977 CU_ASSERT(g_bserrno == 0); 3978 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3979 blob = g_blob; 3980 3981 CU_ASSERT(blob->active.num_clusters == 0); 3982 3983 /* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */ 3984 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 3985 CU_ASSERT(g_bserrno == 0); 3986 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3987 CU_ASSERT(blob->active.num_clusters == 5); 3988 3989 spdk_blob_sync_md(blob, blob_op_complete, NULL); 3990 CU_ASSERT(g_bserrno == 0); 3991 /* Sync must not change anything */ 3992 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3993 CU_ASSERT(blob->active.num_clusters == 5); 3994 3995 /* Payload should be all zeros from unallocated clusters */ 3996 memset(payload_read, 0xFF, sizeof(payload_read)); 3997 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 3998 CU_ASSERT(g_bserrno == 0); 3999 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 4000 4001 write_bytes = g_dev_write_bytes; 4002 read_bytes = g_dev_read_bytes; 4003 4004 memset(payload_write, 0xE5, sizeof(payload_write)); 4005 spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL); 4006 CU_ASSERT(g_bserrno == 0); 4007 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 4008 /* For thin-provisioned blob we need to write 10 pages plus one page metadata and 4009 * read 0 bytes */ 4010 CU_ASSERT(g_dev_write_bytes - write_bytes == page_size * 11); 4011 CU_ASSERT(g_dev_read_bytes - read_bytes == 0); 4012 4013 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 4014 CU_ASSERT(g_bserrno == 0); 4015 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 4016 4017 spdk_blob_close(blob, blob_op_complete, NULL); 4018 CU_ASSERT(g_bserrno == 0); 4019 4020 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 4021 CU_ASSERT(g_bserrno == 0); 4022 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4023 4024 spdk_bs_free_io_channel(channel); 4025 4026 /* Unload the blob store */ 4027 spdk_bs_unload(g_bs, bs_op_complete, NULL); 4028 CU_ASSERT(g_bserrno == 0); 4029 g_bs = NULL; 4030 g_blob = NULL; 4031 g_blobid = 0; 4032 } 4033 4034 static void 4035 blob_thin_prov_rw_iov(void) 4036 { 4037 static const uint8_t zero[10 * 4096] = { 0 }; 4038 struct spdk_blob_store *bs; 4039 struct spdk_bs_dev *dev; 4040 struct spdk_blob *blob; 4041 struct spdk_io_channel *channel; 4042 struct spdk_blob_opts opts; 4043 spdk_blob_id blobid; 4044 uint64_t free_clusters; 4045 uint8_t payload_read[10 * 4096]; 4046 uint8_t payload_write[10 * 4096]; 4047 struct iovec iov_read[3]; 4048 struct iovec iov_write[3]; 4049 4050 dev = init_dev(); 4051 4052 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 4053 CU_ASSERT(g_bserrno == 0); 4054 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4055 bs = g_bs; 4056 free_clusters = spdk_bs_free_cluster_count(bs); 4057 4058 channel = spdk_bs_alloc_io_channel(bs); 4059 CU_ASSERT(channel != NULL); 4060 4061 spdk_blob_opts_init(&opts); 4062 opts.thin_provision = true; 4063 4064 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 4065 CU_ASSERT(g_bserrno == 0); 4066 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4067 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4068 blobid = g_blobid; 4069 4070 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4071 CU_ASSERT(g_bserrno == 0); 4072 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4073 blob = g_blob; 4074 4075 CU_ASSERT(blob->active.num_clusters == 0); 4076 4077 /* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */ 4078 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 4079 CU_ASSERT(g_bserrno == 0); 4080 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4081 CU_ASSERT(blob->active.num_clusters == 5); 4082 4083 spdk_blob_sync_md(blob, blob_op_complete, NULL); 4084 CU_ASSERT(g_bserrno == 0); 4085 /* Sync must not change anything */ 4086 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4087 CU_ASSERT(blob->active.num_clusters == 5); 4088 4089 /* Payload should be all zeros from unallocated clusters */ 4090 memset(payload_read, 0xAA, sizeof(payload_read)); 4091 iov_read[0].iov_base = payload_read; 4092 iov_read[0].iov_len = 3 * 4096; 4093 iov_read[1].iov_base = payload_read + 3 * 4096; 4094 iov_read[1].iov_len = 4 * 4096; 4095 iov_read[2].iov_base = payload_read + 7 * 4096; 4096 iov_read[2].iov_len = 3 * 4096; 4097 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 4098 CU_ASSERT(g_bserrno == 0); 4099 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 4100 4101 memset(payload_write, 0xE5, sizeof(payload_write)); 4102 iov_write[0].iov_base = payload_write; 4103 iov_write[0].iov_len = 1 * 4096; 4104 iov_write[1].iov_base = payload_write + 1 * 4096; 4105 iov_write[1].iov_len = 5 * 4096; 4106 iov_write[2].iov_base = payload_write + 6 * 4096; 4107 iov_write[2].iov_len = 4 * 4096; 4108 4109 spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 4110 CU_ASSERT(g_bserrno == 0); 4111 4112 memset(payload_read, 0xAA, sizeof(payload_read)); 4113 iov_read[0].iov_base = payload_read; 4114 iov_read[0].iov_len = 3 * 4096; 4115 iov_read[1].iov_base = payload_read + 3 * 4096; 4116 iov_read[1].iov_len = 4 * 4096; 4117 iov_read[2].iov_base = payload_read + 7 * 4096; 4118 iov_read[2].iov_len = 3 * 4096; 4119 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 4120 CU_ASSERT(g_bserrno == 0); 4121 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 4122 4123 spdk_blob_close(blob, blob_op_complete, NULL); 4124 CU_ASSERT(g_bserrno == 0); 4125 4126 spdk_bs_free_io_channel(channel); 4127 4128 /* Unload the blob store */ 4129 spdk_bs_unload(g_bs, bs_op_complete, NULL); 4130 CU_ASSERT(g_bserrno == 0); 4131 g_bs = NULL; 4132 g_blob = NULL; 4133 g_blobid = 0; 4134 } 4135 4136 struct iter_ctx { 4137 int current_iter; 4138 spdk_blob_id blobid[4]; 4139 }; 4140 4141 static void 4142 test_iter(void *arg, struct spdk_blob *blob, int bserrno) 4143 { 4144 struct iter_ctx *iter_ctx = arg; 4145 spdk_blob_id blobid; 4146 4147 CU_ASSERT(bserrno == 0); 4148 blobid = spdk_blob_get_id(blob); 4149 CU_ASSERT(blobid == iter_ctx->blobid[iter_ctx->current_iter++]); 4150 } 4151 4152 static void 4153 bs_load_iter(void) 4154 { 4155 struct spdk_bs_dev *dev; 4156 struct iter_ctx iter_ctx = { 0 }; 4157 struct spdk_blob *blob; 4158 int i, rc; 4159 struct spdk_bs_opts opts; 4160 4161 dev = init_dev(); 4162 spdk_bs_opts_init(&opts); 4163 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 4164 4165 /* Initialize a new blob store */ 4166 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 4167 CU_ASSERT(g_bserrno == 0); 4168 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4169 4170 for (i = 0; i < 4; i++) { 4171 g_bserrno = -1; 4172 g_blobid = SPDK_BLOBID_INVALID; 4173 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 4174 CU_ASSERT(g_bserrno == 0); 4175 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4176 iter_ctx.blobid[i] = g_blobid; 4177 4178 g_bserrno = -1; 4179 g_blob = NULL; 4180 spdk_bs_open_blob(g_bs, g_blobid, blob_op_with_handle_complete, NULL); 4181 CU_ASSERT(g_bserrno == 0); 4182 CU_ASSERT(g_blob != NULL); 4183 blob = g_blob; 4184 4185 /* Just save the blobid as an xattr for testing purposes. */ 4186 rc = spdk_blob_set_xattr(blob, "blobid", &g_blobid, sizeof(g_blobid)); 4187 CU_ASSERT(rc == 0); 4188 4189 /* Resize the blob */ 4190 spdk_blob_resize(blob, i, blob_op_complete, NULL); 4191 CU_ASSERT(g_bserrno == 0); 4192 4193 spdk_blob_close(blob, blob_op_complete, NULL); 4194 CU_ASSERT(g_bserrno == 0); 4195 } 4196 4197 g_bserrno = -1; 4198 spdk_bs_unload(g_bs, bs_op_complete, NULL); 4199 CU_ASSERT(g_bserrno == 0); 4200 4201 dev = init_dev(); 4202 spdk_bs_opts_init(&opts); 4203 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 4204 opts.iter_cb_fn = test_iter; 4205 opts.iter_cb_arg = &iter_ctx; 4206 4207 /* Test blob iteration during load after a clean shutdown. */ 4208 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 4209 CU_ASSERT(g_bserrno == 0); 4210 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4211 4212 /* Dirty shutdown */ 4213 _spdk_bs_free(g_bs); 4214 4215 dev = init_dev(); 4216 spdk_bs_opts_init(&opts); 4217 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 4218 opts.iter_cb_fn = test_iter; 4219 iter_ctx.current_iter = 0; 4220 opts.iter_cb_arg = &iter_ctx; 4221 4222 /* Test blob iteration during load after a dirty shutdown. */ 4223 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 4224 CU_ASSERT(g_bserrno == 0); 4225 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4226 4227 spdk_bs_unload(g_bs, bs_op_complete, NULL); 4228 CU_ASSERT(g_bserrno == 0); 4229 g_bs = NULL; 4230 } 4231 4232 static void 4233 blob_snapshot_rw(void) 4234 { 4235 static const uint8_t zero[10 * 4096] = { 0 }; 4236 struct spdk_blob_store *bs; 4237 struct spdk_bs_dev *dev; 4238 struct spdk_blob *blob, *snapshot; 4239 struct spdk_io_channel *channel; 4240 struct spdk_blob_opts opts; 4241 spdk_blob_id blobid, snapshotid; 4242 uint64_t free_clusters; 4243 uint64_t cluster_size; 4244 uint64_t page_size; 4245 uint8_t payload_read[10 * 4096]; 4246 uint8_t payload_write[10 * 4096]; 4247 uint64_t write_bytes; 4248 uint64_t read_bytes; 4249 4250 dev = init_dev(); 4251 4252 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 4253 CU_ASSERT(g_bserrno == 0); 4254 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4255 bs = g_bs; 4256 free_clusters = spdk_bs_free_cluster_count(bs); 4257 cluster_size = spdk_bs_get_cluster_size(bs); 4258 page_size = spdk_bs_get_page_size(bs); 4259 4260 channel = spdk_bs_alloc_io_channel(bs); 4261 CU_ASSERT(channel != NULL); 4262 4263 spdk_blob_opts_init(&opts); 4264 opts.thin_provision = true; 4265 opts.num_clusters = 5; 4266 4267 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 4268 CU_ASSERT(g_bserrno == 0); 4269 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4270 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4271 blobid = g_blobid; 4272 4273 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4274 CU_ASSERT(g_bserrno == 0); 4275 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4276 blob = g_blob; 4277 4278 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 4279 4280 memset(payload_read, 0xFF, sizeof(payload_read)); 4281 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 4282 CU_ASSERT(g_bserrno == 0); 4283 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 4284 4285 memset(payload_write, 0xE5, sizeof(payload_write)); 4286 spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL); 4287 CU_ASSERT(g_bserrno == 0); 4288 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 4289 4290 /* Create snapshot from blob */ 4291 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 4292 CU_ASSERT(g_bserrno == 0); 4293 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4294 snapshotid = g_blobid; 4295 4296 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 4297 CU_ASSERT(g_bserrno == 0); 4298 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4299 snapshot = g_blob; 4300 CU_ASSERT(snapshot->data_ro == true) 4301 CU_ASSERT(snapshot->md_ro == true) 4302 4303 CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 5) 4304 4305 write_bytes = g_dev_write_bytes; 4306 read_bytes = g_dev_read_bytes; 4307 4308 memset(payload_write, 0xAA, sizeof(payload_write)); 4309 spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL); 4310 CU_ASSERT(g_bserrno == 0); 4311 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 4312 4313 /* For a clone we need to allocate and copy one cluster, update one page of metadata 4314 * and then write 10 pages of payload. 4315 */ 4316 CU_ASSERT(g_dev_write_bytes - write_bytes == page_size * 11 + cluster_size); 4317 CU_ASSERT(g_dev_read_bytes - read_bytes == cluster_size); 4318 4319 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 4320 CU_ASSERT(g_bserrno == 0); 4321 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 4322 4323 /* Data on snapshot should not change after write to clone */ 4324 memset(payload_write, 0xE5, sizeof(payload_write)); 4325 spdk_blob_io_read(snapshot, channel, payload_read, 4, 10, blob_op_complete, NULL); 4326 CU_ASSERT(g_bserrno == 0); 4327 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 4328 4329 spdk_blob_close(blob, blob_op_complete, NULL); 4330 CU_ASSERT(g_bserrno == 0); 4331 4332 spdk_blob_close(snapshot, blob_op_complete, NULL); 4333 CU_ASSERT(g_bserrno == 0); 4334 4335 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 4336 CU_ASSERT(g_bserrno == 0); 4337 4338 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 4339 CU_ASSERT(g_bserrno == 0); 4340 4341 spdk_bs_free_io_channel(channel); 4342 4343 /* Unload the blob store */ 4344 spdk_bs_unload(g_bs, bs_op_complete, NULL); 4345 CU_ASSERT(g_bserrno == 0); 4346 g_bs = NULL; 4347 g_blob = NULL; 4348 g_blobid = 0; 4349 } 4350 4351 static void 4352 blob_snapshot_rw_iov(void) 4353 { 4354 static const uint8_t zero[10 * 4096] = { 0 }; 4355 struct spdk_blob_store *bs; 4356 struct spdk_bs_dev *dev; 4357 struct spdk_blob *blob, *snapshot; 4358 struct spdk_io_channel *channel; 4359 struct spdk_blob_opts opts; 4360 spdk_blob_id blobid, snapshotid; 4361 uint64_t free_clusters; 4362 uint8_t payload_read[10 * 4096]; 4363 uint8_t payload_write[10 * 4096]; 4364 struct iovec iov_read[3]; 4365 struct iovec iov_write[3]; 4366 4367 dev = init_dev(); 4368 4369 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 4370 CU_ASSERT(g_bserrno == 0); 4371 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4372 bs = g_bs; 4373 free_clusters = spdk_bs_free_cluster_count(bs); 4374 4375 channel = spdk_bs_alloc_io_channel(bs); 4376 CU_ASSERT(channel != NULL); 4377 4378 spdk_blob_opts_init(&opts); 4379 opts.thin_provision = true; 4380 opts.num_clusters = 5; 4381 4382 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 4383 CU_ASSERT(g_bserrno == 0); 4384 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4385 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4386 blobid = g_blobid; 4387 4388 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4389 CU_ASSERT(g_bserrno == 0); 4390 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4391 blob = g_blob; 4392 4393 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 4394 4395 /* Create snapshot from blob */ 4396 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 4397 CU_ASSERT(g_bserrno == 0); 4398 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4399 snapshotid = g_blobid; 4400 4401 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 4402 CU_ASSERT(g_bserrno == 0); 4403 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4404 snapshot = g_blob; 4405 CU_ASSERT(snapshot->data_ro == true) 4406 CU_ASSERT(snapshot->md_ro == true) 4407 CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 5); 4408 4409 /* Payload should be all zeros from unallocated clusters */ 4410 memset(payload_read, 0xAA, sizeof(payload_read)); 4411 iov_read[0].iov_base = payload_read; 4412 iov_read[0].iov_len = 3 * 4096; 4413 iov_read[1].iov_base = payload_read + 3 * 4096; 4414 iov_read[1].iov_len = 4 * 4096; 4415 iov_read[2].iov_base = payload_read + 7 * 4096; 4416 iov_read[2].iov_len = 3 * 4096; 4417 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 4418 CU_ASSERT(g_bserrno == 0); 4419 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 4420 4421 memset(payload_write, 0xE5, sizeof(payload_write)); 4422 iov_write[0].iov_base = payload_write; 4423 iov_write[0].iov_len = 1 * 4096; 4424 iov_write[1].iov_base = payload_write + 1 * 4096; 4425 iov_write[1].iov_len = 5 * 4096; 4426 iov_write[2].iov_base = payload_write + 6 * 4096; 4427 iov_write[2].iov_len = 4 * 4096; 4428 4429 spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 4430 CU_ASSERT(g_bserrno == 0); 4431 4432 memset(payload_read, 0xAA, sizeof(payload_read)); 4433 iov_read[0].iov_base = payload_read; 4434 iov_read[0].iov_len = 3 * 4096; 4435 iov_read[1].iov_base = payload_read + 3 * 4096; 4436 iov_read[1].iov_len = 4 * 4096; 4437 iov_read[2].iov_base = payload_read + 7 * 4096; 4438 iov_read[2].iov_len = 3 * 4096; 4439 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 4440 CU_ASSERT(g_bserrno == 0); 4441 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 4442 4443 spdk_blob_close(blob, blob_op_complete, NULL); 4444 CU_ASSERT(g_bserrno == 0); 4445 4446 spdk_blob_close(snapshot, blob_op_complete, NULL); 4447 CU_ASSERT(g_bserrno == 0); 4448 4449 spdk_bs_free_io_channel(channel); 4450 4451 /* Unload the blob store */ 4452 spdk_bs_unload(g_bs, bs_op_complete, NULL); 4453 CU_ASSERT(g_bserrno == 0); 4454 g_bs = NULL; 4455 g_blob = NULL; 4456 g_blobid = 0; 4457 } 4458 4459 /** 4460 * Inflate / decouple parent rw unit tests. 4461 * 4462 * -------------- 4463 * original blob: 0 1 2 3 4 4464 * ,---------+---------+---------+---------+---------. 4465 * snapshot |xxxxxxxxx|xxxxxxxxx|xxxxxxxxx|xxxxxxxxx| - | 4466 * +---------+---------+---------+---------+---------+ 4467 * snapshot2 | - |yyyyyyyyy| - |yyyyyyyyy| - | 4468 * +---------+---------+---------+---------+---------+ 4469 * blob | - |zzzzzzzzz| - | - | - | 4470 * '---------+---------+---------+---------+---------' 4471 * . . . . . . 4472 * -------- . . . . . . 4473 * inflate: . . . . . . 4474 * ,---------+---------+---------+---------+---------. 4475 * blob |xxxxxxxxx|zzzzzzzzz|xxxxxxxxx|yyyyyyyyy|000000000| 4476 * '---------+---------+---------+---------+---------' 4477 * 4478 * NOTE: needs to allocate 4 clusters, thin provisioning removed, dependency 4479 * on snapshot2 and snapshot removed . . . 4480 * . . . . . . 4481 * ---------------- . . . . . . 4482 * decouple parent: . . . . . . 4483 * ,---------+---------+---------+---------+---------. 4484 * snapshot |xxxxxxxxx|xxxxxxxxx|xxxxxxxxx|xxxxxxxxx| - | 4485 * +---------+---------+---------+---------+---------+ 4486 * blob | - |zzzzzzzzz| - |yyyyyyyyy| - | 4487 * '---------+---------+---------+---------+---------' 4488 * 4489 * NOTE: needs to allocate 1 cluster, 3 clusters unallocated, dependency 4490 * on snapshot2 removed and on snapshot still exists. Snapshot2 4491 * should remain a clone of snapshot. 4492 */ 4493 static void 4494 _blob_inflate_rw(bool decouple_parent) 4495 { 4496 struct spdk_blob_store *bs; 4497 struct spdk_bs_dev *dev; 4498 struct spdk_blob *blob, *snapshot, *snapshot2; 4499 struct spdk_io_channel *channel; 4500 struct spdk_blob_opts opts; 4501 spdk_blob_id blobid, snapshotid, snapshot2id; 4502 uint64_t free_clusters; 4503 uint64_t cluster_size; 4504 4505 uint64_t payload_size; 4506 uint8_t *payload_read; 4507 uint8_t *payload_write; 4508 uint8_t *payload_clone; 4509 4510 uint64_t pages_per_cluster; 4511 uint64_t pages_per_payload; 4512 4513 int i; 4514 spdk_blob_id ids[2]; 4515 size_t count; 4516 4517 dev = init_dev(); 4518 4519 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 4520 CU_ASSERT(g_bserrno == 0); 4521 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4522 bs = g_bs; 4523 4524 free_clusters = spdk_bs_free_cluster_count(bs); 4525 cluster_size = spdk_bs_get_cluster_size(bs); 4526 pages_per_cluster = cluster_size / spdk_bs_get_page_size(bs); 4527 pages_per_payload = pages_per_cluster * 5; 4528 4529 payload_size = cluster_size * 5; 4530 4531 payload_read = malloc(payload_size); 4532 SPDK_CU_ASSERT_FATAL(payload_read != NULL); 4533 4534 payload_write = malloc(payload_size); 4535 SPDK_CU_ASSERT_FATAL(payload_write != NULL); 4536 4537 payload_clone = malloc(payload_size); 4538 SPDK_CU_ASSERT_FATAL(payload_clone != NULL); 4539 4540 channel = spdk_bs_alloc_io_channel(bs); 4541 SPDK_CU_ASSERT_FATAL(channel != NULL); 4542 4543 /* Create blob */ 4544 spdk_blob_opts_init(&opts); 4545 opts.thin_provision = true; 4546 opts.num_clusters = 5; 4547 4548 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 4549 CU_ASSERT(g_bserrno == 0); 4550 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4551 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4552 blobid = g_blobid; 4553 4554 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4555 CU_ASSERT(g_bserrno == 0); 4556 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4557 blob = g_blob; 4558 4559 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 4560 4561 /* 1) Initial read should return zeroed payload */ 4562 memset(payload_read, 0xFF, payload_size); 4563 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, 4564 blob_op_complete, NULL); 4565 CU_ASSERT(g_bserrno == 0); 4566 CU_ASSERT(spdk_mem_all_zero(payload_read, payload_size)); 4567 4568 /* Fill whole blob with a pattern, except last cluster (to be sure it 4569 * isn't allocated) */ 4570 memset(payload_write, 0xE5, payload_size - cluster_size); 4571 spdk_blob_io_write(blob, channel, payload_write, 0, pages_per_payload - 4572 pages_per_cluster, blob_op_complete, NULL); 4573 CU_ASSERT(g_bserrno == 0); 4574 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 4575 4576 /* 2) Create snapshot from blob (first level) */ 4577 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 4578 CU_ASSERT(g_bserrno == 0); 4579 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4580 snapshotid = g_blobid; 4581 4582 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 4583 CU_ASSERT(g_bserrno == 0); 4584 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4585 snapshot = g_blob; 4586 CU_ASSERT(snapshot->data_ro == true) 4587 CU_ASSERT(snapshot->md_ro == true) 4588 4589 CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 5) 4590 4591 /* Write every second cluster with a pattern. 4592 * 4593 * Last cluster shouldn't be written, to be sure that snapshot nor clone 4594 * doesn't allocate it. 4595 * 4596 * payload_clone stores expected result on "blob" read at the time and 4597 * is used only to check data consistency on clone before and after 4598 * inflation. Initially we fill it with a backing snapshots pattern 4599 * used before. 4600 */ 4601 memset(payload_clone, 0xE5, payload_size - cluster_size); 4602 memset(payload_clone + payload_size - cluster_size, 0x00, cluster_size); 4603 memset(payload_write, 0xAA, payload_size); 4604 for (i = 1; i < 5; i += 2) { 4605 spdk_blob_io_write(blob, channel, payload_write, i * pages_per_cluster, 4606 pages_per_cluster, blob_op_complete, NULL); 4607 CU_ASSERT(g_bserrno == 0); 4608 4609 /* Update expected result */ 4610 memcpy(payload_clone + (cluster_size * i), payload_write, 4611 cluster_size); 4612 } 4613 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 4614 4615 /* Check data consistency on clone */ 4616 memset(payload_read, 0xFF, payload_size); 4617 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, 4618 blob_op_complete, NULL); 4619 CU_ASSERT(g_bserrno == 0); 4620 CU_ASSERT(memcmp(payload_clone, payload_read, payload_size) == 0); 4621 4622 /* 3) Create second levels snapshot from blob */ 4623 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 4624 CU_ASSERT(g_bserrno == 0); 4625 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4626 snapshot2id = g_blobid; 4627 4628 spdk_bs_open_blob(bs, snapshot2id, blob_op_with_handle_complete, NULL); 4629 CU_ASSERT(g_bserrno == 0); 4630 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4631 snapshot2 = g_blob; 4632 CU_ASSERT(snapshot2->data_ro == true) 4633 CU_ASSERT(snapshot2->md_ro == true) 4634 4635 CU_ASSERT(spdk_blob_get_num_clusters(snapshot2) == 5) 4636 4637 CU_ASSERT(snapshot2->parent_id == snapshotid); 4638 4639 /* Write one cluster on the top level blob. This cluster (1) covers 4640 * already allocated cluster in the snapshot2, so shouldn't be inflated 4641 * at all */ 4642 spdk_blob_io_write(blob, channel, payload_write, pages_per_cluster, 4643 pages_per_cluster, blob_op_complete, NULL); 4644 CU_ASSERT(g_bserrno == 0); 4645 4646 /* Update expected result */ 4647 memcpy(payload_clone + cluster_size, payload_write, cluster_size); 4648 4649 /* Check data consistency on clone */ 4650 memset(payload_read, 0xFF, payload_size); 4651 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, 4652 blob_op_complete, NULL); 4653 CU_ASSERT(g_bserrno == 0); 4654 CU_ASSERT(memcmp(payload_clone, payload_read, payload_size) == 0); 4655 4656 4657 /* Close all blobs */ 4658 spdk_blob_close(blob, blob_op_complete, NULL); 4659 CU_ASSERT(g_bserrno == 0); 4660 4661 spdk_blob_close(snapshot2, blob_op_complete, NULL); 4662 CU_ASSERT(g_bserrno == 0); 4663 4664 spdk_blob_close(snapshot, blob_op_complete, NULL); 4665 CU_ASSERT(g_bserrno == 0); 4666 4667 /* Check snapshot-clone relations */ 4668 count = 2; 4669 CU_ASSERT(spdk_blob_get_clones(bs, snapshotid, ids, &count) == 0); 4670 CU_ASSERT(count == 1); 4671 CU_ASSERT(ids[0] == snapshot2id); 4672 4673 count = 2; 4674 CU_ASSERT(spdk_blob_get_clones(bs, snapshot2id, ids, &count) == 0); 4675 CU_ASSERT(count == 1); 4676 CU_ASSERT(ids[0] == blobid); 4677 4678 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshot2id); 4679 4680 free_clusters = spdk_bs_free_cluster_count(bs); 4681 if (!decouple_parent) { 4682 /* Do full blob inflation */ 4683 spdk_bs_inflate_blob(bs, channel, blobid, blob_op_complete, NULL); 4684 CU_ASSERT(g_bserrno == 0); 4685 4686 /* All clusters should be inflated (except one already allocated 4687 * in a top level blob) */ 4688 CU_ASSERT(spdk_bs_free_cluster_count(bs) == free_clusters - 4); 4689 4690 /* Check if relation tree updated correctly */ 4691 count = 2; 4692 CU_ASSERT(spdk_blob_get_clones(bs, snapshotid, ids, &count) == 0); 4693 4694 /* snapshotid have one clone */ 4695 CU_ASSERT(count == 1); 4696 CU_ASSERT(ids[0] == snapshot2id); 4697 4698 /* snapshot2id have no clones */ 4699 count = 2; 4700 CU_ASSERT(spdk_blob_get_clones(bs, snapshot2id, ids, &count) == 0); 4701 CU_ASSERT(count == 0); 4702 4703 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == SPDK_BLOBID_INVALID); 4704 } else { 4705 /* Decouple parent of blob */ 4706 spdk_bs_blob_decouple_parent(bs, channel, blobid, blob_op_complete, NULL); 4707 CU_ASSERT(g_bserrno == 0); 4708 4709 /* Only one cluster from a parent should be inflated (second one 4710 * is covered by a cluster written on a top level blob, and 4711 * already allocated) */ 4712 CU_ASSERT(spdk_bs_free_cluster_count(bs) == free_clusters - 1); 4713 4714 /* Check if relation tree updated correctly */ 4715 count = 2; 4716 CU_ASSERT(spdk_blob_get_clones(bs, snapshotid, ids, &count) == 0); 4717 4718 /* snapshotid have two clones now */ 4719 CU_ASSERT(count == 2); 4720 CU_ASSERT(ids[0] == blobid || ids[1] == blobid); 4721 CU_ASSERT(ids[0] == snapshot2id || ids[1] == snapshot2id); 4722 4723 /* snapshot2id have no clones */ 4724 count = 2; 4725 CU_ASSERT(spdk_blob_get_clones(bs, snapshot2id, ids, &count) == 0); 4726 CU_ASSERT(count == 0); 4727 4728 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid); 4729 } 4730 4731 /* Try to delete snapshot2 (should pass) */ 4732 spdk_bs_delete_blob(bs, snapshot2id, blob_op_complete, NULL); 4733 CU_ASSERT(g_bserrno == 0); 4734 4735 /* Try to delete base snapshot (for decouple_parent should fail while 4736 * dependency still exists) */ 4737 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 4738 CU_ASSERT(decouple_parent || g_bserrno == 0); 4739 CU_ASSERT(!decouple_parent || g_bserrno != 0); 4740 4741 /* Reopen blob after snapshot deletion */ 4742 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4743 CU_ASSERT(g_bserrno == 0); 4744 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4745 blob = g_blob; 4746 4747 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 4748 4749 /* Check data consistency on inflated blob */ 4750 memset(payload_read, 0xFF, payload_size); 4751 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, 4752 blob_op_complete, NULL); 4753 CU_ASSERT(g_bserrno == 0); 4754 CU_ASSERT(memcmp(payload_clone, payload_read, payload_size) == 0); 4755 4756 spdk_blob_close(blob, blob_op_complete, NULL); 4757 CU_ASSERT(g_bserrno == 0); 4758 4759 spdk_bs_free_io_channel(channel); 4760 4761 /* Unload the blob store */ 4762 spdk_bs_unload(g_bs, bs_op_complete, NULL); 4763 CU_ASSERT(g_bserrno == 0); 4764 g_bs = NULL; 4765 g_blob = NULL; 4766 g_blobid = 0; 4767 4768 free(payload_read); 4769 free(payload_write); 4770 free(payload_clone); 4771 } 4772 4773 static void 4774 blob_inflate_rw(void) 4775 { 4776 _blob_inflate_rw(false); 4777 _blob_inflate_rw(true); 4778 } 4779 4780 /** 4781 * Snapshot-clones relation test 4782 * 4783 * snapshot 4784 * | 4785 * +-----+-----+ 4786 * | | 4787 * blob(ro) snapshot2 4788 * | | 4789 * clone2 clone 4790 */ 4791 static void 4792 blob_relations(void) 4793 { 4794 struct spdk_blob_store *bs; 4795 struct spdk_bs_dev *dev; 4796 struct spdk_bs_opts bs_opts; 4797 struct spdk_blob_opts opts; 4798 struct spdk_blob *blob, *snapshot, *snapshot2, *clone, *clone2; 4799 spdk_blob_id blobid, cloneid, snapshotid, cloneid2, snapshotid2; 4800 int rc; 4801 size_t count; 4802 spdk_blob_id ids[10] = {}; 4803 4804 dev = init_dev(); 4805 spdk_bs_opts_init(&bs_opts); 4806 snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE"); 4807 4808 spdk_bs_init(dev, &bs_opts, bs_op_with_handle_complete, NULL); 4809 CU_ASSERT(g_bserrno == 0); 4810 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4811 bs = g_bs; 4812 4813 /* 1. Create blob with 10 clusters */ 4814 4815 spdk_blob_opts_init(&opts); 4816 opts.num_clusters = 10; 4817 4818 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 4819 CU_ASSERT(g_bserrno == 0); 4820 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4821 blobid = g_blobid; 4822 4823 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4824 CU_ASSERT(g_bserrno == 0); 4825 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4826 blob = g_blob; 4827 4828 CU_ASSERT(!spdk_blob_is_read_only(blob)); 4829 CU_ASSERT(!spdk_blob_is_snapshot(blob)); 4830 CU_ASSERT(!spdk_blob_is_clone(blob)); 4831 CU_ASSERT(!spdk_blob_is_thin_provisioned(blob)); 4832 4833 /* blob should not have underlying snapshot nor clones */ 4834 CU_ASSERT(blob->parent_id == SPDK_BLOBID_INVALID); 4835 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == SPDK_BLOBID_INVALID); 4836 count = SPDK_COUNTOF(ids); 4837 rc = spdk_blob_get_clones(bs, blobid, ids, &count); 4838 CU_ASSERT(rc == 0); 4839 CU_ASSERT(count == 0); 4840 4841 4842 /* 2. Create snapshot */ 4843 4844 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 4845 CU_ASSERT(g_bserrno == 0); 4846 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4847 snapshotid = g_blobid; 4848 4849 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 4850 CU_ASSERT(g_bserrno == 0); 4851 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4852 snapshot = g_blob; 4853 4854 CU_ASSERT(spdk_blob_is_read_only(snapshot)); 4855 CU_ASSERT(spdk_blob_is_snapshot(snapshot)); 4856 CU_ASSERT(!spdk_blob_is_clone(snapshot)); 4857 CU_ASSERT(snapshot->parent_id == SPDK_BLOBID_INVALID); 4858 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid) == SPDK_BLOBID_INVALID); 4859 4860 /* Check if original blob is converted to the clone of snapshot */ 4861 CU_ASSERT(!spdk_blob_is_read_only(blob)); 4862 CU_ASSERT(!spdk_blob_is_snapshot(blob)); 4863 CU_ASSERT(spdk_blob_is_clone(blob)); 4864 CU_ASSERT(spdk_blob_is_thin_provisioned(blob)); 4865 CU_ASSERT(blob->parent_id == snapshotid); 4866 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid); 4867 4868 count = SPDK_COUNTOF(ids); 4869 rc = spdk_blob_get_clones(bs, snapshotid, ids, &count); 4870 CU_ASSERT(rc == 0); 4871 CU_ASSERT(count == 1); 4872 CU_ASSERT(ids[0] == blobid); 4873 4874 4875 /* 3. Create clone from snapshot */ 4876 4877 spdk_bs_create_clone(bs, snapshotid, NULL, blob_op_with_id_complete, NULL); 4878 CU_ASSERT(g_bserrno == 0); 4879 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4880 cloneid = g_blobid; 4881 4882 spdk_bs_open_blob(bs, cloneid, blob_op_with_handle_complete, NULL); 4883 CU_ASSERT(g_bserrno == 0); 4884 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4885 clone = g_blob; 4886 4887 CU_ASSERT(!spdk_blob_is_read_only(clone)); 4888 CU_ASSERT(!spdk_blob_is_snapshot(clone)); 4889 CU_ASSERT(spdk_blob_is_clone(clone)); 4890 CU_ASSERT(spdk_blob_is_thin_provisioned(clone)); 4891 CU_ASSERT(clone->parent_id == snapshotid); 4892 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid); 4893 4894 count = SPDK_COUNTOF(ids); 4895 rc = spdk_blob_get_clones(bs, cloneid, ids, &count); 4896 CU_ASSERT(rc == 0); 4897 CU_ASSERT(count == 0); 4898 4899 /* Check if clone is on the snapshot's list */ 4900 count = SPDK_COUNTOF(ids); 4901 rc = spdk_blob_get_clones(bs, snapshotid, ids, &count); 4902 CU_ASSERT(rc == 0); 4903 CU_ASSERT(ids[0] == blobid || ids[1] == blobid); 4904 CU_ASSERT(ids[0] == cloneid || ids[1] == cloneid); 4905 4906 4907 /* 4. Create snapshot of the clone */ 4908 4909 spdk_bs_create_snapshot(bs, cloneid, NULL, blob_op_with_id_complete, NULL); 4910 CU_ASSERT(g_bserrno == 0); 4911 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4912 snapshotid2 = g_blobid; 4913 4914 spdk_bs_open_blob(bs, snapshotid2, blob_op_with_handle_complete, NULL); 4915 CU_ASSERT(g_bserrno == 0); 4916 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4917 snapshot2 = g_blob; 4918 4919 CU_ASSERT(spdk_blob_is_read_only(snapshot2)); 4920 CU_ASSERT(spdk_blob_is_snapshot(snapshot2)); 4921 CU_ASSERT(spdk_blob_is_clone(snapshot2)); 4922 CU_ASSERT(snapshot2->parent_id == snapshotid); 4923 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid2) == snapshotid); 4924 4925 /* Check if clone is converted to the clone of snapshot2 and snapshot2 4926 * is a child of snapshot */ 4927 CU_ASSERT(!spdk_blob_is_read_only(clone)); 4928 CU_ASSERT(!spdk_blob_is_snapshot(clone)); 4929 CU_ASSERT(spdk_blob_is_clone(clone)); 4930 CU_ASSERT(spdk_blob_is_thin_provisioned(clone)); 4931 CU_ASSERT(clone->parent_id == snapshotid2); 4932 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid2); 4933 4934 count = SPDK_COUNTOF(ids); 4935 rc = spdk_blob_get_clones(bs, snapshotid2, ids, &count); 4936 CU_ASSERT(rc == 0); 4937 CU_ASSERT(count == 1); 4938 CU_ASSERT(ids[0] == cloneid); 4939 4940 4941 /* 5. Try to create clone from read only blob */ 4942 4943 /* Mark blob as read only */ 4944 spdk_blob_set_read_only(blob); 4945 spdk_blob_sync_md(blob, blob_op_complete, NULL); 4946 CU_ASSERT(g_bserrno == 0); 4947 4948 /* Check if previously created blob is read only clone */ 4949 CU_ASSERT(spdk_blob_is_read_only(blob)); 4950 CU_ASSERT(!spdk_blob_is_snapshot(blob)); 4951 CU_ASSERT(spdk_blob_is_clone(blob)); 4952 CU_ASSERT(spdk_blob_is_thin_provisioned(blob)); 4953 4954 /* Create clone from read only blob */ 4955 spdk_bs_create_clone(bs, blobid, NULL, blob_op_with_id_complete, NULL); 4956 CU_ASSERT(g_bserrno == 0); 4957 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4958 cloneid2 = g_blobid; 4959 4960 spdk_bs_open_blob(bs, cloneid2, blob_op_with_handle_complete, NULL); 4961 CU_ASSERT(g_bserrno == 0); 4962 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4963 clone2 = g_blob; 4964 4965 CU_ASSERT(!spdk_blob_is_read_only(clone2)); 4966 CU_ASSERT(!spdk_blob_is_snapshot(clone2)); 4967 CU_ASSERT(spdk_blob_is_clone(clone2)); 4968 CU_ASSERT(spdk_blob_is_thin_provisioned(clone2)); 4969 4970 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid2) == blobid); 4971 4972 count = SPDK_COUNTOF(ids); 4973 rc = spdk_blob_get_clones(bs, blobid, ids, &count); 4974 CU_ASSERT(rc == 0); 4975 4976 CU_ASSERT(count == 1); 4977 CU_ASSERT(ids[0] == cloneid2); 4978 4979 /* Close blobs */ 4980 4981 spdk_blob_close(clone2, blob_op_complete, NULL); 4982 CU_ASSERT(g_bserrno == 0); 4983 4984 spdk_blob_close(blob, blob_op_complete, NULL); 4985 CU_ASSERT(g_bserrno == 0); 4986 4987 spdk_blob_close(clone, blob_op_complete, NULL); 4988 CU_ASSERT(g_bserrno == 0); 4989 4990 spdk_blob_close(snapshot, blob_op_complete, NULL); 4991 CU_ASSERT(g_bserrno == 0); 4992 4993 spdk_blob_close(snapshot2, blob_op_complete, NULL); 4994 CU_ASSERT(g_bserrno == 0); 4995 4996 /* Try to delete snapshot with created clones */ 4997 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 4998 CU_ASSERT(g_bserrno != 0); 4999 5000 spdk_bs_delete_blob(bs, snapshotid2, blob_op_complete, NULL); 5001 CU_ASSERT(g_bserrno != 0); 5002 5003 spdk_bs_unload(bs, bs_op_complete, NULL); 5004 CU_ASSERT(g_bserrno == 0); 5005 g_bs = NULL; 5006 5007 /* Load an existing blob store */ 5008 dev = init_dev(); 5009 snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE"); 5010 5011 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 5012 CU_ASSERT(g_bserrno == 0); 5013 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 5014 bs = g_bs; 5015 5016 5017 /* NULL ids array should return number of clones in count */ 5018 count = SPDK_COUNTOF(ids); 5019 rc = spdk_blob_get_clones(bs, snapshotid, NULL, &count); 5020 CU_ASSERT(rc == -ENOMEM); 5021 CU_ASSERT(count == 2); 5022 5023 /* incorrect array size */ 5024 count = 1; 5025 rc = spdk_blob_get_clones(bs, snapshotid, ids, &count); 5026 CU_ASSERT(rc == -ENOMEM); 5027 CU_ASSERT(count == 2); 5028 5029 5030 /* Verify structure of loaded blob store */ 5031 5032 /* snapshot */ 5033 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid) == SPDK_BLOBID_INVALID); 5034 5035 count = SPDK_COUNTOF(ids); 5036 rc = spdk_blob_get_clones(bs, snapshotid, ids, &count); 5037 CU_ASSERT(rc == 0); 5038 CU_ASSERT(count == 2); 5039 CU_ASSERT(ids[0] == blobid || ids[1] == blobid); 5040 CU_ASSERT(ids[0] == snapshotid2 || ids[1] == snapshotid2); 5041 5042 /* blob */ 5043 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid); 5044 count = SPDK_COUNTOF(ids); 5045 rc = spdk_blob_get_clones(bs, blobid, ids, &count); 5046 CU_ASSERT(rc == 0); 5047 CU_ASSERT(count == 1); 5048 CU_ASSERT(ids[0] == cloneid2); 5049 5050 /* clone */ 5051 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid2); 5052 count = SPDK_COUNTOF(ids); 5053 rc = spdk_blob_get_clones(bs, cloneid, ids, &count); 5054 CU_ASSERT(rc == 0); 5055 CU_ASSERT(count == 0); 5056 5057 /* snapshot2 */ 5058 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid2) == snapshotid); 5059 count = SPDK_COUNTOF(ids); 5060 rc = spdk_blob_get_clones(bs, snapshotid2, ids, &count); 5061 CU_ASSERT(rc == 0); 5062 CU_ASSERT(count == 1); 5063 CU_ASSERT(ids[0] == cloneid); 5064 5065 /* clone2 */ 5066 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid2) == blobid); 5067 count = SPDK_COUNTOF(ids); 5068 rc = spdk_blob_get_clones(bs, cloneid2, ids, &count); 5069 CU_ASSERT(rc == 0); 5070 CU_ASSERT(count == 0); 5071 5072 /* Try to delete all blobs in the worse possible order */ 5073 5074 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 5075 CU_ASSERT(g_bserrno != 0); 5076 5077 spdk_bs_delete_blob(bs, snapshotid2, blob_op_complete, NULL); 5078 CU_ASSERT(g_bserrno != 0); 5079 5080 spdk_bs_delete_blob(bs, cloneid, blob_op_complete, NULL); 5081 CU_ASSERT(g_bserrno == 0); 5082 5083 spdk_bs_delete_blob(bs, snapshotid2, blob_op_complete, NULL); 5084 CU_ASSERT(g_bserrno == 0); 5085 5086 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 5087 CU_ASSERT(g_bserrno != 0); 5088 5089 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 5090 CU_ASSERT(g_bserrno != 0); 5091 5092 spdk_bs_delete_blob(bs, cloneid2, blob_op_complete, NULL); 5093 CU_ASSERT(g_bserrno == 0); 5094 5095 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 5096 CU_ASSERT(g_bserrno == 0); 5097 5098 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 5099 CU_ASSERT(g_bserrno == 0); 5100 5101 spdk_bs_unload(bs, bs_op_complete, NULL); 5102 CU_ASSERT(g_bserrno == 0); 5103 5104 g_bs = NULL; 5105 } 5106 5107 int main(int argc, char **argv) 5108 { 5109 CU_pSuite suite = NULL; 5110 unsigned int num_failures; 5111 5112 if (CU_initialize_registry() != CUE_SUCCESS) { 5113 return CU_get_error(); 5114 } 5115 5116 suite = CU_add_suite("blob", NULL, NULL); 5117 if (suite == NULL) { 5118 CU_cleanup_registry(); 5119 return CU_get_error(); 5120 } 5121 5122 if ( 5123 CU_add_test(suite, "blob_init", blob_init) == NULL || 5124 CU_add_test(suite, "blob_open", blob_open) == NULL || 5125 CU_add_test(suite, "blob_create", blob_create) == NULL || 5126 CU_add_test(suite, "blob_create_internal", blob_create_internal) == NULL || 5127 CU_add_test(suite, "blob_thin_provision", blob_thin_provision) == NULL || 5128 CU_add_test(suite, "blob_snapshot", blob_snapshot) == NULL || 5129 CU_add_test(suite, "blob_clone", blob_clone) == NULL || 5130 CU_add_test(suite, "blob_inflate", blob_inflate) == NULL || 5131 CU_add_test(suite, "blob_delete", blob_delete) == NULL || 5132 CU_add_test(suite, "blob_resize", blob_resize) == NULL || 5133 CU_add_test(suite, "blob_read_only", blob_read_only) == NULL || 5134 CU_add_test(suite, "channel_ops", channel_ops) == NULL || 5135 CU_add_test(suite, "blob_super", blob_super) == NULL || 5136 CU_add_test(suite, "blob_write", blob_write) == NULL || 5137 CU_add_test(suite, "blob_read", blob_read) == NULL || 5138 CU_add_test(suite, "blob_rw_verify", blob_rw_verify) == NULL || 5139 CU_add_test(suite, "blob_rw_verify_iov", blob_rw_verify_iov) == NULL || 5140 CU_add_test(suite, "blob_rw_verify_iov_nomem", blob_rw_verify_iov_nomem) == NULL || 5141 CU_add_test(suite, "blob_rw_iov_read_only", blob_rw_iov_read_only) == NULL || 5142 CU_add_test(suite, "blob_unmap", blob_unmap) == NULL || 5143 CU_add_test(suite, "blob_iter", blob_iter) == NULL || 5144 CU_add_test(suite, "blob_xattr", blob_xattr) == NULL || 5145 CU_add_test(suite, "bs_load", bs_load) == NULL || 5146 CU_add_test(suite, "bs_load_custom_cluster_size", bs_load_custom_cluster_size) == NULL || 5147 CU_add_test(suite, "bs_unload", bs_unload) == NULL || 5148 CU_add_test(suite, "bs_cluster_sz", bs_cluster_sz) == NULL || 5149 CU_add_test(suite, "bs_usable_clusters", bs_usable_clusters) == NULL || 5150 CU_add_test(suite, "bs_resize_md", bs_resize_md) == NULL || 5151 CU_add_test(suite, "bs_destroy", bs_destroy) == NULL || 5152 CU_add_test(suite, "bs_type", bs_type) == NULL || 5153 CU_add_test(suite, "bs_super_block", bs_super_block) == NULL || 5154 CU_add_test(suite, "blob_serialize", blob_serialize) == NULL || 5155 CU_add_test(suite, "blob_crc", blob_crc) == NULL || 5156 CU_add_test(suite, "super_block_crc", super_block_crc) == NULL || 5157 CU_add_test(suite, "blob_dirty_shutdown", blob_dirty_shutdown) == NULL || 5158 CU_add_test(suite, "blob_flags", blob_flags) == NULL || 5159 CU_add_test(suite, "bs_version", bs_version) == NULL || 5160 CU_add_test(suite, "blob_set_xattrs", blob_set_xattrs) == NULL || 5161 CU_add_test(suite, "blob_thin_prov_alloc", blob_thin_prov_alloc) == NULL || 5162 CU_add_test(suite, "blob_insert_cluster_msg", blob_insert_cluster_msg) == NULL || 5163 CU_add_test(suite, "blob_thin_prov_rw", blob_thin_prov_rw) == NULL || 5164 CU_add_test(suite, "blob_thin_prov_rw_iov", blob_thin_prov_rw_iov) == NULL || 5165 CU_add_test(suite, "bs_load_iter", bs_load_iter) == NULL || 5166 CU_add_test(suite, "blob_snapshot_rw", blob_snapshot_rw) == NULL || 5167 CU_add_test(suite, "blob_snapshot_rw_iov", blob_snapshot_rw_iov) == NULL || 5168 CU_add_test(suite, "blob_relations", blob_relations) == NULL || 5169 CU_add_test(suite, "blob_inflate_rw", blob_inflate_rw) == NULL || 5170 CU_add_test(suite, "blob_snapshot_freeze_io", blob_snapshot_freeze_io) == NULL || 5171 CU_add_test(suite, "blob_operation_split_rw", blob_operation_split_rw) == NULL || 5172 CU_add_test(suite, "blob_operation_split_rw_iov", blob_operation_split_rw_iov) == NULL 5173 ) { 5174 CU_cleanup_registry(); 5175 return CU_get_error(); 5176 } 5177 5178 g_dev_buffer = calloc(1, DEV_BUFFER_SIZE); 5179 spdk_allocate_thread(_bs_send_msg, NULL, NULL, NULL, "thread0"); 5180 CU_basic_set_mode(CU_BRM_VERBOSE); 5181 CU_basic_run_tests(); 5182 num_failures = CU_get_number_of_failures(); 5183 CU_cleanup_registry(); 5184 spdk_free_thread(); 5185 free(g_dev_buffer); 5186 return num_failures; 5187 } 5188