Lines Matching defs:blob
10 #include "spdk/blob.h"
17 #include "blob/blobstore.c"
18 #include "blob/request.c"
19 #include "blob/zeroes.c"
20 #include "blob/blob_bs_dev.c"
61 static void ut_blob_close_and_delete(struct spdk_blob_store *bs, struct spdk_blob *blob);
196 blob_op_with_handle_complete2(void *cb_arg, struct spdk_blob *blob, int bserrno)
199 g_blob = blob;
202 g_blob2 = blob;
218 /* Unload the blob store */
224 /* Load an existing blob store */
243 /* Load an existing blob store */
287 /* Get the super blob without having set one */
293 /* Create a blob */
301 /* Set the blob as the super blob */
306 /* Get the super blob */
317 struct spdk_blob *blob;
332 blob = g_blob;
334 blobid2 = spdk_blob_get_id(blob);
341 CU_ASSERT(blob == g_blob);
343 spdk_blob_close(blob, blob_op_complete, NULL);
351 blob = g_blob;
352 spdk_blob_close(blob, blob_op_complete, NULL);
364 blob = g_blob;
365 spdk_blob_close(blob, blob_op_complete, NULL);
370 * blob object.
397 struct spdk_blob *blob;
401 /* Create blob with 10 clusters */
416 blob = g_blob;
417 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10);
418 CU_ASSERT(spdk_blob_get_num_allocated_clusters(blob) == 10);
420 spdk_blob_close(blob, blob_op_complete, NULL);
424 /* Create blob with 0 clusters */
439 blob = g_blob;
440 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0);
441 CU_ASSERT(spdk_blob_get_num_allocated_clusters(blob) == 0);
443 spdk_blob_close(blob, blob_op_complete, NULL);
447 /* Create blob with default options (opts == NULL) */
459 blob = g_blob;
460 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0);
461 CU_ASSERT(spdk_blob_get_num_allocated_clusters(blob) == 0);
463 spdk_blob_close(blob, blob_op_complete, NULL);
467 /* Try to create blob with size larger than blobstore */
481 struct spdk_blob *blob;
484 /* Create blob with default options (opts == NULL) */
495 blob = g_blob;
496 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0);
497 CU_ASSERT(blob->extent_table_found == true);
498 CU_ASSERT(blob->active.extent_pages_array_size == 0);
499 CU_ASSERT(blob->active.extent_pages == NULL);
501 spdk_blob_close(blob, blob_op_complete, NULL);
505 /* Create blob with NULL internal options */
516 blob = g_blob;
517 CU_ASSERT(TAILQ_FIRST(&blob->xattrs_internal) == NULL);
518 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0);
519 CU_ASSERT(blob->extent_table_found == true);
520 CU_ASSERT(blob->active.extent_pages_array_size == 0);
521 CU_ASSERT(blob->active.extent_pages == NULL);
523 spdk_blob_close(blob, blob_op_complete, NULL);
529 * Create and delete one blob in a loop over and over again. This helps ensure
601 struct spdk_blob *blob;
609 /* Create blob with custom xattrs */
628 blob = g_blob;
630 rc = blob_get_xattr_value(blob, g_xattr_names[0], &value, &value_len, true);
636 rc = blob_get_xattr_value(blob, g_xattr_names[1], &value, &value_len, true);
642 rc = blob_get_xattr_value(blob, g_xattr_names[2], &value, &value_len, true);
648 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[0], &value, &value_len);
651 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[1], &value, &value_len);
654 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[2], &value, &value_len);
657 spdk_blob_close(blob, blob_op_complete, NULL);
661 /* Create blob with NULL internal options */
676 blob = g_blob;
678 spdk_blob_close(blob, blob_op_complete, NULL);
688 struct spdk_blob *blob;
697 /* Initialize a new blob store */
705 /* Create blob with thin provisioning enabled */
711 blob = ut_blob_create_and_open(bs, &opts);
712 blobid = spdk_blob_get_id(blob);
713 CU_ASSERT(blob->invalid_flags & SPDK_BLOB_THIN_PROV);
714 CU_ASSERT(spdk_blob_get_num_allocated_clusters(blob) == 0);
718 if (blob->extent_table_found == true) {
719 CU_ASSERT(blob->active.extent_pages_array_size > 0);
720 CU_ASSERT(blob->active.extent_pages != NULL);
722 CU_ASSERT(blob->active.extent_pages_array_size == 0);
723 CU_ASSERT(blob->active.extent_pages == NULL);
726 spdk_blob_close(blob, blob_op_complete, NULL);
739 blob = g_blob;
740 CU_ASSERT(blob->invalid_flags & SPDK_BLOB_THIN_PROV);
741 CU_ASSERT(spdk_blob_get_num_allocated_clusters(blob) == 0);
743 ut_blob_close_and_delete(bs, blob);
755 struct spdk_blob *blob;
769 /* Create blob with 10 clusters */
773 blob = ut_blob_create_and_open(bs, &opts);
774 blobid = spdk_blob_get_id(blob);
775 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10);
777 /* Create snapshot from blob */
796 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10);
797 CU_ASSERT(spdk_blob_get_num_allocated_clusters(blob) == 0);
798 CU_ASSERT(blob->invalid_flags & SPDK_BLOB_THIN_PROV);
799 CU_ASSERT(spdk_mem_all_zero(blob->active.clusters,
800 blob->active.num_clusters * sizeof(blob->active.clusters[0])));
823 /* Confirm that blob is backed by snapshot2 and snapshot2 is backed by snapshot */
825 SPDK_CU_ASSERT_FATAL(blob->back_bs_dev != NULL);
828 blob_bs_dev = (struct spdk_blob_bs_dev *)blob->back_bs_dev;
829 CU_ASSERT(blob_bs_dev->blob == snapshot2);
832 CU_ASSERT(blob_bs_dev->blob == snapshot);
852 /* Confirm that blob is clone of snapshot2, and snapshot2 is clone of snapshot */
870 /* Delete blob and confirm that it is no longer on snapshot2 clone list */
871 ut_blob_close_and_delete(bs, blob);
893 struct spdk_blob *blob;
909 /* Create blob with 10 clusters */
914 blob = ut_blob_create_and_open(bs, &opts);
915 blobid = spdk_blob_get_id(blob);
916 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10);
928 CU_ASSERT(blob->frozen_refcnt == 1);
930 /* Write to the blob */
931 spdk_blob_io_write(blob, channel, payload_write, 0, num_of_pages, blob_op_complete, NULL);
936 CU_ASSERT(blob->active.clusters[0] == 0);
945 /* Verify that blob has unset frozen_io */
946 CU_ASSERT(blob->frozen_refcnt == 0);
949 spdk_blob_io_read(blob, channel, payload_read, 0, num_of_pages, blob_op_complete, NULL);
957 ut_blob_close_and_delete(bs, blob);
965 struct spdk_blob *blob, *snapshot, *clone;
972 /* Create blob with 10 clusters */
977 blob = ut_blob_create_and_open(bs, &opts);
978 blobid = spdk_blob_get_id(blob);
979 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10);
1046 /* Try to create clone from not read only blob */
1052 /* Mark blob as read only */
1053 spdk_blob_set_read_only(blob);
1054 spdk_blob_sync_md(blob, blob_op_complete, NULL);
1058 /* Create clone from read only blob */
1075 ut_blob_close_and_delete(bs, blob);
1083 struct spdk_blob *blob, *snapshot;
1091 /* Create blob with 10 clusters */
1097 blob = ut_blob_create_and_open(bs, &opts);
1098 blobid = spdk_blob_get_id(blob);
1099 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10);
1100 CU_ASSERT(spdk_blob_is_thin_provisioned(blob) == true);
1101 CU_ASSERT(spdk_blob_get_num_allocated_clusters(blob) == 0);
1105 /* Decouple parent of blob with no parent (should fail) */
1110 /* Inflate of thin blob with no parent should made it thick */
1114 CU_ASSERT(spdk_blob_is_thin_provisioned(blob) == false);
1115 CU_ASSERT(spdk_blob_get_num_allocated_clusters(blob) == 10);
1124 CU_ASSERT(spdk_blob_is_thin_provisioned(blob) == true);
1125 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10);
1144 /* Do full blob inflation */
1150 CU_ASSERT(spdk_blob_get_num_allocated_clusters(blob) == 10);
1152 /* Decouple parent of blob */
1158 CU_ASSERT(spdk_blob_get_num_allocated_clusters(blob) == 0);
1166 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10);
1167 CU_ASSERT(spdk_blob_is_thin_provisioned(blob) == decouple_parent);
1172 ut_blob_close_and_delete(bs, blob);
1189 /* Create a blob and then delete it. */
1201 /* Try to open the blob */
1211 struct spdk_blob *blob;
1216 blob = ut_blob_create_and_open(bs, NULL);
1218 CU_ASSERT(spdk_blob_get_num_allocated_clusters(blob) == 0);
1220 /* Confirm that resize fails if blob is marked read-only. */
1221 blob->md_ro = true;
1222 spdk_blob_resize(blob, 5, blob_op_complete, NULL);
1225 blob->md_ro = false;
1227 /* The blob started at 0 clusters. Resize it to be 5. */
1228 spdk_blob_resize(blob, 5, blob_op_complete, NULL);
1232 CU_ASSERT(spdk_blob_get_num_allocated_clusters(blob) == 5);
1234 /* Shrink the blob to 3 clusters. This will not actually release
1235 * the old clusters until the blob is synced.
1237 spdk_blob_resize(blob, 3, blob_op_complete, NULL);
1242 CU_ASSERT(spdk_blob_get_num_allocated_clusters(blob) == 3);
1244 spdk_blob_sync_md(blob, blob_op_complete, NULL);
1250 /* Resize the blob to be 10 clusters. Growth takes effect immediately. */
1251 spdk_blob_resize(blob, 10, blob_op_complete, NULL);
1255 CU_ASSERT(spdk_blob_get_num_allocated_clusters(blob) == 10);
1257 /* Try to resize the blob to size larger than blobstore. */
1258 spdk_blob_resize(blob, bs->total_clusters + 1, blob_op_complete, NULL);
1262 ut_blob_close_and_delete(bs, blob);
1269 struct spdk_blob *blob;
1282 /* Create blob with thin provisioning enabled */
1287 blob = ut_blob_create_and_open(bs, &opts);
1289 CU_ASSERT(spdk_blob_get_num_allocated_clusters(blob) == 0);
1290 io_units_per_cluster = bs_io_units_per_cluster(blob);
1292 /* The blob started at 0 clusters. Resize it to be 6. */
1293 spdk_blob_resize(blob, 6, blob_op_complete, NULL);
1297 CU_ASSERT(spdk_blob_get_num_allocated_clusters(blob) == 0);
1299 /* Write on cluster 0,2,4 and 5 of blob */
1301 spdk_blob_io_write(blob, blob_ch, buf1, offset, 1, blob_op_complete, NULL);
1306 spdk_blob_io_write(blob, blob_ch, buf1, offset, 1, blob_op_complete, NULL);
1311 spdk_blob_io_write(blob, blob_ch, buf1, offset, 1, blob_op_complete, NULL);
1316 spdk_blob_io_write(blob, blob_ch, buf1, offset, 1, blob_op_complete, NULL);
1323 CU_ASSERT(spdk_blob_get_num_allocated_clusters(blob) == 4);
1325 /* Shrink the blob to 2 clusters. This will not actually release
1326 * the old clusters until the blob is synced.
1328 spdk_blob_resize(blob, 2, blob_op_complete, NULL);
1331 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 2);
1333 CU_ASSERT(spdk_blob_get_num_allocated_clusters(blob) == 1);
1335 /* Sync blob: 4 clusters were truncated but only 3 of them was allocated */
1336 spdk_blob_sync_md(blob, blob_op_complete, NULL);
1340 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 2);
1341 CU_ASSERT(spdk_blob_get_num_allocated_clusters(blob) == 1);
1344 ut_blob_close_and_delete(bs, blob);
1352 struct spdk_blob *blob;
1367 blob = ut_blob_create_and_open(bs, NULL);
1368 blobid = spdk_blob_get_id(blob);
1370 rc = spdk_blob_set_read_only(blob);
1373 CU_ASSERT(blob->data_ro == false);
1374 CU_ASSERT(blob->md_ro == false);
1376 spdk_blob_sync_md(blob, bs_op_complete, NULL);
1379 CU_ASSERT(blob->data_ro == true);
1380 CU_ASSERT(blob->md_ro == true);
1381 CU_ASSERT(blob->data_ro_flags & SPDK_BLOB_READ_ONLY);
1383 spdk_blob_close(blob, blob_op_complete, NULL);
1391 blob = g_blob;
1393 CU_ASSERT(blob->data_ro == true);
1394 CU_ASSERT(blob->md_ro == true);
1395 CU_ASSERT(blob->data_ro_flags & SPDK_BLOB_READ_ONLY);
1397 spdk_blob_close(blob, blob_op_complete, NULL);
1407 blob = g_blob;
1409 CU_ASSERT(blob->data_ro == true);
1410 CU_ASSERT(blob->md_ro == true);
1411 CU_ASSERT(blob->data_ro_flags & SPDK_BLOB_READ_ONLY);
1413 ut_blob_close_and_delete(bs, blob);
1437 struct spdk_blob *blob = g_blob;
1447 /* Write to a blob with 0 size */
1448 spdk_blob_io_write(blob, channel, payload, 0, 1, blob_op_complete, NULL);
1452 /* Resize the blob */
1453 spdk_blob_resize(blob, 5, blob_op_complete, NULL);
1457 /* Confirm that write fails if blob is marked read-only. */
1458 blob->data_ro = true;
1459 spdk_blob_io_write(blob, channel, payload, 0, 1, blob_op_complete, NULL);
1462 blob->data_ro = false;
1464 /* Write to the blob */
1465 spdk_blob_io_write(blob, channel, payload, 0, 1, blob_op_complete, NULL);
1470 spdk_blob_io_write(blob, channel, payload, 5 * io_units_per_cluster, 1, blob_op_complete,
1476 spdk_blob_io_write(blob, channel, payload, 4 * io_units_per_cluster, io_units_per_cluster + 1,
1489 struct spdk_blob *blob = g_blob;
1499 /* Read from a blob with 0 size */
1500 spdk_blob_io_read(blob, channel, payload, 0, 1, blob_op_complete, NULL);
1504 /* Resize the blob */
1505 spdk_blob_resize(blob, 5, blob_op_complete, NULL);
1509 /* Confirm that read passes if blob is marked read-only. */
1510 blob->data_ro = true;
1511 spdk_blob_io_read(blob, channel, payload, 0, 1, blob_op_complete, NULL);
1514 blob->data_ro = false;
1516 /* Read from the blob */
1517 spdk_blob_io_read(blob, channel, payload, 0, 1, blob_op_complete, NULL);
1522 spdk_blob_io_read(blob, channel, payload, 5 * io_units_per_cluster, 1, blob_op_complete,
1528 spdk_blob_io_read(blob, channel, payload, 4 * io_units_per_cluster, io_units_per_cluster + 1,
1541 struct spdk_blob *blob = g_blob;
1549 spdk_blob_resize(blob, 32, blob_op_complete, NULL);
1554 spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL);
1559 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL);
1572 struct spdk_blob *blob;
1584 blob = ut_blob_create_and_open(bs, NULL);
1586 spdk_blob_resize(blob, 2, blob_op_complete, NULL);
1591 * Manually adjust the offset of the blob's second cluster. This allows
1596 CU_ASSERT(blob->active.clusters[0] == first_data_cluster * 256);
1597 CU_ASSERT(blob->active.clusters[1] == (first_data_cluster + 1) * 256);
1598 blob->active.clusters[1] = (first_data_cluster + 2) * 256;
1611 spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL);
1622 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL);
1634 spdk_blob_close(blob, blob_op_complete, NULL);
1660 struct spdk_blob *blob = g_blob;
1669 spdk_blob_resize(blob, 2, blob_op_complete, NULL);
1685 spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL);
1699 struct spdk_blob *blob = g_blob;
1709 spdk_blob_resize(blob, 2, blob_op_complete, NULL);
1714 blob->data_ro = true;
1717 spdk_blob_io_writev(blob, channel, &iov_write, 1, 0, 1, blob_op_complete, NULL);
1724 spdk_blob_io_readv(blob, channel, &iov_read, 1, 0, 1, blob_op_complete, NULL);
1733 _blob_io_read_no_split(struct spdk_blob *blob, struct spdk_io_channel *channel,
1739 uint64_t io_unit_size = spdk_bs_get_io_unit_size(blob->bs);
1744 spdk_blob_io_read(blob, channel, buf, i + offset, 1, blob_op_complete, NULL);
1757 _blob_io_write_no_split(struct spdk_blob *blob, struct spdk_io_channel *channel,
1763 uint64_t io_unit_size = spdk_bs_get_io_unit_size(blob->bs);
1768 spdk_blob_io_write(blob, channel, buf, i + offset, 1, blob_op_complete, NULL);
1784 struct spdk_blob *blob;
1824 /* Create blob */
1829 blob = ut_blob_create_and_open(bs, &opts);
1830 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5);
1834 spdk_blob_io_read(blob, channel, payload_read, 0, io_units_per_payload, blob_op_complete, NULL);
1839 /* Fill whole blob except last page */
1840 spdk_blob_io_write(blob, channel, payload_pattern, 0, io_units_per_payload - 1,
1846 spdk_blob_io_write(blob, channel, payload_pattern, io_units_per_payload - 1, 1,
1851 /* Read whole blob and check consistency */
1853 spdk_blob_io_read(blob, channel, payload_read, 0, io_units_per_payload, blob_op_complete, NULL);
1859 /* Fill whole blob except first page */
1860 spdk_blob_io_write(blob, channel, payload_pattern, 1, io_units_per_payload - 1,
1866 spdk_blob_io_write(blob, channel, payload_pattern, 0, 1,
1871 /* Read whole blob and check consistency */
1873 spdk_blob_io_read(blob, channel, payload_read, 0, io_units_per_payload, blob_op_complete, NULL);
1880 /* Fill whole blob with a pattern (5 clusters) */
1883 _blob_io_write_no_split(blob, channel, payload_pattern, 0, io_units_per_payload,
1889 spdk_blob_io_read(blob, channel, payload_read, 0, io_units_per_payload, blob_op_complete, NULL);
1896 spdk_blob_io_write(blob, channel, payload_pattern, 0, io_units_per_payload,
1902 _blob_io_read_no_split(blob, channel, payload_read, 0, io_units_per_payload, blob_op_complete,
1918 ut_blob_close_and_delete(bs, blob);
1925 struct spdk_blob *blob;
1973 /* Create blob */
1978 blob = ut_blob_create_and_open(bs, &opts);
1979 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5);
1987 spdk_blob_io_readv(blob, channel, iov_read, 2, 0, io_units_per_payload, blob_op_complete, NULL);
1992 /* First of iovs fills whole blob except last io_unit and second of iovs writes last io_unit
1998 spdk_blob_io_writev(blob, channel, iov_write, 2, 0, io_units_per_payload, blob_op_complete, NULL);
2002 /* Read whole blob and check consistency */
2008 spdk_blob_io_readv(blob, channel, iov_read, 2, 0, io_units_per_payload, blob_op_complete, NULL);
2014 /* First of iovs fills only first io_unit and second of iovs writes whole blob except
2020 spdk_blob_io_writev(blob, channel, iov_write, 2, 0, io_units_per_payload, blob_op_complete, NULL);
2024 /* Read whole blob and check consistency */
2030 spdk_blob_io_readv(blob, channel, iov_read, 2, 0, io_units_per_payload, blob_op_complete, NULL);
2037 /* Fill whole blob with a pattern (5 clusters) */
2040 _blob_io_write_no_split(blob, channel, payload_pattern, 0, io_units_per_payload,
2050 spdk_blob_io_readv(blob, channel, iov_read, 2, 0, io_units_per_payload, blob_op_complete, NULL);
2060 spdk_blob_io_writev(blob, channel, iov_write, 2, 0, io_units_per_payload, blob_op_complete, NULL);
2065 _blob_io_read_no_split(blob, channel, payload_read, 0, io_units_per_payload, blob_op_complete,
2081 ut_blob_close_and_delete(bs, blob);
2088 struct spdk_blob *blob;
2101 blob = ut_blob_create_and_open(bs, &opts);
2103 spdk_blob_resize(blob, 10, blob_op_complete, NULL);
2106 CU_ASSERT(spdk_blob_get_num_allocated_clusters(blob) == 10);
2121 spdk_blob_io_read(blob, channel, &payload, i * SPDK_BLOB_OPTS_CLUSTER_SZ / BLOCKLEN, 1,
2129 blob->active.clusters[1] = 0;
2130 blob->active.clusters[2] = 0;
2131 blob->active.clusters[3] = 0;
2132 blob->active.clusters[6] = 0;
2133 blob->active.clusters[8] = 0;
2134 blob->active.num_allocated_clusters -= 5;
2137 spdk_blob_resize(blob, 0, blob_op_complete, NULL);
2141 spdk_blob_sync_md(blob, blob_op_complete, NULL);
2144 CU_ASSERT(spdk_blob_get_num_allocated_clusters(blob) == 0);
2165 ut_blob_close_and_delete(bs, blob);
2172 struct spdk_blob *blob;
2192 blob = g_blob;
2193 CU_ASSERT(spdk_blob_get_id(blob) == blobid);
2195 spdk_bs_iter_next(bs, blob, blob_op_with_handle_complete, NULL);
2205 struct spdk_blob *blob = g_blob;
2206 spdk_blob_id blobid = spdk_blob_get_id(blob);
2215 blob->md_ro = true;
2216 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1);
2219 blob->md_ro = false;
2220 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1);
2224 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
2229 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
2234 blob->md_ro = true;
2235 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len);
2240 blob->md_ro = false;
2242 rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len);
2246 rc = spdk_blob_get_xattr_names(blob, &names);
2260 blob->md_ro = true;
2261 rc = spdk_blob_remove_xattr(blob, "name");
2264 blob->md_ro = false;
2265 rc = spdk_blob_remove_xattr(blob, "name");
2268 rc = spdk_blob_remove_xattr(blob, "foobar");
2273 rc = blob_set_xattr(blob, "internal", &length, sizeof(length), true);
2275 rc = blob_get_xattr_value(blob, "internal", &value, &value_len, true);
2279 rc = spdk_blob_get_xattr_value(blob, "internal", &value, &value_len);
2281 rc = blob_get_xattr_value(blob, "internal", &value, &value_len, false);
2284 CU_ASSERT((blob->invalid_flags & SPDK_BLOB_INTERNAL_XATTR) ==
2287 spdk_blob_close(blob, blob_op_complete, NULL);
2297 blob = g_blob;
2299 rc = blob_get_xattr_value(blob, "internal", &value, &value_len, true);
2304 rc = spdk_blob_get_xattr_value(blob, "internal", &value, &value_len);
2307 rc = blob_remove_xattr(blob, "internal", true);
2310 CU_ASSERT((blob->invalid_flags & SPDK_BLOB_INTERNAL_XATTR) == 0);
2317 struct spdk_blob *blob;
2324 blob = ut_blob_create_and_open(bs, NULL);
2331 rc = spdk_blob_set_xattr(blob, "large_xattr", xattr, xattr_length);
2335 spdk_blob_sync_md(blob, blob_op_complete, NULL);
2338 /* Delete the blob and verify that number of pages returned to before its creation. */
2340 ut_blob_close_and_delete(bs, blob);
2350 struct spdk_blob *blob;
2363 /* Initialize a new blob store */
2376 /* Create a blob */
2377 blob = ut_blob_create_and_open(bs, NULL);
2378 blobid = spdk_blob_get_id(blob);
2380 /* Try again to open valid blob but without the upper bit set */
2387 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1);
2391 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
2394 /* Resize the blob */
2395 spdk_blob_resize(blob, 10, blob_op_complete, NULL);
2399 spdk_blob_close(blob, blob_op_complete, NULL);
2402 blob = NULL;
2406 /* Unload the blob store */
2440 /* Load an existing blob store */
2458 blob = g_blob;
2461 spdk_blob_sync_md(blob, blob_op_complete, NULL);
2466 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len);
2472 rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len);
2475 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10);
2476 CU_ASSERT(spdk_blob_get_num_allocated_clusters(blob) == 10);
2478 spdk_blob_close(blob, blob_op_complete, NULL);
2481 blob = NULL;
2531 /* Create a blob */
2555 struct spdk_blob *blob, *snapshot;
2561 /* Create blob */
2565 blob = ut_blob_create_and_open(bs, &opts);
2566 blobid = spdk_blob_get_id(blob);
2591 spdk_blob_close(blob, blob_op_complete, NULL);
2598 /* Snapshot should not be removed as blob is still pointing to it */
2619 blob = g_blob;
2621 /* Remove parent_id from blob by removing BLOB_SNAPSHOT xattr */
2622 blob_remove_xattr(blob, BLOB_SNAPSHOT, true);
2624 spdk_blob_sync_md(blob, blob_op_complete, NULL);
2632 spdk_blob_close(blob, blob_op_complete, NULL);
2639 /* Snapshot should be removed as blob is not pointing to it anymore */
2661 /* Initialize a new blob store */
2670 /* Unload the blob store */
2681 /* Load an existing blob store */
2714 struct spdk_blob *blob, *snapshot;
2728 /* Initialize a new blob store */
2735 /* Create blob */
2739 blob = ut_blob_create_and_open(bs, &blob_opts);
2740 blobid = spdk_blob_get_id(blob);
2759 spdk_blob_close(blob, blob_op_complete, NULL);
2766 /* Unload the blob store */
2788 /* Load an existing blob store */
2804 /* Check the blob and the snapshot are still available */
2809 blob = g_blob;
2811 spdk_blob_close(blob, blob_op_complete, NULL);
2844 /* Initialize a new blob store */
2851 /* Unload the blob store */
2889 /* Initialize a new blob store */
2896 /* Unload the blob store */
2925 /* Initialize a new blob store with empty bstype */
2974 /* Initialize a new blob store */
2981 /* Unload the blob store */
2989 /* Load an existing blob store with version newer than supported */
2999 /* Create a new blob store with super block version 1 */
3353 struct spdk_blob *blob;
3356 /* Create a blob and open it. */
3357 blob = ut_blob_create_and_open(bs, NULL);
3359 /* Try to unload blobstore, should fail with open blob */
3366 /* Close the blob, then successfully unload blobstore */
3368 spdk_blob_close(blob, blob_op_complete, NULL);
3407 /* Initialize a new blob store */
3421 /* Initialize a new blob store */
3435 /* Initialize a new blob store */
3447 /* Initialize a new blob store */
3474 struct spdk_blob *blob;
3489 blob = ut_blob_create_and_open(bs, NULL);
3491 spdk_blob_resize(blob, 10, blob_op_complete, NULL);
3496 spdk_blob_close(blob, blob_op_complete, NULL);
3503 /* Reload the blob store to make sure that nothing changed */
3510 * Test resizing of the metadata blob. This requires creating enough blobs
3513 * size to 16KB, which means only 4 4KB blob metadata pages can fit.
3523 struct spdk_blob *blob;
3535 /* Initialize a new blob store */
3567 blob = g_blob;
3569 spdk_blob_close(blob, blob_op_complete, NULL);
3587 /* Initialize a new blob store */
3604 /* Destroy the blob store */
3610 /* Loading an non-existent blob store should fail. */
3621 * a blob to disk
3630 struct spdk_blob *blob[2];
3648 blob[i] = ut_blob_create_and_open(bs, NULL);
3649 blobid[i] = spdk_blob_get_id(blob[i]);
3657 rc = spdk_blob_set_xattr(blob[i], "name", value, dev->blocklen - 64);
3667 spdk_blob_resize(blob[i % 2], (i / 2) + 1, blob_op_complete, NULL);
3673 spdk_blob_sync_md(blob[i], blob_op_complete, NULL);
3680 spdk_blob_close(blob[i], blob_op_complete, NULL);
3688 blob[i] = NULL;
3694 blob[i] = g_blob;
3696 CU_ASSERT(spdk_blob_get_num_clusters(blob[i]) == 3);
3698 spdk_blob_close(blob[i], blob_op_complete, NULL);
3713 struct spdk_blob *blob;
3719 blob = ut_blob_create_and_open(bs, NULL);
3720 blobid = spdk_blob_get_id(blob);
3722 spdk_blob_close(blob, blob_op_complete, NULL);
3765 /* Load an existing blob store */
3772 /* For blob dirty shutdown test case we do the following sub-test cases:
3773 * 1 Initialize new blob store and create 1 super blob with some xattrs, then we
3774 * dirty shutdown and reload the blob store and verify the xattrs.
3775 * 2 Resize the blob from 10 clusters to 20 clusters and then dirty shutdown,
3776 * reload the blob store and verify the clusters number.
3777 * 3 Create the second blob and then dirty shutdown, reload the blob store
3778 * and verify the second blob.
3779 * 4 Delete the second blob and then dirty shutdown, reload the blob store
3780 * and verify the second blob is invalid.
3781 * 5 Create the second blob again and also create the third blob, modify the
3782 * md of second blob which makes the md invalid, and then dirty shutdown,
3783 * reload the blob store verify the second blob, it should invalid and also
3784 * verify the third blob, it should correct.
3793 struct spdk_blob *blob = g_blob;
3802 /* Create first blob */
3803 blobid1 = spdk_blob_get_id(blob);
3806 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1);
3810 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
3822 rc = spdk_blob_set_xattr(blob, "large_xattr", xattr, xattr_length);
3826 /* Resize the blob */
3827 spdk_blob_resize(blob, 10, blob_op_complete, NULL);
3831 /* Set the blob as the super blob */
3838 spdk_blob_close(blob, blob_op_complete, NULL);
3841 blob = NULL;
3847 /* Get the super blob */
3857 blob = g_blob;
3863 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len);
3868 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10);
3870 /* Resize the blob */
3871 spdk_blob_resize(blob, 20, blob_op_complete, NULL);
3877 spdk_blob_close(blob, blob_op_complete, NULL);
3880 blob = NULL;
3890 blob = g_blob;
3891 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 20);
3894 spdk_blob_close(blob, blob_op_complete, NULL);
3897 blob = NULL;
3901 /* Create second blob */
3902 blob = ut_blob_create_and_open(bs, NULL);
3903 blobid2 = spdk_blob_get_id(blob);
3906 rc = spdk_blob_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1);
3910 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
3913 /* Resize the blob */
3914 spdk_blob_resize(blob, 10, blob_op_complete, NULL);
3920 spdk_blob_close(blob, blob_op_complete, NULL);
3923 blob = NULL;
3933 blob = g_blob;
3937 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len);
3942 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10);
3945 ut_blob_close_and_delete(bs, blob);
3960 blob = g_blob;
3962 spdk_blob_close(blob, blob_op_complete, NULL);
3968 /* Create second blob */
3976 /* Create third blob */
3987 blob = g_blob;
3989 /* Set some xattrs for second blob */
3990 rc = spdk_blob_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1);
3994 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
3997 spdk_blob_close(blob, blob_op_complete, NULL);
4000 blob = NULL;
4008 blob = g_blob;
4010 /* Set some xattrs for third blob */
4011 rc = spdk_blob_set_xattr(blob, "name", "log2.txt", strlen("log2.txt") + 1);
4015 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
4018 spdk_blob_close(blob, blob_op_complete, NULL);
4021 blob = NULL;
4025 /* Mark second blob as invalid */
4046 blob = g_blob;
4074 * when blob has non zero number of extents */
4080 * when blob has non zero number of xattrs */
4139 /* If an unknown data_ro flag was found, the blob should be marked both data and md read-only. */
4169 struct spdk_blob *blob;
4173 /* Unload the blob store */
4191 * region on "disk". We will use this to ensure blob IDs are
4200 /* Load an existing blob store */
4210 * Create a blob - just to make sure that when we unload it
4221 /* Unload the blob store */
4242 blob = g_blob;
4244 ut_blob_close_and_delete(bs, blob);
4255 struct spdk_blob *blob;
4263 /* Create blob with extra attributes */
4271 blob = ut_blob_create_and_open(bs, &opts);
4276 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[0], &value, &value_len);
4282 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[1], &value, &value_len);
4288 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[2], &value, &value_len);
4296 rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len);
4304 rc = spdk_blob_set_xattr(blob, "large_xattr", xattr, xattr_length);
4308 spdk_blob_close(blob, blob_op_complete, NULL);
4311 blob = NULL;
4343 struct spdk_blob *blob;
4350 /* Set blob as thin provisioned */
4354 blob = ut_blob_create_and_open(bs, &opts);
4355 blobid = spdk_blob_get_id(blob);
4358 CU_ASSERT(blob->active.num_clusters == 0);
4359 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0);
4360 CU_ASSERT(spdk_blob_get_num_allocated_clusters(blob) == 0);
4362 /* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */
4363 spdk_blob_resize(blob, 5, blob_op_complete, NULL);
4367 CU_ASSERT(blob->active.num_clusters == 5);
4368 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5);
4369 CU_ASSERT(spdk_blob_get_num_allocated_clusters(blob) == 0);
4372 spdk_blob_resize(blob, 262144, blob_op_complete, NULL);
4376 CU_ASSERT(blob->active.num_clusters == 262144);
4377 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 262144);
4378 CU_ASSERT(spdk_blob_get_num_allocated_clusters(blob) == 0);
4380 spdk_blob_sync_md(blob, blob_op_complete, NULL);
4385 CU_ASSERT(blob->active.num_clusters == 262144);
4386 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 262144);
4387 CU_ASSERT(spdk_blob_get_num_allocated_clusters(blob) == 0);
4391 CU_ASSERT(blob->active.num_pages == 1);
4393 /* Shrink the blob to 3 clusters - still unallocated */
4394 spdk_blob_resize(blob, 3, blob_op_complete, NULL);
4398 CU_ASSERT(blob->active.num_clusters == 3);
4399 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 3);
4400 CU_ASSERT(spdk_blob_get_num_allocated_clusters(blob) == 0);
4402 spdk_blob_sync_md(blob, blob_op_complete, NULL);
4407 CU_ASSERT(blob->active.num_clusters == 3);
4408 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 3);
4409 CU_ASSERT(spdk_blob_get_num_allocated_clusters(blob) == 0);
4411 spdk_blob_close(blob, blob_op_complete, NULL);
4421 blob = g_blob;
4425 CU_ASSERT(blob->active.num_clusters == 3);
4427 ut_blob_close_and_delete(bs, blob);
4434 struct spdk_blob *blob;
4454 /* Set blob as thin provisioned */
4459 blob = ut_blob_create_and_open(bs, &opts);
4460 blobid = spdk_blob_get_id(blob);
4463 CU_ASSERT(blob->active.num_clusters == 4);
4464 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 4);
4465 CU_ASSERT(blob->active.clusters[cluster_num] == 0);
4468 * This is to simulate behaviour when cluster is allocated after blob creation.
4471 bs_allocate_cluster(blob, cluster_num, &new_cluster, &extent_page, false);
4472 CU_ASSERT(blob->active.clusters[cluster_num] == 0);
4475 blob_insert_cluster_on_md_thread(blob, cluster_num, new_cluster, extent_page, &md.page,
4479 CU_ASSERT(blob->active.clusters[cluster_num] != 0);
4481 spdk_blob_close(blob, blob_op_complete, NULL);
4491 blob = g_blob;
4493 CU_ASSERT(blob->active.clusters[cluster_num] != 0);
4495 ut_blob_close_and_delete(bs, blob);
4503 struct spdk_blob *blob, *blob_id0;
4523 /* Create and delete blob at md page 0, so that next md page allocation
4526 blob = ut_blob_create_and_open(bs, &opts);
4530 CU_ASSERT(blob->active.num_clusters == 0);
4531 CU_ASSERT(spdk_blob_get_num_allocated_clusters(blob) == 0);
4533 /* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */
4534 spdk_blob_resize(blob, 5, blob_op_complete, NULL);
4538 CU_ASSERT(blob->active.num_clusters == 5);
4539 CU_ASSERT(spdk_blob_get_num_allocated_clusters(blob) == 0);
4541 spdk_blob_sync_md(blob, blob_op_complete, NULL);
4546 CU_ASSERT(blob->active.num_clusters == 5);
4547 CU_ASSERT(spdk_blob_get_num_allocated_clusters(blob) == 0);
4551 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL);
4564 spdk_blob_io_write(blob, channel_thread1, payload_write, 4, 10, blob_op_complete, NULL);
4570 spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL);
4575 CU_ASSERT(spdk_blob_get_num_allocated_clusters(blob) == 1);
4576 /* For thin-provisioned blob we need to write 20 io_units plus one page metadata and
4586 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL);
4591 ut_blob_close_and_delete(bs, blob);
4607 struct spdk_blob *blob;
4649 blob = ut_blob_create_and_open(bs, &opts);
4652 /* Resize the blob so that it will require 8 extent pages to hold all of
4656 spdk_blob_resize(blob, SPDK_EXTENTS_PER_EP * 8, blob_op_complete, NULL);
4661 spdk_blob_sync_md(blob, blob_op_complete, NULL);
4665 CU_ASSERT(blob->active.num_clusters == SPDK_EXTENTS_PER_EP * 8);
4673 spdk_blob_io_write(blob, ch, payload_write, io_units_per_extent_page * i, 1, blob_op_complete,
4682 * the write I/O, plus the blob's primary metadata page
4688 * blob's primary metadata page
4701 spdk_blob_sync_md(blob, blob_op_complete, NULL);
4705 CU_ASSERT(spdk_blob_get_num_allocated_clusters(blob) == 2 * i + 1);
4712 spdk_blob_io_write(blob, ch, payload_write, io_units_per_extent_page * i + io_units_per_cluster,
4717 CU_ASSERT(spdk_blob_get_num_allocated_clusters(blob) == 2 * i + 2);
4729 spdk_blob_io_unmap(blob, ch, io_units_per_extent_page * i, io_units_per_cluster, blob_op_complete,
4737 spdk_blob_io_write(blob, ch, payload_write, io_units_per_extent_page * i, 1, blob_op_complete,
4744 ut_blob_close_and_delete(bs, blob);
4762 struct spdk_blob *blob, *snapshot;
4800 blob = ut_blob_create_and_open(bs, &opts);
4803 blobid = spdk_blob_get_id(blob);
4806 spdk_blob_resize(blob, CLUSTER_COUNT, blob_op_complete, NULL);
4811 spdk_blob_sync_md(blob, blob_op_complete, NULL);
4815 CU_ASSERT(blob->active.num_clusters == CLUSTER_COUNT);
4821 spdk_blob_io_write(blob, ch, payload_write, io_units_per_cluster * i, 1, blob_op_complete, NULL);
4830 spdk_blob_io_unmap(blob, ch, io_units_per_cluster, io_units_per_cluster, blob_op_complete, NULL);
4837 spdk_blob_io_read(blob, ch, payload_read, io_units_per_cluster, 1, blob_op_complete, NULL);
4845 spdk_blob_io_write(blob, ch, payload_write, io_units_per_cluster, 1, blob_op_complete, NULL);
4851 spdk_blob_io_read(blob, ch, payload_read, io_units_per_cluster, 1, blob_op_complete, NULL);
4858 spdk_blob_io_unmap(blob, ch, io_units_per_cluster - 1, io_units_per_cluster + 2, blob_op_complete,
4867 spdk_blob_io_read(blob, ch, payload_read, io_units_per_cluster, 1, blob_op_complete, NULL);
4876 spdk_blob_io_unmap(blob, ch, 0, io_units_per_cluster, blob_op_complete, NULL);
4877 spdk_blob_io_write(blob, ch, payload_write, io_units_per_cluster, 1, blob_op_complete, NULL);
4884 spdk_blob_io_read(blob, ch, payload_read, io_units_per_cluster, 1, blob_op_complete, NULL);
4892 spdk_blob_io_read(blob, ch, payload_read, 0, 1, blob_op_complete, NULL);
4900 spdk_blob_io_write(blob, ch, payload_write, 0, 1, blob_op_complete, NULL);
4906 spdk_blob_io_unmap(blob, ch, 0, io_units_per_cluster, blob_op_complete, NULL);
4920 spdk_blob_io_write(blob, ch, payload_write, 0, 1, blob_op_complete, NULL);
4927 spdk_blob_io_unmap(blob, ch, 0, io_units_per_cluster, blob_op_complete, NULL);
4928 spdk_blob_io_unmap(blob, ch, 0, io_units_per_cluster, blob_op_complete, NULL);
4929 spdk_blob_io_unmap(blob, ch, 0, io_units_per_cluster, blob_op_complete, &err);
4935 /* Test thin-provisioned blob that is backed */
4936 spdk_blob_resize(blob, 1, blob_op_complete, NULL);
4939 spdk_blob_sync_md(blob, blob_op_complete, NULL);
4946 spdk_blob_io_write(blob, ch, payload_write, 0, 1, blob_op_complete, NULL);
4966 /* Write data to blob, it will alloc new cluster */
4969 spdk_blob_io_write(blob, ch, payload_write, 0, 1, blob_op_complete, NULL);
4976 spdk_blob_io_unmap(blob, ch, 0, io_units_per_cluster, blob_op_complete, NULL);
4984 spdk_blob_io_read(blob, ch, payload_read, 0, 1, blob_op_complete, NULL);
4989 ut_blob_close_and_delete(bs, blob);
5009 struct spdk_blob *blob;
5032 blob = ut_blob_create_and_open(bs, &opts);
5033 blobid = spdk_blob_get_id(blob);
5039 /* Target specifically second cluster in a blob as first allocation */
5044 spdk_blob_io_read(blob, channel, payload_read, io_unit, 10, blob_op_complete, NULL);
5052 /* Issue write to second cluster in a blob */
5054 spdk_blob_io_write(blob, channel, payload_write, io_unit, 10, blob_op_complete, NULL);
5058 /* For thin-provisioned blob we need to write 10 pages plus one page metadata and
5068 spdk_blob_io_read(blob, channel, payload_read, io_unit, 10, blob_op_complete, NULL);
5076 spdk_blob_close(blob, blob_op_complete, NULL);
5086 blob = g_blob;
5091 /* Read second cluster after blob reload to confirm data written */
5092 spdk_blob_io_read(blob, channel, payload_read, io_unit, 10, blob_op_complete, NULL);
5100 ut_blob_close_and_delete(bs, blob);
5108 struct spdk_blob *blob;
5125 blob = ut_blob_create_and_open(bs, &opts);
5128 CU_ASSERT(blob->active.num_clusters == 0);
5130 /* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */
5131 spdk_blob_resize(blob, 5, blob_op_complete, NULL);
5135 CU_ASSERT(blob->active.num_clusters == 5);
5137 spdk_blob_sync_md(blob, blob_op_complete, NULL);
5142 CU_ASSERT(blob->active.num_clusters == 5);
5152 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL);
5165 spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL);
5176 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL);
5184 ut_blob_close_and_delete(bs, blob);
5193 test_iter(void *arg, struct spdk_blob *blob, int bserrno)
5199 blobid = spdk_blob_get_id(blob);
5209 struct spdk_blob *blob;
5217 /* Initialize a new blob store */
5225 blob = ut_blob_create_and_open(bs, NULL);
5226 iter_ctx.blobid[i] = spdk_blob_get_id(blob);
5229 rc = spdk_blob_set_xattr(blob, "blobid", &iter_ctx.blobid[i], sizeof(spdk_blob_id));
5232 /* Resize the blob */
5233 spdk_blob_resize(blob, i, blob_op_complete, NULL);
5237 spdk_blob_close(blob, blob_op_complete, NULL);
5253 /* Test blob iteration during load after a clean shutdown. */
5270 /* Test blob iteration during load after a dirty shutdown. */
5288 struct spdk_blob *blob, *snapshot;
5316 blob = ut_blob_create_and_open(bs, &opts);
5317 blobid = spdk_blob_get_id(blob);
5320 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5);
5323 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL);
5329 spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL);
5334 /* Create snapshot from blob */
5356 spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL);
5380 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL);
5392 ut_blob_close_and_delete(bs, blob);
5406 struct spdk_blob *blob, *snapshot;
5425 blob = ut_blob_create_and_open(bs, &opts);
5426 blobid = spdk_blob_get_id(blob);
5429 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5);
5431 /* Create snapshot from blob */
5455 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL);
5468 spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL);
5479 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL);
5487 ut_blob_close_and_delete(bs, blob);
5495 * original blob: 0 1 2 3 4
5501 * blob | - |zzzzzzzzz| - | - | - |
5507 * blob |xxxxxxxxx|zzzzzzzzz|xxxxxxxxx|yyyyyyyyy|000000000|
5518 * blob | - |zzzzzzzzz| - |yyyyyyyyy| - |
5529 struct spdk_blob *blob, *snapshot, *snapshot2;
5567 /* Create blob */
5572 blob = ut_blob_create_and_open(bs, &opts);
5573 blobid = spdk_blob_get_id(blob);
5576 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5);
5580 spdk_blob_io_read(blob, channel, payload_read, 0, io_units_per_payload,
5586 /* Fill whole blob with a pattern, except last cluster (to be sure it
5589 spdk_blob_io_write(blob, channel, payload_write, 0, io_units_per_payload -
5595 /* 2) Create snapshot from blob (first level) */
5617 * payload_clone stores expected result on "blob" read at the time and
5626 spdk_blob_io_write(blob, channel, payload_write, i * io_units_per_cluster,
5639 spdk_blob_io_read(blob, channel, payload_read, 0, io_units_per_payload,
5645 /* 3) Create second levels snapshot from blob */
5664 /* Write one cluster on the top level blob. This cluster (1) covers
5667 spdk_blob_io_write(blob, channel, payload_write, io_units_per_cluster,
5677 spdk_blob_io_read(blob, channel, payload_read, 0, io_units_per_payload,
5685 spdk_blob_close(blob, blob_op_complete, NULL);
5712 /* Do full blob inflation */
5718 * in a top level blob) */
5736 /* Decouple parent of blob */
5742 * is covered by a cluster written on a top level blob, and
5773 /* Reopen blob after snapshot deletion */
5778 blob = g_blob;
5780 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5);
5782 /* Check data consistency on inflated blob */
5784 spdk_blob_io_read(blob, channel, payload_read, 0, io_units_per_payload,
5797 ut_blob_close_and_delete(bs, blob);
5814 * blob(ro) snapshot2
5825 struct spdk_blob *blob, *snapshot, *snapshot2, *clone, *clone2;
5841 /* 1. Create blob with 10 clusters */
5846 blob = ut_blob_create_and_open(bs, &opts);
5847 blobid = spdk_blob_get_id(blob);
5849 CU_ASSERT(!spdk_blob_is_read_only(blob));
5850 CU_ASSERT(!spdk_blob_is_snapshot(blob));
5851 CU_ASSERT(!spdk_blob_is_clone(blob));
5852 CU_ASSERT(!spdk_blob_is_thin_provisioned(blob));
5854 /* blob should not have underlying snapshot nor clones */
5855 CU_ASSERT(blob->parent_id == SPDK_BLOBID_INVALID);
5883 /* Check if original blob is converted to the clone of snapshot */
5884 CU_ASSERT(!spdk_blob_is_read_only(blob));
5885 CU_ASSERT(!spdk_blob_is_snapshot(blob));
5886 CU_ASSERT(spdk_blob_is_clone(blob));
5887 CU_ASSERT(spdk_blob_is_thin_provisioned(blob));
5888 CU_ASSERT(blob->parent_id == snapshotid);
5968 /* 5. Try to create clone from read only blob */
5970 /* Mark blob as read only */
5971 spdk_blob_set_read_only(blob);
5972 spdk_blob_sync_md(blob, blob_op_complete, NULL);
5976 /* Check if previously created blob is read only clone */
5977 CU_ASSERT(spdk_blob_is_read_only(blob));
5978 CU_ASSERT(!spdk_blob_is_snapshot(blob));
5979 CU_ASSERT(spdk_blob_is_clone(blob));
5980 CU_ASSERT(spdk_blob_is_thin_provisioned(blob));
5982 /* Create clone from read only blob */
6015 spdk_blob_close(blob, blob_op_complete, NULL);
6051 /* Verify structure of loaded blob store */
6063 /* blob */
6093 /* Try to delete blob that user should not be able to remove */
6137 * blob(ro) snapshot3
6150 struct spdk_blob *blob, *snapshot1, *snapshot2, *snapshot3, *snapshot4, *clone, *clone2;
6167 /* 1. Create blob with 10 clusters */
6172 blob = ut_blob_create_and_open(bs, &opts);
6173 blobid = spdk_blob_get_id(blob);
6192 CU_ASSERT(blob->parent_id == snapshotid1);
6195 /* Check if blob is the clone of snapshot1 */
6196 CU_ASSERT(blob->parent_id == snapshotid1);
6223 /* Check if snapshot2 is the clone of snapshot1 and blob
6225 CU_ASSERT(blob->parent_id == snapshotid2);
6383 /* 11. Try to create clone from read only blob */
6385 /* Mark blob as read only */
6386 spdk_blob_set_read_only(blob);
6387 spdk_blob_sync_md(blob, blob_op_complete, NULL);
6391 /* Create clone from read only blob */
6418 spdk_blob_close(blob, blob_op_complete, NULL);
6436 /* Verify structure of loaded blob store */
6448 /* blob */
6524 * blob
6534 struct spdk_blob *blob;
6550 /* 1. Create blob with 10 clusters */
6554 blob = ut_blob_create_and_open(bs, &opts);
6555 blobid = spdk_blob_get_id(blob);
6578 /* 5. Decouple blob */
6588 /* 7. Delete blob */
6589 spdk_blob_close(blob, blob_op_complete, NULL);
6626 struct spdk_blob *blob;
6634 /* Create bs and blob */
6639 blob = g_blob;
6648 * Along with marking blob dirty, to cause blob persist. */
6649 blob->state = SPDK_BLOB_STATE_DIRTY;
6656 spdk_blob_sync_md(blob, blob_op_complete, NULL);
6674 /* Delete blob and unload bs */
6687 struct spdk_blob *blob, *snapshot;
6711 /* Create blob */
6748 blob = g_blob;
6749 SPDK_CU_ASSERT_FATAL(spdk_blob_is_thin_provisioned(blob) == true);
6766 CU_ASSERT(spdk_blob_get_num_allocated_clusters(blob) == 0);
6774 CU_ASSERT(spdk_blob_get_num_allocated_clusters(blob) == 10);
6783 spdk_blob_close(blob, blob_op_complete, NULL);
6801 struct spdk_blob *blob, *snapshot;
6825 /* Create blob */
6859 blob = g_blob;
6869 SPDK_CU_ASSERT_FATAL(spdk_blob_is_thin_provisioned(blob) == true);
6871 CU_ASSERT(spdk_blob_get_num_allocated_clusters(blob) == 0);
6890 SPDK_CU_ASSERT_FATAL(spdk_blob_is_thin_provisioned(blob) == false);
6891 CU_ASSERT(spdk_blob_get_num_allocated_clusters(blob) == 10);
6894 spdk_blob_close(blob, blob_op_complete, NULL);
6909 test_io_write(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel)
6922 spdk_blob_io_write(blob, channel, payload_ff, 0, 1, blob_op_complete, NULL);
6927 SPDK_CU_ASSERT_FATAL(blob->active.clusters[0] != 0);
6928 cluster0 = &g_dev_buffer[blob->active.clusters[0] * dev->blocklen];
6937 spdk_blob_io_write(blob, channel, payload_ff, 2, 1, blob_op_complete, NULL);
6949 spdk_blob_io_write(blob, channel, payload_ff, 4, 4, blob_op_complete, NULL);
6961 spdk_blob_io_write(blob, channel, payload_ff, 8, 4, blob_op_complete, NULL);
6973 spdk_blob_io_write(blob, channel, payload_aa, 4, 8, blob_op_complete, NULL);
6985 spdk_blob_io_write(blob, channel, payload_ff, SZ - 4, 8, blob_op_complete, NULL);
6988 SPDK_CU_ASSERT_FATAL(blob->active.clusters[1] != 0);
6989 cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen];
7004 spdk_blob_io_write(blob, channel, payload_ff, SZ + 12, 2, blob_op_complete, NULL);
7007 SPDK_CU_ASSERT_FATAL(blob->active.clusters[1] != 0);
7008 cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen];
7026 test_io_read(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel)
7043 spdk_blob_io_read(blob, channel, payload_read, 0, 1, blob_op_complete, NULL);
7055 spdk_blob_io_read(blob, channel, payload_read, 2, 4, blob_op_complete, NULL);
7070 spdk_blob_io_read(blob, channel, payload_read, 4, 8, blob_op_complete, NULL);
7082 spdk_blob_io_read(blob, channel, payload_read, SZ - 4, 8, blob_op_complete, NULL);
7094 spdk_blob_io_read(blob, channel, payload_read, SZ + 10, 4, blob_op_complete, NULL);
7107 spdk_blob_io_read(blob, channel, payload_read, SZ, SZ, blob_op_complete, NULL);
7119 spdk_blob_io_read(blob, channel, payload_read, 0, SZ * 2, blob_op_complete, NULL);
7138 test_io_unmap(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel)
7150 cluster0 = &g_dev_buffer[blob->active.clusters[0] * dev->blocklen];
7151 cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen];
7154 spdk_blob_io_unmap(blob, channel, 0, SZ * 2, blob_op_complete, NULL);
7164 test_io_zeroes(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel)
7176 cluster0 = &g_dev_buffer[blob->active.clusters[0] * dev->blocklen];
7177 cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen];
7180 spdk_blob_io_write_zeroes(blob, channel, 0, SZ * 2, blob_op_complete, NULL);
7190 test_blob_io_writev(struct spdk_blob *blob, struct spdk_io_channel *channel,
7197 spdk_blob_io_writev_ext(blob, channel, iov, iovcnt, offset, length, blob_op_complete, NULL,
7200 spdk_blob_io_writev(blob, channel, iov, iovcnt, offset, length, blob_op_complete, NULL);
7211 test_iov_write(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel,
7235 test_blob_io_writev(blob, channel, iov, 1, 0, 1, blob_op_complete, NULL,
7239 SPDK_CU_ASSERT_FATAL(blob->active.clusters[0] != 0);
7240 cluster0 = &g_dev_buffer[blob->active.clusters[0] * dev->blocklen];
7252 test_blob_io_writev(blob, channel, iov, 1, 2, 1, blob_op_complete, NULL,
7265 spdk_blob_io_writev(blob, channel, iov, 1, 4, 4, blob_op_complete, NULL);
7279 spdk_blob_io_writev(blob, channel, iov, 1, 8, 4, blob_op_complete, NULL);
7294 test_blob_io_writev(blob, channel, iov, 1, 4, 8, blob_op_complete, NULL,
7310 test_blob_io_writev(blob, channel, iov, 1, (SZ - 4), 8, blob_op_complete, NULL,
7313 SPDK_CU_ASSERT_FATAL(blob->active.clusters[1] != 0);
7314 cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen];
7334 test_blob_io_writev(blob, channel, iov, 1, SZ + 12, 2, blob_op_complete, NULL,
7337 SPDK_CU_ASSERT_FATAL(blob->active.clusters[1] != 0);
7338 cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen];
7356 test_blob_io_readv(struct spdk_blob *blob, struct spdk_io_channel *channel,
7363 spdk_blob_io_readv_ext(blob, channel, iov, iovcnt, offset, length, blob_op_complete, NULL, io_opts);
7365 spdk_blob_io_readv(blob, channel, iov, iovcnt, offset, length, blob_op_complete, NULL);
7376 test_iov_read(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel,
7404 test_blob_io_readv(blob, channel, iov, 1, 0, 1, blob_op_complete, NULL, ext_api ? &ext_opts : NULL);
7418 test_blob_io_readv(blob, channel, iov, 1, 2, 4, blob_op_complete, NULL, ext_api ? &ext_opts : NULL);
7436 test_blob_io_readv(blob, channel, iov, 2, 4, 8, blob_op_complete, NULL, ext_api ? &ext_opts : NULL);
7455 test_blob_io_readv(blob, channel, iov, 4, SZ - 4, 8, blob_op_complete, NULL,
7471 test_blob_io_readv(blob, channel, iov, 2, SZ + 10, 4, blob_op_complete, NULL,
7492 test_blob_io_readv(blob, channel, iov, 4, SZ, SZ, blob_op_complete, NULL,
7513 test_blob_io_readv(blob, channel, iov, 4, 0, SZ * 2, blob_op_complete, NULL,
7536 struct spdk_blob *blob, *snapshot, *clone;
7546 /* Try to initialize a new blob store with unsupported io_unit */
7551 /* Initialize a new blob store */
7561 /* Create thick provisioned blob */
7566 blob = ut_blob_create_and_open(bs, &opts);
7567 blobid = spdk_blob_get_id(blob);
7569 test_io_write(dev, blob, channel);
7570 test_io_read(dev, blob, channel);
7571 test_io_zeroes(dev, blob, channel);
7573 test_iov_write(dev, blob, channel, false);
7574 test_iov_read(dev, blob, channel, false);
7575 test_io_zeroes(dev, blob, channel);
7577 test_iov_write(dev, blob, channel, true);
7578 test_iov_read(dev, blob, channel, true);
7580 test_io_unmap(dev, blob, channel);
7582 spdk_blob_close(blob, blob_op_complete, NULL);
7585 blob = NULL;
7588 /* Create thin provisioned blob */
7594 blob = ut_blob_create_and_open(bs, &opts);
7595 blobid = spdk_blob_get_id(blob);
7597 test_io_write(dev, blob, channel);
7598 test_io_read(dev, blob, channel);
7599 test_io_zeroes(dev, blob, channel);
7601 test_iov_write(dev, blob, channel, false);
7602 test_iov_read(dev, blob, channel, false);
7603 test_io_zeroes(dev, blob, channel);
7605 test_iov_write(dev, blob, channel, true);
7606 test_iov_read(dev, blob, channel, true);
7634 test_io_read(dev, blob, channel);
7638 test_iov_read(dev, blob, channel, false);
7642 test_iov_read(dev, blob, channel, true);
7664 spdk_blob_close(blob, blob_op_complete, NULL);
7669 blob = NULL;
7675 /* Unload the blob store */
7698 /* Try to initialize a new blob store with unsupported io_unit */
7703 /* Initialize a new blob store */
7712 /* Unload the blob store */
7735 /* Unload the blob store */
7748 struct spdk_blob *blob = cb_arg;
7752 rc = spdk_blob_set_xattr(blob, "sync", "second", strlen("second") + 1);
7763 struct spdk_blob *blob = cb_arg;
7771 rc = spdk_blob_get_xattr_value(blob, "sync", &value, &value_len);
7786 struct spdk_blob *blob, *snapshot;
7797 blob = ut_blob_create_and_open(bs, &opts);
7798 blobid = spdk_blob_get_id(blob);
7800 /* Create snapshot and try to remove blob in the same time:
7803 CU_ASSERT(blob->locked_operation_in_progress == false);
7805 CU_ASSERT(blob->locked_operation_in_progress == true);
7807 CU_ASSERT(blob->locked_operation_in_progress == true);
7811 CU_ASSERT(blob->locked_operation_in_progress == false);
7824 /* Inflate blob and try to remove blob in the same time:
7825 * - blob should be inflated successfully
7827 CU_ASSERT(blob->locked_operation_in_progress == false);
7829 CU_ASSERT(blob->locked_operation_in_progress == true);
7831 CU_ASSERT(blob->locked_operation_in_progress == true);
7835 CU_ASSERT(blob->locked_operation_in_progress == false);
7842 CU_ASSERT(blob->locked_operation_in_progress == false);
7848 CU_ASSERT(blob->locked_operation_in_progress == false);
7852 /* Resize blob and try to remove blob in the same time:
7853 * - blob should be resized successfully
7855 CU_ASSERT(blob->locked_operation_in_progress == false);
7856 spdk_blob_resize(blob, 50, blob_op_complete, NULL);
7857 CU_ASSERT(blob->locked_operation_in_progress == true);
7859 CU_ASSERT(blob->locked_operation_in_progress == true);
7863 CU_ASSERT(blob->locked_operation_in_progress == false);
7865 spdk_blob_sync_md(blob, blob_op_complete, NULL);
7869 /* Issue two consecutive blob syncs, neither should fail.
7870 * Force sync to actually occur by marking blob dirty each time.
7875 rc = spdk_blob_set_xattr(blob, "sync", "first", strlen("first") + 1);
7877 spdk_blob_sync_md(blob, first_sync_complete, blob);
7880 spdk_blob_sync_md(blob, second_sync_complete, blob);
7890 ut_blob_close_and_delete(bs, blob);
7898 struct spdk_blob *blob;
7914 blob = ut_blob_create_and_open(bs, &opts);
7915 blobid = spdk_blob_get_id(blob);
7917 /* Save the amount of md pages used after creation of a blob.
7920 SPDK_CU_ASSERT_FATAL(blob->active.num_pages + blob->active.num_extent_pages == page_count_clear);
7921 SPDK_CU_ASSERT_FATAL(blob->clean.num_pages + blob->clean.num_extent_pages == page_count_clear);
7929 rc = spdk_blob_set_xattr(blob, "large_xattr", xattr, xattr_length);
7931 spdk_blob_sync_md(blob, blob_op_complete, NULL);
7937 SPDK_CU_ASSERT_FATAL(blob->active.num_pages + blob->active.num_extent_pages == page_count_xattr);
7938 SPDK_CU_ASSERT_FATAL(blob->clean.num_pages + blob->clean.num_extent_pages == page_count_xattr);
7940 /* Add xattr to a blob and sync it. While sync is occurring, remove the xattr and sync again.
7946 rc = spdk_blob_set_xattr(blob, "large_xattr", xattr, xattr_length);
7949 spdk_blob_sync_md(blob, blob_op_complete, NULL);
7953 * Verify that blob takes up enough of md_pages to store the xattr. */
7954 SPDK_CU_ASSERT_FATAL(blob->active.num_pages + blob->active.num_extent_pages == page_count_xattr);
7955 SPDK_CU_ASSERT_FATAL(blob->clean.num_pages + blob->clean.num_extent_pages == page_count_xattr);
7959 rc = spdk_blob_remove_xattr(blob, "large_xattr");
7961 spdk_blob_sync_md(blob, blob_op_complete, NULL);
7964 SPDK_CU_ASSERT_FATAL(blob->active.num_pages + blob->active.num_extent_pages == page_count_clear);
7965 SPDK_CU_ASSERT_FATAL(blob->clean.num_pages + blob->clean.num_extent_pages == page_count_clear);
7968 /* Reload bs and re-open blob to verify that xattr was not persisted. */
7969 spdk_blob_close(blob, blob_op_complete, NULL);
7979 blob = g_blob;
7981 rc = spdk_blob_get_xattr_value(blob, "large_xattr", (const void **)&xattr, &xattr_length);
7992 ut_blob_close_and_delete(bs, blob);
8003 struct spdk_blob *blob, *snapshot1, *snapshot2;
8016 blob = ut_blob_create_and_open(bs, &opts);
8017 blobid = spdk_blob_get_id(blob);
8068 ut_blob_close_and_delete(bs, blob);
8070 ut_blob_close_and_delete(bs, blob);
8082 struct spdk_blob *blob;
8095 /* Set blob as thin provisioned */
8099 /* Create a blob */
8100 blob = ut_blob_create_and_open(bs, &opts);
8103 io_units_per_cluster = bs_io_units_per_cluster(blob);
8105 /* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */
8106 spdk_blob_resize(blob, 5, blob_op_complete, NULL);
8110 CU_ASSERT(blob->active.num_clusters == 5);
8114 spdk_blob_io_write(blob, channel, payload, offset, 1, blob_op_complete, NULL);
8118 io_unit = spdk_blob_get_next_allocated_io_unit(blob, 0);
8121 io_unit = spdk_blob_get_next_unallocated_io_unit(blob, 0);
8126 spdk_blob_io_write(blob, channel, payload, offset, 1, blob_op_complete, NULL);
8130 io_unit = spdk_blob_get_next_allocated_io_unit(blob, io_units_per_cluster);
8133 io_unit = spdk_blob_get_next_unallocated_io_unit(blob, 2 * io_units_per_cluster);
8138 spdk_blob_io_write(blob, channel, payload, offset, 1, blob_op_complete, NULL);
8142 io_unit = spdk_blob_get_next_allocated_io_unit(blob, 3 * io_units_per_cluster);
8145 io_unit = spdk_blob_get_next_unallocated_io_unit(blob, 4 * io_units_per_cluster);
8151 ut_blob_close_and_delete(bs, blob);
8162 struct spdk_blob *blob;
8174 /* Create a normal blob and verify it is not an esnap clone. */
8176 blob = ut_blob_create_and_open(bs, &opts);
8177 CU_ASSERT(!spdk_blob_is_esnap_clone(blob));
8178 ut_blob_close_and_delete(bs, blob);
8180 /* Create an esnap clone blob then verify it is an esnap clone and has the right size */
8186 blob = ut_blob_create_and_open(bs, &opts);
8187 SPDK_CU_ASSERT_FATAL(blob != NULL);
8188 SPDK_CU_ASSERT_FATAL(spdk_blob_is_esnap_clone(blob));
8189 SPDK_CU_ASSERT_FATAL(blob_is_esnap_clone(blob));
8190 SPDK_CU_ASSERT_FATAL(!spdk_blob_is_clone(blob));
8191 sz = spdk_blob_get_num_clusters(blob);
8193 ut_blob_close_and_delete(bs, blob);
8200 blob = ut_blob_create_and_open(bs, &opts);
8201 SPDK_CU_ASSERT_FATAL(spdk_blob_is_esnap_clone(blob));
8202 sz = spdk_blob_get_num_clusters(blob);
8204 spdk_blob_resize(blob, 1, blob_op_complete, NULL);
8207 sz = spdk_blob_get_num_clusters(blob);
8209 spdk_blob_resize(blob, esnap_num_clusters, blob_op_complete, NULL);
8212 sz = spdk_blob_get_num_clusters(blob);
8214 spdk_blob_resize(blob, esnap_num_clusters + 1, blob_op_complete, NULL);
8217 sz = spdk_blob_get_num_clusters(blob);
8220 /* Reload the blobstore and be sure that the blob can be opened. */
8221 blobid = spdk_blob_get_id(blob);
8222 spdk_blob_close(blob, blob_op_complete, NULL);
8233 blob = g_blob;
8234 SPDK_CU_ASSERT_FATAL(spdk_blob_is_esnap_clone(blob));
8235 sz = spdk_blob_get_num_clusters(blob);
8238 /* Reload the blobstore without esnap_bs_dev_create: should fail to open blob. */
8239 spdk_blob_close(blob, blob_op_complete, NULL);
8262 /* Opening the blob also triggers the esnap to be loaded */
8264 blob = g_blob;
8265 SPDK_CU_ASSERT_FATAL(spdk_blob_is_esnap_clone(blob));
8266 sz = spdk_blob_get_num_clusters(blob);
8268 spdk_blob_close(blob, blob_op_complete, NULL);
8278 blob = g_blob;
8281 spdk_blob_close(blob, blob_op_complete, NULL);
8305 /* Create and open an esnap clone blob */
8418 blob_esnap_verify_contents(struct spdk_blob *blob, struct spdk_io_channel *ch,
8421 const uint32_t bs_blksz = blob->bs->io_unit_size;
8422 const uint32_t esnap_blksz = blob->back_bs_dev ? blob->back_bs_dev->blocklen : bs_blksz;
8440 spdk_blob_io_read(blob, ch, buf, blob_block, blocks_per_read,
8443 spdk_blob_io_readv(blob, ch, &iov, 1, blob_block, blocks_per_read,
8450 spdk_blob_io_readv_ext(blob, ch, &iov, 1, blob_block, blocks_per_read,
8460 block_ok = ut_esnap_content_is_correct(buf, blocks_per_read * bs_blksz, blob->id,
8479 struct spdk_blob *blob;
8497 /* Initialize a new blob store */
8514 blob = ut_blob_create_and_open(bs, &opts);
8515 SPDK_CU_ASSERT_FATAL(blob != NULL);
8518 CU_ASSERT(blob_esnap_verify_contents(blob, bs_ch, 0, esnap_sz, esnap_sz, "read"));
8519 CU_ASSERT(blob_esnap_verify_contents(blob, bs_ch, 0, esnap_sz, esnap_sz, "readv"));
8520 CU_ASSERT(blob_esnap_verify_contents(blob, bs_ch, 0, esnap_sz, esnap_sz, "readv_ext"));
8522 CU_ASSERT(blob_esnap_verify_contents(blob, bs_ch, 0, esnap_sz, bs_blksz, "read"));
8523 CU_ASSERT(blob_esnap_verify_contents(blob, bs_ch, 0, esnap_sz, bs_blksz, "readv"));
8524 CU_ASSERT(blob_esnap_verify_contents(blob, bs_ch, 0, esnap_sz, bs_blksz, "readv_ext"));
8526 /* Write one blob block at a time; verify that the surrounding blocks are OK */
8535 spdk_blob_io_write(blob, bs_ch, buf, block, 1, bs_op_complete, NULL);
8544 spdk_blob_io_read(blob, bs_ch, buf, block - 1, 1, bs_op_complete, NULL);
8555 spdk_blob_io_read(blob, bs_ch, buf, block, 1, bs_op_complete, NULL);
8567 spdk_blob_io_read(blob, bs_ch, buf, block + 1, 1, bs_op_complete, NULL);
8573 CU_ASSERT(ut_esnap_content_is_correct(buf, bs_blksz, blob->id,
8582 spdk_blob_close(blob, blob_op_complete, NULL);
8629 /* Initialize a new blob store */
8670 struct spdk_blob *blob;
8695 /* Open the blob. No channels should be allocated yet. */
8700 blob = g_blob;
8701 ut_dev = (struct ut_esnap_dev *)blob->back_bs_dev;
8711 spdk_blob_io_read(blob, ch0, buf, 0, 1, bs_op_complete, NULL);
8726 spdk_blob_io_read(blob, ch1, buf, 0, 4, bs_op_complete, NULL);
8740 /* Close the blob. There is no outstanding IO so it should close right away. */
8742 spdk_blob_close(blob, blob_op_complete, NULL);
8747 /* The esnap channel for the blob should be gone now too. */
8779 struct spdk_blob *blob;
8794 blob = ut_blob_create_and_open(bs, &opts);
8799 CU_ASSERT(blob->frozen_refcnt == 0);
8800 blob_freeze_io(blob, freeze_done, &freeze_cnt);
8801 CU_ASSERT(blob->frozen_refcnt == 1);
8805 blob_unfreeze_io(blob, unfreeze_done, &unfreeze_cnt);
8806 CU_ASSERT(blob->frozen_refcnt == 0);
8818 CU_ASSERT(blob->frozen_refcnt == 0);
8819 blob_freeze_io(blob, freeze_done, &freeze_cnt);
8820 CU_ASSERT(blob->frozen_refcnt == 1);
8822 blob_freeze_io(blob, freeze_done, &freeze_cnt);
8823 CU_ASSERT(blob->frozen_refcnt == 2);
8827 blob_unfreeze_io(blob, unfreeze_done, &unfreeze_cnt);
8828 CU_ASSERT(blob->frozen_refcnt == 1);
8830 blob_unfreeze_io(blob, unfreeze_done, &unfreeze_cnt);
8831 CU_ASSERT(blob->frozen_refcnt == 0);
8841 ut_blob_close_and_delete(bs, blob);
8853 struct spdk_blob *blob;
8863 * Make sure we can create a blob that uses all of the free clusters.
8868 /* Initialize a new blob store */
8880 blob = ut_blob_create_and_open(bs, &opts);
8881 spdk_blob_close(blob, blob_op_complete, NULL);
8894 * When a snapshot is created, the blob that is being snapped becomes
8896 * snapshot sits between the snapped blob and the external snapshot.
8901 * | blob | | vbdev |
8910 * | blob | | blob | | vbdev |
8922 * | blob | | vbdev |
8928 * In each case, the blob pointed to by the nvme vbdev is considered
8932 * - blob->invalid_flags must contain SPDK_BLOB_EXTERNAL_SNAPSHOT
8933 * - blob->parent_id must be SPDK_BLOBID_EXTERNAL_SNAPSHOT.
8935 * No other blob that descends from the esnap clone may have any of
8942 struct spdk_blob *blob, *snap_blob;
8958 /* Open the blob. */
8963 blob = g_blob;
8964 UT_ASSERT_IS_ESNAP_CLONE(blob, &esnap_opts, sizeof(esnap_opts));
8967 * Create a snapshot of the blob. The snapshot becomes the esnap clone.
8981 UT_ASSERT_IS_NOT_ESNAP_CLONE(blob);
8985 * Delete the snapshot. The original blob becomes the esnap clone.
8990 UT_ASSERT_IS_ESNAP_CLONE(blob, &esnap_opts, sizeof(esnap_opts));
8993 * Create the snapshot again, then delete the original blob. The
9008 UT_ASSERT_IS_NOT_ESNAP_CLONE(blob);
9011 ut_blob_close_and_delete(bs, blob);
9012 blob = NULL;
9029 blob = g_blob;
9031 UT_ASSERT_IS_NOT_ESNAP_CLONE(blob);
9040 UT_ASSERT_IS_ESNAP_CLONE(blob, &esnap_opts, sizeof(esnap_opts));
9045 ut_blob_close_and_delete(bs, blob);
9054 struct spdk_blob *blob;
9085 blob = g_blob;
9086 UT_ASSERT_IS_ESNAP_CLONE(blob, &esnap_opts, sizeof(esnap_opts));
9089 * Inflate or decouple the blob then verify that it is no longer an esnap clone and has
9099 UT_ASSERT_IS_NOT_ESNAP_CLONE(blob);
9100 CU_ASSERT(blob_esnap_verify_contents(blob, channel, 0, esnap_sz, esnap_sz, "read"));
9101 ut_blob_close_and_delete(bs, blob);
9131 struct spdk_blob *blob;
9143 /* Create and open an esnap clone blob */
9149 blob = ut_blob_create_and_open(bs, &opts);
9150 CU_ASSERT(blob != NULL);
9151 CU_ASSERT(spdk_blob_is_esnap_clone(blob));
9152 SPDK_CU_ASSERT_FATAL(blob->back_bs_dev != NULL);
9153 esnap_dev = (struct ut_esnap_dev *)blob->back_bs_dev;
9162 spdk_blob_set_esnap_bs_dev(blob, bs_dev, bs_op_complete, NULL);
9167 SPDK_CU_ASSERT_FATAL(bs_dev == blob->back_bs_dev);
9168 SPDK_CU_ASSERT_FATAL(bs_dev == spdk_blob_get_esnap_bs_dev(blob));
9169 esnap_dev = (struct ut_esnap_dev *)blob->back_bs_dev;
9176 spdk_blob_io_read(blob, ch0, buf, 0, 1, bs_op_complete, NULL);
9180 spdk_blob_io_read(blob, ch1, buf, 0, 1, bs_op_complete, NULL);
9190 spdk_blob_set_esnap_bs_dev(blob, bs_dev, bs_op_complete, NULL);
9195 SPDK_CU_ASSERT_FATAL(blob->back_bs_dev != NULL);
9196 esnap_dev = (struct ut_esnap_dev *)blob->back_bs_dev;
9206 spdk_blob_close(blob, bs_op_complete, NULL);
9281 /* Resize a blob which is a clone created from snapshot. Verify read/writes to
9282 * expanded clone blob. Then inflate the clone blob. */
9288 struct spdk_blob *blob, *clone, *snap_blob, *snap_blob_rsz;
9301 /* Create blob with 10 clusters */
9305 blob = ut_blob_create_and_open(bs, &opts);
9306 blobid = spdk_blob_get_id(blob);
9307 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10);
9361 SPDK_CU_ASSERT_FATAL(blob->back_bs_dev != NULL);
9393 /* Now do full blob inflation of the resized blob/clone. */
9399 * blob should get allocated after inflation */
9414 ut_blob_close_and_delete(bs, blob);
9428 struct spdk_blob *blob;
9444 /* Initialize a new blob store */
9461 blob = ut_blob_create_and_open(bs, &opts);
9462 SPDK_CU_ASSERT_FATAL(blob != NULL);
9465 spdk_blob_resize(blob, esnap_num_clusters * 2, blob_op_complete, NULL);
9468 CU_ASSERT(spdk_blob_get_num_clusters(blob) == esnap_num_clusters * 2);
9470 /* Write one blob block at a time; verify that the surrounding blocks are OK */
9471 blob_num_blocks = (spdk_blob_get_num_clusters(blob) * cluster_sz) / bs_blksz;
9478 spdk_blob_io_write(blob, bs_ch, buf, block, 1, bs_op_complete, NULL);
9486 spdk_blob_io_read(blob, bs_ch, buf, block - 1, 1, bs_op_complete, NULL);
9496 spdk_blob_io_read(blob, bs_ch, buf, block, 1, bs_op_complete, NULL);
9507 spdk_blob_io_read(blob, bs_ch, buf, block + 1, 1, bs_op_complete, NULL);
9513 CU_ASSERT(ut_esnap_content_is_correct(buf, bs_blksz, blob->id,
9521 spdk_blob_close(blob, blob_op_complete, NULL);
9542 struct spdk_blob *blob;
9557 /* Set blob dimension and as thin provisioned */
9562 /* Create a blob */
9563 blob = ut_blob_create_and_open(bs, &blob_opts);
9564 SPDK_CU_ASSERT_FATAL(blob != NULL);
9565 blobid = spdk_blob_get_id(blob);
9566 io_units_per_cluster = bs_io_units_per_cluster(blob);
9568 /* Write on cluster 2 and 4 of blob */
9571 spdk_blob_io_write(blob, blob_ch, buf1, offset, 1, blob_op_complete, NULL);
9577 spdk_blob_io_write(blob, blob_ch, buf1, offset, 1, blob_op_complete, NULL);
9581 CU_ASSERT(spdk_blob_get_num_allocated_clusters(blob) == 2);
9583 /* Make a snapshot over blob */
9587 CU_ASSERT(spdk_blob_get_num_allocated_clusters(blob) == 0);
9589 /* Write on cluster 1 and 3 of blob */
9592 spdk_blob_io_write(blob, blob_ch, buf1, offset, 1, blob_op_complete, NULL);
9598 spdk_blob_io_write(blob, blob_ch, buf1, offset, 1, blob_op_complete, NULL);
9602 CU_ASSERT(spdk_blob_get_num_allocated_clusters(blob) == 2);
9604 /* Shallow copy with a not read only blob */
9614 /* Set blob read only */
9615 spdk_blob_set_read_only(blob);
9616 spdk_blob_sync_md(blob, blob_op_complete, NULL);
9652 /* Correct shallow copy of blob over bdev */
9699 ut_blob_close_and_delete(bs, blob);
9722 /* Create a normal blob and make a couple of snapshots */
9748 /* Call set_parent with a blob and its parent snapshot */
9753 /* Create an esnap clone blob */
9769 /* Call set_parent with blob and snapshot of different size */
9774 /* Call set_parent correctly with a snapshot's clone blob */
9786 /* Create another normal blob with size equal to esnap size and make a snapshot */
9799 /* Call set_parent correctly with an esnap's clone blob */
9812 /* Create a not thin-provisioned blob that is not a clone */
9819 /* Call set_parent with a blob that isn't a clone and that isn't thin-provisioned */
9824 /* Create a thin-provisioned blob that is not a clone */
9831 /* Call set_parent correctly with a blob that isn't a clone */
9883 /* Create an esnap clone blob */
9905 /* Call set_external_parent with a blob and its parent esnap */
9913 /* Create a blob that is a clone of a snapshots */
9924 /* Call set_parent correctly with a snapshot's clone blob */
9941 /* Create a not thin-provisioned blob that is not a clone */
9948 /* Call set_external_parent with a blob that isn't a clone and that isn't thin-provisioned */
9954 /* Create a thin-provisioned blob that is not a clone */
9961 /* Call set_external_parent correctly with a blob that isn't a clone */
10033 struct spdk_blob *blob;
10053 blob = g_blob;
10058 return blob;
10062 ut_blob_close_and_delete(struct spdk_blob_store *bs, struct spdk_blob *blob)
10064 spdk_blob_id blobid = spdk_blob_get_id(blob);
10066 spdk_blob_close(blob, blob_op_complete, NULL);