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 #include "spdk_internal/thread.h" 40 41 #include "common/lib/test_env.c" 42 #include "../bs_dev_common.c" 43 #include "blob/blobstore.c" 44 #include "blob/request.c" 45 #include "blob/zeroes.c" 46 #include "blob/blob_bs_dev.c" 47 48 struct spdk_blob_store *g_bs; 49 spdk_blob_id g_blobid; 50 struct spdk_blob *g_blob; 51 int g_bserrno; 52 struct spdk_xattr_names *g_names; 53 int g_done; 54 char *g_xattr_names[] = {"first", "second", "third"}; 55 char *g_xattr_values[] = {"one", "two", "three"}; 56 uint64_t g_ctx = 1729; 57 58 struct spdk_bs_super_block_ver1 { 59 uint8_t signature[8]; 60 uint32_t version; 61 uint32_t length; 62 uint32_t clean; /* If there was a clean shutdown, this is 1. */ 63 spdk_blob_id super_blob; 64 65 uint32_t cluster_size; /* In bytes */ 66 67 uint32_t used_page_mask_start; /* Offset from beginning of disk, in pages */ 68 uint32_t used_page_mask_len; /* Count, in pages */ 69 70 uint32_t used_cluster_mask_start; /* Offset from beginning of disk, in pages */ 71 uint32_t used_cluster_mask_len; /* Count, in pages */ 72 73 uint32_t md_start; /* Offset from beginning of disk, in pages */ 74 uint32_t md_len; /* Count, in pages */ 75 76 uint8_t reserved[4036]; 77 uint32_t crc; 78 } __attribute__((packed)); 79 SPDK_STATIC_ASSERT(sizeof(struct spdk_bs_super_block_ver1) == 0x1000, "Invalid super block size"); 80 81 82 static void 83 _get_xattr_value(void *arg, const char *name, 84 const void **value, size_t *value_len) 85 { 86 uint64_t i; 87 88 SPDK_CU_ASSERT_FATAL(value_len != NULL); 89 SPDK_CU_ASSERT_FATAL(value != NULL); 90 CU_ASSERT(arg == &g_ctx) 91 92 for (i = 0; i < sizeof(g_xattr_names); i++) { 93 if (!strcmp(name, g_xattr_names[i])) { 94 *value_len = strlen(g_xattr_values[i]); 95 *value = g_xattr_values[i]; 96 break; 97 } 98 } 99 } 100 101 static void 102 _get_xattr_value_null(void *arg, const char *name, 103 const void **value, size_t *value_len) 104 { 105 SPDK_CU_ASSERT_FATAL(value_len != NULL); 106 SPDK_CU_ASSERT_FATAL(value != NULL); 107 CU_ASSERT(arg == NULL) 108 109 *value_len = 0; 110 *value = NULL; 111 } 112 113 static int 114 _get_snapshots_count(struct spdk_blob_store *bs) 115 { 116 struct spdk_blob_list *snapshot = NULL; 117 int count = 0; 118 119 TAILQ_FOREACH(snapshot, &bs->snapshots, link) { 120 count += 1; 121 } 122 123 return count; 124 } 125 126 static void 127 bs_op_complete(void *cb_arg, int bserrno) 128 { 129 g_bserrno = bserrno; 130 } 131 132 static void 133 bs_op_with_handle_complete(void *cb_arg, struct spdk_blob_store *bs, 134 int bserrno) 135 { 136 g_bs = bs; 137 g_bserrno = bserrno; 138 } 139 140 static void 141 blob_op_complete(void *cb_arg, int bserrno) 142 { 143 g_bserrno = bserrno; 144 } 145 146 static void 147 blob_op_with_id_complete(void *cb_arg, spdk_blob_id blobid, int bserrno) 148 { 149 g_blobid = blobid; 150 g_bserrno = bserrno; 151 } 152 153 static void 154 blob_op_with_handle_complete(void *cb_arg, struct spdk_blob *blb, int bserrno) 155 { 156 g_blob = blb; 157 g_bserrno = bserrno; 158 } 159 160 static void 161 blob_init(void) 162 { 163 struct spdk_bs_dev *dev; 164 165 dev = init_dev(); 166 167 /* should fail for an unsupported blocklen */ 168 dev->blocklen = 500; 169 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 170 CU_ASSERT(g_bserrno == -EINVAL); 171 172 dev = init_dev(); 173 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 174 CU_ASSERT(g_bserrno == 0); 175 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 176 177 spdk_bs_unload(g_bs, bs_op_complete, NULL); 178 CU_ASSERT(g_bserrno == 0); 179 g_bs = NULL; 180 } 181 182 static void 183 blob_super(void) 184 { 185 struct spdk_blob_store *bs; 186 struct spdk_bs_dev *dev; 187 spdk_blob_id blobid; 188 189 dev = init_dev(); 190 191 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 192 CU_ASSERT(g_bserrno == 0); 193 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 194 bs = g_bs; 195 196 /* Get the super blob without having set one */ 197 spdk_bs_get_super(bs, blob_op_with_id_complete, NULL); 198 CU_ASSERT(g_bserrno == -ENOENT); 199 CU_ASSERT(g_blobid == SPDK_BLOBID_INVALID); 200 201 /* Create a blob */ 202 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 203 CU_ASSERT(g_bserrno == 0); 204 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 205 blobid = g_blobid; 206 207 /* Set the blob as the super blob */ 208 spdk_bs_set_super(bs, blobid, blob_op_complete, NULL); 209 CU_ASSERT(g_bserrno == 0); 210 211 /* Get the super blob */ 212 spdk_bs_get_super(bs, blob_op_with_id_complete, NULL); 213 CU_ASSERT(g_bserrno == 0); 214 CU_ASSERT(blobid == g_blobid); 215 216 spdk_bs_unload(g_bs, bs_op_complete, NULL); 217 CU_ASSERT(g_bserrno == 0); 218 g_bs = NULL; 219 } 220 221 static void 222 blob_open(void) 223 { 224 struct spdk_blob_store *bs; 225 struct spdk_bs_dev *dev; 226 struct spdk_blob *blob; 227 spdk_blob_id blobid, blobid2; 228 229 dev = init_dev(); 230 231 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 232 CU_ASSERT(g_bserrno == 0); 233 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 234 bs = g_bs; 235 236 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 237 CU_ASSERT(g_bserrno == 0); 238 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 239 blobid = g_blobid; 240 241 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 242 CU_ASSERT(g_bserrno == 0); 243 CU_ASSERT(g_blob != NULL); 244 blob = g_blob; 245 246 blobid2 = spdk_blob_get_id(blob); 247 CU_ASSERT(blobid == blobid2); 248 249 /* Try to open file again. It should return success. */ 250 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 251 CU_ASSERT(g_bserrno == 0); 252 CU_ASSERT(blob == g_blob); 253 254 spdk_blob_close(blob, blob_op_complete, NULL); 255 CU_ASSERT(g_bserrno == 0); 256 257 /* 258 * Close the file a second time, releasing the second reference. This 259 * should succeed. 260 */ 261 blob = g_blob; 262 spdk_blob_close(blob, blob_op_complete, NULL); 263 CU_ASSERT(g_bserrno == 0); 264 265 /* 266 * Try to open file again. It should succeed. This tests the case 267 * where the file is opened, closed, then re-opened again. 268 */ 269 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 270 CU_ASSERT(g_bserrno == 0); 271 CU_ASSERT(g_blob != NULL); 272 blob = g_blob; 273 274 spdk_blob_close(blob, blob_op_complete, NULL); 275 CU_ASSERT(g_bserrno == 0); 276 277 spdk_bs_unload(g_bs, bs_op_complete, NULL); 278 CU_ASSERT(g_bserrno == 0); 279 g_bs = NULL; 280 } 281 282 static void 283 blob_create(void) 284 { 285 struct spdk_blob_store *bs; 286 struct spdk_bs_dev *dev; 287 struct spdk_blob *blob; 288 struct spdk_blob_opts opts; 289 spdk_blob_id blobid; 290 291 dev = init_dev(); 292 293 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 294 CU_ASSERT(g_bserrno == 0); 295 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 296 bs = g_bs; 297 298 /* Create blob with 10 clusters */ 299 300 spdk_blob_opts_init(&opts); 301 opts.num_clusters = 10; 302 303 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 304 CU_ASSERT(g_bserrno == 0); 305 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 306 blobid = g_blobid; 307 308 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 309 CU_ASSERT(g_bserrno == 0); 310 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 311 blob = g_blob; 312 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10) 313 314 spdk_blob_close(blob, blob_op_complete, NULL); 315 CU_ASSERT(g_bserrno == 0); 316 317 /* Create blob with 0 clusters */ 318 319 spdk_blob_opts_init(&opts); 320 opts.num_clusters = 0; 321 322 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 323 CU_ASSERT(g_bserrno == 0); 324 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 325 blobid = g_blobid; 326 327 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 328 CU_ASSERT(g_bserrno == 0); 329 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 330 blob = g_blob; 331 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0) 332 333 spdk_blob_close(blob, blob_op_complete, NULL); 334 CU_ASSERT(g_bserrno == 0); 335 336 /* Create blob with default options (opts == NULL) */ 337 338 spdk_bs_create_blob_ext(bs, NULL, blob_op_with_id_complete, NULL); 339 CU_ASSERT(g_bserrno == 0); 340 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 341 blobid = g_blobid; 342 343 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 344 CU_ASSERT(g_bserrno == 0); 345 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 346 blob = g_blob; 347 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0) 348 349 spdk_blob_close(blob, blob_op_complete, NULL); 350 CU_ASSERT(g_bserrno == 0); 351 352 /* Try to create blob with size larger than blobstore */ 353 354 spdk_blob_opts_init(&opts); 355 opts.num_clusters = bs->total_clusters + 1; 356 357 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 358 CU_ASSERT(g_bserrno == -ENOSPC); 359 360 spdk_bs_unload(g_bs, bs_op_complete, NULL); 361 CU_ASSERT(g_bserrno == 0); 362 g_bs = NULL; 363 364 } 365 366 static void 367 blob_create_internal(void) 368 { 369 struct spdk_blob_store *bs; 370 struct spdk_bs_dev *dev; 371 struct spdk_blob *blob; 372 struct spdk_blob_opts opts; 373 struct spdk_blob_xattr_opts internal_xattrs; 374 const void *value; 375 size_t value_len; 376 spdk_blob_id blobid; 377 int rc; 378 379 dev = init_dev(); 380 381 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 382 CU_ASSERT(g_bserrno == 0); 383 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 384 bs = g_bs; 385 386 /* Create blob with custom xattrs */ 387 388 spdk_blob_opts_init(&opts); 389 _spdk_blob_xattrs_init(&internal_xattrs); 390 internal_xattrs.count = 3; 391 internal_xattrs.names = g_xattr_names; 392 internal_xattrs.get_value = _get_xattr_value; 393 internal_xattrs.ctx = &g_ctx; 394 395 _spdk_bs_create_blob(bs, &opts, &internal_xattrs, blob_op_with_id_complete, NULL); 396 CU_ASSERT(g_bserrno == 0); 397 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 398 blobid = g_blobid; 399 400 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 401 CU_ASSERT(g_bserrno == 0); 402 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 403 blob = g_blob; 404 405 rc = _spdk_blob_get_xattr_value(blob, g_xattr_names[0], &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[0])); 409 CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len); 410 411 rc = _spdk_blob_get_xattr_value(blob, g_xattr_names[1], &value, &value_len, true); 412 CU_ASSERT(rc == 0); 413 SPDK_CU_ASSERT_FATAL(value != NULL); 414 CU_ASSERT(value_len == strlen(g_xattr_values[1])); 415 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len); 416 417 rc = _spdk_blob_get_xattr_value(blob, g_xattr_names[2], &value, &value_len, true); 418 CU_ASSERT(rc == 0); 419 SPDK_CU_ASSERT_FATAL(value != NULL); 420 CU_ASSERT(value_len == strlen(g_xattr_values[2])); 421 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len); 422 423 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[0], &value, &value_len); 424 CU_ASSERT(rc != 0); 425 426 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[1], &value, &value_len); 427 CU_ASSERT(rc != 0); 428 429 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[2], &value, &value_len); 430 CU_ASSERT(rc != 0); 431 432 spdk_blob_close(blob, blob_op_complete, NULL); 433 CU_ASSERT(g_bserrno == 0); 434 435 /* Create blob with NULL internal options */ 436 437 _spdk_bs_create_blob(bs, NULL, NULL, blob_op_with_id_complete, NULL); 438 CU_ASSERT(g_bserrno == 0); 439 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 440 blobid = g_blobid; 441 442 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 443 CU_ASSERT(g_bserrno == 0); 444 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 445 CU_ASSERT(TAILQ_FIRST(&g_blob->xattrs_internal) == NULL); 446 447 blob = g_blob; 448 449 spdk_blob_close(blob, blob_op_complete, NULL); 450 CU_ASSERT(g_bserrno == 0); 451 452 spdk_bs_unload(g_bs, bs_op_complete, NULL); 453 CU_ASSERT(g_bserrno == 0); 454 g_bs = NULL; 455 456 } 457 458 static void 459 blob_thin_provision(void) 460 { 461 struct spdk_blob_store *bs; 462 struct spdk_bs_dev *dev; 463 struct spdk_blob *blob; 464 struct spdk_blob_opts opts; 465 struct spdk_bs_opts bs_opts; 466 spdk_blob_id blobid; 467 468 dev = init_dev(); 469 spdk_bs_opts_init(&bs_opts); 470 snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE"); 471 472 /* Initialize a new blob store */ 473 spdk_bs_init(dev, &bs_opts, bs_op_with_handle_complete, NULL); 474 CU_ASSERT(g_bserrno == 0); 475 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 476 477 bs = g_bs; 478 479 /* Create blob with thin provisioning enabled */ 480 481 spdk_blob_opts_init(&opts); 482 opts.thin_provision = true; 483 opts.num_clusters = 10; 484 485 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 486 CU_ASSERT(g_bserrno == 0); 487 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 488 blobid = g_blobid; 489 490 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 491 CU_ASSERT(g_bserrno == 0); 492 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 493 blob = g_blob; 494 CU_ASSERT(blob->invalid_flags & SPDK_BLOB_THIN_PROV); 495 496 spdk_blob_close(blob, blob_op_complete, NULL); 497 CU_ASSERT(g_bserrno == 0); 498 499 /* Do not shut down cleanly. This makes sure that when we load again 500 * and try to recover a valid used_cluster map, that blobstore will 501 * ignore clusters with index 0 since these are unallocated clusters. 502 */ 503 504 /* Load an existing blob store and check if invalid_flags is set */ 505 dev = init_dev(); 506 snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE"); 507 spdk_bs_load(dev, &bs_opts, bs_op_with_handle_complete, NULL); 508 CU_ASSERT(g_bserrno == 0); 509 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 510 511 bs = g_bs; 512 513 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 514 CU_ASSERT(g_bserrno == 0); 515 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 516 blob = g_blob; 517 CU_ASSERT(blob->invalid_flags & SPDK_BLOB_THIN_PROV); 518 519 spdk_blob_close(blob, blob_op_complete, NULL); 520 CU_ASSERT(g_bserrno == 0); 521 522 spdk_bs_unload(g_bs, bs_op_complete, NULL); 523 CU_ASSERT(g_bserrno == 0); 524 g_bs = NULL; 525 } 526 527 static void 528 blob_snapshot(void) 529 { 530 struct spdk_blob_store *bs; 531 struct spdk_bs_dev *dev; 532 struct spdk_blob *blob; 533 struct spdk_blob *snapshot, *snapshot2; 534 struct spdk_blob_bs_dev *blob_bs_dev; 535 struct spdk_blob_opts opts; 536 struct spdk_blob_xattr_opts xattrs; 537 spdk_blob_id blobid; 538 spdk_blob_id snapshotid; 539 spdk_blob_id snapshotid2; 540 const void *value; 541 size_t value_len; 542 int rc; 543 544 dev = init_dev(); 545 546 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 547 CU_ASSERT(g_bserrno == 0); 548 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 549 bs = g_bs; 550 551 /* Create blob with 10 clusters */ 552 spdk_blob_opts_init(&opts); 553 opts.num_clusters = 10; 554 555 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 556 CU_ASSERT(g_bserrno == 0); 557 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 558 blobid = g_blobid; 559 560 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 561 CU_ASSERT(g_bserrno == 0); 562 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 563 blob = g_blob; 564 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10) 565 566 /* Create snapshot from blob */ 567 CU_ASSERT_EQUAL(_get_snapshots_count(bs), 0); 568 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 569 CU_ASSERT(g_bserrno == 0); 570 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 571 CU_ASSERT_EQUAL(_get_snapshots_count(bs), 1); 572 snapshotid = g_blobid; 573 574 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 575 CU_ASSERT(g_bserrno == 0); 576 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 577 snapshot = g_blob; 578 CU_ASSERT(snapshot->data_ro == true) 579 CU_ASSERT(snapshot->md_ro == true) 580 CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 10) 581 582 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10) 583 CU_ASSERT(blob->invalid_flags & SPDK_BLOB_THIN_PROV); 584 CU_ASSERT(spdk_mem_all_zero(blob->active.clusters, 585 blob->active.num_clusters * sizeof(blob->active.clusters[0]))); 586 587 /* Try to create snapshot from clone with xattrs */ 588 xattrs.names = g_xattr_names; 589 xattrs.get_value = _get_xattr_value; 590 xattrs.count = 3; 591 xattrs.ctx = &g_ctx; 592 spdk_bs_create_snapshot(bs, blobid, &xattrs, blob_op_with_id_complete, NULL); 593 CU_ASSERT(g_bserrno == 0); 594 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 595 CU_ASSERT_EQUAL(_get_snapshots_count(bs), 2); 596 snapshotid2 = g_blobid; 597 598 spdk_bs_open_blob(bs, snapshotid2, blob_op_with_handle_complete, NULL); 599 CU_ASSERT(g_bserrno == 0); 600 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 601 snapshot2 = g_blob; 602 CU_ASSERT(snapshot2->data_ro == true) 603 CU_ASSERT(snapshot2->md_ro == true) 604 CU_ASSERT(spdk_blob_get_num_clusters(snapshot2) == 10) 605 606 /* Confirm that blob is backed by snapshot2 and snapshot2 is backed by snapshot */ 607 CU_ASSERT(snapshot->back_bs_dev == NULL); 608 SPDK_CU_ASSERT_FATAL(blob->back_bs_dev != NULL); 609 SPDK_CU_ASSERT_FATAL(snapshot2->back_bs_dev != NULL); 610 611 blob_bs_dev = (struct spdk_blob_bs_dev *)blob->back_bs_dev; 612 CU_ASSERT(blob_bs_dev->blob == snapshot2); 613 614 blob_bs_dev = (struct spdk_blob_bs_dev *)snapshot2->back_bs_dev; 615 CU_ASSERT(blob_bs_dev->blob == snapshot); 616 617 rc = spdk_blob_get_xattr_value(snapshot2, g_xattr_names[0], &value, &value_len); 618 CU_ASSERT(rc == 0); 619 SPDK_CU_ASSERT_FATAL(value != NULL); 620 CU_ASSERT(value_len == strlen(g_xattr_values[0])); 621 CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len); 622 623 rc = spdk_blob_get_xattr_value(snapshot2, g_xattr_names[1], &value, &value_len); 624 CU_ASSERT(rc == 0); 625 SPDK_CU_ASSERT_FATAL(value != NULL); 626 CU_ASSERT(value_len == strlen(g_xattr_values[1])); 627 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len); 628 629 rc = spdk_blob_get_xattr_value(snapshot2, g_xattr_names[2], &value, &value_len); 630 CU_ASSERT(rc == 0); 631 SPDK_CU_ASSERT_FATAL(value != NULL); 632 CU_ASSERT(value_len == strlen(g_xattr_values[2])); 633 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len); 634 635 /* Try to create snapshot from snapshot */ 636 spdk_bs_create_snapshot(bs, snapshotid, NULL, blob_op_with_id_complete, NULL); 637 CU_ASSERT(g_bserrno == -EINVAL); 638 CU_ASSERT(g_blobid == SPDK_BLOBID_INVALID); 639 CU_ASSERT_EQUAL(_get_snapshots_count(bs), 2); 640 641 spdk_blob_close(blob, blob_op_complete, NULL); 642 CU_ASSERT(g_bserrno == 0); 643 644 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 645 CU_ASSERT(g_bserrno == 0); 646 CU_ASSERT_EQUAL(_get_snapshots_count(bs), 2); 647 648 spdk_blob_close(snapshot2, blob_op_complete, NULL); 649 CU_ASSERT(g_bserrno == 0); 650 651 spdk_bs_delete_blob(bs, snapshotid2, blob_op_complete, NULL); 652 CU_ASSERT(g_bserrno == 0); 653 CU_ASSERT_EQUAL(_get_snapshots_count(bs), 1); 654 655 spdk_blob_close(snapshot, blob_op_complete, NULL); 656 CU_ASSERT(g_bserrno == 0); 657 658 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 659 CU_ASSERT(g_bserrno == 0); 660 CU_ASSERT_EQUAL(_get_snapshots_count(bs), 0); 661 662 spdk_bs_unload(g_bs, bs_op_complete, NULL); 663 CU_ASSERT(g_bserrno == 0); 664 g_bs = NULL; 665 } 666 667 static void 668 blob_snapshot_freeze_io(void) 669 { 670 struct spdk_io_channel *channel; 671 struct spdk_bs_channel *bs_channel; 672 struct spdk_blob_store *bs; 673 struct spdk_bs_dev *dev; 674 struct spdk_blob *blob; 675 struct spdk_blob_opts opts; 676 spdk_blob_id blobid; 677 uint32_t num_of_pages = 10; 678 uint8_t payload_read[num_of_pages * SPDK_BS_PAGE_SIZE]; 679 uint8_t payload_write[num_of_pages * SPDK_BS_PAGE_SIZE]; 680 uint8_t payload_zero[num_of_pages * SPDK_BS_PAGE_SIZE]; 681 682 memset(payload_write, 0xE5, sizeof(payload_write)); 683 memset(payload_read, 0x00, sizeof(payload_read)); 684 memset(payload_zero, 0x00, sizeof(payload_zero)); 685 686 dev = init_dev(); 687 memset(g_dev_buffer, 0, DEV_BUFFER_SIZE); 688 689 /* Test freeze I/O during snapshot */ 690 691 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 692 CU_ASSERT(g_bserrno == 0); 693 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 694 bs = g_bs; 695 696 channel = spdk_bs_alloc_io_channel(bs); 697 bs_channel = spdk_io_channel_get_ctx(channel); 698 699 /* Create blob with 10 clusters */ 700 spdk_blob_opts_init(&opts); 701 opts.num_clusters = 10; 702 opts.thin_provision = false; 703 704 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 705 CU_ASSERT(g_bserrno == 0); 706 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 707 blobid = g_blobid; 708 709 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 710 CU_ASSERT(g_bserrno == 0); 711 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 712 blob = g_blob; 713 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 714 715 /* Enable explicitly calling callbacks. On each read/write to back device 716 * execution will stop and wait until _bs_flush_scheduler is called */ 717 g_scheduler_delay = true; 718 719 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 720 721 /* This is implementation specific. 722 * Flag 'frozen_io' is set in _spdk_bs_snapshot_freeze_cpl callback. 723 * Four async I/O operations happen before that. */ 724 725 _bs_flush_scheduler(4); 726 727 CU_ASSERT(TAILQ_EMPTY(&bs_channel->queued_io)); 728 729 /* Blob I/O should be frozen here */ 730 CU_ASSERT(blob->frozen_refcnt == 1); 731 732 /* Write to the blob */ 733 spdk_blob_io_write(blob, channel, payload_write, 0, num_of_pages, blob_op_complete, NULL); 734 735 /* Verify that I/O is queued */ 736 CU_ASSERT(!TAILQ_EMPTY(&bs_channel->queued_io)); 737 /* Verify that payload is not written to disk */ 738 CU_ASSERT(memcmp(payload_zero, &g_dev_buffer[blob->active.clusters[0]*SPDK_BS_PAGE_SIZE], 739 SPDK_BS_PAGE_SIZE) == 0); 740 741 /* Disable scheduler delay. 742 * Finish all operations including spdk_bs_create_snapshot */ 743 g_scheduler_delay = false; 744 _bs_flush_scheduler(1); 745 746 /* Verify snapshot */ 747 CU_ASSERT(g_bserrno == 0); 748 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 749 750 /* Verify that blob has unset frozen_io */ 751 CU_ASSERT(blob->frozen_refcnt == 0); 752 753 /* Verify that postponed I/O completed successfully by comparing payload */ 754 spdk_blob_io_read(blob, channel, payload_read, 0, num_of_pages, blob_op_complete, NULL); 755 CU_ASSERT(g_bserrno == 0); 756 CU_ASSERT(memcmp(payload_write, payload_read, num_of_pages * SPDK_BS_PAGE_SIZE) == 0); 757 758 spdk_blob_close(blob, blob_op_complete, NULL); 759 CU_ASSERT(g_bserrno == 0); 760 761 spdk_bs_free_io_channel(channel); 762 763 spdk_bs_unload(g_bs, bs_op_complete, NULL); 764 CU_ASSERT(g_bserrno == 0); 765 g_bs = NULL; 766 } 767 768 static void 769 blob_clone(void) 770 { 771 struct spdk_blob_store *bs; 772 struct spdk_bs_dev *dev; 773 struct spdk_blob_opts opts; 774 struct spdk_blob *blob, *snapshot, *clone; 775 spdk_blob_id blobid, cloneid, snapshotid; 776 struct spdk_blob_xattr_opts xattrs; 777 const void *value; 778 size_t value_len; 779 int rc; 780 781 dev = init_dev(); 782 783 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 784 CU_ASSERT(g_bserrno == 0); 785 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 786 bs = g_bs; 787 788 /* Create blob with 10 clusters */ 789 790 spdk_blob_opts_init(&opts); 791 opts.num_clusters = 10; 792 793 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 794 CU_ASSERT(g_bserrno == 0); 795 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 796 blobid = g_blobid; 797 798 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 799 CU_ASSERT(g_bserrno == 0); 800 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 801 blob = g_blob; 802 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10) 803 804 /* Create snapshot */ 805 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 806 CU_ASSERT(g_bserrno == 0); 807 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 808 snapshotid = g_blobid; 809 810 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 811 CU_ASSERT(g_bserrno == 0); 812 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 813 snapshot = g_blob; 814 CU_ASSERT(snapshot->data_ro == true) 815 CU_ASSERT(snapshot->md_ro == true) 816 CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 10); 817 818 spdk_blob_close(snapshot, blob_op_complete, NULL); 819 CU_ASSERT(g_bserrno == 0); 820 821 /* Create clone from snapshot with xattrs */ 822 xattrs.names = g_xattr_names; 823 xattrs.get_value = _get_xattr_value; 824 xattrs.count = 3; 825 xattrs.ctx = &g_ctx; 826 827 spdk_bs_create_clone(bs, snapshotid, &xattrs, blob_op_with_id_complete, NULL); 828 CU_ASSERT(g_bserrno == 0); 829 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 830 cloneid = g_blobid; 831 832 spdk_bs_open_blob(bs, cloneid, blob_op_with_handle_complete, NULL); 833 CU_ASSERT(g_bserrno == 0); 834 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 835 clone = g_blob; 836 CU_ASSERT(clone->data_ro == false) 837 CU_ASSERT(clone->md_ro == false) 838 CU_ASSERT(spdk_blob_get_num_clusters(clone) == 10); 839 840 rc = spdk_blob_get_xattr_value(clone, g_xattr_names[0], &value, &value_len); 841 CU_ASSERT(rc == 0); 842 SPDK_CU_ASSERT_FATAL(value != NULL); 843 CU_ASSERT(value_len == strlen(g_xattr_values[0])); 844 CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len); 845 846 rc = spdk_blob_get_xattr_value(clone, g_xattr_names[1], &value, &value_len); 847 CU_ASSERT(rc == 0); 848 SPDK_CU_ASSERT_FATAL(value != NULL); 849 CU_ASSERT(value_len == strlen(g_xattr_values[1])); 850 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len); 851 852 rc = spdk_blob_get_xattr_value(clone, g_xattr_names[2], &value, &value_len); 853 CU_ASSERT(rc == 0); 854 SPDK_CU_ASSERT_FATAL(value != NULL); 855 CU_ASSERT(value_len == strlen(g_xattr_values[2])); 856 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len); 857 858 859 spdk_blob_close(clone, blob_op_complete, NULL); 860 CU_ASSERT(g_bserrno == 0); 861 862 /* Try to create clone from not read only blob */ 863 spdk_bs_create_clone(bs, blobid, NULL, blob_op_with_id_complete, NULL); 864 CU_ASSERT(g_bserrno == -EINVAL); 865 CU_ASSERT(g_blobid == SPDK_BLOBID_INVALID); 866 867 /* Mark blob as read only */ 868 spdk_blob_set_read_only(blob); 869 spdk_blob_sync_md(blob, blob_op_complete, NULL); 870 CU_ASSERT(g_bserrno == 0); 871 872 /* Create clone from read only blob */ 873 spdk_bs_create_clone(bs, blobid, NULL, blob_op_with_id_complete, NULL); 874 CU_ASSERT(g_bserrno == 0); 875 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 876 cloneid = g_blobid; 877 878 spdk_bs_open_blob(bs, cloneid, blob_op_with_handle_complete, NULL); 879 CU_ASSERT(g_bserrno == 0); 880 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 881 clone = g_blob; 882 CU_ASSERT(clone->data_ro == false) 883 CU_ASSERT(clone->md_ro == false) 884 CU_ASSERT(spdk_blob_get_num_clusters(clone) == 10); 885 886 spdk_blob_close(clone, blob_op_complete, NULL); 887 CU_ASSERT(g_bserrno == 0); 888 889 spdk_blob_close(blob, blob_op_complete, NULL); 890 CU_ASSERT(g_bserrno == 0); 891 892 spdk_bs_unload(g_bs, bs_op_complete, NULL); 893 CU_ASSERT(g_bserrno == 0); 894 g_bs = NULL; 895 896 } 897 898 static void 899 _blob_inflate(bool decouple_parent) 900 { 901 struct spdk_blob_store *bs; 902 struct spdk_bs_dev *dev; 903 struct spdk_blob_opts opts; 904 struct spdk_blob *blob, *snapshot; 905 spdk_blob_id blobid, snapshotid; 906 struct spdk_io_channel *channel; 907 uint64_t free_clusters; 908 909 dev = init_dev(); 910 911 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 912 CU_ASSERT(g_bserrno == 0); 913 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 914 bs = g_bs; 915 916 channel = spdk_bs_alloc_io_channel(bs); 917 SPDK_CU_ASSERT_FATAL(channel != NULL); 918 919 /* Create blob with 10 clusters */ 920 921 spdk_blob_opts_init(&opts); 922 opts.num_clusters = 10; 923 opts.thin_provision = true; 924 925 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 926 CU_ASSERT(g_bserrno == 0); 927 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 928 blobid = g_blobid; 929 930 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 931 CU_ASSERT(g_bserrno == 0); 932 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 933 blob = g_blob; 934 935 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10) 936 CU_ASSERT(spdk_blob_is_thin_provisioned(blob) == true); 937 938 /* 1) Blob with no parent */ 939 if (decouple_parent) { 940 /* Decouple parent of blob with no parent (should fail) */ 941 spdk_bs_blob_decouple_parent(bs, channel, blobid, blob_op_complete, NULL); 942 CU_ASSERT(g_bserrno != 0); 943 } else { 944 /* Inflate of thin blob with no parent should made it thick */ 945 spdk_bs_inflate_blob(bs, channel, blobid, blob_op_complete, NULL); 946 CU_ASSERT(g_bserrno == 0); 947 CU_ASSERT(spdk_blob_is_thin_provisioned(blob) == false); 948 } 949 950 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 951 CU_ASSERT(g_bserrno == 0); 952 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 953 snapshotid = g_blobid; 954 955 CU_ASSERT(spdk_blob_is_thin_provisioned(blob) == true); 956 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10) 957 958 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 959 CU_ASSERT(g_bserrno == 0); 960 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 961 snapshot = g_blob; 962 CU_ASSERT(snapshot->data_ro == true) 963 CU_ASSERT(snapshot->md_ro == true) 964 CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 10); 965 966 spdk_blob_close(snapshot, blob_op_complete, NULL); 967 CU_ASSERT(g_bserrno == 0); 968 969 free_clusters = spdk_bs_free_cluster_count(bs); 970 971 /* 2) Blob with parent */ 972 if (!decouple_parent) { 973 /* Do full blob inflation */ 974 spdk_bs_inflate_blob(bs, channel, blobid, blob_op_complete, NULL); 975 CU_ASSERT(g_bserrno == 0); 976 /* all 10 clusters should be allocated */ 977 CU_ASSERT(spdk_bs_free_cluster_count(bs) == free_clusters - 10); 978 } else { 979 /* Decouple parent of blob */ 980 spdk_bs_blob_decouple_parent(bs, channel, blobid, blob_op_complete, NULL); 981 CU_ASSERT(g_bserrno == 0); 982 /* when only parent is removed, none of the clusters should be allocated */ 983 CU_ASSERT(spdk_bs_free_cluster_count(bs) == free_clusters); 984 } 985 986 /* Now, it should be possible to delete snapshot */ 987 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 988 CU_ASSERT(g_bserrno == 0); 989 990 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10) 991 CU_ASSERT(spdk_blob_is_thin_provisioned(blob) == decouple_parent); 992 993 spdk_blob_close(blob, blob_op_complete, NULL); 994 CU_ASSERT(g_bserrno == 0); 995 996 spdk_bs_unload(g_bs, bs_op_complete, NULL); 997 CU_ASSERT(g_bserrno == 0); 998 g_bs = NULL; 999 1000 spdk_bs_free_io_channel(channel); 1001 } 1002 1003 static void 1004 blob_inflate(void) 1005 { 1006 _blob_inflate(false); 1007 _blob_inflate(true); 1008 } 1009 1010 static void 1011 blob_delete(void) 1012 { 1013 struct spdk_blob_store *bs; 1014 struct spdk_bs_dev *dev; 1015 spdk_blob_id blobid; 1016 1017 dev = init_dev(); 1018 1019 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1020 CU_ASSERT(g_bserrno == 0); 1021 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1022 bs = g_bs; 1023 1024 /* Create a blob and then delete it. */ 1025 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1026 CU_ASSERT(g_bserrno == 0); 1027 CU_ASSERT(g_blobid > 0); 1028 blobid = g_blobid; 1029 1030 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 1031 CU_ASSERT(g_bserrno == 0); 1032 1033 /* Try to open the blob */ 1034 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1035 CU_ASSERT(g_bserrno == -ENOENT); 1036 1037 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1038 CU_ASSERT(g_bserrno == 0); 1039 g_bs = NULL; 1040 } 1041 1042 static void 1043 blob_resize(void) 1044 { 1045 struct spdk_blob_store *bs; 1046 struct spdk_bs_dev *dev; 1047 struct spdk_blob *blob; 1048 spdk_blob_id blobid; 1049 uint64_t free_clusters; 1050 1051 dev = init_dev(); 1052 1053 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1054 CU_ASSERT(g_bserrno == 0); 1055 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1056 bs = g_bs; 1057 free_clusters = spdk_bs_free_cluster_count(bs); 1058 1059 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1060 CU_ASSERT(g_bserrno == 0); 1061 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1062 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 1063 blobid = g_blobid; 1064 1065 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1066 CU_ASSERT(g_bserrno == 0); 1067 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1068 blob = g_blob; 1069 1070 /* Confirm that resize fails if blob is marked read-only. */ 1071 blob->md_ro = true; 1072 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 1073 CU_ASSERT(g_bserrno == -EPERM); 1074 blob->md_ro = false; 1075 1076 /* The blob started at 0 clusters. Resize it to be 5. */ 1077 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 1078 CU_ASSERT(g_bserrno == 0); 1079 CU_ASSERT((free_clusters - 5) == spdk_bs_free_cluster_count(bs)); 1080 1081 /* Shrink the blob to 3 clusters. This will not actually release 1082 * the old clusters until the blob is synced. 1083 */ 1084 spdk_blob_resize(blob, 3, blob_op_complete, NULL); 1085 CU_ASSERT(g_bserrno == 0); 1086 /* Verify there are still 5 clusters in use */ 1087 CU_ASSERT((free_clusters - 5) == spdk_bs_free_cluster_count(bs)); 1088 1089 spdk_blob_sync_md(blob, blob_op_complete, NULL); 1090 CU_ASSERT(g_bserrno == 0); 1091 /* Now there are only 3 clusters in use */ 1092 CU_ASSERT((free_clusters - 3) == spdk_bs_free_cluster_count(bs)); 1093 1094 /* Resize the blob to be 10 clusters. Growth takes effect immediately. */ 1095 spdk_blob_resize(blob, 10, blob_op_complete, NULL); 1096 CU_ASSERT(g_bserrno == 0); 1097 CU_ASSERT((free_clusters - 10) == spdk_bs_free_cluster_count(bs)); 1098 1099 /* Try to resize the blob to size larger than blobstore. */ 1100 spdk_blob_resize(blob, bs->total_clusters + 1, blob_op_complete, NULL); 1101 CU_ASSERT(g_bserrno == -ENOSPC); 1102 1103 spdk_blob_close(blob, blob_op_complete, NULL); 1104 CU_ASSERT(g_bserrno == 0); 1105 1106 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 1107 CU_ASSERT(g_bserrno == 0); 1108 1109 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1110 CU_ASSERT(g_bserrno == 0); 1111 g_bs = NULL; 1112 } 1113 1114 static void 1115 blob_read_only(void) 1116 { 1117 struct spdk_blob_store *bs; 1118 struct spdk_bs_dev *dev; 1119 struct spdk_blob *blob; 1120 struct spdk_bs_opts opts; 1121 spdk_blob_id blobid; 1122 int rc; 1123 1124 dev = init_dev(); 1125 spdk_bs_opts_init(&opts); 1126 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 1127 1128 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1129 CU_ASSERT(g_bserrno == 0); 1130 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1131 bs = g_bs; 1132 1133 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1134 CU_ASSERT(g_bserrno == 0); 1135 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1136 blobid = g_blobid; 1137 1138 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1139 CU_ASSERT(g_bserrno == 0); 1140 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1141 blob = g_blob; 1142 1143 rc = spdk_blob_set_read_only(blob); 1144 CU_ASSERT(rc == 0); 1145 1146 CU_ASSERT(blob->data_ro == false); 1147 CU_ASSERT(blob->md_ro == false); 1148 1149 spdk_blob_sync_md(blob, bs_op_complete, NULL); 1150 1151 CU_ASSERT(blob->data_ro == true); 1152 CU_ASSERT(blob->md_ro == true); 1153 CU_ASSERT(blob->data_ro_flags & SPDK_BLOB_READ_ONLY); 1154 1155 spdk_blob_close(blob, blob_op_complete, NULL); 1156 CU_ASSERT(g_bserrno == 0); 1157 1158 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1159 CU_ASSERT(g_bserrno == 0); 1160 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1161 blob = g_blob; 1162 1163 CU_ASSERT(blob->data_ro == true); 1164 CU_ASSERT(blob->md_ro == true); 1165 CU_ASSERT(blob->data_ro_flags & SPDK_BLOB_READ_ONLY); 1166 1167 spdk_blob_close(blob, blob_op_complete, NULL); 1168 CU_ASSERT(g_bserrno == 0); 1169 1170 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1171 CU_ASSERT(g_bserrno == 0); 1172 g_bs = NULL; 1173 g_blob = NULL; 1174 g_blobid = 0; 1175 1176 /* Load an existing blob store */ 1177 dev = init_dev(); 1178 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 1179 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1180 CU_ASSERT(g_bserrno == 0); 1181 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1182 1183 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 1184 CU_ASSERT(g_bserrno == 0); 1185 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1186 blob = g_blob; 1187 1188 CU_ASSERT(blob->data_ro == true); 1189 CU_ASSERT(blob->md_ro == true); 1190 CU_ASSERT(blob->data_ro_flags & SPDK_BLOB_READ_ONLY); 1191 1192 spdk_blob_close(blob, blob_op_complete, NULL); 1193 CU_ASSERT(g_bserrno == 0); 1194 1195 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1196 CU_ASSERT(g_bserrno == 0); 1197 1198 } 1199 1200 static void 1201 channel_ops(void) 1202 { 1203 struct spdk_blob_store *bs; 1204 struct spdk_bs_dev *dev; 1205 struct spdk_io_channel *channel; 1206 1207 dev = init_dev(); 1208 1209 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1210 CU_ASSERT(g_bserrno == 0); 1211 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1212 bs = g_bs; 1213 1214 channel = spdk_bs_alloc_io_channel(bs); 1215 CU_ASSERT(channel != NULL); 1216 1217 spdk_bs_free_io_channel(channel); 1218 1219 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1220 CU_ASSERT(g_bserrno == 0); 1221 g_bs = NULL; 1222 } 1223 1224 static void 1225 blob_write(void) 1226 { 1227 struct spdk_blob_store *bs; 1228 struct spdk_bs_dev *dev; 1229 struct spdk_blob *blob; 1230 struct spdk_io_channel *channel; 1231 spdk_blob_id blobid; 1232 uint64_t pages_per_cluster; 1233 uint8_t payload[10 * 4096]; 1234 1235 dev = init_dev(); 1236 1237 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1238 CU_ASSERT(g_bserrno == 0); 1239 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1240 bs = g_bs; 1241 1242 pages_per_cluster = spdk_bs_get_cluster_size(bs) / spdk_bs_get_page_size(bs); 1243 1244 channel = spdk_bs_alloc_io_channel(bs); 1245 CU_ASSERT(channel != NULL); 1246 1247 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1248 CU_ASSERT(g_bserrno == 0); 1249 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1250 blobid = g_blobid; 1251 1252 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1253 CU_ASSERT(g_bserrno == 0); 1254 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1255 blob = g_blob; 1256 1257 /* Write to a blob with 0 size */ 1258 spdk_blob_io_write(blob, channel, payload, 0, 1, blob_op_complete, NULL); 1259 CU_ASSERT(g_bserrno == -EINVAL); 1260 1261 /* Resize the blob */ 1262 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 1263 CU_ASSERT(g_bserrno == 0); 1264 1265 /* Confirm that write fails if blob is marked read-only. */ 1266 blob->data_ro = true; 1267 spdk_blob_io_write(blob, channel, payload, 0, 1, blob_op_complete, NULL); 1268 CU_ASSERT(g_bserrno == -EPERM); 1269 blob->data_ro = false; 1270 1271 /* Write to the blob */ 1272 spdk_blob_io_write(blob, channel, payload, 0, 1, blob_op_complete, NULL); 1273 CU_ASSERT(g_bserrno == 0); 1274 1275 /* Write starting beyond the end */ 1276 spdk_blob_io_write(blob, channel, payload, 5 * pages_per_cluster, 1, blob_op_complete, 1277 NULL); 1278 CU_ASSERT(g_bserrno == -EINVAL); 1279 1280 /* Write starting at a valid location but going off the end */ 1281 spdk_blob_io_write(blob, channel, payload, 4 * pages_per_cluster, pages_per_cluster + 1, 1282 blob_op_complete, NULL); 1283 CU_ASSERT(g_bserrno == -EINVAL); 1284 1285 spdk_blob_close(blob, blob_op_complete, NULL); 1286 CU_ASSERT(g_bserrno == 0); 1287 1288 spdk_bs_free_io_channel(channel); 1289 1290 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1291 CU_ASSERT(g_bserrno == 0); 1292 g_bs = NULL; 1293 } 1294 1295 static void 1296 blob_read(void) 1297 { 1298 struct spdk_blob_store *bs; 1299 struct spdk_bs_dev *dev; 1300 struct spdk_blob *blob; 1301 struct spdk_io_channel *channel; 1302 spdk_blob_id blobid; 1303 uint64_t pages_per_cluster; 1304 uint8_t payload[10 * 4096]; 1305 1306 dev = init_dev(); 1307 1308 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1309 CU_ASSERT(g_bserrno == 0); 1310 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1311 bs = g_bs; 1312 1313 pages_per_cluster = spdk_bs_get_cluster_size(bs) / spdk_bs_get_page_size(bs); 1314 1315 channel = spdk_bs_alloc_io_channel(bs); 1316 CU_ASSERT(channel != NULL); 1317 1318 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1319 CU_ASSERT(g_bserrno == 0); 1320 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1321 blobid = g_blobid; 1322 1323 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1324 CU_ASSERT(g_bserrno == 0); 1325 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1326 blob = g_blob; 1327 1328 /* Read from a blob with 0 size */ 1329 spdk_blob_io_read(blob, channel, payload, 0, 1, blob_op_complete, NULL); 1330 CU_ASSERT(g_bserrno == -EINVAL); 1331 1332 /* Resize the blob */ 1333 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 1334 CU_ASSERT(g_bserrno == 0); 1335 1336 /* Confirm that read passes if blob is marked read-only. */ 1337 blob->data_ro = true; 1338 spdk_blob_io_read(blob, channel, payload, 0, 1, blob_op_complete, NULL); 1339 CU_ASSERT(g_bserrno == 0); 1340 blob->data_ro = false; 1341 1342 /* Read from the blob */ 1343 spdk_blob_io_read(blob, channel, payload, 0, 1, blob_op_complete, NULL); 1344 CU_ASSERT(g_bserrno == 0); 1345 1346 /* Read starting beyond the end */ 1347 spdk_blob_io_read(blob, channel, payload, 5 * pages_per_cluster, 1, blob_op_complete, 1348 NULL); 1349 CU_ASSERT(g_bserrno == -EINVAL); 1350 1351 /* Read starting at a valid location but going off the end */ 1352 spdk_blob_io_read(blob, channel, payload, 4 * pages_per_cluster, pages_per_cluster + 1, 1353 blob_op_complete, NULL); 1354 CU_ASSERT(g_bserrno == -EINVAL); 1355 1356 spdk_blob_close(blob, blob_op_complete, NULL); 1357 CU_ASSERT(g_bserrno == 0); 1358 1359 spdk_bs_free_io_channel(channel); 1360 1361 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1362 CU_ASSERT(g_bserrno == 0); 1363 g_bs = NULL; 1364 } 1365 1366 static void 1367 blob_rw_verify(void) 1368 { 1369 struct spdk_blob_store *bs; 1370 struct spdk_bs_dev *dev; 1371 struct spdk_blob *blob; 1372 struct spdk_io_channel *channel; 1373 spdk_blob_id blobid; 1374 uint8_t payload_read[10 * 4096]; 1375 uint8_t payload_write[10 * 4096]; 1376 1377 dev = init_dev(); 1378 1379 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1380 CU_ASSERT(g_bserrno == 0); 1381 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1382 bs = g_bs; 1383 1384 channel = spdk_bs_alloc_io_channel(bs); 1385 CU_ASSERT(channel != NULL); 1386 1387 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1388 CU_ASSERT(g_bserrno == 0); 1389 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1390 blobid = g_blobid; 1391 1392 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1393 CU_ASSERT(g_bserrno == 0); 1394 CU_ASSERT(g_blob != NULL); 1395 blob = g_blob; 1396 1397 spdk_blob_resize(blob, 32, blob_op_complete, NULL); 1398 CU_ASSERT(g_bserrno == 0); 1399 1400 memset(payload_write, 0xE5, sizeof(payload_write)); 1401 spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL); 1402 CU_ASSERT(g_bserrno == 0); 1403 1404 memset(payload_read, 0x00, sizeof(payload_read)); 1405 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 1406 CU_ASSERT(g_bserrno == 0); 1407 CU_ASSERT(memcmp(payload_write, payload_read, 4 * 4096) == 0); 1408 1409 spdk_blob_close(blob, blob_op_complete, NULL); 1410 CU_ASSERT(g_bserrno == 0); 1411 1412 spdk_bs_free_io_channel(channel); 1413 1414 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1415 CU_ASSERT(g_bserrno == 0); 1416 g_bs = NULL; 1417 } 1418 1419 static void 1420 blob_rw_verify_iov(void) 1421 { 1422 struct spdk_blob_store *bs; 1423 struct spdk_bs_dev *dev; 1424 struct spdk_blob *blob; 1425 struct spdk_io_channel *channel; 1426 spdk_blob_id blobid; 1427 uint8_t payload_read[10 * 4096]; 1428 uint8_t payload_write[10 * 4096]; 1429 struct iovec iov_read[3]; 1430 struct iovec iov_write[3]; 1431 void *buf; 1432 1433 dev = init_dev(); 1434 memset(g_dev_buffer, 0, DEV_BUFFER_SIZE); 1435 1436 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1437 CU_ASSERT(g_bserrno == 0); 1438 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1439 bs = g_bs; 1440 1441 channel = spdk_bs_alloc_io_channel(bs); 1442 CU_ASSERT(channel != NULL); 1443 1444 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1445 CU_ASSERT(g_bserrno == 0); 1446 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1447 blobid = g_blobid; 1448 1449 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1450 CU_ASSERT(g_bserrno == 0); 1451 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1452 blob = g_blob; 1453 1454 spdk_blob_resize(blob, 2, blob_op_complete, NULL); 1455 CU_ASSERT(g_bserrno == 0); 1456 1457 /* 1458 * Manually adjust the offset of the blob's second cluster. This allows 1459 * us to make sure that the readv/write code correctly accounts for I/O 1460 * that cross cluster boundaries. Start by asserting that the allocated 1461 * clusters are where we expect before modifying the second cluster. 1462 */ 1463 CU_ASSERT(blob->active.clusters[0] == 1 * 256); 1464 CU_ASSERT(blob->active.clusters[1] == 2 * 256); 1465 blob->active.clusters[1] = 3 * 256; 1466 1467 memset(payload_write, 0xE5, sizeof(payload_write)); 1468 iov_write[0].iov_base = payload_write; 1469 iov_write[0].iov_len = 1 * 4096; 1470 iov_write[1].iov_base = payload_write + 1 * 4096; 1471 iov_write[1].iov_len = 5 * 4096; 1472 iov_write[2].iov_base = payload_write + 6 * 4096; 1473 iov_write[2].iov_len = 4 * 4096; 1474 /* 1475 * Choose a page offset just before the cluster boundary. The first 6 pages of payload 1476 * will get written to the first cluster, the last 4 to the second cluster. 1477 */ 1478 spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 1479 CU_ASSERT(g_bserrno == 0); 1480 1481 memset(payload_read, 0xAA, sizeof(payload_read)); 1482 iov_read[0].iov_base = payload_read; 1483 iov_read[0].iov_len = 3 * 4096; 1484 iov_read[1].iov_base = payload_read + 3 * 4096; 1485 iov_read[1].iov_len = 4 * 4096; 1486 iov_read[2].iov_base = payload_read + 7 * 4096; 1487 iov_read[2].iov_len = 3 * 4096; 1488 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 1489 CU_ASSERT(g_bserrno == 0); 1490 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 1491 1492 buf = calloc(1, 256 * 4096); 1493 SPDK_CU_ASSERT_FATAL(buf != NULL); 1494 /* Check that cluster 2 on "disk" was not modified. */ 1495 CU_ASSERT(memcmp(buf, &g_dev_buffer[512 * 4096], 256 * 4096) == 0); 1496 free(buf); 1497 1498 spdk_blob_close(blob, blob_op_complete, NULL); 1499 CU_ASSERT(g_bserrno == 0); 1500 1501 spdk_bs_free_io_channel(channel); 1502 1503 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1504 CU_ASSERT(g_bserrno == 0); 1505 g_bs = NULL; 1506 } 1507 1508 static uint32_t 1509 bs_channel_get_req_count(struct spdk_io_channel *_channel) 1510 { 1511 struct spdk_bs_channel *channel = spdk_io_channel_get_ctx(_channel); 1512 struct spdk_bs_request_set *set; 1513 uint32_t count = 0; 1514 1515 TAILQ_FOREACH(set, &channel->reqs, link) { 1516 count++; 1517 } 1518 1519 return count; 1520 } 1521 1522 static void 1523 blob_rw_verify_iov_nomem(void) 1524 { 1525 struct spdk_blob_store *bs; 1526 struct spdk_bs_dev *dev; 1527 struct spdk_blob *blob; 1528 struct spdk_io_channel *channel; 1529 spdk_blob_id blobid; 1530 uint8_t payload_write[10 * 4096]; 1531 struct iovec iov_write[3]; 1532 uint32_t req_count; 1533 1534 dev = init_dev(); 1535 memset(g_dev_buffer, 0, DEV_BUFFER_SIZE); 1536 1537 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1538 CU_ASSERT(g_bserrno == 0); 1539 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1540 bs = g_bs; 1541 1542 channel = spdk_bs_alloc_io_channel(bs); 1543 CU_ASSERT(channel != NULL); 1544 1545 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1546 CU_ASSERT(g_bserrno == 0); 1547 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1548 blobid = g_blobid; 1549 1550 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1551 CU_ASSERT(g_bserrno == 0); 1552 CU_ASSERT(g_blob != NULL); 1553 blob = g_blob; 1554 1555 spdk_blob_resize(blob, 2, blob_op_complete, NULL); 1556 CU_ASSERT(g_bserrno == 0); 1557 1558 /* 1559 * Choose a page offset just before the cluster boundary. The first 6 pages of payload 1560 * will get written to the first cluster, the last 4 to the second cluster. 1561 */ 1562 iov_write[0].iov_base = payload_write; 1563 iov_write[0].iov_len = 1 * 4096; 1564 iov_write[1].iov_base = payload_write + 1 * 4096; 1565 iov_write[1].iov_len = 5 * 4096; 1566 iov_write[2].iov_base = payload_write + 6 * 4096; 1567 iov_write[2].iov_len = 4 * 4096; 1568 MOCK_SET(calloc, NULL); 1569 req_count = bs_channel_get_req_count(channel); 1570 spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 1571 CU_ASSERT(g_bserrno = -ENOMEM); 1572 CU_ASSERT(req_count == bs_channel_get_req_count(channel)); 1573 MOCK_CLEAR(calloc); 1574 1575 spdk_blob_close(blob, blob_op_complete, NULL); 1576 CU_ASSERT(g_bserrno == 0); 1577 1578 spdk_bs_free_io_channel(channel); 1579 1580 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1581 CU_ASSERT(g_bserrno == 0); 1582 g_bs = NULL; 1583 } 1584 1585 static void 1586 blob_rw_iov_read_only(void) 1587 { 1588 struct spdk_blob_store *bs; 1589 struct spdk_bs_dev *dev; 1590 struct spdk_blob *blob; 1591 struct spdk_io_channel *channel; 1592 spdk_blob_id blobid; 1593 uint8_t payload_read[4096]; 1594 uint8_t payload_write[4096]; 1595 struct iovec iov_read; 1596 struct iovec iov_write; 1597 1598 dev = init_dev(); 1599 memset(g_dev_buffer, 0, DEV_BUFFER_SIZE); 1600 1601 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1602 CU_ASSERT(g_bserrno == 0); 1603 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1604 bs = g_bs; 1605 1606 channel = spdk_bs_alloc_io_channel(bs); 1607 CU_ASSERT(channel != NULL); 1608 1609 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1610 CU_ASSERT(g_bserrno == 0); 1611 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1612 blobid = g_blobid; 1613 1614 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1615 CU_ASSERT(g_bserrno == 0); 1616 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1617 blob = g_blob; 1618 1619 spdk_blob_resize(blob, 2, blob_op_complete, NULL); 1620 CU_ASSERT(g_bserrno == 0); 1621 1622 /* Verify that writev failed if read_only flag is set. */ 1623 blob->data_ro = true; 1624 iov_write.iov_base = payload_write; 1625 iov_write.iov_len = sizeof(payload_write); 1626 spdk_blob_io_writev(blob, channel, &iov_write, 1, 0, 1, blob_op_complete, NULL); 1627 CU_ASSERT(g_bserrno == -EPERM); 1628 1629 /* Verify that reads pass if data_ro flag is set. */ 1630 iov_read.iov_base = payload_read; 1631 iov_read.iov_len = sizeof(payload_read); 1632 spdk_blob_io_readv(blob, channel, &iov_read, 1, 0, 1, blob_op_complete, NULL); 1633 CU_ASSERT(g_bserrno == 0); 1634 1635 spdk_blob_close(blob, blob_op_complete, NULL); 1636 CU_ASSERT(g_bserrno == 0); 1637 1638 spdk_bs_free_io_channel(channel); 1639 1640 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1641 CU_ASSERT(g_bserrno == 0); 1642 g_bs = NULL; 1643 } 1644 1645 static void 1646 _blob_io_read_no_split(struct spdk_blob *blob, struct spdk_io_channel *channel, 1647 uint8_t *payload, uint64_t offset, uint64_t length, 1648 spdk_blob_op_complete cb_fn, void *cb_arg) 1649 { 1650 uint64_t i; 1651 uint8_t *buf; 1652 uint64_t page_size = spdk_bs_get_page_size(blob->bs); 1653 1654 /* To be sure that operation is NOT splitted, read one page at the time */ 1655 buf = payload; 1656 for (i = 0; i < length; i++) { 1657 spdk_blob_io_read(blob, channel, buf, i + offset, 1, blob_op_complete, NULL); 1658 if (g_bserrno != 0) { 1659 /* Pass the error code up */ 1660 break; 1661 } 1662 buf += page_size; 1663 } 1664 1665 cb_fn(cb_arg, g_bserrno); 1666 } 1667 1668 static void 1669 _blob_io_write_no_split(struct spdk_blob *blob, struct spdk_io_channel *channel, 1670 uint8_t *payload, uint64_t offset, uint64_t length, 1671 spdk_blob_op_complete cb_fn, void *cb_arg) 1672 { 1673 uint64_t i; 1674 uint8_t *buf; 1675 uint64_t page_size = spdk_bs_get_page_size(blob->bs); 1676 1677 /* To be sure that operation is NOT splitted, write one page at the time */ 1678 buf = payload; 1679 for (i = 0; i < length; i++) { 1680 spdk_blob_io_write(blob, channel, buf, i + offset, 1, blob_op_complete, NULL); 1681 if (g_bserrno != 0) { 1682 /* Pass the error code up */ 1683 break; 1684 } 1685 buf += page_size; 1686 } 1687 1688 cb_fn(cb_arg, g_bserrno); 1689 } 1690 1691 static void 1692 blob_operation_split_rw(void) 1693 { 1694 struct spdk_blob_store *bs; 1695 struct spdk_bs_dev *dev; 1696 struct spdk_blob *blob; 1697 struct spdk_io_channel *channel; 1698 struct spdk_blob_opts opts; 1699 spdk_blob_id blobid; 1700 uint64_t cluster_size; 1701 1702 uint64_t payload_size; 1703 uint8_t *payload_read; 1704 uint8_t *payload_write; 1705 uint8_t *payload_pattern; 1706 1707 uint64_t page_size; 1708 uint64_t pages_per_cluster; 1709 uint64_t pages_per_payload; 1710 1711 uint64_t i; 1712 1713 dev = init_dev(); 1714 1715 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1716 CU_ASSERT(g_bserrno == 0); 1717 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1718 bs = g_bs; 1719 1720 cluster_size = spdk_bs_get_cluster_size(bs); 1721 page_size = spdk_bs_get_page_size(bs); 1722 pages_per_cluster = cluster_size / page_size; 1723 pages_per_payload = pages_per_cluster * 5; 1724 payload_size = cluster_size * 5; 1725 1726 payload_read = malloc(payload_size); 1727 SPDK_CU_ASSERT_FATAL(payload_read != NULL); 1728 1729 payload_write = malloc(payload_size); 1730 SPDK_CU_ASSERT_FATAL(payload_write != NULL); 1731 1732 payload_pattern = malloc(payload_size); 1733 SPDK_CU_ASSERT_FATAL(payload_pattern != NULL); 1734 1735 /* Prepare random pattern to write */ 1736 memset(payload_pattern, 0xFF, payload_size); 1737 for (i = 0; i < pages_per_payload; i++) { 1738 *((uint64_t *)(payload_pattern + page_size * i)) = (i + 1); 1739 } 1740 1741 channel = spdk_bs_alloc_io_channel(bs); 1742 SPDK_CU_ASSERT_FATAL(channel != NULL); 1743 1744 /* Create blob */ 1745 spdk_blob_opts_init(&opts); 1746 opts.thin_provision = false; 1747 opts.num_clusters = 5; 1748 1749 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 1750 CU_ASSERT(g_bserrno == 0); 1751 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1752 blobid = g_blobid; 1753 1754 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1755 CU_ASSERT(g_bserrno == 0); 1756 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1757 blob = g_blob; 1758 1759 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 1760 1761 /* Initial read should return zeroed payload */ 1762 memset(payload_read, 0xFF, payload_size); 1763 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, blob_op_complete, NULL); 1764 CU_ASSERT(g_bserrno == 0); 1765 CU_ASSERT(spdk_mem_all_zero(payload_read, payload_size)); 1766 1767 /* Fill whole blob except last page */ 1768 spdk_blob_io_write(blob, channel, payload_pattern, 0, pages_per_payload - 1, 1769 blob_op_complete, NULL); 1770 CU_ASSERT(g_bserrno == 0); 1771 1772 /* Write last page with a pattern */ 1773 spdk_blob_io_write(blob, channel, payload_pattern, pages_per_payload - 1, 1, 1774 blob_op_complete, NULL); 1775 CU_ASSERT(g_bserrno == 0); 1776 1777 /* Read whole blob and check consistency */ 1778 memset(payload_read, 0xFF, payload_size); 1779 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, blob_op_complete, NULL); 1780 CU_ASSERT(g_bserrno == 0); 1781 CU_ASSERT(memcmp(payload_pattern, payload_read, payload_size - page_size) == 0); 1782 CU_ASSERT(memcmp(payload_pattern, payload_read + payload_size - page_size, page_size) == 0); 1783 1784 /* Fill whole blob except first page */ 1785 spdk_blob_io_write(blob, channel, payload_pattern, 1, pages_per_payload - 1, 1786 blob_op_complete, NULL); 1787 CU_ASSERT(g_bserrno == 0); 1788 1789 /* Write first page with a pattern */ 1790 spdk_blob_io_write(blob, channel, payload_pattern, 0, 1, 1791 blob_op_complete, NULL); 1792 CU_ASSERT(g_bserrno == 0); 1793 1794 /* Read whole blob and check consistency */ 1795 memset(payload_read, 0xFF, payload_size); 1796 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, blob_op_complete, NULL); 1797 CU_ASSERT(g_bserrno == 0); 1798 CU_ASSERT(memcmp(payload_pattern, payload_read + page_size, payload_size - page_size) == 0); 1799 CU_ASSERT(memcmp(payload_pattern, payload_read, page_size) == 0); 1800 1801 1802 /* Fill whole blob with a pattern (5 clusters) */ 1803 1804 /* 1. Read test. */ 1805 _blob_io_write_no_split(blob, channel, payload_pattern, 0, pages_per_payload, 1806 blob_op_complete, NULL); 1807 CU_ASSERT(g_bserrno == 0); 1808 1809 memset(payload_read, 0xFF, payload_size); 1810 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, blob_op_complete, NULL); 1811 CU_ASSERT(g_bserrno == 0); 1812 CU_ASSERT(memcmp(payload_pattern, payload_read, payload_size) == 0); 1813 1814 /* 2. Write test. */ 1815 spdk_blob_io_write(blob, channel, payload_pattern, 0, pages_per_payload, 1816 blob_op_complete, NULL); 1817 CU_ASSERT(g_bserrno == 0); 1818 1819 memset(payload_read, 0xFF, payload_size); 1820 _blob_io_read_no_split(blob, channel, payload_read, 0, pages_per_payload, blob_op_complete, NULL); 1821 CU_ASSERT(g_bserrno == 0); 1822 CU_ASSERT(memcmp(payload_pattern, payload_read, payload_size) == 0); 1823 1824 spdk_blob_close(blob, blob_op_complete, NULL); 1825 CU_ASSERT(g_bserrno == 0); 1826 1827 spdk_bs_free_io_channel(channel); 1828 1829 /* Unload the blob store */ 1830 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1831 CU_ASSERT(g_bserrno == 0); 1832 g_bs = NULL; 1833 g_blob = NULL; 1834 g_blobid = 0; 1835 1836 free(payload_read); 1837 free(payload_write); 1838 free(payload_pattern); 1839 } 1840 1841 static void 1842 blob_operation_split_rw_iov(void) 1843 { 1844 struct spdk_blob_store *bs; 1845 struct spdk_bs_dev *dev; 1846 struct spdk_blob *blob; 1847 struct spdk_io_channel *channel; 1848 struct spdk_blob_opts opts; 1849 spdk_blob_id blobid; 1850 uint64_t cluster_size; 1851 1852 uint64_t payload_size; 1853 uint8_t *payload_read; 1854 uint8_t *payload_write; 1855 uint8_t *payload_pattern; 1856 1857 uint64_t page_size; 1858 uint64_t pages_per_cluster; 1859 uint64_t pages_per_payload; 1860 1861 struct iovec iov_read[2]; 1862 struct iovec iov_write[2]; 1863 1864 uint64_t i, j; 1865 1866 dev = init_dev(); 1867 1868 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1869 CU_ASSERT(g_bserrno == 0); 1870 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1871 bs = g_bs; 1872 1873 cluster_size = spdk_bs_get_cluster_size(bs); 1874 page_size = spdk_bs_get_page_size(bs); 1875 pages_per_cluster = cluster_size / page_size; 1876 pages_per_payload = pages_per_cluster * 5; 1877 payload_size = cluster_size * 5; 1878 1879 payload_read = malloc(payload_size); 1880 SPDK_CU_ASSERT_FATAL(payload_read != NULL); 1881 1882 payload_write = malloc(payload_size); 1883 SPDK_CU_ASSERT_FATAL(payload_write != NULL); 1884 1885 payload_pattern = malloc(payload_size); 1886 SPDK_CU_ASSERT_FATAL(payload_pattern != NULL); 1887 1888 /* Prepare random pattern to write */ 1889 for (i = 0; i < pages_per_payload; i++) { 1890 for (j = 0; j < page_size / sizeof(uint64_t); j++) { 1891 uint64_t *tmp; 1892 1893 tmp = (uint64_t *)payload_pattern; 1894 tmp += ((page_size * i) / sizeof(uint64_t)) + j; 1895 *tmp = i + 1; 1896 } 1897 } 1898 1899 channel = spdk_bs_alloc_io_channel(bs); 1900 SPDK_CU_ASSERT_FATAL(channel != NULL); 1901 1902 /* Create blob */ 1903 spdk_blob_opts_init(&opts); 1904 opts.thin_provision = false; 1905 opts.num_clusters = 5; 1906 1907 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 1908 CU_ASSERT(g_bserrno == 0); 1909 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1910 blobid = g_blobid; 1911 1912 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1913 CU_ASSERT(g_bserrno == 0); 1914 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1915 blob = g_blob; 1916 1917 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 1918 1919 /* Initial read should return zeroes payload */ 1920 memset(payload_read, 0xFF, payload_size); 1921 iov_read[0].iov_base = payload_read; 1922 iov_read[0].iov_len = cluster_size * 3; 1923 iov_read[1].iov_base = payload_read + cluster_size * 3; 1924 iov_read[1].iov_len = cluster_size * 2; 1925 spdk_blob_io_readv(blob, channel, iov_read, 2, 0, pages_per_payload, blob_op_complete, NULL); 1926 CU_ASSERT(g_bserrno == 0); 1927 CU_ASSERT(spdk_mem_all_zero(payload_read, payload_size)); 1928 1929 /* First of iovs fills whole blob except last page and second of iovs writes last page 1930 * with a pattern. */ 1931 iov_write[0].iov_base = payload_pattern; 1932 iov_write[0].iov_len = payload_size - page_size; 1933 iov_write[1].iov_base = payload_pattern; 1934 iov_write[1].iov_len = page_size; 1935 spdk_blob_io_writev(blob, channel, iov_write, 2, 0, pages_per_payload, blob_op_complete, NULL); 1936 CU_ASSERT(g_bserrno == 0); 1937 1938 /* Read whole blob and check consistency */ 1939 memset(payload_read, 0xFF, payload_size); 1940 iov_read[0].iov_base = payload_read; 1941 iov_read[0].iov_len = cluster_size * 2; 1942 iov_read[1].iov_base = payload_read + cluster_size * 2; 1943 iov_read[1].iov_len = cluster_size * 3; 1944 spdk_blob_io_readv(blob, channel, iov_read, 2, 0, pages_per_payload, blob_op_complete, NULL); 1945 CU_ASSERT(g_bserrno == 0); 1946 CU_ASSERT(memcmp(payload_pattern, payload_read, payload_size - page_size) == 0); 1947 CU_ASSERT(memcmp(payload_pattern, payload_read + payload_size - page_size, page_size) == 0); 1948 1949 /* First of iovs fills only first page and second of iovs writes whole blob except 1950 * first page with a pattern. */ 1951 iov_write[0].iov_base = payload_pattern; 1952 iov_write[0].iov_len = page_size; 1953 iov_write[1].iov_base = payload_pattern; 1954 iov_write[1].iov_len = payload_size - page_size; 1955 spdk_blob_io_writev(blob, channel, iov_write, 2, 0, pages_per_payload, blob_op_complete, NULL); 1956 CU_ASSERT(g_bserrno == 0); 1957 1958 /* Read whole blob and check consistency */ 1959 memset(payload_read, 0xFF, payload_size); 1960 iov_read[0].iov_base = payload_read; 1961 iov_read[0].iov_len = cluster_size * 4; 1962 iov_read[1].iov_base = payload_read + cluster_size * 4; 1963 iov_read[1].iov_len = cluster_size; 1964 spdk_blob_io_readv(blob, channel, iov_read, 2, 0, pages_per_payload, blob_op_complete, NULL); 1965 CU_ASSERT(g_bserrno == 0); 1966 CU_ASSERT(memcmp(payload_pattern, payload_read + page_size, payload_size - page_size) == 0); 1967 CU_ASSERT(memcmp(payload_pattern, payload_read, page_size) == 0); 1968 1969 1970 /* Fill whole blob with a pattern (5 clusters) */ 1971 1972 /* 1. Read test. */ 1973 _blob_io_write_no_split(blob, channel, payload_pattern, 0, pages_per_payload, 1974 blob_op_complete, NULL); 1975 CU_ASSERT(g_bserrno == 0); 1976 1977 memset(payload_read, 0xFF, payload_size); 1978 iov_read[0].iov_base = payload_read; 1979 iov_read[0].iov_len = cluster_size; 1980 iov_read[1].iov_base = payload_read + cluster_size; 1981 iov_read[1].iov_len = cluster_size * 4; 1982 spdk_blob_io_readv(blob, channel, iov_read, 2, 0, pages_per_payload, blob_op_complete, NULL); 1983 CU_ASSERT(g_bserrno == 0); 1984 CU_ASSERT(memcmp(payload_pattern, payload_read, payload_size) == 0); 1985 1986 /* 2. Write test. */ 1987 iov_write[0].iov_base = payload_read; 1988 iov_write[0].iov_len = cluster_size * 2; 1989 iov_write[1].iov_base = payload_read + cluster_size * 2; 1990 iov_write[1].iov_len = cluster_size * 3; 1991 spdk_blob_io_writev(blob, channel, iov_write, 2, 0, pages_per_payload, blob_op_complete, NULL); 1992 CU_ASSERT(g_bserrno == 0); 1993 1994 memset(payload_read, 0xFF, payload_size); 1995 _blob_io_read_no_split(blob, channel, payload_read, 0, pages_per_payload, blob_op_complete, NULL); 1996 CU_ASSERT(g_bserrno == 0); 1997 CU_ASSERT(memcmp(payload_pattern, payload_read, payload_size) == 0); 1998 1999 spdk_blob_close(blob, blob_op_complete, NULL); 2000 CU_ASSERT(g_bserrno == 0); 2001 2002 spdk_bs_free_io_channel(channel); 2003 2004 /* Unload the blob store */ 2005 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2006 CU_ASSERT(g_bserrno == 0); 2007 g_bs = NULL; 2008 g_blob = NULL; 2009 g_blobid = 0; 2010 2011 free(payload_read); 2012 free(payload_write); 2013 free(payload_pattern); 2014 } 2015 2016 static void 2017 blob_unmap(void) 2018 { 2019 struct spdk_blob_store *bs; 2020 struct spdk_bs_dev *dev; 2021 struct spdk_blob *blob; 2022 struct spdk_io_channel *channel; 2023 spdk_blob_id blobid; 2024 struct spdk_blob_opts opts; 2025 uint8_t payload[4096]; 2026 int i; 2027 2028 dev = init_dev(); 2029 2030 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2031 CU_ASSERT(g_bserrno == 0); 2032 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2033 bs = g_bs; 2034 2035 channel = spdk_bs_alloc_io_channel(bs); 2036 CU_ASSERT(channel != NULL); 2037 2038 spdk_blob_opts_init(&opts); 2039 opts.num_clusters = 10; 2040 2041 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 2042 CU_ASSERT(g_bserrno == 0); 2043 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2044 blobid = g_blobid; 2045 2046 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2047 CU_ASSERT(g_bserrno == 0); 2048 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2049 blob = g_blob; 2050 2051 spdk_blob_resize(blob, 10, blob_op_complete, NULL); 2052 CU_ASSERT(g_bserrno == 0); 2053 2054 memset(payload, 0, sizeof(payload)); 2055 payload[0] = 0xFF; 2056 2057 /* 2058 * Set first byte of every cluster to 0xFF. 2059 * First cluster on device is reserved so let's start from cluster number 1 2060 */ 2061 for (i = 1; i < 11; i++) { 2062 g_dev_buffer[i * SPDK_BLOB_OPTS_CLUSTER_SZ] = 0xFF; 2063 } 2064 2065 /* Confirm writes */ 2066 for (i = 0; i < 10; i++) { 2067 payload[0] = 0; 2068 spdk_blob_io_read(blob, channel, &payload, i * SPDK_BLOB_OPTS_CLUSTER_SZ / 4096, 1, 2069 blob_op_complete, NULL); 2070 CU_ASSERT(g_bserrno == 0); 2071 CU_ASSERT(payload[0] == 0xFF); 2072 } 2073 2074 /* Mark some clusters as unallocated */ 2075 blob->active.clusters[1] = 0; 2076 blob->active.clusters[2] = 0; 2077 blob->active.clusters[3] = 0; 2078 blob->active.clusters[6] = 0; 2079 blob->active.clusters[8] = 0; 2080 2081 /* Unmap clusters by resizing to 0 */ 2082 spdk_blob_resize(blob, 0, blob_op_complete, NULL); 2083 CU_ASSERT(g_bserrno == 0); 2084 2085 spdk_blob_sync_md(blob, blob_op_complete, NULL); 2086 CU_ASSERT(g_bserrno == 0); 2087 2088 /* Confirm that only 'allocated' clusters were unmapped */ 2089 for (i = 1; i < 11; i++) { 2090 switch (i) { 2091 case 2: 2092 case 3: 2093 case 4: 2094 case 7: 2095 case 9: 2096 CU_ASSERT(g_dev_buffer[i * SPDK_BLOB_OPTS_CLUSTER_SZ] == 0xFF); 2097 break; 2098 default: 2099 CU_ASSERT(g_dev_buffer[i * SPDK_BLOB_OPTS_CLUSTER_SZ] == 0); 2100 break; 2101 } 2102 } 2103 2104 spdk_blob_close(blob, blob_op_complete, NULL); 2105 CU_ASSERT(g_bserrno == 0); 2106 2107 spdk_bs_free_io_channel(channel); 2108 2109 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2110 CU_ASSERT(g_bserrno == 0); 2111 g_bs = NULL; 2112 } 2113 2114 2115 static void 2116 blob_iter(void) 2117 { 2118 struct spdk_blob_store *bs; 2119 struct spdk_bs_dev *dev; 2120 struct spdk_blob *blob; 2121 spdk_blob_id blobid; 2122 2123 dev = init_dev(); 2124 2125 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2126 CU_ASSERT(g_bserrno == 0); 2127 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2128 bs = g_bs; 2129 2130 spdk_bs_iter_first(bs, blob_op_with_handle_complete, NULL); 2131 CU_ASSERT(g_blob == NULL); 2132 CU_ASSERT(g_bserrno == -ENOENT); 2133 2134 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 2135 CU_ASSERT(g_bserrno == 0); 2136 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2137 blobid = g_blobid; 2138 2139 spdk_bs_iter_first(bs, blob_op_with_handle_complete, NULL); 2140 CU_ASSERT(g_blob != NULL); 2141 CU_ASSERT(g_bserrno == 0); 2142 blob = g_blob; 2143 CU_ASSERT(spdk_blob_get_id(blob) == blobid); 2144 2145 spdk_bs_iter_next(bs, blob, blob_op_with_handle_complete, NULL); 2146 CU_ASSERT(g_blob == NULL); 2147 CU_ASSERT(g_bserrno == -ENOENT); 2148 2149 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2150 CU_ASSERT(g_bserrno == 0); 2151 g_bs = NULL; 2152 } 2153 2154 static void 2155 blob_xattr(void) 2156 { 2157 struct spdk_blob_store *bs; 2158 struct spdk_bs_dev *dev; 2159 struct spdk_blob *blob; 2160 spdk_blob_id blobid; 2161 uint64_t length; 2162 int rc; 2163 const char *name1, *name2; 2164 const void *value; 2165 size_t value_len; 2166 struct spdk_xattr_names *names; 2167 2168 dev = init_dev(); 2169 2170 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2171 CU_ASSERT(g_bserrno == 0); 2172 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2173 bs = g_bs; 2174 2175 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 2176 CU_ASSERT(g_bserrno == 0); 2177 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2178 blobid = g_blobid; 2179 2180 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2181 CU_ASSERT(g_bserrno == 0); 2182 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2183 blob = g_blob; 2184 2185 /* Test that set_xattr fails if md_ro flag is set. */ 2186 blob->md_ro = true; 2187 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 2188 CU_ASSERT(rc == -EPERM); 2189 2190 blob->md_ro = false; 2191 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 2192 CU_ASSERT(rc == 0); 2193 2194 length = 2345; 2195 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 2196 CU_ASSERT(rc == 0); 2197 2198 /* Overwrite "length" xattr. */ 2199 length = 3456; 2200 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 2201 CU_ASSERT(rc == 0); 2202 2203 /* get_xattr should still work even if md_ro flag is set. */ 2204 value = NULL; 2205 blob->md_ro = true; 2206 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 2207 CU_ASSERT(rc == 0); 2208 SPDK_CU_ASSERT_FATAL(value != NULL); 2209 CU_ASSERT(*(uint64_t *)value == length); 2210 CU_ASSERT(value_len == 8); 2211 blob->md_ro = false; 2212 2213 rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len); 2214 CU_ASSERT(rc == -ENOENT); 2215 2216 names = NULL; 2217 rc = spdk_blob_get_xattr_names(blob, &names); 2218 CU_ASSERT(rc == 0); 2219 SPDK_CU_ASSERT_FATAL(names != NULL); 2220 CU_ASSERT(spdk_xattr_names_get_count(names) == 2); 2221 name1 = spdk_xattr_names_get_name(names, 0); 2222 SPDK_CU_ASSERT_FATAL(name1 != NULL); 2223 CU_ASSERT(!strcmp(name1, "name") || !strcmp(name1, "length")); 2224 name2 = spdk_xattr_names_get_name(names, 1); 2225 SPDK_CU_ASSERT_FATAL(name2 != NULL); 2226 CU_ASSERT(!strcmp(name2, "name") || !strcmp(name2, "length")); 2227 CU_ASSERT(strcmp(name1, name2)); 2228 spdk_xattr_names_free(names); 2229 2230 /* Confirm that remove_xattr fails if md_ro is set to true. */ 2231 blob->md_ro = true; 2232 rc = spdk_blob_remove_xattr(blob, "name"); 2233 CU_ASSERT(rc == -EPERM); 2234 2235 blob->md_ro = false; 2236 rc = spdk_blob_remove_xattr(blob, "name"); 2237 CU_ASSERT(rc == 0); 2238 2239 rc = spdk_blob_remove_xattr(blob, "foobar"); 2240 CU_ASSERT(rc == -ENOENT); 2241 2242 /* Set internal xattr */ 2243 length = 7898; 2244 rc = _spdk_blob_set_xattr(blob, "internal", &length, sizeof(length), true); 2245 CU_ASSERT(rc == 0); 2246 rc = _spdk_blob_get_xattr_value(blob, "internal", &value, &value_len, true); 2247 CU_ASSERT(rc == 0); 2248 CU_ASSERT(*(uint64_t *)value == length); 2249 /* try to get public xattr with same name */ 2250 rc = spdk_blob_get_xattr_value(blob, "internal", &value, &value_len); 2251 CU_ASSERT(rc != 0); 2252 rc = _spdk_blob_get_xattr_value(blob, "internal", &value, &value_len, false); 2253 CU_ASSERT(rc != 0); 2254 /* Check if SPDK_BLOB_INTERNAL_XATTR is set */ 2255 CU_ASSERT((blob->invalid_flags & SPDK_BLOB_INTERNAL_XATTR) == 2256 SPDK_BLOB_INTERNAL_XATTR) 2257 2258 spdk_blob_close(blob, blob_op_complete, NULL); 2259 2260 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2261 2262 /* Check if xattrs are persisted */ 2263 dev = init_dev(); 2264 2265 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 2266 CU_ASSERT(g_bserrno == 0); 2267 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2268 2269 bs = g_bs; 2270 2271 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2272 CU_ASSERT(g_bserrno == 0); 2273 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2274 blob = g_blob; 2275 2276 rc = _spdk_blob_get_xattr_value(blob, "internal", &value, &value_len, true); 2277 CU_ASSERT(rc == 0); 2278 CU_ASSERT(*(uint64_t *)value == length); 2279 2280 /* try to get internal xattr trough public call */ 2281 rc = spdk_blob_get_xattr_value(blob, "internal", &value, &value_len); 2282 CU_ASSERT(rc != 0); 2283 2284 rc = _spdk_blob_remove_xattr(blob, "internal", true); 2285 CU_ASSERT(rc == 0); 2286 2287 CU_ASSERT((blob->invalid_flags & SPDK_BLOB_INTERNAL_XATTR) == 0); 2288 2289 CU_ASSERT(g_bserrno == 0); 2290 g_bs = NULL; 2291 } 2292 2293 static void 2294 bs_load(void) 2295 { 2296 struct spdk_bs_dev *dev; 2297 spdk_blob_id blobid; 2298 struct spdk_blob *blob; 2299 struct spdk_bs_super_block *super_block; 2300 uint64_t length; 2301 int rc; 2302 const void *value; 2303 size_t value_len; 2304 struct spdk_bs_opts opts; 2305 2306 dev = init_dev(); 2307 spdk_bs_opts_init(&opts); 2308 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 2309 2310 /* Initialize a new blob store */ 2311 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2312 CU_ASSERT(g_bserrno == 0); 2313 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2314 2315 /* Try to open a blobid that does not exist */ 2316 spdk_bs_open_blob(g_bs, 0, blob_op_with_handle_complete, NULL); 2317 CU_ASSERT(g_bserrno == -ENOENT); 2318 CU_ASSERT(g_blob == NULL); 2319 2320 /* Create a blob */ 2321 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2322 CU_ASSERT(g_bserrno == 0); 2323 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2324 blobid = g_blobid; 2325 2326 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 2327 CU_ASSERT(g_bserrno == 0); 2328 CU_ASSERT(g_blob != NULL); 2329 blob = g_blob; 2330 2331 /* Try again to open valid blob but without the upper bit set */ 2332 spdk_bs_open_blob(g_bs, blobid & 0xFFFFFFFF, blob_op_with_handle_complete, NULL); 2333 CU_ASSERT(g_bserrno == -ENOENT); 2334 CU_ASSERT(g_blob == NULL); 2335 2336 /* Set some xattrs */ 2337 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 2338 CU_ASSERT(rc == 0); 2339 2340 length = 2345; 2341 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 2342 CU_ASSERT(rc == 0); 2343 2344 /* Resize the blob */ 2345 spdk_blob_resize(blob, 10, blob_op_complete, NULL); 2346 CU_ASSERT(g_bserrno == 0); 2347 2348 spdk_blob_close(blob, blob_op_complete, NULL); 2349 CU_ASSERT(g_bserrno == 0); 2350 blob = NULL; 2351 g_blob = NULL; 2352 g_blobid = SPDK_BLOBID_INVALID; 2353 2354 /* Unload the blob store */ 2355 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2356 CU_ASSERT(g_bserrno == 0); 2357 g_bs = NULL; 2358 g_blob = NULL; 2359 g_blobid = 0; 2360 2361 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 2362 CU_ASSERT(super_block->clean == 1); 2363 2364 /* Load should fail for device with an unsupported blocklen */ 2365 dev = init_dev(); 2366 dev->blocklen = SPDK_BS_PAGE_SIZE * 2; 2367 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 2368 CU_ASSERT(g_bserrno == -EINVAL); 2369 2370 /* Load should when max_md_ops is set to zero */ 2371 dev = init_dev(); 2372 spdk_bs_opts_init(&opts); 2373 opts.max_md_ops = 0; 2374 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2375 CU_ASSERT(g_bserrno == -EINVAL); 2376 2377 /* Load should when max_channel_ops is set to zero */ 2378 dev = init_dev(); 2379 spdk_bs_opts_init(&opts); 2380 opts.max_channel_ops = 0; 2381 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2382 CU_ASSERT(g_bserrno == -EINVAL); 2383 2384 /* Load an existing blob store */ 2385 dev = init_dev(); 2386 spdk_bs_opts_init(&opts); 2387 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 2388 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2389 CU_ASSERT(g_bserrno == 0); 2390 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2391 2392 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 2393 CU_ASSERT(super_block->clean == 1); 2394 CU_ASSERT(super_block->size == dev->blockcnt * dev->blocklen); 2395 2396 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 2397 CU_ASSERT(g_bserrno == 0); 2398 CU_ASSERT(g_blob != NULL); 2399 blob = g_blob; 2400 2401 /* Verify that blobstore is marked dirty after first metadata sync */ 2402 spdk_blob_sync_md(blob, blob_op_complete, NULL); 2403 CU_ASSERT(super_block->clean == 1); 2404 2405 /* Get the xattrs */ 2406 value = NULL; 2407 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 2408 CU_ASSERT(rc == 0); 2409 SPDK_CU_ASSERT_FATAL(value != NULL); 2410 CU_ASSERT(*(uint64_t *)value == length); 2411 CU_ASSERT(value_len == 8); 2412 2413 rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len); 2414 CU_ASSERT(rc == -ENOENT); 2415 2416 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 2417 2418 spdk_blob_close(blob, blob_op_complete, NULL); 2419 CU_ASSERT(g_bserrno == 0); 2420 blob = NULL; 2421 g_blob = NULL; 2422 2423 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2424 CU_ASSERT(g_bserrno == 0); 2425 g_bs = NULL; 2426 2427 /* Load should fail: bdev size < saved size */ 2428 dev = init_dev(); 2429 dev->blockcnt /= 2; 2430 2431 spdk_bs_opts_init(&opts); 2432 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 2433 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2434 2435 CU_ASSERT(g_bserrno == -EILSEQ); 2436 2437 /* Load should succeed: bdev size > saved size */ 2438 dev = init_dev(); 2439 dev->blockcnt *= 4; 2440 2441 spdk_bs_opts_init(&opts); 2442 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 2443 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2444 2445 CU_ASSERT(g_bserrno == 0); 2446 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2447 2448 2449 /* Test compatibility mode */ 2450 2451 dev = init_dev(); 2452 super_block->size = 0; 2453 super_block->crc = _spdk_blob_md_page_calc_crc(super_block); 2454 2455 spdk_bs_opts_init(&opts); 2456 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 2457 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2458 CU_ASSERT(g_bserrno == 0); 2459 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2460 2461 /* Create a blob */ 2462 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2463 CU_ASSERT(g_bserrno == 0); 2464 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2465 2466 /* Blobstore should update number of blocks in super_block */ 2467 CU_ASSERT(super_block->size == dev->blockcnt * dev->blocklen); 2468 CU_ASSERT(super_block->clean == 0); 2469 2470 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2471 CU_ASSERT(g_bserrno == 0); 2472 CU_ASSERT(super_block->clean == 1); 2473 g_bs = NULL; 2474 2475 } 2476 2477 static void 2478 bs_load_custom_cluster_size(void) 2479 { 2480 struct spdk_bs_dev *dev; 2481 struct spdk_bs_super_block *super_block; 2482 struct spdk_bs_opts opts; 2483 uint32_t custom_cluster_size = 4194304; /* 4MiB */ 2484 uint32_t cluster_sz; 2485 uint64_t total_clusters; 2486 2487 dev = init_dev(); 2488 spdk_bs_opts_init(&opts); 2489 opts.cluster_sz = custom_cluster_size; 2490 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 2491 2492 /* Initialize a new blob store */ 2493 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2494 CU_ASSERT(g_bserrno == 0); 2495 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2496 cluster_sz = g_bs->cluster_sz; 2497 total_clusters = g_bs->total_clusters; 2498 2499 /* Unload the blob store */ 2500 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2501 CU_ASSERT(g_bserrno == 0); 2502 g_bs = NULL; 2503 g_blob = NULL; 2504 g_blobid = 0; 2505 2506 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 2507 CU_ASSERT(super_block->clean == 1); 2508 2509 /* Load an existing blob store */ 2510 dev = init_dev(); 2511 spdk_bs_opts_init(&opts); 2512 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 2513 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2514 CU_ASSERT(g_bserrno == 0); 2515 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2516 /* Compare cluster size and number to one after initialization */ 2517 CU_ASSERT(cluster_sz == g_bs->cluster_sz); 2518 CU_ASSERT(total_clusters == g_bs->total_clusters); 2519 2520 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 2521 CU_ASSERT(super_block->clean == 1); 2522 CU_ASSERT(super_block->size == dev->blockcnt * dev->blocklen); 2523 2524 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2525 CU_ASSERT(g_bserrno == 0); 2526 CU_ASSERT(super_block->clean == 1); 2527 g_bs = NULL; 2528 } 2529 2530 static void 2531 bs_type(void) 2532 { 2533 struct spdk_bs_dev *dev; 2534 struct spdk_bs_opts opts; 2535 2536 dev = init_dev(); 2537 spdk_bs_opts_init(&opts); 2538 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 2539 2540 /* Initialize a new blob store */ 2541 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2542 CU_ASSERT(g_bserrno == 0); 2543 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2544 2545 /* Unload the blob store */ 2546 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2547 CU_ASSERT(g_bserrno == 0); 2548 g_bs = NULL; 2549 g_blob = NULL; 2550 g_blobid = 0; 2551 2552 /* Load non existing blobstore type */ 2553 dev = init_dev(); 2554 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "NONEXISTING"); 2555 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2556 CU_ASSERT(g_bserrno != 0); 2557 2558 /* Load with empty blobstore type */ 2559 dev = init_dev(); 2560 memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype)); 2561 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2562 CU_ASSERT(g_bserrno == 0); 2563 2564 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2565 CU_ASSERT(g_bserrno == 0); 2566 g_bs = NULL; 2567 2568 /* Initialize a new blob store with empty bstype */ 2569 dev = init_dev(); 2570 memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype)); 2571 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2572 CU_ASSERT(g_bserrno == 0); 2573 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2574 2575 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2576 CU_ASSERT(g_bserrno == 0); 2577 g_bs = NULL; 2578 2579 /* Load non existing blobstore type */ 2580 dev = init_dev(); 2581 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "NONEXISTING"); 2582 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2583 CU_ASSERT(g_bserrno != 0); 2584 2585 /* Load with empty blobstore type */ 2586 dev = init_dev(); 2587 memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype)); 2588 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2589 CU_ASSERT(g_bserrno == 0); 2590 2591 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2592 CU_ASSERT(g_bserrno == 0); 2593 g_bs = NULL; 2594 } 2595 2596 static void 2597 bs_super_block(void) 2598 { 2599 struct spdk_bs_dev *dev; 2600 struct spdk_bs_super_block *super_block; 2601 struct spdk_bs_opts opts; 2602 struct spdk_bs_super_block_ver1 super_block_v1; 2603 2604 dev = init_dev(); 2605 spdk_bs_opts_init(&opts); 2606 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 2607 2608 /* Initialize a new blob store */ 2609 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2610 CU_ASSERT(g_bserrno == 0); 2611 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2612 2613 /* Unload the blob store */ 2614 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2615 CU_ASSERT(g_bserrno == 0); 2616 g_bs = NULL; 2617 g_blob = NULL; 2618 g_blobid = 0; 2619 2620 /* Load an existing blob store with version newer than supported */ 2621 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 2622 super_block->version++; 2623 2624 dev = init_dev(); 2625 memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype)); 2626 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2627 CU_ASSERT(g_bserrno != 0); 2628 2629 /* Create a new blob store with super block version 1 */ 2630 dev = init_dev(); 2631 super_block_v1.version = 1; 2632 memcpy(super_block_v1.signature, "SPDKBLOB", sizeof(super_block_v1.signature)); 2633 super_block_v1.length = 0x1000; 2634 super_block_v1.clean = 1; 2635 super_block_v1.super_blob = 0xFFFFFFFFFFFFFFFF; 2636 super_block_v1.cluster_size = 0x100000; 2637 super_block_v1.used_page_mask_start = 0x01; 2638 super_block_v1.used_page_mask_len = 0x01; 2639 super_block_v1.used_cluster_mask_start = 0x02; 2640 super_block_v1.used_cluster_mask_len = 0x01; 2641 super_block_v1.md_start = 0x03; 2642 super_block_v1.md_len = 0x40; 2643 memset(super_block_v1.reserved, 0, 4036); 2644 super_block_v1.crc = _spdk_blob_md_page_calc_crc(&super_block_v1); 2645 memcpy(g_dev_buffer, &super_block_v1, sizeof(struct spdk_bs_super_block_ver1)); 2646 2647 memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype)); 2648 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2649 CU_ASSERT(g_bserrno == 0); 2650 2651 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2652 CU_ASSERT(g_bserrno == 0); 2653 g_bs = NULL; 2654 } 2655 2656 /* 2657 * Create a blobstore and then unload it. 2658 */ 2659 static void 2660 bs_unload(void) 2661 { 2662 struct spdk_bs_dev *dev; 2663 struct spdk_blob_store *bs; 2664 spdk_blob_id blobid; 2665 struct spdk_blob *blob; 2666 2667 dev = init_dev(); 2668 2669 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2670 CU_ASSERT(g_bserrno == 0); 2671 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2672 bs = g_bs; 2673 2674 /* Create a blob and open it. */ 2675 g_bserrno = -1; 2676 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 2677 CU_ASSERT(g_bserrno == 0); 2678 CU_ASSERT(g_blobid > 0); 2679 blobid = g_blobid; 2680 2681 g_bserrno = -1; 2682 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2683 CU_ASSERT(g_bserrno == 0); 2684 CU_ASSERT(g_blob != NULL); 2685 blob = g_blob; 2686 2687 /* Try to unload blobstore, should fail with open blob */ 2688 g_bserrno = -1; 2689 spdk_bs_unload(bs, bs_op_complete, NULL); 2690 CU_ASSERT(g_bserrno == -EBUSY); 2691 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2692 2693 /* Close the blob, then successfully unload blobstore */ 2694 g_bserrno = -1; 2695 spdk_blob_close(blob, blob_op_complete, NULL); 2696 CU_ASSERT(g_bserrno == 0); 2697 2698 g_bserrno = -1; 2699 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2700 CU_ASSERT(g_bserrno == 0); 2701 g_bs = NULL; 2702 } 2703 2704 /* 2705 * Create a blobstore with a cluster size different than the default, and ensure it is 2706 * persisted. 2707 */ 2708 static void 2709 bs_cluster_sz(void) 2710 { 2711 struct spdk_bs_dev *dev; 2712 struct spdk_bs_opts opts; 2713 uint32_t cluster_sz; 2714 2715 /* Set cluster size to zero */ 2716 dev = init_dev(); 2717 spdk_bs_opts_init(&opts); 2718 opts.cluster_sz = 0; 2719 2720 /* Initialize a new blob store */ 2721 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2722 CU_ASSERT(g_bserrno == -EINVAL); 2723 SPDK_CU_ASSERT_FATAL(g_bs == NULL); 2724 2725 /* 2726 * Set cluster size to blobstore page size, 2727 * to work it is required to be at least twice the blobstore page size. 2728 */ 2729 dev = init_dev(); 2730 spdk_bs_opts_init(&opts); 2731 opts.cluster_sz = SPDK_BS_PAGE_SIZE; 2732 2733 /* Initialize a new blob store */ 2734 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2735 CU_ASSERT(g_bserrno == -ENOMEM); 2736 SPDK_CU_ASSERT_FATAL(g_bs == NULL); 2737 2738 /* 2739 * Set cluster size to lower than page size, 2740 * to work it is required to be at least twice the blobstore page size. 2741 */ 2742 dev = init_dev(); 2743 spdk_bs_opts_init(&opts); 2744 opts.cluster_sz = SPDK_BS_PAGE_SIZE - 1; 2745 2746 /* Initialize a new blob store */ 2747 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2748 CU_ASSERT(g_bserrno == -EINVAL); 2749 SPDK_CU_ASSERT_FATAL(g_bs == NULL); 2750 2751 /* Set cluster size to twice the default */ 2752 dev = init_dev(); 2753 spdk_bs_opts_init(&opts); 2754 opts.cluster_sz *= 2; 2755 cluster_sz = opts.cluster_sz; 2756 2757 /* Initialize a new blob store */ 2758 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2759 CU_ASSERT(g_bserrno == 0); 2760 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2761 2762 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 2763 2764 /* Unload the blob store */ 2765 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2766 CU_ASSERT(g_bserrno == 0); 2767 g_bs = NULL; 2768 g_blob = NULL; 2769 g_blobid = 0; 2770 2771 dev = init_dev(); 2772 /* Load an existing blob store */ 2773 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2774 CU_ASSERT(g_bserrno == 0); 2775 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2776 2777 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 2778 2779 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2780 CU_ASSERT(g_bserrno == 0); 2781 g_bs = NULL; 2782 } 2783 2784 /* 2785 * Create a blobstore, reload it and ensure total usable cluster count 2786 * stays the same. 2787 */ 2788 static void 2789 bs_usable_clusters(void) 2790 { 2791 struct spdk_bs_dev *dev; 2792 struct spdk_bs_opts opts; 2793 uint32_t clusters; 2794 int i; 2795 2796 /* Init blobstore */ 2797 dev = init_dev(); 2798 spdk_bs_opts_init(&opts); 2799 2800 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2801 CU_ASSERT(g_bserrno == 0); 2802 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2803 2804 clusters = spdk_bs_total_data_cluster_count(g_bs); 2805 2806 /* Unload the blob store */ 2807 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2808 CU_ASSERT(g_bserrno == 0); 2809 g_bs = NULL; 2810 2811 dev = init_dev(); 2812 /* Load an existing blob store */ 2813 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2814 CU_ASSERT(g_bserrno == 0); 2815 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2816 2817 CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters); 2818 2819 /* Create and resize blobs to make sure that useable cluster count won't change */ 2820 for (i = 0; i < 4; i++) { 2821 g_bserrno = -1; 2822 g_blobid = SPDK_BLOBID_INVALID; 2823 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2824 CU_ASSERT(g_bserrno == 0); 2825 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2826 2827 g_bserrno = -1; 2828 g_blob = NULL; 2829 spdk_bs_open_blob(g_bs, g_blobid, blob_op_with_handle_complete, NULL); 2830 CU_ASSERT(g_bserrno == 0); 2831 CU_ASSERT(g_blob != NULL); 2832 2833 spdk_blob_resize(g_blob, 10, blob_op_complete, NULL); 2834 CU_ASSERT(g_bserrno == 0); 2835 2836 g_bserrno = -1; 2837 spdk_blob_close(g_blob, blob_op_complete, NULL); 2838 CU_ASSERT(g_bserrno == 0); 2839 2840 CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters); 2841 } 2842 2843 /* Reload the blob store to make sure that nothing changed */ 2844 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2845 CU_ASSERT(g_bserrno == 0); 2846 g_bs = NULL; 2847 2848 dev = init_dev(); 2849 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2850 CU_ASSERT(g_bserrno == 0); 2851 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2852 2853 CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters); 2854 2855 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2856 CU_ASSERT(g_bserrno == 0); 2857 g_bs = NULL; 2858 } 2859 2860 /* 2861 * Test resizing of the metadata blob. This requires creating enough blobs 2862 * so that one cluster is not enough to fit the metadata for those blobs. 2863 * To induce this condition to happen more quickly, we reduce the cluster 2864 * size to 16KB, which means only 4 4KB blob metadata pages can fit. 2865 */ 2866 static void 2867 bs_resize_md(void) 2868 { 2869 const int CLUSTER_PAGE_COUNT = 4; 2870 const int NUM_BLOBS = CLUSTER_PAGE_COUNT * 4; 2871 struct spdk_bs_dev *dev; 2872 struct spdk_bs_opts opts; 2873 uint32_t cluster_sz; 2874 spdk_blob_id blobids[NUM_BLOBS]; 2875 int i; 2876 2877 2878 dev = init_dev(); 2879 spdk_bs_opts_init(&opts); 2880 opts.cluster_sz = CLUSTER_PAGE_COUNT * 4096; 2881 cluster_sz = opts.cluster_sz; 2882 2883 /* Initialize a new blob store */ 2884 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2885 CU_ASSERT(g_bserrno == 0); 2886 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2887 2888 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 2889 2890 for (i = 0; i < NUM_BLOBS; i++) { 2891 g_bserrno = -1; 2892 g_blobid = SPDK_BLOBID_INVALID; 2893 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2894 CU_ASSERT(g_bserrno == 0); 2895 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2896 blobids[i] = g_blobid; 2897 } 2898 2899 /* Unload the blob store */ 2900 g_bserrno = -1; 2901 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2902 CU_ASSERT(g_bserrno == 0); 2903 2904 /* Load an existing blob store */ 2905 g_bserrno = -1; 2906 g_bs = NULL; 2907 dev = init_dev(); 2908 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2909 CU_ASSERT(g_bserrno == 0); 2910 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2911 2912 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 2913 2914 for (i = 0; i < NUM_BLOBS; i++) { 2915 g_bserrno = -1; 2916 g_blob = NULL; 2917 spdk_bs_open_blob(g_bs, blobids[i], blob_op_with_handle_complete, NULL); 2918 CU_ASSERT(g_bserrno == 0); 2919 CU_ASSERT(g_blob != NULL); 2920 g_bserrno = -1; 2921 spdk_blob_close(g_blob, blob_op_complete, NULL); 2922 CU_ASSERT(g_bserrno == 0); 2923 } 2924 2925 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2926 CU_ASSERT(g_bserrno == 0); 2927 g_bs = NULL; 2928 } 2929 2930 static void 2931 bs_destroy(void) 2932 { 2933 struct spdk_bs_dev *dev; 2934 struct spdk_bs_opts opts; 2935 2936 /* Initialize a new blob store */ 2937 dev = init_dev(); 2938 spdk_bs_opts_init(&opts); 2939 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2940 CU_ASSERT(g_bserrno == 0); 2941 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2942 2943 /* Destroy the blob store */ 2944 g_bserrno = -1; 2945 spdk_bs_destroy(g_bs, bs_op_complete, NULL); 2946 CU_ASSERT(g_bserrno == 0); 2947 2948 /* Loading an non-existent blob store should fail. */ 2949 g_bs = NULL; 2950 dev = init_dev(); 2951 2952 g_bserrno = 0; 2953 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2954 CU_ASSERT(g_bserrno != 0); 2955 } 2956 2957 /* Try to hit all of the corner cases associated with serializing 2958 * a blob to disk 2959 */ 2960 static void 2961 blob_serialize(void) 2962 { 2963 struct spdk_bs_dev *dev; 2964 struct spdk_bs_opts opts; 2965 struct spdk_blob_store *bs; 2966 spdk_blob_id blobid[2]; 2967 struct spdk_blob *blob[2]; 2968 uint64_t i; 2969 char *value; 2970 int rc; 2971 2972 dev = init_dev(); 2973 2974 /* Initialize a new blobstore with very small clusters */ 2975 spdk_bs_opts_init(&opts); 2976 opts.cluster_sz = dev->blocklen * 8; 2977 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2978 CU_ASSERT(g_bserrno == 0); 2979 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2980 bs = g_bs; 2981 2982 /* Create and open two blobs */ 2983 for (i = 0; i < 2; i++) { 2984 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 2985 CU_ASSERT(g_bserrno == 0); 2986 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2987 blobid[i] = g_blobid; 2988 2989 /* Open a blob */ 2990 spdk_bs_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL); 2991 CU_ASSERT(g_bserrno == 0); 2992 CU_ASSERT(g_blob != NULL); 2993 blob[i] = g_blob; 2994 2995 /* Set a fairly large xattr on both blobs to eat up 2996 * metadata space 2997 */ 2998 value = calloc(dev->blocklen - 64, sizeof(char)); 2999 SPDK_CU_ASSERT_FATAL(value != NULL); 3000 memset(value, i, dev->blocklen / 2); 3001 rc = spdk_blob_set_xattr(blob[i], "name", value, dev->blocklen - 64); 3002 CU_ASSERT(rc == 0); 3003 free(value); 3004 } 3005 3006 /* Resize the blobs, alternating 1 cluster at a time. 3007 * This thwarts run length encoding and will cause spill 3008 * over of the extents. 3009 */ 3010 for (i = 0; i < 6; i++) { 3011 spdk_blob_resize(blob[i % 2], (i / 2) + 1, blob_op_complete, NULL); 3012 CU_ASSERT(g_bserrno == 0); 3013 } 3014 3015 for (i = 0; i < 2; i++) { 3016 spdk_blob_sync_md(blob[i], blob_op_complete, NULL); 3017 CU_ASSERT(g_bserrno == 0); 3018 } 3019 3020 /* Close the blobs */ 3021 for (i = 0; i < 2; i++) { 3022 spdk_blob_close(blob[i], blob_op_complete, NULL); 3023 CU_ASSERT(g_bserrno == 0); 3024 } 3025 3026 /* Unload the blobstore */ 3027 spdk_bs_unload(bs, bs_op_complete, NULL); 3028 CU_ASSERT(g_bserrno == 0); 3029 g_bs = NULL; 3030 g_blob = NULL; 3031 g_blobid = 0; 3032 bs = NULL; 3033 3034 dev = init_dev(); 3035 /* Load an existing blob store */ 3036 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3037 CU_ASSERT(g_bserrno == 0); 3038 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3039 bs = g_bs; 3040 3041 for (i = 0; i < 2; i++) { 3042 blob[i] = NULL; 3043 3044 spdk_bs_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL); 3045 CU_ASSERT(g_bserrno == 0); 3046 CU_ASSERT(g_blob != NULL); 3047 blob[i] = g_blob; 3048 3049 CU_ASSERT(spdk_blob_get_num_clusters(blob[i]) == 3); 3050 3051 spdk_blob_close(blob[i], blob_op_complete, NULL); 3052 CU_ASSERT(g_bserrno == 0); 3053 } 3054 3055 spdk_bs_unload(bs, bs_op_complete, NULL); 3056 CU_ASSERT(g_bserrno == 0); 3057 g_bs = NULL; 3058 } 3059 3060 static void 3061 blob_crc(void) 3062 { 3063 struct spdk_blob_store *bs; 3064 struct spdk_bs_dev *dev; 3065 struct spdk_blob *blob; 3066 spdk_blob_id blobid; 3067 uint32_t page_num; 3068 int index; 3069 struct spdk_blob_md_page *page; 3070 3071 dev = init_dev(); 3072 3073 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3074 CU_ASSERT(g_bserrno == 0); 3075 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3076 bs = g_bs; 3077 3078 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 3079 CU_ASSERT(g_bserrno == 0); 3080 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3081 blobid = g_blobid; 3082 3083 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3084 CU_ASSERT(g_bserrno == 0); 3085 CU_ASSERT(g_blob != NULL); 3086 blob = g_blob; 3087 3088 spdk_blob_close(blob, blob_op_complete, NULL); 3089 CU_ASSERT(g_bserrno == 0); 3090 3091 page_num = _spdk_bs_blobid_to_page(blobid); 3092 index = DEV_BUFFER_BLOCKLEN * (bs->md_start + page_num); 3093 page = (struct spdk_blob_md_page *)&g_dev_buffer[index]; 3094 page->crc = 0; 3095 3096 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3097 CU_ASSERT(g_bserrno == -EINVAL); 3098 CU_ASSERT(g_blob == NULL); 3099 g_bserrno = 0; 3100 3101 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 3102 CU_ASSERT(g_bserrno == -EINVAL); 3103 3104 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3105 CU_ASSERT(g_bserrno == 0); 3106 g_bs = NULL; 3107 } 3108 3109 static void 3110 super_block_crc(void) 3111 { 3112 struct spdk_bs_dev *dev; 3113 struct spdk_bs_super_block *super_block; 3114 struct spdk_bs_opts opts; 3115 3116 dev = init_dev(); 3117 spdk_bs_opts_init(&opts); 3118 3119 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3120 CU_ASSERT(g_bserrno == 0); 3121 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3122 3123 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3124 CU_ASSERT(g_bserrno == 0); 3125 g_bs = NULL; 3126 3127 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 3128 super_block->crc = 0; 3129 dev = init_dev(); 3130 3131 /* Load an existing blob store */ 3132 g_bserrno = 0; 3133 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3134 CU_ASSERT(g_bserrno == -EILSEQ); 3135 } 3136 3137 /* For blob dirty shutdown test case we do the following sub-test cases: 3138 * 1 Initialize new blob store and create 1 super blob with some xattrs, then we 3139 * dirty shutdown and reload the blob store and verify the xattrs. 3140 * 2 Resize the blob from 10 clusters to 20 clusters and then dirty shutdown, 3141 * reload the blob store and verify the clusters number. 3142 * 3 Create the second blob and then dirty shutdown, reload the blob store 3143 * and verify the second blob. 3144 * 4 Delete the second blob and then dirty shutdown, reload the blob store 3145 * and verify the second blob is invalid. 3146 * 5 Create the second blob again and also create the third blob, modify the 3147 * md of second blob which makes the md invalid, and then dirty shutdown, 3148 * reload the blob store verify the second blob, it should invalid and also 3149 * verify the third blob, it should correct. 3150 */ 3151 static void 3152 blob_dirty_shutdown(void) 3153 { 3154 int rc; 3155 int index; 3156 struct spdk_bs_dev *dev; 3157 spdk_blob_id blobid1, blobid2, blobid3; 3158 struct spdk_blob *blob; 3159 uint64_t length; 3160 uint64_t free_clusters; 3161 const void *value; 3162 size_t value_len; 3163 uint32_t page_num; 3164 struct spdk_blob_md_page *page; 3165 struct spdk_bs_opts opts; 3166 3167 dev = init_dev(); 3168 spdk_bs_opts_init(&opts); 3169 /* Initialize a new blob store */ 3170 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3171 CU_ASSERT(g_bserrno == 0); 3172 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3173 3174 /* Create first blob */ 3175 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 3176 CU_ASSERT(g_bserrno == 0); 3177 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3178 blobid1 = g_blobid; 3179 3180 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 3181 CU_ASSERT(g_bserrno == 0); 3182 CU_ASSERT(g_blob != NULL); 3183 blob = g_blob; 3184 3185 /* Set some xattrs */ 3186 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 3187 CU_ASSERT(rc == 0); 3188 3189 length = 2345; 3190 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 3191 CU_ASSERT(rc == 0); 3192 3193 /* Resize the blob */ 3194 spdk_blob_resize(blob, 10, blob_op_complete, NULL); 3195 CU_ASSERT(g_bserrno == 0); 3196 3197 /* Set the blob as the super blob */ 3198 spdk_bs_set_super(g_bs, blobid1, blob_op_complete, NULL); 3199 CU_ASSERT(g_bserrno == 0); 3200 3201 free_clusters = spdk_bs_free_cluster_count(g_bs); 3202 3203 spdk_blob_close(blob, blob_op_complete, NULL); 3204 blob = NULL; 3205 g_blob = NULL; 3206 g_blobid = SPDK_BLOBID_INVALID; 3207 3208 /* Dirty shutdown */ 3209 _spdk_bs_free(g_bs); 3210 3211 /* reload blobstore */ 3212 dev = init_dev(); 3213 spdk_bs_opts_init(&opts); 3214 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3215 CU_ASSERT(g_bserrno == 0); 3216 3217 /* Get the super blob */ 3218 spdk_bs_get_super(g_bs, blob_op_with_id_complete, NULL); 3219 CU_ASSERT(g_bserrno == 0); 3220 CU_ASSERT(blobid1 == g_blobid); 3221 3222 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 3223 CU_ASSERT(g_bserrno == 0); 3224 CU_ASSERT(g_blob != NULL); 3225 blob = g_blob; 3226 3227 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 3228 3229 /* Get the xattrs */ 3230 value = NULL; 3231 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 3232 CU_ASSERT(rc == 0); 3233 SPDK_CU_ASSERT_FATAL(value != NULL); 3234 CU_ASSERT(*(uint64_t *)value == length); 3235 CU_ASSERT(value_len == 8); 3236 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 3237 3238 /* Resize the blob */ 3239 spdk_blob_resize(blob, 20, blob_op_complete, NULL); 3240 CU_ASSERT(g_bserrno == 0); 3241 3242 free_clusters = spdk_bs_free_cluster_count(g_bs); 3243 3244 spdk_blob_close(blob, blob_op_complete, NULL); 3245 CU_ASSERT(g_bserrno == 0); 3246 blob = NULL; 3247 g_blob = NULL; 3248 g_blobid = SPDK_BLOBID_INVALID; 3249 3250 /* Dirty shutdown */ 3251 _spdk_bs_free(g_bs); 3252 3253 /* reload the blobstore */ 3254 dev = init_dev(); 3255 spdk_bs_opts_init(&opts); 3256 /* Load an existing blob store */ 3257 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3258 CU_ASSERT(g_bserrno == 0); 3259 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3260 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 3261 CU_ASSERT(g_bserrno == 0); 3262 CU_ASSERT(g_blob != NULL); 3263 blob = g_blob; 3264 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 20); 3265 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 3266 3267 spdk_blob_close(blob, blob_op_complete, NULL); 3268 CU_ASSERT(g_bserrno == 0); 3269 blob = NULL; 3270 g_blob = NULL; 3271 g_blobid = SPDK_BLOBID_INVALID; 3272 3273 /* Create second blob */ 3274 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 3275 CU_ASSERT(g_bserrno == 0); 3276 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3277 blobid2 = g_blobid; 3278 3279 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 3280 CU_ASSERT(g_bserrno == 0); 3281 CU_ASSERT(g_blob != NULL); 3282 blob = g_blob; 3283 3284 /* Set some xattrs */ 3285 rc = spdk_blob_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1); 3286 CU_ASSERT(rc == 0); 3287 3288 length = 5432; 3289 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 3290 CU_ASSERT(rc == 0); 3291 3292 /* Resize the blob */ 3293 spdk_blob_resize(blob, 10, blob_op_complete, NULL); 3294 CU_ASSERT(g_bserrno == 0); 3295 3296 free_clusters = spdk_bs_free_cluster_count(g_bs); 3297 3298 spdk_blob_close(blob, blob_op_complete, NULL); 3299 blob = NULL; 3300 g_blob = NULL; 3301 g_blobid = SPDK_BLOBID_INVALID; 3302 3303 /* Dirty shutdown */ 3304 _spdk_bs_free(g_bs); 3305 3306 /* reload the blobstore */ 3307 dev = init_dev(); 3308 spdk_bs_opts_init(&opts); 3309 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3310 CU_ASSERT(g_bserrno == 0); 3311 3312 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 3313 CU_ASSERT(g_bserrno == 0); 3314 CU_ASSERT(g_blob != NULL); 3315 blob = g_blob; 3316 3317 /* Get the xattrs */ 3318 value = NULL; 3319 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 3320 CU_ASSERT(rc == 0); 3321 SPDK_CU_ASSERT_FATAL(value != NULL); 3322 CU_ASSERT(*(uint64_t *)value == length); 3323 CU_ASSERT(value_len == 8); 3324 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 3325 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 3326 3327 spdk_blob_close(blob, blob_op_complete, NULL); 3328 CU_ASSERT(g_bserrno == 0); 3329 spdk_bs_delete_blob(g_bs, blobid2, blob_op_complete, NULL); 3330 CU_ASSERT(g_bserrno == 0); 3331 3332 free_clusters = spdk_bs_free_cluster_count(g_bs); 3333 3334 /* Dirty shutdown */ 3335 _spdk_bs_free(g_bs); 3336 /* reload the blobstore */ 3337 dev = init_dev(); 3338 spdk_bs_opts_init(&opts); 3339 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3340 CU_ASSERT(g_bserrno == 0); 3341 3342 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 3343 CU_ASSERT(g_bserrno != 0); 3344 CU_ASSERT(g_blob == NULL); 3345 3346 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 3347 CU_ASSERT(g_bserrno == 0); 3348 CU_ASSERT(g_blob != NULL); 3349 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 3350 spdk_blob_close(g_blob, blob_op_complete, NULL); 3351 CU_ASSERT(g_bserrno == 0); 3352 3353 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3354 CU_ASSERT(g_bserrno == 0); 3355 g_bs = NULL; 3356 3357 /* reload the blobstore */ 3358 dev = init_dev(); 3359 spdk_bs_opts_init(&opts); 3360 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3361 CU_ASSERT(g_bserrno == 0); 3362 3363 /* Create second blob */ 3364 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 3365 CU_ASSERT(g_bserrno == 0); 3366 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3367 blobid2 = g_blobid; 3368 3369 /* Create third blob */ 3370 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 3371 CU_ASSERT(g_bserrno == 0); 3372 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3373 blobid3 = g_blobid; 3374 3375 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 3376 CU_ASSERT(g_bserrno == 0); 3377 CU_ASSERT(g_blob != NULL); 3378 blob = g_blob; 3379 3380 /* Set some xattrs for second blob */ 3381 rc = spdk_blob_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1); 3382 CU_ASSERT(rc == 0); 3383 3384 length = 5432; 3385 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 3386 CU_ASSERT(rc == 0); 3387 3388 spdk_blob_close(blob, blob_op_complete, NULL); 3389 blob = NULL; 3390 g_blob = NULL; 3391 g_blobid = SPDK_BLOBID_INVALID; 3392 3393 spdk_bs_open_blob(g_bs, blobid3, blob_op_with_handle_complete, NULL); 3394 CU_ASSERT(g_bserrno == 0); 3395 CU_ASSERT(g_blob != NULL); 3396 blob = g_blob; 3397 3398 /* Set some xattrs for third blob */ 3399 rc = spdk_blob_set_xattr(blob, "name", "log2.txt", strlen("log2.txt") + 1); 3400 CU_ASSERT(rc == 0); 3401 3402 length = 5432; 3403 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 3404 CU_ASSERT(rc == 0); 3405 3406 spdk_blob_close(blob, blob_op_complete, NULL); 3407 blob = NULL; 3408 g_blob = NULL; 3409 g_blobid = SPDK_BLOBID_INVALID; 3410 3411 /* Mark second blob as invalid */ 3412 page_num = _spdk_bs_blobid_to_page(blobid2); 3413 3414 index = DEV_BUFFER_BLOCKLEN * (g_bs->md_start + page_num); 3415 page = (struct spdk_blob_md_page *)&g_dev_buffer[index]; 3416 page->sequence_num = 1; 3417 page->crc = _spdk_blob_md_page_calc_crc(page); 3418 3419 free_clusters = spdk_bs_free_cluster_count(g_bs); 3420 3421 /* Dirty shutdown */ 3422 _spdk_bs_free(g_bs); 3423 /* reload the blobstore */ 3424 dev = init_dev(); 3425 spdk_bs_opts_init(&opts); 3426 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3427 CU_ASSERT(g_bserrno == 0); 3428 3429 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 3430 CU_ASSERT(g_bserrno != 0); 3431 CU_ASSERT(g_blob == NULL); 3432 3433 spdk_bs_open_blob(g_bs, blobid3, blob_op_with_handle_complete, NULL); 3434 CU_ASSERT(g_bserrno == 0); 3435 CU_ASSERT(g_blob != NULL); 3436 blob = g_blob; 3437 3438 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 3439 3440 spdk_blob_close(blob, blob_op_complete, NULL); 3441 blob = NULL; 3442 g_blob = NULL; 3443 g_blobid = SPDK_BLOBID_INVALID; 3444 3445 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3446 CU_ASSERT(g_bserrno == 0); 3447 g_bs = NULL; 3448 } 3449 3450 static void 3451 blob_flags(void) 3452 { 3453 struct spdk_bs_dev *dev; 3454 spdk_blob_id blobid_invalid, blobid_data_ro, blobid_md_ro; 3455 struct spdk_blob *blob_invalid, *blob_data_ro, *blob_md_ro; 3456 struct spdk_bs_opts opts; 3457 int rc; 3458 3459 dev = init_dev(); 3460 spdk_bs_opts_init(&opts); 3461 3462 /* Initialize a new blob store */ 3463 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 3464 CU_ASSERT(g_bserrno == 0); 3465 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3466 3467 /* Create three blobs - one each for testing invalid, data_ro and md_ro flags. */ 3468 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 3469 CU_ASSERT(g_bserrno == 0); 3470 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3471 blobid_invalid = g_blobid; 3472 3473 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 3474 CU_ASSERT(g_bserrno == 0); 3475 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3476 blobid_data_ro = g_blobid; 3477 3478 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 3479 CU_ASSERT(g_bserrno == 0); 3480 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3481 blobid_md_ro = g_blobid; 3482 3483 spdk_bs_open_blob(g_bs, blobid_invalid, blob_op_with_handle_complete, NULL); 3484 CU_ASSERT(g_bserrno == 0); 3485 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3486 blob_invalid = g_blob; 3487 3488 spdk_bs_open_blob(g_bs, blobid_data_ro, blob_op_with_handle_complete, NULL); 3489 CU_ASSERT(g_bserrno == 0); 3490 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3491 blob_data_ro = g_blob; 3492 3493 spdk_bs_open_blob(g_bs, blobid_md_ro, blob_op_with_handle_complete, NULL); 3494 CU_ASSERT(g_bserrno == 0); 3495 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3496 blob_md_ro = g_blob; 3497 3498 /* Change the size of blob_data_ro to check if flags are serialized 3499 * when blob has non zero number of extents */ 3500 spdk_blob_resize(blob_data_ro, 10, blob_op_complete, NULL); 3501 CU_ASSERT(g_bserrno == 0); 3502 3503 /* Set the xattr to check if flags are serialized 3504 * when blob has non zero number of xattrs */ 3505 rc = spdk_blob_set_xattr(blob_md_ro, "name", "log.txt", strlen("log.txt") + 1); 3506 CU_ASSERT(rc == 0); 3507 3508 blob_invalid->invalid_flags = (1ULL << 63); 3509 blob_invalid->state = SPDK_BLOB_STATE_DIRTY; 3510 blob_data_ro->data_ro_flags = (1ULL << 62); 3511 blob_data_ro->state = SPDK_BLOB_STATE_DIRTY; 3512 blob_md_ro->md_ro_flags = (1ULL << 61); 3513 blob_md_ro->state = SPDK_BLOB_STATE_DIRTY; 3514 3515 g_bserrno = -1; 3516 spdk_blob_sync_md(blob_invalid, blob_op_complete, NULL); 3517 CU_ASSERT(g_bserrno == 0); 3518 g_bserrno = -1; 3519 spdk_blob_sync_md(blob_data_ro, blob_op_complete, NULL); 3520 CU_ASSERT(g_bserrno == 0); 3521 g_bserrno = -1; 3522 spdk_blob_sync_md(blob_md_ro, blob_op_complete, NULL); 3523 CU_ASSERT(g_bserrno == 0); 3524 3525 g_bserrno = -1; 3526 spdk_blob_close(blob_invalid, blob_op_complete, NULL); 3527 CU_ASSERT(g_bserrno == 0); 3528 blob_invalid = NULL; 3529 g_bserrno = -1; 3530 spdk_blob_close(blob_data_ro, blob_op_complete, NULL); 3531 CU_ASSERT(g_bserrno == 0); 3532 blob_data_ro = NULL; 3533 g_bserrno = -1; 3534 spdk_blob_close(blob_md_ro, blob_op_complete, NULL); 3535 CU_ASSERT(g_bserrno == 0); 3536 blob_md_ro = NULL; 3537 3538 g_blob = NULL; 3539 g_blobid = SPDK_BLOBID_INVALID; 3540 3541 /* Unload the blob store */ 3542 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3543 CU_ASSERT(g_bserrno == 0); 3544 g_bs = NULL; 3545 3546 /* Load an existing blob store */ 3547 dev = init_dev(); 3548 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3549 CU_ASSERT(g_bserrno == 0); 3550 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3551 3552 g_blob = NULL; 3553 g_bserrno = 0; 3554 spdk_bs_open_blob(g_bs, blobid_invalid, blob_op_with_handle_complete, NULL); 3555 CU_ASSERT(g_bserrno != 0); 3556 CU_ASSERT(g_blob == NULL); 3557 3558 g_blob = NULL; 3559 g_bserrno = -1; 3560 spdk_bs_open_blob(g_bs, blobid_data_ro, blob_op_with_handle_complete, NULL); 3561 CU_ASSERT(g_bserrno == 0); 3562 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3563 blob_data_ro = g_blob; 3564 /* If an unknown data_ro flag was found, the blob should be marked both data and md read-only. */ 3565 CU_ASSERT(blob_data_ro->data_ro == true); 3566 CU_ASSERT(blob_data_ro->md_ro == true); 3567 CU_ASSERT(spdk_blob_get_num_clusters(blob_data_ro) == 10); 3568 3569 g_blob = NULL; 3570 g_bserrno = -1; 3571 spdk_bs_open_blob(g_bs, blobid_md_ro, blob_op_with_handle_complete, NULL); 3572 CU_ASSERT(g_bserrno == 0); 3573 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3574 blob_md_ro = g_blob; 3575 CU_ASSERT(blob_md_ro->data_ro == false); 3576 CU_ASSERT(blob_md_ro->md_ro == true); 3577 3578 g_bserrno = -1; 3579 spdk_blob_sync_md(blob_md_ro, blob_op_complete, NULL); 3580 CU_ASSERT(g_bserrno == 0); 3581 3582 spdk_blob_close(blob_data_ro, blob_op_complete, NULL); 3583 CU_ASSERT(g_bserrno == 0); 3584 spdk_blob_close(blob_md_ro, blob_op_complete, NULL); 3585 CU_ASSERT(g_bserrno == 0); 3586 3587 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3588 CU_ASSERT(g_bserrno == 0); 3589 } 3590 3591 static void 3592 bs_version(void) 3593 { 3594 struct spdk_bs_super_block *super; 3595 struct spdk_bs_dev *dev; 3596 struct spdk_bs_opts opts; 3597 spdk_blob_id blobid; 3598 3599 dev = init_dev(); 3600 spdk_bs_opts_init(&opts); 3601 3602 /* Initialize a new blob store */ 3603 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 3604 CU_ASSERT(g_bserrno == 0); 3605 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3606 3607 /* Unload the blob store */ 3608 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3609 CU_ASSERT(g_bserrno == 0); 3610 g_bs = NULL; 3611 3612 /* 3613 * Change the bs version on disk. This will allow us to 3614 * test that the version does not get modified automatically 3615 * when loading and unloading the blobstore. 3616 */ 3617 super = (struct spdk_bs_super_block *)&g_dev_buffer[0]; 3618 CU_ASSERT(super->version == SPDK_BS_VERSION); 3619 CU_ASSERT(super->clean == 1); 3620 super->version = 2; 3621 /* 3622 * Version 2 metadata does not have a used blobid mask, so clear 3623 * those fields in the super block and zero the corresponding 3624 * region on "disk". We will use this to ensure blob IDs are 3625 * correctly reconstructed. 3626 */ 3627 memset(&g_dev_buffer[super->used_blobid_mask_start * SPDK_BS_PAGE_SIZE], 0, 3628 super->used_blobid_mask_len * SPDK_BS_PAGE_SIZE); 3629 super->used_blobid_mask_start = 0; 3630 super->used_blobid_mask_len = 0; 3631 super->crc = _spdk_blob_md_page_calc_crc(super); 3632 3633 /* Load an existing blob store */ 3634 dev = init_dev(); 3635 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3636 CU_ASSERT(g_bserrno == 0); 3637 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3638 CU_ASSERT(super->clean == 1); 3639 3640 /* 3641 * Create a blob - just to make sure that when we unload it 3642 * results in writing the super block (since metadata pages 3643 * were allocated. 3644 */ 3645 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 3646 CU_ASSERT(g_bserrno == 0); 3647 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3648 blobid = g_blobid; 3649 3650 /* Unload the blob store */ 3651 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3652 CU_ASSERT(g_bserrno == 0); 3653 g_bs = NULL; 3654 CU_ASSERT(super->version == 2); 3655 CU_ASSERT(super->used_blobid_mask_start == 0); 3656 CU_ASSERT(super->used_blobid_mask_len == 0); 3657 3658 dev = init_dev(); 3659 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3660 CU_ASSERT(g_bserrno == 0); 3661 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3662 3663 g_blob = NULL; 3664 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 3665 CU_ASSERT(g_bserrno == 0); 3666 CU_ASSERT(g_blob != NULL); 3667 3668 spdk_blob_close(g_blob, blob_op_complete, NULL); 3669 CU_ASSERT(g_bserrno == 0); 3670 3671 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3672 CU_ASSERT(g_bserrno == 0); 3673 g_bs = NULL; 3674 CU_ASSERT(super->version == 2); 3675 CU_ASSERT(super->used_blobid_mask_start == 0); 3676 CU_ASSERT(super->used_blobid_mask_len == 0); 3677 } 3678 3679 static void 3680 blob_set_xattrs(void) 3681 { 3682 struct spdk_blob_store *bs; 3683 struct spdk_bs_dev *dev; 3684 struct spdk_blob *blob; 3685 struct spdk_blob_opts opts; 3686 spdk_blob_id blobid; 3687 const void *value; 3688 size_t value_len; 3689 int rc; 3690 3691 dev = init_dev(); 3692 3693 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3694 CU_ASSERT(g_bserrno == 0); 3695 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3696 bs = g_bs; 3697 3698 /* Create blob with extra attributes */ 3699 spdk_blob_opts_init(&opts); 3700 3701 opts.xattrs.names = g_xattr_names; 3702 opts.xattrs.get_value = _get_xattr_value; 3703 opts.xattrs.count = 3; 3704 opts.xattrs.ctx = &g_ctx; 3705 3706 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 3707 CU_ASSERT(g_bserrno == 0); 3708 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3709 blobid = g_blobid; 3710 3711 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3712 CU_ASSERT(g_bserrno == 0); 3713 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3714 blob = g_blob; 3715 3716 /* Get the xattrs */ 3717 value = NULL; 3718 3719 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[0], &value, &value_len); 3720 CU_ASSERT(rc == 0); 3721 SPDK_CU_ASSERT_FATAL(value != NULL); 3722 CU_ASSERT(value_len == strlen(g_xattr_values[0])); 3723 CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len); 3724 3725 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[1], &value, &value_len); 3726 CU_ASSERT(rc == 0); 3727 SPDK_CU_ASSERT_FATAL(value != NULL); 3728 CU_ASSERT(value_len == strlen(g_xattr_values[1])); 3729 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len); 3730 3731 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[2], &value, &value_len); 3732 CU_ASSERT(rc == 0); 3733 SPDK_CU_ASSERT_FATAL(value != NULL); 3734 CU_ASSERT(value_len == strlen(g_xattr_values[2])); 3735 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len); 3736 3737 /* Try to get non existing attribute */ 3738 3739 rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len); 3740 CU_ASSERT(rc == -ENOENT); 3741 3742 spdk_blob_close(blob, blob_op_complete, NULL); 3743 CU_ASSERT(g_bserrno == 0); 3744 blob = NULL; 3745 g_blob = NULL; 3746 g_blobid = SPDK_BLOBID_INVALID; 3747 3748 /* NULL callback */ 3749 spdk_blob_opts_init(&opts); 3750 opts.xattrs.names = g_xattr_names; 3751 opts.xattrs.get_value = NULL; 3752 opts.xattrs.count = 1; 3753 opts.xattrs.ctx = &g_ctx; 3754 3755 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 3756 CU_ASSERT(g_bserrno == -EINVAL); 3757 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3758 3759 /* NULL values */ 3760 spdk_blob_opts_init(&opts); 3761 opts.xattrs.names = g_xattr_names; 3762 opts.xattrs.get_value = _get_xattr_value_null; 3763 opts.xattrs.count = 1; 3764 opts.xattrs.ctx = NULL; 3765 3766 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 3767 CU_ASSERT(g_bserrno == -EINVAL); 3768 3769 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3770 CU_ASSERT(g_bserrno == 0); 3771 g_bs = NULL; 3772 3773 } 3774 3775 static void 3776 blob_thin_prov_alloc(void) 3777 { 3778 struct spdk_blob_store *bs; 3779 struct spdk_bs_dev *dev; 3780 struct spdk_blob *blob; 3781 struct spdk_blob_opts opts; 3782 spdk_blob_id blobid; 3783 uint64_t free_clusters; 3784 3785 dev = init_dev(); 3786 3787 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3788 CU_ASSERT(g_bserrno == 0); 3789 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3790 bs = g_bs; 3791 free_clusters = spdk_bs_free_cluster_count(bs); 3792 3793 /* Set blob as thin provisioned */ 3794 spdk_blob_opts_init(&opts); 3795 opts.thin_provision = true; 3796 3797 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 3798 CU_ASSERT(g_bserrno == 0); 3799 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3800 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3801 blobid = g_blobid; 3802 3803 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3804 CU_ASSERT(g_bserrno == 0); 3805 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3806 blob = g_blob; 3807 3808 CU_ASSERT(blob->active.num_clusters == 0); 3809 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0); 3810 3811 /* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */ 3812 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 3813 CU_ASSERT(g_bserrno == 0); 3814 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3815 CU_ASSERT(blob->active.num_clusters == 5); 3816 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 3817 3818 /* Grow it to 1TB - still unallocated */ 3819 spdk_blob_resize(blob, 262144, blob_op_complete, NULL); 3820 CU_ASSERT(g_bserrno == 0); 3821 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3822 CU_ASSERT(blob->active.num_clusters == 262144); 3823 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 262144); 3824 3825 spdk_blob_sync_md(blob, blob_op_complete, NULL); 3826 CU_ASSERT(g_bserrno == 0); 3827 /* Sync must not change anything */ 3828 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3829 CU_ASSERT(blob->active.num_clusters == 262144); 3830 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 262144); 3831 /* Since clusters are not allocated, 3832 * number of metadata pages is expected to be minimal. 3833 */ 3834 CU_ASSERT(blob->active.num_pages == 1); 3835 3836 /* Shrink the blob to 3 clusters - still unallocated */ 3837 spdk_blob_resize(blob, 3, blob_op_complete, NULL); 3838 CU_ASSERT(g_bserrno == 0); 3839 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3840 CU_ASSERT(blob->active.num_clusters == 3); 3841 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 3); 3842 3843 spdk_blob_sync_md(blob, blob_op_complete, NULL); 3844 CU_ASSERT(g_bserrno == 0); 3845 /* Sync must not change anything */ 3846 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3847 CU_ASSERT(blob->active.num_clusters == 3); 3848 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 3); 3849 3850 spdk_blob_close(blob, blob_op_complete, NULL); 3851 CU_ASSERT(g_bserrno == 0); 3852 3853 /* Unload the blob store */ 3854 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3855 CU_ASSERT(g_bserrno == 0); 3856 g_bs = NULL; 3857 g_blob = NULL; 3858 g_blobid = 0; 3859 3860 /* Load an existing blob store */ 3861 dev = init_dev(); 3862 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 3863 CU_ASSERT(g_bserrno == 0); 3864 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3865 3866 bs = g_bs; 3867 3868 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 3869 CU_ASSERT(g_bserrno == 0); 3870 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3871 blob = g_blob; 3872 3873 /* Check that clusters allocation and size is still the same */ 3874 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3875 CU_ASSERT(blob->active.num_clusters == 3); 3876 3877 spdk_blob_close(blob, blob_op_complete, NULL); 3878 CU_ASSERT(g_bserrno == 0); 3879 3880 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 3881 CU_ASSERT(g_bserrno == 0); 3882 3883 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3884 CU_ASSERT(g_bserrno == 0); 3885 g_bs = NULL; 3886 } 3887 3888 static void 3889 blob_insert_cluster_msg(void) 3890 { 3891 struct spdk_blob_store *bs; 3892 struct spdk_bs_dev *dev; 3893 struct spdk_blob *blob; 3894 struct spdk_blob_opts opts; 3895 spdk_blob_id blobid; 3896 uint64_t free_clusters; 3897 3898 dev = init_dev(); 3899 3900 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3901 CU_ASSERT(g_bserrno == 0); 3902 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3903 bs = g_bs; 3904 free_clusters = spdk_bs_free_cluster_count(bs); 3905 3906 /* Set blob as thin provisioned */ 3907 spdk_blob_opts_init(&opts); 3908 opts.thin_provision = true; 3909 opts.num_clusters = 4; 3910 3911 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 3912 CU_ASSERT(g_bserrno == 0); 3913 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3914 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3915 blobid = g_blobid; 3916 3917 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3918 CU_ASSERT(g_bserrno == 0); 3919 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3920 blob = g_blob; 3921 3922 CU_ASSERT(blob->active.num_clusters == 4); 3923 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 4); 3924 CU_ASSERT(blob->active.clusters[1] == 0); 3925 3926 _spdk_bs_claim_cluster(bs, 0xF); 3927 _spdk_blob_insert_cluster_on_md_thread(blob, 1, 0xF, blob_op_complete, NULL); 3928 3929 CU_ASSERT(blob->active.clusters[1] != 0); 3930 3931 spdk_blob_close(blob, blob_op_complete, NULL); 3932 CU_ASSERT(g_bserrno == 0); 3933 3934 /* Unload the blob store */ 3935 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3936 CU_ASSERT(g_bserrno == 0); 3937 g_bs = NULL; 3938 g_blob = NULL; 3939 g_blobid = 0; 3940 3941 /* Load an existing blob store */ 3942 dev = init_dev(); 3943 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 3944 CU_ASSERT(g_bserrno == 0); 3945 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3946 3947 bs = g_bs; 3948 3949 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 3950 CU_ASSERT(g_bserrno == 0); 3951 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3952 blob = g_blob; 3953 3954 CU_ASSERT(blob->active.clusters[1] != 0); 3955 3956 spdk_blob_close(blob, blob_op_complete, NULL); 3957 CU_ASSERT(g_bserrno == 0); 3958 3959 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 3960 CU_ASSERT(g_bserrno == 0); 3961 3962 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3963 CU_ASSERT(g_bserrno == 0); 3964 g_bs = NULL; 3965 } 3966 3967 static void 3968 blob_thin_prov_rw(void) 3969 { 3970 static const uint8_t zero[10 * 4096] = { 0 }; 3971 struct spdk_blob_store *bs; 3972 struct spdk_bs_dev *dev; 3973 struct spdk_blob *blob; 3974 struct spdk_io_channel *channel; 3975 struct spdk_blob_opts opts; 3976 spdk_blob_id blobid; 3977 uint64_t free_clusters; 3978 uint64_t page_size; 3979 uint8_t payload_read[10 * 4096]; 3980 uint8_t payload_write[10 * 4096]; 3981 uint64_t write_bytes; 3982 uint64_t read_bytes; 3983 3984 dev = init_dev(); 3985 3986 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3987 CU_ASSERT(g_bserrno == 0); 3988 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3989 bs = g_bs; 3990 free_clusters = spdk_bs_free_cluster_count(bs); 3991 page_size = spdk_bs_get_page_size(bs); 3992 3993 channel = spdk_bs_alloc_io_channel(bs); 3994 CU_ASSERT(channel != NULL); 3995 3996 spdk_blob_opts_init(&opts); 3997 opts.thin_provision = true; 3998 3999 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 4000 CU_ASSERT(g_bserrno == 0); 4001 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4002 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4003 blobid = g_blobid; 4004 4005 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4006 CU_ASSERT(g_bserrno == 0); 4007 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4008 blob = g_blob; 4009 4010 CU_ASSERT(blob->active.num_clusters == 0); 4011 4012 /* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */ 4013 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 4014 CU_ASSERT(g_bserrno == 0); 4015 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4016 CU_ASSERT(blob->active.num_clusters == 5); 4017 4018 spdk_blob_sync_md(blob, blob_op_complete, NULL); 4019 CU_ASSERT(g_bserrno == 0); 4020 /* Sync must not change anything */ 4021 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4022 CU_ASSERT(blob->active.num_clusters == 5); 4023 4024 /* Payload should be all zeros from unallocated clusters */ 4025 memset(payload_read, 0xFF, sizeof(payload_read)); 4026 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 4027 CU_ASSERT(g_bserrno == 0); 4028 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 4029 4030 write_bytes = g_dev_write_bytes; 4031 read_bytes = g_dev_read_bytes; 4032 4033 memset(payload_write, 0xE5, sizeof(payload_write)); 4034 spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL); 4035 CU_ASSERT(g_bserrno == 0); 4036 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 4037 /* For thin-provisioned blob we need to write 10 pages plus one page metadata and 4038 * read 0 bytes */ 4039 CU_ASSERT(g_dev_write_bytes - write_bytes == page_size * 11); 4040 CU_ASSERT(g_dev_read_bytes - read_bytes == 0); 4041 4042 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 4043 CU_ASSERT(g_bserrno == 0); 4044 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 4045 4046 spdk_blob_close(blob, blob_op_complete, NULL); 4047 CU_ASSERT(g_bserrno == 0); 4048 4049 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 4050 CU_ASSERT(g_bserrno == 0); 4051 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4052 4053 spdk_bs_free_io_channel(channel); 4054 4055 /* Unload the blob store */ 4056 spdk_bs_unload(g_bs, bs_op_complete, NULL); 4057 CU_ASSERT(g_bserrno == 0); 4058 g_bs = NULL; 4059 g_blob = NULL; 4060 g_blobid = 0; 4061 } 4062 4063 static void 4064 blob_thin_prov_rw_iov(void) 4065 { 4066 static const uint8_t zero[10 * 4096] = { 0 }; 4067 struct spdk_blob_store *bs; 4068 struct spdk_bs_dev *dev; 4069 struct spdk_blob *blob; 4070 struct spdk_io_channel *channel; 4071 struct spdk_blob_opts opts; 4072 spdk_blob_id blobid; 4073 uint64_t free_clusters; 4074 uint8_t payload_read[10 * 4096]; 4075 uint8_t payload_write[10 * 4096]; 4076 struct iovec iov_read[3]; 4077 struct iovec iov_write[3]; 4078 4079 dev = init_dev(); 4080 4081 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 4082 CU_ASSERT(g_bserrno == 0); 4083 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4084 bs = g_bs; 4085 free_clusters = spdk_bs_free_cluster_count(bs); 4086 4087 channel = spdk_bs_alloc_io_channel(bs); 4088 CU_ASSERT(channel != NULL); 4089 4090 spdk_blob_opts_init(&opts); 4091 opts.thin_provision = true; 4092 4093 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 4094 CU_ASSERT(g_bserrno == 0); 4095 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4096 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4097 blobid = g_blobid; 4098 4099 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4100 CU_ASSERT(g_bserrno == 0); 4101 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4102 blob = g_blob; 4103 4104 CU_ASSERT(blob->active.num_clusters == 0); 4105 4106 /* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */ 4107 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 4108 CU_ASSERT(g_bserrno == 0); 4109 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4110 CU_ASSERT(blob->active.num_clusters == 5); 4111 4112 spdk_blob_sync_md(blob, blob_op_complete, NULL); 4113 CU_ASSERT(g_bserrno == 0); 4114 /* Sync must not change anything */ 4115 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4116 CU_ASSERT(blob->active.num_clusters == 5); 4117 4118 /* Payload should be all zeros from unallocated clusters */ 4119 memset(payload_read, 0xAA, sizeof(payload_read)); 4120 iov_read[0].iov_base = payload_read; 4121 iov_read[0].iov_len = 3 * 4096; 4122 iov_read[1].iov_base = payload_read + 3 * 4096; 4123 iov_read[1].iov_len = 4 * 4096; 4124 iov_read[2].iov_base = payload_read + 7 * 4096; 4125 iov_read[2].iov_len = 3 * 4096; 4126 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 4127 CU_ASSERT(g_bserrno == 0); 4128 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 4129 4130 memset(payload_write, 0xE5, sizeof(payload_write)); 4131 iov_write[0].iov_base = payload_write; 4132 iov_write[0].iov_len = 1 * 4096; 4133 iov_write[1].iov_base = payload_write + 1 * 4096; 4134 iov_write[1].iov_len = 5 * 4096; 4135 iov_write[2].iov_base = payload_write + 6 * 4096; 4136 iov_write[2].iov_len = 4 * 4096; 4137 4138 spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 4139 CU_ASSERT(g_bserrno == 0); 4140 4141 memset(payload_read, 0xAA, sizeof(payload_read)); 4142 iov_read[0].iov_base = payload_read; 4143 iov_read[0].iov_len = 3 * 4096; 4144 iov_read[1].iov_base = payload_read + 3 * 4096; 4145 iov_read[1].iov_len = 4 * 4096; 4146 iov_read[2].iov_base = payload_read + 7 * 4096; 4147 iov_read[2].iov_len = 3 * 4096; 4148 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 4149 CU_ASSERT(g_bserrno == 0); 4150 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 4151 4152 spdk_blob_close(blob, blob_op_complete, NULL); 4153 CU_ASSERT(g_bserrno == 0); 4154 4155 spdk_bs_free_io_channel(channel); 4156 4157 /* Unload the blob store */ 4158 spdk_bs_unload(g_bs, bs_op_complete, NULL); 4159 CU_ASSERT(g_bserrno == 0); 4160 g_bs = NULL; 4161 g_blob = NULL; 4162 g_blobid = 0; 4163 } 4164 4165 struct iter_ctx { 4166 int current_iter; 4167 spdk_blob_id blobid[4]; 4168 }; 4169 4170 static void 4171 test_iter(void *arg, struct spdk_blob *blob, int bserrno) 4172 { 4173 struct iter_ctx *iter_ctx = arg; 4174 spdk_blob_id blobid; 4175 4176 CU_ASSERT(bserrno == 0); 4177 blobid = spdk_blob_get_id(blob); 4178 CU_ASSERT(blobid == iter_ctx->blobid[iter_ctx->current_iter++]); 4179 } 4180 4181 static void 4182 bs_load_iter(void) 4183 { 4184 struct spdk_bs_dev *dev; 4185 struct iter_ctx iter_ctx = { 0 }; 4186 struct spdk_blob *blob; 4187 int i, rc; 4188 struct spdk_bs_opts opts; 4189 4190 dev = init_dev(); 4191 spdk_bs_opts_init(&opts); 4192 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 4193 4194 /* Initialize a new blob store */ 4195 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 4196 CU_ASSERT(g_bserrno == 0); 4197 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4198 4199 for (i = 0; i < 4; i++) { 4200 g_bserrno = -1; 4201 g_blobid = SPDK_BLOBID_INVALID; 4202 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 4203 CU_ASSERT(g_bserrno == 0); 4204 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4205 iter_ctx.blobid[i] = g_blobid; 4206 4207 g_bserrno = -1; 4208 g_blob = NULL; 4209 spdk_bs_open_blob(g_bs, g_blobid, blob_op_with_handle_complete, NULL); 4210 CU_ASSERT(g_bserrno == 0); 4211 CU_ASSERT(g_blob != NULL); 4212 blob = g_blob; 4213 4214 /* Just save the blobid as an xattr for testing purposes. */ 4215 rc = spdk_blob_set_xattr(blob, "blobid", &g_blobid, sizeof(g_blobid)); 4216 CU_ASSERT(rc == 0); 4217 4218 /* Resize the blob */ 4219 spdk_blob_resize(blob, i, blob_op_complete, NULL); 4220 CU_ASSERT(g_bserrno == 0); 4221 4222 spdk_blob_close(blob, blob_op_complete, NULL); 4223 CU_ASSERT(g_bserrno == 0); 4224 } 4225 4226 g_bserrno = -1; 4227 spdk_bs_unload(g_bs, bs_op_complete, NULL); 4228 CU_ASSERT(g_bserrno == 0); 4229 4230 dev = init_dev(); 4231 spdk_bs_opts_init(&opts); 4232 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 4233 opts.iter_cb_fn = test_iter; 4234 opts.iter_cb_arg = &iter_ctx; 4235 4236 /* Test blob iteration during load after a clean shutdown. */ 4237 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 4238 CU_ASSERT(g_bserrno == 0); 4239 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4240 4241 /* Dirty shutdown */ 4242 _spdk_bs_free(g_bs); 4243 4244 dev = init_dev(); 4245 spdk_bs_opts_init(&opts); 4246 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 4247 opts.iter_cb_fn = test_iter; 4248 iter_ctx.current_iter = 0; 4249 opts.iter_cb_arg = &iter_ctx; 4250 4251 /* Test blob iteration during load after a dirty shutdown. */ 4252 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 4253 CU_ASSERT(g_bserrno == 0); 4254 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4255 4256 spdk_bs_unload(g_bs, bs_op_complete, NULL); 4257 CU_ASSERT(g_bserrno == 0); 4258 g_bs = NULL; 4259 } 4260 4261 static void 4262 blob_snapshot_rw(void) 4263 { 4264 static const uint8_t zero[10 * 4096] = { 0 }; 4265 struct spdk_blob_store *bs; 4266 struct spdk_bs_dev *dev; 4267 struct spdk_blob *blob, *snapshot; 4268 struct spdk_io_channel *channel; 4269 struct spdk_blob_opts opts; 4270 spdk_blob_id blobid, snapshotid; 4271 uint64_t free_clusters; 4272 uint64_t cluster_size; 4273 uint64_t page_size; 4274 uint8_t payload_read[10 * 4096]; 4275 uint8_t payload_write[10 * 4096]; 4276 uint64_t write_bytes; 4277 uint64_t read_bytes; 4278 4279 dev = init_dev(); 4280 4281 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 4282 CU_ASSERT(g_bserrno == 0); 4283 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4284 bs = g_bs; 4285 free_clusters = spdk_bs_free_cluster_count(bs); 4286 cluster_size = spdk_bs_get_cluster_size(bs); 4287 page_size = spdk_bs_get_page_size(bs); 4288 4289 channel = spdk_bs_alloc_io_channel(bs); 4290 CU_ASSERT(channel != NULL); 4291 4292 spdk_blob_opts_init(&opts); 4293 opts.thin_provision = true; 4294 opts.num_clusters = 5; 4295 4296 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 4297 CU_ASSERT(g_bserrno == 0); 4298 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4299 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4300 blobid = g_blobid; 4301 4302 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4303 CU_ASSERT(g_bserrno == 0); 4304 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4305 blob = g_blob; 4306 4307 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 4308 4309 memset(payload_read, 0xFF, sizeof(payload_read)); 4310 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 4311 CU_ASSERT(g_bserrno == 0); 4312 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 4313 4314 memset(payload_write, 0xE5, sizeof(payload_write)); 4315 spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL); 4316 CU_ASSERT(g_bserrno == 0); 4317 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 4318 4319 /* Create snapshot from blob */ 4320 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 4321 CU_ASSERT(g_bserrno == 0); 4322 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4323 snapshotid = g_blobid; 4324 4325 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 4326 CU_ASSERT(g_bserrno == 0); 4327 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4328 snapshot = g_blob; 4329 CU_ASSERT(snapshot->data_ro == true) 4330 CU_ASSERT(snapshot->md_ro == true) 4331 4332 CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 5) 4333 4334 write_bytes = g_dev_write_bytes; 4335 read_bytes = g_dev_read_bytes; 4336 4337 memset(payload_write, 0xAA, sizeof(payload_write)); 4338 spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL); 4339 CU_ASSERT(g_bserrno == 0); 4340 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 4341 4342 /* For a clone we need to allocate and copy one cluster, update one page of metadata 4343 * and then write 10 pages of payload. 4344 */ 4345 CU_ASSERT(g_dev_write_bytes - write_bytes == page_size * 11 + cluster_size); 4346 CU_ASSERT(g_dev_read_bytes - read_bytes == cluster_size); 4347 4348 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 4349 CU_ASSERT(g_bserrno == 0); 4350 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 4351 4352 /* Data on snapshot should not change after write to clone */ 4353 memset(payload_write, 0xE5, sizeof(payload_write)); 4354 spdk_blob_io_read(snapshot, channel, payload_read, 4, 10, blob_op_complete, NULL); 4355 CU_ASSERT(g_bserrno == 0); 4356 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 4357 4358 spdk_blob_close(blob, blob_op_complete, NULL); 4359 CU_ASSERT(g_bserrno == 0); 4360 4361 spdk_blob_close(snapshot, blob_op_complete, NULL); 4362 CU_ASSERT(g_bserrno == 0); 4363 4364 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 4365 CU_ASSERT(g_bserrno == 0); 4366 4367 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 4368 CU_ASSERT(g_bserrno == 0); 4369 4370 spdk_bs_free_io_channel(channel); 4371 4372 /* Unload the blob store */ 4373 spdk_bs_unload(g_bs, bs_op_complete, NULL); 4374 CU_ASSERT(g_bserrno == 0); 4375 g_bs = NULL; 4376 g_blob = NULL; 4377 g_blobid = 0; 4378 } 4379 4380 static void 4381 blob_snapshot_rw_iov(void) 4382 { 4383 static const uint8_t zero[10 * 4096] = { 0 }; 4384 struct spdk_blob_store *bs; 4385 struct spdk_bs_dev *dev; 4386 struct spdk_blob *blob, *snapshot; 4387 struct spdk_io_channel *channel; 4388 struct spdk_blob_opts opts; 4389 spdk_blob_id blobid, snapshotid; 4390 uint64_t free_clusters; 4391 uint8_t payload_read[10 * 4096]; 4392 uint8_t payload_write[10 * 4096]; 4393 struct iovec iov_read[3]; 4394 struct iovec iov_write[3]; 4395 4396 dev = init_dev(); 4397 4398 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 4399 CU_ASSERT(g_bserrno == 0); 4400 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4401 bs = g_bs; 4402 free_clusters = spdk_bs_free_cluster_count(bs); 4403 4404 channel = spdk_bs_alloc_io_channel(bs); 4405 CU_ASSERT(channel != NULL); 4406 4407 spdk_blob_opts_init(&opts); 4408 opts.thin_provision = true; 4409 opts.num_clusters = 5; 4410 4411 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 4412 CU_ASSERT(g_bserrno == 0); 4413 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4414 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4415 blobid = g_blobid; 4416 4417 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4418 CU_ASSERT(g_bserrno == 0); 4419 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4420 blob = g_blob; 4421 4422 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 4423 4424 /* Create snapshot from blob */ 4425 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 4426 CU_ASSERT(g_bserrno == 0); 4427 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4428 snapshotid = g_blobid; 4429 4430 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 4431 CU_ASSERT(g_bserrno == 0); 4432 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4433 snapshot = g_blob; 4434 CU_ASSERT(snapshot->data_ro == true) 4435 CU_ASSERT(snapshot->md_ro == true) 4436 CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 5); 4437 4438 /* Payload should be all zeros from unallocated clusters */ 4439 memset(payload_read, 0xAA, sizeof(payload_read)); 4440 iov_read[0].iov_base = payload_read; 4441 iov_read[0].iov_len = 3 * 4096; 4442 iov_read[1].iov_base = payload_read + 3 * 4096; 4443 iov_read[1].iov_len = 4 * 4096; 4444 iov_read[2].iov_base = payload_read + 7 * 4096; 4445 iov_read[2].iov_len = 3 * 4096; 4446 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 4447 CU_ASSERT(g_bserrno == 0); 4448 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 4449 4450 memset(payload_write, 0xE5, sizeof(payload_write)); 4451 iov_write[0].iov_base = payload_write; 4452 iov_write[0].iov_len = 1 * 4096; 4453 iov_write[1].iov_base = payload_write + 1 * 4096; 4454 iov_write[1].iov_len = 5 * 4096; 4455 iov_write[2].iov_base = payload_write + 6 * 4096; 4456 iov_write[2].iov_len = 4 * 4096; 4457 4458 spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 4459 CU_ASSERT(g_bserrno == 0); 4460 4461 memset(payload_read, 0xAA, sizeof(payload_read)); 4462 iov_read[0].iov_base = payload_read; 4463 iov_read[0].iov_len = 3 * 4096; 4464 iov_read[1].iov_base = payload_read + 3 * 4096; 4465 iov_read[1].iov_len = 4 * 4096; 4466 iov_read[2].iov_base = payload_read + 7 * 4096; 4467 iov_read[2].iov_len = 3 * 4096; 4468 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 4469 CU_ASSERT(g_bserrno == 0); 4470 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 4471 4472 spdk_blob_close(blob, blob_op_complete, NULL); 4473 CU_ASSERT(g_bserrno == 0); 4474 4475 spdk_blob_close(snapshot, blob_op_complete, NULL); 4476 CU_ASSERT(g_bserrno == 0); 4477 4478 spdk_bs_free_io_channel(channel); 4479 4480 /* Unload the blob store */ 4481 spdk_bs_unload(g_bs, bs_op_complete, NULL); 4482 CU_ASSERT(g_bserrno == 0); 4483 g_bs = NULL; 4484 g_blob = NULL; 4485 g_blobid = 0; 4486 } 4487 4488 /** 4489 * Inflate / decouple parent rw unit tests. 4490 * 4491 * -------------- 4492 * original blob: 0 1 2 3 4 4493 * ,---------+---------+---------+---------+---------. 4494 * snapshot |xxxxxxxxx|xxxxxxxxx|xxxxxxxxx|xxxxxxxxx| - | 4495 * +---------+---------+---------+---------+---------+ 4496 * snapshot2 | - |yyyyyyyyy| - |yyyyyyyyy| - | 4497 * +---------+---------+---------+---------+---------+ 4498 * blob | - |zzzzzzzzz| - | - | - | 4499 * '---------+---------+---------+---------+---------' 4500 * . . . . . . 4501 * -------- . . . . . . 4502 * inflate: . . . . . . 4503 * ,---------+---------+---------+---------+---------. 4504 * blob |xxxxxxxxx|zzzzzzzzz|xxxxxxxxx|yyyyyyyyy|000000000| 4505 * '---------+---------+---------+---------+---------' 4506 * 4507 * NOTE: needs to allocate 4 clusters, thin provisioning removed, dependency 4508 * on snapshot2 and snapshot removed . . . 4509 * . . . . . . 4510 * ---------------- . . . . . . 4511 * decouple parent: . . . . . . 4512 * ,---------+---------+---------+---------+---------. 4513 * snapshot |xxxxxxxxx|xxxxxxxxx|xxxxxxxxx|xxxxxxxxx| - | 4514 * +---------+---------+---------+---------+---------+ 4515 * blob | - |zzzzzzzzz| - |yyyyyyyyy| - | 4516 * '---------+---------+---------+---------+---------' 4517 * 4518 * NOTE: needs to allocate 1 cluster, 3 clusters unallocated, dependency 4519 * on snapshot2 removed and on snapshot still exists. Snapshot2 4520 * should remain a clone of snapshot. 4521 */ 4522 static void 4523 _blob_inflate_rw(bool decouple_parent) 4524 { 4525 struct spdk_blob_store *bs; 4526 struct spdk_bs_dev *dev; 4527 struct spdk_blob *blob, *snapshot, *snapshot2; 4528 struct spdk_io_channel *channel; 4529 struct spdk_blob_opts opts; 4530 spdk_blob_id blobid, snapshotid, snapshot2id; 4531 uint64_t free_clusters; 4532 uint64_t cluster_size; 4533 4534 uint64_t payload_size; 4535 uint8_t *payload_read; 4536 uint8_t *payload_write; 4537 uint8_t *payload_clone; 4538 4539 uint64_t pages_per_cluster; 4540 uint64_t pages_per_payload; 4541 4542 int i; 4543 spdk_blob_id ids[2]; 4544 size_t count; 4545 4546 dev = init_dev(); 4547 4548 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 4549 CU_ASSERT(g_bserrno == 0); 4550 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4551 bs = g_bs; 4552 4553 free_clusters = spdk_bs_free_cluster_count(bs); 4554 cluster_size = spdk_bs_get_cluster_size(bs); 4555 pages_per_cluster = cluster_size / spdk_bs_get_page_size(bs); 4556 pages_per_payload = pages_per_cluster * 5; 4557 4558 payload_size = cluster_size * 5; 4559 4560 payload_read = malloc(payload_size); 4561 SPDK_CU_ASSERT_FATAL(payload_read != NULL); 4562 4563 payload_write = malloc(payload_size); 4564 SPDK_CU_ASSERT_FATAL(payload_write != NULL); 4565 4566 payload_clone = malloc(payload_size); 4567 SPDK_CU_ASSERT_FATAL(payload_clone != NULL); 4568 4569 channel = spdk_bs_alloc_io_channel(bs); 4570 SPDK_CU_ASSERT_FATAL(channel != NULL); 4571 4572 /* Create blob */ 4573 spdk_blob_opts_init(&opts); 4574 opts.thin_provision = true; 4575 opts.num_clusters = 5; 4576 4577 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 4578 CU_ASSERT(g_bserrno == 0); 4579 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4580 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4581 blobid = g_blobid; 4582 4583 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4584 CU_ASSERT(g_bserrno == 0); 4585 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4586 blob = g_blob; 4587 4588 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 4589 4590 /* 1) Initial read should return zeroed payload */ 4591 memset(payload_read, 0xFF, payload_size); 4592 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, 4593 blob_op_complete, NULL); 4594 CU_ASSERT(g_bserrno == 0); 4595 CU_ASSERT(spdk_mem_all_zero(payload_read, payload_size)); 4596 4597 /* Fill whole blob with a pattern, except last cluster (to be sure it 4598 * isn't allocated) */ 4599 memset(payload_write, 0xE5, payload_size - cluster_size); 4600 spdk_blob_io_write(blob, channel, payload_write, 0, pages_per_payload - 4601 pages_per_cluster, blob_op_complete, NULL); 4602 CU_ASSERT(g_bserrno == 0); 4603 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 4604 4605 /* 2) Create snapshot from blob (first level) */ 4606 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 4607 CU_ASSERT(g_bserrno == 0); 4608 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4609 snapshotid = g_blobid; 4610 4611 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 4612 CU_ASSERT(g_bserrno == 0); 4613 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4614 snapshot = g_blob; 4615 CU_ASSERT(snapshot->data_ro == true) 4616 CU_ASSERT(snapshot->md_ro == true) 4617 4618 CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 5) 4619 4620 /* Write every second cluster with a pattern. 4621 * 4622 * Last cluster shouldn't be written, to be sure that snapshot nor clone 4623 * doesn't allocate it. 4624 * 4625 * payload_clone stores expected result on "blob" read at the time and 4626 * is used only to check data consistency on clone before and after 4627 * inflation. Initially we fill it with a backing snapshots pattern 4628 * used before. 4629 */ 4630 memset(payload_clone, 0xE5, payload_size - cluster_size); 4631 memset(payload_clone + payload_size - cluster_size, 0x00, cluster_size); 4632 memset(payload_write, 0xAA, payload_size); 4633 for (i = 1; i < 5; i += 2) { 4634 spdk_blob_io_write(blob, channel, payload_write, i * pages_per_cluster, 4635 pages_per_cluster, blob_op_complete, NULL); 4636 CU_ASSERT(g_bserrno == 0); 4637 4638 /* Update expected result */ 4639 memcpy(payload_clone + (cluster_size * i), payload_write, 4640 cluster_size); 4641 } 4642 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 4643 4644 /* Check data consistency on clone */ 4645 memset(payload_read, 0xFF, payload_size); 4646 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, 4647 blob_op_complete, NULL); 4648 CU_ASSERT(g_bserrno == 0); 4649 CU_ASSERT(memcmp(payload_clone, payload_read, payload_size) == 0); 4650 4651 /* 3) Create second levels snapshot from blob */ 4652 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 4653 CU_ASSERT(g_bserrno == 0); 4654 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4655 snapshot2id = g_blobid; 4656 4657 spdk_bs_open_blob(bs, snapshot2id, blob_op_with_handle_complete, NULL); 4658 CU_ASSERT(g_bserrno == 0); 4659 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4660 snapshot2 = g_blob; 4661 CU_ASSERT(snapshot2->data_ro == true) 4662 CU_ASSERT(snapshot2->md_ro == true) 4663 4664 CU_ASSERT(spdk_blob_get_num_clusters(snapshot2) == 5) 4665 4666 CU_ASSERT(snapshot2->parent_id == snapshotid); 4667 4668 /* Write one cluster on the top level blob. This cluster (1) covers 4669 * already allocated cluster in the snapshot2, so shouldn't be inflated 4670 * at all */ 4671 spdk_blob_io_write(blob, channel, payload_write, pages_per_cluster, 4672 pages_per_cluster, blob_op_complete, NULL); 4673 CU_ASSERT(g_bserrno == 0); 4674 4675 /* Update expected result */ 4676 memcpy(payload_clone + cluster_size, payload_write, cluster_size); 4677 4678 /* Check data consistency on clone */ 4679 memset(payload_read, 0xFF, payload_size); 4680 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, 4681 blob_op_complete, NULL); 4682 CU_ASSERT(g_bserrno == 0); 4683 CU_ASSERT(memcmp(payload_clone, payload_read, payload_size) == 0); 4684 4685 4686 /* Close all blobs */ 4687 spdk_blob_close(blob, blob_op_complete, NULL); 4688 CU_ASSERT(g_bserrno == 0); 4689 4690 spdk_blob_close(snapshot2, blob_op_complete, NULL); 4691 CU_ASSERT(g_bserrno == 0); 4692 4693 spdk_blob_close(snapshot, blob_op_complete, NULL); 4694 CU_ASSERT(g_bserrno == 0); 4695 4696 /* Check snapshot-clone relations */ 4697 count = 2; 4698 CU_ASSERT(spdk_blob_get_clones(bs, snapshotid, ids, &count) == 0); 4699 CU_ASSERT(count == 1); 4700 CU_ASSERT(ids[0] == snapshot2id); 4701 4702 count = 2; 4703 CU_ASSERT(spdk_blob_get_clones(bs, snapshot2id, ids, &count) == 0); 4704 CU_ASSERT(count == 1); 4705 CU_ASSERT(ids[0] == blobid); 4706 4707 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshot2id); 4708 4709 free_clusters = spdk_bs_free_cluster_count(bs); 4710 if (!decouple_parent) { 4711 /* Do full blob inflation */ 4712 spdk_bs_inflate_blob(bs, channel, blobid, blob_op_complete, NULL); 4713 CU_ASSERT(g_bserrno == 0); 4714 4715 /* All clusters should be inflated (except one already allocated 4716 * in a top level blob) */ 4717 CU_ASSERT(spdk_bs_free_cluster_count(bs) == free_clusters - 4); 4718 4719 /* Check if relation tree updated correctly */ 4720 count = 2; 4721 CU_ASSERT(spdk_blob_get_clones(bs, snapshotid, ids, &count) == 0); 4722 4723 /* snapshotid have one clone */ 4724 CU_ASSERT(count == 1); 4725 CU_ASSERT(ids[0] == snapshot2id); 4726 4727 /* snapshot2id have no clones */ 4728 count = 2; 4729 CU_ASSERT(spdk_blob_get_clones(bs, snapshot2id, ids, &count) == 0); 4730 CU_ASSERT(count == 0); 4731 4732 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == SPDK_BLOBID_INVALID); 4733 } else { 4734 /* Decouple parent of blob */ 4735 spdk_bs_blob_decouple_parent(bs, channel, blobid, blob_op_complete, NULL); 4736 CU_ASSERT(g_bserrno == 0); 4737 4738 /* Only one cluster from a parent should be inflated (second one 4739 * is covered by a cluster written on a top level blob, and 4740 * already allocated) */ 4741 CU_ASSERT(spdk_bs_free_cluster_count(bs) == free_clusters - 1); 4742 4743 /* Check if relation tree updated correctly */ 4744 count = 2; 4745 CU_ASSERT(spdk_blob_get_clones(bs, snapshotid, ids, &count) == 0); 4746 4747 /* snapshotid have two clones now */ 4748 CU_ASSERT(count == 2); 4749 CU_ASSERT(ids[0] == blobid || ids[1] == blobid); 4750 CU_ASSERT(ids[0] == snapshot2id || ids[1] == snapshot2id); 4751 4752 /* snapshot2id have no clones */ 4753 count = 2; 4754 CU_ASSERT(spdk_blob_get_clones(bs, snapshot2id, ids, &count) == 0); 4755 CU_ASSERT(count == 0); 4756 4757 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid); 4758 } 4759 4760 /* Try to delete snapshot2 (should pass) */ 4761 spdk_bs_delete_blob(bs, snapshot2id, blob_op_complete, NULL); 4762 CU_ASSERT(g_bserrno == 0); 4763 4764 /* Try to delete base snapshot (for decouple_parent should fail while 4765 * dependency still exists) */ 4766 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 4767 CU_ASSERT(decouple_parent || g_bserrno == 0); 4768 CU_ASSERT(!decouple_parent || g_bserrno != 0); 4769 4770 /* Reopen blob after snapshot deletion */ 4771 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4772 CU_ASSERT(g_bserrno == 0); 4773 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4774 blob = g_blob; 4775 4776 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 4777 4778 /* Check data consistency on inflated blob */ 4779 memset(payload_read, 0xFF, payload_size); 4780 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, 4781 blob_op_complete, NULL); 4782 CU_ASSERT(g_bserrno == 0); 4783 CU_ASSERT(memcmp(payload_clone, payload_read, payload_size) == 0); 4784 4785 spdk_blob_close(blob, blob_op_complete, NULL); 4786 CU_ASSERT(g_bserrno == 0); 4787 4788 spdk_bs_free_io_channel(channel); 4789 4790 /* Unload the blob store */ 4791 spdk_bs_unload(g_bs, bs_op_complete, NULL); 4792 CU_ASSERT(g_bserrno == 0); 4793 g_bs = NULL; 4794 g_blob = NULL; 4795 g_blobid = 0; 4796 4797 free(payload_read); 4798 free(payload_write); 4799 free(payload_clone); 4800 } 4801 4802 static void 4803 blob_inflate_rw(void) 4804 { 4805 _blob_inflate_rw(false); 4806 _blob_inflate_rw(true); 4807 } 4808 4809 /** 4810 * Snapshot-clones relation test 4811 * 4812 * snapshot 4813 * | 4814 * +-----+-----+ 4815 * | | 4816 * blob(ro) snapshot2 4817 * | | 4818 * clone2 clone 4819 */ 4820 static void 4821 blob_relations(void) 4822 { 4823 struct spdk_blob_store *bs; 4824 struct spdk_bs_dev *dev; 4825 struct spdk_bs_opts bs_opts; 4826 struct spdk_blob_opts opts; 4827 struct spdk_blob *blob, *snapshot, *snapshot2, *clone, *clone2; 4828 spdk_blob_id blobid, cloneid, snapshotid, cloneid2, snapshotid2; 4829 int rc; 4830 size_t count; 4831 spdk_blob_id ids[10] = {}; 4832 4833 dev = init_dev(); 4834 spdk_bs_opts_init(&bs_opts); 4835 snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE"); 4836 4837 spdk_bs_init(dev, &bs_opts, bs_op_with_handle_complete, NULL); 4838 CU_ASSERT(g_bserrno == 0); 4839 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4840 bs = g_bs; 4841 4842 /* 1. Create blob with 10 clusters */ 4843 4844 spdk_blob_opts_init(&opts); 4845 opts.num_clusters = 10; 4846 4847 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 4848 CU_ASSERT(g_bserrno == 0); 4849 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4850 blobid = g_blobid; 4851 4852 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4853 CU_ASSERT(g_bserrno == 0); 4854 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4855 blob = g_blob; 4856 4857 CU_ASSERT(!spdk_blob_is_read_only(blob)); 4858 CU_ASSERT(!spdk_blob_is_snapshot(blob)); 4859 CU_ASSERT(!spdk_blob_is_clone(blob)); 4860 CU_ASSERT(!spdk_blob_is_thin_provisioned(blob)); 4861 4862 /* blob should not have underlying snapshot nor clones */ 4863 CU_ASSERT(blob->parent_id == SPDK_BLOBID_INVALID); 4864 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == SPDK_BLOBID_INVALID); 4865 count = SPDK_COUNTOF(ids); 4866 rc = spdk_blob_get_clones(bs, blobid, ids, &count); 4867 CU_ASSERT(rc == 0); 4868 CU_ASSERT(count == 0); 4869 4870 4871 /* 2. Create snapshot */ 4872 4873 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 4874 CU_ASSERT(g_bserrno == 0); 4875 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4876 snapshotid = g_blobid; 4877 4878 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 4879 CU_ASSERT(g_bserrno == 0); 4880 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4881 snapshot = g_blob; 4882 4883 CU_ASSERT(spdk_blob_is_read_only(snapshot)); 4884 CU_ASSERT(spdk_blob_is_snapshot(snapshot)); 4885 CU_ASSERT(!spdk_blob_is_clone(snapshot)); 4886 CU_ASSERT(snapshot->parent_id == SPDK_BLOBID_INVALID); 4887 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid) == SPDK_BLOBID_INVALID); 4888 4889 /* Check if original blob is converted to the clone of snapshot */ 4890 CU_ASSERT(!spdk_blob_is_read_only(blob)); 4891 CU_ASSERT(!spdk_blob_is_snapshot(blob)); 4892 CU_ASSERT(spdk_blob_is_clone(blob)); 4893 CU_ASSERT(spdk_blob_is_thin_provisioned(blob)); 4894 CU_ASSERT(blob->parent_id == snapshotid); 4895 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid); 4896 4897 count = SPDK_COUNTOF(ids); 4898 rc = spdk_blob_get_clones(bs, snapshotid, ids, &count); 4899 CU_ASSERT(rc == 0); 4900 CU_ASSERT(count == 1); 4901 CU_ASSERT(ids[0] == blobid); 4902 4903 4904 /* 3. Create clone from snapshot */ 4905 4906 spdk_bs_create_clone(bs, snapshotid, NULL, blob_op_with_id_complete, NULL); 4907 CU_ASSERT(g_bserrno == 0); 4908 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4909 cloneid = g_blobid; 4910 4911 spdk_bs_open_blob(bs, cloneid, blob_op_with_handle_complete, NULL); 4912 CU_ASSERT(g_bserrno == 0); 4913 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4914 clone = g_blob; 4915 4916 CU_ASSERT(!spdk_blob_is_read_only(clone)); 4917 CU_ASSERT(!spdk_blob_is_snapshot(clone)); 4918 CU_ASSERT(spdk_blob_is_clone(clone)); 4919 CU_ASSERT(spdk_blob_is_thin_provisioned(clone)); 4920 CU_ASSERT(clone->parent_id == snapshotid); 4921 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid); 4922 4923 count = SPDK_COUNTOF(ids); 4924 rc = spdk_blob_get_clones(bs, cloneid, ids, &count); 4925 CU_ASSERT(rc == 0); 4926 CU_ASSERT(count == 0); 4927 4928 /* Check if clone is on the snapshot's list */ 4929 count = SPDK_COUNTOF(ids); 4930 rc = spdk_blob_get_clones(bs, snapshotid, ids, &count); 4931 CU_ASSERT(rc == 0); 4932 CU_ASSERT(ids[0] == blobid || ids[1] == blobid); 4933 CU_ASSERT(ids[0] == cloneid || ids[1] == cloneid); 4934 4935 4936 /* 4. Create snapshot of the clone */ 4937 4938 spdk_bs_create_snapshot(bs, cloneid, NULL, blob_op_with_id_complete, NULL); 4939 CU_ASSERT(g_bserrno == 0); 4940 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4941 snapshotid2 = g_blobid; 4942 4943 spdk_bs_open_blob(bs, snapshotid2, blob_op_with_handle_complete, NULL); 4944 CU_ASSERT(g_bserrno == 0); 4945 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4946 snapshot2 = g_blob; 4947 4948 CU_ASSERT(spdk_blob_is_read_only(snapshot2)); 4949 CU_ASSERT(spdk_blob_is_snapshot(snapshot2)); 4950 CU_ASSERT(spdk_blob_is_clone(snapshot2)); 4951 CU_ASSERT(snapshot2->parent_id == snapshotid); 4952 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid2) == snapshotid); 4953 4954 /* Check if clone is converted to the clone of snapshot2 and snapshot2 4955 * is a child of snapshot */ 4956 CU_ASSERT(!spdk_blob_is_read_only(clone)); 4957 CU_ASSERT(!spdk_blob_is_snapshot(clone)); 4958 CU_ASSERT(spdk_blob_is_clone(clone)); 4959 CU_ASSERT(spdk_blob_is_thin_provisioned(clone)); 4960 CU_ASSERT(clone->parent_id == snapshotid2); 4961 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid2); 4962 4963 count = SPDK_COUNTOF(ids); 4964 rc = spdk_blob_get_clones(bs, snapshotid2, ids, &count); 4965 CU_ASSERT(rc == 0); 4966 CU_ASSERT(count == 1); 4967 CU_ASSERT(ids[0] == cloneid); 4968 4969 4970 /* 5. Try to create clone from read only blob */ 4971 4972 /* Mark blob as read only */ 4973 spdk_blob_set_read_only(blob); 4974 spdk_blob_sync_md(blob, blob_op_complete, NULL); 4975 CU_ASSERT(g_bserrno == 0); 4976 4977 /* Check if previously created blob is read only clone */ 4978 CU_ASSERT(spdk_blob_is_read_only(blob)); 4979 CU_ASSERT(!spdk_blob_is_snapshot(blob)); 4980 CU_ASSERT(spdk_blob_is_clone(blob)); 4981 CU_ASSERT(spdk_blob_is_thin_provisioned(blob)); 4982 4983 /* Create clone from read only blob */ 4984 spdk_bs_create_clone(bs, blobid, NULL, blob_op_with_id_complete, NULL); 4985 CU_ASSERT(g_bserrno == 0); 4986 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4987 cloneid2 = g_blobid; 4988 4989 spdk_bs_open_blob(bs, cloneid2, blob_op_with_handle_complete, NULL); 4990 CU_ASSERT(g_bserrno == 0); 4991 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4992 clone2 = g_blob; 4993 4994 CU_ASSERT(!spdk_blob_is_read_only(clone2)); 4995 CU_ASSERT(!spdk_blob_is_snapshot(clone2)); 4996 CU_ASSERT(spdk_blob_is_clone(clone2)); 4997 CU_ASSERT(spdk_blob_is_thin_provisioned(clone2)); 4998 4999 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid2) == blobid); 5000 5001 count = SPDK_COUNTOF(ids); 5002 rc = spdk_blob_get_clones(bs, blobid, ids, &count); 5003 CU_ASSERT(rc == 0); 5004 5005 CU_ASSERT(count == 1); 5006 CU_ASSERT(ids[0] == cloneid2); 5007 5008 /* Close blobs */ 5009 5010 spdk_blob_close(clone2, blob_op_complete, NULL); 5011 CU_ASSERT(g_bserrno == 0); 5012 5013 spdk_blob_close(blob, blob_op_complete, NULL); 5014 CU_ASSERT(g_bserrno == 0); 5015 5016 spdk_blob_close(clone, blob_op_complete, NULL); 5017 CU_ASSERT(g_bserrno == 0); 5018 5019 spdk_blob_close(snapshot, blob_op_complete, NULL); 5020 CU_ASSERT(g_bserrno == 0); 5021 5022 spdk_blob_close(snapshot2, blob_op_complete, NULL); 5023 CU_ASSERT(g_bserrno == 0); 5024 5025 /* Try to delete snapshot with created clones */ 5026 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 5027 CU_ASSERT(g_bserrno != 0); 5028 5029 spdk_bs_delete_blob(bs, snapshotid2, blob_op_complete, NULL); 5030 CU_ASSERT(g_bserrno != 0); 5031 5032 spdk_bs_unload(bs, bs_op_complete, NULL); 5033 CU_ASSERT(g_bserrno == 0); 5034 g_bs = NULL; 5035 5036 /* Load an existing blob store */ 5037 dev = init_dev(); 5038 snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE"); 5039 5040 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 5041 CU_ASSERT(g_bserrno == 0); 5042 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 5043 bs = g_bs; 5044 5045 5046 /* NULL ids array should return number of clones in count */ 5047 count = SPDK_COUNTOF(ids); 5048 rc = spdk_blob_get_clones(bs, snapshotid, NULL, &count); 5049 CU_ASSERT(rc == -ENOMEM); 5050 CU_ASSERT(count == 2); 5051 5052 /* incorrect array size */ 5053 count = 1; 5054 rc = spdk_blob_get_clones(bs, snapshotid, ids, &count); 5055 CU_ASSERT(rc == -ENOMEM); 5056 CU_ASSERT(count == 2); 5057 5058 5059 /* Verify structure of loaded blob store */ 5060 5061 /* snapshot */ 5062 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid) == SPDK_BLOBID_INVALID); 5063 5064 count = SPDK_COUNTOF(ids); 5065 rc = spdk_blob_get_clones(bs, snapshotid, ids, &count); 5066 CU_ASSERT(rc == 0); 5067 CU_ASSERT(count == 2); 5068 CU_ASSERT(ids[0] == blobid || ids[1] == blobid); 5069 CU_ASSERT(ids[0] == snapshotid2 || ids[1] == snapshotid2); 5070 5071 /* blob */ 5072 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid); 5073 count = SPDK_COUNTOF(ids); 5074 rc = spdk_blob_get_clones(bs, blobid, ids, &count); 5075 CU_ASSERT(rc == 0); 5076 CU_ASSERT(count == 1); 5077 CU_ASSERT(ids[0] == cloneid2); 5078 5079 /* clone */ 5080 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid2); 5081 count = SPDK_COUNTOF(ids); 5082 rc = spdk_blob_get_clones(bs, cloneid, ids, &count); 5083 CU_ASSERT(rc == 0); 5084 CU_ASSERT(count == 0); 5085 5086 /* snapshot2 */ 5087 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid2) == snapshotid); 5088 count = SPDK_COUNTOF(ids); 5089 rc = spdk_blob_get_clones(bs, snapshotid2, ids, &count); 5090 CU_ASSERT(rc == 0); 5091 CU_ASSERT(count == 1); 5092 CU_ASSERT(ids[0] == cloneid); 5093 5094 /* clone2 */ 5095 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid2) == blobid); 5096 count = SPDK_COUNTOF(ids); 5097 rc = spdk_blob_get_clones(bs, cloneid2, ids, &count); 5098 CU_ASSERT(rc == 0); 5099 CU_ASSERT(count == 0); 5100 5101 /* Try to delete all blobs in the worse possible order */ 5102 5103 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 5104 CU_ASSERT(g_bserrno != 0); 5105 5106 spdk_bs_delete_blob(bs, snapshotid2, blob_op_complete, NULL); 5107 CU_ASSERT(g_bserrno != 0); 5108 5109 spdk_bs_delete_blob(bs, cloneid, blob_op_complete, NULL); 5110 CU_ASSERT(g_bserrno == 0); 5111 5112 spdk_bs_delete_blob(bs, snapshotid2, blob_op_complete, NULL); 5113 CU_ASSERT(g_bserrno == 0); 5114 5115 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 5116 CU_ASSERT(g_bserrno != 0); 5117 5118 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 5119 CU_ASSERT(g_bserrno != 0); 5120 5121 spdk_bs_delete_blob(bs, cloneid2, blob_op_complete, NULL); 5122 CU_ASSERT(g_bserrno == 0); 5123 5124 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 5125 CU_ASSERT(g_bserrno == 0); 5126 5127 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 5128 CU_ASSERT(g_bserrno == 0); 5129 5130 spdk_bs_unload(bs, bs_op_complete, NULL); 5131 CU_ASSERT(g_bserrno == 0); 5132 5133 g_bs = NULL; 5134 } 5135 5136 static void 5137 test_io_write(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel) 5138 { 5139 uint8_t payload_ff[64 * 512]; 5140 uint8_t payload_aa[64 * 512]; 5141 uint8_t payload_00[64 * 512]; 5142 uint8_t *cluster0, *cluster1; 5143 5144 memset(payload_ff, 0xFF, sizeof(payload_ff)); 5145 memset(payload_aa, 0xAA, sizeof(payload_aa)); 5146 memset(payload_00, 0x00, sizeof(payload_00)); 5147 5148 /* Try to perform I/O with io unit = 512 */ 5149 spdk_blob_io_write(blob, channel, payload_ff, 0, 1, blob_op_complete, NULL); 5150 CU_ASSERT(g_bserrno == 0); 5151 5152 /* If thin provisioned is set cluster should be allocated now */ 5153 SPDK_CU_ASSERT_FATAL(blob->active.clusters[0] != 0); 5154 cluster0 = &g_dev_buffer[blob->active.clusters[0] * dev->blocklen]; 5155 5156 /* Each character 0-F symbolizes single io_unit containing 512 bytes block filled with that character. 5157 * Each page is separated by |. Whole block [...] symbolizes one cluster (containing 4 pages). */ 5158 /* cluster0: [ F000 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */ 5159 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 5160 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 31 * 512) == 0); 5161 5162 /* Verify write with offset on first page */ 5163 spdk_blob_io_write(blob, channel, payload_ff, 2, 1, blob_op_complete, NULL); 5164 CU_ASSERT(g_bserrno == 0); 5165 5166 /* cluster0: [ F0F0 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */ 5167 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 5168 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 5169 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 5170 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 5171 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_00, 28 * 512) == 0); 5172 5173 /* Verify write with offset on first page */ 5174 spdk_blob_io_write(blob, channel, payload_ff, 4, 4, blob_op_complete, NULL); 5175 5176 /* cluster0: [ F0F0 FFFF | 0000 0000 | 0000 0000 | 0000 0000 ] */ 5177 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 5178 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 5179 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 5180 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 5181 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_ff, 4 * 512) == 0); 5182 CU_ASSERT(memcmp(cluster0 + 8 * 512, payload_00, 24 * 512) == 0); 5183 5184 /* Verify write with offset on second page */ 5185 spdk_blob_io_write(blob, channel, payload_ff, 8, 4, blob_op_complete, NULL); 5186 5187 /* cluster0: [ F0F0 FFFF | FFFF 0000 | 0000 0000 | 0000 0000 ] */ 5188 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 5189 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 5190 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 5191 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 5192 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_ff, 8 * 512) == 0); 5193 CU_ASSERT(memcmp(cluster0 + 12 * 512, payload_00, 20 * 512) == 0); 5194 5195 /* Verify write across multiple pages */ 5196 spdk_blob_io_write(blob, channel, payload_aa, 4, 8, blob_op_complete, NULL); 5197 5198 /* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 0000 ] */ 5199 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 5200 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 5201 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 5202 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 5203 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0); 5204 CU_ASSERT(memcmp(cluster0 + 12 * 512, payload_00, 20 * 512) == 0); 5205 5206 /* Verify write across multiple clusters */ 5207 spdk_blob_io_write(blob, channel, payload_ff, 28, 8, blob_op_complete, NULL); 5208 5209 SPDK_CU_ASSERT_FATAL(blob->active.clusters[1] != 0); 5210 cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen]; 5211 5212 /* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 5213 * cluster1: [ FFFF 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */ 5214 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 5215 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 5216 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 5217 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 5218 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0); 5219 CU_ASSERT(memcmp(cluster0 + 28 * 512, payload_ff, 4 * 512) == 0); 5220 5221 CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_ff, 4 * 512) == 0); 5222 CU_ASSERT(memcmp(cluster1 + 4 * 512, payload_00, 28 * 512) == 0); 5223 5224 /* Verify write to second cluster */ 5225 spdk_blob_io_write(blob, channel, payload_ff, 32 + 12, 2, blob_op_complete, NULL); 5226 5227 SPDK_CU_ASSERT_FATAL(blob->active.clusters[1] != 0); 5228 cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen]; 5229 5230 /* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 5231 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] */ 5232 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 5233 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 5234 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 5235 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 5236 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0); 5237 CU_ASSERT(memcmp(cluster0 + 28 * 512, payload_ff, 4 * 512) == 0); 5238 5239 CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_ff, 4 * 512) == 0); 5240 CU_ASSERT(memcmp(cluster1 + 4 * 512, payload_00, 8 * 512) == 0); 5241 CU_ASSERT(memcmp(cluster1 + 12 * 512, payload_ff, 2 * 512) == 0); 5242 CU_ASSERT(memcmp(cluster1 + 14 * 512, payload_00, 18 * 512) == 0); 5243 } 5244 5245 static void 5246 test_io_read(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel) 5247 { 5248 uint8_t payload_read[64 * 512]; 5249 uint8_t payload_ff[64 * 512]; 5250 uint8_t payload_aa[64 * 512]; 5251 uint8_t payload_00[64 * 512]; 5252 5253 memset(payload_ff, 0xFF, sizeof(payload_ff)); 5254 memset(payload_aa, 0xAA, sizeof(payload_aa)); 5255 memset(payload_00, 0x00, sizeof(payload_00)); 5256 5257 /* Read only first io unit */ 5258 /* cluster0: [ (F)0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 5259 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 5260 * payload_read: F000 0000 | 0000 0000 ... */ 5261 memset(payload_read, 0x00, sizeof(payload_read)); 5262 spdk_blob_io_read(blob, channel, payload_read, 0, 1, blob_op_complete, NULL); 5263 CU_ASSERT(g_bserrno == 0); 5264 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0); 5265 CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 31 * 512) == 0); 5266 5267 /* Read four io_units starting from offset = 2 5268 * cluster0: [ F0(F0 AA)AA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 5269 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 5270 * payload_read: F0AA 0000 | 0000 0000 ... */ 5271 5272 memset(payload_read, 0x00, sizeof(payload_read)); 5273 spdk_blob_io_read(blob, channel, payload_read, 2, 4, blob_op_complete, NULL); 5274 CU_ASSERT(g_bserrno == 0); 5275 5276 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0); 5277 CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 512) == 0); 5278 CU_ASSERT(memcmp(payload_read + 2 * 512, payload_aa, 512) == 0); 5279 CU_ASSERT(memcmp(payload_read + 3 * 512, payload_aa, 512) == 0); 5280 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 28 * 512) == 0); 5281 5282 /* Read eight io_units across multiple pages 5283 * cluster0: [ F0F0 (AAAA | AAAA) 0000 | 0000 0000 | 0000 FFFF ] 5284 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 5285 * payload_read: AAAA AAAA | 0000 0000 ... */ 5286 memset(payload_read, 0x00, sizeof(payload_read)); 5287 spdk_blob_io_read(blob, channel, payload_read, 4, 8, blob_op_complete, NULL); 5288 CU_ASSERT(g_bserrno == 0); 5289 5290 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_aa, 8 * 512) == 0); 5291 CU_ASSERT(memcmp(payload_read + 8 * 512, payload_00, 24 * 512) == 0); 5292 5293 /* Read eight io_units across multiple clusters 5294 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 (FFFF ] 5295 * cluster1: [ FFFF) 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 5296 * payload_read: FFFF FFFF | 0000 0000 ... */ 5297 memset(payload_read, 0x00, sizeof(payload_read)); 5298 spdk_blob_io_read(blob, channel, payload_read, 28, 8, blob_op_complete, NULL); 5299 CU_ASSERT(g_bserrno == 0); 5300 5301 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 8 * 512) == 0); 5302 CU_ASSERT(memcmp(payload_read + 8 * 512, payload_00, 24 * 512) == 0); 5303 5304 /* Read four io_units from second cluster 5305 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 5306 * cluster1: [ FFFF 0000 | 00(00 FF)00 | 0000 0000 | 0000 0000 ] 5307 * payload_read: 00FF 0000 | 0000 0000 ... */ 5308 memset(payload_read, 0x00, sizeof(payload_read)); 5309 spdk_blob_io_read(blob, channel, payload_read, 32 + 10, 4, blob_op_complete, NULL); 5310 CU_ASSERT(g_bserrno == 0); 5311 5312 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_00, 2 * 512) == 0); 5313 CU_ASSERT(memcmp(payload_read + 2 * 512, payload_ff, 2 * 512) == 0); 5314 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 28 * 512) == 0); 5315 5316 /* Read second cluster 5317 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 5318 * cluster1: [ (FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000) ] 5319 * payload_read: FFFF 0000 | 0000 FF00 ... */ 5320 memset(payload_read, 0x00, sizeof(payload_read)); 5321 spdk_blob_io_read(blob, channel, payload_read, 32, 32, blob_op_complete, NULL); 5322 CU_ASSERT(g_bserrno == 0); 5323 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 4 * 512) == 0); 5324 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 8 * 512) == 0); 5325 CU_ASSERT(memcmp(payload_read + 12 * 512, payload_ff, 2 * 512) == 0); 5326 CU_ASSERT(memcmp(payload_read + 14 * 512, payload_00, 18 * 512) == 0); 5327 5328 /* Read whole two clusters 5329 * cluster0: [ (F0F0 AAAA | AAAA) 0000 | 0000 0000 | 0000 FFFF ] 5330 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000) ] */ 5331 memset(payload_read, 0x00, sizeof(payload_read)); 5332 spdk_blob_io_read(blob, channel, payload_read, 0, 64, blob_op_complete, NULL); 5333 CU_ASSERT(g_bserrno == 0); 5334 5335 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0); 5336 CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 512) == 0); 5337 CU_ASSERT(memcmp(payload_read + 2 * 512, payload_ff, 512) == 0); 5338 CU_ASSERT(memcmp(payload_read + 3 * 512, payload_00, 512) == 0); 5339 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_aa, 8 * 512) == 0); 5340 CU_ASSERT(memcmp(payload_read + 28 * 512, payload_ff, 4 * 512) == 0); 5341 5342 CU_ASSERT(memcmp(payload_read + (32 + 0) * 512, payload_ff, 4 * 512) == 0); 5343 CU_ASSERT(memcmp(payload_read + (32 + 4) * 512, payload_00, 8 * 512) == 0); 5344 CU_ASSERT(memcmp(payload_read + (32 + 12) * 512, payload_ff, 2 * 512) == 0); 5345 CU_ASSERT(memcmp(payload_read + (32 + 14) * 512, payload_00, 18 * 512) == 0); 5346 } 5347 5348 5349 static void 5350 test_io_unmap(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel) 5351 { 5352 uint8_t payload_ff[64 * 512]; 5353 uint8_t payload_aa[64 * 512]; 5354 uint8_t payload_00[64 * 512]; 5355 uint8_t *cluster0, *cluster1; 5356 5357 memset(payload_ff, 0xFF, sizeof(payload_ff)); 5358 memset(payload_aa, 0xAA, sizeof(payload_aa)); 5359 memset(payload_00, 0x00, sizeof(payload_00)); 5360 5361 cluster0 = &g_dev_buffer[blob->active.clusters[0] * dev->blocklen]; 5362 cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen]; 5363 5364 /* Unmap */ 5365 spdk_blob_io_unmap(blob, channel, 0, 64, blob_op_complete, NULL); 5366 5367 CU_ASSERT(g_bserrno == 0); 5368 5369 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_00, 32 * 512) == 0); 5370 CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_00, 32 * 512) == 0); 5371 } 5372 5373 static void 5374 test_io_zeroes(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel) 5375 { 5376 uint8_t payload_ff[64 * 512]; 5377 uint8_t payload_aa[64 * 512]; 5378 uint8_t payload_00[64 * 512]; 5379 uint8_t *cluster0, *cluster1; 5380 5381 memset(payload_ff, 0xFF, sizeof(payload_ff)); 5382 memset(payload_aa, 0xAA, sizeof(payload_aa)); 5383 memset(payload_00, 0x00, sizeof(payload_00)); 5384 5385 cluster0 = &g_dev_buffer[blob->active.clusters[0] * dev->blocklen]; 5386 cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen]; 5387 5388 /* Write zeroes */ 5389 spdk_blob_io_write_zeroes(blob, channel, 0, 64, blob_op_complete, NULL); 5390 5391 CU_ASSERT(g_bserrno == 0); 5392 5393 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_00, 32 * 512) == 0); 5394 CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_00, 32 * 512) == 0); 5395 } 5396 5397 5398 static void 5399 test_iov_write(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel) 5400 { 5401 uint8_t payload_ff[64 * 512]; 5402 uint8_t payload_aa[64 * 512]; 5403 uint8_t payload_00[64 * 512]; 5404 uint8_t *cluster0, *cluster1; 5405 struct iovec iov[4]; 5406 5407 memset(payload_ff, 0xFF, sizeof(payload_ff)); 5408 memset(payload_aa, 0xAA, sizeof(payload_aa)); 5409 memset(payload_00, 0x00, sizeof(payload_00)); 5410 5411 /* Try to perform I/O with io unit = 512 */ 5412 iov[0].iov_base = payload_ff; 5413 iov[0].iov_len = 1 * 512; 5414 spdk_blob_io_writev(blob, channel, iov, 1, 0, 1, blob_op_complete, NULL); 5415 CU_ASSERT(g_bserrno == 0); 5416 5417 /* If thin provisioned is set cluster should be allocated now */ 5418 SPDK_CU_ASSERT_FATAL(blob->active.clusters[0] != 0); 5419 cluster0 = &g_dev_buffer[blob->active.clusters[0] * dev->blocklen]; 5420 5421 /* Each character 0-F symbolizes single io_unit containing 512 bytes block filled with that character. 5422 * Each page is separated by |. Whole block [...] symbolizes one cluster (containing 4 pages). */ 5423 /* cluster0: [ F000 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */ 5424 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 5425 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 31 * 512) == 0); 5426 5427 /* Verify write with offset on first page */ 5428 iov[0].iov_base = payload_ff; 5429 iov[0].iov_len = 1 * 512; 5430 spdk_blob_io_writev(blob, channel, iov, 1, 2, 1, blob_op_complete, NULL); 5431 CU_ASSERT(g_bserrno == 0); 5432 5433 /* cluster0: [ F0F0 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */ 5434 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 5435 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 5436 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 5437 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 5438 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_00, 28 * 512) == 0); 5439 5440 /* Verify write with offset on first page */ 5441 iov[0].iov_base = payload_ff; 5442 iov[0].iov_len = 4 * 512; 5443 spdk_blob_io_writev(blob, channel, iov, 1, 4, 4, blob_op_complete, NULL); 5444 5445 /* cluster0: [ F0F0 FFFF | 0000 0000 | 0000 0000 | 0000 0000 ] */ 5446 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 5447 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 5448 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 5449 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 5450 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_ff, 4 * 512) == 0); 5451 CU_ASSERT(memcmp(cluster0 + 8 * 512, payload_00, 24 * 512) == 0); 5452 5453 /* Verify write with offset on second page */ 5454 iov[0].iov_base = payload_ff; 5455 iov[0].iov_len = 4 * 512; 5456 spdk_blob_io_writev(blob, channel, iov, 1, 8, 4, blob_op_complete, NULL); 5457 5458 /* cluster0: [ F0F0 FFFF | FFFF 0000 | 0000 0000 | 0000 0000 ] */ 5459 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 5460 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 5461 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 5462 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 5463 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_ff, 8 * 512) == 0); 5464 CU_ASSERT(memcmp(cluster0 + 12 * 512, payload_00, 20 * 512) == 0); 5465 5466 /* Verify write across multiple pages */ 5467 iov[0].iov_base = payload_aa; 5468 iov[0].iov_len = 8 * 512; 5469 spdk_blob_io_writev(blob, channel, iov, 1, 4, 8, blob_op_complete, NULL); 5470 5471 /* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 0000 ] */ 5472 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 5473 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 5474 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 5475 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 5476 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0); 5477 CU_ASSERT(memcmp(cluster0 + 12 * 512, payload_00, 20 * 512) == 0); 5478 5479 /* Verify write across multiple clusters */ 5480 5481 iov[0].iov_base = payload_ff; 5482 iov[0].iov_len = 8 * 512; 5483 spdk_blob_io_writev(blob, channel, iov, 1, 28, 8, blob_op_complete, NULL); 5484 5485 SPDK_CU_ASSERT_FATAL(blob->active.clusters[1] != 0); 5486 cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen]; 5487 5488 /* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 5489 * cluster1: [ FFFF 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */ 5490 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 5491 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 5492 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 5493 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 5494 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0); 5495 CU_ASSERT(memcmp(cluster0 + 12 * 512, payload_00, 16 * 512) == 0); 5496 CU_ASSERT(memcmp(cluster0 + 28 * 512, payload_ff, 4 * 512) == 0); 5497 5498 CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_ff, 4 * 512) == 0); 5499 CU_ASSERT(memcmp(cluster1 + 4 * 512, payload_00, 28 * 512) == 0); 5500 5501 /* Verify write to second cluster */ 5502 5503 iov[0].iov_base = payload_ff; 5504 iov[0].iov_len = 2 * 512; 5505 spdk_blob_io_writev(blob, channel, iov, 1, 32 + 12, 2, blob_op_complete, NULL); 5506 5507 SPDK_CU_ASSERT_FATAL(blob->active.clusters[1] != 0); 5508 cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen]; 5509 5510 /* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 5511 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] */ 5512 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 5513 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 5514 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 5515 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 5516 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0); 5517 CU_ASSERT(memcmp(cluster0 + 28 * 512, payload_ff, 4 * 512) == 0); 5518 5519 CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_ff, 4 * 512) == 0); 5520 CU_ASSERT(memcmp(cluster1 + 4 * 512, payload_00, 8 * 512) == 0); 5521 CU_ASSERT(memcmp(cluster1 + 12 * 512, payload_ff, 2 * 512) == 0); 5522 CU_ASSERT(memcmp(cluster1 + 14 * 512, payload_00, 18 * 512) == 0); 5523 } 5524 5525 static void 5526 test_iov_read(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel) 5527 { 5528 uint8_t payload_read[64 * 512]; 5529 uint8_t payload_ff[64 * 512]; 5530 uint8_t payload_aa[64 * 512]; 5531 uint8_t payload_00[64 * 512]; 5532 struct iovec iov[4]; 5533 5534 memset(payload_ff, 0xFF, sizeof(payload_ff)); 5535 memset(payload_aa, 0xAA, sizeof(payload_aa)); 5536 memset(payload_00, 0x00, sizeof(payload_00)); 5537 5538 /* Read only first io unit */ 5539 /* cluster0: [ (F)0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 5540 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 5541 * payload_read: F000 0000 | 0000 0000 ... */ 5542 memset(payload_read, 0x00, sizeof(payload_read)); 5543 iov[0].iov_base = payload_read; 5544 iov[0].iov_len = 1 * 512; 5545 spdk_blob_io_readv(blob, channel, iov, 1, 0, 1, blob_op_complete, NULL); 5546 5547 CU_ASSERT(g_bserrno == 0); 5548 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0); 5549 CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 31 * 512) == 0); 5550 5551 /* Read four io_units starting from offset = 2 5552 * cluster0: [ F0(F0 AA)AA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 5553 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 5554 * payload_read: F0AA 0000 | 0000 0000 ... */ 5555 5556 memset(payload_read, 0x00, sizeof(payload_read)); 5557 iov[0].iov_base = payload_read; 5558 iov[0].iov_len = 4 * 512; 5559 spdk_blob_io_readv(blob, channel, iov, 1, 2, 4, blob_op_complete, NULL); 5560 CU_ASSERT(g_bserrno == 0); 5561 5562 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0); 5563 CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 512) == 0); 5564 CU_ASSERT(memcmp(payload_read + 2 * 512, payload_aa, 512) == 0); 5565 CU_ASSERT(memcmp(payload_read + 3 * 512, payload_aa, 512) == 0); 5566 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 28 * 512) == 0); 5567 5568 /* Read eight io_units across multiple pages 5569 * cluster0: [ F0F0 (AAAA | AAAA) 0000 | 0000 0000 | 0000 FFFF ] 5570 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 5571 * payload_read: AAAA AAAA | 0000 0000 ... */ 5572 memset(payload_read, 0x00, sizeof(payload_read)); 5573 iov[0].iov_base = payload_read; 5574 iov[0].iov_len = 4 * 512; 5575 iov[1].iov_base = payload_read + 4 * 512; 5576 iov[1].iov_len = 4 * 512; 5577 spdk_blob_io_readv(blob, channel, iov, 2, 4, 8, blob_op_complete, NULL); 5578 CU_ASSERT(g_bserrno == 0); 5579 5580 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_aa, 8 * 512) == 0); 5581 CU_ASSERT(memcmp(payload_read + 8 * 512, payload_00, 24 * 512) == 0); 5582 5583 /* Read eight io_units across multiple clusters 5584 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 (FFFF ] 5585 * cluster1: [ FFFF) 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 5586 * payload_read: FFFF FFFF | 0000 0000 ... */ 5587 memset(payload_read, 0x00, sizeof(payload_read)); 5588 iov[0].iov_base = payload_read; 5589 iov[0].iov_len = 2 * 512; 5590 iov[1].iov_base = payload_read + 2 * 512; 5591 iov[1].iov_len = 2 * 512; 5592 iov[2].iov_base = payload_read + 4 * 512; 5593 iov[2].iov_len = 2 * 512; 5594 iov[3].iov_base = payload_read + 6 * 512; 5595 iov[3].iov_len = 2 * 512; 5596 spdk_blob_io_readv(blob, channel, iov, 4, 28, 8, blob_op_complete, NULL); 5597 CU_ASSERT(g_bserrno == 0); 5598 5599 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 8 * 512) == 0); 5600 CU_ASSERT(memcmp(payload_read + 8 * 512, payload_00, 24 * 512) == 0); 5601 5602 /* Read four io_units from second cluster 5603 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 5604 * cluster1: [ FFFF 0000 | 00(00 FF)00 | 0000 0000 | 0000 0000 ] 5605 * payload_read: 00FF 0000 | 0000 0000 ... */ 5606 memset(payload_read, 0x00, sizeof(payload_read)); 5607 iov[0].iov_base = payload_read; 5608 iov[0].iov_len = 1 * 512; 5609 iov[1].iov_base = payload_read + 1 * 512; 5610 iov[1].iov_len = 3 * 512; 5611 spdk_blob_io_readv(blob, channel, iov, 2, 32 + 10, 4, blob_op_complete, NULL); 5612 CU_ASSERT(g_bserrno == 0); 5613 5614 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_00, 2 * 512) == 0); 5615 CU_ASSERT(memcmp(payload_read + 2 * 512, payload_ff, 2 * 512) == 0); 5616 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 28 * 512) == 0); 5617 5618 /* Read second cluster 5619 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 5620 * cluster1: [ (FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000) ] 5621 * payload_read: FFFF 0000 | 0000 FF00 ... */ 5622 memset(payload_read, 0x00, sizeof(payload_read)); 5623 iov[0].iov_base = payload_read; 5624 iov[0].iov_len = 1 * 512; 5625 iov[1].iov_base = payload_read + 1 * 512; 5626 iov[1].iov_len = 2 * 512; 5627 iov[2].iov_base = payload_read + 3 * 512; 5628 iov[2].iov_len = 4 * 512; 5629 iov[3].iov_base = payload_read + 7 * 512; 5630 iov[3].iov_len = 25 * 512; 5631 spdk_blob_io_readv(blob, channel, iov, 4, 32, 32, blob_op_complete, NULL); 5632 CU_ASSERT(g_bserrno == 0); 5633 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 4 * 512) == 0); 5634 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 8 * 512) == 0); 5635 CU_ASSERT(memcmp(payload_read + 12 * 512, payload_ff, 2 * 512) == 0); 5636 CU_ASSERT(memcmp(payload_read + 14 * 512, payload_00, 18 * 512) == 0); 5637 5638 /* Read whole two clusters 5639 * cluster0: [ (F0F0 AAAA | AAAA) 0000 | 0000 0000 | 0000 FFFF ] 5640 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000) ] */ 5641 memset(payload_read, 0x00, sizeof(payload_read)); 5642 iov[0].iov_base = payload_read; 5643 iov[0].iov_len = 1 * 512; 5644 iov[1].iov_base = payload_read + 1 * 512; 5645 iov[1].iov_len = 8 * 512; 5646 iov[2].iov_base = payload_read + 9 * 512; 5647 iov[2].iov_len = 16 * 512; 5648 iov[3].iov_base = payload_read + 25 * 512; 5649 iov[3].iov_len = 39 * 512; 5650 spdk_blob_io_readv(blob, channel, iov, 4, 0, 64, blob_op_complete, NULL); 5651 CU_ASSERT(g_bserrno == 0); 5652 5653 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0); 5654 CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 512) == 0); 5655 CU_ASSERT(memcmp(payload_read + 2 * 512, payload_ff, 512) == 0); 5656 CU_ASSERT(memcmp(payload_read + 3 * 512, payload_00, 512) == 0); 5657 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_aa, 8 * 512) == 0); 5658 CU_ASSERT(memcmp(payload_read + 28 * 512, payload_ff, 4 * 512) == 0); 5659 5660 CU_ASSERT(memcmp(payload_read + (32 + 0) * 512, payload_ff, 4 * 512) == 0); 5661 CU_ASSERT(memcmp(payload_read + (32 + 4) * 512, payload_00, 8 * 512) == 0); 5662 CU_ASSERT(memcmp(payload_read + (32 + 12) * 512, payload_ff, 2 * 512) == 0); 5663 CU_ASSERT(memcmp(payload_read + (32 + 14) * 512, payload_00, 18 * 512) == 0); 5664 } 5665 5666 static void 5667 blob_io_unit(void) 5668 { 5669 struct spdk_bs_opts bsopts; 5670 struct spdk_blob_opts opts; 5671 struct spdk_bs_dev *dev; 5672 struct spdk_blob *blob, *snapshot, *clone; 5673 spdk_blob_id blobid; 5674 struct spdk_io_channel *channel; 5675 5676 /* Create dev with 512 bytes io unit size */ 5677 5678 spdk_bs_opts_init(&bsopts); 5679 bsopts.cluster_sz = SPDK_BS_PAGE_SIZE * 4; /* 8 * 4 = 32 io_unit */ 5680 snprintf(bsopts.bstype.bstype, sizeof(bsopts.bstype.bstype), "TESTTYPE"); 5681 5682 /* Try to initialize a new blob store with unsupported io_unit */ 5683 dev = init_dev(); 5684 dev->blocklen = 512; 5685 dev->blockcnt = DEV_BUFFER_SIZE / dev->blocklen; 5686 5687 /* Initialize a new blob store */ 5688 spdk_bs_init(dev, &bsopts, bs_op_with_handle_complete, NULL); 5689 CU_ASSERT(g_bserrno == 0); 5690 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 5691 5692 CU_ASSERT(spdk_bs_get_io_unit_size(g_bs) == 512); 5693 channel = spdk_bs_alloc_io_channel(g_bs); 5694 5695 /* Create thick provisioned blob */ 5696 spdk_blob_opts_init(&opts); 5697 opts.thin_provision = false; 5698 opts.num_clusters = 32; 5699 5700 spdk_bs_create_blob_ext(g_bs, &opts, blob_op_with_id_complete, NULL); 5701 5702 CU_ASSERT(g_bserrno == 0); 5703 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5704 blobid = g_blobid; 5705 5706 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 5707 CU_ASSERT(g_bserrno == 0); 5708 CU_ASSERT(g_blob != NULL); 5709 blob = g_blob; 5710 5711 test_io_write(dev, blob, channel); 5712 test_io_read(dev, blob, channel); 5713 test_io_zeroes(dev, blob, channel); 5714 5715 test_iov_write(dev, blob, channel); 5716 test_iov_read(dev, blob, channel); 5717 5718 test_io_unmap(dev, blob, channel); 5719 5720 spdk_blob_close(blob, blob_op_complete, NULL); 5721 CU_ASSERT(g_bserrno == 0); 5722 blob = NULL; 5723 g_blob = NULL; 5724 5725 /* Create thin provisioned blob */ 5726 5727 spdk_blob_opts_init(&opts); 5728 opts.thin_provision = true; 5729 opts.num_clusters = 32; 5730 5731 spdk_bs_create_blob_ext(g_bs, &opts, blob_op_with_id_complete, NULL); 5732 CU_ASSERT(g_bserrno == 0); 5733 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5734 blobid = g_blobid; 5735 5736 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 5737 CU_ASSERT(g_bserrno == 0); 5738 CU_ASSERT(g_blob != NULL); 5739 blob = g_blob; 5740 5741 test_io_write(dev, blob, channel); 5742 test_io_read(dev, blob, channel); 5743 5744 test_io_zeroes(dev, blob, channel); 5745 5746 test_iov_write(dev, blob, channel); 5747 test_iov_read(dev, blob, channel); 5748 5749 /* Create snapshot */ 5750 5751 spdk_bs_create_snapshot(g_bs, blobid, NULL, blob_op_with_id_complete, NULL); 5752 CU_ASSERT(g_bserrno == 0); 5753 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5754 blobid = g_blobid; 5755 5756 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 5757 CU_ASSERT(g_bserrno == 0); 5758 CU_ASSERT(g_blob != NULL); 5759 snapshot = g_blob; 5760 5761 spdk_bs_create_clone(g_bs, blobid, NULL, blob_op_with_id_complete, NULL); 5762 CU_ASSERT(g_bserrno == 0); 5763 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5764 blobid = g_blobid; 5765 5766 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 5767 CU_ASSERT(g_bserrno == 0); 5768 CU_ASSERT(g_blob != NULL); 5769 clone = g_blob; 5770 5771 test_io_read(dev, blob, channel); 5772 test_io_read(dev, snapshot, channel); 5773 test_io_read(dev, clone, channel); 5774 5775 test_iov_read(dev, blob, channel); 5776 test_iov_read(dev, snapshot, channel); 5777 test_iov_read(dev, clone, channel); 5778 5779 /* Inflate clone */ 5780 5781 spdk_bs_inflate_blob(g_bs, channel, blobid, blob_op_complete, NULL); 5782 5783 CU_ASSERT(g_bserrno == 0); 5784 5785 test_io_read(dev, clone, channel); 5786 5787 test_io_unmap(dev, clone, channel); 5788 5789 test_iov_write(dev, clone, channel); 5790 test_iov_read(dev, clone, channel); 5791 5792 spdk_blob_close(blob, blob_op_complete, NULL); 5793 spdk_blob_close(snapshot, blob_op_complete, NULL); 5794 spdk_blob_close(clone, blob_op_complete, NULL); 5795 CU_ASSERT(g_bserrno == 0); 5796 blob = NULL; 5797 g_blob = NULL; 5798 5799 /* Unload the blob store */ 5800 spdk_bs_unload(g_bs, bs_op_complete, NULL); 5801 CU_ASSERT(g_bserrno == 0); 5802 g_bs = NULL; 5803 g_blob = NULL; 5804 g_blobid = 0; 5805 } 5806 5807 static void 5808 blob_io_unit_compatiblity(void) 5809 { 5810 struct spdk_bs_opts bsopts; 5811 struct spdk_bs_dev *dev; 5812 struct spdk_bs_super_block *super; 5813 5814 /* Create dev with 512 bytes io unit size */ 5815 5816 spdk_bs_opts_init(&bsopts); 5817 bsopts.cluster_sz = SPDK_BS_PAGE_SIZE * 4; /* 8 * 4 = 32 io_unit */ 5818 snprintf(bsopts.bstype.bstype, sizeof(bsopts.bstype.bstype), "TESTTYPE"); 5819 5820 /* Try to initialize a new blob store with unsupported io_unit */ 5821 dev = init_dev(); 5822 dev->blocklen = 512; 5823 dev->blockcnt = DEV_BUFFER_SIZE / dev->blocklen; 5824 5825 /* Initialize a new blob store */ 5826 spdk_bs_init(dev, &bsopts, bs_op_with_handle_complete, NULL); 5827 CU_ASSERT(g_bserrno == 0); 5828 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 5829 5830 CU_ASSERT(spdk_bs_get_io_unit_size(g_bs) == 512); 5831 5832 /* Unload the blob store */ 5833 spdk_bs_unload(g_bs, bs_op_complete, NULL); 5834 CU_ASSERT(g_bserrno == 0); 5835 5836 /* Modify super block to behave like older version. 5837 * Check if loaded io unit size equals SPDK_BS_PAGE_SIZE */ 5838 super = (struct spdk_bs_super_block *)&g_dev_buffer[0]; 5839 super->io_unit_size = 0; 5840 super->crc = _spdk_blob_md_page_calc_crc(super); 5841 5842 dev = init_dev(); 5843 dev->blocklen = 512; 5844 dev->blockcnt = DEV_BUFFER_SIZE / dev->blocklen; 5845 5846 spdk_bs_load(dev, &bsopts, bs_op_with_handle_complete, NULL); 5847 CU_ASSERT(g_bserrno == 0); 5848 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 5849 5850 CU_ASSERT(spdk_bs_get_io_unit_size(g_bs) == SPDK_BS_PAGE_SIZE); 5851 5852 /* Unload the blob store */ 5853 spdk_bs_unload(g_bs, bs_op_complete, NULL); 5854 CU_ASSERT(g_bserrno == 0); 5855 5856 g_bs = NULL; 5857 g_blob = NULL; 5858 g_blobid = 0; 5859 } 5860 5861 int main(int argc, char **argv) 5862 { 5863 struct spdk_thread *thread; 5864 CU_pSuite suite = NULL; 5865 unsigned int num_failures; 5866 5867 if (CU_initialize_registry() != CUE_SUCCESS) { 5868 return CU_get_error(); 5869 } 5870 5871 suite = CU_add_suite("blob", NULL, NULL); 5872 if (suite == NULL) { 5873 CU_cleanup_registry(); 5874 return CU_get_error(); 5875 } 5876 5877 if ( 5878 CU_add_test(suite, "blob_init", blob_init) == NULL || 5879 CU_add_test(suite, "blob_open", blob_open) == NULL || 5880 CU_add_test(suite, "blob_create", blob_create) == NULL || 5881 CU_add_test(suite, "blob_create_internal", blob_create_internal) == NULL || 5882 CU_add_test(suite, "blob_thin_provision", blob_thin_provision) == NULL || 5883 CU_add_test(suite, "blob_snapshot", blob_snapshot) == NULL || 5884 CU_add_test(suite, "blob_clone", blob_clone) == NULL || 5885 CU_add_test(suite, "blob_inflate", blob_inflate) == NULL || 5886 CU_add_test(suite, "blob_delete", blob_delete) == NULL || 5887 CU_add_test(suite, "blob_resize", blob_resize) == NULL || 5888 CU_add_test(suite, "blob_read_only", blob_read_only) == NULL || 5889 CU_add_test(suite, "channel_ops", channel_ops) == NULL || 5890 CU_add_test(suite, "blob_super", blob_super) == NULL || 5891 CU_add_test(suite, "blob_write", blob_write) == NULL || 5892 CU_add_test(suite, "blob_read", blob_read) == NULL || 5893 CU_add_test(suite, "blob_rw_verify", blob_rw_verify) == NULL || 5894 CU_add_test(suite, "blob_rw_verify_iov", blob_rw_verify_iov) == NULL || 5895 CU_add_test(suite, "blob_rw_verify_iov_nomem", blob_rw_verify_iov_nomem) == NULL || 5896 CU_add_test(suite, "blob_rw_iov_read_only", blob_rw_iov_read_only) == NULL || 5897 CU_add_test(suite, "blob_unmap", blob_unmap) == NULL || 5898 CU_add_test(suite, "blob_iter", blob_iter) == NULL || 5899 CU_add_test(suite, "blob_xattr", blob_xattr) == NULL || 5900 CU_add_test(suite, "bs_load", bs_load) == NULL || 5901 CU_add_test(suite, "bs_load_custom_cluster_size", bs_load_custom_cluster_size) == NULL || 5902 CU_add_test(suite, "bs_unload", bs_unload) == NULL || 5903 CU_add_test(suite, "bs_cluster_sz", bs_cluster_sz) == NULL || 5904 CU_add_test(suite, "bs_usable_clusters", bs_usable_clusters) == NULL || 5905 CU_add_test(suite, "bs_resize_md", bs_resize_md) == NULL || 5906 CU_add_test(suite, "bs_destroy", bs_destroy) == NULL || 5907 CU_add_test(suite, "bs_type", bs_type) == NULL || 5908 CU_add_test(suite, "bs_super_block", bs_super_block) == NULL || 5909 CU_add_test(suite, "blob_serialize", blob_serialize) == NULL || 5910 CU_add_test(suite, "blob_crc", blob_crc) == NULL || 5911 CU_add_test(suite, "super_block_crc", super_block_crc) == NULL || 5912 CU_add_test(suite, "blob_dirty_shutdown", blob_dirty_shutdown) == NULL || 5913 CU_add_test(suite, "blob_flags", blob_flags) == NULL || 5914 CU_add_test(suite, "bs_version", bs_version) == NULL || 5915 CU_add_test(suite, "blob_set_xattrs", blob_set_xattrs) == NULL || 5916 CU_add_test(suite, "blob_thin_prov_alloc", blob_thin_prov_alloc) == NULL || 5917 CU_add_test(suite, "blob_insert_cluster_msg", blob_insert_cluster_msg) == NULL || 5918 CU_add_test(suite, "blob_thin_prov_rw", blob_thin_prov_rw) == NULL || 5919 CU_add_test(suite, "blob_thin_prov_rw_iov", blob_thin_prov_rw_iov) == NULL || 5920 CU_add_test(suite, "bs_load_iter", bs_load_iter) == NULL || 5921 CU_add_test(suite, "blob_snapshot_rw", blob_snapshot_rw) == NULL || 5922 CU_add_test(suite, "blob_snapshot_rw_iov", blob_snapshot_rw_iov) == NULL || 5923 CU_add_test(suite, "blob_relations", blob_relations) == NULL || 5924 CU_add_test(suite, "blob_inflate_rw", blob_inflate_rw) == NULL || 5925 CU_add_test(suite, "blob_snapshot_freeze_io", blob_snapshot_freeze_io) == NULL || 5926 CU_add_test(suite, "blob_operation_split_rw", blob_operation_split_rw) == NULL || 5927 CU_add_test(suite, "blob_operation_split_rw_iov", blob_operation_split_rw_iov) == NULL || 5928 CU_add_test(suite, "blob_io_unit", blob_io_unit) == NULL || 5929 CU_add_test(suite, "blob_io_unit_compatiblity", blob_io_unit_compatiblity) == NULL 5930 ) { 5931 CU_cleanup_registry(); 5932 return CU_get_error(); 5933 } 5934 5935 g_dev_buffer = calloc(1, DEV_BUFFER_SIZE); 5936 thread = spdk_allocate_thread(_bs_send_msg, NULL, NULL, NULL, "thread0"); 5937 spdk_set_thread(thread); 5938 CU_basic_set_mode(CU_BRM_VERBOSE); 5939 CU_basic_run_tests(); 5940 num_failures = CU_get_number_of_failures(); 5941 CU_cleanup_registry(); 5942 spdk_free_thread(); 5943 free(g_dev_buffer); 5944 return num_failures; 5945 } 5946