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 39 #include "lib/test_env.c" 40 #include "../bs_dev_common.c" 41 #include "blobstore.c" 42 #include "request.c" 43 44 struct spdk_blob_store *g_bs; 45 spdk_blob_id g_blobid; 46 struct spdk_blob *g_blob; 47 int g_bserrno; 48 struct spdk_xattr_names *g_names; 49 int g_done; 50 51 static void 52 _bs_send_msg(spdk_thread_fn fn, void *ctx, void *thread_ctx) 53 { 54 fn(ctx); 55 } 56 57 static void 58 bs_op_complete(void *cb_arg, int bserrno) 59 { 60 g_bserrno = bserrno; 61 } 62 63 static void 64 bs_op_with_handle_complete(void *cb_arg, struct spdk_blob_store *bs, 65 int bserrno) 66 { 67 g_bs = bs; 68 g_bserrno = bserrno; 69 } 70 71 static void 72 blob_op_complete(void *cb_arg, int bserrno) 73 { 74 g_bserrno = bserrno; 75 } 76 77 static void 78 blob_op_with_id_complete(void *cb_arg, spdk_blob_id blobid, int bserrno) 79 { 80 g_blobid = blobid; 81 g_bserrno = bserrno; 82 } 83 84 static void 85 blob_op_with_handle_complete(void *cb_arg, struct spdk_blob *blb, int bserrno) 86 { 87 g_blob = blb; 88 g_bserrno = bserrno; 89 } 90 91 static void 92 blob_init(void) 93 { 94 struct spdk_bs_dev dev; 95 96 init_dev(&dev); 97 98 /* should fail for an unsupported blocklen */ 99 dev.blocklen = 500; 100 spdk_bs_init(&dev, NULL, bs_op_with_handle_complete, NULL); 101 CU_ASSERT(g_bserrno == -EINVAL); 102 103 init_dev(&dev); 104 spdk_bs_init(&dev, NULL, bs_op_with_handle_complete, NULL); 105 CU_ASSERT(g_bserrno == 0); 106 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 107 108 spdk_bs_unload(g_bs, bs_op_complete, NULL); 109 CU_ASSERT(g_bserrno == 0); 110 g_bs = NULL; 111 } 112 113 static void 114 blob_super(void) 115 { 116 struct spdk_blob_store *bs; 117 struct spdk_bs_dev dev; 118 spdk_blob_id blobid; 119 120 init_dev(&dev); 121 122 spdk_bs_init(&dev, NULL, bs_op_with_handle_complete, NULL); 123 CU_ASSERT(g_bserrno == 0); 124 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 125 bs = g_bs; 126 127 /* Get the super blob without having set one */ 128 spdk_bs_get_super(bs, blob_op_with_id_complete, NULL); 129 CU_ASSERT(g_bserrno == -ENOENT); 130 CU_ASSERT(g_blobid == SPDK_BLOBID_INVALID); 131 132 /* Create a blob */ 133 spdk_bs_md_create_blob(bs, 134 blob_op_with_id_complete, NULL); 135 CU_ASSERT(g_bserrno == 0); 136 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 137 blobid = g_blobid; 138 139 /* Set the blob as the super blob */ 140 spdk_bs_set_super(bs, blobid, blob_op_complete, NULL); 141 CU_ASSERT(g_bserrno == 0); 142 143 /* Get the super blob */ 144 spdk_bs_get_super(bs, blob_op_with_id_complete, NULL); 145 CU_ASSERT(g_bserrno == 0); 146 CU_ASSERT(blobid == g_blobid); 147 148 spdk_bs_unload(g_bs, bs_op_complete, NULL); 149 CU_ASSERT(g_bserrno == 0); 150 g_bs = NULL; 151 } 152 153 static void 154 blob_open(void) 155 { 156 struct spdk_blob_store *bs; 157 struct spdk_bs_dev dev; 158 struct spdk_blob *blob; 159 spdk_blob_id blobid, blobid2; 160 161 init_dev(&dev); 162 163 spdk_bs_init(&dev, NULL, bs_op_with_handle_complete, NULL); 164 CU_ASSERT(g_bserrno == 0); 165 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 166 bs = g_bs; 167 168 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 169 CU_ASSERT(g_bserrno == 0); 170 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 171 blobid = g_blobid; 172 173 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 174 CU_ASSERT(g_bserrno == 0); 175 CU_ASSERT(g_blob != NULL); 176 blob = g_blob; 177 178 blobid2 = spdk_blob_get_id(blob); 179 CU_ASSERT(blobid == blobid2); 180 181 /* Try to open file again. It should return success. */ 182 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 183 CU_ASSERT(g_bserrno == 0); 184 CU_ASSERT(blob == g_blob); 185 186 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 187 CU_ASSERT(g_bserrno == 0); 188 CU_ASSERT(blob == NULL); 189 190 /* 191 * Close the file a second time, releasing the second reference. This 192 * should succeed. 193 */ 194 blob = g_blob; 195 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 196 CU_ASSERT(g_bserrno == 0); 197 198 /* 199 * Try to open file again. It should succeed. This tests the case 200 * where the file is opened, closed, then re-opened again. 201 */ 202 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 203 CU_ASSERT(g_bserrno == 0); 204 CU_ASSERT(g_blob != NULL); 205 blob = g_blob; 206 207 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 208 CU_ASSERT(g_bserrno == 0); 209 210 spdk_bs_unload(g_bs, bs_op_complete, NULL); 211 CU_ASSERT(g_bserrno == 0); 212 g_bs = NULL; 213 } 214 215 static void 216 blob_delete(void) 217 { 218 struct spdk_blob_store *bs; 219 struct spdk_bs_dev dev; 220 spdk_blob_id blobid; 221 222 init_dev(&dev); 223 224 spdk_bs_init(&dev, NULL, bs_op_with_handle_complete, NULL); 225 CU_ASSERT(g_bserrno == 0); 226 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 227 bs = g_bs; 228 229 /* Create a blob and then delete it. */ 230 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 231 CU_ASSERT(g_bserrno == 0); 232 CU_ASSERT(g_blobid > 0); 233 blobid = g_blobid; 234 235 spdk_bs_md_delete_blob(bs, blobid, blob_op_complete, NULL); 236 CU_ASSERT(g_bserrno == 0); 237 238 /* Try to open the blob */ 239 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 240 CU_ASSERT(g_bserrno == -ENOENT); 241 242 spdk_bs_unload(g_bs, bs_op_complete, NULL); 243 CU_ASSERT(g_bserrno == 0); 244 g_bs = NULL; 245 } 246 247 static void 248 blob_resize(void) 249 { 250 struct spdk_blob_store *bs; 251 struct spdk_bs_dev dev; 252 struct spdk_blob *blob; 253 spdk_blob_id blobid; 254 uint64_t free_clusters; 255 int rc; 256 257 init_dev(&dev); 258 259 spdk_bs_init(&dev, NULL, bs_op_with_handle_complete, NULL); 260 CU_ASSERT(g_bserrno == 0); 261 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 262 bs = g_bs; 263 free_clusters = spdk_bs_free_cluster_count(bs); 264 265 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 266 CU_ASSERT(g_bserrno == 0); 267 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 268 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 269 blobid = g_blobid; 270 271 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 272 CU_ASSERT(g_bserrno == 0); 273 CU_ASSERT(g_blob != NULL); 274 blob = g_blob; 275 276 /* The blob started at 0 clusters. Resize it to be 5. */ 277 rc = spdk_bs_md_resize_blob(blob, 5); 278 CU_ASSERT(rc == 0); 279 CU_ASSERT((free_clusters - 5) == spdk_bs_free_cluster_count(bs)); 280 281 /* Shrink the blob to 3 clusters. This will not actually release 282 * the old clusters until the blob is synced. 283 */ 284 rc = spdk_bs_md_resize_blob(blob, 3); 285 CU_ASSERT(rc == 0); 286 /* Verify there are still 5 clusters in use */ 287 CU_ASSERT((free_clusters - 5) == spdk_bs_free_cluster_count(bs)); 288 289 spdk_bs_md_sync_blob(blob, blob_op_complete, NULL); 290 CU_ASSERT(g_bserrno == 0); 291 /* Now there are only 3 clusters in use */ 292 CU_ASSERT((free_clusters - 3) == spdk_bs_free_cluster_count(bs)); 293 294 /* Resize the blob to be 10 clusters. Growth takes effect immediately. */ 295 rc = spdk_bs_md_resize_blob(blob, 10); 296 CU_ASSERT(rc == 0); 297 CU_ASSERT((free_clusters - 10) == spdk_bs_free_cluster_count(bs)); 298 299 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 300 CU_ASSERT(g_bserrno == 0); 301 302 spdk_bs_md_delete_blob(bs, blobid, blob_op_complete, NULL); 303 CU_ASSERT(g_bserrno == 0); 304 305 spdk_bs_unload(g_bs, bs_op_complete, NULL); 306 CU_ASSERT(g_bserrno == 0); 307 g_bs = NULL; 308 } 309 310 static void 311 channel_ops(void) 312 { 313 struct spdk_blob_store *bs; 314 struct spdk_bs_dev dev; 315 struct spdk_io_channel *channel; 316 317 init_dev(&dev); 318 319 spdk_bs_init(&dev, NULL, bs_op_with_handle_complete, NULL); 320 CU_ASSERT(g_bserrno == 0); 321 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 322 bs = g_bs; 323 324 channel = spdk_bs_alloc_io_channel(bs); 325 CU_ASSERT(channel != NULL); 326 327 spdk_bs_free_io_channel(channel); 328 329 spdk_bs_unload(g_bs, bs_op_complete, NULL); 330 CU_ASSERT(g_bserrno == 0); 331 g_bs = NULL; 332 } 333 334 static void 335 blob_write(void) 336 { 337 struct spdk_blob_store *bs; 338 struct spdk_bs_dev dev; 339 struct spdk_blob *blob; 340 struct spdk_io_channel *channel; 341 spdk_blob_id blobid; 342 uint64_t pages_per_cluster; 343 uint8_t payload[10 * 4096]; 344 int rc; 345 346 init_dev(&dev); 347 348 spdk_bs_init(&dev, NULL, bs_op_with_handle_complete, NULL); 349 CU_ASSERT(g_bserrno == 0); 350 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 351 bs = g_bs; 352 353 pages_per_cluster = spdk_bs_get_cluster_size(bs) / spdk_bs_get_page_size(bs); 354 355 channel = spdk_bs_alloc_io_channel(bs); 356 CU_ASSERT(channel != NULL); 357 358 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 359 CU_ASSERT(g_bserrno == 0); 360 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 361 blobid = g_blobid; 362 363 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 364 CU_ASSERT(g_bserrno == 0); 365 CU_ASSERT(g_blob != NULL); 366 blob = g_blob; 367 368 /* Write to a blob with 0 size */ 369 spdk_bs_io_write_blob(blob, channel, payload, 0, 1, blob_op_complete, NULL); 370 CU_ASSERT(g_bserrno == -EINVAL); 371 372 /* Resize the blob */ 373 rc = spdk_bs_md_resize_blob(blob, 5); 374 CU_ASSERT(rc == 0); 375 376 /* Write to the blob */ 377 spdk_bs_io_write_blob(blob, channel, payload, 0, 1, blob_op_complete, NULL); 378 CU_ASSERT(g_bserrno == 0); 379 380 /* Write starting beyond the end */ 381 spdk_bs_io_write_blob(blob, channel, payload, 5 * pages_per_cluster, 1, blob_op_complete, 382 NULL); 383 CU_ASSERT(g_bserrno == -EINVAL); 384 385 /* Write starting at a valid location but going off the end */ 386 spdk_bs_io_write_blob(blob, channel, payload, 4 * pages_per_cluster, pages_per_cluster + 1, 387 blob_op_complete, NULL); 388 CU_ASSERT(g_bserrno == -EINVAL); 389 390 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 391 CU_ASSERT(g_bserrno == 0); 392 393 spdk_bs_free_io_channel(channel); 394 395 spdk_bs_unload(g_bs, bs_op_complete, NULL); 396 CU_ASSERT(g_bserrno == 0); 397 g_bs = NULL; 398 } 399 400 static void 401 blob_read(void) 402 { 403 struct spdk_blob_store *bs; 404 struct spdk_bs_dev dev; 405 struct spdk_blob *blob; 406 struct spdk_io_channel *channel; 407 spdk_blob_id blobid; 408 uint64_t pages_per_cluster; 409 uint8_t payload[10 * 4096]; 410 int rc; 411 412 init_dev(&dev); 413 414 spdk_bs_init(&dev, NULL, bs_op_with_handle_complete, NULL); 415 CU_ASSERT(g_bserrno == 0); 416 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 417 bs = g_bs; 418 419 pages_per_cluster = spdk_bs_get_cluster_size(bs) / spdk_bs_get_page_size(bs); 420 421 channel = spdk_bs_alloc_io_channel(bs); 422 CU_ASSERT(channel != NULL); 423 424 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 425 CU_ASSERT(g_bserrno == 0); 426 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 427 blobid = g_blobid; 428 429 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 430 CU_ASSERT(g_bserrno == 0); 431 CU_ASSERT(g_blob != NULL); 432 blob = g_blob; 433 434 /* Read from a blob with 0 size */ 435 spdk_bs_io_read_blob(blob, channel, payload, 0, 1, blob_op_complete, NULL); 436 CU_ASSERT(g_bserrno == -EINVAL); 437 438 /* Resize the blob */ 439 rc = spdk_bs_md_resize_blob(blob, 5); 440 CU_ASSERT(rc == 0); 441 442 /* Read from the blob */ 443 spdk_bs_io_read_blob(blob, channel, payload, 0, 1, blob_op_complete, NULL); 444 CU_ASSERT(g_bserrno == 0); 445 446 /* Read starting beyond the end */ 447 spdk_bs_io_read_blob(blob, channel, payload, 5 * pages_per_cluster, 1, blob_op_complete, 448 NULL); 449 CU_ASSERT(g_bserrno == -EINVAL); 450 451 /* Read starting at a valid location but going off the end */ 452 spdk_bs_io_read_blob(blob, channel, payload, 4 * pages_per_cluster, pages_per_cluster + 1, 453 blob_op_complete, NULL); 454 CU_ASSERT(g_bserrno == -EINVAL); 455 456 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 457 CU_ASSERT(g_bserrno == 0); 458 459 spdk_bs_free_io_channel(channel); 460 461 spdk_bs_unload(g_bs, bs_op_complete, NULL); 462 CU_ASSERT(g_bserrno == 0); 463 g_bs = NULL; 464 } 465 466 static void 467 blob_rw_verify(void) 468 { 469 struct spdk_blob_store *bs; 470 struct spdk_bs_dev dev; 471 struct spdk_blob *blob; 472 struct spdk_io_channel *channel; 473 spdk_blob_id blobid; 474 uint8_t payload_read[10 * 4096]; 475 uint8_t payload_write[10 * 4096]; 476 int rc; 477 478 init_dev(&dev); 479 480 spdk_bs_init(&dev, NULL, bs_op_with_handle_complete, NULL); 481 CU_ASSERT(g_bserrno == 0); 482 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 483 bs = g_bs; 484 485 channel = spdk_bs_alloc_io_channel(bs); 486 CU_ASSERT(channel != NULL); 487 488 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 489 CU_ASSERT(g_bserrno == 0); 490 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 491 blobid = g_blobid; 492 493 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 494 CU_ASSERT(g_bserrno == 0); 495 CU_ASSERT(g_blob != NULL); 496 blob = g_blob; 497 498 rc = spdk_bs_md_resize_blob(blob, 32); 499 CU_ASSERT(rc == 0); 500 501 memset(payload_write, 0xE5, sizeof(payload_write)); 502 spdk_bs_io_write_blob(blob, channel, payload_write, 4, 10, blob_op_complete, NULL); 503 CU_ASSERT(g_bserrno == 0); 504 505 memset(payload_read, 0x00, sizeof(payload_read)); 506 spdk_bs_io_read_blob(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 507 CU_ASSERT(g_bserrno == 0); 508 CU_ASSERT(memcmp(payload_write, payload_read, 4 * 4096) == 0); 509 510 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 511 CU_ASSERT(g_bserrno == 0); 512 513 spdk_bs_free_io_channel(channel); 514 515 spdk_bs_unload(g_bs, bs_op_complete, NULL); 516 CU_ASSERT(g_bserrno == 0); 517 g_bs = NULL; 518 } 519 520 static void 521 blob_rw_verify_iov(void) 522 { 523 struct spdk_blob_store *bs; 524 struct spdk_bs_dev dev; 525 struct spdk_blob *blob; 526 struct spdk_io_channel *channel; 527 spdk_blob_id blobid; 528 uint8_t payload_read[10 * 4096]; 529 uint8_t payload_write[10 * 4096]; 530 struct iovec iov_read[3]; 531 struct iovec iov_write[3]; 532 void *buf; 533 int rc; 534 535 init_dev(&dev); 536 memset(g_dev_buffer, 0, DEV_BUFFER_SIZE); 537 538 spdk_bs_init(&dev, NULL, bs_op_with_handle_complete, NULL); 539 CU_ASSERT(g_bserrno == 0); 540 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 541 bs = g_bs; 542 543 channel = spdk_bs_alloc_io_channel(bs); 544 CU_ASSERT(channel != NULL); 545 546 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 547 CU_ASSERT(g_bserrno == 0); 548 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 549 blobid = g_blobid; 550 551 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 552 CU_ASSERT(g_bserrno == 0); 553 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 554 blob = g_blob; 555 556 rc = spdk_bs_md_resize_blob(blob, 2); 557 CU_ASSERT(rc == 0); 558 559 /* 560 * Manually adjust the offset of the blob's second cluster. This allows 561 * us to make sure that the readv/write code correctly accounts for I/O 562 * that cross cluster boundaries. Start by asserting that the allocated 563 * clusters are where we expect before modifying the second cluster. 564 */ 565 CU_ASSERT(blob->active.clusters[0] == 1 * 256); 566 CU_ASSERT(blob->active.clusters[1] == 2 * 256); 567 blob->active.clusters[1] = 3 * 256; 568 569 memset(payload_write, 0xE5, sizeof(payload_write)); 570 iov_write[0].iov_base = payload_write; 571 iov_write[0].iov_len = 1 * 4096; 572 iov_write[1].iov_base = payload_write + 1 * 4096; 573 iov_write[1].iov_len = 5 * 4096; 574 iov_write[2].iov_base = payload_write + 6 * 4096; 575 iov_write[2].iov_len = 4 * 4096; 576 /* 577 * Choose a page offset just before the cluster boundary. The first 6 pages of payload 578 * will get written to the first cluster, the last 4 to the second cluster. 579 */ 580 spdk_bs_io_writev_blob(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 581 CU_ASSERT(g_bserrno == 0); 582 583 memset(payload_read, 0xAA, sizeof(payload_read)); 584 iov_read[0].iov_base = payload_read; 585 iov_read[0].iov_len = 3 * 4096; 586 iov_read[1].iov_base = payload_read + 3 * 4096; 587 iov_read[1].iov_len = 4 * 4096; 588 iov_read[2].iov_base = payload_read + 7 * 4096; 589 iov_read[2].iov_len = 3 * 4096; 590 spdk_bs_io_readv_blob(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 591 CU_ASSERT(g_bserrno == 0); 592 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 593 594 buf = calloc(1, 256 * 4096); 595 /* Check that cluster 2 on "disk" was not modified. */ 596 CU_ASSERT(memcmp(buf, &g_dev_buffer[512 * 4096], 256 * 4096) == 0); 597 free(buf); 598 599 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 600 CU_ASSERT(g_bserrno == 0); 601 602 spdk_bs_free_io_channel(channel); 603 604 spdk_bs_unload(g_bs, bs_op_complete, NULL); 605 CU_ASSERT(g_bserrno == 0); 606 g_bs = NULL; 607 } 608 609 static uint32_t 610 bs_channel_get_req_count(struct spdk_io_channel *_channel) 611 { 612 struct spdk_bs_channel *channel = spdk_io_channel_get_ctx(_channel); 613 struct spdk_bs_request_set *set; 614 uint32_t count = 0; 615 616 TAILQ_FOREACH(set, &channel->reqs, link) { 617 count++; 618 } 619 620 return count; 621 } 622 623 static void 624 blob_rw_verify_iov_nomem(void) 625 { 626 struct spdk_blob_store *bs; 627 struct spdk_bs_dev dev; 628 struct spdk_blob *blob; 629 struct spdk_io_channel *channel; 630 spdk_blob_id blobid; 631 uint8_t payload_write[10 * 4096]; 632 struct iovec iov_write[3]; 633 uint32_t req_count; 634 int rc; 635 636 init_dev(&dev); 637 memset(g_dev_buffer, 0, DEV_BUFFER_SIZE); 638 639 spdk_bs_init(&dev, NULL, bs_op_with_handle_complete, NULL); 640 CU_ASSERT(g_bserrno == 0); 641 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 642 bs = g_bs; 643 644 channel = spdk_bs_alloc_io_channel(bs); 645 CU_ASSERT(channel != NULL); 646 647 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 648 CU_ASSERT(g_bserrno == 0); 649 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 650 blobid = g_blobid; 651 652 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 653 CU_ASSERT(g_bserrno == 0); 654 CU_ASSERT(g_blob != NULL); 655 blob = g_blob; 656 657 rc = spdk_bs_md_resize_blob(blob, 2); 658 CU_ASSERT(rc == 0); 659 660 /* 661 * Choose a page offset just before the cluster boundary. The first 6 pages of payload 662 * will get written to the first cluster, the last 4 to the second cluster. 663 */ 664 iov_write[0].iov_base = payload_write; 665 iov_write[0].iov_len = 1 * 4096; 666 iov_write[1].iov_base = payload_write + 1 * 4096; 667 iov_write[1].iov_len = 5 * 4096; 668 iov_write[2].iov_base = payload_write + 6 * 4096; 669 iov_write[2].iov_len = 4 * 4096; 670 MOCK_SET(calloc, void *, NULL); 671 req_count = bs_channel_get_req_count(channel); 672 spdk_bs_io_writev_blob(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 673 CU_ASSERT(g_bserrno = -ENOMEM); 674 CU_ASSERT(req_count == bs_channel_get_req_count(channel)); 675 MOCK_SET(calloc, void *, (void *)MOCK_PASS_THRU); 676 677 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 678 CU_ASSERT(g_bserrno == 0); 679 680 spdk_bs_free_io_channel(channel); 681 682 spdk_bs_unload(g_bs, bs_op_complete, NULL); 683 CU_ASSERT(g_bserrno == 0); 684 g_bs = NULL; 685 } 686 687 static void 688 blob_iter(void) 689 { 690 struct spdk_blob_store *bs; 691 struct spdk_bs_dev dev; 692 struct spdk_blob *blob; 693 spdk_blob_id blobid; 694 695 init_dev(&dev); 696 697 spdk_bs_init(&dev, NULL, bs_op_with_handle_complete, NULL); 698 CU_ASSERT(g_bserrno == 0); 699 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 700 bs = g_bs; 701 702 spdk_bs_md_iter_first(bs, blob_op_with_handle_complete, NULL); 703 CU_ASSERT(g_blob == NULL); 704 CU_ASSERT(g_bserrno == -ENOENT); 705 706 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 707 CU_ASSERT(g_bserrno == 0); 708 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 709 blobid = g_blobid; 710 711 spdk_bs_md_iter_first(bs, blob_op_with_handle_complete, NULL); 712 CU_ASSERT(g_blob != NULL); 713 CU_ASSERT(g_bserrno == 0); 714 blob = g_blob; 715 CU_ASSERT(spdk_blob_get_id(blob) == blobid); 716 717 spdk_bs_md_iter_next(bs, &blob, blob_op_with_handle_complete, NULL); 718 CU_ASSERT(g_blob == NULL); 719 CU_ASSERT(g_bserrno == -ENOENT); 720 721 spdk_bs_unload(g_bs, bs_op_complete, NULL); 722 CU_ASSERT(g_bserrno == 0); 723 g_bs = NULL; 724 } 725 726 static void 727 blob_xattr(void) 728 { 729 struct spdk_blob_store *bs; 730 struct spdk_bs_dev dev; 731 struct spdk_blob *blob; 732 spdk_blob_id blobid; 733 uint64_t length; 734 int rc; 735 const char *name1, *name2; 736 const void *value; 737 size_t value_len; 738 struct spdk_xattr_names *names; 739 740 init_dev(&dev); 741 742 spdk_bs_init(&dev, NULL, bs_op_with_handle_complete, NULL); 743 CU_ASSERT(g_bserrno == 0); 744 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 745 bs = g_bs; 746 747 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 748 CU_ASSERT(g_bserrno == 0); 749 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 750 blobid = g_blobid; 751 752 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 753 CU_ASSERT(g_bserrno == 0); 754 CU_ASSERT(g_blob != NULL); 755 blob = g_blob; 756 757 rc = spdk_blob_md_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 758 CU_ASSERT(rc == 0); 759 760 length = 2345; 761 rc = spdk_blob_md_set_xattr(blob, "length", &length, sizeof(length)); 762 CU_ASSERT(rc == 0); 763 764 /* Overwrite "length" xattr. */ 765 length = 3456; 766 rc = spdk_blob_md_set_xattr(blob, "length", &length, sizeof(length)); 767 CU_ASSERT(rc == 0); 768 769 value = NULL; 770 rc = spdk_bs_md_get_xattr_value(blob, "length", &value, &value_len); 771 CU_ASSERT(rc == 0); 772 SPDK_CU_ASSERT_FATAL(value != NULL); 773 CU_ASSERT(*(uint64_t *)value == length); 774 CU_ASSERT(value_len == 8); 775 776 rc = spdk_bs_md_get_xattr_value(blob, "foobar", &value, &value_len); 777 CU_ASSERT(rc == -ENOENT); 778 779 names = NULL; 780 rc = spdk_bs_md_get_xattr_names(blob, &names); 781 CU_ASSERT(rc == 0); 782 SPDK_CU_ASSERT_FATAL(names != NULL); 783 CU_ASSERT(spdk_xattr_names_get_count(names) == 2); 784 name1 = spdk_xattr_names_get_name(names, 0); 785 SPDK_CU_ASSERT_FATAL(name1 != NULL); 786 CU_ASSERT(!strcmp(name1, "name") || !strcmp(name1, "length")); 787 name2 = spdk_xattr_names_get_name(names, 1); 788 SPDK_CU_ASSERT_FATAL(name2 != NULL); 789 CU_ASSERT(!strcmp(name2, "name") || !strcmp(name2, "length")); 790 CU_ASSERT(strcmp(name1, name2)); 791 spdk_xattr_names_free(names); 792 793 rc = spdk_blob_md_remove_xattr(blob, "name"); 794 CU_ASSERT(rc == 0); 795 796 rc = spdk_blob_md_remove_xattr(blob, "foobar"); 797 CU_ASSERT(rc == -ENOENT); 798 799 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 800 801 spdk_bs_unload(g_bs, bs_op_complete, NULL); 802 CU_ASSERT(g_bserrno == 0); 803 g_bs = NULL; 804 } 805 806 static void 807 bs_load(void) 808 { 809 struct spdk_bs_dev dev; 810 spdk_blob_id blobid; 811 struct spdk_blob *blob; 812 uint64_t length; 813 int rc; 814 const void *value; 815 size_t value_len; 816 817 init_dev(&dev); 818 819 /* Initialize a new blob store */ 820 spdk_bs_init(&dev, NULL, bs_op_with_handle_complete, NULL); 821 CU_ASSERT(g_bserrno == 0); 822 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 823 824 /* Create a blob */ 825 spdk_bs_md_create_blob(g_bs, blob_op_with_id_complete, NULL); 826 CU_ASSERT(g_bserrno == 0); 827 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 828 blobid = g_blobid; 829 830 spdk_bs_md_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 831 CU_ASSERT(g_bserrno == 0); 832 CU_ASSERT(g_blob != NULL); 833 blob = g_blob; 834 835 /* Set some xattrs */ 836 rc = spdk_blob_md_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 837 CU_ASSERT(rc == 0); 838 839 length = 2345; 840 rc = spdk_blob_md_set_xattr(blob, "length", &length, sizeof(length)); 841 CU_ASSERT(rc == 0); 842 843 /* Resize the blob */ 844 rc = spdk_bs_md_resize_blob(blob, 10); 845 CU_ASSERT(rc == 0); 846 847 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 848 CU_ASSERT(g_bserrno == 0); 849 blob = NULL; 850 g_blob = NULL; 851 g_blobid = SPDK_BLOBID_INVALID; 852 853 /* Unload the blob store */ 854 spdk_bs_unload(g_bs, bs_op_complete, NULL); 855 CU_ASSERT(g_bserrno == 0); 856 g_bs = NULL; 857 g_blob = NULL; 858 g_blobid = 0; 859 860 /* Load an existing blob store */ 861 spdk_bs_load(&dev, bs_op_with_handle_complete, NULL); 862 CU_ASSERT(g_bserrno == 0); 863 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 864 865 spdk_bs_md_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 866 CU_ASSERT(g_bserrno == 0); 867 CU_ASSERT(g_blob != NULL); 868 blob = g_blob; 869 870 /* Get the xattrs */ 871 value = NULL; 872 rc = spdk_bs_md_get_xattr_value(blob, "length", &value, &value_len); 873 CU_ASSERT(rc == 0); 874 SPDK_CU_ASSERT_FATAL(value != NULL); 875 CU_ASSERT(*(uint64_t *)value == length); 876 CU_ASSERT(value_len == 8); 877 878 rc = spdk_bs_md_get_xattr_value(blob, "foobar", &value, &value_len); 879 CU_ASSERT(rc == -ENOENT); 880 881 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 882 883 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 884 CU_ASSERT(g_bserrno == 0); 885 blob = NULL; 886 g_blob = NULL; 887 g_blobid = SPDK_BLOBID_INVALID; 888 889 spdk_bs_unload(g_bs, bs_op_complete, NULL); 890 CU_ASSERT(g_bserrno == 0); 891 g_bs = NULL; 892 } 893 894 /* 895 * Create a blobstore with a cluster size different than the default, and ensure it is 896 * persisted. 897 */ 898 static void 899 bs_cluster_sz(void) 900 { 901 struct spdk_bs_dev dev; 902 struct spdk_bs_opts opts; 903 uint32_t cluster_sz; 904 905 init_dev(&dev); 906 spdk_bs_opts_init(&opts); 907 opts.cluster_sz *= 2; 908 cluster_sz = opts.cluster_sz; 909 910 /* Initialize a new blob store */ 911 spdk_bs_init(&dev, &opts, bs_op_with_handle_complete, NULL); 912 CU_ASSERT(g_bserrno == 0); 913 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 914 915 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 916 917 /* Unload the blob store */ 918 spdk_bs_unload(g_bs, bs_op_complete, NULL); 919 CU_ASSERT(g_bserrno == 0); 920 g_bs = NULL; 921 g_blob = NULL; 922 g_blobid = 0; 923 924 /* Load an existing blob store */ 925 spdk_bs_load(&dev, bs_op_with_handle_complete, NULL); 926 CU_ASSERT(g_bserrno == 0); 927 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 928 929 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 930 931 spdk_bs_unload(g_bs, bs_op_complete, NULL); 932 CU_ASSERT(g_bserrno == 0); 933 g_bs = NULL; 934 } 935 936 /* 937 * Test resizing of the metadata blob. This requires creating enough blobs 938 * so that one cluster is not enough to fit the metadata for those blobs. 939 * To induce this condition to happen more quickly, we reduce the cluster 940 * size to 16KB, which means only 4 4KB blob metadata pages can fit. 941 */ 942 static void 943 bs_resize_md(void) 944 { 945 const int CLUSTER_PAGE_COUNT = 4; 946 const int NUM_BLOBS = CLUSTER_PAGE_COUNT * 4; 947 struct spdk_bs_dev dev; 948 struct spdk_bs_opts opts; 949 uint32_t cluster_sz; 950 spdk_blob_id blobids[NUM_BLOBS]; 951 int i; 952 953 954 init_dev(&dev); 955 spdk_bs_opts_init(&opts); 956 opts.cluster_sz = CLUSTER_PAGE_COUNT * 4096; 957 cluster_sz = opts.cluster_sz; 958 959 /* Initialize a new blob store */ 960 spdk_bs_init(&dev, &opts, bs_op_with_handle_complete, NULL); 961 CU_ASSERT(g_bserrno == 0); 962 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 963 964 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 965 966 for (i = 0; i < NUM_BLOBS; i++) { 967 g_bserrno = -1; 968 g_blobid = SPDK_BLOBID_INVALID; 969 spdk_bs_md_create_blob(g_bs, 970 blob_op_with_id_complete, NULL); 971 CU_ASSERT(g_bserrno == 0); 972 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 973 blobids[i] = g_blobid; 974 } 975 976 /* Unload the blob store */ 977 g_bserrno = -1; 978 spdk_bs_unload(g_bs, bs_op_complete, NULL); 979 CU_ASSERT(g_bserrno == 0); 980 981 /* Load an existing blob store */ 982 g_bserrno = -1; 983 g_bs = NULL; 984 spdk_bs_load(&dev, bs_op_with_handle_complete, NULL); 985 CU_ASSERT(g_bserrno == 0); 986 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 987 988 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 989 990 for (i = 0; i < NUM_BLOBS; i++) { 991 g_bserrno = -1; 992 g_blob = NULL; 993 spdk_bs_md_open_blob(g_bs, blobids[i], blob_op_with_handle_complete, NULL); 994 CU_ASSERT(g_bserrno == 0); 995 CU_ASSERT(g_blob != NULL); 996 g_bserrno = -1; 997 spdk_bs_md_close_blob(&g_blob, blob_op_complete, NULL); 998 CU_ASSERT(g_bserrno == 0); 999 } 1000 1001 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1002 CU_ASSERT(g_bserrno == 0); 1003 g_bs = NULL; 1004 } 1005 1006 /* Try to hit all of the corner cases associated with serializing 1007 * a blob to disk 1008 */ 1009 static void 1010 blob_serialize(void) 1011 { 1012 struct spdk_bs_dev dev; 1013 struct spdk_bs_opts opts; 1014 struct spdk_blob_store *bs; 1015 spdk_blob_id blobid[2]; 1016 struct spdk_blob *blob[2]; 1017 uint64_t i; 1018 char *value; 1019 int rc; 1020 1021 init_dev(&dev); 1022 1023 /* Initialize a new blobstore with very small clusters */ 1024 spdk_bs_opts_init(&opts); 1025 opts.cluster_sz = dev.blocklen * 8; 1026 spdk_bs_init(&dev, &opts, bs_op_with_handle_complete, NULL); 1027 CU_ASSERT(g_bserrno == 0); 1028 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1029 bs = g_bs; 1030 1031 /* Create and open two blobs */ 1032 for (i = 0; i < 2; i++) { 1033 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 1034 CU_ASSERT(g_bserrno == 0); 1035 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1036 blobid[i] = g_blobid; 1037 1038 /* Open a blob */ 1039 spdk_bs_md_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL); 1040 CU_ASSERT(g_bserrno == 0); 1041 CU_ASSERT(g_blob != NULL); 1042 blob[i] = g_blob; 1043 1044 /* Set a fairly large xattr on both blobs to eat up 1045 * metadata space 1046 */ 1047 value = calloc(dev.blocklen - 64, sizeof(char)); 1048 SPDK_CU_ASSERT_FATAL(value != NULL); 1049 memset(value, i, dev.blocklen / 2); 1050 rc = spdk_blob_md_set_xattr(blob[i], "name", value, dev.blocklen - 64); 1051 CU_ASSERT(rc == 0); 1052 free(value); 1053 } 1054 1055 /* Resize the blobs, alternating 1 cluster at a time. 1056 * This thwarts run length encoding and will cause spill 1057 * over of the extents. 1058 */ 1059 for (i = 0; i < 6; i++) { 1060 rc = spdk_bs_md_resize_blob(blob[i % 2], (i / 2) + 1); 1061 CU_ASSERT(rc == 0); 1062 } 1063 1064 for (i = 0; i < 2; i++) { 1065 spdk_bs_md_sync_blob(blob[i], blob_op_complete, NULL); 1066 CU_ASSERT(g_bserrno == 0); 1067 } 1068 1069 /* Close the blobs */ 1070 for (i = 0; i < 2; i++) { 1071 spdk_bs_md_close_blob(&blob[i], blob_op_complete, NULL); 1072 CU_ASSERT(g_bserrno == 0); 1073 } 1074 1075 /* Unload the blobstore */ 1076 spdk_bs_unload(bs, bs_op_complete, NULL); 1077 CU_ASSERT(g_bserrno == 0); 1078 g_bs = NULL; 1079 g_blob = NULL; 1080 g_blobid = 0; 1081 bs = NULL; 1082 1083 /* Load an existing blob store */ 1084 spdk_bs_load(&dev, bs_op_with_handle_complete, NULL); 1085 CU_ASSERT(g_bserrno == 0); 1086 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1087 bs = g_bs; 1088 1089 for (i = 0; i < 2; i++) { 1090 blob[i] = NULL; 1091 1092 spdk_bs_md_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL); 1093 CU_ASSERT(g_bserrno == 0); 1094 CU_ASSERT(g_blob != NULL); 1095 blob[i] = g_blob; 1096 1097 CU_ASSERT(spdk_blob_get_num_clusters(blob[i]) == 3); 1098 1099 spdk_bs_md_close_blob(&blob[i], blob_op_complete, NULL); 1100 CU_ASSERT(g_bserrno == 0); 1101 } 1102 1103 spdk_bs_unload(bs, bs_op_complete, NULL); 1104 CU_ASSERT(g_bserrno == 0); 1105 g_bs = NULL; 1106 } 1107 1108 int main(int argc, char **argv) 1109 { 1110 CU_pSuite suite = NULL; 1111 unsigned int num_failures; 1112 1113 if (CU_initialize_registry() != CUE_SUCCESS) { 1114 return CU_get_error(); 1115 } 1116 1117 suite = CU_add_suite("blob", NULL, NULL); 1118 if (suite == NULL) { 1119 CU_cleanup_registry(); 1120 return CU_get_error(); 1121 } 1122 1123 if ( 1124 CU_add_test(suite, "blob_init", blob_init) == NULL || 1125 CU_add_test(suite, "blob_open", blob_open) == NULL || 1126 CU_add_test(suite, "blob_delete", blob_delete) == NULL || 1127 CU_add_test(suite, "blob_resize", blob_resize) == NULL || 1128 CU_add_test(suite, "channel_ops", channel_ops) == NULL || 1129 CU_add_test(suite, "blob_super", blob_super) == NULL || 1130 CU_add_test(suite, "blob_write", blob_write) == NULL || 1131 CU_add_test(suite, "blob_read", blob_read) == NULL || 1132 CU_add_test(suite, "blob_rw_verify", blob_rw_verify) == NULL || 1133 CU_add_test(suite, "blob_rw_verify_iov", blob_rw_verify_iov) == NULL || 1134 CU_add_test(suite, "blob_rw_verify_iov_nomem", blob_rw_verify_iov_nomem) == NULL || 1135 CU_add_test(suite, "blob_iter", blob_iter) == NULL || 1136 CU_add_test(suite, "blob_xattr", blob_xattr) == NULL || 1137 CU_add_test(suite, "bs_load", bs_load) == NULL || 1138 CU_add_test(suite, "bs_cluster_sz", bs_cluster_sz) == NULL || 1139 CU_add_test(suite, "bs_resize_md", bs_resize_md) == NULL || 1140 CU_add_test(suite, "blob_serialize", blob_serialize) == NULL 1141 ) { 1142 CU_cleanup_registry(); 1143 return CU_get_error(); 1144 } 1145 1146 g_dev_buffer = calloc(1, DEV_BUFFER_SIZE); 1147 spdk_allocate_thread(_bs_send_msg, NULL); 1148 CU_basic_set_mode(CU_BRM_VERBOSE); 1149 CU_basic_run_tests(); 1150 num_failures = CU_get_number_of_failures(); 1151 CU_cleanup_registry(); 1152 spdk_free_thread(); 1153 free(g_dev_buffer); 1154 return num_failures; 1155 } 1156