xref: /spdk/test/unit/lib/blob/blob.c/blob_ut.c (revision 12d1404125561b467696ddeccea59a1cb408597a)
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright (c) Intel Corporation.
5  *   All rights reserved.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 #include "spdk/stdinc.h"
35 
36 #include "spdk_cunit.h"
37 #include "spdk/blob.h"
38 #include "spdk/string.h"
39 #include "spdk_internal/thread.h"
40 
41 #include "common/lib/ut_multithread.c"
42 #include "../bs_dev_common.c"
43 #include "blob/blobstore.c"
44 #include "blob/request.c"
45 #include "blob/zeroes.c"
46 #include "blob/blob_bs_dev.c"
47 
48 struct spdk_blob_store *g_bs;
49 spdk_blob_id g_blobid;
50 struct spdk_blob *g_blob;
51 int g_bserrno;
52 struct spdk_xattr_names *g_names;
53 int g_done;
54 char *g_xattr_names[] = {"first", "second", "third"};
55 char *g_xattr_values[] = {"one", "two", "three"};
56 uint64_t g_ctx = 1729;
57 bool g_use_extent_table = false;
58 
59 struct spdk_bs_super_block_ver1 {
60 	uint8_t		signature[8];
61 	uint32_t        version;
62 	uint32_t        length;
63 	uint32_t	clean; /* If there was a clean shutdown, this is 1. */
64 	spdk_blob_id	super_blob;
65 
66 	uint32_t	cluster_size; /* In bytes */
67 
68 	uint32_t	used_page_mask_start; /* Offset from beginning of disk, in pages */
69 	uint32_t	used_page_mask_len; /* Count, in pages */
70 
71 	uint32_t	used_cluster_mask_start; /* Offset from beginning of disk, in pages */
72 	uint32_t	used_cluster_mask_len; /* Count, in pages */
73 
74 	uint32_t	md_start; /* Offset from beginning of disk, in pages */
75 	uint32_t	md_len; /* Count, in pages */
76 
77 	uint8_t		reserved[4036];
78 	uint32_t	crc;
79 } __attribute__((packed));
80 SPDK_STATIC_ASSERT(sizeof(struct spdk_bs_super_block_ver1) == 0x1000, "Invalid super block size");
81 
82 static void
83 _get_xattr_value(void *arg, const char *name,
84 		 const void **value, size_t *value_len)
85 {
86 	uint64_t i;
87 
88 	SPDK_CU_ASSERT_FATAL(value_len != NULL);
89 	SPDK_CU_ASSERT_FATAL(value != NULL);
90 	CU_ASSERT(arg == &g_ctx);
91 
92 	for (i = 0; i < sizeof(g_xattr_names); i++) {
93 		if (!strcmp(name, g_xattr_names[i])) {
94 			*value_len = strlen(g_xattr_values[i]);
95 			*value = g_xattr_values[i];
96 			break;
97 		}
98 	}
99 }
100 
101 static void
102 _get_xattr_value_null(void *arg, const char *name,
103 		      const void **value, size_t *value_len)
104 {
105 	SPDK_CU_ASSERT_FATAL(value_len != NULL);
106 	SPDK_CU_ASSERT_FATAL(value != NULL);
107 	CU_ASSERT(arg == NULL);
108 
109 	*value_len = 0;
110 	*value = NULL;
111 }
112 
113 static int
114 _get_snapshots_count(struct spdk_blob_store *bs)
115 {
116 	struct spdk_blob_list *snapshot = NULL;
117 	int count = 0;
118 
119 	TAILQ_FOREACH(snapshot, &bs->snapshots, link) {
120 		count += 1;
121 	}
122 
123 	return count;
124 }
125 
126 static void
127 ut_spdk_blob_opts_init(struct spdk_blob_opts *opts)
128 {
129 	spdk_blob_opts_init(opts);
130 	opts->use_extent_table = g_use_extent_table;
131 }
132 
133 static void
134 bs_op_complete(void *cb_arg, int bserrno)
135 {
136 	g_bserrno = bserrno;
137 }
138 
139 static void
140 bs_op_with_handle_complete(void *cb_arg, struct spdk_blob_store *bs,
141 			   int bserrno)
142 {
143 	g_bs = bs;
144 	g_bserrno = bserrno;
145 }
146 
147 static void
148 blob_op_complete(void *cb_arg, int bserrno)
149 {
150 	g_bserrno = bserrno;
151 }
152 
153 static void
154 blob_op_with_id_complete(void *cb_arg, spdk_blob_id blobid, int bserrno)
155 {
156 	g_blobid = blobid;
157 	g_bserrno = bserrno;
158 }
159 
160 static void
161 blob_op_with_handle_complete(void *cb_arg, struct spdk_blob *blb, int bserrno)
162 {
163 	g_blob = blb;
164 	g_bserrno = bserrno;
165 }
166 
167 static void
168 blob_init(void)
169 {
170 	struct spdk_bs_dev *dev;
171 
172 	dev = init_dev();
173 
174 	/* should fail for an unsupported blocklen */
175 	dev->blocklen = 500;
176 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
177 	poll_threads();
178 	CU_ASSERT(g_bserrno == -EINVAL);
179 
180 	dev = init_dev();
181 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
182 	poll_threads();
183 	CU_ASSERT(g_bserrno == 0);
184 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
185 
186 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
187 	poll_threads();
188 	CU_ASSERT(g_bserrno == 0);
189 	g_bs = NULL;
190 }
191 
192 static void
193 blob_super(void)
194 {
195 	struct spdk_blob_store *bs;
196 	struct spdk_bs_dev *dev;
197 	spdk_blob_id blobid;
198 	struct spdk_blob_opts blob_opts;
199 
200 	dev = init_dev();
201 
202 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
203 	poll_threads();
204 	CU_ASSERT(g_bserrno == 0);
205 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
206 	bs = g_bs;
207 
208 	/* Get the super blob without having set one */
209 	spdk_bs_get_super(bs, blob_op_with_id_complete, NULL);
210 	poll_threads();
211 	CU_ASSERT(g_bserrno == -ENOENT);
212 	CU_ASSERT(g_blobid == SPDK_BLOBID_INVALID);
213 
214 	/* Create a blob */
215 	ut_spdk_blob_opts_init(&blob_opts);
216 	spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL);
217 	poll_threads();
218 	CU_ASSERT(g_bserrno == 0);
219 	CU_ASSERT(g_blobid !=  SPDK_BLOBID_INVALID);
220 	blobid = g_blobid;
221 
222 	/* Set the blob as the super blob */
223 	spdk_bs_set_super(bs, blobid, blob_op_complete, NULL);
224 	poll_threads();
225 	CU_ASSERT(g_bserrno == 0);
226 
227 	/* Get the super blob */
228 	spdk_bs_get_super(bs, blob_op_with_id_complete, NULL);
229 	poll_threads();
230 	CU_ASSERT(g_bserrno == 0);
231 	CU_ASSERT(blobid == g_blobid);
232 
233 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
234 	poll_threads();
235 	CU_ASSERT(g_bserrno == 0);
236 	g_bs = NULL;
237 }
238 
239 static void
240 blob_open(void)
241 {
242 	struct spdk_blob_store *bs;
243 	struct spdk_bs_dev *dev;
244 	struct spdk_blob *blob;
245 	struct spdk_blob_opts blob_opts;
246 	spdk_blob_id blobid, blobid2;
247 
248 	dev = init_dev();
249 
250 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
251 	poll_threads();
252 	CU_ASSERT(g_bserrno == 0);
253 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
254 	bs = g_bs;
255 
256 	ut_spdk_blob_opts_init(&blob_opts);
257 	spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL);
258 	poll_threads();
259 	CU_ASSERT(g_bserrno == 0);
260 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
261 	blobid = g_blobid;
262 
263 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
264 	poll_threads();
265 	CU_ASSERT(g_bserrno == 0);
266 	CU_ASSERT(g_blob != NULL);
267 	blob = g_blob;
268 
269 	blobid2 = spdk_blob_get_id(blob);
270 	CU_ASSERT(blobid == blobid2);
271 
272 	/* Try to open file again.  It should return success. */
273 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
274 	poll_threads();
275 	CU_ASSERT(g_bserrno == 0);
276 	CU_ASSERT(blob == g_blob);
277 
278 	spdk_blob_close(blob, blob_op_complete, NULL);
279 	poll_threads();
280 	CU_ASSERT(g_bserrno == 0);
281 
282 	/*
283 	 * Close the file a second time, releasing the second reference.  This
284 	 *  should succeed.
285 	 */
286 	blob = g_blob;
287 	spdk_blob_close(blob, blob_op_complete, NULL);
288 	poll_threads();
289 	CU_ASSERT(g_bserrno == 0);
290 
291 	/*
292 	 * Try to open file again.  It should succeed.  This tests the case
293 	 *  where the file is opened, closed, then re-opened again.
294 	 */
295 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
296 	poll_threads();
297 	CU_ASSERT(g_bserrno == 0);
298 	CU_ASSERT(g_blob != NULL);
299 	blob = g_blob;
300 
301 	spdk_blob_close(blob, blob_op_complete, NULL);
302 	poll_threads();
303 	CU_ASSERT(g_bserrno == 0);
304 
305 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
306 	poll_threads();
307 	CU_ASSERT(g_bserrno == 0);
308 	g_bs = NULL;
309 }
310 
311 static void
312 blob_create(void)
313 {
314 	struct spdk_blob_store *bs;
315 	struct spdk_bs_dev *dev;
316 	struct spdk_blob *blob;
317 	struct spdk_blob_opts opts;
318 	spdk_blob_id blobid;
319 
320 	dev = init_dev();
321 
322 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
323 	poll_threads();
324 	CU_ASSERT(g_bserrno == 0);
325 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
326 	bs = g_bs;
327 
328 	/* Create blob with 10 clusters */
329 
330 	ut_spdk_blob_opts_init(&opts);
331 	opts.num_clusters = 10;
332 
333 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
334 	poll_threads();
335 	CU_ASSERT(g_bserrno == 0);
336 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
337 	blobid = g_blobid;
338 
339 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
340 	poll_threads();
341 	CU_ASSERT(g_bserrno == 0);
342 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
343 	blob = g_blob;
344 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10);
345 
346 	spdk_blob_close(blob, blob_op_complete, NULL);
347 	poll_threads();
348 	CU_ASSERT(g_bserrno == 0);
349 
350 	/* Create blob with 0 clusters */
351 
352 	ut_spdk_blob_opts_init(&opts);
353 	opts.num_clusters = 0;
354 
355 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
356 	poll_threads();
357 	CU_ASSERT(g_bserrno == 0);
358 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
359 	blobid = g_blobid;
360 
361 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
362 	poll_threads();
363 	CU_ASSERT(g_bserrno == 0);
364 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
365 	blob = g_blob;
366 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0);
367 
368 	spdk_blob_close(blob, blob_op_complete, NULL);
369 	poll_threads();
370 	CU_ASSERT(g_bserrno == 0);
371 
372 	/* Create blob with default options (opts == NULL) */
373 
374 	spdk_bs_create_blob_ext(bs, NULL, blob_op_with_id_complete, NULL);
375 	poll_threads();
376 	CU_ASSERT(g_bserrno == 0);
377 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
378 	blobid = g_blobid;
379 
380 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
381 	poll_threads();
382 	CU_ASSERT(g_bserrno == 0);
383 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
384 	blob = g_blob;
385 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0);
386 
387 	spdk_blob_close(blob, blob_op_complete, NULL);
388 	poll_threads();
389 	CU_ASSERT(g_bserrno == 0);
390 
391 	/* Try to create blob with size larger than blobstore */
392 
393 	ut_spdk_blob_opts_init(&opts);
394 	opts.num_clusters = bs->total_clusters + 1;
395 
396 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
397 	poll_threads();
398 	CU_ASSERT(g_bserrno == -ENOSPC);
399 
400 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
401 	poll_threads();
402 	CU_ASSERT(g_bserrno == 0);
403 	g_bs = NULL;
404 
405 }
406 
407 static void
408 blob_create_internal(void)
409 {
410 	struct spdk_blob_store *bs;
411 	struct spdk_bs_dev *dev;
412 	struct spdk_blob *blob;
413 	struct spdk_blob_opts opts;
414 	struct spdk_blob_xattr_opts internal_xattrs;
415 	const void *value;
416 	size_t value_len;
417 	spdk_blob_id blobid;
418 	int rc;
419 
420 	dev = init_dev();
421 
422 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
423 	poll_threads();
424 	CU_ASSERT(g_bserrno == 0);
425 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
426 	bs = g_bs;
427 
428 	/* Create blob with custom xattrs */
429 
430 	ut_spdk_blob_opts_init(&opts);
431 	_spdk_blob_xattrs_init(&internal_xattrs);
432 	internal_xattrs.count = 3;
433 	internal_xattrs.names = g_xattr_names;
434 	internal_xattrs.get_value = _get_xattr_value;
435 	internal_xattrs.ctx = &g_ctx;
436 
437 	_spdk_bs_create_blob(bs, &opts, &internal_xattrs, blob_op_with_id_complete, NULL);
438 	poll_threads();
439 	CU_ASSERT(g_bserrno == 0);
440 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
441 	blobid = g_blobid;
442 
443 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
444 	poll_threads();
445 	CU_ASSERT(g_bserrno == 0);
446 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
447 	blob = g_blob;
448 
449 	rc = _spdk_blob_get_xattr_value(blob, g_xattr_names[0], &value, &value_len, true);
450 	CU_ASSERT(rc == 0);
451 	SPDK_CU_ASSERT_FATAL(value != NULL);
452 	CU_ASSERT(value_len == strlen(g_xattr_values[0]));
453 	CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len);
454 
455 	rc = _spdk_blob_get_xattr_value(blob, g_xattr_names[1], &value, &value_len, true);
456 	CU_ASSERT(rc == 0);
457 	SPDK_CU_ASSERT_FATAL(value != NULL);
458 	CU_ASSERT(value_len == strlen(g_xattr_values[1]));
459 	CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len);
460 
461 	rc = _spdk_blob_get_xattr_value(blob, g_xattr_names[2], &value, &value_len, true);
462 	CU_ASSERT(rc == 0);
463 	SPDK_CU_ASSERT_FATAL(value != NULL);
464 	CU_ASSERT(value_len == strlen(g_xattr_values[2]));
465 	CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len);
466 
467 	rc = spdk_blob_get_xattr_value(blob, g_xattr_names[0], &value, &value_len);
468 	CU_ASSERT(rc != 0);
469 
470 	rc = spdk_blob_get_xattr_value(blob, g_xattr_names[1], &value, &value_len);
471 	CU_ASSERT(rc != 0);
472 
473 	rc = spdk_blob_get_xattr_value(blob, g_xattr_names[2], &value, &value_len);
474 	CU_ASSERT(rc != 0);
475 
476 	spdk_blob_close(blob, blob_op_complete, NULL);
477 	poll_threads();
478 	CU_ASSERT(g_bserrno == 0);
479 
480 	/* Create blob with NULL internal options  */
481 
482 	_spdk_bs_create_blob(bs, NULL, NULL, blob_op_with_id_complete, NULL);
483 	poll_threads();
484 	CU_ASSERT(g_bserrno == 0);
485 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
486 	blobid = g_blobid;
487 
488 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
489 	poll_threads();
490 	CU_ASSERT(g_bserrno == 0);
491 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
492 	CU_ASSERT(TAILQ_FIRST(&g_blob->xattrs_internal) == NULL);
493 
494 	blob = g_blob;
495 
496 	spdk_blob_close(blob, blob_op_complete, NULL);
497 	poll_threads();
498 	CU_ASSERT(g_bserrno == 0);
499 
500 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
501 	poll_threads();
502 	CU_ASSERT(g_bserrno == 0);
503 	g_bs = NULL;
504 
505 }
506 
507 static void
508 blob_thin_provision(void)
509 {
510 	struct spdk_blob_store *bs;
511 	struct spdk_bs_dev *dev;
512 	struct spdk_blob *blob;
513 	struct spdk_blob_opts opts;
514 	struct spdk_bs_opts bs_opts;
515 	spdk_blob_id blobid;
516 
517 	dev = init_dev();
518 	spdk_bs_opts_init(&bs_opts);
519 	snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE");
520 
521 	/* Initialize a new blob store */
522 	spdk_bs_init(dev, &bs_opts, bs_op_with_handle_complete, NULL);
523 	poll_threads();
524 	CU_ASSERT(g_bserrno == 0);
525 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
526 
527 	bs = g_bs;
528 
529 	/* Create blob with thin provisioning enabled */
530 
531 	ut_spdk_blob_opts_init(&opts);
532 	opts.thin_provision = true;
533 	opts.num_clusters = 10;
534 
535 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
536 	poll_threads();
537 	CU_ASSERT(g_bserrno == 0);
538 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
539 	blobid = g_blobid;
540 
541 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
542 	poll_threads();
543 	CU_ASSERT(g_bserrno == 0);
544 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
545 	blob = g_blob;
546 	CU_ASSERT(blob->invalid_flags & SPDK_BLOB_THIN_PROV);
547 
548 	spdk_blob_close(blob, blob_op_complete, NULL);
549 	CU_ASSERT(g_bserrno == 0);
550 
551 	/* Do not shut down cleanly.  This makes sure that when we load again
552 	 *  and try to recover a valid used_cluster map, that blobstore will
553 	 *  ignore clusters with index 0 since these are unallocated clusters.
554 	 */
555 	_spdk_bs_free(bs);
556 
557 	/* Load an existing blob store and check if invalid_flags is set */
558 	dev = init_dev();
559 	snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE");
560 	spdk_bs_load(dev, &bs_opts, bs_op_with_handle_complete, NULL);
561 	poll_threads();
562 	CU_ASSERT(g_bserrno == 0);
563 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
564 
565 	bs = g_bs;
566 
567 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
568 	poll_threads();
569 	CU_ASSERT(g_bserrno == 0);
570 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
571 	blob = g_blob;
572 	CU_ASSERT(blob->invalid_flags & SPDK_BLOB_THIN_PROV);
573 
574 	spdk_blob_close(blob, blob_op_complete, NULL);
575 	poll_threads();
576 	CU_ASSERT(g_bserrno == 0);
577 
578 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
579 	poll_threads();
580 	CU_ASSERT(g_bserrno == 0);
581 	g_bs = NULL;
582 }
583 
584 static void
585 blob_snapshot(void)
586 {
587 	struct spdk_blob_store *bs;
588 	struct spdk_bs_dev *dev;
589 	struct spdk_blob *blob;
590 	struct spdk_blob *snapshot, *snapshot2;
591 	struct spdk_blob_bs_dev *blob_bs_dev;
592 	struct spdk_blob_opts opts;
593 	struct spdk_blob_xattr_opts xattrs;
594 	spdk_blob_id blobid;
595 	spdk_blob_id snapshotid;
596 	spdk_blob_id snapshotid2;
597 	const void *value;
598 	size_t value_len;
599 	int rc;
600 	spdk_blob_id ids[2];
601 	size_t count;
602 
603 	dev = init_dev();
604 
605 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
606 	poll_threads();
607 	CU_ASSERT(g_bserrno == 0);
608 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
609 	bs = g_bs;
610 
611 	/* Create blob with 10 clusters */
612 	ut_spdk_blob_opts_init(&opts);
613 	opts.num_clusters = 10;
614 
615 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
616 	poll_threads();
617 	CU_ASSERT(g_bserrno == 0);
618 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
619 	blobid = g_blobid;
620 
621 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
622 	poll_threads();
623 	CU_ASSERT(g_bserrno == 0);
624 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
625 	blob = g_blob;
626 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10);
627 
628 	/* Create snapshot from blob */
629 	CU_ASSERT_EQUAL(_get_snapshots_count(bs), 0);
630 	spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL);
631 	poll_threads();
632 	CU_ASSERT(g_bserrno == 0);
633 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
634 	CU_ASSERT_EQUAL(_get_snapshots_count(bs), 1);
635 	snapshotid = g_blobid;
636 
637 	spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL);
638 	poll_threads();
639 	CU_ASSERT(g_bserrno == 0);
640 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
641 	snapshot = g_blob;
642 	CU_ASSERT(snapshot->data_ro == true);
643 	CU_ASSERT(snapshot->md_ro == true);
644 	CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 10);
645 
646 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10);
647 	CU_ASSERT(blob->invalid_flags & SPDK_BLOB_THIN_PROV);
648 	CU_ASSERT(spdk_mem_all_zero(blob->active.clusters,
649 				    blob->active.num_clusters * sizeof(blob->active.clusters[0])));
650 
651 	/* Try to create snapshot from clone with xattrs */
652 	xattrs.names = g_xattr_names;
653 	xattrs.get_value = _get_xattr_value;
654 	xattrs.count = 3;
655 	xattrs.ctx = &g_ctx;
656 	spdk_bs_create_snapshot(bs, blobid, &xattrs, blob_op_with_id_complete, NULL);
657 	poll_threads();
658 	CU_ASSERT(g_bserrno == 0);
659 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
660 	CU_ASSERT_EQUAL(_get_snapshots_count(bs), 2);
661 	snapshotid2 = g_blobid;
662 
663 	spdk_bs_open_blob(bs, snapshotid2, blob_op_with_handle_complete, NULL);
664 	CU_ASSERT(g_bserrno == 0);
665 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
666 	snapshot2 = g_blob;
667 	CU_ASSERT(snapshot2->data_ro == true);
668 	CU_ASSERT(snapshot2->md_ro == true);
669 	CU_ASSERT(spdk_blob_get_num_clusters(snapshot2) == 10);
670 
671 	/* Confirm that blob is backed by snapshot2 and snapshot2 is backed by snapshot */
672 	CU_ASSERT(snapshot->back_bs_dev == NULL);
673 	SPDK_CU_ASSERT_FATAL(blob->back_bs_dev != NULL);
674 	SPDK_CU_ASSERT_FATAL(snapshot2->back_bs_dev != NULL);
675 
676 	blob_bs_dev = (struct spdk_blob_bs_dev *)blob->back_bs_dev;
677 	CU_ASSERT(blob_bs_dev->blob == snapshot2);
678 
679 	blob_bs_dev = (struct spdk_blob_bs_dev *)snapshot2->back_bs_dev;
680 	CU_ASSERT(blob_bs_dev->blob == snapshot);
681 
682 	rc = spdk_blob_get_xattr_value(snapshot2, g_xattr_names[0], &value, &value_len);
683 	CU_ASSERT(rc == 0);
684 	SPDK_CU_ASSERT_FATAL(value != NULL);
685 	CU_ASSERT(value_len == strlen(g_xattr_values[0]));
686 	CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len);
687 
688 	rc = spdk_blob_get_xattr_value(snapshot2, g_xattr_names[1], &value, &value_len);
689 	CU_ASSERT(rc == 0);
690 	SPDK_CU_ASSERT_FATAL(value != NULL);
691 	CU_ASSERT(value_len == strlen(g_xattr_values[1]));
692 	CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len);
693 
694 	rc = spdk_blob_get_xattr_value(snapshot2, g_xattr_names[2], &value, &value_len);
695 	CU_ASSERT(rc == 0);
696 	SPDK_CU_ASSERT_FATAL(value != NULL);
697 	CU_ASSERT(value_len == strlen(g_xattr_values[2]));
698 	CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len);
699 
700 	/* Confirm that blob is clone of snapshot2, and snapshot2 is clone of snapshot */
701 	count = 2;
702 	CU_ASSERT(spdk_blob_get_clones(bs, snapshotid2, ids, &count) == 0);
703 	CU_ASSERT(count == 1);
704 	CU_ASSERT(ids[0] == blobid);
705 
706 	count = 2;
707 	CU_ASSERT(spdk_blob_get_clones(bs, snapshotid, ids, &count) == 0);
708 	CU_ASSERT(count == 1);
709 	CU_ASSERT(ids[0] == snapshotid2);
710 
711 	/* Try to create snapshot from snapshot */
712 	spdk_bs_create_snapshot(bs, snapshotid, NULL, blob_op_with_id_complete, NULL);
713 	poll_threads();
714 	CU_ASSERT(g_bserrno == -EINVAL);
715 	CU_ASSERT(g_blobid == SPDK_BLOBID_INVALID);
716 	CU_ASSERT_EQUAL(_get_snapshots_count(bs), 2);
717 
718 	/* Delete blob and confirm that it is no longer on snapshot2 clone list */
719 	spdk_blob_close(blob, blob_op_complete, NULL);
720 	poll_threads();
721 	CU_ASSERT(g_bserrno == 0);
722 
723 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
724 	poll_threads();
725 	CU_ASSERT(g_bserrno == 0);
726 	count = 2;
727 	CU_ASSERT(spdk_blob_get_clones(bs, snapshotid2, ids, &count) == 0);
728 	CU_ASSERT(count == 0);
729 
730 	/* Delete snapshot2 and confirm that it is no longer on snapshot clone list */
731 	spdk_blob_close(snapshot2, blob_op_complete, NULL);
732 	poll_threads();
733 	CU_ASSERT(g_bserrno == 0);
734 
735 	spdk_bs_delete_blob(bs, snapshotid2, blob_op_complete, NULL);
736 	poll_threads();
737 	CU_ASSERT(g_bserrno == 0);
738 	CU_ASSERT_EQUAL(_get_snapshots_count(bs), 1);
739 	count = 2;
740 	CU_ASSERT(spdk_blob_get_clones(bs, snapshotid2, ids, &count) == 0);
741 	CU_ASSERT(count == 0);
742 
743 	spdk_blob_close(snapshot, blob_op_complete, NULL);
744 	poll_threads();
745 	CU_ASSERT(g_bserrno == 0);
746 
747 	spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL);
748 	poll_threads();
749 	CU_ASSERT(g_bserrno == 0);
750 	CU_ASSERT_EQUAL(_get_snapshots_count(bs), 0);
751 
752 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
753 	poll_threads();
754 	CU_ASSERT(g_bserrno == 0);
755 	g_bs = NULL;
756 }
757 
758 static void
759 blob_snapshot_freeze_io(void)
760 {
761 	struct spdk_thread *thread;
762 	struct spdk_io_channel *channel;
763 	struct spdk_bs_channel *bs_channel;
764 	struct spdk_blob_store *bs;
765 	struct spdk_bs_dev *dev;
766 	struct spdk_blob *blob;
767 	struct spdk_blob_opts opts;
768 	spdk_blob_id blobid;
769 	uint32_t num_of_pages = 10;
770 	uint8_t payload_read[num_of_pages * SPDK_BS_PAGE_SIZE];
771 	uint8_t payload_write[num_of_pages * SPDK_BS_PAGE_SIZE];
772 	uint8_t payload_zero[num_of_pages * SPDK_BS_PAGE_SIZE];
773 
774 	memset(payload_write, 0xE5, sizeof(payload_write));
775 	memset(payload_read, 0x00, sizeof(payload_read));
776 	memset(payload_zero, 0x00, sizeof(payload_zero));
777 
778 	dev = init_dev();
779 	memset(g_dev_buffer, 0, DEV_BUFFER_SIZE);
780 
781 	/* Test freeze I/O during snapshot */
782 
783 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
784 	poll_threads();
785 	CU_ASSERT(g_bserrno == 0);
786 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
787 	bs = g_bs;
788 
789 	channel = spdk_bs_alloc_io_channel(bs);
790 	bs_channel = spdk_io_channel_get_ctx(channel);
791 
792 	/* Create blob with 10 clusters */
793 	ut_spdk_blob_opts_init(&opts);
794 	opts.num_clusters = 10;
795 	opts.thin_provision = false;
796 
797 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
798 	poll_threads();
799 	CU_ASSERT(g_bserrno == 0);
800 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
801 	blobid = g_blobid;
802 
803 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
804 	poll_threads();
805 	CU_ASSERT(g_bserrno == 0);
806 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
807 	blob = g_blob;
808 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10);
809 
810 	spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL);
811 
812 	/* This is implementation specific.
813 	 * Flag 'frozen_io' is set in _spdk_bs_snapshot_freeze_cpl callback.
814 	 * Four async I/O operations happen before that. */
815 	thread = spdk_get_thread();
816 	spdk_thread_poll(thread, 1, 0);
817 	spdk_thread_poll(thread, 1, 0);
818 	spdk_thread_poll(thread, 1, 0);
819 
820 	CU_ASSERT(TAILQ_EMPTY(&bs_channel->queued_io));
821 
822 	/* Blob I/O should be frozen here */
823 	CU_ASSERT(blob->frozen_refcnt == 1);
824 
825 	/* Write to the blob */
826 	spdk_blob_io_write(blob, channel, payload_write, 0, num_of_pages, blob_op_complete, NULL);
827 
828 	/* Verify that I/O is queued */
829 	CU_ASSERT(!TAILQ_EMPTY(&bs_channel->queued_io));
830 	/* Verify that payload is not written to disk */
831 	CU_ASSERT(memcmp(payload_zero, &g_dev_buffer[blob->active.clusters[0]*SPDK_BS_PAGE_SIZE],
832 			 SPDK_BS_PAGE_SIZE) == 0);
833 
834 	/* Finish all operations including spdk_bs_create_snapshot */
835 	poll_threads();
836 
837 	/* Verify snapshot */
838 	CU_ASSERT(g_bserrno == 0);
839 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
840 
841 	/* Verify that blob has unset frozen_io */
842 	CU_ASSERT(blob->frozen_refcnt == 0);
843 
844 	/* Verify that postponed I/O completed successfully by comparing payload */
845 	spdk_blob_io_read(blob, channel, payload_read, 0, num_of_pages, blob_op_complete, NULL);
846 	poll_threads();
847 	CU_ASSERT(g_bserrno == 0);
848 	CU_ASSERT(memcmp(payload_write, payload_read, num_of_pages * SPDK_BS_PAGE_SIZE) == 0);
849 
850 	spdk_blob_close(blob, blob_op_complete, NULL);
851 	poll_threads();
852 	CU_ASSERT(g_bserrno == 0);
853 
854 	spdk_bs_free_io_channel(channel);
855 	poll_threads();
856 
857 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
858 	poll_threads();
859 	CU_ASSERT(g_bserrno == 0);
860 	g_bs = NULL;
861 }
862 
863 static void
864 blob_clone(void)
865 {
866 	struct spdk_blob_store *bs;
867 	struct spdk_bs_dev *dev;
868 	struct spdk_blob_opts opts;
869 	struct spdk_blob *blob, *snapshot, *clone;
870 	spdk_blob_id blobid, cloneid, snapshotid;
871 	struct spdk_blob_xattr_opts xattrs;
872 	const void *value;
873 	size_t value_len;
874 	int rc;
875 
876 	dev = init_dev();
877 
878 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
879 	poll_threads();
880 	CU_ASSERT(g_bserrno == 0);
881 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
882 	bs = g_bs;
883 
884 	/* Create blob with 10 clusters */
885 
886 	ut_spdk_blob_opts_init(&opts);
887 	opts.num_clusters = 10;
888 
889 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
890 	poll_threads();
891 	CU_ASSERT(g_bserrno == 0);
892 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
893 	blobid = g_blobid;
894 
895 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
896 	poll_threads();
897 	CU_ASSERT(g_bserrno == 0);
898 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
899 	blob = g_blob;
900 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10);
901 
902 	/* Create snapshot */
903 	spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL);
904 	poll_threads();
905 	CU_ASSERT(g_bserrno == 0);
906 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
907 	snapshotid = g_blobid;
908 
909 	spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL);
910 	poll_threads();
911 	CU_ASSERT(g_bserrno == 0);
912 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
913 	snapshot = g_blob;
914 	CU_ASSERT(snapshot->data_ro == true);
915 	CU_ASSERT(snapshot->md_ro == true);
916 	CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 10);
917 
918 	spdk_blob_close(snapshot, blob_op_complete, NULL);
919 	poll_threads();
920 	CU_ASSERT(g_bserrno == 0);
921 
922 	/* Create clone from snapshot with xattrs */
923 	xattrs.names = g_xattr_names;
924 	xattrs.get_value = _get_xattr_value;
925 	xattrs.count = 3;
926 	xattrs.ctx = &g_ctx;
927 
928 	spdk_bs_create_clone(bs, snapshotid, &xattrs, blob_op_with_id_complete, NULL);
929 	poll_threads();
930 	CU_ASSERT(g_bserrno == 0);
931 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
932 	cloneid = g_blobid;
933 
934 	spdk_bs_open_blob(bs, cloneid, blob_op_with_handle_complete, NULL);
935 	poll_threads();
936 	CU_ASSERT(g_bserrno == 0);
937 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
938 	clone = g_blob;
939 	CU_ASSERT(clone->data_ro == false);
940 	CU_ASSERT(clone->md_ro == false);
941 	CU_ASSERT(spdk_blob_get_num_clusters(clone) == 10);
942 
943 	rc = spdk_blob_get_xattr_value(clone, g_xattr_names[0], &value, &value_len);
944 	CU_ASSERT(rc == 0);
945 	SPDK_CU_ASSERT_FATAL(value != NULL);
946 	CU_ASSERT(value_len == strlen(g_xattr_values[0]));
947 	CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len);
948 
949 	rc = spdk_blob_get_xattr_value(clone, g_xattr_names[1], &value, &value_len);
950 	CU_ASSERT(rc == 0);
951 	SPDK_CU_ASSERT_FATAL(value != NULL);
952 	CU_ASSERT(value_len == strlen(g_xattr_values[1]));
953 	CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len);
954 
955 	rc = spdk_blob_get_xattr_value(clone, g_xattr_names[2], &value, &value_len);
956 	CU_ASSERT(rc == 0);
957 	SPDK_CU_ASSERT_FATAL(value != NULL);
958 	CU_ASSERT(value_len == strlen(g_xattr_values[2]));
959 	CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len);
960 
961 
962 	spdk_blob_close(clone, blob_op_complete, NULL);
963 	poll_threads();
964 	CU_ASSERT(g_bserrno == 0);
965 
966 	/* Try to create clone from not read only blob */
967 	spdk_bs_create_clone(bs, blobid, NULL, blob_op_with_id_complete, NULL);
968 	poll_threads();
969 	CU_ASSERT(g_bserrno == -EINVAL);
970 	CU_ASSERT(g_blobid == SPDK_BLOBID_INVALID);
971 
972 	/* Mark blob as read only */
973 	spdk_blob_set_read_only(blob);
974 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
975 	poll_threads();
976 	CU_ASSERT(g_bserrno == 0);
977 
978 	/* Create clone from read only blob */
979 	spdk_bs_create_clone(bs, blobid, NULL, blob_op_with_id_complete, NULL);
980 	poll_threads();
981 	CU_ASSERT(g_bserrno == 0);
982 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
983 	cloneid = g_blobid;
984 
985 	spdk_bs_open_blob(bs, cloneid, blob_op_with_handle_complete, NULL);
986 	poll_threads();
987 	CU_ASSERT(g_bserrno == 0);
988 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
989 	clone = g_blob;
990 	CU_ASSERT(clone->data_ro == false);
991 	CU_ASSERT(clone->md_ro == false);
992 	CU_ASSERT(spdk_blob_get_num_clusters(clone) == 10);
993 
994 	spdk_blob_close(clone, blob_op_complete, NULL);
995 	poll_threads();
996 	CU_ASSERT(g_bserrno == 0);
997 
998 	spdk_blob_close(blob, blob_op_complete, NULL);
999 	poll_threads();
1000 	CU_ASSERT(g_bserrno == 0);
1001 
1002 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1003 	poll_threads();
1004 	CU_ASSERT(g_bserrno == 0);
1005 	g_bs = NULL;
1006 
1007 }
1008 
1009 static void
1010 _blob_inflate(bool decouple_parent)
1011 {
1012 	struct spdk_blob_store *bs;
1013 	struct spdk_bs_dev *dev;
1014 	struct spdk_blob_opts opts;
1015 	struct spdk_blob *blob, *snapshot;
1016 	spdk_blob_id blobid, snapshotid;
1017 	struct spdk_io_channel *channel;
1018 	uint64_t free_clusters;
1019 
1020 	dev = init_dev();
1021 
1022 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1023 	poll_threads();
1024 	CU_ASSERT(g_bserrno == 0);
1025 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1026 	bs = g_bs;
1027 
1028 	channel = spdk_bs_alloc_io_channel(bs);
1029 	SPDK_CU_ASSERT_FATAL(channel != NULL);
1030 
1031 	/* Create blob with 10 clusters */
1032 
1033 	ut_spdk_blob_opts_init(&opts);
1034 	opts.num_clusters = 10;
1035 	opts.thin_provision = true;
1036 
1037 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
1038 	poll_threads();
1039 	CU_ASSERT(g_bserrno == 0);
1040 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1041 	blobid = g_blobid;
1042 
1043 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1044 	poll_threads();
1045 	CU_ASSERT(g_bserrno == 0);
1046 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1047 	blob = g_blob;
1048 
1049 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10);
1050 	CU_ASSERT(spdk_blob_is_thin_provisioned(blob) == true);
1051 
1052 	/* 1) Blob with no parent */
1053 	if (decouple_parent) {
1054 		/* Decouple parent of blob with no parent (should fail) */
1055 		spdk_bs_blob_decouple_parent(bs, channel, blobid, blob_op_complete, NULL);
1056 		poll_threads();
1057 		CU_ASSERT(g_bserrno != 0);
1058 	} else {
1059 		/* Inflate of thin blob with no parent should made it thick */
1060 		spdk_bs_inflate_blob(bs, channel, blobid, blob_op_complete, NULL);
1061 		poll_threads();
1062 		CU_ASSERT(g_bserrno == 0);
1063 		CU_ASSERT(spdk_blob_is_thin_provisioned(blob) == false);
1064 	}
1065 
1066 	spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL);
1067 	poll_threads();
1068 	CU_ASSERT(g_bserrno == 0);
1069 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1070 	snapshotid = g_blobid;
1071 
1072 	CU_ASSERT(spdk_blob_is_thin_provisioned(blob) == true);
1073 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10);
1074 
1075 	spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL);
1076 	poll_threads();
1077 	CU_ASSERT(g_bserrno == 0);
1078 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1079 	snapshot = g_blob;
1080 	CU_ASSERT(snapshot->data_ro == true);
1081 	CU_ASSERT(snapshot->md_ro == true);
1082 	CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 10);
1083 
1084 	spdk_blob_close(snapshot, blob_op_complete, NULL);
1085 	poll_threads();
1086 	CU_ASSERT(g_bserrno == 0);
1087 
1088 	free_clusters = spdk_bs_free_cluster_count(bs);
1089 
1090 	/* 2) Blob with parent */
1091 	if (!decouple_parent) {
1092 		/* Do full blob inflation */
1093 		spdk_bs_inflate_blob(bs, channel, blobid, blob_op_complete, NULL);
1094 		poll_threads();
1095 		CU_ASSERT(g_bserrno == 0);
1096 		/* all 10 clusters should be allocated */
1097 		CU_ASSERT(spdk_bs_free_cluster_count(bs) == free_clusters - 10);
1098 	} else {
1099 		/* Decouple parent of blob */
1100 		spdk_bs_blob_decouple_parent(bs, channel, blobid, blob_op_complete, NULL);
1101 		poll_threads();
1102 		CU_ASSERT(g_bserrno == 0);
1103 		/* when only parent is removed, none of the clusters should be allocated */
1104 		CU_ASSERT(spdk_bs_free_cluster_count(bs) == free_clusters);
1105 	}
1106 
1107 	/* Now, it should be possible to delete snapshot */
1108 	spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL);
1109 	poll_threads();
1110 	CU_ASSERT(g_bserrno == 0);
1111 
1112 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10);
1113 	CU_ASSERT(spdk_blob_is_thin_provisioned(blob) == decouple_parent);
1114 
1115 	spdk_blob_close(blob, blob_op_complete, NULL);
1116 	poll_threads();
1117 	CU_ASSERT(g_bserrno == 0);
1118 
1119 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1120 	poll_threads();
1121 	CU_ASSERT(g_bserrno == 0);
1122 	g_bs = NULL;
1123 
1124 	spdk_bs_free_io_channel(channel);
1125 	poll_threads();
1126 }
1127 
1128 static void
1129 blob_inflate(void)
1130 {
1131 	_blob_inflate(false);
1132 	_blob_inflate(true);
1133 }
1134 
1135 static void
1136 blob_delete(void)
1137 {
1138 	struct spdk_blob_store *bs;
1139 	struct spdk_bs_dev *dev;
1140 	struct spdk_blob_opts blob_opts;
1141 	spdk_blob_id blobid;
1142 
1143 	dev = init_dev();
1144 
1145 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1146 	poll_threads();
1147 	CU_ASSERT(g_bserrno == 0);
1148 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1149 	bs = g_bs;
1150 
1151 	/* Create a blob and then delete it. */
1152 	ut_spdk_blob_opts_init(&blob_opts);
1153 	spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL);
1154 	poll_threads();
1155 	CU_ASSERT(g_bserrno == 0);
1156 	CU_ASSERT(g_blobid > 0);
1157 	blobid = g_blobid;
1158 
1159 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
1160 	poll_threads();
1161 	CU_ASSERT(g_bserrno == 0);
1162 
1163 	/* Try to open the blob */
1164 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1165 	poll_threads();
1166 	CU_ASSERT(g_bserrno == -ENOENT);
1167 
1168 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1169 	poll_threads();
1170 	CU_ASSERT(g_bserrno == 0);
1171 	g_bs = NULL;
1172 }
1173 
1174 static void
1175 blob_resize(void)
1176 {
1177 	struct spdk_blob_store *bs;
1178 	struct spdk_bs_dev *dev;
1179 	struct spdk_blob *blob;
1180 	struct spdk_blob_opts blob_opts;
1181 	spdk_blob_id blobid;
1182 	uint64_t free_clusters;
1183 
1184 	dev = init_dev();
1185 
1186 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1187 	poll_threads();
1188 	CU_ASSERT(g_bserrno == 0);
1189 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1190 	bs = g_bs;
1191 	free_clusters = spdk_bs_free_cluster_count(bs);
1192 
1193 	ut_spdk_blob_opts_init(&blob_opts);
1194 	spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL);
1195 	poll_threads();
1196 	CU_ASSERT(g_bserrno == 0);
1197 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1198 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
1199 	blobid = g_blobid;
1200 
1201 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1202 	poll_threads();
1203 	CU_ASSERT(g_bserrno == 0);
1204 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1205 	blob = g_blob;
1206 
1207 	/* Confirm that resize fails if blob is marked read-only. */
1208 	blob->md_ro = true;
1209 	spdk_blob_resize(blob, 5, blob_op_complete, NULL);
1210 	poll_threads();
1211 	CU_ASSERT(g_bserrno == -EPERM);
1212 	blob->md_ro = false;
1213 
1214 	/* The blob started at 0 clusters. Resize it to be 5. */
1215 	spdk_blob_resize(blob, 5, blob_op_complete, NULL);
1216 	poll_threads();
1217 	CU_ASSERT(g_bserrno == 0);
1218 	CU_ASSERT((free_clusters - 5) == spdk_bs_free_cluster_count(bs));
1219 
1220 	/* Shrink the blob to 3 clusters. This will not actually release
1221 	 * the old clusters until the blob is synced.
1222 	 */
1223 	spdk_blob_resize(blob, 3, blob_op_complete, NULL);
1224 	poll_threads();
1225 	CU_ASSERT(g_bserrno == 0);
1226 	/* Verify there are still 5 clusters in use */
1227 	CU_ASSERT((free_clusters - 5) == spdk_bs_free_cluster_count(bs));
1228 
1229 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
1230 	poll_threads();
1231 	CU_ASSERT(g_bserrno == 0);
1232 	/* Now there are only 3 clusters in use */
1233 	CU_ASSERT((free_clusters - 3) == spdk_bs_free_cluster_count(bs));
1234 
1235 	/* Resize the blob to be 10 clusters. Growth takes effect immediately. */
1236 	spdk_blob_resize(blob, 10, blob_op_complete, NULL);
1237 	poll_threads();
1238 	CU_ASSERT(g_bserrno == 0);
1239 	CU_ASSERT((free_clusters - 10) == spdk_bs_free_cluster_count(bs));
1240 
1241 	/* Try to resize the blob to size larger than blobstore. */
1242 	spdk_blob_resize(blob, bs->total_clusters + 1, blob_op_complete, NULL);
1243 	poll_threads();
1244 	CU_ASSERT(g_bserrno == -ENOSPC);
1245 
1246 	spdk_blob_close(blob, blob_op_complete, NULL);
1247 	poll_threads();
1248 	CU_ASSERT(g_bserrno == 0);
1249 
1250 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
1251 	poll_threads();
1252 	CU_ASSERT(g_bserrno == 0);
1253 
1254 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1255 	poll_threads();
1256 	CU_ASSERT(g_bserrno == 0);
1257 	g_bs = NULL;
1258 }
1259 
1260 static void
1261 blob_read_only(void)
1262 {
1263 	struct spdk_blob_store *bs;
1264 	struct spdk_bs_dev *dev;
1265 	struct spdk_blob *blob;
1266 	struct spdk_bs_opts opts;
1267 	struct spdk_blob_opts blob_opts;
1268 	spdk_blob_id blobid;
1269 	int rc;
1270 
1271 	dev = init_dev();
1272 	spdk_bs_opts_init(&opts);
1273 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
1274 
1275 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
1276 	poll_threads();
1277 	CU_ASSERT(g_bserrno == 0);
1278 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1279 	bs = g_bs;
1280 
1281 	ut_spdk_blob_opts_init(&blob_opts);
1282 	spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL);
1283 	poll_threads();
1284 	CU_ASSERT(g_bserrno == 0);
1285 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1286 	blobid = g_blobid;
1287 
1288 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1289 	poll_threads();
1290 	CU_ASSERT(g_bserrno == 0);
1291 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1292 	blob = g_blob;
1293 
1294 	rc = spdk_blob_set_read_only(blob);
1295 	CU_ASSERT(rc == 0);
1296 
1297 	CU_ASSERT(blob->data_ro == false);
1298 	CU_ASSERT(blob->md_ro == false);
1299 
1300 	spdk_blob_sync_md(blob, bs_op_complete, NULL);
1301 	poll_threads();
1302 
1303 	CU_ASSERT(blob->data_ro == true);
1304 	CU_ASSERT(blob->md_ro == true);
1305 	CU_ASSERT(blob->data_ro_flags & SPDK_BLOB_READ_ONLY);
1306 
1307 	spdk_blob_close(blob, blob_op_complete, NULL);
1308 	poll_threads();
1309 	CU_ASSERT(g_bserrno == 0);
1310 
1311 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1312 	poll_threads();
1313 	CU_ASSERT(g_bserrno == 0);
1314 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1315 	blob = g_blob;
1316 
1317 	CU_ASSERT(blob->data_ro == true);
1318 	CU_ASSERT(blob->md_ro == true);
1319 	CU_ASSERT(blob->data_ro_flags & SPDK_BLOB_READ_ONLY);
1320 
1321 	spdk_blob_close(blob, blob_op_complete, NULL);
1322 	poll_threads();
1323 	CU_ASSERT(g_bserrno == 0);
1324 
1325 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1326 	poll_threads();
1327 	CU_ASSERT(g_bserrno == 0);
1328 	g_bs = NULL;
1329 	g_blob = NULL;
1330 	g_blobid = 0;
1331 
1332 	/* Load an existing blob store */
1333 	dev = init_dev();
1334 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
1335 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1336 	poll_threads();
1337 	CU_ASSERT(g_bserrno == 0);
1338 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1339 
1340 	spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
1341 	poll_threads();
1342 	CU_ASSERT(g_bserrno == 0);
1343 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1344 	blob = g_blob;
1345 
1346 	CU_ASSERT(blob->data_ro == true);
1347 	CU_ASSERT(blob->md_ro == true);
1348 	CU_ASSERT(blob->data_ro_flags & SPDK_BLOB_READ_ONLY);
1349 
1350 	spdk_blob_close(blob, blob_op_complete, NULL);
1351 	poll_threads();
1352 	CU_ASSERT(g_bserrno == 0);
1353 
1354 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1355 	poll_threads();
1356 	CU_ASSERT(g_bserrno == 0);
1357 
1358 }
1359 
1360 static void
1361 channel_ops(void)
1362 {
1363 	struct spdk_blob_store *bs;
1364 	struct spdk_bs_dev *dev;
1365 	struct spdk_io_channel *channel;
1366 
1367 	dev = init_dev();
1368 
1369 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1370 	poll_threads();
1371 	CU_ASSERT(g_bserrno == 0);
1372 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1373 	bs = g_bs;
1374 
1375 	channel = spdk_bs_alloc_io_channel(bs);
1376 	CU_ASSERT(channel != NULL);
1377 
1378 	spdk_bs_free_io_channel(channel);
1379 	poll_threads();
1380 
1381 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1382 	poll_threads();
1383 	CU_ASSERT(g_bserrno == 0);
1384 	g_bs = NULL;
1385 }
1386 
1387 static void
1388 blob_write(void)
1389 {
1390 	struct spdk_blob_store *bs;
1391 	struct spdk_bs_dev *dev;
1392 	struct spdk_blob *blob;
1393 	struct spdk_blob_opts blob_opts;
1394 	struct spdk_io_channel *channel;
1395 	spdk_blob_id blobid;
1396 	uint64_t pages_per_cluster;
1397 	uint8_t payload[10 * 4096];
1398 
1399 	dev = init_dev();
1400 
1401 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1402 	poll_threads();
1403 	CU_ASSERT(g_bserrno == 0);
1404 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1405 	bs = g_bs;
1406 
1407 	pages_per_cluster = spdk_bs_get_cluster_size(bs) / spdk_bs_get_page_size(bs);
1408 
1409 	channel = spdk_bs_alloc_io_channel(bs);
1410 	CU_ASSERT(channel != NULL);
1411 
1412 	ut_spdk_blob_opts_init(&blob_opts);
1413 	spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL);
1414 	poll_threads();
1415 	CU_ASSERT(g_bserrno == 0);
1416 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1417 	blobid = g_blobid;
1418 
1419 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1420 	poll_threads();
1421 	CU_ASSERT(g_bserrno == 0);
1422 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1423 	blob = g_blob;
1424 
1425 	/* Write to a blob with 0 size */
1426 	spdk_blob_io_write(blob, channel, payload, 0, 1, blob_op_complete, NULL);
1427 	poll_threads();
1428 	CU_ASSERT(g_bserrno == -EINVAL);
1429 
1430 	/* Resize the blob */
1431 	spdk_blob_resize(blob, 5, blob_op_complete, NULL);
1432 	poll_threads();
1433 	CU_ASSERT(g_bserrno == 0);
1434 
1435 	/* Confirm that write fails if blob is marked read-only. */
1436 	blob->data_ro = true;
1437 	spdk_blob_io_write(blob, channel, payload, 0, 1, blob_op_complete, NULL);
1438 	poll_threads();
1439 	CU_ASSERT(g_bserrno == -EPERM);
1440 	blob->data_ro = false;
1441 
1442 	/* Write to the blob */
1443 	spdk_blob_io_write(blob, channel, payload, 0, 1, blob_op_complete, NULL);
1444 	poll_threads();
1445 	CU_ASSERT(g_bserrno == 0);
1446 
1447 	/* Write starting beyond the end */
1448 	spdk_blob_io_write(blob, channel, payload, 5 * pages_per_cluster, 1, blob_op_complete,
1449 			   NULL);
1450 	poll_threads();
1451 	CU_ASSERT(g_bserrno == -EINVAL);
1452 
1453 	/* Write starting at a valid location but going off the end */
1454 	spdk_blob_io_write(blob, channel, payload, 4 * pages_per_cluster, pages_per_cluster + 1,
1455 			   blob_op_complete, NULL);
1456 	poll_threads();
1457 	CU_ASSERT(g_bserrno == -EINVAL);
1458 
1459 	spdk_blob_close(blob, blob_op_complete, NULL);
1460 	poll_threads();
1461 	CU_ASSERT(g_bserrno == 0);
1462 
1463 	spdk_bs_free_io_channel(channel);
1464 	poll_threads();
1465 
1466 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1467 	poll_threads();
1468 	CU_ASSERT(g_bserrno == 0);
1469 	g_bs = NULL;
1470 }
1471 
1472 static void
1473 blob_read(void)
1474 {
1475 	struct spdk_blob_store *bs;
1476 	struct spdk_bs_dev *dev;
1477 	struct spdk_blob *blob;
1478 	struct spdk_blob_opts blob_opts;
1479 	struct spdk_io_channel *channel;
1480 	spdk_blob_id blobid;
1481 	uint64_t pages_per_cluster;
1482 	uint8_t payload[10 * 4096];
1483 
1484 	dev = init_dev();
1485 
1486 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1487 	poll_threads();
1488 	CU_ASSERT(g_bserrno == 0);
1489 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1490 	bs = g_bs;
1491 
1492 	pages_per_cluster = spdk_bs_get_cluster_size(bs) / spdk_bs_get_page_size(bs);
1493 
1494 	channel = spdk_bs_alloc_io_channel(bs);
1495 	CU_ASSERT(channel != NULL);
1496 
1497 	ut_spdk_blob_opts_init(&blob_opts);
1498 	spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL);
1499 	poll_threads();
1500 	CU_ASSERT(g_bserrno == 0);
1501 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1502 	blobid = g_blobid;
1503 
1504 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1505 	poll_threads();
1506 	CU_ASSERT(g_bserrno == 0);
1507 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1508 	blob = g_blob;
1509 
1510 	/* Read from a blob with 0 size */
1511 	spdk_blob_io_read(blob, channel, payload, 0, 1, blob_op_complete, NULL);
1512 	poll_threads();
1513 	CU_ASSERT(g_bserrno == -EINVAL);
1514 
1515 	/* Resize the blob */
1516 	spdk_blob_resize(blob, 5, blob_op_complete, NULL);
1517 	poll_threads();
1518 	CU_ASSERT(g_bserrno == 0);
1519 
1520 	/* Confirm that read passes if blob is marked read-only. */
1521 	blob->data_ro = true;
1522 	spdk_blob_io_read(blob, channel, payload, 0, 1, blob_op_complete, NULL);
1523 	poll_threads();
1524 	CU_ASSERT(g_bserrno == 0);
1525 	blob->data_ro = false;
1526 
1527 	/* Read from the blob */
1528 	spdk_blob_io_read(blob, channel, payload, 0, 1, blob_op_complete, NULL);
1529 	poll_threads();
1530 	CU_ASSERT(g_bserrno == 0);
1531 
1532 	/* Read starting beyond the end */
1533 	spdk_blob_io_read(blob, channel, payload, 5 * pages_per_cluster, 1, blob_op_complete,
1534 			  NULL);
1535 	poll_threads();
1536 	CU_ASSERT(g_bserrno == -EINVAL);
1537 
1538 	/* Read starting at a valid location but going off the end */
1539 	spdk_blob_io_read(blob, channel, payload, 4 * pages_per_cluster, pages_per_cluster + 1,
1540 			  blob_op_complete, NULL);
1541 	poll_threads();
1542 	CU_ASSERT(g_bserrno == -EINVAL);
1543 
1544 	spdk_blob_close(blob, blob_op_complete, NULL);
1545 	poll_threads();
1546 	CU_ASSERT(g_bserrno == 0);
1547 
1548 	spdk_bs_free_io_channel(channel);
1549 	poll_threads();
1550 
1551 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1552 	poll_threads();
1553 	CU_ASSERT(g_bserrno == 0);
1554 	g_bs = NULL;
1555 }
1556 
1557 static void
1558 blob_rw_verify(void)
1559 {
1560 	struct spdk_blob_store *bs;
1561 	struct spdk_bs_dev *dev;
1562 	struct spdk_blob *blob;
1563 	struct spdk_blob_opts blob_opts;
1564 	struct spdk_io_channel *channel;
1565 	spdk_blob_id blobid;
1566 	uint8_t payload_read[10 * 4096];
1567 	uint8_t payload_write[10 * 4096];
1568 
1569 	dev = init_dev();
1570 
1571 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1572 	poll_threads();
1573 	CU_ASSERT(g_bserrno == 0);
1574 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1575 	bs = g_bs;
1576 
1577 	channel = spdk_bs_alloc_io_channel(bs);
1578 	CU_ASSERT(channel != NULL);
1579 
1580 	ut_spdk_blob_opts_init(&blob_opts);
1581 	spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL);
1582 	poll_threads();
1583 	CU_ASSERT(g_bserrno == 0);
1584 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1585 	blobid = g_blobid;
1586 
1587 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1588 	poll_threads();
1589 	CU_ASSERT(g_bserrno == 0);
1590 	CU_ASSERT(g_blob != NULL);
1591 	blob = g_blob;
1592 
1593 	spdk_blob_resize(blob, 32, blob_op_complete, NULL);
1594 	poll_threads();
1595 	CU_ASSERT(g_bserrno == 0);
1596 
1597 	memset(payload_write, 0xE5, sizeof(payload_write));
1598 	spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL);
1599 	poll_threads();
1600 	CU_ASSERT(g_bserrno == 0);
1601 
1602 	memset(payload_read, 0x00, sizeof(payload_read));
1603 	spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL);
1604 	poll_threads();
1605 	CU_ASSERT(g_bserrno == 0);
1606 	CU_ASSERT(memcmp(payload_write, payload_read, 4 * 4096) == 0);
1607 
1608 	spdk_blob_close(blob, blob_op_complete, NULL);
1609 	poll_threads();
1610 	CU_ASSERT(g_bserrno == 0);
1611 
1612 	spdk_bs_free_io_channel(channel);
1613 	poll_threads();
1614 
1615 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1616 	poll_threads();
1617 	CU_ASSERT(g_bserrno == 0);
1618 	g_bs = NULL;
1619 }
1620 
1621 static void
1622 blob_rw_verify_iov(void)
1623 {
1624 	struct spdk_blob_store *bs;
1625 	struct spdk_bs_dev *dev;
1626 	struct spdk_blob *blob;
1627 	struct spdk_blob_opts blob_opts;
1628 	struct spdk_io_channel *channel;
1629 	spdk_blob_id blobid;
1630 	uint8_t payload_read[10 * 4096];
1631 	uint8_t payload_write[10 * 4096];
1632 	struct iovec iov_read[3];
1633 	struct iovec iov_write[3];
1634 	void *buf;
1635 
1636 	dev = init_dev();
1637 	memset(g_dev_buffer, 0, DEV_BUFFER_SIZE);
1638 
1639 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1640 	poll_threads();
1641 	CU_ASSERT(g_bserrno == 0);
1642 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1643 	bs = g_bs;
1644 
1645 	channel = spdk_bs_alloc_io_channel(bs);
1646 	CU_ASSERT(channel != NULL);
1647 
1648 	ut_spdk_blob_opts_init(&blob_opts);
1649 	spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL);
1650 	poll_threads();
1651 	CU_ASSERT(g_bserrno == 0);
1652 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1653 	blobid = g_blobid;
1654 
1655 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1656 	poll_threads();
1657 	CU_ASSERT(g_bserrno == 0);
1658 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1659 	blob = g_blob;
1660 
1661 	spdk_blob_resize(blob, 2, blob_op_complete, NULL);
1662 	poll_threads();
1663 	CU_ASSERT(g_bserrno == 0);
1664 
1665 	/*
1666 	 * Manually adjust the offset of the blob's second cluster.  This allows
1667 	 *  us to make sure that the readv/write code correctly accounts for I/O
1668 	 *  that cross cluster boundaries.  Start by asserting that the allocated
1669 	 *  clusters are where we expect before modifying the second cluster.
1670 	 */
1671 	CU_ASSERT(blob->active.clusters[0] == 1 * 256);
1672 	CU_ASSERT(blob->active.clusters[1] == 2 * 256);
1673 	blob->active.clusters[1] = 3 * 256;
1674 
1675 	memset(payload_write, 0xE5, sizeof(payload_write));
1676 	iov_write[0].iov_base = payload_write;
1677 	iov_write[0].iov_len = 1 * 4096;
1678 	iov_write[1].iov_base = payload_write + 1 * 4096;
1679 	iov_write[1].iov_len = 5 * 4096;
1680 	iov_write[2].iov_base = payload_write + 6 * 4096;
1681 	iov_write[2].iov_len = 4 * 4096;
1682 	/*
1683 	 * Choose a page offset just before the cluster boundary.  The first 6 pages of payload
1684 	 *  will get written to the first cluster, the last 4 to the second cluster.
1685 	 */
1686 	spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL);
1687 	poll_threads();
1688 	CU_ASSERT(g_bserrno == 0);
1689 
1690 	memset(payload_read, 0xAA, sizeof(payload_read));
1691 	iov_read[0].iov_base = payload_read;
1692 	iov_read[0].iov_len = 3 * 4096;
1693 	iov_read[1].iov_base = payload_read + 3 * 4096;
1694 	iov_read[1].iov_len = 4 * 4096;
1695 	iov_read[2].iov_base = payload_read + 7 * 4096;
1696 	iov_read[2].iov_len = 3 * 4096;
1697 	spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL);
1698 	poll_threads();
1699 	CU_ASSERT(g_bserrno == 0);
1700 	CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0);
1701 
1702 	buf = calloc(1, 256 * 4096);
1703 	SPDK_CU_ASSERT_FATAL(buf != NULL);
1704 	/* Check that cluster 2 on "disk" was not modified. */
1705 	CU_ASSERT(memcmp(buf, &g_dev_buffer[512 * 4096], 256 * 4096) == 0);
1706 	free(buf);
1707 
1708 	spdk_blob_close(blob, blob_op_complete, NULL);
1709 	poll_threads();
1710 	CU_ASSERT(g_bserrno == 0);
1711 
1712 	spdk_bs_free_io_channel(channel);
1713 	poll_threads();
1714 
1715 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1716 	poll_threads();
1717 	CU_ASSERT(g_bserrno == 0);
1718 	g_bs = NULL;
1719 }
1720 
1721 static uint32_t
1722 bs_channel_get_req_count(struct spdk_io_channel *_channel)
1723 {
1724 	struct spdk_bs_channel *channel = spdk_io_channel_get_ctx(_channel);
1725 	struct spdk_bs_request_set *set;
1726 	uint32_t count = 0;
1727 
1728 	TAILQ_FOREACH(set, &channel->reqs, link) {
1729 		count++;
1730 	}
1731 
1732 	return count;
1733 }
1734 
1735 static void
1736 blob_rw_verify_iov_nomem(void)
1737 {
1738 	struct spdk_blob_store *bs;
1739 	struct spdk_bs_dev *dev;
1740 	struct spdk_blob *blob;
1741 	struct spdk_blob_opts blob_opts;
1742 	struct spdk_io_channel *channel;
1743 	spdk_blob_id blobid;
1744 	uint8_t payload_write[10 * 4096];
1745 	struct iovec iov_write[3];
1746 	uint32_t req_count;
1747 
1748 	dev = init_dev();
1749 	memset(g_dev_buffer, 0, DEV_BUFFER_SIZE);
1750 
1751 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1752 	poll_threads();
1753 	CU_ASSERT(g_bserrno == 0);
1754 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1755 	bs = g_bs;
1756 
1757 	channel = spdk_bs_alloc_io_channel(bs);
1758 	CU_ASSERT(channel != NULL);
1759 
1760 	ut_spdk_blob_opts_init(&blob_opts);
1761 	spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL);
1762 	poll_threads();
1763 	CU_ASSERT(g_bserrno == 0);
1764 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1765 	blobid = g_blobid;
1766 
1767 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1768 	poll_threads();
1769 	CU_ASSERT(g_bserrno == 0);
1770 	CU_ASSERT(g_blob != NULL);
1771 	blob = g_blob;
1772 
1773 	spdk_blob_resize(blob, 2, blob_op_complete, NULL);
1774 	poll_threads();
1775 	CU_ASSERT(g_bserrno == 0);
1776 
1777 	/*
1778 	 * Choose a page offset just before the cluster boundary.  The first 6 pages of payload
1779 	 *  will get written to the first cluster, the last 4 to the second cluster.
1780 	 */
1781 	iov_write[0].iov_base = payload_write;
1782 	iov_write[0].iov_len = 1 * 4096;
1783 	iov_write[1].iov_base = payload_write + 1 * 4096;
1784 	iov_write[1].iov_len = 5 * 4096;
1785 	iov_write[2].iov_base = payload_write + 6 * 4096;
1786 	iov_write[2].iov_len = 4 * 4096;
1787 	MOCK_SET(calloc, NULL);
1788 	req_count = bs_channel_get_req_count(channel);
1789 	spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL);
1790 	poll_threads();
1791 	CU_ASSERT(g_bserrno = -ENOMEM);
1792 	CU_ASSERT(req_count == bs_channel_get_req_count(channel));
1793 	MOCK_CLEAR(calloc);
1794 
1795 	spdk_blob_close(blob, blob_op_complete, NULL);
1796 	poll_threads();
1797 	CU_ASSERT(g_bserrno == 0);
1798 
1799 	spdk_bs_free_io_channel(channel);
1800 	poll_threads();
1801 
1802 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1803 	poll_threads();
1804 	CU_ASSERT(g_bserrno == 0);
1805 	g_bs = NULL;
1806 }
1807 
1808 static void
1809 blob_rw_iov_read_only(void)
1810 {
1811 	struct spdk_blob_store *bs;
1812 	struct spdk_bs_dev *dev;
1813 	struct spdk_blob *blob;
1814 	struct spdk_io_channel *channel;
1815 	spdk_blob_id blobid;
1816 	uint8_t payload_read[4096];
1817 	uint8_t payload_write[4096];
1818 	struct iovec iov_read;
1819 	struct iovec iov_write;
1820 	struct spdk_blob_opts blob_opts;
1821 
1822 	dev = init_dev();
1823 	memset(g_dev_buffer, 0, DEV_BUFFER_SIZE);
1824 
1825 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1826 	poll_threads();
1827 	CU_ASSERT(g_bserrno == 0);
1828 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1829 	bs = g_bs;
1830 
1831 	channel = spdk_bs_alloc_io_channel(bs);
1832 	CU_ASSERT(channel != NULL);
1833 
1834 	ut_spdk_blob_opts_init(&blob_opts);
1835 	spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL);
1836 	poll_threads();
1837 	CU_ASSERT(g_bserrno == 0);
1838 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1839 	blobid = g_blobid;
1840 
1841 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1842 	poll_threads();
1843 	CU_ASSERT(g_bserrno == 0);
1844 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1845 	blob = g_blob;
1846 
1847 	spdk_blob_resize(blob, 2, blob_op_complete, NULL);
1848 	poll_threads();
1849 	CU_ASSERT(g_bserrno == 0);
1850 
1851 	/* Verify that writev failed if read_only flag is set. */
1852 	blob->data_ro = true;
1853 	iov_write.iov_base = payload_write;
1854 	iov_write.iov_len = sizeof(payload_write);
1855 	spdk_blob_io_writev(blob, channel, &iov_write, 1, 0, 1, blob_op_complete, NULL);
1856 	poll_threads();
1857 	CU_ASSERT(g_bserrno == -EPERM);
1858 
1859 	/* Verify that reads pass if data_ro flag is set. */
1860 	iov_read.iov_base = payload_read;
1861 	iov_read.iov_len = sizeof(payload_read);
1862 	spdk_blob_io_readv(blob, channel, &iov_read, 1, 0, 1, blob_op_complete, NULL);
1863 	poll_threads();
1864 	CU_ASSERT(g_bserrno == 0);
1865 
1866 	spdk_blob_close(blob, blob_op_complete, NULL);
1867 	poll_threads();
1868 	CU_ASSERT(g_bserrno == 0);
1869 
1870 	spdk_bs_free_io_channel(channel);
1871 	poll_threads();
1872 
1873 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1874 	poll_threads();
1875 	CU_ASSERT(g_bserrno == 0);
1876 	g_bs = NULL;
1877 }
1878 
1879 static void
1880 _blob_io_read_no_split(struct spdk_blob *blob, struct spdk_io_channel *channel,
1881 		       uint8_t *payload, uint64_t offset, uint64_t length,
1882 		       spdk_blob_op_complete cb_fn, void *cb_arg)
1883 {
1884 	uint64_t i;
1885 	uint8_t *buf;
1886 	uint64_t page_size = spdk_bs_get_page_size(blob->bs);
1887 
1888 	/* To be sure that operation is NOT splitted, read one page at the time */
1889 	buf = payload;
1890 	for (i = 0; i < length; i++) {
1891 		spdk_blob_io_read(blob, channel, buf, i + offset, 1, blob_op_complete, NULL);
1892 		poll_threads();
1893 		if (g_bserrno != 0) {
1894 			/* Pass the error code up */
1895 			break;
1896 		}
1897 		buf += page_size;
1898 	}
1899 
1900 	cb_fn(cb_arg, g_bserrno);
1901 }
1902 
1903 static void
1904 _blob_io_write_no_split(struct spdk_blob *blob, struct spdk_io_channel *channel,
1905 			uint8_t *payload, uint64_t offset, uint64_t length,
1906 			spdk_blob_op_complete cb_fn, void *cb_arg)
1907 {
1908 	uint64_t i;
1909 	uint8_t *buf;
1910 	uint64_t page_size = spdk_bs_get_page_size(blob->bs);
1911 
1912 	/* To be sure that operation is NOT splitted, write one page at the time */
1913 	buf = payload;
1914 	for (i = 0; i < length; i++) {
1915 		spdk_blob_io_write(blob, channel, buf, i + offset, 1, blob_op_complete, NULL);
1916 		poll_threads();
1917 		if (g_bserrno != 0) {
1918 			/* Pass the error code up */
1919 			break;
1920 		}
1921 		buf += page_size;
1922 	}
1923 
1924 	cb_fn(cb_arg, g_bserrno);
1925 }
1926 
1927 static void
1928 blob_operation_split_rw(void)
1929 {
1930 	struct spdk_blob_store *bs;
1931 	struct spdk_bs_dev *dev;
1932 	struct spdk_blob *blob;
1933 	struct spdk_io_channel *channel;
1934 	struct spdk_blob_opts opts;
1935 	spdk_blob_id blobid;
1936 	uint64_t cluster_size;
1937 
1938 	uint64_t payload_size;
1939 	uint8_t *payload_read;
1940 	uint8_t *payload_write;
1941 	uint8_t *payload_pattern;
1942 
1943 	uint64_t page_size;
1944 	uint64_t pages_per_cluster;
1945 	uint64_t pages_per_payload;
1946 
1947 	uint64_t i;
1948 
1949 	dev = init_dev();
1950 
1951 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1952 	poll_threads();
1953 	CU_ASSERT(g_bserrno == 0);
1954 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1955 	bs = g_bs;
1956 
1957 	cluster_size = spdk_bs_get_cluster_size(bs);
1958 	page_size = spdk_bs_get_page_size(bs);
1959 	pages_per_cluster = cluster_size / page_size;
1960 	pages_per_payload = pages_per_cluster * 5;
1961 	payload_size = cluster_size * 5;
1962 
1963 	payload_read = malloc(payload_size);
1964 	SPDK_CU_ASSERT_FATAL(payload_read != NULL);
1965 
1966 	payload_write = malloc(payload_size);
1967 	SPDK_CU_ASSERT_FATAL(payload_write != NULL);
1968 
1969 	payload_pattern = malloc(payload_size);
1970 	SPDK_CU_ASSERT_FATAL(payload_pattern != NULL);
1971 
1972 	/* Prepare random pattern to write */
1973 	memset(payload_pattern, 0xFF, payload_size);
1974 	for (i = 0; i < pages_per_payload; i++) {
1975 		*((uint64_t *)(payload_pattern + page_size * i)) = (i + 1);
1976 	}
1977 
1978 	channel = spdk_bs_alloc_io_channel(bs);
1979 	SPDK_CU_ASSERT_FATAL(channel != NULL);
1980 
1981 	/* Create blob */
1982 	ut_spdk_blob_opts_init(&opts);
1983 	opts.thin_provision = false;
1984 	opts.num_clusters = 5;
1985 
1986 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
1987 	poll_threads();
1988 	CU_ASSERT(g_bserrno == 0);
1989 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1990 	blobid = g_blobid;
1991 
1992 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1993 	poll_threads();
1994 	CU_ASSERT(g_bserrno == 0);
1995 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1996 	blob = g_blob;
1997 
1998 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5);
1999 
2000 	/* Initial read should return zeroed payload */
2001 	memset(payload_read, 0xFF, payload_size);
2002 	spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, blob_op_complete, NULL);
2003 	poll_threads();
2004 	CU_ASSERT(g_bserrno == 0);
2005 	CU_ASSERT(spdk_mem_all_zero(payload_read, payload_size));
2006 
2007 	/* Fill whole blob except last page */
2008 	spdk_blob_io_write(blob, channel, payload_pattern, 0, pages_per_payload - 1,
2009 			   blob_op_complete, NULL);
2010 	poll_threads();
2011 	CU_ASSERT(g_bserrno == 0);
2012 
2013 	/* Write last page with a pattern */
2014 	spdk_blob_io_write(blob, channel, payload_pattern, pages_per_payload - 1, 1,
2015 			   blob_op_complete, NULL);
2016 	poll_threads();
2017 	CU_ASSERT(g_bserrno == 0);
2018 
2019 	/* Read whole blob and check consistency */
2020 	memset(payload_read, 0xFF, payload_size);
2021 	spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, blob_op_complete, NULL);
2022 	poll_threads();
2023 	CU_ASSERT(g_bserrno == 0);
2024 	CU_ASSERT(memcmp(payload_pattern, payload_read, payload_size - page_size) == 0);
2025 	CU_ASSERT(memcmp(payload_pattern, payload_read + payload_size - page_size, page_size) == 0);
2026 
2027 	/* Fill whole blob except first page */
2028 	spdk_blob_io_write(blob, channel, payload_pattern, 1, pages_per_payload - 1,
2029 			   blob_op_complete, NULL);
2030 	poll_threads();
2031 	CU_ASSERT(g_bserrno == 0);
2032 
2033 	/* Write first page with a pattern */
2034 	spdk_blob_io_write(blob, channel, payload_pattern, 0, 1,
2035 			   blob_op_complete, NULL);
2036 	poll_threads();
2037 	CU_ASSERT(g_bserrno == 0);
2038 
2039 	/* Read whole blob and check consistency */
2040 	memset(payload_read, 0xFF, payload_size);
2041 	spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, blob_op_complete, NULL);
2042 	poll_threads();
2043 	CU_ASSERT(g_bserrno == 0);
2044 	CU_ASSERT(memcmp(payload_pattern, payload_read + page_size, payload_size - page_size) == 0);
2045 	CU_ASSERT(memcmp(payload_pattern, payload_read, page_size) == 0);
2046 
2047 
2048 	/* Fill whole blob with a pattern (5 clusters) */
2049 
2050 	/* 1. Read test. */
2051 	_blob_io_write_no_split(blob, channel, payload_pattern, 0, pages_per_payload,
2052 				blob_op_complete, NULL);
2053 	poll_threads();
2054 	CU_ASSERT(g_bserrno == 0);
2055 
2056 	memset(payload_read, 0xFF, payload_size);
2057 	spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, blob_op_complete, NULL);
2058 	poll_threads();
2059 	poll_threads();
2060 	CU_ASSERT(g_bserrno == 0);
2061 	CU_ASSERT(memcmp(payload_pattern, payload_read, payload_size) == 0);
2062 
2063 	/* 2. Write test. */
2064 	spdk_blob_io_write(blob, channel, payload_pattern, 0, pages_per_payload,
2065 			   blob_op_complete, NULL);
2066 	poll_threads();
2067 	CU_ASSERT(g_bserrno == 0);
2068 
2069 	memset(payload_read, 0xFF, payload_size);
2070 	_blob_io_read_no_split(blob, channel, payload_read, 0, pages_per_payload, blob_op_complete, NULL);
2071 	poll_threads();
2072 	CU_ASSERT(g_bserrno == 0);
2073 	CU_ASSERT(memcmp(payload_pattern, payload_read, payload_size) == 0);
2074 
2075 	spdk_blob_close(blob, blob_op_complete, NULL);
2076 	poll_threads();
2077 	CU_ASSERT(g_bserrno == 0);
2078 
2079 	spdk_bs_free_io_channel(channel);
2080 	poll_threads();
2081 
2082 	/* Unload the blob store */
2083 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2084 	poll_threads();
2085 	CU_ASSERT(g_bserrno == 0);
2086 	g_bs = NULL;
2087 	g_blob = NULL;
2088 	g_blobid = 0;
2089 
2090 	free(payload_read);
2091 	free(payload_write);
2092 	free(payload_pattern);
2093 }
2094 
2095 static void
2096 blob_operation_split_rw_iov(void)
2097 {
2098 	struct spdk_blob_store *bs;
2099 	struct spdk_bs_dev *dev;
2100 	struct spdk_blob *blob;
2101 	struct spdk_io_channel *channel;
2102 	struct spdk_blob_opts opts;
2103 	spdk_blob_id blobid;
2104 	uint64_t cluster_size;
2105 
2106 	uint64_t payload_size;
2107 	uint8_t *payload_read;
2108 	uint8_t *payload_write;
2109 	uint8_t *payload_pattern;
2110 
2111 	uint64_t page_size;
2112 	uint64_t pages_per_cluster;
2113 	uint64_t pages_per_payload;
2114 
2115 	struct iovec iov_read[2];
2116 	struct iovec iov_write[2];
2117 
2118 	uint64_t i, j;
2119 
2120 	dev = init_dev();
2121 
2122 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
2123 	poll_threads();
2124 	CU_ASSERT(g_bserrno == 0);
2125 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2126 	bs = g_bs;
2127 
2128 	cluster_size = spdk_bs_get_cluster_size(bs);
2129 	page_size = spdk_bs_get_page_size(bs);
2130 	pages_per_cluster = cluster_size / page_size;
2131 	pages_per_payload = pages_per_cluster * 5;
2132 	payload_size = cluster_size * 5;
2133 
2134 	payload_read = malloc(payload_size);
2135 	SPDK_CU_ASSERT_FATAL(payload_read != NULL);
2136 
2137 	payload_write = malloc(payload_size);
2138 	SPDK_CU_ASSERT_FATAL(payload_write != NULL);
2139 
2140 	payload_pattern = malloc(payload_size);
2141 	SPDK_CU_ASSERT_FATAL(payload_pattern != NULL);
2142 
2143 	/* Prepare random pattern to write */
2144 	for (i = 0; i < pages_per_payload; i++) {
2145 		for (j = 0; j < page_size / sizeof(uint64_t); j++) {
2146 			uint64_t *tmp;
2147 
2148 			tmp = (uint64_t *)payload_pattern;
2149 			tmp += ((page_size * i) / sizeof(uint64_t)) + j;
2150 			*tmp = i + 1;
2151 		}
2152 	}
2153 
2154 	channel = spdk_bs_alloc_io_channel(bs);
2155 	SPDK_CU_ASSERT_FATAL(channel != NULL);
2156 
2157 	/* Create blob */
2158 	ut_spdk_blob_opts_init(&opts);
2159 	opts.thin_provision = false;
2160 	opts.num_clusters = 5;
2161 
2162 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
2163 	poll_threads();
2164 	CU_ASSERT(g_bserrno == 0);
2165 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2166 	blobid = g_blobid;
2167 
2168 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
2169 	poll_threads();
2170 	CU_ASSERT(g_bserrno == 0);
2171 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
2172 	blob = g_blob;
2173 
2174 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5);
2175 
2176 	/* Initial read should return zeroes payload */
2177 	memset(payload_read, 0xFF, payload_size);
2178 	iov_read[0].iov_base = payload_read;
2179 	iov_read[0].iov_len = cluster_size * 3;
2180 	iov_read[1].iov_base = payload_read + cluster_size * 3;
2181 	iov_read[1].iov_len = cluster_size * 2;
2182 	spdk_blob_io_readv(blob, channel, iov_read, 2, 0, pages_per_payload, blob_op_complete, NULL);
2183 	poll_threads();
2184 	CU_ASSERT(g_bserrno == 0);
2185 	CU_ASSERT(spdk_mem_all_zero(payload_read, payload_size));
2186 
2187 	/* First of iovs fills whole blob except last page and second of iovs writes last page
2188 	 *  with a pattern. */
2189 	iov_write[0].iov_base = payload_pattern;
2190 	iov_write[0].iov_len = payload_size - page_size;
2191 	iov_write[1].iov_base = payload_pattern;
2192 	iov_write[1].iov_len = page_size;
2193 	spdk_blob_io_writev(blob, channel, iov_write, 2, 0, pages_per_payload, blob_op_complete, NULL);
2194 	poll_threads();
2195 	CU_ASSERT(g_bserrno == 0);
2196 
2197 	/* Read whole blob and check consistency */
2198 	memset(payload_read, 0xFF, payload_size);
2199 	iov_read[0].iov_base = payload_read;
2200 	iov_read[0].iov_len = cluster_size * 2;
2201 	iov_read[1].iov_base = payload_read + cluster_size * 2;
2202 	iov_read[1].iov_len = cluster_size * 3;
2203 	spdk_blob_io_readv(blob, channel, iov_read, 2, 0, pages_per_payload, blob_op_complete, NULL);
2204 	poll_threads();
2205 	CU_ASSERT(g_bserrno == 0);
2206 	CU_ASSERT(memcmp(payload_pattern, payload_read, payload_size - page_size) == 0);
2207 	CU_ASSERT(memcmp(payload_pattern, payload_read + payload_size - page_size, page_size) == 0);
2208 
2209 	/* First of iovs fills only first page and second of iovs writes whole blob except
2210 	 *  first page with a pattern. */
2211 	iov_write[0].iov_base = payload_pattern;
2212 	iov_write[0].iov_len = page_size;
2213 	iov_write[1].iov_base = payload_pattern;
2214 	iov_write[1].iov_len = payload_size - page_size;
2215 	spdk_blob_io_writev(blob, channel, iov_write, 2, 0, pages_per_payload, blob_op_complete, NULL);
2216 	poll_threads();
2217 	CU_ASSERT(g_bserrno == 0);
2218 
2219 	/* Read whole blob and check consistency */
2220 	memset(payload_read, 0xFF, payload_size);
2221 	iov_read[0].iov_base = payload_read;
2222 	iov_read[0].iov_len = cluster_size * 4;
2223 	iov_read[1].iov_base = payload_read + cluster_size * 4;
2224 	iov_read[1].iov_len = cluster_size;
2225 	spdk_blob_io_readv(blob, channel, iov_read, 2, 0, pages_per_payload, blob_op_complete, NULL);
2226 	poll_threads();
2227 	CU_ASSERT(g_bserrno == 0);
2228 	CU_ASSERT(memcmp(payload_pattern, payload_read + page_size, payload_size - page_size) == 0);
2229 	CU_ASSERT(memcmp(payload_pattern, payload_read, page_size) == 0);
2230 
2231 
2232 	/* Fill whole blob with a pattern (5 clusters) */
2233 
2234 	/* 1. Read test. */
2235 	_blob_io_write_no_split(blob, channel, payload_pattern, 0, pages_per_payload,
2236 				blob_op_complete, NULL);
2237 	poll_threads();
2238 	CU_ASSERT(g_bserrno == 0);
2239 
2240 	memset(payload_read, 0xFF, payload_size);
2241 	iov_read[0].iov_base = payload_read;
2242 	iov_read[0].iov_len = cluster_size;
2243 	iov_read[1].iov_base = payload_read + cluster_size;
2244 	iov_read[1].iov_len = cluster_size * 4;
2245 	spdk_blob_io_readv(blob, channel, iov_read, 2, 0, pages_per_payload, blob_op_complete, NULL);
2246 	poll_threads();
2247 	CU_ASSERT(g_bserrno == 0);
2248 	CU_ASSERT(memcmp(payload_pattern, payload_read, payload_size) == 0);
2249 
2250 	/* 2. Write test. */
2251 	iov_write[0].iov_base = payload_read;
2252 	iov_write[0].iov_len = cluster_size * 2;
2253 	iov_write[1].iov_base = payload_read + cluster_size * 2;
2254 	iov_write[1].iov_len = cluster_size * 3;
2255 	spdk_blob_io_writev(blob, channel, iov_write, 2, 0, pages_per_payload, blob_op_complete, NULL);
2256 	poll_threads();
2257 	CU_ASSERT(g_bserrno == 0);
2258 
2259 	memset(payload_read, 0xFF, payload_size);
2260 	_blob_io_read_no_split(blob, channel, payload_read, 0, pages_per_payload, blob_op_complete, NULL);
2261 	poll_threads();
2262 	CU_ASSERT(g_bserrno == 0);
2263 	CU_ASSERT(memcmp(payload_pattern, payload_read, payload_size) == 0);
2264 
2265 	spdk_blob_close(blob, blob_op_complete, NULL);
2266 	CU_ASSERT(g_bserrno == 0);
2267 
2268 	spdk_bs_free_io_channel(channel);
2269 	poll_threads();
2270 
2271 	/* Unload the blob store */
2272 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2273 	poll_threads();
2274 	CU_ASSERT(g_bserrno == 0);
2275 	g_bs = NULL;
2276 	g_blob = NULL;
2277 	g_blobid = 0;
2278 
2279 	free(payload_read);
2280 	free(payload_write);
2281 	free(payload_pattern);
2282 }
2283 
2284 static void
2285 blob_unmap(void)
2286 {
2287 	struct spdk_blob_store *bs;
2288 	struct spdk_bs_dev *dev;
2289 	struct spdk_blob *blob;
2290 	struct spdk_io_channel *channel;
2291 	spdk_blob_id blobid;
2292 	struct spdk_blob_opts opts;
2293 	uint8_t payload[4096];
2294 	int i;
2295 
2296 	dev = init_dev();
2297 
2298 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
2299 	poll_threads();
2300 	CU_ASSERT(g_bserrno == 0);
2301 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2302 	bs = g_bs;
2303 
2304 	channel = spdk_bs_alloc_io_channel(bs);
2305 	CU_ASSERT(channel != NULL);
2306 
2307 	ut_spdk_blob_opts_init(&opts);
2308 	opts.num_clusters = 10;
2309 
2310 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
2311 	poll_threads();
2312 	CU_ASSERT(g_bserrno == 0);
2313 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2314 	blobid = g_blobid;
2315 
2316 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
2317 	poll_threads();
2318 	CU_ASSERT(g_bserrno == 0);
2319 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
2320 	blob = g_blob;
2321 
2322 	spdk_blob_resize(blob, 10, blob_op_complete, NULL);
2323 	poll_threads();
2324 	CU_ASSERT(g_bserrno == 0);
2325 
2326 	memset(payload, 0, sizeof(payload));
2327 	payload[0] = 0xFF;
2328 
2329 	/*
2330 	 * Set first byte of every cluster to 0xFF.
2331 	 * First cluster on device is reserved so let's start from cluster number 1
2332 	 */
2333 	for (i = 1; i < 11; i++) {
2334 		g_dev_buffer[i * SPDK_BLOB_OPTS_CLUSTER_SZ] = 0xFF;
2335 	}
2336 
2337 	/* Confirm writes */
2338 	for (i = 0; i < 10; i++) {
2339 		payload[0] = 0;
2340 		spdk_blob_io_read(blob, channel, &payload, i * SPDK_BLOB_OPTS_CLUSTER_SZ / 4096, 1,
2341 				  blob_op_complete, NULL);
2342 		poll_threads();
2343 		CU_ASSERT(g_bserrno == 0);
2344 		CU_ASSERT(payload[0] == 0xFF);
2345 	}
2346 
2347 	/* Mark some clusters as unallocated */
2348 	blob->active.clusters[1] = 0;
2349 	blob->active.clusters[2] = 0;
2350 	blob->active.clusters[3] = 0;
2351 	blob->active.clusters[6] = 0;
2352 	blob->active.clusters[8] = 0;
2353 
2354 	/* Unmap clusters by resizing to 0 */
2355 	spdk_blob_resize(blob, 0, blob_op_complete, NULL);
2356 	poll_threads();
2357 	CU_ASSERT(g_bserrno == 0);
2358 
2359 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
2360 	poll_threads();
2361 	CU_ASSERT(g_bserrno == 0);
2362 
2363 	/* Confirm that only 'allocated' clusters were unmapped */
2364 	for (i = 1; i < 11; i++) {
2365 		switch (i) {
2366 		case 2:
2367 		case 3:
2368 		case 4:
2369 		case 7:
2370 		case 9:
2371 			CU_ASSERT(g_dev_buffer[i * SPDK_BLOB_OPTS_CLUSTER_SZ] == 0xFF);
2372 			break;
2373 		default:
2374 			CU_ASSERT(g_dev_buffer[i * SPDK_BLOB_OPTS_CLUSTER_SZ] == 0);
2375 			break;
2376 		}
2377 	}
2378 
2379 	spdk_blob_close(blob, blob_op_complete, NULL);
2380 	poll_threads();
2381 	CU_ASSERT(g_bserrno == 0);
2382 
2383 	spdk_bs_free_io_channel(channel);
2384 	poll_threads();
2385 
2386 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2387 	poll_threads();
2388 	CU_ASSERT(g_bserrno == 0);
2389 	g_bs = NULL;
2390 }
2391 
2392 
2393 static void
2394 blob_iter(void)
2395 {
2396 	struct spdk_blob_store *bs;
2397 	struct spdk_bs_dev *dev;
2398 	struct spdk_blob *blob;
2399 	spdk_blob_id blobid;
2400 	struct spdk_blob_opts blob_opts;
2401 
2402 	dev = init_dev();
2403 
2404 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
2405 	poll_threads();
2406 	CU_ASSERT(g_bserrno == 0);
2407 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2408 	bs = g_bs;
2409 
2410 	spdk_bs_iter_first(bs, blob_op_with_handle_complete, NULL);
2411 	poll_threads();
2412 	CU_ASSERT(g_blob == NULL);
2413 	CU_ASSERT(g_bserrno == -ENOENT);
2414 
2415 	ut_spdk_blob_opts_init(&blob_opts);
2416 	spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL);
2417 	poll_threads();
2418 	CU_ASSERT(g_bserrno == 0);
2419 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2420 	blobid = g_blobid;
2421 
2422 	spdk_bs_iter_first(bs, blob_op_with_handle_complete, NULL);
2423 	poll_threads();
2424 	CU_ASSERT(g_blob != NULL);
2425 	CU_ASSERT(g_bserrno == 0);
2426 	blob = g_blob;
2427 	CU_ASSERT(spdk_blob_get_id(blob) == blobid);
2428 
2429 	spdk_bs_iter_next(bs, blob, blob_op_with_handle_complete, NULL);
2430 	poll_threads();
2431 	CU_ASSERT(g_blob == NULL);
2432 	CU_ASSERT(g_bserrno == -ENOENT);
2433 
2434 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2435 	poll_threads();
2436 	CU_ASSERT(g_bserrno == 0);
2437 	g_bs = NULL;
2438 }
2439 
2440 static void
2441 blob_xattr(void)
2442 {
2443 	struct spdk_blob_store *bs;
2444 	struct spdk_bs_dev *dev;
2445 	struct spdk_blob *blob;
2446 	struct spdk_blob_opts blob_opts;
2447 	spdk_blob_id blobid;
2448 	uint64_t length;
2449 	int rc;
2450 	const char *name1, *name2;
2451 	const void *value;
2452 	size_t value_len;
2453 	struct spdk_xattr_names *names;
2454 
2455 	dev = init_dev();
2456 
2457 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
2458 	poll_threads();
2459 	CU_ASSERT(g_bserrno == 0);
2460 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2461 	bs = g_bs;
2462 
2463 	ut_spdk_blob_opts_init(&blob_opts);
2464 	spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL);
2465 	poll_threads();
2466 	CU_ASSERT(g_bserrno == 0);
2467 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2468 	blobid = g_blobid;
2469 
2470 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
2471 	poll_threads();
2472 	CU_ASSERT(g_bserrno == 0);
2473 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
2474 	blob = g_blob;
2475 
2476 	/* Test that set_xattr fails if md_ro flag is set. */
2477 	blob->md_ro = true;
2478 	rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1);
2479 	CU_ASSERT(rc == -EPERM);
2480 
2481 	blob->md_ro = false;
2482 	rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1);
2483 	CU_ASSERT(rc == 0);
2484 
2485 	length = 2345;
2486 	rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
2487 	CU_ASSERT(rc == 0);
2488 
2489 	/* Overwrite "length" xattr. */
2490 	length = 3456;
2491 	rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
2492 	CU_ASSERT(rc == 0);
2493 
2494 	/* get_xattr should still work even if md_ro flag is set. */
2495 	value = NULL;
2496 	blob->md_ro = true;
2497 	rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len);
2498 	CU_ASSERT(rc == 0);
2499 	SPDK_CU_ASSERT_FATAL(value != NULL);
2500 	CU_ASSERT(*(uint64_t *)value == length);
2501 	CU_ASSERT(value_len == 8);
2502 	blob->md_ro = false;
2503 
2504 	rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len);
2505 	CU_ASSERT(rc == -ENOENT);
2506 
2507 	names = NULL;
2508 	rc = spdk_blob_get_xattr_names(blob, &names);
2509 	CU_ASSERT(rc == 0);
2510 	SPDK_CU_ASSERT_FATAL(names != NULL);
2511 	CU_ASSERT(spdk_xattr_names_get_count(names) == 2);
2512 	name1 = spdk_xattr_names_get_name(names, 0);
2513 	SPDK_CU_ASSERT_FATAL(name1 != NULL);
2514 	CU_ASSERT(!strcmp(name1, "name") || !strcmp(name1, "length"));
2515 	name2 = spdk_xattr_names_get_name(names, 1);
2516 	SPDK_CU_ASSERT_FATAL(name2 != NULL);
2517 	CU_ASSERT(!strcmp(name2, "name") || !strcmp(name2, "length"));
2518 	CU_ASSERT(strcmp(name1, name2));
2519 	spdk_xattr_names_free(names);
2520 
2521 	/* Confirm that remove_xattr fails if md_ro is set to true. */
2522 	blob->md_ro = true;
2523 	rc = spdk_blob_remove_xattr(blob, "name");
2524 	CU_ASSERT(rc == -EPERM);
2525 
2526 	blob->md_ro = false;
2527 	rc = spdk_blob_remove_xattr(blob, "name");
2528 	CU_ASSERT(rc == 0);
2529 
2530 	rc = spdk_blob_remove_xattr(blob, "foobar");
2531 	CU_ASSERT(rc == -ENOENT);
2532 
2533 	/* Set internal xattr */
2534 	length = 7898;
2535 	rc = _spdk_blob_set_xattr(blob, "internal", &length, sizeof(length), true);
2536 	CU_ASSERT(rc == 0);
2537 	rc = _spdk_blob_get_xattr_value(blob, "internal", &value, &value_len, true);
2538 	CU_ASSERT(rc == 0);
2539 	CU_ASSERT(*(uint64_t *)value == length);
2540 	/* try to get public xattr with same name */
2541 	rc = spdk_blob_get_xattr_value(blob, "internal", &value, &value_len);
2542 	CU_ASSERT(rc != 0);
2543 	rc = _spdk_blob_get_xattr_value(blob, "internal", &value, &value_len, false);
2544 	CU_ASSERT(rc != 0);
2545 	/* Check if SPDK_BLOB_INTERNAL_XATTR is set */
2546 	CU_ASSERT((blob->invalid_flags & SPDK_BLOB_INTERNAL_XATTR) ==
2547 		  SPDK_BLOB_INTERNAL_XATTR);
2548 
2549 	spdk_blob_close(blob, blob_op_complete, NULL);
2550 	poll_threads();
2551 
2552 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2553 	poll_threads();
2554 
2555 	/* Check if xattrs are persisted */
2556 	dev = init_dev();
2557 
2558 	spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL);
2559 	poll_threads();
2560 	CU_ASSERT(g_bserrno == 0);
2561 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2562 
2563 	bs = g_bs;
2564 
2565 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
2566 	poll_threads();
2567 	CU_ASSERT(g_bserrno == 0);
2568 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
2569 	blob = g_blob;
2570 
2571 	rc = _spdk_blob_get_xattr_value(blob, "internal", &value, &value_len, true);
2572 	CU_ASSERT(rc == 0);
2573 	CU_ASSERT(*(uint64_t *)value == length);
2574 
2575 	/* try to get internal xattr trough public call */
2576 	rc = spdk_blob_get_xattr_value(blob, "internal", &value, &value_len);
2577 	CU_ASSERT(rc != 0);
2578 
2579 	rc = _spdk_blob_remove_xattr(blob, "internal", true);
2580 	CU_ASSERT(rc == 0);
2581 
2582 	CU_ASSERT((blob->invalid_flags & SPDK_BLOB_INTERNAL_XATTR) == 0);
2583 
2584 	spdk_blob_close(blob, blob_op_complete, NULL);
2585 	poll_threads();
2586 	CU_ASSERT(g_bserrno == 0);
2587 
2588 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2589 	poll_threads();
2590 	CU_ASSERT(g_bserrno == 0);
2591 	g_bs = NULL;
2592 }
2593 
2594 static void
2595 bs_load(void)
2596 {
2597 	struct spdk_bs_dev *dev;
2598 	spdk_blob_id blobid;
2599 	struct spdk_blob *blob;
2600 	struct spdk_bs_super_block *super_block;
2601 	uint64_t length;
2602 	int rc;
2603 	const void *value;
2604 	size_t value_len;
2605 	struct spdk_bs_opts opts;
2606 	struct spdk_blob_opts blob_opts;
2607 
2608 	dev = init_dev();
2609 	spdk_bs_opts_init(&opts);
2610 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
2611 
2612 	/* Initialize a new blob store */
2613 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2614 	poll_threads();
2615 	CU_ASSERT(g_bserrno == 0);
2616 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2617 
2618 	/* Try to open a blobid that does not exist */
2619 	spdk_bs_open_blob(g_bs, 0, blob_op_with_handle_complete, NULL);
2620 	poll_threads();
2621 	CU_ASSERT(g_bserrno == -ENOENT);
2622 	CU_ASSERT(g_blob == NULL);
2623 
2624 	/* Create a blob */
2625 	ut_spdk_blob_opts_init(&blob_opts);
2626 	spdk_bs_create_blob_ext(g_bs, &blob_opts, blob_op_with_id_complete, NULL);
2627 	poll_threads();
2628 	CU_ASSERT(g_bserrno == 0);
2629 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2630 	blobid = g_blobid;
2631 
2632 	spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
2633 	poll_threads();
2634 	CU_ASSERT(g_bserrno == 0);
2635 	CU_ASSERT(g_blob != NULL);
2636 	blob = g_blob;
2637 
2638 	/* Try again to open valid blob but without the upper bit set */
2639 	spdk_bs_open_blob(g_bs, blobid & 0xFFFFFFFF, blob_op_with_handle_complete, NULL);
2640 	poll_threads();
2641 	CU_ASSERT(g_bserrno == -ENOENT);
2642 	CU_ASSERT(g_blob == NULL);
2643 
2644 	/* Set some xattrs */
2645 	rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1);
2646 	CU_ASSERT(rc == 0);
2647 
2648 	length = 2345;
2649 	rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
2650 	CU_ASSERT(rc == 0);
2651 
2652 	/* Resize the blob */
2653 	spdk_blob_resize(blob, 10, blob_op_complete, NULL);
2654 	poll_threads();
2655 	CU_ASSERT(g_bserrno == 0);
2656 
2657 	spdk_blob_close(blob, blob_op_complete, NULL);
2658 	poll_threads();
2659 	CU_ASSERT(g_bserrno == 0);
2660 	blob = NULL;
2661 	g_blob = NULL;
2662 	g_blobid = SPDK_BLOBID_INVALID;
2663 
2664 	/* Unload the blob store */
2665 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2666 	poll_threads();
2667 	CU_ASSERT(g_bserrno == 0);
2668 	g_bs = NULL;
2669 	g_blob = NULL;
2670 	g_blobid = 0;
2671 
2672 	super_block = (struct spdk_bs_super_block *)g_dev_buffer;
2673 	CU_ASSERT(super_block->clean == 1);
2674 
2675 	/* Load should fail for device with an unsupported blocklen */
2676 	dev = init_dev();
2677 	dev->blocklen = SPDK_BS_PAGE_SIZE * 2;
2678 	spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL);
2679 	poll_threads();
2680 	CU_ASSERT(g_bserrno == -EINVAL);
2681 
2682 	/* Load should when max_md_ops is set to zero */
2683 	dev = init_dev();
2684 	spdk_bs_opts_init(&opts);
2685 	opts.max_md_ops = 0;
2686 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2687 	poll_threads();
2688 	CU_ASSERT(g_bserrno == -EINVAL);
2689 
2690 	/* Load should when max_channel_ops is set to zero */
2691 	dev = init_dev();
2692 	spdk_bs_opts_init(&opts);
2693 	opts.max_channel_ops = 0;
2694 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2695 	poll_threads();
2696 	CU_ASSERT(g_bserrno == -EINVAL);
2697 
2698 	/* Load an existing blob store */
2699 	dev = init_dev();
2700 	spdk_bs_opts_init(&opts);
2701 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
2702 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2703 	poll_threads();
2704 	CU_ASSERT(g_bserrno == 0);
2705 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2706 
2707 	super_block = (struct spdk_bs_super_block *)g_dev_buffer;
2708 	CU_ASSERT(super_block->clean == 1);
2709 	CU_ASSERT(super_block->size == dev->blockcnt * dev->blocklen);
2710 
2711 	spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
2712 	poll_threads();
2713 	CU_ASSERT(g_bserrno == 0);
2714 	CU_ASSERT(g_blob != NULL);
2715 	blob = g_blob;
2716 
2717 	/* Verify that blobstore is marked dirty after first metadata sync */
2718 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
2719 	CU_ASSERT(super_block->clean == 1);
2720 
2721 	/* Get the xattrs */
2722 	value = NULL;
2723 	rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len);
2724 	CU_ASSERT(rc == 0);
2725 	SPDK_CU_ASSERT_FATAL(value != NULL);
2726 	CU_ASSERT(*(uint64_t *)value == length);
2727 	CU_ASSERT(value_len == 8);
2728 
2729 	rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len);
2730 	CU_ASSERT(rc == -ENOENT);
2731 
2732 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10);
2733 
2734 	spdk_blob_close(blob, blob_op_complete, NULL);
2735 	poll_threads();
2736 	CU_ASSERT(g_bserrno == 0);
2737 	blob = NULL;
2738 	g_blob = NULL;
2739 
2740 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2741 	poll_threads();
2742 	CU_ASSERT(g_bserrno == 0);
2743 	g_bs = NULL;
2744 
2745 	/* Load should fail: bdev size < saved size */
2746 	dev = init_dev();
2747 	dev->blockcnt /= 2;
2748 
2749 	spdk_bs_opts_init(&opts);
2750 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
2751 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2752 	poll_threads();
2753 
2754 	CU_ASSERT(g_bserrno == -EILSEQ);
2755 
2756 	/* Load should succeed: bdev size > saved size */
2757 	dev = init_dev();
2758 	dev->blockcnt *= 4;
2759 
2760 	spdk_bs_opts_init(&opts);
2761 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
2762 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2763 	poll_threads();
2764 
2765 	CU_ASSERT(g_bserrno == 0);
2766 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2767 	poll_threads();
2768 
2769 
2770 	/* Test compatibility mode */
2771 
2772 	dev = init_dev();
2773 	super_block->size = 0;
2774 	super_block->crc = _spdk_blob_md_page_calc_crc(super_block);
2775 
2776 	spdk_bs_opts_init(&opts);
2777 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
2778 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2779 	poll_threads();
2780 	CU_ASSERT(g_bserrno == 0);
2781 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2782 
2783 	/* Create a blob */
2784 	spdk_bs_create_blob_ext(g_bs, &blob_opts, blob_op_with_id_complete, NULL);
2785 	poll_threads();
2786 	CU_ASSERT(g_bserrno == 0);
2787 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2788 
2789 	/* Blobstore should update number of blocks in super_block */
2790 	CU_ASSERT(super_block->size == dev->blockcnt * dev->blocklen);
2791 	CU_ASSERT(super_block->clean == 0);
2792 
2793 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2794 	poll_threads();
2795 	CU_ASSERT(g_bserrno == 0);
2796 	CU_ASSERT(super_block->clean == 1);
2797 	g_bs = NULL;
2798 
2799 }
2800 
2801 static void
2802 bs_load_pending_removal(void)
2803 {
2804 	struct spdk_blob_store *bs;
2805 	struct spdk_bs_dev *dev;
2806 	struct spdk_blob_opts opts;
2807 	struct spdk_blob *blob, *snapshot;
2808 	spdk_blob_id blobid, snapshotid;
2809 	const void *value;
2810 	size_t value_len;
2811 	int rc;
2812 
2813 	dev = init_dev();
2814 
2815 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
2816 	poll_threads();
2817 	CU_ASSERT(g_bserrno == 0);
2818 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2819 	bs = g_bs;
2820 
2821 	/* Create blob */
2822 	ut_spdk_blob_opts_init(&opts);
2823 	opts.num_clusters = 10;
2824 
2825 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
2826 	poll_threads();
2827 	CU_ASSERT(g_bserrno == 0);
2828 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2829 	blobid = g_blobid;
2830 
2831 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
2832 	poll_threads();
2833 	CU_ASSERT(g_bserrno == 0);
2834 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
2835 	blob = g_blob;
2836 
2837 	/* Create snapshot */
2838 	spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL);
2839 	poll_threads();
2840 	CU_ASSERT(g_bserrno == 0);
2841 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2842 	snapshotid = g_blobid;
2843 
2844 	spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL);
2845 	poll_threads();
2846 	CU_ASSERT(g_bserrno == 0);
2847 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
2848 	snapshot = g_blob;
2849 
2850 	/* Set SNAPSHOT_PENDING_REMOVAL xattr */
2851 	snapshot->md_ro = false;
2852 	rc = _spdk_blob_set_xattr(snapshot, SNAPSHOT_PENDING_REMOVAL, &blobid, sizeof(spdk_blob_id), true);
2853 	CU_ASSERT(rc == 0);
2854 	snapshot->md_ro = true;
2855 
2856 	spdk_blob_close(snapshot, blob_op_complete, NULL);
2857 	poll_threads();
2858 	CU_ASSERT(g_bserrno == 0);
2859 
2860 	spdk_blob_close(blob, blob_op_complete, NULL);
2861 	poll_threads();
2862 	CU_ASSERT(g_bserrno == 0);
2863 
2864 	/* Reload blobstore */
2865 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2866 	poll_threads();
2867 	CU_ASSERT(g_bserrno == 0);
2868 	g_bs = NULL;
2869 
2870 	dev = init_dev();
2871 	spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL);
2872 	poll_threads();
2873 	CU_ASSERT(g_bserrno == 0);
2874 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2875 	bs = g_bs;
2876 
2877 	/* Snapshot should not be removed as blob is still pointing to it */
2878 	spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL);
2879 	poll_threads();
2880 	CU_ASSERT(g_bserrno == 0);
2881 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
2882 	snapshot = g_blob;
2883 
2884 	/* SNAPSHOT_PENDING_REMOVAL xattr should be removed during load */
2885 	rc = spdk_blob_get_xattr_value(snapshot, SNAPSHOT_PENDING_REMOVAL, &value, &value_len);
2886 	CU_ASSERT(rc != 0);
2887 
2888 	/* Set SNAPSHOT_PENDING_REMOVAL xattr again */
2889 	snapshot->md_ro = false;
2890 	rc = _spdk_blob_set_xattr(snapshot, SNAPSHOT_PENDING_REMOVAL, &blobid, sizeof(spdk_blob_id), true);
2891 	CU_ASSERT(rc == 0);
2892 	snapshot->md_ro = true;
2893 
2894 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
2895 	poll_threads();
2896 	CU_ASSERT(g_bserrno == 0);
2897 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
2898 	blob = g_blob;
2899 
2900 	/* Remove parent_id from blob by removing BLOB_SNAPSHOT xattr */
2901 	_spdk_blob_remove_xattr(blob, BLOB_SNAPSHOT, true);
2902 
2903 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
2904 	poll_threads();
2905 	CU_ASSERT(g_bserrno == 0);
2906 
2907 	spdk_blob_close(snapshot, blob_op_complete, NULL);
2908 	poll_threads();
2909 	CU_ASSERT(g_bserrno == 0);
2910 
2911 	spdk_blob_close(blob, blob_op_complete, NULL);
2912 	poll_threads();
2913 	CU_ASSERT(g_bserrno == 0);
2914 
2915 	/* Reload blobstore */
2916 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2917 	poll_threads();
2918 	CU_ASSERT(g_bserrno == 0);
2919 	g_bs = NULL;
2920 
2921 	dev = init_dev();
2922 	spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL);
2923 	poll_threads();
2924 	CU_ASSERT(g_bserrno == 0);
2925 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2926 	bs = g_bs;
2927 
2928 	/* Snapshot should be removed as blob is not pointing to it anymore */
2929 	spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL);
2930 	poll_threads();
2931 	CU_ASSERT(g_bserrno != 0);
2932 
2933 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2934 	poll_threads();
2935 	CU_ASSERT(g_bserrno == 0);
2936 	g_bs = NULL;
2937 }
2938 
2939 static void
2940 bs_load_custom_cluster_size(void)
2941 {
2942 	struct spdk_bs_dev *dev;
2943 	struct spdk_bs_super_block *super_block;
2944 	struct spdk_bs_opts opts;
2945 	uint32_t custom_cluster_size = 4194304; /* 4MiB */
2946 	uint32_t cluster_sz;
2947 	uint64_t total_clusters;
2948 
2949 	dev = init_dev();
2950 	spdk_bs_opts_init(&opts);
2951 	opts.cluster_sz = custom_cluster_size;
2952 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
2953 
2954 	/* Initialize a new blob store */
2955 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2956 	poll_threads();
2957 	CU_ASSERT(g_bserrno == 0);
2958 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2959 	cluster_sz = g_bs->cluster_sz;
2960 	total_clusters = g_bs->total_clusters;
2961 
2962 	/* Unload the blob store */
2963 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2964 	poll_threads();
2965 	CU_ASSERT(g_bserrno == 0);
2966 	g_bs = NULL;
2967 	g_blob = NULL;
2968 	g_blobid = 0;
2969 
2970 	super_block = (struct spdk_bs_super_block *)g_dev_buffer;
2971 	CU_ASSERT(super_block->clean == 1);
2972 
2973 	/* Load an existing blob store */
2974 	dev = init_dev();
2975 	spdk_bs_opts_init(&opts);
2976 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
2977 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2978 	poll_threads();
2979 	CU_ASSERT(g_bserrno == 0);
2980 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2981 	/* Compare cluster size and number to one after initialization */
2982 	CU_ASSERT(cluster_sz == g_bs->cluster_sz);
2983 	CU_ASSERT(total_clusters == g_bs->total_clusters);
2984 
2985 	super_block = (struct spdk_bs_super_block *)g_dev_buffer;
2986 	CU_ASSERT(super_block->clean == 1);
2987 	CU_ASSERT(super_block->size == dev->blockcnt * dev->blocklen);
2988 
2989 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2990 	poll_threads();
2991 	CU_ASSERT(g_bserrno == 0);
2992 	CU_ASSERT(super_block->clean == 1);
2993 	g_bs = NULL;
2994 }
2995 
2996 static void
2997 bs_type(void)
2998 {
2999 	struct spdk_bs_dev *dev;
3000 	struct spdk_bs_opts opts;
3001 
3002 	dev = init_dev();
3003 	spdk_bs_opts_init(&opts);
3004 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
3005 
3006 	/* Initialize a new blob store */
3007 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
3008 	poll_threads();
3009 	CU_ASSERT(g_bserrno == 0);
3010 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3011 
3012 	/* Unload the blob store */
3013 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3014 	poll_threads();
3015 	CU_ASSERT(g_bserrno == 0);
3016 	g_bs = NULL;
3017 	g_blob = NULL;
3018 	g_blobid = 0;
3019 
3020 	/* Load non existing blobstore type */
3021 	dev = init_dev();
3022 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "NONEXISTING");
3023 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
3024 	poll_threads();
3025 	CU_ASSERT(g_bserrno != 0);
3026 
3027 	/* Load with empty blobstore type */
3028 	dev = init_dev();
3029 	memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype));
3030 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
3031 	poll_threads();
3032 	CU_ASSERT(g_bserrno == 0);
3033 
3034 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3035 	poll_threads();
3036 	CU_ASSERT(g_bserrno == 0);
3037 	g_bs = NULL;
3038 
3039 	/* Initialize a new blob store with empty bstype */
3040 	dev = init_dev();
3041 	memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype));
3042 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
3043 	poll_threads();
3044 	CU_ASSERT(g_bserrno == 0);
3045 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3046 
3047 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3048 	poll_threads();
3049 	CU_ASSERT(g_bserrno == 0);
3050 	g_bs = NULL;
3051 
3052 	/* Load non existing blobstore type */
3053 	dev = init_dev();
3054 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "NONEXISTING");
3055 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
3056 	poll_threads();
3057 	CU_ASSERT(g_bserrno != 0);
3058 
3059 	/* Load with empty blobstore type */
3060 	dev = init_dev();
3061 	memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype));
3062 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
3063 	poll_threads();
3064 	CU_ASSERT(g_bserrno == 0);
3065 
3066 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3067 	poll_threads();
3068 	CU_ASSERT(g_bserrno == 0);
3069 	g_bs = NULL;
3070 }
3071 
3072 static void
3073 bs_super_block(void)
3074 {
3075 	struct spdk_bs_dev *dev;
3076 	struct spdk_bs_super_block *super_block;
3077 	struct spdk_bs_opts opts;
3078 	struct spdk_bs_super_block_ver1 super_block_v1;
3079 
3080 	dev = init_dev();
3081 	spdk_bs_opts_init(&opts);
3082 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
3083 
3084 	/* Initialize a new blob store */
3085 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
3086 	poll_threads();
3087 	CU_ASSERT(g_bserrno == 0);
3088 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3089 
3090 	/* Unload the blob store */
3091 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3092 	poll_threads();
3093 	CU_ASSERT(g_bserrno == 0);
3094 	g_bs = NULL;
3095 	g_blob = NULL;
3096 	g_blobid = 0;
3097 
3098 	/* Load an existing blob store with version newer than supported */
3099 	super_block = (struct spdk_bs_super_block *)g_dev_buffer;
3100 	super_block->version++;
3101 
3102 	dev = init_dev();
3103 	memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype));
3104 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
3105 	poll_threads();
3106 	CU_ASSERT(g_bserrno != 0);
3107 
3108 	/* Create a new blob store with super block version 1 */
3109 	dev = init_dev();
3110 	super_block_v1.version = 1;
3111 	memcpy(super_block_v1.signature, "SPDKBLOB", sizeof(super_block_v1.signature));
3112 	super_block_v1.length = 0x1000;
3113 	super_block_v1.clean = 1;
3114 	super_block_v1.super_blob = 0xFFFFFFFFFFFFFFFF;
3115 	super_block_v1.cluster_size = 0x100000;
3116 	super_block_v1.used_page_mask_start = 0x01;
3117 	super_block_v1.used_page_mask_len = 0x01;
3118 	super_block_v1.used_cluster_mask_start = 0x02;
3119 	super_block_v1.used_cluster_mask_len = 0x01;
3120 	super_block_v1.md_start = 0x03;
3121 	super_block_v1.md_len = 0x40;
3122 	memset(super_block_v1.reserved, 0, 4036);
3123 	super_block_v1.crc = _spdk_blob_md_page_calc_crc(&super_block_v1);
3124 	memcpy(g_dev_buffer, &super_block_v1, sizeof(struct spdk_bs_super_block_ver1));
3125 
3126 	memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype));
3127 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
3128 	poll_threads();
3129 	CU_ASSERT(g_bserrno == 0);
3130 
3131 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3132 	poll_threads();
3133 	CU_ASSERT(g_bserrno == 0);
3134 	g_bs = NULL;
3135 }
3136 
3137 /*
3138  * Create a blobstore and then unload it.
3139  */
3140 static void
3141 bs_unload(void)
3142 {
3143 	struct spdk_bs_dev *dev;
3144 	struct spdk_blob_store *bs;
3145 	spdk_blob_id blobid;
3146 	struct spdk_blob *blob;
3147 	struct spdk_blob_opts blob_opts;
3148 
3149 	dev = init_dev();
3150 
3151 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
3152 	poll_threads();
3153 	CU_ASSERT(g_bserrno == 0);
3154 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3155 	bs = g_bs;
3156 
3157 	/* Create a blob and open it. */
3158 	g_bserrno = -1;
3159 	ut_spdk_blob_opts_init(&blob_opts);
3160 	spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL);
3161 	poll_threads();
3162 	CU_ASSERT(g_bserrno == 0);
3163 	CU_ASSERT(g_blobid > 0);
3164 	blobid = g_blobid;
3165 
3166 	g_bserrno = -1;
3167 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
3168 	poll_threads();
3169 	CU_ASSERT(g_bserrno == 0);
3170 	CU_ASSERT(g_blob != NULL);
3171 	blob = g_blob;
3172 
3173 	/* Try to unload blobstore, should fail with open blob */
3174 	g_bserrno = -1;
3175 	spdk_bs_unload(bs, bs_op_complete, NULL);
3176 	poll_threads();
3177 	CU_ASSERT(g_bserrno == -EBUSY);
3178 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3179 
3180 	/* Close the blob, then successfully unload blobstore */
3181 	g_bserrno = -1;
3182 	spdk_blob_close(blob, blob_op_complete, NULL);
3183 	poll_threads();
3184 	CU_ASSERT(g_bserrno == 0);
3185 
3186 	g_bserrno = -1;
3187 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3188 	poll_threads();
3189 	CU_ASSERT(g_bserrno == 0);
3190 	g_bs = NULL;
3191 }
3192 
3193 /*
3194  * Create a blobstore with a cluster size different than the default, and ensure it is
3195  *  persisted.
3196  */
3197 static void
3198 bs_cluster_sz(void)
3199 {
3200 	struct spdk_bs_dev *dev;
3201 	struct spdk_bs_opts opts;
3202 	uint32_t cluster_sz;
3203 
3204 	/* Set cluster size to zero */
3205 	dev = init_dev();
3206 	spdk_bs_opts_init(&opts);
3207 	opts.cluster_sz = 0;
3208 
3209 	/* Initialize a new blob store */
3210 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
3211 	poll_threads();
3212 	CU_ASSERT(g_bserrno == -EINVAL);
3213 	SPDK_CU_ASSERT_FATAL(g_bs == NULL);
3214 
3215 	/*
3216 	 * Set cluster size to blobstore page size,
3217 	 * to work it is required to be at least twice the blobstore page size.
3218 	 */
3219 	dev = init_dev();
3220 	spdk_bs_opts_init(&opts);
3221 	opts.cluster_sz = SPDK_BS_PAGE_SIZE;
3222 
3223 	/* Initialize a new blob store */
3224 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
3225 	poll_threads();
3226 	CU_ASSERT(g_bserrno == -ENOMEM);
3227 	SPDK_CU_ASSERT_FATAL(g_bs == NULL);
3228 
3229 	/*
3230 	 * Set cluster size to lower than page size,
3231 	 * to work it is required to be at least twice the blobstore page size.
3232 	 */
3233 	dev = init_dev();
3234 	spdk_bs_opts_init(&opts);
3235 	opts.cluster_sz = SPDK_BS_PAGE_SIZE - 1;
3236 
3237 	/* Initialize a new blob store */
3238 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
3239 	poll_threads();
3240 	CU_ASSERT(g_bserrno == -EINVAL);
3241 	SPDK_CU_ASSERT_FATAL(g_bs == NULL);
3242 
3243 	/* Set cluster size to twice the default */
3244 	dev = init_dev();
3245 	spdk_bs_opts_init(&opts);
3246 	opts.cluster_sz *= 2;
3247 	cluster_sz = opts.cluster_sz;
3248 
3249 	/* Initialize a new blob store */
3250 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
3251 	poll_threads();
3252 	CU_ASSERT(g_bserrno == 0);
3253 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3254 
3255 	CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz);
3256 
3257 	/* Unload the blob store */
3258 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3259 	poll_threads();
3260 	CU_ASSERT(g_bserrno == 0);
3261 	g_bs = NULL;
3262 	g_blob = NULL;
3263 	g_blobid = 0;
3264 
3265 	dev = init_dev();
3266 	/* Load an existing blob store */
3267 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
3268 	poll_threads();
3269 	CU_ASSERT(g_bserrno == 0);
3270 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3271 
3272 	CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz);
3273 
3274 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3275 	poll_threads();
3276 	CU_ASSERT(g_bserrno == 0);
3277 	g_bs = NULL;
3278 }
3279 
3280 /*
3281  * Create a blobstore, reload it and ensure total usable cluster count
3282  *  stays the same.
3283  */
3284 static void
3285 bs_usable_clusters(void)
3286 {
3287 	struct spdk_bs_dev *dev;
3288 	struct spdk_bs_opts opts;
3289 	struct spdk_blob_opts blob_opts;
3290 	uint32_t clusters;
3291 	int i;
3292 
3293 	/* Init blobstore */
3294 	dev = init_dev();
3295 	spdk_bs_opts_init(&opts);
3296 
3297 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
3298 	poll_threads();
3299 	CU_ASSERT(g_bserrno == 0);
3300 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3301 
3302 	clusters = spdk_bs_total_data_cluster_count(g_bs);
3303 
3304 	/* Unload the blob store */
3305 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3306 	poll_threads();
3307 	CU_ASSERT(g_bserrno == 0);
3308 	g_bs = NULL;
3309 
3310 	dev = init_dev();
3311 	/* Load an existing blob store */
3312 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
3313 	poll_threads();
3314 	CU_ASSERT(g_bserrno == 0);
3315 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3316 
3317 	CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters);
3318 	ut_spdk_blob_opts_init(&blob_opts);
3319 
3320 	/* Create and resize blobs to make sure that useable cluster count won't change */
3321 	for (i = 0; i < 4; i++) {
3322 		g_bserrno = -1;
3323 		g_blobid = SPDK_BLOBID_INVALID;
3324 		spdk_bs_create_blob_ext(g_bs, &blob_opts, blob_op_with_id_complete, NULL);
3325 		poll_threads();
3326 		CU_ASSERT(g_bserrno == 0);
3327 		CU_ASSERT(g_blobid !=  SPDK_BLOBID_INVALID);
3328 
3329 		g_bserrno = -1;
3330 		g_blob = NULL;
3331 		spdk_bs_open_blob(g_bs, g_blobid, blob_op_with_handle_complete, NULL);
3332 		poll_threads();
3333 		CU_ASSERT(g_bserrno == 0);
3334 		CU_ASSERT(g_blob !=  NULL);
3335 
3336 		spdk_blob_resize(g_blob, 10, blob_op_complete, NULL);
3337 		poll_threads();
3338 		CU_ASSERT(g_bserrno == 0);
3339 
3340 		g_bserrno = -1;
3341 		spdk_blob_close(g_blob, blob_op_complete, NULL);
3342 		poll_threads();
3343 		CU_ASSERT(g_bserrno == 0);
3344 
3345 		CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters);
3346 	}
3347 
3348 	/* Reload the blob store to make sure that nothing changed */
3349 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3350 	poll_threads();
3351 	CU_ASSERT(g_bserrno == 0);
3352 	g_bs = NULL;
3353 
3354 	dev = init_dev();
3355 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
3356 	poll_threads();
3357 	CU_ASSERT(g_bserrno == 0);
3358 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3359 
3360 	CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters);
3361 
3362 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3363 	poll_threads();
3364 	CU_ASSERT(g_bserrno == 0);
3365 	g_bs = NULL;
3366 }
3367 
3368 /*
3369  * Test resizing of the metadata blob.  This requires creating enough blobs
3370  *  so that one cluster is not enough to fit the metadata for those blobs.
3371  *  To induce this condition to happen more quickly, we reduce the cluster
3372  *  size to 16KB, which means only 4 4KB blob metadata pages can fit.
3373  */
3374 static void
3375 bs_resize_md(void)
3376 {
3377 	const int CLUSTER_PAGE_COUNT = 4;
3378 	const int NUM_BLOBS = CLUSTER_PAGE_COUNT * 4;
3379 	struct spdk_bs_dev *dev;
3380 	struct spdk_bs_opts opts;
3381 	struct spdk_blob_opts blob_opts;
3382 	uint32_t cluster_sz;
3383 	spdk_blob_id blobids[NUM_BLOBS];
3384 	int i;
3385 
3386 
3387 	dev = init_dev();
3388 	spdk_bs_opts_init(&opts);
3389 	opts.cluster_sz = CLUSTER_PAGE_COUNT * 4096;
3390 	cluster_sz = opts.cluster_sz;
3391 
3392 	/* Initialize a new blob store */
3393 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
3394 	poll_threads();
3395 	CU_ASSERT(g_bserrno == 0);
3396 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3397 
3398 	CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz);
3399 
3400 	ut_spdk_blob_opts_init(&blob_opts);
3401 
3402 	for (i = 0; i < NUM_BLOBS; i++) {
3403 		g_bserrno = -1;
3404 		g_blobid = SPDK_BLOBID_INVALID;
3405 		spdk_bs_create_blob_ext(g_bs, &blob_opts, blob_op_with_id_complete, NULL);
3406 		poll_threads();
3407 		CU_ASSERT(g_bserrno == 0);
3408 		CU_ASSERT(g_blobid !=  SPDK_BLOBID_INVALID);
3409 		blobids[i] = g_blobid;
3410 	}
3411 
3412 	/* Unload the blob store */
3413 	g_bserrno = -1;
3414 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3415 	poll_threads();
3416 	CU_ASSERT(g_bserrno == 0);
3417 
3418 	/* Load an existing blob store */
3419 	g_bserrno = -1;
3420 	g_bs = NULL;
3421 	dev = init_dev();
3422 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
3423 	poll_threads();
3424 	CU_ASSERT(g_bserrno == 0);
3425 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3426 
3427 	CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz);
3428 
3429 	for (i = 0; i < NUM_BLOBS; i++) {
3430 		g_bserrno = -1;
3431 		g_blob = NULL;
3432 		spdk_bs_open_blob(g_bs, blobids[i], blob_op_with_handle_complete, NULL);
3433 		poll_threads();
3434 		CU_ASSERT(g_bserrno == 0);
3435 		CU_ASSERT(g_blob !=  NULL);
3436 		g_bserrno = -1;
3437 		spdk_blob_close(g_blob, blob_op_complete, NULL);
3438 		poll_threads();
3439 		CU_ASSERT(g_bserrno == 0);
3440 	}
3441 
3442 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3443 	poll_threads();
3444 	CU_ASSERT(g_bserrno == 0);
3445 	g_bs = NULL;
3446 }
3447 
3448 static void
3449 bs_destroy(void)
3450 {
3451 	struct spdk_bs_dev *dev;
3452 	struct spdk_bs_opts opts;
3453 
3454 	/* Initialize a new blob store */
3455 	dev = init_dev();
3456 	spdk_bs_opts_init(&opts);
3457 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
3458 	poll_threads();
3459 	CU_ASSERT(g_bserrno == 0);
3460 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3461 
3462 	/* Destroy the blob store */
3463 	g_bserrno = -1;
3464 	spdk_bs_destroy(g_bs, bs_op_complete, NULL);
3465 	poll_threads();
3466 	CU_ASSERT(g_bserrno == 0);
3467 
3468 	/* Loading an non-existent blob store should fail. */
3469 	g_bs = NULL;
3470 	dev = init_dev();
3471 
3472 	g_bserrno = 0;
3473 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
3474 	poll_threads();
3475 	CU_ASSERT(g_bserrno != 0);
3476 }
3477 
3478 /* Try to hit all of the corner cases associated with serializing
3479  * a blob to disk
3480  */
3481 static void
3482 blob_serialize(void)
3483 {
3484 	struct spdk_bs_dev *dev;
3485 	struct spdk_bs_opts opts;
3486 	struct spdk_blob_store *bs;
3487 	struct spdk_blob_opts blob_opts;
3488 	spdk_blob_id blobid[2];
3489 	struct spdk_blob *blob[2];
3490 	uint64_t i;
3491 	char *value;
3492 	int rc;
3493 
3494 	dev = init_dev();
3495 
3496 	/* Initialize a new blobstore with very small clusters */
3497 	spdk_bs_opts_init(&opts);
3498 	opts.cluster_sz = dev->blocklen * 8;
3499 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
3500 	poll_threads();
3501 	CU_ASSERT(g_bserrno == 0);
3502 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3503 	bs = g_bs;
3504 	ut_spdk_blob_opts_init(&blob_opts);
3505 
3506 	/* Create and open two blobs */
3507 	for (i = 0; i < 2; i++) {
3508 		spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL);
3509 		poll_threads();
3510 		CU_ASSERT(g_bserrno == 0);
3511 		CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3512 		blobid[i] = g_blobid;
3513 
3514 		/* Open a blob */
3515 		spdk_bs_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL);
3516 		poll_threads();
3517 		CU_ASSERT(g_bserrno == 0);
3518 		CU_ASSERT(g_blob != NULL);
3519 		blob[i] = g_blob;
3520 
3521 		/* Set a fairly large xattr on both blobs to eat up
3522 		 * metadata space
3523 		 */
3524 		value = calloc(dev->blocklen - 64, sizeof(char));
3525 		SPDK_CU_ASSERT_FATAL(value != NULL);
3526 		memset(value, i, dev->blocklen / 2);
3527 		rc = spdk_blob_set_xattr(blob[i], "name", value, dev->blocklen - 64);
3528 		CU_ASSERT(rc == 0);
3529 		free(value);
3530 	}
3531 
3532 	/* Resize the blobs, alternating 1 cluster at a time.
3533 	 * This thwarts run length encoding and will cause spill
3534 	 * over of the extents.
3535 	 */
3536 	for (i = 0; i < 6; i++) {
3537 		spdk_blob_resize(blob[i % 2], (i / 2) + 1, blob_op_complete, NULL);
3538 		poll_threads();
3539 		CU_ASSERT(g_bserrno == 0);
3540 	}
3541 
3542 	for (i = 0; i < 2; i++) {
3543 		spdk_blob_sync_md(blob[i], blob_op_complete, NULL);
3544 		poll_threads();
3545 		CU_ASSERT(g_bserrno == 0);
3546 	}
3547 
3548 	/* Close the blobs */
3549 	for (i = 0; i < 2; i++) {
3550 		spdk_blob_close(blob[i], blob_op_complete, NULL);
3551 		poll_threads();
3552 		CU_ASSERT(g_bserrno == 0);
3553 	}
3554 
3555 	/* Unload the blobstore */
3556 	spdk_bs_unload(bs, bs_op_complete, NULL);
3557 	poll_threads();
3558 	CU_ASSERT(g_bserrno == 0);
3559 	g_bs = NULL;
3560 	g_blob = NULL;
3561 	g_blobid = 0;
3562 	bs = NULL;
3563 
3564 	dev = init_dev();
3565 	/* Load an existing blob store */
3566 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
3567 	poll_threads();
3568 	CU_ASSERT(g_bserrno == 0);
3569 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3570 	bs = g_bs;
3571 
3572 	for (i = 0; i < 2; i++) {
3573 		blob[i] = NULL;
3574 
3575 		spdk_bs_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL);
3576 		poll_threads();
3577 		CU_ASSERT(g_bserrno == 0);
3578 		CU_ASSERT(g_blob != NULL);
3579 		blob[i] = g_blob;
3580 
3581 		CU_ASSERT(spdk_blob_get_num_clusters(blob[i]) == 3);
3582 
3583 		spdk_blob_close(blob[i], blob_op_complete, NULL);
3584 		poll_threads();
3585 		CU_ASSERT(g_bserrno == 0);
3586 	}
3587 
3588 	spdk_bs_unload(bs, bs_op_complete, NULL);
3589 	poll_threads();
3590 	CU_ASSERT(g_bserrno == 0);
3591 	g_bs = NULL;
3592 }
3593 
3594 static void
3595 blob_crc(void)
3596 {
3597 	struct spdk_blob_store *bs;
3598 	struct spdk_bs_dev *dev;
3599 	struct spdk_blob *blob;
3600 	spdk_blob_id blobid;
3601 	uint32_t page_num;
3602 	int index;
3603 	struct spdk_blob_md_page *page;
3604 	struct spdk_blob_opts blob_opts;
3605 
3606 	dev = init_dev();
3607 
3608 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
3609 	poll_threads();
3610 	CU_ASSERT(g_bserrno == 0);
3611 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3612 	bs = g_bs;
3613 
3614 	ut_spdk_blob_opts_init(&blob_opts);
3615 	spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL);
3616 	poll_threads();
3617 	CU_ASSERT(g_bserrno == 0);
3618 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3619 	blobid = g_blobid;
3620 
3621 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
3622 	poll_threads();
3623 	CU_ASSERT(g_bserrno == 0);
3624 	CU_ASSERT(g_blob != NULL);
3625 	blob = g_blob;
3626 
3627 	spdk_blob_close(blob, blob_op_complete, NULL);
3628 	poll_threads();
3629 	CU_ASSERT(g_bserrno == 0);
3630 
3631 	page_num = _spdk_bs_blobid_to_page(blobid);
3632 	index = DEV_BUFFER_BLOCKLEN * (bs->md_start + page_num);
3633 	page = (struct spdk_blob_md_page *)&g_dev_buffer[index];
3634 	page->crc = 0;
3635 
3636 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
3637 	poll_threads();
3638 	CU_ASSERT(g_bserrno == -EINVAL);
3639 	CU_ASSERT(g_blob == NULL);
3640 	g_bserrno = 0;
3641 
3642 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
3643 	poll_threads();
3644 	CU_ASSERT(g_bserrno == -EINVAL);
3645 
3646 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3647 	poll_threads();
3648 	CU_ASSERT(g_bserrno == 0);
3649 	g_bs = NULL;
3650 }
3651 
3652 static void
3653 super_block_crc(void)
3654 {
3655 	struct spdk_bs_dev *dev;
3656 	struct spdk_bs_super_block *super_block;
3657 	struct spdk_bs_opts opts;
3658 
3659 	dev = init_dev();
3660 	spdk_bs_opts_init(&opts);
3661 
3662 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
3663 	poll_threads();
3664 	CU_ASSERT(g_bserrno == 0);
3665 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3666 
3667 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3668 	poll_threads();
3669 	CU_ASSERT(g_bserrno == 0);
3670 	g_bs = NULL;
3671 
3672 	super_block = (struct spdk_bs_super_block *)g_dev_buffer;
3673 	super_block->crc = 0;
3674 	dev = init_dev();
3675 
3676 	/* Load an existing blob store */
3677 	g_bserrno = 0;
3678 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
3679 	poll_threads();
3680 	CU_ASSERT(g_bserrno == -EILSEQ);
3681 }
3682 
3683 /* For blob dirty shutdown test case we do the following sub-test cases:
3684  * 1 Initialize new blob store and create 1 super blob with some xattrs, then we
3685  *   dirty shutdown and reload the blob store and verify the xattrs.
3686  * 2 Resize the blob from 10 clusters to 20 clusters and then dirty shutdown,
3687  *   reload the blob store and verify the clusters number.
3688  * 3 Create the second blob and then dirty shutdown, reload the blob store
3689  *   and verify the second blob.
3690  * 4 Delete the second blob and then dirty shutdown, reload the blob store
3691  *   and verify the second blob is invalid.
3692  * 5 Create the second blob again and also create the third blob, modify the
3693  *   md of second blob which makes the md invalid, and then dirty shutdown,
3694  *   reload the blob store verify the second blob, it should invalid and also
3695  *   verify the third blob, it should correct.
3696  */
3697 static void
3698 blob_dirty_shutdown(void)
3699 {
3700 	int rc;
3701 	int index;
3702 	struct spdk_bs_dev *dev;
3703 	spdk_blob_id blobid1, blobid2, blobid3;
3704 	struct spdk_blob *blob;
3705 	uint64_t length;
3706 	uint64_t free_clusters;
3707 	const void *value;
3708 	size_t value_len;
3709 	uint32_t page_num;
3710 	struct spdk_blob_md_page *page;
3711 	struct spdk_bs_opts opts;
3712 	struct spdk_blob_opts blob_opts;
3713 
3714 	dev = init_dev();
3715 	spdk_bs_opts_init(&opts);
3716 	/* Initialize a new blob store */
3717 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
3718 	poll_threads();
3719 	CU_ASSERT(g_bserrno == 0);
3720 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3721 
3722 	/* Create first blob */
3723 	ut_spdk_blob_opts_init(&blob_opts);
3724 	spdk_bs_create_blob_ext(g_bs, &blob_opts, blob_op_with_id_complete, NULL);
3725 	poll_threads();
3726 	CU_ASSERT(g_bserrno == 0);
3727 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3728 	blobid1 = g_blobid;
3729 
3730 	spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL);
3731 	poll_threads();
3732 	CU_ASSERT(g_bserrno == 0);
3733 	CU_ASSERT(g_blob != NULL);
3734 	blob = g_blob;
3735 
3736 	/* Set some xattrs */
3737 	rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1);
3738 	CU_ASSERT(rc == 0);
3739 
3740 	length = 2345;
3741 	rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
3742 	CU_ASSERT(rc == 0);
3743 
3744 	/* Put xattr that fits exactly single page.
3745 	 * This results in adding additional pages to MD.
3746 	 * First is flags and smaller xattr, second the large xattr,
3747 	 * third are just the extents.
3748 	 */
3749 	size_t xattr_length = 4072 - sizeof(struct spdk_blob_md_descriptor_xattr) -
3750 			      strlen("large_xattr");
3751 	char *xattr = calloc(xattr_length, sizeof(char));
3752 	SPDK_CU_ASSERT_FATAL(xattr != NULL);
3753 	rc = spdk_blob_set_xattr(blob, "large_xattr", xattr, xattr_length);
3754 	free(xattr);
3755 	SPDK_CU_ASSERT_FATAL(rc == 0);
3756 
3757 	/* Resize the blob */
3758 	spdk_blob_resize(blob, 10, blob_op_complete, NULL);
3759 	poll_threads();
3760 	CU_ASSERT(g_bserrno == 0);
3761 
3762 	/* Set the blob as the super blob */
3763 	spdk_bs_set_super(g_bs, blobid1, blob_op_complete, NULL);
3764 	poll_threads();
3765 	CU_ASSERT(g_bserrno == 0);
3766 
3767 	free_clusters = spdk_bs_free_cluster_count(g_bs);
3768 
3769 	spdk_blob_close(blob, blob_op_complete, NULL);
3770 	poll_threads();
3771 	CU_ASSERT(g_bserrno == 0);
3772 	blob = NULL;
3773 	g_blob = NULL;
3774 	g_blobid = SPDK_BLOBID_INVALID;
3775 
3776 	/* Dirty shutdown */
3777 	_spdk_bs_free(g_bs);
3778 
3779 	/* reload blobstore */
3780 	dev = init_dev();
3781 	spdk_bs_opts_init(&opts);
3782 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
3783 	poll_threads();
3784 	CU_ASSERT(g_bserrno == 0);
3785 
3786 	/* Get the super blob */
3787 	spdk_bs_get_super(g_bs, blob_op_with_id_complete, NULL);
3788 	poll_threads();
3789 	CU_ASSERT(g_bserrno == 0);
3790 	CU_ASSERT(blobid1 == g_blobid);
3791 
3792 	spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL);
3793 	poll_threads();
3794 	CU_ASSERT(g_bserrno == 0);
3795 	CU_ASSERT(g_blob != NULL);
3796 	blob = g_blob;
3797 
3798 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs));
3799 
3800 	/* Get the xattrs */
3801 	value = NULL;
3802 	rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len);
3803 	CU_ASSERT(rc == 0);
3804 	SPDK_CU_ASSERT_FATAL(value != NULL);
3805 	CU_ASSERT(*(uint64_t *)value == length);
3806 	CU_ASSERT(value_len == 8);
3807 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10);
3808 
3809 	/* Resize the blob */
3810 	spdk_blob_resize(blob, 20, blob_op_complete, NULL);
3811 	poll_threads();
3812 	CU_ASSERT(g_bserrno == 0);
3813 
3814 	free_clusters = spdk_bs_free_cluster_count(g_bs);
3815 
3816 	spdk_blob_close(blob, blob_op_complete, NULL);
3817 	poll_threads();
3818 	CU_ASSERT(g_bserrno == 0);
3819 	blob = NULL;
3820 	g_blob = NULL;
3821 	g_blobid = SPDK_BLOBID_INVALID;
3822 
3823 	/* Dirty shutdown */
3824 	_spdk_bs_free(g_bs);
3825 
3826 	/* reload the blobstore */
3827 	dev = init_dev();
3828 	spdk_bs_opts_init(&opts);
3829 	/* Load an existing blob store */
3830 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
3831 	poll_threads();
3832 	CU_ASSERT(g_bserrno == 0);
3833 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3834 	spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL);
3835 	poll_threads();
3836 	CU_ASSERT(g_bserrno == 0);
3837 	CU_ASSERT(g_blob != NULL);
3838 	blob = g_blob;
3839 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 20);
3840 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs));
3841 
3842 	spdk_blob_close(blob, blob_op_complete, NULL);
3843 	poll_threads();
3844 	CU_ASSERT(g_bserrno == 0);
3845 	blob = NULL;
3846 	g_blob = NULL;
3847 	g_blobid = SPDK_BLOBID_INVALID;
3848 
3849 	/* Create second blob */
3850 	spdk_bs_create_blob_ext(g_bs, &blob_opts, blob_op_with_id_complete, NULL);
3851 	poll_threads();
3852 	CU_ASSERT(g_bserrno == 0);
3853 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3854 	blobid2 = g_blobid;
3855 
3856 	spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL);
3857 	poll_threads();
3858 	CU_ASSERT(g_bserrno == 0);
3859 	CU_ASSERT(g_blob != NULL);
3860 	blob = g_blob;
3861 
3862 	/* Set some xattrs */
3863 	rc = spdk_blob_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1);
3864 	CU_ASSERT(rc == 0);
3865 
3866 	length = 5432;
3867 	rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
3868 	CU_ASSERT(rc == 0);
3869 
3870 	/* Resize the blob */
3871 	spdk_blob_resize(blob, 10, blob_op_complete, NULL);
3872 	poll_threads();
3873 	CU_ASSERT(g_bserrno == 0);
3874 
3875 	free_clusters = spdk_bs_free_cluster_count(g_bs);
3876 
3877 	spdk_blob_close(blob, blob_op_complete, NULL);
3878 	poll_threads();
3879 	CU_ASSERT(g_bserrno == 0);
3880 	blob = NULL;
3881 	g_blob = NULL;
3882 	g_blobid = SPDK_BLOBID_INVALID;
3883 
3884 	/* Dirty shutdown */
3885 	_spdk_bs_free(g_bs);
3886 
3887 	/* reload the blobstore */
3888 	dev = init_dev();
3889 	spdk_bs_opts_init(&opts);
3890 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
3891 	poll_threads();
3892 	CU_ASSERT(g_bserrno == 0);
3893 
3894 	spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL);
3895 	poll_threads();
3896 	CU_ASSERT(g_bserrno == 0);
3897 	CU_ASSERT(g_blob != NULL);
3898 	blob = g_blob;
3899 
3900 	/* Get the xattrs */
3901 	value = NULL;
3902 	rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len);
3903 	CU_ASSERT(rc == 0);
3904 	SPDK_CU_ASSERT_FATAL(value != NULL);
3905 	CU_ASSERT(*(uint64_t *)value == length);
3906 	CU_ASSERT(value_len == 8);
3907 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10);
3908 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs));
3909 
3910 	spdk_blob_close(blob, blob_op_complete, NULL);
3911 	poll_threads();
3912 	CU_ASSERT(g_bserrno == 0);
3913 	spdk_bs_delete_blob(g_bs, blobid2, blob_op_complete, NULL);
3914 	poll_threads();
3915 	CU_ASSERT(g_bserrno == 0);
3916 
3917 	free_clusters = spdk_bs_free_cluster_count(g_bs);
3918 
3919 	/* Dirty shutdown */
3920 	_spdk_bs_free(g_bs);
3921 	/* reload the blobstore */
3922 	dev = init_dev();
3923 	spdk_bs_opts_init(&opts);
3924 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
3925 	poll_threads();
3926 	CU_ASSERT(g_bserrno == 0);
3927 
3928 	spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL);
3929 	poll_threads();
3930 	CU_ASSERT(g_bserrno != 0);
3931 	CU_ASSERT(g_blob == NULL);
3932 
3933 	spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL);
3934 	poll_threads();
3935 	CU_ASSERT(g_bserrno == 0);
3936 	CU_ASSERT(g_blob != NULL);
3937 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs));
3938 	spdk_blob_close(g_blob, blob_op_complete, NULL);
3939 	poll_threads();
3940 	CU_ASSERT(g_bserrno == 0);
3941 
3942 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3943 	poll_threads();
3944 	CU_ASSERT(g_bserrno == 0);
3945 	g_bs = NULL;
3946 
3947 	/* reload the blobstore */
3948 	dev = init_dev();
3949 	spdk_bs_opts_init(&opts);
3950 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
3951 	poll_threads();
3952 	CU_ASSERT(g_bserrno == 0);
3953 
3954 	/* Create second blob */
3955 	spdk_bs_create_blob_ext(g_bs, &blob_opts, blob_op_with_id_complete, NULL);
3956 	poll_threads();
3957 	CU_ASSERT(g_bserrno == 0);
3958 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3959 	blobid2 = g_blobid;
3960 
3961 	/* Create third blob */
3962 	spdk_bs_create_blob_ext(g_bs, &blob_opts, blob_op_with_id_complete, NULL);
3963 	poll_threads();
3964 	CU_ASSERT(g_bserrno == 0);
3965 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3966 	blobid3 = g_blobid;
3967 
3968 	spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL);
3969 	poll_threads();
3970 	CU_ASSERT(g_bserrno == 0);
3971 	CU_ASSERT(g_blob != NULL);
3972 	blob = g_blob;
3973 
3974 	/* Set some xattrs for second blob */
3975 	rc = spdk_blob_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1);
3976 	CU_ASSERT(rc == 0);
3977 
3978 	length = 5432;
3979 	rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
3980 	CU_ASSERT(rc == 0);
3981 
3982 	spdk_blob_close(blob, blob_op_complete, NULL);
3983 	poll_threads();
3984 	CU_ASSERT(g_bserrno == 0);
3985 	blob = NULL;
3986 	g_blob = NULL;
3987 	g_blobid = SPDK_BLOBID_INVALID;
3988 
3989 	spdk_bs_open_blob(g_bs, blobid3, blob_op_with_handle_complete, NULL);
3990 	poll_threads();
3991 	CU_ASSERT(g_bserrno == 0);
3992 	CU_ASSERT(g_blob != NULL);
3993 	blob = g_blob;
3994 
3995 	/* Set some xattrs for third blob */
3996 	rc = spdk_blob_set_xattr(blob, "name", "log2.txt", strlen("log2.txt") + 1);
3997 	CU_ASSERT(rc == 0);
3998 
3999 	length = 5432;
4000 	rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
4001 	CU_ASSERT(rc == 0);
4002 
4003 	spdk_blob_close(blob, blob_op_complete, NULL);
4004 	poll_threads();
4005 	CU_ASSERT(g_bserrno == 0);
4006 	blob = NULL;
4007 	g_blob = NULL;
4008 	g_blobid = SPDK_BLOBID_INVALID;
4009 
4010 	/* Mark second blob as invalid */
4011 	page_num = _spdk_bs_blobid_to_page(blobid2);
4012 
4013 	index = DEV_BUFFER_BLOCKLEN * (g_bs->md_start + page_num);
4014 	page = (struct spdk_blob_md_page *)&g_dev_buffer[index];
4015 	page->sequence_num = 1;
4016 	page->crc = _spdk_blob_md_page_calc_crc(page);
4017 
4018 	free_clusters = spdk_bs_free_cluster_count(g_bs);
4019 
4020 	/* Dirty shutdown */
4021 	_spdk_bs_free(g_bs);
4022 	/* reload the blobstore */
4023 	dev = init_dev();
4024 	spdk_bs_opts_init(&opts);
4025 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
4026 	poll_threads();
4027 	CU_ASSERT(g_bserrno == 0);
4028 
4029 	spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL);
4030 	poll_threads();
4031 	CU_ASSERT(g_bserrno != 0);
4032 	CU_ASSERT(g_blob == NULL);
4033 
4034 	spdk_bs_open_blob(g_bs, blobid3, blob_op_with_handle_complete, NULL);
4035 	poll_threads();
4036 	CU_ASSERT(g_bserrno == 0);
4037 	CU_ASSERT(g_blob != NULL);
4038 	blob = g_blob;
4039 
4040 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs));
4041 
4042 	spdk_blob_close(blob, blob_op_complete, NULL);
4043 	poll_threads();
4044 	CU_ASSERT(g_bserrno == 0);
4045 	blob = NULL;
4046 	g_blob = NULL;
4047 	g_blobid = SPDK_BLOBID_INVALID;
4048 
4049 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
4050 	poll_threads();
4051 	CU_ASSERT(g_bserrno == 0);
4052 	g_bs = NULL;
4053 }
4054 
4055 static void
4056 blob_flags(void)
4057 {
4058 	struct spdk_bs_dev *dev;
4059 	spdk_blob_id blobid_invalid, blobid_data_ro, blobid_md_ro;
4060 	struct spdk_blob *blob_invalid, *blob_data_ro, *blob_md_ro;
4061 	struct spdk_bs_opts opts;
4062 	struct spdk_blob_opts blob_opts;
4063 	int rc;
4064 
4065 	dev = init_dev();
4066 	spdk_bs_opts_init(&opts);
4067 	ut_spdk_blob_opts_init(&blob_opts);
4068 
4069 	/* Initialize a new blob store */
4070 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
4071 	poll_threads();
4072 	CU_ASSERT(g_bserrno == 0);
4073 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
4074 
4075 	/* Create three blobs - one each for testing invalid, data_ro and md_ro flags. */
4076 	spdk_bs_create_blob_ext(g_bs, &blob_opts, blob_op_with_id_complete, NULL);
4077 	poll_threads();
4078 	CU_ASSERT(g_bserrno == 0);
4079 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
4080 	blobid_invalid = g_blobid;
4081 
4082 	spdk_bs_create_blob_ext(g_bs, &blob_opts, blob_op_with_id_complete, NULL);
4083 	poll_threads();
4084 	CU_ASSERT(g_bserrno == 0);
4085 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
4086 	blobid_data_ro = g_blobid;
4087 
4088 	blob_opts.clear_method = BLOB_CLEAR_WITH_WRITE_ZEROES;
4089 	spdk_bs_create_blob_ext(g_bs, &blob_opts, blob_op_with_id_complete, NULL);
4090 	poll_threads();
4091 	CU_ASSERT(g_bserrno == 0);
4092 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
4093 	blobid_md_ro = g_blobid;
4094 
4095 	spdk_bs_open_blob(g_bs, blobid_invalid, blob_op_with_handle_complete, NULL);
4096 	poll_threads();
4097 	CU_ASSERT(g_bserrno == 0);
4098 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4099 	blob_invalid = g_blob;
4100 
4101 	spdk_bs_open_blob(g_bs, blobid_data_ro, blob_op_with_handle_complete, NULL);
4102 	poll_threads();
4103 	CU_ASSERT(g_bserrno == 0);
4104 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4105 	blob_data_ro = g_blob;
4106 
4107 	spdk_bs_open_blob(g_bs, blobid_md_ro, blob_op_with_handle_complete, NULL);
4108 	poll_threads();
4109 	CU_ASSERT(g_bserrno == 0);
4110 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4111 	blob_md_ro = g_blob;
4112 	CU_ASSERT((blob_md_ro->md_ro_flags & SPDK_BLOB_MD_RO_FLAGS_MASK) == BLOB_CLEAR_WITH_WRITE_ZEROES);
4113 
4114 	/* Change the size of blob_data_ro to check if flags are serialized
4115 	 * when blob has non zero number of extents */
4116 	spdk_blob_resize(blob_data_ro, 10, blob_op_complete, NULL);
4117 	poll_threads();
4118 	CU_ASSERT(g_bserrno == 0);
4119 
4120 	/* Set the xattr to check if flags are serialized
4121 	 * when blob has non zero number of xattrs */
4122 	rc = spdk_blob_set_xattr(blob_md_ro, "name", "log.txt", strlen("log.txt") + 1);
4123 	CU_ASSERT(rc == 0);
4124 
4125 	blob_invalid->invalid_flags = (1ULL << 63);
4126 	blob_invalid->state = SPDK_BLOB_STATE_DIRTY;
4127 	blob_data_ro->data_ro_flags = (1ULL << 62);
4128 	blob_data_ro->state = SPDK_BLOB_STATE_DIRTY;
4129 	blob_md_ro->md_ro_flags = (1ULL << 61);
4130 	blob_md_ro->state = SPDK_BLOB_STATE_DIRTY;
4131 
4132 	g_bserrno = -1;
4133 	spdk_blob_sync_md(blob_invalid, blob_op_complete, NULL);
4134 	poll_threads();
4135 	CU_ASSERT(g_bserrno == 0);
4136 	g_bserrno = -1;
4137 	spdk_blob_sync_md(blob_data_ro, blob_op_complete, NULL);
4138 	poll_threads();
4139 	CU_ASSERT(g_bserrno == 0);
4140 	g_bserrno = -1;
4141 	spdk_blob_sync_md(blob_md_ro, blob_op_complete, NULL);
4142 	poll_threads();
4143 	CU_ASSERT(g_bserrno == 0);
4144 
4145 	g_bserrno = -1;
4146 	spdk_blob_close(blob_invalid, blob_op_complete, NULL);
4147 	poll_threads();
4148 	CU_ASSERT(g_bserrno == 0);
4149 	blob_invalid = NULL;
4150 	g_bserrno = -1;
4151 	spdk_blob_close(blob_data_ro, blob_op_complete, NULL);
4152 	poll_threads();
4153 	CU_ASSERT(g_bserrno == 0);
4154 	blob_data_ro = NULL;
4155 	g_bserrno = -1;
4156 	spdk_blob_close(blob_md_ro, blob_op_complete, NULL);
4157 	poll_threads();
4158 	CU_ASSERT(g_bserrno == 0);
4159 	blob_md_ro = NULL;
4160 
4161 	g_blob = NULL;
4162 	g_blobid = SPDK_BLOBID_INVALID;
4163 
4164 	/* Unload the blob store */
4165 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
4166 	poll_threads();
4167 	CU_ASSERT(g_bserrno == 0);
4168 	g_bs = NULL;
4169 
4170 	/* Load an existing blob store */
4171 	dev = init_dev();
4172 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
4173 	poll_threads();
4174 	CU_ASSERT(g_bserrno == 0);
4175 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
4176 
4177 	g_blob = NULL;
4178 	g_bserrno = 0;
4179 	spdk_bs_open_blob(g_bs, blobid_invalid, blob_op_with_handle_complete, NULL);
4180 	poll_threads();
4181 	CU_ASSERT(g_bserrno != 0);
4182 	CU_ASSERT(g_blob == NULL);
4183 
4184 	g_blob = NULL;
4185 	g_bserrno = -1;
4186 	spdk_bs_open_blob(g_bs, blobid_data_ro, blob_op_with_handle_complete, NULL);
4187 	poll_threads();
4188 	CU_ASSERT(g_bserrno == 0);
4189 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4190 	blob_data_ro = g_blob;
4191 	/* If an unknown data_ro flag was found, the blob should be marked both data and md read-only. */
4192 	CU_ASSERT(blob_data_ro->data_ro == true);
4193 	CU_ASSERT(blob_data_ro->md_ro == true);
4194 	CU_ASSERT(spdk_blob_get_num_clusters(blob_data_ro) == 10);
4195 
4196 	g_blob = NULL;
4197 	g_bserrno = -1;
4198 	spdk_bs_open_blob(g_bs, blobid_md_ro, blob_op_with_handle_complete, NULL);
4199 	poll_threads();
4200 	CU_ASSERT(g_bserrno == 0);
4201 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4202 	blob_md_ro = g_blob;
4203 	CU_ASSERT(blob_md_ro->data_ro == false);
4204 	CU_ASSERT(blob_md_ro->md_ro == true);
4205 
4206 	g_bserrno = -1;
4207 	spdk_blob_sync_md(blob_md_ro, blob_op_complete, NULL);
4208 	poll_threads();
4209 	CU_ASSERT(g_bserrno == 0);
4210 
4211 	spdk_blob_close(blob_data_ro, blob_op_complete, NULL);
4212 	poll_threads();
4213 	CU_ASSERT(g_bserrno == 0);
4214 	spdk_blob_close(blob_md_ro, blob_op_complete, NULL);
4215 	poll_threads();
4216 	CU_ASSERT(g_bserrno == 0);
4217 
4218 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
4219 	poll_threads();
4220 	CU_ASSERT(g_bserrno == 0);
4221 }
4222 
4223 static void
4224 bs_version(void)
4225 {
4226 	struct spdk_bs_super_block *super;
4227 	struct spdk_bs_dev *dev;
4228 	struct spdk_bs_opts opts;
4229 	struct spdk_blob_opts blob_opts;
4230 	spdk_blob_id blobid;
4231 
4232 	dev = init_dev();
4233 	spdk_bs_opts_init(&opts);
4234 
4235 	/* Initialize a new blob store */
4236 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
4237 	poll_threads();
4238 	CU_ASSERT(g_bserrno == 0);
4239 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
4240 
4241 	/* Unload the blob store */
4242 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
4243 	poll_threads();
4244 	CU_ASSERT(g_bserrno == 0);
4245 	g_bs = NULL;
4246 
4247 	/*
4248 	 * Change the bs version on disk.  This will allow us to
4249 	 *  test that the version does not get modified automatically
4250 	 *  when loading and unloading the blobstore.
4251 	 */
4252 	super = (struct spdk_bs_super_block *)&g_dev_buffer[0];
4253 	CU_ASSERT(super->version == SPDK_BS_VERSION);
4254 	CU_ASSERT(super->clean == 1);
4255 	super->version = 2;
4256 	/*
4257 	 * Version 2 metadata does not have a used blobid mask, so clear
4258 	 *  those fields in the super block and zero the corresponding
4259 	 *  region on "disk".  We will use this to ensure blob IDs are
4260 	 *  correctly reconstructed.
4261 	 */
4262 	memset(&g_dev_buffer[super->used_blobid_mask_start * SPDK_BS_PAGE_SIZE], 0,
4263 	       super->used_blobid_mask_len * SPDK_BS_PAGE_SIZE);
4264 	super->used_blobid_mask_start = 0;
4265 	super->used_blobid_mask_len = 0;
4266 	super->crc = _spdk_blob_md_page_calc_crc(super);
4267 
4268 	/* Load an existing blob store */
4269 	dev = init_dev();
4270 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
4271 	poll_threads();
4272 	CU_ASSERT(g_bserrno == 0);
4273 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
4274 	CU_ASSERT(super->clean == 1);
4275 
4276 	/*
4277 	 * Create a blob - just to make sure that when we unload it
4278 	 *  results in writing the super block (since metadata pages
4279 	 *  were allocated.
4280 	 */
4281 	ut_spdk_blob_opts_init(&blob_opts);
4282 	spdk_bs_create_blob_ext(g_bs, &blob_opts, blob_op_with_id_complete, NULL);
4283 	poll_threads();
4284 	CU_ASSERT(g_bserrno == 0);
4285 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
4286 	blobid = g_blobid;
4287 
4288 	/* Unload the blob store */
4289 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
4290 	poll_threads();
4291 	CU_ASSERT(g_bserrno == 0);
4292 	g_bs = NULL;
4293 	CU_ASSERT(super->version == 2);
4294 	CU_ASSERT(super->used_blobid_mask_start == 0);
4295 	CU_ASSERT(super->used_blobid_mask_len == 0);
4296 
4297 	dev = init_dev();
4298 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
4299 	poll_threads();
4300 	CU_ASSERT(g_bserrno == 0);
4301 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
4302 
4303 	g_blob = NULL;
4304 	spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
4305 	poll_threads();
4306 	CU_ASSERT(g_bserrno == 0);
4307 	CU_ASSERT(g_blob != NULL);
4308 
4309 	spdk_blob_close(g_blob, blob_op_complete, NULL);
4310 	poll_threads();
4311 	CU_ASSERT(g_bserrno == 0);
4312 
4313 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
4314 	poll_threads();
4315 	CU_ASSERT(g_bserrno == 0);
4316 	g_bs = NULL;
4317 	CU_ASSERT(super->version == 2);
4318 	CU_ASSERT(super->used_blobid_mask_start == 0);
4319 	CU_ASSERT(super->used_blobid_mask_len == 0);
4320 }
4321 
4322 static void
4323 blob_set_xattrs(void)
4324 {
4325 	struct spdk_blob_store *bs;
4326 	struct spdk_bs_dev *dev;
4327 	struct spdk_blob *blob;
4328 	struct spdk_blob_opts opts;
4329 	spdk_blob_id blobid;
4330 	const void *value;
4331 	size_t value_len;
4332 	char *xattr;
4333 	size_t xattr_length;
4334 	int rc;
4335 
4336 	dev = init_dev();
4337 
4338 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
4339 	poll_threads();
4340 	CU_ASSERT(g_bserrno == 0);
4341 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
4342 	bs = g_bs;
4343 
4344 	/* Create blob with extra attributes */
4345 	ut_spdk_blob_opts_init(&opts);
4346 
4347 	opts.xattrs.names = g_xattr_names;
4348 	opts.xattrs.get_value = _get_xattr_value;
4349 	opts.xattrs.count = 3;
4350 	opts.xattrs.ctx = &g_ctx;
4351 
4352 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
4353 	poll_threads();
4354 	CU_ASSERT(g_bserrno == 0);
4355 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
4356 	blobid = g_blobid;
4357 
4358 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
4359 	poll_threads();
4360 	CU_ASSERT(g_bserrno == 0);
4361 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4362 	blob = g_blob;
4363 
4364 	/* Get the xattrs */
4365 	value = NULL;
4366 
4367 	rc = spdk_blob_get_xattr_value(blob, g_xattr_names[0], &value, &value_len);
4368 	CU_ASSERT(rc == 0);
4369 	SPDK_CU_ASSERT_FATAL(value != NULL);
4370 	CU_ASSERT(value_len == strlen(g_xattr_values[0]));
4371 	CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len);
4372 
4373 	rc = spdk_blob_get_xattr_value(blob, g_xattr_names[1], &value, &value_len);
4374 	CU_ASSERT(rc == 0);
4375 	SPDK_CU_ASSERT_FATAL(value != NULL);
4376 	CU_ASSERT(value_len == strlen(g_xattr_values[1]));
4377 	CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len);
4378 
4379 	rc = spdk_blob_get_xattr_value(blob, g_xattr_names[2], &value, &value_len);
4380 	CU_ASSERT(rc == 0);
4381 	SPDK_CU_ASSERT_FATAL(value != NULL);
4382 	CU_ASSERT(value_len == strlen(g_xattr_values[2]));
4383 	CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len);
4384 
4385 	/* Try to get non existing attribute */
4386 
4387 	rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len);
4388 	CU_ASSERT(rc == -ENOENT);
4389 
4390 	/* Try xattr exceeding maximum length of descriptor in single page */
4391 	xattr_length = SPDK_BS_MAX_DESC_SIZE - sizeof(struct spdk_blob_md_descriptor_xattr) -
4392 		       strlen("large_xattr") + 1;
4393 	xattr = calloc(xattr_length, sizeof(char));
4394 	SPDK_CU_ASSERT_FATAL(xattr != NULL);
4395 	rc = spdk_blob_set_xattr(blob, "large_xattr", xattr, xattr_length);
4396 	free(xattr);
4397 	SPDK_CU_ASSERT_FATAL(rc == -ENOMEM);
4398 
4399 	spdk_blob_close(blob, blob_op_complete, NULL);
4400 	poll_threads();
4401 	CU_ASSERT(g_bserrno == 0);
4402 	blob = NULL;
4403 	g_blob = NULL;
4404 	g_blobid = SPDK_BLOBID_INVALID;
4405 
4406 	/* NULL callback */
4407 	ut_spdk_blob_opts_init(&opts);
4408 	opts.xattrs.names = g_xattr_names;
4409 	opts.xattrs.get_value = NULL;
4410 	opts.xattrs.count = 1;
4411 	opts.xattrs.ctx = &g_ctx;
4412 
4413 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
4414 	poll_threads();
4415 	CU_ASSERT(g_bserrno == -EINVAL);
4416 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
4417 
4418 	/* NULL values */
4419 	ut_spdk_blob_opts_init(&opts);
4420 	opts.xattrs.names = g_xattr_names;
4421 	opts.xattrs.get_value = _get_xattr_value_null;
4422 	opts.xattrs.count = 1;
4423 	opts.xattrs.ctx = NULL;
4424 
4425 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
4426 	poll_threads();
4427 	CU_ASSERT(g_bserrno == -EINVAL);
4428 
4429 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
4430 	poll_threads();
4431 	CU_ASSERT(g_bserrno == 0);
4432 	g_bs = NULL;
4433 
4434 }
4435 
4436 static void
4437 blob_thin_prov_alloc(void)
4438 {
4439 	struct spdk_blob_store *bs;
4440 	struct spdk_bs_dev *dev;
4441 	struct spdk_blob *blob;
4442 	struct spdk_blob_opts opts;
4443 	spdk_blob_id blobid;
4444 	uint64_t free_clusters;
4445 
4446 	dev = init_dev();
4447 
4448 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
4449 	poll_threads();
4450 	CU_ASSERT(g_bserrno == 0);
4451 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
4452 	bs = g_bs;
4453 	free_clusters = spdk_bs_free_cluster_count(bs);
4454 
4455 	/* Set blob as thin provisioned */
4456 	ut_spdk_blob_opts_init(&opts);
4457 	opts.thin_provision = true;
4458 
4459 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
4460 	poll_threads();
4461 	CU_ASSERT(g_bserrno == 0);
4462 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
4463 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
4464 	blobid = g_blobid;
4465 
4466 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
4467 	poll_threads();
4468 	CU_ASSERT(g_bserrno == 0);
4469 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4470 	blob = g_blob;
4471 
4472 	CU_ASSERT(blob->active.num_clusters == 0);
4473 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0);
4474 
4475 	/* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */
4476 	spdk_blob_resize(blob, 5, blob_op_complete, NULL);
4477 	poll_threads();
4478 	CU_ASSERT(g_bserrno == 0);
4479 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
4480 	CU_ASSERT(blob->active.num_clusters == 5);
4481 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5);
4482 
4483 	/* Grow it to 1TB - still unallocated */
4484 	spdk_blob_resize(blob, 262144, blob_op_complete, NULL);
4485 	poll_threads();
4486 	CU_ASSERT(g_bserrno == 0);
4487 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
4488 	CU_ASSERT(blob->active.num_clusters == 262144);
4489 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 262144);
4490 
4491 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
4492 	poll_threads();
4493 	CU_ASSERT(g_bserrno == 0);
4494 	/* Sync must not change anything */
4495 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
4496 	CU_ASSERT(blob->active.num_clusters == 262144);
4497 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 262144);
4498 	/* Since clusters are not allocated,
4499 	 * number of metadata pages is expected to be minimal.
4500 	 */
4501 	CU_ASSERT(blob->active.num_pages == 1);
4502 
4503 	/* Shrink the blob to 3 clusters - still unallocated */
4504 	spdk_blob_resize(blob, 3, blob_op_complete, NULL);
4505 	poll_threads();
4506 	CU_ASSERT(g_bserrno == 0);
4507 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
4508 	CU_ASSERT(blob->active.num_clusters == 3);
4509 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 3);
4510 
4511 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
4512 	poll_threads();
4513 	CU_ASSERT(g_bserrno == 0);
4514 	/* Sync must not change anything */
4515 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
4516 	CU_ASSERT(blob->active.num_clusters == 3);
4517 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 3);
4518 
4519 	spdk_blob_close(blob, blob_op_complete, NULL);
4520 	poll_threads();
4521 	CU_ASSERT(g_bserrno == 0);
4522 
4523 	/* Unload the blob store */
4524 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
4525 	poll_threads();
4526 	CU_ASSERT(g_bserrno == 0);
4527 	g_bs = NULL;
4528 	g_blob = NULL;
4529 	g_blobid = 0;
4530 
4531 	/* Load an existing blob store */
4532 	dev = init_dev();
4533 	spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL);
4534 	poll_threads();
4535 	CU_ASSERT(g_bserrno == 0);
4536 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
4537 
4538 	bs = g_bs;
4539 
4540 	spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
4541 	poll_threads();
4542 	CU_ASSERT(g_bserrno == 0);
4543 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4544 	blob = g_blob;
4545 
4546 	/* Check that clusters allocation and size is still the same */
4547 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
4548 	CU_ASSERT(blob->active.num_clusters == 3);
4549 
4550 	spdk_blob_close(blob, blob_op_complete, NULL);
4551 	poll_threads();
4552 	CU_ASSERT(g_bserrno == 0);
4553 
4554 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
4555 	poll_threads();
4556 	CU_ASSERT(g_bserrno == 0);
4557 
4558 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
4559 	poll_threads();
4560 	CU_ASSERT(g_bserrno == 0);
4561 	g_bs = NULL;
4562 }
4563 
4564 static void
4565 blob_insert_cluster_msg(void)
4566 {
4567 	struct spdk_blob_store *bs;
4568 	struct spdk_bs_dev *dev;
4569 	struct spdk_blob *blob;
4570 	struct spdk_blob_opts opts;
4571 	spdk_blob_id blobid;
4572 	uint64_t free_clusters;
4573 	uint64_t new_cluster = 0;
4574 	uint32_t cluster_num = 3;
4575 	uint32_t extent_page = 0;
4576 
4577 	dev = init_dev();
4578 
4579 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
4580 	poll_threads();
4581 	CU_ASSERT(g_bserrno == 0);
4582 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
4583 	bs = g_bs;
4584 	free_clusters = spdk_bs_free_cluster_count(bs);
4585 
4586 	/* Set blob as thin provisioned */
4587 	ut_spdk_blob_opts_init(&opts);
4588 	opts.thin_provision = true;
4589 	opts.num_clusters = 4;
4590 
4591 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
4592 	poll_threads();
4593 	CU_ASSERT(g_bserrno == 0);
4594 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
4595 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
4596 	blobid = g_blobid;
4597 
4598 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
4599 	poll_threads();
4600 	CU_ASSERT(g_bserrno == 0);
4601 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4602 	blob = g_blob;
4603 
4604 	CU_ASSERT(blob->active.num_clusters == 4);
4605 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 4);
4606 	CU_ASSERT(blob->active.clusters[cluster_num] == 0);
4607 
4608 	/* Specify cluster_num to allocate and new_cluster will be returned to insert on md_thread.
4609 	 * This is to simulate behaviour when cluster is allocated after blob creation.
4610 	 * Such as _spdk_bs_allocate_and_copy_cluster(). */
4611 	_spdk_bs_allocate_cluster(blob, cluster_num, &new_cluster, &extent_page, false);
4612 	CU_ASSERT(blob->active.clusters[cluster_num] == 0);
4613 
4614 	_spdk_blob_insert_cluster_on_md_thread(blob, cluster_num, new_cluster, extent_page,
4615 					       blob_op_complete, NULL);
4616 	poll_threads();
4617 
4618 	CU_ASSERT(blob->active.clusters[cluster_num] != 0);
4619 
4620 	spdk_blob_close(blob, blob_op_complete, NULL);
4621 	poll_threads();
4622 	CU_ASSERT(g_bserrno == 0);
4623 
4624 	/* Unload the blob store */
4625 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
4626 	poll_threads();
4627 	CU_ASSERT(g_bserrno == 0);
4628 	g_bs = NULL;
4629 	g_blob = NULL;
4630 	g_blobid = 0;
4631 
4632 	/* Load an existing blob store */
4633 	dev = init_dev();
4634 	spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL);
4635 	poll_threads();
4636 	CU_ASSERT(g_bserrno == 0);
4637 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
4638 
4639 	bs = g_bs;
4640 
4641 	spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
4642 	poll_threads();
4643 	CU_ASSERT(g_bserrno == 0);
4644 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4645 	blob = g_blob;
4646 
4647 	CU_ASSERT(blob->active.clusters[cluster_num] != 0);
4648 
4649 	spdk_blob_close(blob, blob_op_complete, NULL);
4650 	poll_threads();
4651 	CU_ASSERT(g_bserrno == 0);
4652 
4653 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
4654 	poll_threads();
4655 	CU_ASSERT(g_bserrno == 0);
4656 
4657 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
4658 	poll_threads();
4659 	CU_ASSERT(g_bserrno == 0);
4660 	g_bs = NULL;
4661 }
4662 
4663 static void
4664 blob_thin_prov_rw(void)
4665 {
4666 	static const uint8_t zero[10 * 4096] = { 0 };
4667 	struct spdk_blob_store *bs;
4668 	struct spdk_bs_dev *dev;
4669 	struct spdk_blob *blob;
4670 	struct spdk_io_channel *channel, *channel_thread1;
4671 	struct spdk_blob_opts opts;
4672 	spdk_blob_id blobid;
4673 	uint64_t free_clusters;
4674 	uint64_t page_size;
4675 	uint8_t payload_read[10 * 4096];
4676 	uint8_t payload_write[10 * 4096];
4677 	uint64_t write_bytes;
4678 	uint64_t read_bytes;
4679 
4680 	dev = init_dev();
4681 
4682 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
4683 	poll_threads();
4684 	CU_ASSERT(g_bserrno == 0);
4685 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
4686 	bs = g_bs;
4687 	free_clusters = spdk_bs_free_cluster_count(bs);
4688 	page_size = spdk_bs_get_page_size(bs);
4689 
4690 	channel = spdk_bs_alloc_io_channel(bs);
4691 	CU_ASSERT(channel != NULL);
4692 
4693 	ut_spdk_blob_opts_init(&opts);
4694 	opts.thin_provision = true;
4695 
4696 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
4697 	poll_threads();
4698 	CU_ASSERT(g_bserrno == 0);
4699 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
4700 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
4701 	blobid = g_blobid;
4702 
4703 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
4704 	poll_threads();
4705 	CU_ASSERT(g_bserrno == 0);
4706 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4707 	blob = g_blob;
4708 
4709 	CU_ASSERT(blob->active.num_clusters == 0);
4710 
4711 	/* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */
4712 	spdk_blob_resize(blob, 5, blob_op_complete, NULL);
4713 	poll_threads();
4714 	CU_ASSERT(g_bserrno == 0);
4715 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
4716 	CU_ASSERT(blob->active.num_clusters == 5);
4717 
4718 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
4719 	poll_threads();
4720 	CU_ASSERT(g_bserrno == 0);
4721 	/* Sync must not change anything */
4722 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
4723 	CU_ASSERT(blob->active.num_clusters == 5);
4724 
4725 	/* Payload should be all zeros from unallocated clusters */
4726 	memset(payload_read, 0xFF, sizeof(payload_read));
4727 	spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL);
4728 	poll_threads();
4729 	CU_ASSERT(g_bserrno == 0);
4730 	CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0);
4731 
4732 	write_bytes = g_dev_write_bytes;
4733 	read_bytes = g_dev_read_bytes;
4734 
4735 	/* Perform write on thread 1. That will allocate cluster on thread 0 via send_msg */
4736 	set_thread(1);
4737 	channel_thread1 = spdk_bs_alloc_io_channel(bs);
4738 	CU_ASSERT(channel_thread1 != NULL);
4739 	memset(payload_write, 0xE5, sizeof(payload_write));
4740 	spdk_blob_io_write(blob, channel_thread1, payload_write, 4, 10, blob_op_complete, NULL);
4741 	CU_ASSERT(free_clusters - 1 == spdk_bs_free_cluster_count(bs));
4742 	/* Perform write on thread 0. That will try to allocate cluster,
4743 	 * but fail due to another thread issuing the cluster allocation first. */
4744 	set_thread(0);
4745 	memset(payload_write, 0xE5, sizeof(payload_write));
4746 	spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL);
4747 	CU_ASSERT(free_clusters - 2 == spdk_bs_free_cluster_count(bs));
4748 	poll_threads();
4749 	CU_ASSERT(g_bserrno == 0);
4750 	CU_ASSERT(free_clusters - 1 == spdk_bs_free_cluster_count(bs));
4751 	/* For thin-provisioned blob we need to write 20 pages plus one page metadata and
4752 	 * read 0 bytes */
4753 	if (g_use_extent_table) {
4754 		/* Add one more page for EXTENT_PAGE write */
4755 		CU_ASSERT(g_dev_write_bytes - write_bytes == page_size * 22);
4756 	} else {
4757 		CU_ASSERT(g_dev_write_bytes - write_bytes == page_size * 21);
4758 	}
4759 	CU_ASSERT(g_dev_read_bytes - read_bytes == 0);
4760 
4761 	spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL);
4762 	poll_threads();
4763 	CU_ASSERT(g_bserrno == 0);
4764 	CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0);
4765 
4766 	spdk_blob_close(blob, blob_op_complete, NULL);
4767 	poll_threads();
4768 	CU_ASSERT(g_bserrno == 0);
4769 
4770 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
4771 	poll_threads();
4772 	CU_ASSERT(g_bserrno == 0);
4773 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
4774 
4775 	spdk_bs_free_io_channel(channel_thread1);
4776 	spdk_bs_free_io_channel(channel);
4777 	poll_threads();
4778 
4779 	/* Unload the blob store */
4780 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
4781 	poll_threads();
4782 	CU_ASSERT(g_bserrno == 0);
4783 	g_bs = NULL;
4784 	g_blob = NULL;
4785 	g_blobid = 0;
4786 }
4787 
4788 static void
4789 blob_thin_prov_rle(void)
4790 {
4791 	static const uint8_t zero[10 * 4096] = { 0 };
4792 	struct spdk_blob_store *bs;
4793 	struct spdk_bs_dev *dev;
4794 	struct spdk_blob *blob;
4795 	struct spdk_io_channel *channel;
4796 	struct spdk_blob_opts opts;
4797 	spdk_blob_id blobid;
4798 	uint64_t free_clusters;
4799 	uint64_t page_size;
4800 	uint8_t payload_read[10 * 4096];
4801 	uint8_t payload_write[10 * 4096];
4802 	uint64_t write_bytes;
4803 	uint64_t read_bytes;
4804 	uint64_t io_unit;
4805 
4806 	dev = init_dev();
4807 
4808 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
4809 	poll_threads();
4810 	CU_ASSERT(g_bserrno == 0);
4811 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
4812 	bs = g_bs;
4813 	free_clusters = spdk_bs_free_cluster_count(bs);
4814 	page_size = spdk_bs_get_page_size(bs);
4815 
4816 	ut_spdk_blob_opts_init(&opts);
4817 	opts.thin_provision = true;
4818 	opts.num_clusters = 5;
4819 
4820 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
4821 	poll_threads();
4822 	CU_ASSERT(g_bserrno == 0);
4823 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
4824 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
4825 	blobid = g_blobid;
4826 
4827 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
4828 	poll_threads();
4829 	CU_ASSERT(g_bserrno == 0);
4830 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4831 	blob = g_blob;
4832 
4833 	channel = spdk_bs_alloc_io_channel(bs);
4834 	CU_ASSERT(channel != NULL);
4835 
4836 	/* Target specifically second cluster in a blob as first allocation */
4837 	io_unit = _spdk_bs_cluster_to_page(bs, 1) * _spdk_bs_io_unit_per_page(bs);
4838 
4839 	/* Payload should be all zeros from unallocated clusters */
4840 	memset(payload_read, 0xFF, sizeof(payload_read));
4841 	spdk_blob_io_read(blob, channel, payload_read, io_unit, 10, blob_op_complete, NULL);
4842 	poll_threads();
4843 	CU_ASSERT(g_bserrno == 0);
4844 	CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0);
4845 
4846 	write_bytes = g_dev_write_bytes;
4847 	read_bytes = g_dev_read_bytes;
4848 
4849 	/* Issue write to second cluster in a blob */
4850 	memset(payload_write, 0xE5, sizeof(payload_write));
4851 	spdk_blob_io_write(blob, channel, payload_write, io_unit, 10, blob_op_complete, NULL);
4852 	poll_threads();
4853 	CU_ASSERT(g_bserrno == 0);
4854 	CU_ASSERT(free_clusters - 1 == spdk_bs_free_cluster_count(bs));
4855 	/* For thin-provisioned blob we need to write 10 pages plus one page metadata and
4856 	 * read 0 bytes */
4857 	if (g_use_extent_table) {
4858 		/* Add one more page for EXTENT_PAGE write */
4859 		CU_ASSERT(g_dev_write_bytes - write_bytes == page_size * 12);
4860 	} else {
4861 		CU_ASSERT(g_dev_write_bytes - write_bytes == page_size * 11);
4862 	}
4863 	CU_ASSERT(g_dev_read_bytes - read_bytes == 0);
4864 
4865 	spdk_blob_io_read(blob, channel, payload_read, io_unit, 10, blob_op_complete, NULL);
4866 	poll_threads();
4867 	CU_ASSERT(g_bserrno == 0);
4868 	CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0);
4869 
4870 	spdk_bs_free_io_channel(channel);
4871 	poll_threads();
4872 
4873 	spdk_blob_close(blob, blob_op_complete, NULL);
4874 	poll_threads();
4875 	CU_ASSERT(g_bserrno == 0);
4876 
4877 	/* Unload the blob store */
4878 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
4879 	poll_threads();
4880 	CU_ASSERT(g_bserrno == 0);
4881 	g_bs = NULL;
4882 	g_blob = NULL;
4883 	g_blobid = 0;
4884 
4885 	/* Load an existing blob store */
4886 	dev = init_dev();
4887 	spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL);
4888 	poll_threads();
4889 	CU_ASSERT(g_bserrno == 0);
4890 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
4891 
4892 	bs = g_bs;
4893 
4894 	spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
4895 	poll_threads();
4896 	CU_ASSERT(g_bserrno == 0);
4897 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4898 	blob = g_blob;
4899 
4900 	channel = spdk_bs_alloc_io_channel(bs);
4901 	CU_ASSERT(channel != NULL);
4902 
4903 	/* Read second cluster after blob reload to confirm data written */
4904 	spdk_blob_io_read(blob, channel, payload_read, io_unit, 10, blob_op_complete, NULL);
4905 	poll_threads();
4906 	CU_ASSERT(g_bserrno == 0);
4907 	CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0);
4908 
4909 	spdk_bs_free_io_channel(channel);
4910 	poll_threads();
4911 
4912 	spdk_blob_close(blob, blob_op_complete, NULL);
4913 	poll_threads();
4914 	CU_ASSERT(g_bserrno == 0);
4915 
4916 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
4917 	poll_threads();
4918 	CU_ASSERT(g_bserrno == 0);
4919 
4920 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
4921 	poll_threads();
4922 	CU_ASSERT(g_bserrno == 0);
4923 	g_bs = NULL;
4924 }
4925 
4926 static void
4927 blob_thin_prov_rw_iov(void)
4928 {
4929 	static const uint8_t zero[10 * 4096] = { 0 };
4930 	struct spdk_blob_store *bs;
4931 	struct spdk_bs_dev *dev;
4932 	struct spdk_blob *blob;
4933 	struct spdk_io_channel *channel;
4934 	struct spdk_blob_opts opts;
4935 	spdk_blob_id blobid;
4936 	uint64_t free_clusters;
4937 	uint8_t payload_read[10 * 4096];
4938 	uint8_t payload_write[10 * 4096];
4939 	struct iovec iov_read[3];
4940 	struct iovec iov_write[3];
4941 
4942 	dev = init_dev();
4943 
4944 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
4945 	poll_threads();
4946 	CU_ASSERT(g_bserrno == 0);
4947 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
4948 	bs = g_bs;
4949 	free_clusters = spdk_bs_free_cluster_count(bs);
4950 
4951 	channel = spdk_bs_alloc_io_channel(bs);
4952 	CU_ASSERT(channel != NULL);
4953 
4954 	ut_spdk_blob_opts_init(&opts);
4955 	opts.thin_provision = true;
4956 
4957 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
4958 	poll_threads();
4959 	CU_ASSERT(g_bserrno == 0);
4960 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
4961 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
4962 	blobid = g_blobid;
4963 
4964 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
4965 	poll_threads();
4966 	CU_ASSERT(g_bserrno == 0);
4967 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4968 	blob = g_blob;
4969 
4970 	CU_ASSERT(blob->active.num_clusters == 0);
4971 
4972 	/* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */
4973 	spdk_blob_resize(blob, 5, blob_op_complete, NULL);
4974 	poll_threads();
4975 	CU_ASSERT(g_bserrno == 0);
4976 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
4977 	CU_ASSERT(blob->active.num_clusters == 5);
4978 
4979 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
4980 	poll_threads();
4981 	CU_ASSERT(g_bserrno == 0);
4982 	/* Sync must not change anything */
4983 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
4984 	CU_ASSERT(blob->active.num_clusters == 5);
4985 
4986 	/* Payload should be all zeros from unallocated clusters */
4987 	memset(payload_read, 0xAA, sizeof(payload_read));
4988 	iov_read[0].iov_base = payload_read;
4989 	iov_read[0].iov_len = 3 * 4096;
4990 	iov_read[1].iov_base = payload_read + 3 * 4096;
4991 	iov_read[1].iov_len = 4 * 4096;
4992 	iov_read[2].iov_base = payload_read + 7 * 4096;
4993 	iov_read[2].iov_len = 3 * 4096;
4994 	spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL);
4995 	poll_threads();
4996 	CU_ASSERT(g_bserrno == 0);
4997 	CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0);
4998 
4999 	memset(payload_write, 0xE5, sizeof(payload_write));
5000 	iov_write[0].iov_base = payload_write;
5001 	iov_write[0].iov_len = 1 * 4096;
5002 	iov_write[1].iov_base = payload_write + 1 * 4096;
5003 	iov_write[1].iov_len = 5 * 4096;
5004 	iov_write[2].iov_base = payload_write + 6 * 4096;
5005 	iov_write[2].iov_len = 4 * 4096;
5006 
5007 	spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL);
5008 	poll_threads();
5009 	CU_ASSERT(g_bserrno == 0);
5010 
5011 	memset(payload_read, 0xAA, sizeof(payload_read));
5012 	iov_read[0].iov_base = payload_read;
5013 	iov_read[0].iov_len = 3 * 4096;
5014 	iov_read[1].iov_base = payload_read + 3 * 4096;
5015 	iov_read[1].iov_len = 4 * 4096;
5016 	iov_read[2].iov_base = payload_read + 7 * 4096;
5017 	iov_read[2].iov_len = 3 * 4096;
5018 	spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL);
5019 	poll_threads();
5020 	CU_ASSERT(g_bserrno == 0);
5021 	CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0);
5022 
5023 	spdk_blob_close(blob, blob_op_complete, NULL);
5024 	poll_threads();
5025 	CU_ASSERT(g_bserrno == 0);
5026 
5027 	spdk_bs_free_io_channel(channel);
5028 	poll_threads();
5029 
5030 	/* Unload the blob store */
5031 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
5032 	poll_threads();
5033 	CU_ASSERT(g_bserrno == 0);
5034 	g_bs = NULL;
5035 	g_blob = NULL;
5036 	g_blobid = 0;
5037 }
5038 
5039 struct iter_ctx {
5040 	int		current_iter;
5041 	spdk_blob_id	blobid[4];
5042 };
5043 
5044 static void
5045 test_iter(void *arg, struct spdk_blob *blob, int bserrno)
5046 {
5047 	struct iter_ctx *iter_ctx = arg;
5048 	spdk_blob_id blobid;
5049 
5050 	CU_ASSERT(bserrno == 0);
5051 	blobid = spdk_blob_get_id(blob);
5052 	CU_ASSERT(blobid == iter_ctx->blobid[iter_ctx->current_iter++]);
5053 }
5054 
5055 static void
5056 bs_load_iter(void)
5057 {
5058 	struct spdk_bs_dev *dev;
5059 	struct iter_ctx iter_ctx = { 0 };
5060 	struct spdk_blob *blob;
5061 	int i, rc;
5062 	struct spdk_bs_opts opts;
5063 	struct spdk_blob_opts blob_opts;
5064 
5065 	dev = init_dev();
5066 	spdk_bs_opts_init(&opts);
5067 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
5068 
5069 	/* Initialize a new blob store */
5070 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
5071 	poll_threads();
5072 	CU_ASSERT(g_bserrno == 0);
5073 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
5074 
5075 	ut_spdk_blob_opts_init(&blob_opts);
5076 
5077 	for (i = 0; i < 4; i++) {
5078 		g_bserrno = -1;
5079 		g_blobid = SPDK_BLOBID_INVALID;
5080 		spdk_bs_create_blob_ext(g_bs, &blob_opts, blob_op_with_id_complete, NULL);
5081 		poll_threads();
5082 		CU_ASSERT(g_bserrno == 0);
5083 		CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
5084 		iter_ctx.blobid[i] = g_blobid;
5085 
5086 		g_bserrno = -1;
5087 		g_blob = NULL;
5088 		spdk_bs_open_blob(g_bs, g_blobid, blob_op_with_handle_complete, NULL);
5089 		poll_threads();
5090 		CU_ASSERT(g_bserrno == 0);
5091 		CU_ASSERT(g_blob != NULL);
5092 		blob = g_blob;
5093 
5094 		/* Just save the blobid as an xattr for testing purposes. */
5095 		rc = spdk_blob_set_xattr(blob, "blobid", &g_blobid, sizeof(g_blobid));
5096 		CU_ASSERT(rc == 0);
5097 
5098 		/* Resize the blob */
5099 		spdk_blob_resize(blob, i, blob_op_complete, NULL);
5100 		poll_threads();
5101 		CU_ASSERT(g_bserrno == 0);
5102 
5103 		spdk_blob_close(blob, blob_op_complete, NULL);
5104 		poll_threads();
5105 		CU_ASSERT(g_bserrno == 0);
5106 	}
5107 
5108 	g_bserrno = -1;
5109 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
5110 	poll_threads();
5111 	CU_ASSERT(g_bserrno == 0);
5112 
5113 	dev = init_dev();
5114 	spdk_bs_opts_init(&opts);
5115 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
5116 	opts.iter_cb_fn = test_iter;
5117 	opts.iter_cb_arg = &iter_ctx;
5118 
5119 	/* Test blob iteration during load after a clean shutdown. */
5120 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
5121 	poll_threads();
5122 	CU_ASSERT(g_bserrno == 0);
5123 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
5124 
5125 	/* Dirty shutdown */
5126 	_spdk_bs_free(g_bs);
5127 
5128 	dev = init_dev();
5129 	spdk_bs_opts_init(&opts);
5130 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
5131 	opts.iter_cb_fn = test_iter;
5132 	iter_ctx.current_iter = 0;
5133 	opts.iter_cb_arg = &iter_ctx;
5134 
5135 	/* Test blob iteration during load after a dirty shutdown. */
5136 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
5137 	poll_threads();
5138 	CU_ASSERT(g_bserrno == 0);
5139 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
5140 
5141 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
5142 	poll_threads();
5143 	CU_ASSERT(g_bserrno == 0);
5144 	g_bs = NULL;
5145 }
5146 
5147 static void
5148 blob_snapshot_rw(void)
5149 {
5150 	static const uint8_t zero[10 * 4096] = { 0 };
5151 	struct spdk_blob_store *bs;
5152 	struct spdk_bs_dev *dev;
5153 	struct spdk_blob *blob, *snapshot;
5154 	struct spdk_io_channel *channel;
5155 	struct spdk_blob_opts opts;
5156 	spdk_blob_id blobid, snapshotid;
5157 	uint64_t free_clusters;
5158 	uint64_t cluster_size;
5159 	uint64_t page_size;
5160 	uint8_t payload_read[10 * 4096];
5161 	uint8_t payload_write[10 * 4096];
5162 	uint64_t write_bytes;
5163 	uint64_t read_bytes;
5164 
5165 	dev = init_dev();
5166 
5167 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
5168 	poll_threads();
5169 	CU_ASSERT(g_bserrno == 0);
5170 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
5171 	bs = g_bs;
5172 	free_clusters = spdk_bs_free_cluster_count(bs);
5173 	cluster_size = spdk_bs_get_cluster_size(bs);
5174 	page_size = spdk_bs_get_page_size(bs);
5175 
5176 	channel = spdk_bs_alloc_io_channel(bs);
5177 	CU_ASSERT(channel != NULL);
5178 
5179 	ut_spdk_blob_opts_init(&opts);
5180 	opts.thin_provision = true;
5181 	opts.num_clusters = 5;
5182 
5183 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
5184 	poll_threads();
5185 	CU_ASSERT(g_bserrno == 0);
5186 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
5187 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
5188 	blobid = g_blobid;
5189 
5190 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
5191 	poll_threads();
5192 	CU_ASSERT(g_bserrno == 0);
5193 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
5194 	blob = g_blob;
5195 
5196 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5);
5197 
5198 	memset(payload_read, 0xFF, sizeof(payload_read));
5199 	spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL);
5200 	poll_threads();
5201 	CU_ASSERT(g_bserrno == 0);
5202 	CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0);
5203 
5204 	memset(payload_write, 0xE5, sizeof(payload_write));
5205 	spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL);
5206 	poll_threads();
5207 	CU_ASSERT(g_bserrno == 0);
5208 	CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs));
5209 
5210 	/* Create snapshot from blob */
5211 	spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL);
5212 	poll_threads();
5213 	CU_ASSERT(g_bserrno == 0);
5214 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
5215 	snapshotid = g_blobid;
5216 
5217 	spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL);
5218 	poll_threads();
5219 	CU_ASSERT(g_bserrno == 0);
5220 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
5221 	snapshot = g_blob;
5222 	CU_ASSERT(snapshot->data_ro == true);
5223 	CU_ASSERT(snapshot->md_ro == true);
5224 
5225 	CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 5);
5226 
5227 	write_bytes = g_dev_write_bytes;
5228 	read_bytes = g_dev_read_bytes;
5229 
5230 	memset(payload_write, 0xAA, sizeof(payload_write));
5231 	spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL);
5232 	poll_threads();
5233 	CU_ASSERT(g_bserrno == 0);
5234 	CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs));
5235 
5236 	/* For a clone we need to allocate and copy one cluster, update one page of metadata
5237 	 * and then write 10 pages of payload.
5238 	 */
5239 	if (g_use_extent_table) {
5240 		/* Add one more page for EXTENT_PAGE write */
5241 		CU_ASSERT(g_dev_write_bytes - write_bytes == page_size * 12 + cluster_size);
5242 	} else {
5243 		CU_ASSERT(g_dev_write_bytes - write_bytes == page_size * 11 + cluster_size);
5244 	}
5245 	CU_ASSERT(g_dev_read_bytes - read_bytes == cluster_size);
5246 
5247 	spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL);
5248 	poll_threads();
5249 	CU_ASSERT(g_bserrno == 0);
5250 	CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0);
5251 
5252 	/* Data on snapshot should not change after write to clone */
5253 	memset(payload_write, 0xE5, sizeof(payload_write));
5254 	spdk_blob_io_read(snapshot, channel, payload_read, 4, 10, blob_op_complete, NULL);
5255 	poll_threads();
5256 	CU_ASSERT(g_bserrno == 0);
5257 	CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0);
5258 
5259 	spdk_blob_close(blob, blob_op_complete, NULL);
5260 	poll_threads();
5261 	CU_ASSERT(g_bserrno == 0);
5262 
5263 	spdk_blob_close(snapshot, blob_op_complete, NULL);
5264 	poll_threads();
5265 	CU_ASSERT(g_bserrno == 0);
5266 
5267 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
5268 	poll_threads();
5269 	CU_ASSERT(g_bserrno == 0);
5270 
5271 	spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL);
5272 	poll_threads();
5273 	CU_ASSERT(g_bserrno == 0);
5274 
5275 	spdk_bs_free_io_channel(channel);
5276 	poll_threads();
5277 
5278 	/* Unload the blob store */
5279 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
5280 	poll_threads();
5281 	CU_ASSERT(g_bserrno == 0);
5282 	g_bs = NULL;
5283 	g_blob = NULL;
5284 	g_blobid = 0;
5285 }
5286 
5287 static void
5288 blob_snapshot_rw_iov(void)
5289 {
5290 	static const uint8_t zero[10 * 4096] = { 0 };
5291 	struct spdk_blob_store *bs;
5292 	struct spdk_bs_dev *dev;
5293 	struct spdk_blob *blob, *snapshot;
5294 	struct spdk_io_channel *channel;
5295 	struct spdk_blob_opts opts;
5296 	spdk_blob_id blobid, snapshotid;
5297 	uint64_t free_clusters;
5298 	uint8_t payload_read[10 * 4096];
5299 	uint8_t payload_write[10 * 4096];
5300 	struct iovec iov_read[3];
5301 	struct iovec iov_write[3];
5302 
5303 	dev = init_dev();
5304 
5305 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
5306 	poll_threads();
5307 	CU_ASSERT(g_bserrno == 0);
5308 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
5309 	bs = g_bs;
5310 	free_clusters = spdk_bs_free_cluster_count(bs);
5311 
5312 	channel = spdk_bs_alloc_io_channel(bs);
5313 	CU_ASSERT(channel != NULL);
5314 
5315 	ut_spdk_blob_opts_init(&opts);
5316 	opts.thin_provision = true;
5317 	opts.num_clusters = 5;
5318 
5319 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
5320 	poll_threads();
5321 	CU_ASSERT(g_bserrno == 0);
5322 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
5323 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
5324 	blobid = g_blobid;
5325 
5326 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
5327 	poll_threads();
5328 	CU_ASSERT(g_bserrno == 0);
5329 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
5330 	blob = g_blob;
5331 
5332 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5);
5333 
5334 	/* Create snapshot from blob */
5335 	spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL);
5336 	poll_threads();
5337 	CU_ASSERT(g_bserrno == 0);
5338 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
5339 	snapshotid = g_blobid;
5340 
5341 	spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL);
5342 	poll_threads();
5343 	CU_ASSERT(g_bserrno == 0);
5344 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
5345 	snapshot = g_blob;
5346 	CU_ASSERT(snapshot->data_ro == true);
5347 	CU_ASSERT(snapshot->md_ro == true);
5348 	CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 5);
5349 
5350 	/* Payload should be all zeros from unallocated clusters */
5351 	memset(payload_read, 0xAA, sizeof(payload_read));
5352 	iov_read[0].iov_base = payload_read;
5353 	iov_read[0].iov_len = 3 * 4096;
5354 	iov_read[1].iov_base = payload_read + 3 * 4096;
5355 	iov_read[1].iov_len = 4 * 4096;
5356 	iov_read[2].iov_base = payload_read + 7 * 4096;
5357 	iov_read[2].iov_len = 3 * 4096;
5358 	spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL);
5359 	poll_threads();
5360 	CU_ASSERT(g_bserrno == 0);
5361 	CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0);
5362 
5363 	memset(payload_write, 0xE5, sizeof(payload_write));
5364 	iov_write[0].iov_base = payload_write;
5365 	iov_write[0].iov_len = 1 * 4096;
5366 	iov_write[1].iov_base = payload_write + 1 * 4096;
5367 	iov_write[1].iov_len = 5 * 4096;
5368 	iov_write[2].iov_base = payload_write + 6 * 4096;
5369 	iov_write[2].iov_len = 4 * 4096;
5370 
5371 	spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL);
5372 	poll_threads();
5373 	CU_ASSERT(g_bserrno == 0);
5374 
5375 	memset(payload_read, 0xAA, sizeof(payload_read));
5376 	iov_read[0].iov_base = payload_read;
5377 	iov_read[0].iov_len = 3 * 4096;
5378 	iov_read[1].iov_base = payload_read + 3 * 4096;
5379 	iov_read[1].iov_len = 4 * 4096;
5380 	iov_read[2].iov_base = payload_read + 7 * 4096;
5381 	iov_read[2].iov_len = 3 * 4096;
5382 	spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL);
5383 	poll_threads();
5384 	CU_ASSERT(g_bserrno == 0);
5385 	CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0);
5386 
5387 	spdk_blob_close(blob, blob_op_complete, NULL);
5388 	poll_threads();
5389 	CU_ASSERT(g_bserrno == 0);
5390 
5391 	spdk_blob_close(snapshot, blob_op_complete, NULL);
5392 	poll_threads();
5393 	CU_ASSERT(g_bserrno == 0);
5394 
5395 	spdk_bs_free_io_channel(channel);
5396 	poll_threads();
5397 
5398 	/* Unload the blob store */
5399 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
5400 	poll_threads();
5401 	CU_ASSERT(g_bserrno == 0);
5402 	g_bs = NULL;
5403 	g_blob = NULL;
5404 	g_blobid = 0;
5405 }
5406 
5407 /**
5408  * Inflate / decouple parent rw unit tests.
5409  *
5410  * --------------
5411  * original blob:         0         1         2         3         4
5412  *                   ,---------+---------+---------+---------+---------.
5413  *         snapshot  |xxxxxxxxx|xxxxxxxxx|xxxxxxxxx|xxxxxxxxx|    -    |
5414  *                   +---------+---------+---------+---------+---------+
5415  *         snapshot2 |    -    |yyyyyyyyy|    -    |yyyyyyyyy|    -    |
5416  *                   +---------+---------+---------+---------+---------+
5417  *         blob      |    -    |zzzzzzzzz|    -    |    -    |    -    |
5418  *                   '---------+---------+---------+---------+---------'
5419  *                   .         .         .         .         .         .
5420  * --------          .         .         .         .         .         .
5421  * inflate:          .         .         .         .         .         .
5422  *                   ,---------+---------+---------+---------+---------.
5423  *         blob      |xxxxxxxxx|zzzzzzzzz|xxxxxxxxx|yyyyyyyyy|000000000|
5424  *                   '---------+---------+---------+---------+---------'
5425  *
5426  *         NOTE: needs to allocate 4 clusters, thin provisioning removed, dependency
5427  *               on snapshot2 and snapshot removed .         .         .
5428  *                   .         .         .         .         .         .
5429  * ----------------  .         .         .         .         .         .
5430  * decouple parent:  .         .         .         .         .         .
5431  *                   ,---------+---------+---------+---------+---------.
5432  *         snapshot  |xxxxxxxxx|xxxxxxxxx|xxxxxxxxx|xxxxxxxxx|    -    |
5433  *                   +---------+---------+---------+---------+---------+
5434  *         blob      |    -    |zzzzzzzzz|    -    |yyyyyyyyy|    -    |
5435  *                   '---------+---------+---------+---------+---------'
5436  *
5437  *         NOTE: needs to allocate 1 cluster, 3 clusters unallocated, dependency
5438  *               on snapshot2 removed and on snapshot still exists. Snapshot2
5439  *               should remain a clone of snapshot.
5440  */
5441 static void
5442 _blob_inflate_rw(bool decouple_parent)
5443 {
5444 	struct spdk_blob_store *bs;
5445 	struct spdk_bs_dev *dev;
5446 	struct spdk_blob *blob, *snapshot, *snapshot2;
5447 	struct spdk_io_channel *channel;
5448 	struct spdk_blob_opts opts;
5449 	spdk_blob_id blobid, snapshotid, snapshot2id;
5450 	uint64_t free_clusters;
5451 	uint64_t cluster_size;
5452 
5453 	uint64_t payload_size;
5454 	uint8_t *payload_read;
5455 	uint8_t *payload_write;
5456 	uint8_t *payload_clone;
5457 
5458 	uint64_t pages_per_cluster;
5459 	uint64_t pages_per_payload;
5460 
5461 	int i;
5462 	spdk_blob_id ids[2];
5463 	size_t count;
5464 
5465 	dev = init_dev();
5466 
5467 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
5468 	poll_threads();
5469 	CU_ASSERT(g_bserrno == 0);
5470 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
5471 	bs = g_bs;
5472 
5473 	free_clusters = spdk_bs_free_cluster_count(bs);
5474 	cluster_size = spdk_bs_get_cluster_size(bs);
5475 	pages_per_cluster = cluster_size / spdk_bs_get_page_size(bs);
5476 	pages_per_payload = pages_per_cluster * 5;
5477 
5478 	payload_size = cluster_size * 5;
5479 
5480 	payload_read = malloc(payload_size);
5481 	SPDK_CU_ASSERT_FATAL(payload_read != NULL);
5482 
5483 	payload_write = malloc(payload_size);
5484 	SPDK_CU_ASSERT_FATAL(payload_write != NULL);
5485 
5486 	payload_clone = malloc(payload_size);
5487 	SPDK_CU_ASSERT_FATAL(payload_clone != NULL);
5488 
5489 	channel = spdk_bs_alloc_io_channel(bs);
5490 	SPDK_CU_ASSERT_FATAL(channel != NULL);
5491 
5492 	/* Create blob */
5493 	ut_spdk_blob_opts_init(&opts);
5494 	opts.thin_provision = true;
5495 	opts.num_clusters = 5;
5496 
5497 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
5498 	poll_threads();
5499 	CU_ASSERT(g_bserrno == 0);
5500 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
5501 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
5502 	blobid = g_blobid;
5503 
5504 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
5505 	poll_threads();
5506 	CU_ASSERT(g_bserrno == 0);
5507 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
5508 	blob = g_blob;
5509 
5510 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5);
5511 
5512 	/* 1) Initial read should return zeroed payload */
5513 	memset(payload_read, 0xFF, payload_size);
5514 	spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload,
5515 			  blob_op_complete, NULL);
5516 	poll_threads();
5517 	CU_ASSERT(g_bserrno == 0);
5518 	CU_ASSERT(spdk_mem_all_zero(payload_read, payload_size));
5519 
5520 	/* Fill whole blob with a pattern, except last cluster (to be sure it
5521 	 * isn't allocated) */
5522 	memset(payload_write, 0xE5, payload_size - cluster_size);
5523 	spdk_blob_io_write(blob, channel, payload_write, 0, pages_per_payload -
5524 			   pages_per_cluster, blob_op_complete, NULL);
5525 	poll_threads();
5526 	CU_ASSERT(g_bserrno == 0);
5527 	CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs));
5528 
5529 	/* 2) Create snapshot from blob (first level) */
5530 	spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL);
5531 	poll_threads();
5532 	CU_ASSERT(g_bserrno == 0);
5533 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
5534 	snapshotid = g_blobid;
5535 
5536 	spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL);
5537 	poll_threads();
5538 	CU_ASSERT(g_bserrno == 0);
5539 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
5540 	snapshot = g_blob;
5541 	CU_ASSERT(snapshot->data_ro == true);
5542 	CU_ASSERT(snapshot->md_ro == true);
5543 
5544 	CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 5);
5545 
5546 	/* Write every second cluster with a pattern.
5547 	 *
5548 	 * Last cluster shouldn't be written, to be sure that snapshot nor clone
5549 	 * doesn't allocate it.
5550 	 *
5551 	 * payload_clone stores expected result on "blob" read at the time and
5552 	 * is used only to check data consistency on clone before and after
5553 	 * inflation. Initially we fill it with a backing snapshots pattern
5554 	 * used before.
5555 	 */
5556 	memset(payload_clone, 0xE5, payload_size - cluster_size);
5557 	memset(payload_clone + payload_size - cluster_size, 0x00, cluster_size);
5558 	memset(payload_write, 0xAA, payload_size);
5559 	for (i = 1; i < 5; i += 2) {
5560 		spdk_blob_io_write(blob, channel, payload_write, i * pages_per_cluster,
5561 				   pages_per_cluster, blob_op_complete, NULL);
5562 		poll_threads();
5563 		CU_ASSERT(g_bserrno == 0);
5564 
5565 		/* Update expected result */
5566 		memcpy(payload_clone + (cluster_size * i), payload_write,
5567 		       cluster_size);
5568 	}
5569 	CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs));
5570 
5571 	/* Check data consistency on clone */
5572 	memset(payload_read, 0xFF, payload_size);
5573 	spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload,
5574 			  blob_op_complete, NULL);
5575 	poll_threads();
5576 	CU_ASSERT(g_bserrno == 0);
5577 	CU_ASSERT(memcmp(payload_clone, payload_read, payload_size) == 0);
5578 
5579 	/* 3) Create second levels snapshot from blob */
5580 	spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL);
5581 	poll_threads();
5582 	CU_ASSERT(g_bserrno == 0);
5583 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
5584 	snapshot2id = g_blobid;
5585 
5586 	spdk_bs_open_blob(bs, snapshot2id, blob_op_with_handle_complete, NULL);
5587 	poll_threads();
5588 	CU_ASSERT(g_bserrno == 0);
5589 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
5590 	snapshot2 = g_blob;
5591 	CU_ASSERT(snapshot2->data_ro == true);
5592 	CU_ASSERT(snapshot2->md_ro == true);
5593 
5594 	CU_ASSERT(spdk_blob_get_num_clusters(snapshot2) == 5);
5595 
5596 	CU_ASSERT(snapshot2->parent_id == snapshotid);
5597 
5598 	/* Write one cluster on the top level blob. This cluster (1) covers
5599 	 * already allocated cluster in the snapshot2, so shouldn't be inflated
5600 	 * at all */
5601 	spdk_blob_io_write(blob, channel, payload_write, pages_per_cluster,
5602 			   pages_per_cluster, blob_op_complete, NULL);
5603 	poll_threads();
5604 	CU_ASSERT(g_bserrno == 0);
5605 
5606 	/* Update expected result */
5607 	memcpy(payload_clone + cluster_size, payload_write, cluster_size);
5608 
5609 	/* Check data consistency on clone */
5610 	memset(payload_read, 0xFF, payload_size);
5611 	spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload,
5612 			  blob_op_complete, NULL);
5613 	poll_threads();
5614 	CU_ASSERT(g_bserrno == 0);
5615 	CU_ASSERT(memcmp(payload_clone, payload_read, payload_size) == 0);
5616 
5617 
5618 	/* Close all blobs */
5619 	spdk_blob_close(blob, blob_op_complete, NULL);
5620 	poll_threads();
5621 	CU_ASSERT(g_bserrno == 0);
5622 
5623 	spdk_blob_close(snapshot2, blob_op_complete, NULL);
5624 	poll_threads();
5625 	CU_ASSERT(g_bserrno == 0);
5626 
5627 	spdk_blob_close(snapshot, blob_op_complete, NULL);
5628 	poll_threads();
5629 	CU_ASSERT(g_bserrno == 0);
5630 
5631 	/* Check snapshot-clone relations */
5632 	count = 2;
5633 	CU_ASSERT(spdk_blob_get_clones(bs, snapshotid, ids, &count) == 0);
5634 	CU_ASSERT(count == 1);
5635 	CU_ASSERT(ids[0] == snapshot2id);
5636 
5637 	count = 2;
5638 	CU_ASSERT(spdk_blob_get_clones(bs, snapshot2id, ids, &count) == 0);
5639 	CU_ASSERT(count == 1);
5640 	CU_ASSERT(ids[0] == blobid);
5641 
5642 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshot2id);
5643 
5644 	free_clusters = spdk_bs_free_cluster_count(bs);
5645 	if (!decouple_parent) {
5646 		/* Do full blob inflation */
5647 		spdk_bs_inflate_blob(bs, channel, blobid, blob_op_complete, NULL);
5648 		poll_threads();
5649 		CU_ASSERT(g_bserrno == 0);
5650 
5651 		/* All clusters should be inflated (except one already allocated
5652 		 * in a top level blob) */
5653 		CU_ASSERT(spdk_bs_free_cluster_count(bs) == free_clusters - 4);
5654 
5655 		/* Check if relation tree updated correctly */
5656 		count = 2;
5657 		CU_ASSERT(spdk_blob_get_clones(bs, snapshotid, ids, &count) == 0);
5658 
5659 		/* snapshotid have one clone */
5660 		CU_ASSERT(count == 1);
5661 		CU_ASSERT(ids[0] == snapshot2id);
5662 
5663 		/* snapshot2id have no clones */
5664 		count = 2;
5665 		CU_ASSERT(spdk_blob_get_clones(bs, snapshot2id, ids, &count) == 0);
5666 		CU_ASSERT(count == 0);
5667 
5668 		CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == SPDK_BLOBID_INVALID);
5669 	} else {
5670 		/* Decouple parent of blob */
5671 		spdk_bs_blob_decouple_parent(bs, channel, blobid, blob_op_complete, NULL);
5672 		poll_threads();
5673 		CU_ASSERT(g_bserrno == 0);
5674 
5675 		/* Only one cluster from a parent should be inflated (second one
5676 		 * is covered by a cluster written on a top level blob, and
5677 		 * already allocated) */
5678 		CU_ASSERT(spdk_bs_free_cluster_count(bs) == free_clusters - 1);
5679 
5680 		/* Check if relation tree updated correctly */
5681 		count = 2;
5682 		CU_ASSERT(spdk_blob_get_clones(bs, snapshotid, ids, &count) == 0);
5683 
5684 		/* snapshotid have two clones now */
5685 		CU_ASSERT(count == 2);
5686 		CU_ASSERT(ids[0] == blobid || ids[1] == blobid);
5687 		CU_ASSERT(ids[0] == snapshot2id || ids[1] == snapshot2id);
5688 
5689 		/* snapshot2id have no clones */
5690 		count = 2;
5691 		CU_ASSERT(spdk_blob_get_clones(bs, snapshot2id, ids, &count) == 0);
5692 		CU_ASSERT(count == 0);
5693 
5694 		CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid);
5695 	}
5696 
5697 	/* Try to delete snapshot2 (should pass) */
5698 	spdk_bs_delete_blob(bs, snapshot2id, blob_op_complete, NULL);
5699 	poll_threads();
5700 	CU_ASSERT(g_bserrno == 0);
5701 
5702 	/* Try to delete base snapshot */
5703 	spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL);
5704 	poll_threads();
5705 	CU_ASSERT(g_bserrno == 0);
5706 
5707 	/* Reopen blob after snapshot deletion */
5708 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
5709 	poll_threads();
5710 	CU_ASSERT(g_bserrno == 0);
5711 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
5712 	blob = g_blob;
5713 
5714 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5);
5715 
5716 	/* Check data consistency on inflated blob */
5717 	memset(payload_read, 0xFF, payload_size);
5718 	spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload,
5719 			  blob_op_complete, NULL);
5720 	poll_threads();
5721 	CU_ASSERT(g_bserrno == 0);
5722 	CU_ASSERT(memcmp(payload_clone, payload_read, payload_size) == 0);
5723 
5724 	spdk_blob_close(blob, blob_op_complete, NULL);
5725 	poll_threads();
5726 	CU_ASSERT(g_bserrno == 0);
5727 
5728 	spdk_bs_free_io_channel(channel);
5729 	poll_threads();
5730 
5731 	/* Unload the blob store */
5732 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
5733 	poll_threads();
5734 	CU_ASSERT(g_bserrno == 0);
5735 	g_bs = NULL;
5736 	g_blob = NULL;
5737 	g_blobid = 0;
5738 
5739 	free(payload_read);
5740 	free(payload_write);
5741 	free(payload_clone);
5742 }
5743 
5744 static void
5745 blob_inflate_rw(void)
5746 {
5747 	_blob_inflate_rw(false);
5748 	_blob_inflate_rw(true);
5749 }
5750 
5751 /**
5752  * Snapshot-clones relation test
5753  *
5754  *         snapshot
5755  *            |
5756  *      +-----+-----+
5757  *      |           |
5758  *   blob(ro)   snapshot2
5759  *      |           |
5760  *   clone2      clone
5761  */
5762 static void
5763 blob_relations(void)
5764 {
5765 	struct spdk_blob_store *bs;
5766 	struct spdk_bs_dev *dev;
5767 	struct spdk_bs_opts bs_opts;
5768 	struct spdk_blob_opts opts;
5769 	struct spdk_blob *blob, *snapshot, *snapshot2, *clone, *clone2;
5770 	spdk_blob_id blobid, cloneid, snapshotid, cloneid2, snapshotid2;
5771 	int rc;
5772 	size_t count;
5773 	spdk_blob_id ids[10] = {};
5774 
5775 	dev = init_dev();
5776 	spdk_bs_opts_init(&bs_opts);
5777 	snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE");
5778 
5779 	spdk_bs_init(dev, &bs_opts, bs_op_with_handle_complete, NULL);
5780 	poll_threads();
5781 	CU_ASSERT(g_bserrno == 0);
5782 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
5783 	bs = g_bs;
5784 
5785 	/* 1. Create blob with 10 clusters */
5786 
5787 	ut_spdk_blob_opts_init(&opts);
5788 	opts.num_clusters = 10;
5789 
5790 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
5791 	poll_threads();
5792 	CU_ASSERT(g_bserrno == 0);
5793 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
5794 	blobid = g_blobid;
5795 
5796 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
5797 	poll_threads();
5798 	CU_ASSERT(g_bserrno == 0);
5799 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
5800 	blob = g_blob;
5801 
5802 	CU_ASSERT(!spdk_blob_is_read_only(blob));
5803 	CU_ASSERT(!spdk_blob_is_snapshot(blob));
5804 	CU_ASSERT(!spdk_blob_is_clone(blob));
5805 	CU_ASSERT(!spdk_blob_is_thin_provisioned(blob));
5806 
5807 	/* blob should not have underlying snapshot nor clones */
5808 	CU_ASSERT(blob->parent_id == SPDK_BLOBID_INVALID);
5809 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == SPDK_BLOBID_INVALID);
5810 	count = SPDK_COUNTOF(ids);
5811 	rc = spdk_blob_get_clones(bs, blobid, ids, &count);
5812 	CU_ASSERT(rc == 0);
5813 	CU_ASSERT(count == 0);
5814 
5815 
5816 	/* 2. Create snapshot */
5817 
5818 	spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL);
5819 	poll_threads();
5820 	CU_ASSERT(g_bserrno == 0);
5821 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
5822 	snapshotid = g_blobid;
5823 
5824 	spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL);
5825 	poll_threads();
5826 	CU_ASSERT(g_bserrno == 0);
5827 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
5828 	snapshot = g_blob;
5829 
5830 	CU_ASSERT(spdk_blob_is_read_only(snapshot));
5831 	CU_ASSERT(spdk_blob_is_snapshot(snapshot));
5832 	CU_ASSERT(!spdk_blob_is_clone(snapshot));
5833 	CU_ASSERT(snapshot->parent_id == SPDK_BLOBID_INVALID);
5834 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid) == SPDK_BLOBID_INVALID);
5835 
5836 	/* Check if original blob is converted to the clone of snapshot */
5837 	CU_ASSERT(!spdk_blob_is_read_only(blob));
5838 	CU_ASSERT(!spdk_blob_is_snapshot(blob));
5839 	CU_ASSERT(spdk_blob_is_clone(blob));
5840 	CU_ASSERT(spdk_blob_is_thin_provisioned(blob));
5841 	CU_ASSERT(blob->parent_id == snapshotid);
5842 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid);
5843 
5844 	count = SPDK_COUNTOF(ids);
5845 	rc = spdk_blob_get_clones(bs, snapshotid, ids, &count);
5846 	CU_ASSERT(rc == 0);
5847 	CU_ASSERT(count == 1);
5848 	CU_ASSERT(ids[0] == blobid);
5849 
5850 
5851 	/* 3. Create clone from snapshot */
5852 
5853 	spdk_bs_create_clone(bs, snapshotid, NULL, blob_op_with_id_complete, NULL);
5854 	poll_threads();
5855 	CU_ASSERT(g_bserrno == 0);
5856 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
5857 	cloneid = g_blobid;
5858 
5859 	spdk_bs_open_blob(bs, cloneid, blob_op_with_handle_complete, NULL);
5860 	poll_threads();
5861 	CU_ASSERT(g_bserrno == 0);
5862 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
5863 	clone = g_blob;
5864 
5865 	CU_ASSERT(!spdk_blob_is_read_only(clone));
5866 	CU_ASSERT(!spdk_blob_is_snapshot(clone));
5867 	CU_ASSERT(spdk_blob_is_clone(clone));
5868 	CU_ASSERT(spdk_blob_is_thin_provisioned(clone));
5869 	CU_ASSERT(clone->parent_id == snapshotid);
5870 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid);
5871 
5872 	count = SPDK_COUNTOF(ids);
5873 	rc = spdk_blob_get_clones(bs, cloneid, ids, &count);
5874 	CU_ASSERT(rc == 0);
5875 	CU_ASSERT(count == 0);
5876 
5877 	/* Check if clone is on the snapshot's list */
5878 	count = SPDK_COUNTOF(ids);
5879 	rc = spdk_blob_get_clones(bs, snapshotid, ids, &count);
5880 	CU_ASSERT(rc == 0);
5881 	CU_ASSERT(ids[0] == blobid || ids[1] == blobid);
5882 	CU_ASSERT(ids[0] == cloneid || ids[1] == cloneid);
5883 
5884 
5885 	/* 4. Create snapshot of the clone */
5886 
5887 	spdk_bs_create_snapshot(bs, cloneid, NULL, blob_op_with_id_complete, NULL);
5888 	poll_threads();
5889 	CU_ASSERT(g_bserrno == 0);
5890 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
5891 	snapshotid2 = g_blobid;
5892 
5893 	spdk_bs_open_blob(bs, snapshotid2, blob_op_with_handle_complete, NULL);
5894 	poll_threads();
5895 	CU_ASSERT(g_bserrno == 0);
5896 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
5897 	snapshot2 = g_blob;
5898 
5899 	CU_ASSERT(spdk_blob_is_read_only(snapshot2));
5900 	CU_ASSERT(spdk_blob_is_snapshot(snapshot2));
5901 	CU_ASSERT(spdk_blob_is_clone(snapshot2));
5902 	CU_ASSERT(snapshot2->parent_id == snapshotid);
5903 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid2) == snapshotid);
5904 
5905 	/* Check if clone is converted to the clone of snapshot2 and snapshot2
5906 	 * is a child of snapshot */
5907 	CU_ASSERT(!spdk_blob_is_read_only(clone));
5908 	CU_ASSERT(!spdk_blob_is_snapshot(clone));
5909 	CU_ASSERT(spdk_blob_is_clone(clone));
5910 	CU_ASSERT(spdk_blob_is_thin_provisioned(clone));
5911 	CU_ASSERT(clone->parent_id == snapshotid2);
5912 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid2);
5913 
5914 	count = SPDK_COUNTOF(ids);
5915 	rc = spdk_blob_get_clones(bs, snapshotid2, ids, &count);
5916 	CU_ASSERT(rc == 0);
5917 	CU_ASSERT(count == 1);
5918 	CU_ASSERT(ids[0] == cloneid);
5919 
5920 
5921 	/* 5. Try to create clone from read only blob */
5922 
5923 	/* Mark blob as read only */
5924 	spdk_blob_set_read_only(blob);
5925 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
5926 	poll_threads();
5927 	CU_ASSERT(g_bserrno == 0);
5928 
5929 	/* Check if previously created blob is read only clone */
5930 	CU_ASSERT(spdk_blob_is_read_only(blob));
5931 	CU_ASSERT(!spdk_blob_is_snapshot(blob));
5932 	CU_ASSERT(spdk_blob_is_clone(blob));
5933 	CU_ASSERT(spdk_blob_is_thin_provisioned(blob));
5934 
5935 	/* Create clone from read only blob */
5936 	spdk_bs_create_clone(bs, blobid, NULL, blob_op_with_id_complete, NULL);
5937 	poll_threads();
5938 	CU_ASSERT(g_bserrno == 0);
5939 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
5940 	cloneid2 = g_blobid;
5941 
5942 	spdk_bs_open_blob(bs, cloneid2, blob_op_with_handle_complete, NULL);
5943 	poll_threads();
5944 	CU_ASSERT(g_bserrno == 0);
5945 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
5946 	clone2 = g_blob;
5947 
5948 	CU_ASSERT(!spdk_blob_is_read_only(clone2));
5949 	CU_ASSERT(!spdk_blob_is_snapshot(clone2));
5950 	CU_ASSERT(spdk_blob_is_clone(clone2));
5951 	CU_ASSERT(spdk_blob_is_thin_provisioned(clone2));
5952 
5953 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid2) == blobid);
5954 
5955 	count = SPDK_COUNTOF(ids);
5956 	rc = spdk_blob_get_clones(bs, blobid, ids, &count);
5957 	CU_ASSERT(rc == 0);
5958 
5959 	CU_ASSERT(count == 1);
5960 	CU_ASSERT(ids[0] == cloneid2);
5961 
5962 	/* Close blobs */
5963 
5964 	spdk_blob_close(clone2, blob_op_complete, NULL);
5965 	poll_threads();
5966 	CU_ASSERT(g_bserrno == 0);
5967 
5968 	spdk_blob_close(blob, blob_op_complete, NULL);
5969 	poll_threads();
5970 	CU_ASSERT(g_bserrno == 0);
5971 
5972 	spdk_blob_close(clone, blob_op_complete, NULL);
5973 	poll_threads();
5974 	CU_ASSERT(g_bserrno == 0);
5975 
5976 	spdk_blob_close(snapshot, blob_op_complete, NULL);
5977 	poll_threads();
5978 	CU_ASSERT(g_bserrno == 0);
5979 
5980 	spdk_blob_close(snapshot2, blob_op_complete, NULL);
5981 	poll_threads();
5982 	CU_ASSERT(g_bserrno == 0);
5983 
5984 	/* Try to delete snapshot with more than 1 clone */
5985 	spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL);
5986 	poll_threads();
5987 	CU_ASSERT(g_bserrno != 0);
5988 
5989 	spdk_bs_unload(bs, bs_op_complete, NULL);
5990 	poll_threads();
5991 	CU_ASSERT(g_bserrno == 0);
5992 	g_bs = NULL;
5993 
5994 	/* Load an existing blob store */
5995 	dev = init_dev();
5996 	snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE");
5997 
5998 	spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL);
5999 	poll_threads();
6000 	CU_ASSERT(g_bserrno == 0);
6001 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
6002 	bs = g_bs;
6003 
6004 
6005 	/* NULL ids array should return number of clones in count */
6006 	count = SPDK_COUNTOF(ids);
6007 	rc = spdk_blob_get_clones(bs, snapshotid, NULL, &count);
6008 	CU_ASSERT(rc == -ENOMEM);
6009 	CU_ASSERT(count == 2);
6010 
6011 	/* incorrect array size */
6012 	count = 1;
6013 	rc = spdk_blob_get_clones(bs, snapshotid, ids, &count);
6014 	CU_ASSERT(rc == -ENOMEM);
6015 	CU_ASSERT(count == 2);
6016 
6017 
6018 	/* Verify structure of loaded blob store */
6019 
6020 	/* snapshot */
6021 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid) == SPDK_BLOBID_INVALID);
6022 
6023 	count = SPDK_COUNTOF(ids);
6024 	rc = spdk_blob_get_clones(bs, snapshotid, ids, &count);
6025 	CU_ASSERT(rc == 0);
6026 	CU_ASSERT(count == 2);
6027 	CU_ASSERT(ids[0] == blobid || ids[1] == blobid);
6028 	CU_ASSERT(ids[0] == snapshotid2 || ids[1] == snapshotid2);
6029 
6030 	/* blob */
6031 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid);
6032 	count = SPDK_COUNTOF(ids);
6033 	rc = spdk_blob_get_clones(bs, blobid, ids, &count);
6034 	CU_ASSERT(rc == 0);
6035 	CU_ASSERT(count == 1);
6036 	CU_ASSERT(ids[0] == cloneid2);
6037 
6038 	/* clone */
6039 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid2);
6040 	count = SPDK_COUNTOF(ids);
6041 	rc = spdk_blob_get_clones(bs, cloneid, ids, &count);
6042 	CU_ASSERT(rc == 0);
6043 	CU_ASSERT(count == 0);
6044 
6045 	/* snapshot2 */
6046 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid2) == snapshotid);
6047 	count = SPDK_COUNTOF(ids);
6048 	rc = spdk_blob_get_clones(bs, snapshotid2, ids, &count);
6049 	CU_ASSERT(rc == 0);
6050 	CU_ASSERT(count == 1);
6051 	CU_ASSERT(ids[0] == cloneid);
6052 
6053 	/* clone2 */
6054 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid2) == blobid);
6055 	count = SPDK_COUNTOF(ids);
6056 	rc = spdk_blob_get_clones(bs, cloneid2, ids, &count);
6057 	CU_ASSERT(rc == 0);
6058 	CU_ASSERT(count == 0);
6059 
6060 	/* Try to delete blob that user should not be able to remove */
6061 
6062 	spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL);
6063 	poll_threads();
6064 	CU_ASSERT(g_bserrno != 0);
6065 
6066 	/* Remove all blobs */
6067 
6068 	spdk_bs_delete_blob(bs, cloneid, blob_op_complete, NULL);
6069 	poll_threads();
6070 	CU_ASSERT(g_bserrno == 0);
6071 
6072 	spdk_bs_delete_blob(bs, snapshotid2, blob_op_complete, NULL);
6073 	poll_threads();
6074 	CU_ASSERT(g_bserrno == 0);
6075 
6076 	spdk_bs_delete_blob(bs, cloneid2, blob_op_complete, NULL);
6077 	poll_threads();
6078 	CU_ASSERT(g_bserrno == 0);
6079 
6080 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
6081 	poll_threads();
6082 	CU_ASSERT(g_bserrno == 0);
6083 
6084 	spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL);
6085 	poll_threads();
6086 	CU_ASSERT(g_bserrno == 0);
6087 
6088 	spdk_bs_unload(bs, bs_op_complete, NULL);
6089 	poll_threads();
6090 	CU_ASSERT(g_bserrno == 0);
6091 
6092 	g_bs = NULL;
6093 }
6094 
6095 /**
6096  * Snapshot-clones relation test 2
6097  *
6098  *         snapshot1
6099  *            |
6100  *         snapshot2
6101  *            |
6102  *      +-----+-----+
6103  *      |           |
6104  *   blob(ro)   snapshot3
6105  *      |           |
6106  *      |       snapshot4
6107  *      |        |     |
6108  *   clone2   clone  clone3
6109  */
6110 static void
6111 blob_relations2(void)
6112 {
6113 	struct spdk_blob_store *bs;
6114 	struct spdk_bs_dev *dev;
6115 	struct spdk_bs_opts bs_opts;
6116 	struct spdk_blob_opts opts;
6117 	struct spdk_blob *blob, *snapshot1, *snapshot2, *snapshot3, *snapshot4, *clone, *clone2;
6118 	spdk_blob_id blobid, snapshotid1, snapshotid2, snapshotid3, snapshotid4, cloneid, cloneid2,
6119 		     cloneid3;
6120 	int rc;
6121 	size_t count;
6122 	spdk_blob_id ids[10] = {};
6123 
6124 	dev = init_dev();
6125 	spdk_bs_opts_init(&bs_opts);
6126 	snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE");
6127 
6128 	spdk_bs_init(dev, &bs_opts, bs_op_with_handle_complete, NULL);
6129 	poll_threads();
6130 	CU_ASSERT(g_bserrno == 0);
6131 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
6132 	bs = g_bs;
6133 
6134 	/* 1. Create blob with 10 clusters */
6135 
6136 	ut_spdk_blob_opts_init(&opts);
6137 	opts.num_clusters = 10;
6138 
6139 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
6140 	poll_threads();
6141 	CU_ASSERT(g_bserrno == 0);
6142 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
6143 	blobid = g_blobid;
6144 
6145 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
6146 	poll_threads();
6147 	CU_ASSERT(g_bserrno == 0);
6148 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
6149 	blob = g_blob;
6150 
6151 	/* 2. Create snapshot1 */
6152 
6153 	spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL);
6154 	poll_threads();
6155 	CU_ASSERT(g_bserrno == 0);
6156 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
6157 	snapshotid1 = g_blobid;
6158 
6159 	spdk_bs_open_blob(bs, snapshotid1, blob_op_with_handle_complete, NULL);
6160 	poll_threads();
6161 	CU_ASSERT(g_bserrno == 0);
6162 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
6163 	snapshot1 = g_blob;
6164 
6165 	CU_ASSERT(snapshot1->parent_id == SPDK_BLOBID_INVALID);
6166 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid1) == SPDK_BLOBID_INVALID);
6167 
6168 	CU_ASSERT(blob->parent_id == snapshotid1);
6169 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid1);
6170 
6171 	/* Check if blob is the clone of snapshot1 */
6172 	CU_ASSERT(blob->parent_id == snapshotid1);
6173 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid1);
6174 
6175 	count = SPDK_COUNTOF(ids);
6176 	rc = spdk_blob_get_clones(bs, snapshotid1, ids, &count);
6177 	CU_ASSERT(rc == 0);
6178 	CU_ASSERT(count == 1);
6179 	CU_ASSERT(ids[0] == blobid);
6180 
6181 	/* 3. Create another snapshot */
6182 
6183 	spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL);
6184 	poll_threads();
6185 	CU_ASSERT(g_bserrno == 0);
6186 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
6187 	snapshotid2 = g_blobid;
6188 
6189 	spdk_bs_open_blob(bs, snapshotid2, blob_op_with_handle_complete, NULL);
6190 	poll_threads();
6191 	CU_ASSERT(g_bserrno == 0);
6192 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
6193 	snapshot2 = g_blob;
6194 
6195 	CU_ASSERT(spdk_blob_is_clone(snapshot2));
6196 	CU_ASSERT(snapshot2->parent_id == snapshotid1);
6197 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid2) == snapshotid1);
6198 
6199 	/* Check if snapshot2 is the clone of snapshot1 and blob
6200 	 * is a child of snapshot2 */
6201 	CU_ASSERT(blob->parent_id == snapshotid2);
6202 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid2);
6203 
6204 	count = SPDK_COUNTOF(ids);
6205 	rc = spdk_blob_get_clones(bs, snapshotid2, ids, &count);
6206 	CU_ASSERT(rc == 0);
6207 	CU_ASSERT(count == 1);
6208 	CU_ASSERT(ids[0] == blobid);
6209 
6210 	/* 4. Create clone from snapshot */
6211 
6212 	spdk_bs_create_clone(bs, snapshotid2, NULL, blob_op_with_id_complete, NULL);
6213 	poll_threads();
6214 	CU_ASSERT(g_bserrno == 0);
6215 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
6216 	cloneid = g_blobid;
6217 
6218 	spdk_bs_open_blob(bs, cloneid, blob_op_with_handle_complete, NULL);
6219 	poll_threads();
6220 	CU_ASSERT(g_bserrno == 0);
6221 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
6222 	clone = g_blob;
6223 
6224 	CU_ASSERT(clone->parent_id == snapshotid2);
6225 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid2);
6226 
6227 	/* Check if clone is on the snapshot's list */
6228 	count = SPDK_COUNTOF(ids);
6229 	rc = spdk_blob_get_clones(bs, snapshotid2, ids, &count);
6230 	CU_ASSERT(rc == 0);
6231 	CU_ASSERT(count == 2);
6232 	CU_ASSERT(ids[0] == blobid || ids[1] == blobid);
6233 	CU_ASSERT(ids[0] == cloneid || ids[1] == cloneid);
6234 
6235 	/* 5. Create snapshot of the clone */
6236 
6237 	spdk_bs_create_snapshot(bs, cloneid, NULL, blob_op_with_id_complete, NULL);
6238 	poll_threads();
6239 	CU_ASSERT(g_bserrno == 0);
6240 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
6241 	snapshotid3 = g_blobid;
6242 
6243 	spdk_bs_open_blob(bs, snapshotid3, blob_op_with_handle_complete, NULL);
6244 	poll_threads();
6245 	CU_ASSERT(g_bserrno == 0);
6246 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
6247 	snapshot3 = g_blob;
6248 
6249 	CU_ASSERT(snapshot3->parent_id == snapshotid2);
6250 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid3) == snapshotid2);
6251 
6252 	/* Check if clone is converted to the clone of snapshot3 and snapshot3
6253 	 * is a child of snapshot2 */
6254 	CU_ASSERT(clone->parent_id == snapshotid3);
6255 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid3);
6256 
6257 	count = SPDK_COUNTOF(ids);
6258 	rc = spdk_blob_get_clones(bs, snapshotid3, ids, &count);
6259 	CU_ASSERT(rc == 0);
6260 	CU_ASSERT(count == 1);
6261 	CU_ASSERT(ids[0] == cloneid);
6262 
6263 	/* 6. Create another snapshot of the clone */
6264 
6265 	spdk_bs_create_snapshot(bs, cloneid, NULL, blob_op_with_id_complete, NULL);
6266 	poll_threads();
6267 	CU_ASSERT(g_bserrno == 0);
6268 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
6269 	snapshotid4 = g_blobid;
6270 
6271 	spdk_bs_open_blob(bs, snapshotid4, blob_op_with_handle_complete, NULL);
6272 	poll_threads();
6273 	CU_ASSERT(g_bserrno == 0);
6274 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
6275 	snapshot4 = g_blob;
6276 
6277 	CU_ASSERT(snapshot4->parent_id == snapshotid3);
6278 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid4) == snapshotid3);
6279 
6280 	/* Check if clone is converted to the clone of snapshot4 and snapshot4
6281 	 * is a child of snapshot3 */
6282 	CU_ASSERT(clone->parent_id == snapshotid4);
6283 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid4);
6284 
6285 	count = SPDK_COUNTOF(ids);
6286 	rc = spdk_blob_get_clones(bs, snapshotid4, ids, &count);
6287 	CU_ASSERT(rc == 0);
6288 	CU_ASSERT(count == 1);
6289 	CU_ASSERT(ids[0] == cloneid);
6290 
6291 	/* 7. Remove snapshot 4 */
6292 
6293 	spdk_blob_close(snapshot4, blob_op_complete, NULL);
6294 	poll_threads();
6295 	CU_ASSERT(g_bserrno == 0);
6296 
6297 	spdk_bs_delete_blob(bs, snapshotid4, blob_op_complete, NULL);
6298 	poll_threads();
6299 	CU_ASSERT(g_bserrno == 0);
6300 
6301 	/* Check if relations are back to state from before creating snapshot 4 */
6302 	CU_ASSERT(clone->parent_id == snapshotid3);
6303 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid3);
6304 
6305 	count = SPDK_COUNTOF(ids);
6306 	rc = spdk_blob_get_clones(bs, snapshotid3, ids, &count);
6307 	CU_ASSERT(rc == 0);
6308 	CU_ASSERT(count == 1);
6309 	CU_ASSERT(ids[0] == cloneid);
6310 
6311 	/* 8. Create second clone of snapshot 3 and try to remove snapshot 3 */
6312 
6313 	spdk_bs_create_clone(bs, snapshotid3, NULL, blob_op_with_id_complete, NULL);
6314 	poll_threads();
6315 	CU_ASSERT(g_bserrno == 0);
6316 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
6317 	cloneid3 = g_blobid;
6318 
6319 	spdk_bs_delete_blob(bs, snapshotid3, blob_op_complete, NULL);
6320 	poll_threads();
6321 	CU_ASSERT(g_bserrno != 0);
6322 
6323 	/* 9. Open snapshot 3 again and try to remove it while clone 3 is closed */
6324 
6325 	spdk_bs_open_blob(bs, snapshotid3, blob_op_with_handle_complete, NULL);
6326 	poll_threads();
6327 	CU_ASSERT(g_bserrno == 0);
6328 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
6329 	snapshot3 = g_blob;
6330 
6331 	spdk_bs_delete_blob(bs, snapshotid3, blob_op_complete, NULL);
6332 	poll_threads();
6333 	CU_ASSERT(g_bserrno != 0);
6334 
6335 	spdk_blob_close(snapshot3, blob_op_complete, NULL);
6336 	poll_threads();
6337 	CU_ASSERT(g_bserrno == 0);
6338 
6339 	spdk_bs_delete_blob(bs, cloneid3, blob_op_complete, NULL);
6340 	poll_threads();
6341 	CU_ASSERT(g_bserrno == 0);
6342 
6343 	/* 10. Remove snapshot 1 */
6344 
6345 	spdk_blob_close(snapshot1, blob_op_complete, NULL);
6346 	poll_threads();
6347 	CU_ASSERT(g_bserrno == 0);
6348 
6349 	spdk_bs_delete_blob(bs, snapshotid1, blob_op_complete, NULL);
6350 	poll_threads();
6351 	CU_ASSERT(g_bserrno == 0);
6352 
6353 	/* Check if relations are back to state from before creating snapshot 4 (before step 6) */
6354 	CU_ASSERT(snapshot2->parent_id == SPDK_BLOBID_INVALID);
6355 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid2) == SPDK_BLOBID_INVALID);
6356 
6357 	count = SPDK_COUNTOF(ids);
6358 	rc = spdk_blob_get_clones(bs, snapshotid2, ids, &count);
6359 	CU_ASSERT(rc == 0);
6360 	CU_ASSERT(count == 2);
6361 	CU_ASSERT(ids[0] == blobid || ids[1] == blobid);
6362 	CU_ASSERT(ids[0] == snapshotid3 || ids[1] == snapshotid3);
6363 
6364 	/* 11. Try to create clone from read only blob */
6365 
6366 	/* Mark blob as read only */
6367 	spdk_blob_set_read_only(blob);
6368 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
6369 	poll_threads();
6370 	CU_ASSERT(g_bserrno == 0);
6371 
6372 	/* Create clone from read only blob */
6373 	spdk_bs_create_clone(bs, blobid, NULL, blob_op_with_id_complete, NULL);
6374 	poll_threads();
6375 	CU_ASSERT(g_bserrno == 0);
6376 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
6377 	cloneid2 = g_blobid;
6378 
6379 	spdk_bs_open_blob(bs, cloneid2, blob_op_with_handle_complete, NULL);
6380 	poll_threads();
6381 	CU_ASSERT(g_bserrno == 0);
6382 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
6383 	clone2 = g_blob;
6384 
6385 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid2) == blobid);
6386 
6387 	count = SPDK_COUNTOF(ids);
6388 	rc = spdk_blob_get_clones(bs, blobid, ids, &count);
6389 	CU_ASSERT(rc == 0);
6390 	CU_ASSERT(count == 1);
6391 	CU_ASSERT(ids[0] == cloneid2);
6392 
6393 	/* Close blobs */
6394 
6395 	spdk_blob_close(clone2, blob_op_complete, NULL);
6396 	poll_threads();
6397 	CU_ASSERT(g_bserrno == 0);
6398 
6399 	spdk_blob_close(blob, blob_op_complete, NULL);
6400 	poll_threads();
6401 	CU_ASSERT(g_bserrno == 0);
6402 
6403 	spdk_blob_close(clone, blob_op_complete, NULL);
6404 	poll_threads();
6405 	CU_ASSERT(g_bserrno == 0);
6406 
6407 	spdk_blob_close(snapshot2, blob_op_complete, NULL);
6408 	poll_threads();
6409 	CU_ASSERT(g_bserrno == 0);
6410 
6411 	spdk_blob_close(snapshot3, blob_op_complete, NULL);
6412 	poll_threads();
6413 	CU_ASSERT(g_bserrno == 0);
6414 
6415 	spdk_bs_unload(bs, bs_op_complete, NULL);
6416 	poll_threads();
6417 	CU_ASSERT(g_bserrno == 0);
6418 	g_bs = NULL;
6419 
6420 	/* Load an existing blob store */
6421 	dev = init_dev();
6422 	snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE");
6423 
6424 	spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL);
6425 	poll_threads();
6426 	CU_ASSERT(g_bserrno == 0);
6427 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
6428 	bs = g_bs;
6429 
6430 	/* Verify structure of loaded blob store */
6431 
6432 	/* snapshot2 */
6433 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid2) == SPDK_BLOBID_INVALID);
6434 
6435 	count = SPDK_COUNTOF(ids);
6436 	rc = spdk_blob_get_clones(bs, snapshotid2, ids, &count);
6437 	CU_ASSERT(rc == 0);
6438 	CU_ASSERT(count == 2);
6439 	CU_ASSERT(ids[0] == blobid || ids[1] == blobid);
6440 	CU_ASSERT(ids[0] == snapshotid3 || ids[1] == snapshotid3);
6441 
6442 	/* blob */
6443 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid2);
6444 	count = SPDK_COUNTOF(ids);
6445 	rc = spdk_blob_get_clones(bs, blobid, ids, &count);
6446 	CU_ASSERT(rc == 0);
6447 	CU_ASSERT(count == 1);
6448 	CU_ASSERT(ids[0] == cloneid2);
6449 
6450 	/* clone */
6451 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid3);
6452 	count = SPDK_COUNTOF(ids);
6453 	rc = spdk_blob_get_clones(bs, cloneid, ids, &count);
6454 	CU_ASSERT(rc == 0);
6455 	CU_ASSERT(count == 0);
6456 
6457 	/* snapshot3 */
6458 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid3) == snapshotid2);
6459 	count = SPDK_COUNTOF(ids);
6460 	rc = spdk_blob_get_clones(bs, snapshotid3, ids, &count);
6461 	CU_ASSERT(rc == 0);
6462 	CU_ASSERT(count == 1);
6463 	CU_ASSERT(ids[0] == cloneid);
6464 
6465 	/* clone2 */
6466 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid2) == blobid);
6467 	count = SPDK_COUNTOF(ids);
6468 	rc = spdk_blob_get_clones(bs, cloneid2, ids, &count);
6469 	CU_ASSERT(rc == 0);
6470 	CU_ASSERT(count == 0);
6471 
6472 	/* Try to delete all blobs in the worse possible order */
6473 
6474 	spdk_bs_delete_blob(bs, snapshotid2, blob_op_complete, NULL);
6475 	poll_threads();
6476 	CU_ASSERT(g_bserrno != 0);
6477 
6478 	spdk_bs_delete_blob(bs, snapshotid3, blob_op_complete, NULL);
6479 	poll_threads();
6480 	CU_ASSERT(g_bserrno == 0);
6481 
6482 	spdk_bs_delete_blob(bs, snapshotid2, blob_op_complete, NULL);
6483 	poll_threads();
6484 	CU_ASSERT(g_bserrno != 0);
6485 
6486 	spdk_bs_delete_blob(bs, cloneid, blob_op_complete, NULL);
6487 	poll_threads();
6488 	CU_ASSERT(g_bserrno == 0);
6489 
6490 	spdk_bs_delete_blob(bs, snapshotid2, blob_op_complete, NULL);
6491 	poll_threads();
6492 	CU_ASSERT(g_bserrno == 0);
6493 
6494 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
6495 	poll_threads();
6496 	CU_ASSERT(g_bserrno == 0);
6497 
6498 	spdk_bs_delete_blob(bs, cloneid2, blob_op_complete, NULL);
6499 	poll_threads();
6500 	CU_ASSERT(g_bserrno == 0);
6501 
6502 	spdk_bs_unload(bs, bs_op_complete, NULL);
6503 	poll_threads();
6504 	CU_ASSERT(g_bserrno == 0);
6505 
6506 	g_bs = NULL;
6507 }
6508 
6509 static void
6510 blob_delete_snapshot_power_failure(void)
6511 {
6512 	struct spdk_blob_store *bs;
6513 	struct spdk_bs_dev *dev;
6514 	struct spdk_blob_opts opts;
6515 	struct spdk_blob *blob, *snapshot;
6516 	struct spdk_power_failure_thresholds thresholds = {};
6517 	spdk_blob_id blobid, snapshotid;
6518 	const void *value;
6519 	size_t value_len;
6520 	size_t count;
6521 	spdk_blob_id ids[3] = {};
6522 	int rc;
6523 	bool deleted = false;
6524 
6525 	dev = init_dev();
6526 
6527 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
6528 	poll_threads();
6529 	CU_ASSERT(g_bserrno == 0);
6530 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
6531 	bs = g_bs;
6532 
6533 	/* Create blob */
6534 	ut_spdk_blob_opts_init(&opts);
6535 	opts.num_clusters = 10;
6536 
6537 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
6538 	poll_threads();
6539 	CU_ASSERT(g_bserrno == 0);
6540 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
6541 	blobid = g_blobid;
6542 
6543 	/* Create snapshot */
6544 	spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL);
6545 	poll_threads();
6546 	CU_ASSERT(g_bserrno == 0);
6547 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
6548 	snapshotid = g_blobid;
6549 	SPDK_CU_ASSERT_FATAL(spdk_bit_array_get(bs->used_clusters, 1));
6550 	SPDK_CU_ASSERT_FATAL(!spdk_bit_array_get(bs->used_clusters, 11));
6551 
6552 	thresholds.general_threshold = 1;
6553 	while (!deleted) {
6554 		dev_set_power_failure_thresholds(thresholds);
6555 
6556 		spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL);
6557 		poll_threads();
6558 
6559 		/* Do not shut down cleanly. Assumption is that after snapshot deletion
6560 		 * reports success, changes to both blobs should already persisted. */
6561 		_spdk_bs_free(bs);
6562 
6563 		dev_reset_power_failure_event();
6564 
6565 		dev = init_dev();
6566 		spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL);
6567 		poll_threads();
6568 		CU_ASSERT(g_bserrno == 0);
6569 		SPDK_CU_ASSERT_FATAL(g_bs != NULL);
6570 		bs = g_bs;
6571 		SPDK_CU_ASSERT_FATAL(spdk_bit_array_get(bs->used_clusters, 1));
6572 		SPDK_CU_ASSERT_FATAL(!spdk_bit_array_get(bs->used_clusters, 11));
6573 
6574 		spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
6575 		poll_threads();
6576 		CU_ASSERT(g_bserrno == 0);
6577 		SPDK_CU_ASSERT_FATAL(g_blob != NULL);
6578 		blob = g_blob;
6579 		SPDK_CU_ASSERT_FATAL(spdk_blob_is_thin_provisioned(blob) == true);
6580 
6581 		spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL);
6582 		poll_threads();
6583 
6584 		if (g_bserrno == 0) {
6585 			SPDK_CU_ASSERT_FATAL(g_blob != NULL);
6586 			snapshot = g_blob;
6587 			CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid);
6588 			count = SPDK_COUNTOF(ids);
6589 			rc = spdk_blob_get_clones(bs, snapshotid, ids, &count);
6590 			CU_ASSERT(rc == 0);
6591 			CU_ASSERT(count == 1);
6592 			CU_ASSERT(ids[0] == blobid);
6593 			rc = spdk_blob_get_xattr_value(snapshot, SNAPSHOT_PENDING_REMOVAL, &value, &value_len);
6594 			CU_ASSERT(rc != 0);
6595 			SPDK_CU_ASSERT_FATAL(spdk_blob_is_thin_provisioned(snapshot) == false);
6596 
6597 			spdk_blob_close(snapshot, blob_op_complete, NULL);
6598 			poll_threads();
6599 			CU_ASSERT(g_bserrno == 0);
6600 		} else {
6601 			CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == SPDK_BLOBID_INVALID);
6602 			deleted = true;
6603 		}
6604 
6605 		spdk_blob_close(blob, blob_op_complete, NULL);
6606 		poll_threads();
6607 		CU_ASSERT(g_bserrno == 0);
6608 
6609 		/* Reload blobstore to have the same starting conditions (as the previous blobstore load
6610 		 * may trigger cleanup after power failure or may not) */
6611 		spdk_bs_unload(g_bs, bs_op_complete, NULL);
6612 		poll_threads();
6613 		CU_ASSERT(g_bserrno == 0);
6614 
6615 		dev = init_dev();
6616 		spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL);
6617 		poll_threads();
6618 		CU_ASSERT(g_bserrno == 0);
6619 		SPDK_CU_ASSERT_FATAL(g_bs != NULL);
6620 		bs = g_bs;
6621 		SPDK_CU_ASSERT_FATAL(spdk_bit_array_get(bs->used_clusters, 1));
6622 		SPDK_CU_ASSERT_FATAL(!spdk_bit_array_get(bs->used_clusters, 11));
6623 
6624 		thresholds.general_threshold++;
6625 	}
6626 
6627 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
6628 	poll_threads();
6629 	CU_ASSERT(g_bserrno == 0);
6630 	g_bs = NULL;
6631 }
6632 
6633 static void
6634 blob_create_snapshot_power_failure(void)
6635 {
6636 	struct spdk_blob_store *bs;
6637 	struct spdk_bs_dev *dev;
6638 	struct spdk_blob_opts opts;
6639 	struct spdk_blob *blob, *snapshot;
6640 	struct spdk_power_failure_thresholds thresholds = {};
6641 	spdk_blob_id blobid, snapshotid;
6642 	const void *value;
6643 	size_t value_len;
6644 	size_t count;
6645 	spdk_blob_id ids[3] = {};
6646 	int rc;
6647 	bool created = false;
6648 
6649 	dev = init_dev();
6650 
6651 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
6652 	poll_threads();
6653 	CU_ASSERT(g_bserrno == 0);
6654 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
6655 	bs = g_bs;
6656 
6657 	/* Create blob */
6658 	ut_spdk_blob_opts_init(&opts);
6659 	opts.num_clusters = 10;
6660 
6661 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
6662 	poll_threads();
6663 	CU_ASSERT(g_bserrno == 0);
6664 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
6665 	blobid = g_blobid;
6666 	SPDK_CU_ASSERT_FATAL(spdk_bit_array_get(bs->used_clusters, 1));
6667 	SPDK_CU_ASSERT_FATAL(!spdk_bit_array_get(bs->used_clusters, 11));
6668 
6669 	thresholds.general_threshold = 1;
6670 	while (!created) {
6671 		dev_set_power_failure_thresholds(thresholds);
6672 
6673 		/* Create snapshot */
6674 		spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL);
6675 		poll_threads();
6676 		snapshotid = g_blobid;
6677 		SPDK_CU_ASSERT_FATAL(spdk_bit_array_get(bs->used_clusters, 1));
6678 		SPDK_CU_ASSERT_FATAL(!spdk_bit_array_get(bs->used_clusters, 11));
6679 
6680 		/* Do not shut down cleanly. Assumption is that after create snapshot
6681 		 * reports success, both blobs should be power-fail safe. */
6682 		_spdk_bs_free(bs);
6683 
6684 		dev_reset_power_failure_event();
6685 
6686 		dev = init_dev();
6687 		spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL);
6688 		poll_threads();
6689 		CU_ASSERT(g_bserrno == 0);
6690 		SPDK_CU_ASSERT_FATAL(g_bs != NULL);
6691 		bs = g_bs;
6692 		SPDK_CU_ASSERT_FATAL(spdk_bit_array_get(bs->used_clusters, 1));
6693 		SPDK_CU_ASSERT_FATAL(!spdk_bit_array_get(bs->used_clusters, 11));
6694 
6695 		spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
6696 		poll_threads();
6697 		CU_ASSERT(g_bserrno == 0);
6698 		SPDK_CU_ASSERT_FATAL(g_blob != NULL);
6699 		blob = g_blob;
6700 
6701 		if (snapshotid != SPDK_BLOBID_INVALID) {
6702 			spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL);
6703 			poll_threads();
6704 		}
6705 
6706 		if ((snapshotid != SPDK_BLOBID_INVALID) && (g_bserrno == 0)) {
6707 			SPDK_CU_ASSERT_FATAL(g_blob != NULL);
6708 			snapshot = g_blob;
6709 			SPDK_CU_ASSERT_FATAL(spdk_blob_is_thin_provisioned(blob) == true);
6710 			SPDK_CU_ASSERT_FATAL(spdk_blob_is_thin_provisioned(snapshot) == false);
6711 			CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid);
6712 			count = SPDK_COUNTOF(ids);
6713 			rc = spdk_blob_get_clones(bs, snapshotid, ids, &count);
6714 			CU_ASSERT(rc == 0);
6715 			CU_ASSERT(count == 1);
6716 			CU_ASSERT(ids[0] == blobid);
6717 			rc = spdk_blob_get_xattr_value(snapshot, SNAPSHOT_IN_PROGRESS, &value, &value_len);
6718 			CU_ASSERT(rc != 0);
6719 
6720 			spdk_blob_close(snapshot, blob_op_complete, NULL);
6721 			poll_threads();
6722 			CU_ASSERT(g_bserrno == 0);
6723 			created = true;
6724 		} else {
6725 			CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == SPDK_BLOBID_INVALID);
6726 			SPDK_CU_ASSERT_FATAL(spdk_blob_is_thin_provisioned(blob) == false);
6727 		}
6728 
6729 		spdk_blob_close(blob, blob_op_complete, NULL);
6730 		poll_threads();
6731 		CU_ASSERT(g_bserrno == 0);
6732 
6733 		/* Reload blobstore to have the same starting conditions (as the previous blobstore load
6734 		 * may trigger cleanup after power failure or may not) */
6735 		spdk_bs_unload(g_bs, bs_op_complete, NULL);
6736 		poll_threads();
6737 		CU_ASSERT(g_bserrno == 0);
6738 
6739 		dev = init_dev();
6740 		spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL);
6741 		poll_threads();
6742 		CU_ASSERT(g_bserrno == 0);
6743 		SPDK_CU_ASSERT_FATAL(g_bs != NULL);
6744 		bs = g_bs;
6745 		SPDK_CU_ASSERT_FATAL(spdk_bit_array_get(bs->used_clusters, 1));
6746 		SPDK_CU_ASSERT_FATAL(!spdk_bit_array_get(bs->used_clusters, 11));
6747 
6748 		thresholds.general_threshold++;
6749 	}
6750 
6751 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
6752 	poll_threads();
6753 	CU_ASSERT(g_bserrno == 0);
6754 	g_bs = NULL;
6755 }
6756 
6757 static void
6758 test_io_write(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel)
6759 {
6760 	uint8_t payload_ff[64 * 512];
6761 	uint8_t payload_aa[64 * 512];
6762 	uint8_t payload_00[64 * 512];
6763 	uint8_t *cluster0, *cluster1;
6764 
6765 	memset(payload_ff, 0xFF, sizeof(payload_ff));
6766 	memset(payload_aa, 0xAA, sizeof(payload_aa));
6767 	memset(payload_00, 0x00, sizeof(payload_00));
6768 
6769 	/* Try to perform I/O with io unit = 512 */
6770 	spdk_blob_io_write(blob, channel, payload_ff, 0, 1, blob_op_complete, NULL);
6771 	poll_threads();
6772 	CU_ASSERT(g_bserrno == 0);
6773 
6774 	/* If thin provisioned is set cluster should be allocated now */
6775 	SPDK_CU_ASSERT_FATAL(blob->active.clusters[0] != 0);
6776 	cluster0 = &g_dev_buffer[blob->active.clusters[0] * dev->blocklen];
6777 
6778 	/* Each character 0-F symbolizes single io_unit containing 512 bytes block filled with that character.
6779 	* Each page is separated by |. Whole block [...] symbolizes one cluster (containing 4 pages). */
6780 	/* cluster0: [ F000 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */
6781 	CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0);
6782 	CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 31 * 512) == 0);
6783 
6784 	/* Verify write with offset on first page */
6785 	spdk_blob_io_write(blob, channel, payload_ff, 2, 1, blob_op_complete, NULL);
6786 	poll_threads();
6787 	CU_ASSERT(g_bserrno == 0);
6788 
6789 	/* cluster0: [ F0F0 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */
6790 	CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0);
6791 	CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0);
6792 	CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0);
6793 	CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0);
6794 	CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_00, 28 * 512) == 0);
6795 
6796 	/* Verify write with offset on first page */
6797 	spdk_blob_io_write(blob, channel, payload_ff, 4, 4, blob_op_complete, NULL);
6798 	poll_threads();
6799 
6800 	/* cluster0: [ F0F0 FFFF | 0000 0000 | 0000 0000 | 0000 0000 ] */
6801 	CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0);
6802 	CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0);
6803 	CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0);
6804 	CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0);
6805 	CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_ff, 4 * 512) == 0);
6806 	CU_ASSERT(memcmp(cluster0 + 8 * 512, payload_00, 24 * 512) == 0);
6807 
6808 	/* Verify write with offset on second page */
6809 	spdk_blob_io_write(blob, channel, payload_ff, 8, 4, blob_op_complete, NULL);
6810 	poll_threads();
6811 
6812 	/* cluster0: [ F0F0 FFFF | FFFF 0000 | 0000 0000 | 0000 0000 ] */
6813 	CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0);
6814 	CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0);
6815 	CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0);
6816 	CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0);
6817 	CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_ff, 8 * 512) == 0);
6818 	CU_ASSERT(memcmp(cluster0 + 12 * 512, payload_00, 20 * 512) == 0);
6819 
6820 	/* Verify write across multiple pages */
6821 	spdk_blob_io_write(blob, channel, payload_aa, 4, 8, blob_op_complete, NULL);
6822 	poll_threads();
6823 
6824 	/* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 0000 ] */
6825 	CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0);
6826 	CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0);
6827 	CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0);
6828 	CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0);
6829 	CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0);
6830 	CU_ASSERT(memcmp(cluster0 + 12 * 512, payload_00, 20 * 512) == 0);
6831 
6832 	/* Verify write across multiple clusters */
6833 	spdk_blob_io_write(blob, channel, payload_ff, 28, 8, blob_op_complete, NULL);
6834 	poll_threads();
6835 
6836 	SPDK_CU_ASSERT_FATAL(blob->active.clusters[1] != 0);
6837 	cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen];
6838 
6839 	/* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ]
6840 	 * cluster1: [ FFFF 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */
6841 	CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0);
6842 	CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0);
6843 	CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0);
6844 	CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0);
6845 	CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0);
6846 	CU_ASSERT(memcmp(cluster0 + 28 * 512, payload_ff, 4 * 512) == 0);
6847 
6848 	CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_ff, 4 * 512) == 0);
6849 	CU_ASSERT(memcmp(cluster1 + 4 * 512, payload_00, 28 * 512) == 0);
6850 
6851 	/* Verify write to second cluster */
6852 	spdk_blob_io_write(blob, channel, payload_ff, 32 + 12, 2, blob_op_complete, NULL);
6853 	poll_threads();
6854 
6855 	SPDK_CU_ASSERT_FATAL(blob->active.clusters[1] != 0);
6856 	cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen];
6857 
6858 	/* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ]
6859 	 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] */
6860 	CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0);
6861 	CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0);
6862 	CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0);
6863 	CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0);
6864 	CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0);
6865 	CU_ASSERT(memcmp(cluster0 + 28 * 512, payload_ff, 4 * 512) == 0);
6866 
6867 	CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_ff, 4 * 512) == 0);
6868 	CU_ASSERT(memcmp(cluster1 + 4 * 512, payload_00, 8 * 512) == 0);
6869 	CU_ASSERT(memcmp(cluster1 + 12 * 512, payload_ff, 2 * 512) == 0);
6870 	CU_ASSERT(memcmp(cluster1 + 14 * 512, payload_00, 18 * 512) == 0);
6871 }
6872 
6873 static void
6874 test_io_read(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel)
6875 {
6876 	uint8_t payload_read[64 * 512];
6877 	uint8_t payload_ff[64 * 512];
6878 	uint8_t payload_aa[64 * 512];
6879 	uint8_t payload_00[64 * 512];
6880 
6881 	memset(payload_ff, 0xFF, sizeof(payload_ff));
6882 	memset(payload_aa, 0xAA, sizeof(payload_aa));
6883 	memset(payload_00, 0x00, sizeof(payload_00));
6884 
6885 	/* Read only first io unit */
6886 	/* cluster0: [ (F)0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ]
6887 	 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ]
6888 	 * payload_read: F000 0000 | 0000 0000 ... */
6889 	memset(payload_read, 0x00, sizeof(payload_read));
6890 	spdk_blob_io_read(blob, channel, payload_read, 0, 1, blob_op_complete, NULL);
6891 	poll_threads();
6892 	CU_ASSERT(g_bserrno == 0);
6893 	CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0);
6894 	CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 31 * 512) == 0);
6895 
6896 	/* Read four io_units starting from offset = 2
6897 	 * cluster0: [ F0(F0 AA)AA | AAAA 0000 | 0000 0000 | 0000 FFFF ]
6898 	 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ]
6899 	 * payload_read: F0AA 0000 | 0000 0000 ... */
6900 
6901 	memset(payload_read, 0x00, sizeof(payload_read));
6902 	spdk_blob_io_read(blob, channel, payload_read, 2, 4, blob_op_complete, NULL);
6903 	poll_threads();
6904 	CU_ASSERT(g_bserrno == 0);
6905 
6906 	CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0);
6907 	CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 512) == 0);
6908 	CU_ASSERT(memcmp(payload_read + 2 * 512, payload_aa, 512) == 0);
6909 	CU_ASSERT(memcmp(payload_read + 3 * 512, payload_aa, 512) == 0);
6910 	CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 28 * 512) == 0);
6911 
6912 	/* Read eight io_units across multiple pages
6913 	 * cluster0: [ F0F0 (AAAA | AAAA) 0000 | 0000 0000 | 0000 FFFF ]
6914 	 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ]
6915 	 * payload_read: AAAA AAAA | 0000 0000 ... */
6916 	memset(payload_read, 0x00, sizeof(payload_read));
6917 	spdk_blob_io_read(blob, channel, payload_read, 4, 8, blob_op_complete, NULL);
6918 	poll_threads();
6919 	CU_ASSERT(g_bserrno == 0);
6920 
6921 	CU_ASSERT(memcmp(payload_read + 0 * 512, payload_aa, 8 * 512) == 0);
6922 	CU_ASSERT(memcmp(payload_read + 8 * 512, payload_00, 24 * 512) == 0);
6923 
6924 	/* Read eight io_units across multiple clusters
6925 	 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 (FFFF ]
6926 	 * cluster1: [ FFFF) 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ]
6927 	 * payload_read: FFFF FFFF | 0000 0000 ... */
6928 	memset(payload_read, 0x00, sizeof(payload_read));
6929 	spdk_blob_io_read(blob, channel, payload_read, 28, 8, blob_op_complete, NULL);
6930 	poll_threads();
6931 	CU_ASSERT(g_bserrno == 0);
6932 
6933 	CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 8 * 512) == 0);
6934 	CU_ASSERT(memcmp(payload_read + 8 * 512, payload_00, 24 * 512) == 0);
6935 
6936 	/* Read four io_units from second cluster
6937 	 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ]
6938 	 * cluster1: [ FFFF 0000 | 00(00 FF)00 | 0000 0000 | 0000 0000 ]
6939 	 * payload_read: 00FF 0000 | 0000 0000 ... */
6940 	memset(payload_read, 0x00, sizeof(payload_read));
6941 	spdk_blob_io_read(blob, channel, payload_read, 32 + 10, 4, blob_op_complete, NULL);
6942 	poll_threads();
6943 	CU_ASSERT(g_bserrno == 0);
6944 
6945 	CU_ASSERT(memcmp(payload_read + 0 * 512, payload_00, 2 * 512) == 0);
6946 	CU_ASSERT(memcmp(payload_read + 2 * 512, payload_ff, 2 * 512) == 0);
6947 	CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 28 * 512) == 0);
6948 
6949 	/* Read second cluster
6950 	 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ]
6951 	 * cluster1: [ (FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000) ]
6952 	 * payload_read: FFFF 0000 | 0000 FF00 ... */
6953 	memset(payload_read, 0x00, sizeof(payload_read));
6954 	spdk_blob_io_read(blob, channel, payload_read, 32, 32, blob_op_complete, NULL);
6955 	poll_threads();
6956 	CU_ASSERT(g_bserrno == 0);
6957 	CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 4 * 512) == 0);
6958 	CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 8 * 512) == 0);
6959 	CU_ASSERT(memcmp(payload_read + 12 * 512, payload_ff, 2 * 512) == 0);
6960 	CU_ASSERT(memcmp(payload_read + 14 * 512, payload_00, 18 * 512) == 0);
6961 
6962 	/* Read whole two clusters
6963 	 * cluster0: [ (F0F0 AAAA | AAAA) 0000 | 0000 0000 | 0000 FFFF ]
6964 	 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000) ] */
6965 	memset(payload_read, 0x00, sizeof(payload_read));
6966 	spdk_blob_io_read(blob, channel, payload_read, 0, 64, blob_op_complete, NULL);
6967 	poll_threads();
6968 	CU_ASSERT(g_bserrno == 0);
6969 
6970 	CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0);
6971 	CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 512) == 0);
6972 	CU_ASSERT(memcmp(payload_read + 2 * 512, payload_ff, 512) == 0);
6973 	CU_ASSERT(memcmp(payload_read + 3 * 512, payload_00, 512) == 0);
6974 	CU_ASSERT(memcmp(payload_read + 4 * 512, payload_aa, 8 * 512) == 0);
6975 	CU_ASSERT(memcmp(payload_read + 28 * 512, payload_ff, 4 * 512) == 0);
6976 
6977 	CU_ASSERT(memcmp(payload_read + (32 + 0) * 512, payload_ff, 4 * 512) == 0);
6978 	CU_ASSERT(memcmp(payload_read + (32 + 4) * 512, payload_00, 8 * 512) == 0);
6979 	CU_ASSERT(memcmp(payload_read + (32 + 12) * 512, payload_ff, 2 * 512) == 0);
6980 	CU_ASSERT(memcmp(payload_read + (32 + 14) * 512, payload_00, 18 * 512) == 0);
6981 }
6982 
6983 
6984 static void
6985 test_io_unmap(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel)
6986 {
6987 	uint8_t payload_ff[64 * 512];
6988 	uint8_t payload_aa[64 * 512];
6989 	uint8_t payload_00[64 * 512];
6990 	uint8_t *cluster0, *cluster1;
6991 
6992 	memset(payload_ff, 0xFF, sizeof(payload_ff));
6993 	memset(payload_aa, 0xAA, sizeof(payload_aa));
6994 	memset(payload_00, 0x00, sizeof(payload_00));
6995 
6996 	cluster0 = &g_dev_buffer[blob->active.clusters[0] * dev->blocklen];
6997 	cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen];
6998 
6999 	/* Unmap */
7000 	spdk_blob_io_unmap(blob, channel, 0, 64, blob_op_complete, NULL);
7001 	poll_threads();
7002 
7003 	CU_ASSERT(g_bserrno == 0);
7004 
7005 	CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_00, 32 * 512) == 0);
7006 	CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_00, 32 * 512) == 0);
7007 }
7008 
7009 static void
7010 test_io_zeroes(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel)
7011 {
7012 	uint8_t payload_ff[64 * 512];
7013 	uint8_t payload_aa[64 * 512];
7014 	uint8_t payload_00[64 * 512];
7015 	uint8_t *cluster0, *cluster1;
7016 
7017 	memset(payload_ff, 0xFF, sizeof(payload_ff));
7018 	memset(payload_aa, 0xAA, sizeof(payload_aa));
7019 	memset(payload_00, 0x00, sizeof(payload_00));
7020 
7021 	cluster0 = &g_dev_buffer[blob->active.clusters[0] * dev->blocklen];
7022 	cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen];
7023 
7024 	/* Write zeroes  */
7025 	spdk_blob_io_write_zeroes(blob, channel, 0, 64, blob_op_complete, NULL);
7026 	poll_threads();
7027 
7028 	CU_ASSERT(g_bserrno == 0);
7029 
7030 	CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_00, 32 * 512) == 0);
7031 	CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_00, 32 * 512) == 0);
7032 }
7033 
7034 
7035 static void
7036 test_iov_write(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel)
7037 {
7038 	uint8_t payload_ff[64 * 512];
7039 	uint8_t payload_aa[64 * 512];
7040 	uint8_t payload_00[64 * 512];
7041 	uint8_t *cluster0, *cluster1;
7042 	struct iovec iov[4];
7043 
7044 	memset(payload_ff, 0xFF, sizeof(payload_ff));
7045 	memset(payload_aa, 0xAA, sizeof(payload_aa));
7046 	memset(payload_00, 0x00, sizeof(payload_00));
7047 
7048 	/* Try to perform I/O with io unit = 512 */
7049 	iov[0].iov_base = payload_ff;
7050 	iov[0].iov_len = 1 * 512;
7051 	spdk_blob_io_writev(blob, channel, iov, 1, 0, 1, blob_op_complete, NULL);
7052 	poll_threads();
7053 	CU_ASSERT(g_bserrno == 0);
7054 
7055 	/* If thin provisioned is set cluster should be allocated now */
7056 	SPDK_CU_ASSERT_FATAL(blob->active.clusters[0] != 0);
7057 	cluster0 = &g_dev_buffer[blob->active.clusters[0] * dev->blocklen];
7058 
7059 	/* Each character 0-F symbolizes single io_unit containing 512 bytes block filled with that character.
7060 	* Each page is separated by |. Whole block [...] symbolizes one cluster (containing 4 pages). */
7061 	/* cluster0: [ F000 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */
7062 	CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0);
7063 	CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 31 * 512) == 0);
7064 
7065 	/* Verify write with offset on first page */
7066 	iov[0].iov_base = payload_ff;
7067 	iov[0].iov_len = 1 * 512;
7068 	spdk_blob_io_writev(blob, channel, iov, 1, 2, 1, blob_op_complete, NULL);
7069 	poll_threads();
7070 	CU_ASSERT(g_bserrno == 0);
7071 
7072 	/* cluster0: [ F0F0 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */
7073 	CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0);
7074 	CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0);
7075 	CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0);
7076 	CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0);
7077 	CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_00, 28 * 512) == 0);
7078 
7079 	/* Verify write with offset on first page */
7080 	iov[0].iov_base = payload_ff;
7081 	iov[0].iov_len = 4 * 512;
7082 	spdk_blob_io_writev(blob, channel, iov, 1, 4, 4, blob_op_complete, NULL);
7083 	poll_threads();
7084 
7085 	/* cluster0: [ F0F0 FFFF | 0000 0000 | 0000 0000 | 0000 0000 ] */
7086 	CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0);
7087 	CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0);
7088 	CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0);
7089 	CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0);
7090 	CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_ff, 4 * 512) == 0);
7091 	CU_ASSERT(memcmp(cluster0 + 8 * 512, payload_00, 24 * 512) == 0);
7092 
7093 	/* Verify write with offset on second page */
7094 	iov[0].iov_base = payload_ff;
7095 	iov[0].iov_len = 4 * 512;
7096 	spdk_blob_io_writev(blob, channel, iov, 1, 8, 4, blob_op_complete, NULL);
7097 	poll_threads();
7098 
7099 	/* cluster0: [ F0F0 FFFF | FFFF 0000 | 0000 0000 | 0000 0000 ] */
7100 	CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0);
7101 	CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0);
7102 	CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0);
7103 	CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0);
7104 	CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_ff, 8 * 512) == 0);
7105 	CU_ASSERT(memcmp(cluster0 + 12 * 512, payload_00, 20 * 512) == 0);
7106 
7107 	/* Verify write across multiple pages */
7108 	iov[0].iov_base = payload_aa;
7109 	iov[0].iov_len = 8 * 512;
7110 	spdk_blob_io_writev(blob, channel, iov, 1, 4, 8, blob_op_complete, NULL);
7111 	poll_threads();
7112 
7113 	/* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 0000 ] */
7114 	CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0);
7115 	CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0);
7116 	CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0);
7117 	CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0);
7118 	CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0);
7119 	CU_ASSERT(memcmp(cluster0 + 12 * 512, payload_00, 20 * 512) == 0);
7120 
7121 	/* Verify write across multiple clusters */
7122 
7123 	iov[0].iov_base = payload_ff;
7124 	iov[0].iov_len = 8 * 512;
7125 	spdk_blob_io_writev(blob, channel, iov, 1, 28, 8, blob_op_complete, NULL);
7126 	poll_threads();
7127 
7128 	SPDK_CU_ASSERT_FATAL(blob->active.clusters[1] != 0);
7129 	cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen];
7130 
7131 	/* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ]
7132 	 * cluster1: [ FFFF 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */
7133 	CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0);
7134 	CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0);
7135 	CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0);
7136 	CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0);
7137 	CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0);
7138 	CU_ASSERT(memcmp(cluster0 + 12 * 512, payload_00, 16 * 512) == 0);
7139 	CU_ASSERT(memcmp(cluster0 + 28 * 512, payload_ff, 4 * 512) == 0);
7140 
7141 	CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_ff, 4 * 512) == 0);
7142 	CU_ASSERT(memcmp(cluster1 + 4 * 512, payload_00, 28 * 512) == 0);
7143 
7144 	/* Verify write to second cluster */
7145 
7146 	iov[0].iov_base = payload_ff;
7147 	iov[0].iov_len = 2 * 512;
7148 	spdk_blob_io_writev(blob, channel, iov, 1, 32 + 12, 2, blob_op_complete, NULL);
7149 	poll_threads();
7150 
7151 	SPDK_CU_ASSERT_FATAL(blob->active.clusters[1] != 0);
7152 	cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen];
7153 
7154 	/* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ]
7155 	 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] */
7156 	CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0);
7157 	CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0);
7158 	CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0);
7159 	CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0);
7160 	CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0);
7161 	CU_ASSERT(memcmp(cluster0 + 28 * 512, payload_ff, 4 * 512) == 0);
7162 
7163 	CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_ff, 4 * 512) == 0);
7164 	CU_ASSERT(memcmp(cluster1 + 4 * 512, payload_00, 8 * 512) == 0);
7165 	CU_ASSERT(memcmp(cluster1 + 12 * 512, payload_ff, 2 * 512) == 0);
7166 	CU_ASSERT(memcmp(cluster1 + 14 * 512, payload_00, 18 * 512) == 0);
7167 }
7168 
7169 static void
7170 test_iov_read(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel)
7171 {
7172 	uint8_t payload_read[64 * 512];
7173 	uint8_t payload_ff[64 * 512];
7174 	uint8_t payload_aa[64 * 512];
7175 	uint8_t payload_00[64 * 512];
7176 	struct iovec iov[4];
7177 
7178 	memset(payload_ff, 0xFF, sizeof(payload_ff));
7179 	memset(payload_aa, 0xAA, sizeof(payload_aa));
7180 	memset(payload_00, 0x00, sizeof(payload_00));
7181 
7182 	/* Read only first io unit */
7183 	/* cluster0: [ (F)0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ]
7184 	 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ]
7185 	 * payload_read: F000 0000 | 0000 0000 ... */
7186 	memset(payload_read, 0x00, sizeof(payload_read));
7187 	iov[0].iov_base = payload_read;
7188 	iov[0].iov_len = 1 * 512;
7189 	spdk_blob_io_readv(blob, channel, iov, 1, 0, 1, blob_op_complete, NULL);
7190 	poll_threads();
7191 
7192 	CU_ASSERT(g_bserrno == 0);
7193 	CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0);
7194 	CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 31 * 512) == 0);
7195 
7196 	/* Read four io_units starting from offset = 2
7197 	 * cluster0: [ F0(F0 AA)AA | AAAA 0000 | 0000 0000 | 0000 FFFF ]
7198 	 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ]
7199 	 * payload_read: F0AA 0000 | 0000 0000 ... */
7200 
7201 	memset(payload_read, 0x00, sizeof(payload_read));
7202 	iov[0].iov_base = payload_read;
7203 	iov[0].iov_len = 4 * 512;
7204 	spdk_blob_io_readv(blob, channel, iov, 1, 2, 4, blob_op_complete, NULL);
7205 	poll_threads();
7206 	CU_ASSERT(g_bserrno == 0);
7207 
7208 	CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0);
7209 	CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 512) == 0);
7210 	CU_ASSERT(memcmp(payload_read + 2 * 512, payload_aa, 512) == 0);
7211 	CU_ASSERT(memcmp(payload_read + 3 * 512, payload_aa, 512) == 0);
7212 	CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 28 * 512) == 0);
7213 
7214 	/* Read eight io_units across multiple pages
7215 	 * cluster0: [ F0F0 (AAAA | AAAA) 0000 | 0000 0000 | 0000 FFFF ]
7216 	 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ]
7217 	 * payload_read: AAAA AAAA | 0000 0000 ... */
7218 	memset(payload_read, 0x00, sizeof(payload_read));
7219 	iov[0].iov_base = payload_read;
7220 	iov[0].iov_len = 4 * 512;
7221 	iov[1].iov_base = payload_read + 4 * 512;
7222 	iov[1].iov_len = 4 * 512;
7223 	spdk_blob_io_readv(blob, channel, iov, 2, 4, 8, blob_op_complete, NULL);
7224 	poll_threads();
7225 	CU_ASSERT(g_bserrno == 0);
7226 
7227 	CU_ASSERT(memcmp(payload_read + 0 * 512, payload_aa, 8 * 512) == 0);
7228 	CU_ASSERT(memcmp(payload_read + 8 * 512, payload_00, 24 * 512) == 0);
7229 
7230 	/* Read eight io_units across multiple clusters
7231 	 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 (FFFF ]
7232 	 * cluster1: [ FFFF) 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ]
7233 	 * payload_read: FFFF FFFF | 0000 0000 ... */
7234 	memset(payload_read, 0x00, sizeof(payload_read));
7235 	iov[0].iov_base = payload_read;
7236 	iov[0].iov_len = 2 * 512;
7237 	iov[1].iov_base = payload_read + 2 * 512;
7238 	iov[1].iov_len = 2 * 512;
7239 	iov[2].iov_base = payload_read + 4 * 512;
7240 	iov[2].iov_len = 2 * 512;
7241 	iov[3].iov_base = payload_read + 6 * 512;
7242 	iov[3].iov_len = 2 * 512;
7243 	spdk_blob_io_readv(blob, channel, iov, 4, 28, 8, blob_op_complete, NULL);
7244 	poll_threads();
7245 	CU_ASSERT(g_bserrno == 0);
7246 
7247 	CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 8 * 512) == 0);
7248 	CU_ASSERT(memcmp(payload_read + 8 * 512, payload_00, 24 * 512) == 0);
7249 
7250 	/* Read four io_units from second cluster
7251 	 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ]
7252 	 * cluster1: [ FFFF 0000 | 00(00 FF)00 | 0000 0000 | 0000 0000 ]
7253 	 * payload_read: 00FF 0000 | 0000 0000 ... */
7254 	memset(payload_read, 0x00, sizeof(payload_read));
7255 	iov[0].iov_base = payload_read;
7256 	iov[0].iov_len = 1 * 512;
7257 	iov[1].iov_base = payload_read + 1 * 512;
7258 	iov[1].iov_len = 3 * 512;
7259 	spdk_blob_io_readv(blob, channel, iov, 2, 32 + 10, 4, blob_op_complete, NULL);
7260 	poll_threads();
7261 	CU_ASSERT(g_bserrno == 0);
7262 
7263 	CU_ASSERT(memcmp(payload_read + 0 * 512, payload_00, 2 * 512) == 0);
7264 	CU_ASSERT(memcmp(payload_read + 2 * 512, payload_ff, 2 * 512) == 0);
7265 	CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 28 * 512) == 0);
7266 
7267 	/* Read second cluster
7268 	 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ]
7269 	 * cluster1: [ (FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000) ]
7270 	 * payload_read: FFFF 0000 | 0000 FF00 ... */
7271 	memset(payload_read, 0x00, sizeof(payload_read));
7272 	iov[0].iov_base = payload_read;
7273 	iov[0].iov_len = 1 * 512;
7274 	iov[1].iov_base = payload_read + 1 * 512;
7275 	iov[1].iov_len = 2 * 512;
7276 	iov[2].iov_base = payload_read + 3 * 512;
7277 	iov[2].iov_len = 4 * 512;
7278 	iov[3].iov_base = payload_read + 7 * 512;
7279 	iov[3].iov_len = 25 * 512;
7280 	spdk_blob_io_readv(blob, channel, iov, 4, 32, 32, blob_op_complete, NULL);
7281 	poll_threads();
7282 	CU_ASSERT(g_bserrno == 0);
7283 	CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 4 * 512) == 0);
7284 	CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 8 * 512) == 0);
7285 	CU_ASSERT(memcmp(payload_read + 12 * 512, payload_ff, 2 * 512) == 0);
7286 	CU_ASSERT(memcmp(payload_read + 14 * 512, payload_00, 18 * 512) == 0);
7287 
7288 	/* Read whole two clusters
7289 	 * cluster0: [ (F0F0 AAAA | AAAA) 0000 | 0000 0000 | 0000 FFFF ]
7290 	 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000) ] */
7291 	memset(payload_read, 0x00, sizeof(payload_read));
7292 	iov[0].iov_base = payload_read;
7293 	iov[0].iov_len = 1 * 512;
7294 	iov[1].iov_base = payload_read + 1 * 512;
7295 	iov[1].iov_len = 8 * 512;
7296 	iov[2].iov_base = payload_read + 9 * 512;
7297 	iov[2].iov_len = 16 * 512;
7298 	iov[3].iov_base = payload_read + 25 * 512;
7299 	iov[3].iov_len = 39 * 512;
7300 	spdk_blob_io_readv(blob, channel, iov, 4, 0, 64, blob_op_complete, NULL);
7301 	poll_threads();
7302 	CU_ASSERT(g_bserrno == 0);
7303 
7304 	CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0);
7305 	CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 512) == 0);
7306 	CU_ASSERT(memcmp(payload_read + 2 * 512, payload_ff, 512) == 0);
7307 	CU_ASSERT(memcmp(payload_read + 3 * 512, payload_00, 512) == 0);
7308 	CU_ASSERT(memcmp(payload_read + 4 * 512, payload_aa, 8 * 512) == 0);
7309 	CU_ASSERT(memcmp(payload_read + 28 * 512, payload_ff, 4 * 512) == 0);
7310 
7311 	CU_ASSERT(memcmp(payload_read + (32 + 0) * 512, payload_ff, 4 * 512) == 0);
7312 	CU_ASSERT(memcmp(payload_read + (32 + 4) * 512, payload_00, 8 * 512) == 0);
7313 	CU_ASSERT(memcmp(payload_read + (32 + 12) * 512, payload_ff, 2 * 512) == 0);
7314 	CU_ASSERT(memcmp(payload_read + (32 + 14) * 512, payload_00, 18 * 512) == 0);
7315 }
7316 
7317 static void
7318 blob_io_unit(void)
7319 {
7320 	struct spdk_bs_opts bsopts;
7321 	struct spdk_blob_opts opts;
7322 	struct spdk_bs_dev *dev;
7323 	struct spdk_blob *blob, *snapshot, *clone;
7324 	spdk_blob_id blobid;
7325 	struct spdk_io_channel *channel;
7326 
7327 	/* Create dev with 512 bytes io unit size */
7328 
7329 	spdk_bs_opts_init(&bsopts);
7330 	bsopts.cluster_sz = SPDK_BS_PAGE_SIZE * 4;	/* 8 * 4 = 32 io_unit */
7331 	snprintf(bsopts.bstype.bstype, sizeof(bsopts.bstype.bstype), "TESTTYPE");
7332 
7333 	/* Try to initialize a new blob store with unsupported io_unit */
7334 	dev = init_dev();
7335 	dev->blocklen = 512;
7336 	dev->blockcnt =  DEV_BUFFER_SIZE / dev->blocklen;
7337 
7338 	/* Initialize a new blob store */
7339 	spdk_bs_init(dev, &bsopts, bs_op_with_handle_complete, NULL);
7340 	poll_threads();
7341 	CU_ASSERT(g_bserrno == 0);
7342 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
7343 
7344 	CU_ASSERT(spdk_bs_get_io_unit_size(g_bs) == 512);
7345 	channel = spdk_bs_alloc_io_channel(g_bs);
7346 
7347 	/* Create thick provisioned blob */
7348 	ut_spdk_blob_opts_init(&opts);
7349 	opts.thin_provision = false;
7350 	opts.num_clusters = 32;
7351 
7352 	spdk_bs_create_blob_ext(g_bs, &opts, blob_op_with_id_complete, NULL);
7353 	poll_threads();
7354 
7355 	CU_ASSERT(g_bserrno == 0);
7356 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
7357 	blobid = g_blobid;
7358 
7359 	spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
7360 	poll_threads();
7361 	CU_ASSERT(g_bserrno == 0);
7362 	CU_ASSERT(g_blob != NULL);
7363 	blob = g_blob;
7364 
7365 	test_io_write(dev, blob, channel);
7366 	test_io_read(dev, blob, channel);
7367 	test_io_zeroes(dev, blob, channel);
7368 
7369 	test_iov_write(dev, blob, channel);
7370 	test_iov_read(dev, blob, channel);
7371 
7372 	test_io_unmap(dev, blob, channel);
7373 
7374 	spdk_blob_close(blob, blob_op_complete, NULL);
7375 	poll_threads();
7376 	CU_ASSERT(g_bserrno == 0);
7377 	blob = NULL;
7378 	g_blob = NULL;
7379 
7380 	/* Create thin provisioned blob */
7381 
7382 	ut_spdk_blob_opts_init(&opts);
7383 	opts.thin_provision = true;
7384 	opts.num_clusters = 32;
7385 
7386 	spdk_bs_create_blob_ext(g_bs, &opts, blob_op_with_id_complete, NULL);
7387 	poll_threads();
7388 	CU_ASSERT(g_bserrno == 0);
7389 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
7390 	blobid = g_blobid;
7391 
7392 	spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
7393 	poll_threads();
7394 	CU_ASSERT(g_bserrno == 0);
7395 	CU_ASSERT(g_blob != NULL);
7396 	blob = g_blob;
7397 
7398 	test_io_write(dev, blob, channel);
7399 	test_io_read(dev, blob, channel);
7400 
7401 	test_io_zeroes(dev, blob, channel);
7402 
7403 	test_iov_write(dev, blob, channel);
7404 	test_iov_read(dev, blob, channel);
7405 
7406 	/* Create snapshot */
7407 
7408 	spdk_bs_create_snapshot(g_bs, blobid, NULL, blob_op_with_id_complete, NULL);
7409 	poll_threads();
7410 	CU_ASSERT(g_bserrno == 0);
7411 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
7412 	blobid = g_blobid;
7413 
7414 	spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
7415 	poll_threads();
7416 	CU_ASSERT(g_bserrno == 0);
7417 	CU_ASSERT(g_blob != NULL);
7418 	snapshot = g_blob;
7419 
7420 	spdk_bs_create_clone(g_bs, blobid, NULL, blob_op_with_id_complete, NULL);
7421 	poll_threads();
7422 	CU_ASSERT(g_bserrno == 0);
7423 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
7424 	blobid = g_blobid;
7425 
7426 	spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
7427 	poll_threads();
7428 	CU_ASSERT(g_bserrno == 0);
7429 	CU_ASSERT(g_blob != NULL);
7430 	clone = g_blob;
7431 
7432 	test_io_read(dev, blob, channel);
7433 	test_io_read(dev, snapshot, channel);
7434 	test_io_read(dev, clone, channel);
7435 
7436 	test_iov_read(dev, blob, channel);
7437 	test_iov_read(dev, snapshot, channel);
7438 	test_iov_read(dev, clone, channel);
7439 
7440 	/* Inflate clone */
7441 
7442 	spdk_bs_inflate_blob(g_bs, channel, blobid, blob_op_complete, NULL);
7443 	poll_threads();
7444 
7445 	CU_ASSERT(g_bserrno == 0);
7446 
7447 	test_io_read(dev, clone, channel);
7448 
7449 	test_io_unmap(dev, clone, channel);
7450 
7451 	test_iov_write(dev, clone, channel);
7452 	test_iov_read(dev, clone, channel);
7453 
7454 	spdk_blob_close(blob, blob_op_complete, NULL);
7455 	spdk_blob_close(snapshot, blob_op_complete, NULL);
7456 	spdk_blob_close(clone, blob_op_complete, NULL);
7457 	poll_threads();
7458 	CU_ASSERT(g_bserrno == 0);
7459 	blob = NULL;
7460 	g_blob = NULL;
7461 
7462 	spdk_bs_free_io_channel(channel);
7463 	poll_threads();
7464 
7465 	/* Unload the blob store */
7466 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
7467 	poll_threads();
7468 	CU_ASSERT(g_bserrno == 0);
7469 	g_bs = NULL;
7470 	g_blob = NULL;
7471 	g_blobid = 0;
7472 }
7473 
7474 static void
7475 blob_io_unit_compatiblity(void)
7476 {
7477 	struct spdk_bs_opts bsopts;
7478 	struct spdk_bs_dev *dev;
7479 	struct spdk_bs_super_block *super;
7480 
7481 	/* Create dev with 512 bytes io unit size */
7482 
7483 	spdk_bs_opts_init(&bsopts);
7484 	bsopts.cluster_sz = SPDK_BS_PAGE_SIZE * 4;	/* 8 * 4 = 32 io_unit */
7485 	snprintf(bsopts.bstype.bstype, sizeof(bsopts.bstype.bstype), "TESTTYPE");
7486 
7487 	/* Try to initialize a new blob store with unsupported io_unit */
7488 	dev = init_dev();
7489 	dev->blocklen = 512;
7490 	dev->blockcnt =  DEV_BUFFER_SIZE / dev->blocklen;
7491 
7492 	/* Initialize a new blob store */
7493 	spdk_bs_init(dev, &bsopts, bs_op_with_handle_complete, NULL);
7494 	poll_threads();
7495 	CU_ASSERT(g_bserrno == 0);
7496 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
7497 
7498 	CU_ASSERT(spdk_bs_get_io_unit_size(g_bs) == 512);
7499 
7500 	/* Unload the blob store */
7501 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
7502 	poll_threads();
7503 	CU_ASSERT(g_bserrno == 0);
7504 
7505 	/* Modify super block to behave like older version.
7506 	 * Check if loaded io unit size equals SPDK_BS_PAGE_SIZE */
7507 	super = (struct spdk_bs_super_block *)&g_dev_buffer[0];
7508 	super->io_unit_size = 0;
7509 	super->crc = _spdk_blob_md_page_calc_crc(super);
7510 
7511 	dev = init_dev();
7512 	dev->blocklen = 512;
7513 	dev->blockcnt =  DEV_BUFFER_SIZE / dev->blocklen;
7514 
7515 	spdk_bs_load(dev, &bsopts, bs_op_with_handle_complete, NULL);
7516 	poll_threads();
7517 	CU_ASSERT(g_bserrno == 0);
7518 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
7519 
7520 	CU_ASSERT(spdk_bs_get_io_unit_size(g_bs) == SPDK_BS_PAGE_SIZE);
7521 
7522 	/* Unload the blob store */
7523 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
7524 	poll_threads();
7525 	CU_ASSERT(g_bserrno == 0);
7526 
7527 	g_bs = NULL;
7528 	g_blob = NULL;
7529 	g_blobid = 0;
7530 }
7531 
7532 static void
7533 blob_simultaneous_operations(void)
7534 {
7535 	struct spdk_blob_store *bs;
7536 	struct spdk_bs_dev *dev;
7537 	struct spdk_blob_opts opts;
7538 	struct spdk_blob *blob, *snapshot;
7539 	spdk_blob_id blobid, snapshotid;
7540 	struct spdk_io_channel *channel;
7541 
7542 	dev = init_dev();
7543 
7544 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
7545 	poll_threads();
7546 	CU_ASSERT(g_bserrno == 0);
7547 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
7548 	bs = g_bs;
7549 
7550 	channel = spdk_bs_alloc_io_channel(bs);
7551 	SPDK_CU_ASSERT_FATAL(channel != NULL);
7552 
7553 	ut_spdk_blob_opts_init(&opts);
7554 	opts.num_clusters = 10;
7555 
7556 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
7557 	poll_threads();
7558 	CU_ASSERT(g_bserrno == 0);
7559 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
7560 	blobid = g_blobid;
7561 
7562 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
7563 	poll_threads();
7564 	CU_ASSERT(g_bserrno == 0);
7565 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
7566 	blob = g_blob;
7567 
7568 	/* Create snapshot and try to remove blob in the same time:
7569 	 * - snapshot should be created successfully
7570 	 * - delete operation should fail w -EBUSY */
7571 	CU_ASSERT(blob->locked_operation_in_progress == false);
7572 	spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL);
7573 	CU_ASSERT(blob->locked_operation_in_progress == true);
7574 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
7575 	CU_ASSERT(blob->locked_operation_in_progress == true);
7576 	/* Deletion failure */
7577 	CU_ASSERT(g_bserrno == -EBUSY);
7578 	poll_threads();
7579 	CU_ASSERT(blob->locked_operation_in_progress == false);
7580 	/* Snapshot creation success */
7581 	CU_ASSERT(g_bserrno == 0);
7582 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
7583 
7584 	snapshotid = g_blobid;
7585 
7586 	spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL);
7587 	poll_threads();
7588 	CU_ASSERT(g_bserrno == 0);
7589 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
7590 	snapshot = g_blob;
7591 
7592 	/* Inflate blob and try to remove blob in the same time:
7593 	 * - blob should be inflated successfully
7594 	 * - delete operation should fail w -EBUSY */
7595 	CU_ASSERT(blob->locked_operation_in_progress == false);
7596 	spdk_bs_inflate_blob(bs, channel, blobid, blob_op_complete, NULL);
7597 	CU_ASSERT(blob->locked_operation_in_progress == true);
7598 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
7599 	CU_ASSERT(blob->locked_operation_in_progress == true);
7600 	/* Deletion failure */
7601 	CU_ASSERT(g_bserrno == -EBUSY);
7602 	poll_threads();
7603 	CU_ASSERT(blob->locked_operation_in_progress == false);
7604 	/* Inflation success */
7605 	CU_ASSERT(g_bserrno == 0);
7606 
7607 	/* Clone snapshot and try to remove snapshot in the same time:
7608 	 * - snapshot should be cloned successfully
7609 	 * - delete operation should fail w -EBUSY */
7610 	CU_ASSERT(blob->locked_operation_in_progress == false);
7611 	spdk_bs_create_clone(bs, snapshotid, NULL, blob_op_with_id_complete, NULL);
7612 	spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL);
7613 	/* Deletion failure */
7614 	CU_ASSERT(g_bserrno == -EBUSY);
7615 	poll_threads();
7616 	CU_ASSERT(blob->locked_operation_in_progress == false);
7617 	/* Clone created */
7618 	CU_ASSERT(g_bserrno == 0);
7619 
7620 	/* Resize blob and try to remove blob in the same time:
7621 	 * - blob should be resized successfully
7622 	 * - delete operation should fail w -EBUSY */
7623 	CU_ASSERT(blob->locked_operation_in_progress == false);
7624 	spdk_blob_resize(blob, 50, blob_op_complete, NULL);
7625 	CU_ASSERT(blob->locked_operation_in_progress == true);
7626 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
7627 	CU_ASSERT(blob->locked_operation_in_progress == true);
7628 	/* Deletion failure */
7629 	CU_ASSERT(g_bserrno == -EBUSY);
7630 	poll_threads();
7631 	CU_ASSERT(blob->locked_operation_in_progress == false);
7632 	/* Blob resized successfully */
7633 	CU_ASSERT(g_bserrno == 0);
7634 
7635 	spdk_blob_close(blob, blob_op_complete, NULL);
7636 	poll_threads();
7637 	CU_ASSERT(g_bserrno == 0);
7638 
7639 	spdk_blob_close(snapshot, blob_op_complete, NULL);
7640 	poll_threads();
7641 	CU_ASSERT(g_bserrno == 0);
7642 
7643 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
7644 	poll_threads();
7645 	CU_ASSERT(g_bserrno == 0);
7646 
7647 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
7648 	poll_threads();
7649 	CU_ASSERT(g_bserrno == 0);
7650 	g_bs = NULL;
7651 
7652 	spdk_bs_free_io_channel(channel);
7653 	poll_threads();
7654 }
7655 
7656 int main(int argc, char **argv)
7657 {
7658 	CU_pSuite	suite = NULL;
7659 	unsigned int	num_failures;
7660 
7661 	if (CU_initialize_registry() != CUE_SUCCESS) {
7662 		return CU_get_error();
7663 	}
7664 
7665 	suite = CU_add_suite("blob", NULL, NULL);
7666 	if (suite == NULL) {
7667 		CU_cleanup_registry();
7668 		return CU_get_error();
7669 	}
7670 
7671 	if (
7672 		CU_add_test(suite, "blob_init", blob_init) == NULL ||
7673 		CU_add_test(suite, "blob_open", blob_open) == NULL ||
7674 		CU_add_test(suite, "blob_create", blob_create) == NULL ||
7675 		CU_add_test(suite, "blob_create_internal", blob_create_internal) == NULL ||
7676 		CU_add_test(suite, "blob_thin_provision", blob_thin_provision) == NULL ||
7677 		CU_add_test(suite, "blob_snapshot", blob_snapshot) == NULL ||
7678 		CU_add_test(suite, "blob_clone", blob_clone) == NULL ||
7679 		CU_add_test(suite, "blob_inflate", blob_inflate) == NULL ||
7680 		CU_add_test(suite, "blob_delete", blob_delete) == NULL ||
7681 		CU_add_test(suite, "blob_resize", blob_resize) == NULL ||
7682 		CU_add_test(suite, "blob_read_only", blob_read_only) == NULL ||
7683 		CU_add_test(suite, "channel_ops", channel_ops) == NULL ||
7684 		CU_add_test(suite, "blob_super", blob_super) == NULL ||
7685 		CU_add_test(suite, "blob_write", blob_write) == NULL ||
7686 		CU_add_test(suite, "blob_read", blob_read) == NULL ||
7687 		CU_add_test(suite, "blob_rw_verify", blob_rw_verify) == NULL ||
7688 		CU_add_test(suite, "blob_rw_verify_iov", blob_rw_verify_iov) == NULL ||
7689 		CU_add_test(suite, "blob_rw_verify_iov_nomem", blob_rw_verify_iov_nomem) == NULL ||
7690 		CU_add_test(suite, "blob_rw_iov_read_only", blob_rw_iov_read_only) == NULL ||
7691 		CU_add_test(suite, "blob_unmap", blob_unmap) == NULL ||
7692 		CU_add_test(suite, "blob_iter", blob_iter) == NULL ||
7693 		CU_add_test(suite, "blob_xattr", blob_xattr) == NULL ||
7694 		CU_add_test(suite, "bs_load", bs_load) == NULL ||
7695 		CU_add_test(suite, "bs_load_pending_removal", bs_load_pending_removal) == NULL ||
7696 		CU_add_test(suite, "bs_load_custom_cluster_size", bs_load_custom_cluster_size) == NULL ||
7697 		CU_add_test(suite, "bs_unload", bs_unload) == NULL ||
7698 		CU_add_test(suite, "bs_cluster_sz", bs_cluster_sz) == NULL ||
7699 		CU_add_test(suite, "bs_usable_clusters", bs_usable_clusters) == NULL ||
7700 		CU_add_test(suite, "bs_resize_md", bs_resize_md) == NULL ||
7701 		CU_add_test(suite, "bs_destroy", bs_destroy) == NULL ||
7702 		CU_add_test(suite, "bs_type", bs_type) == NULL ||
7703 		CU_add_test(suite, "bs_super_block", bs_super_block) == NULL ||
7704 		CU_add_test(suite, "blob_serialize", blob_serialize) == NULL ||
7705 		CU_add_test(suite, "blob_crc", blob_crc) == NULL ||
7706 		CU_add_test(suite, "super_block_crc", super_block_crc) == NULL ||
7707 		CU_add_test(suite, "blob_dirty_shutdown", blob_dirty_shutdown) == NULL ||
7708 		CU_add_test(suite, "blob_flags", blob_flags) == NULL ||
7709 		CU_add_test(suite, "bs_version", bs_version) == NULL ||
7710 		CU_add_test(suite, "blob_set_xattrs", blob_set_xattrs) == NULL ||
7711 		CU_add_test(suite, "blob_thin_prov_alloc", blob_thin_prov_alloc) == NULL ||
7712 		CU_add_test(suite, "blob_insert_cluster_msg", blob_insert_cluster_msg) == NULL ||
7713 		CU_add_test(suite, "blob_thin_prov_rw", blob_thin_prov_rw) == NULL ||
7714 		CU_add_test(suite, "blob_thin_prov_rle", blob_thin_prov_rle) == NULL ||
7715 		CU_add_test(suite, "blob_thin_prov_rw_iov", blob_thin_prov_rw_iov) == NULL ||
7716 		CU_add_test(suite, "bs_load_iter", bs_load_iter) == NULL ||
7717 		CU_add_test(suite, "blob_snapshot_rw", blob_snapshot_rw) == NULL ||
7718 		CU_add_test(suite, "blob_snapshot_rw_iov", blob_snapshot_rw_iov) == NULL ||
7719 		CU_add_test(suite, "blob_relations", blob_relations) == NULL ||
7720 		CU_add_test(suite, "blob_relations2", blob_relations2) == NULL ||
7721 		CU_add_test(suite, "blob_delete_snapshot_power_failure",
7722 			    blob_delete_snapshot_power_failure) == NULL ||
7723 		CU_add_test(suite, "blob_create_snapshot_power_failure",
7724 			    blob_create_snapshot_power_failure) == NULL ||
7725 		CU_add_test(suite, "blob_inflate_rw", blob_inflate_rw) == NULL ||
7726 		CU_add_test(suite, "blob_snapshot_freeze_io", blob_snapshot_freeze_io) == NULL ||
7727 		CU_add_test(suite, "blob_operation_split_rw", blob_operation_split_rw) == NULL ||
7728 		CU_add_test(suite, "blob_operation_split_rw_iov", blob_operation_split_rw_iov) == NULL ||
7729 		CU_add_test(suite, "blob_io_unit", blob_io_unit) == NULL ||
7730 		CU_add_test(suite, "blob_io_unit_compatiblity", blob_io_unit_compatiblity) == NULL ||
7731 		CU_add_test(suite, "blob_simultaneous_operations", blob_simultaneous_operations) == NULL
7732 	) {
7733 		CU_cleanup_registry();
7734 		return CU_get_error();
7735 	}
7736 
7737 	allocate_threads(2);
7738 	set_thread(0);
7739 
7740 	g_dev_buffer = calloc(1, DEV_BUFFER_SIZE);
7741 
7742 	CU_basic_set_mode(CU_BRM_VERBOSE);
7743 	g_use_extent_table = false;
7744 	CU_basic_run_tests();
7745 	num_failures = CU_get_number_of_failures();
7746 	g_use_extent_table = true;
7747 	CU_basic_run_tests();
7748 	num_failures += CU_get_number_of_failures();
7749 	CU_cleanup_registry();
7750 
7751 	free(g_dev_buffer);
7752 
7753 	free_threads();
7754 
7755 	return num_failures;
7756 }
7757