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