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