xref: /spdk/test/unit/lib/blob/blob.c/blob_ut.c (revision a9f76ed2043ed8e8fc62766295766b761b15d3fa)
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_blob_opts blob_opts;
3287 	uint32_t clusters;
3288 	int i;
3289 
3290 	/* Init blobstore */
3291 	dev = init_dev();
3292 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
3293 	poll_threads();
3294 	CU_ASSERT(g_bserrno == 0);
3295 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3296 	bs = g_bs;
3297 
3298 	clusters = spdk_bs_total_data_cluster_count(bs);
3299 
3300 	ut_bs_reload(&bs, NULL);
3301 
3302 	CU_ASSERT(spdk_bs_total_data_cluster_count(bs) == clusters);
3303 	ut_spdk_blob_opts_init(&blob_opts);
3304 
3305 	/* Create and resize blobs to make sure that useable cluster count won't change */
3306 	for (i = 0; i < 4; i++) {
3307 		g_bserrno = -1;
3308 		g_blobid = SPDK_BLOBID_INVALID;
3309 		spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL);
3310 		poll_threads();
3311 		CU_ASSERT(g_bserrno == 0);
3312 		CU_ASSERT(g_blobid !=  SPDK_BLOBID_INVALID);
3313 
3314 		g_bserrno = -1;
3315 		g_blob = NULL;
3316 		spdk_bs_open_blob(bs, g_blobid, blob_op_with_handle_complete, NULL);
3317 		poll_threads();
3318 		CU_ASSERT(g_bserrno == 0);
3319 		CU_ASSERT(g_blob !=  NULL);
3320 
3321 		spdk_blob_resize(g_blob, 10, blob_op_complete, NULL);
3322 		poll_threads();
3323 		CU_ASSERT(g_bserrno == 0);
3324 
3325 		g_bserrno = -1;
3326 		spdk_blob_close(g_blob, blob_op_complete, NULL);
3327 		poll_threads();
3328 		CU_ASSERT(g_bserrno == 0);
3329 
3330 		CU_ASSERT(spdk_bs_total_data_cluster_count(bs) == clusters);
3331 	}
3332 
3333 	/* Reload the blob store to make sure that nothing changed */
3334 	ut_bs_reload(&bs, NULL);
3335 
3336 	CU_ASSERT(spdk_bs_total_data_cluster_count(bs) == clusters);
3337 
3338 	spdk_bs_unload(bs, bs_op_complete, NULL);
3339 	poll_threads();
3340 	CU_ASSERT(g_bserrno == 0);
3341 	g_bs = NULL;
3342 }
3343 
3344 /*
3345  * Test resizing of the metadata blob.  This requires creating enough blobs
3346  *  so that one cluster is not enough to fit the metadata for those blobs.
3347  *  To induce this condition to happen more quickly, we reduce the cluster
3348  *  size to 16KB, which means only 4 4KB blob metadata pages can fit.
3349  */
3350 static void
3351 bs_resize_md(void)
3352 {
3353 	struct spdk_blob_store *bs;
3354 	const int CLUSTER_PAGE_COUNT = 4;
3355 	const int NUM_BLOBS = CLUSTER_PAGE_COUNT * 4;
3356 	struct spdk_bs_dev *dev;
3357 	struct spdk_bs_opts opts;
3358 	struct spdk_blob_opts blob_opts;
3359 	uint32_t cluster_sz;
3360 	spdk_blob_id blobids[NUM_BLOBS];
3361 	int i;
3362 
3363 
3364 	dev = init_dev();
3365 	spdk_bs_opts_init(&opts);
3366 	opts.cluster_sz = CLUSTER_PAGE_COUNT * 4096;
3367 	cluster_sz = opts.cluster_sz;
3368 
3369 	/* Initialize a new blob store */
3370 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
3371 	poll_threads();
3372 	CU_ASSERT(g_bserrno == 0);
3373 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3374 	bs = g_bs;
3375 
3376 	CU_ASSERT(spdk_bs_get_cluster_size(bs) == cluster_sz);
3377 
3378 	ut_spdk_blob_opts_init(&blob_opts);
3379 
3380 	for (i = 0; i < NUM_BLOBS; i++) {
3381 		g_bserrno = -1;
3382 		g_blobid = SPDK_BLOBID_INVALID;
3383 		spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL);
3384 		poll_threads();
3385 		CU_ASSERT(g_bserrno == 0);
3386 		CU_ASSERT(g_blobid !=  SPDK_BLOBID_INVALID);
3387 		blobids[i] = g_blobid;
3388 	}
3389 
3390 	ut_bs_reload(&bs, &opts);
3391 
3392 	CU_ASSERT(spdk_bs_get_cluster_size(bs) == cluster_sz);
3393 
3394 	for (i = 0; i < NUM_BLOBS; i++) {
3395 		g_bserrno = -1;
3396 		g_blob = NULL;
3397 		spdk_bs_open_blob(bs, blobids[i], blob_op_with_handle_complete, NULL);
3398 		poll_threads();
3399 		CU_ASSERT(g_bserrno == 0);
3400 		CU_ASSERT(g_blob !=  NULL);
3401 		g_bserrno = -1;
3402 		spdk_blob_close(g_blob, blob_op_complete, NULL);
3403 		poll_threads();
3404 		CU_ASSERT(g_bserrno == 0);
3405 	}
3406 
3407 	spdk_bs_unload(bs, bs_op_complete, NULL);
3408 	poll_threads();
3409 	CU_ASSERT(g_bserrno == 0);
3410 	g_bs = NULL;
3411 }
3412 
3413 static void
3414 bs_destroy(void)
3415 {
3416 	struct spdk_blob_store *bs;
3417 	struct spdk_bs_dev *dev;
3418 
3419 	/* Initialize a new blob store */
3420 	dev = init_dev();
3421 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
3422 	poll_threads();
3423 	CU_ASSERT(g_bserrno == 0);
3424 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3425 	bs = g_bs;
3426 
3427 	/* Destroy the blob store */
3428 	g_bserrno = -1;
3429 	spdk_bs_destroy(bs, bs_op_complete, NULL);
3430 	poll_threads();
3431 	CU_ASSERT(g_bserrno == 0);
3432 
3433 	/* Loading an non-existent blob store should fail. */
3434 	g_bs = NULL;
3435 	dev = init_dev();
3436 
3437 	g_bserrno = 0;
3438 	spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL);
3439 	poll_threads();
3440 	CU_ASSERT(g_bserrno != 0);
3441 }
3442 
3443 /* Try to hit all of the corner cases associated with serializing
3444  * a blob to disk
3445  */
3446 static void
3447 blob_serialize(void)
3448 {
3449 	struct spdk_bs_dev *dev;
3450 	struct spdk_bs_opts opts;
3451 	struct spdk_blob_store *bs;
3452 	struct spdk_blob_opts blob_opts;
3453 	spdk_blob_id blobid[2];
3454 	struct spdk_blob *blob[2];
3455 	uint64_t i;
3456 	char *value;
3457 	int rc;
3458 
3459 	dev = init_dev();
3460 
3461 	/* Initialize a new blobstore with very small clusters */
3462 	spdk_bs_opts_init(&opts);
3463 	opts.cluster_sz = dev->blocklen * 8;
3464 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
3465 	poll_threads();
3466 	CU_ASSERT(g_bserrno == 0);
3467 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3468 	bs = g_bs;
3469 	ut_spdk_blob_opts_init(&blob_opts);
3470 
3471 	/* Create and open two blobs */
3472 	for (i = 0; i < 2; i++) {
3473 		spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL);
3474 		poll_threads();
3475 		CU_ASSERT(g_bserrno == 0);
3476 		CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3477 		blobid[i] = g_blobid;
3478 
3479 		/* Open a blob */
3480 		spdk_bs_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL);
3481 		poll_threads();
3482 		CU_ASSERT(g_bserrno == 0);
3483 		CU_ASSERT(g_blob != NULL);
3484 		blob[i] = g_blob;
3485 
3486 		/* Set a fairly large xattr on both blobs to eat up
3487 		 * metadata space
3488 		 */
3489 		value = calloc(dev->blocklen - 64, sizeof(char));
3490 		SPDK_CU_ASSERT_FATAL(value != NULL);
3491 		memset(value, i, dev->blocklen / 2);
3492 		rc = spdk_blob_set_xattr(blob[i], "name", value, dev->blocklen - 64);
3493 		CU_ASSERT(rc == 0);
3494 		free(value);
3495 	}
3496 
3497 	/* Resize the blobs, alternating 1 cluster at a time.
3498 	 * This thwarts run length encoding and will cause spill
3499 	 * over of the extents.
3500 	 */
3501 	for (i = 0; i < 6; i++) {
3502 		spdk_blob_resize(blob[i % 2], (i / 2) + 1, blob_op_complete, NULL);
3503 		poll_threads();
3504 		CU_ASSERT(g_bserrno == 0);
3505 	}
3506 
3507 	for (i = 0; i < 2; i++) {
3508 		spdk_blob_sync_md(blob[i], blob_op_complete, NULL);
3509 		poll_threads();
3510 		CU_ASSERT(g_bserrno == 0);
3511 	}
3512 
3513 	/* Close the blobs */
3514 	for (i = 0; i < 2; i++) {
3515 		spdk_blob_close(blob[i], blob_op_complete, NULL);
3516 		poll_threads();
3517 		CU_ASSERT(g_bserrno == 0);
3518 	}
3519 
3520 	ut_bs_reload(&bs, &opts);
3521 
3522 	for (i = 0; i < 2; i++) {
3523 		blob[i] = NULL;
3524 
3525 		spdk_bs_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL);
3526 		poll_threads();
3527 		CU_ASSERT(g_bserrno == 0);
3528 		CU_ASSERT(g_blob != NULL);
3529 		blob[i] = g_blob;
3530 
3531 		CU_ASSERT(spdk_blob_get_num_clusters(blob[i]) == 3);
3532 
3533 		spdk_blob_close(blob[i], blob_op_complete, NULL);
3534 		poll_threads();
3535 		CU_ASSERT(g_bserrno == 0);
3536 	}
3537 
3538 	spdk_bs_unload(bs, bs_op_complete, NULL);
3539 	poll_threads();
3540 	CU_ASSERT(g_bserrno == 0);
3541 	g_bs = NULL;
3542 }
3543 
3544 static void
3545 blob_crc(void)
3546 {
3547 	struct spdk_blob_store *bs;
3548 	struct spdk_bs_dev *dev;
3549 	struct spdk_blob *blob;
3550 	spdk_blob_id blobid;
3551 	uint32_t page_num;
3552 	int index;
3553 	struct spdk_blob_md_page *page;
3554 	struct spdk_blob_opts blob_opts;
3555 
3556 	dev = init_dev();
3557 
3558 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
3559 	poll_threads();
3560 	CU_ASSERT(g_bserrno == 0);
3561 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3562 	bs = g_bs;
3563 
3564 	ut_spdk_blob_opts_init(&blob_opts);
3565 	spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL);
3566 	poll_threads();
3567 	CU_ASSERT(g_bserrno == 0);
3568 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3569 	blobid = g_blobid;
3570 
3571 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
3572 	poll_threads();
3573 	CU_ASSERT(g_bserrno == 0);
3574 	CU_ASSERT(g_blob != NULL);
3575 	blob = g_blob;
3576 
3577 	spdk_blob_close(blob, blob_op_complete, NULL);
3578 	poll_threads();
3579 	CU_ASSERT(g_bserrno == 0);
3580 
3581 	page_num = _spdk_bs_blobid_to_page(blobid);
3582 	index = DEV_BUFFER_BLOCKLEN * (bs->md_start + page_num);
3583 	page = (struct spdk_blob_md_page *)&g_dev_buffer[index];
3584 	page->crc = 0;
3585 
3586 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
3587 	poll_threads();
3588 	CU_ASSERT(g_bserrno == -EINVAL);
3589 	CU_ASSERT(g_blob == NULL);
3590 	g_bserrno = 0;
3591 
3592 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
3593 	poll_threads();
3594 	CU_ASSERT(g_bserrno == -EINVAL);
3595 
3596 	spdk_bs_unload(bs, bs_op_complete, NULL);
3597 	poll_threads();
3598 	CU_ASSERT(g_bserrno == 0);
3599 	g_bs = NULL;
3600 }
3601 
3602 static void
3603 super_block_crc(void)
3604 {
3605 	struct spdk_blob_store *bs;
3606 	struct spdk_bs_dev *dev;
3607 	struct spdk_bs_super_block *super_block;
3608 
3609 	dev = init_dev();
3610 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
3611 	poll_threads();
3612 	CU_ASSERT(g_bserrno == 0);
3613 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3614 	bs = g_bs;
3615 
3616 	spdk_bs_unload(bs, bs_op_complete, NULL);
3617 	poll_threads();
3618 	CU_ASSERT(g_bserrno == 0);
3619 	g_bs = NULL;
3620 
3621 	super_block = (struct spdk_bs_super_block *)g_dev_buffer;
3622 	super_block->crc = 0;
3623 	dev = init_dev();
3624 
3625 	/* Load an existing blob store */
3626 	g_bserrno = 0;
3627 	spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL);
3628 	poll_threads();
3629 	CU_ASSERT(g_bserrno == -EILSEQ);
3630 }
3631 
3632 /* For blob dirty shutdown test case we do the following sub-test cases:
3633  * 1 Initialize new blob store and create 1 super blob with some xattrs, then we
3634  *   dirty shutdown and reload the blob store and verify the xattrs.
3635  * 2 Resize the blob from 10 clusters to 20 clusters and then dirty shutdown,
3636  *   reload the blob store and verify the clusters number.
3637  * 3 Create the second blob and then dirty shutdown, reload the blob store
3638  *   and verify the second blob.
3639  * 4 Delete the second blob and then dirty shutdown, reload the blob store
3640  *   and verify the second blob is invalid.
3641  * 5 Create the second blob again and also create the third blob, modify the
3642  *   md of second blob which makes the md invalid, and then dirty shutdown,
3643  *   reload the blob store verify the second blob, it should invalid and also
3644  *   verify the third blob, it should correct.
3645  */
3646 static void
3647 blob_dirty_shutdown(void)
3648 {
3649 	int rc;
3650 	int index;
3651 	struct spdk_blob_store *bs;
3652 	struct spdk_bs_dev *dev;
3653 	spdk_blob_id blobid1, blobid2, blobid3;
3654 	struct spdk_blob *blob;
3655 	uint64_t length;
3656 	uint64_t free_clusters;
3657 	const void *value;
3658 	size_t value_len;
3659 	uint32_t page_num;
3660 	struct spdk_blob_md_page *page;
3661 	struct spdk_blob_opts blob_opts;
3662 
3663 	dev = init_dev();
3664 	/* Initialize a new blob store */
3665 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
3666 	poll_threads();
3667 	CU_ASSERT(g_bserrno == 0);
3668 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3669 	bs = g_bs;
3670 
3671 	/* Create first blob */
3672 	ut_spdk_blob_opts_init(&blob_opts);
3673 	spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL);
3674 	poll_threads();
3675 	CU_ASSERT(g_bserrno == 0);
3676 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3677 	blobid1 = g_blobid;
3678 
3679 	spdk_bs_open_blob(bs, blobid1, blob_op_with_handle_complete, NULL);
3680 	poll_threads();
3681 	CU_ASSERT(g_bserrno == 0);
3682 	CU_ASSERT(g_blob != NULL);
3683 	blob = g_blob;
3684 
3685 	/* Set some xattrs */
3686 	rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1);
3687 	CU_ASSERT(rc == 0);
3688 
3689 	length = 2345;
3690 	rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
3691 	CU_ASSERT(rc == 0);
3692 
3693 	/* Put xattr that fits exactly single page.
3694 	 * This results in adding additional pages to MD.
3695 	 * First is flags and smaller xattr, second the large xattr,
3696 	 * third are just the extents.
3697 	 */
3698 	size_t xattr_length = 4072 - sizeof(struct spdk_blob_md_descriptor_xattr) -
3699 			      strlen("large_xattr");
3700 	char *xattr = calloc(xattr_length, sizeof(char));
3701 	SPDK_CU_ASSERT_FATAL(xattr != NULL);
3702 	rc = spdk_blob_set_xattr(blob, "large_xattr", xattr, xattr_length);
3703 	free(xattr);
3704 	SPDK_CU_ASSERT_FATAL(rc == 0);
3705 
3706 	/* Resize the blob */
3707 	spdk_blob_resize(blob, 10, blob_op_complete, NULL);
3708 	poll_threads();
3709 	CU_ASSERT(g_bserrno == 0);
3710 
3711 	/* Set the blob as the super blob */
3712 	spdk_bs_set_super(bs, blobid1, blob_op_complete, NULL);
3713 	poll_threads();
3714 	CU_ASSERT(g_bserrno == 0);
3715 
3716 	free_clusters = spdk_bs_free_cluster_count(bs);
3717 
3718 	spdk_blob_close(blob, blob_op_complete, NULL);
3719 	poll_threads();
3720 	CU_ASSERT(g_bserrno == 0);
3721 	blob = NULL;
3722 	g_blob = NULL;
3723 	g_blobid = SPDK_BLOBID_INVALID;
3724 
3725 	ut_bs_dirty_load(&bs, NULL);
3726 
3727 	/* Get the super blob */
3728 	spdk_bs_get_super(bs, blob_op_with_id_complete, NULL);
3729 	poll_threads();
3730 	CU_ASSERT(g_bserrno == 0);
3731 	CU_ASSERT(blobid1 == g_blobid);
3732 
3733 	spdk_bs_open_blob(bs, blobid1, blob_op_with_handle_complete, NULL);
3734 	poll_threads();
3735 	CU_ASSERT(g_bserrno == 0);
3736 	CU_ASSERT(g_blob != NULL);
3737 	blob = g_blob;
3738 
3739 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3740 
3741 	/* Get the xattrs */
3742 	value = NULL;
3743 	rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len);
3744 	CU_ASSERT(rc == 0);
3745 	SPDK_CU_ASSERT_FATAL(value != NULL);
3746 	CU_ASSERT(*(uint64_t *)value == length);
3747 	CU_ASSERT(value_len == 8);
3748 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10);
3749 
3750 	/* Resize the blob */
3751 	spdk_blob_resize(blob, 20, blob_op_complete, NULL);
3752 	poll_threads();
3753 	CU_ASSERT(g_bserrno == 0);
3754 
3755 	free_clusters = spdk_bs_free_cluster_count(bs);
3756 
3757 	spdk_blob_close(blob, blob_op_complete, NULL);
3758 	poll_threads();
3759 	CU_ASSERT(g_bserrno == 0);
3760 	blob = NULL;
3761 	g_blob = NULL;
3762 	g_blobid = SPDK_BLOBID_INVALID;
3763 
3764 	ut_bs_dirty_load(&bs, NULL);
3765 
3766 	spdk_bs_open_blob(bs, blobid1, blob_op_with_handle_complete, NULL);
3767 	poll_threads();
3768 	CU_ASSERT(g_bserrno == 0);
3769 	CU_ASSERT(g_blob != NULL);
3770 	blob = g_blob;
3771 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 20);
3772 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3773 
3774 	spdk_blob_close(blob, blob_op_complete, NULL);
3775 	poll_threads();
3776 	CU_ASSERT(g_bserrno == 0);
3777 	blob = NULL;
3778 	g_blob = NULL;
3779 	g_blobid = SPDK_BLOBID_INVALID;
3780 
3781 	/* Create second blob */
3782 	spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL);
3783 	poll_threads();
3784 	CU_ASSERT(g_bserrno == 0);
3785 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3786 	blobid2 = g_blobid;
3787 
3788 	spdk_bs_open_blob(bs, blobid2, blob_op_with_handle_complete, NULL);
3789 	poll_threads();
3790 	CU_ASSERT(g_bserrno == 0);
3791 	CU_ASSERT(g_blob != NULL);
3792 	blob = g_blob;
3793 
3794 	/* Set some xattrs */
3795 	rc = spdk_blob_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1);
3796 	CU_ASSERT(rc == 0);
3797 
3798 	length = 5432;
3799 	rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
3800 	CU_ASSERT(rc == 0);
3801 
3802 	/* Resize the blob */
3803 	spdk_blob_resize(blob, 10, blob_op_complete, NULL);
3804 	poll_threads();
3805 	CU_ASSERT(g_bserrno == 0);
3806 
3807 	free_clusters = spdk_bs_free_cluster_count(bs);
3808 
3809 	spdk_blob_close(blob, blob_op_complete, NULL);
3810 	poll_threads();
3811 	CU_ASSERT(g_bserrno == 0);
3812 	blob = NULL;
3813 	g_blob = NULL;
3814 	g_blobid = SPDK_BLOBID_INVALID;
3815 
3816 	ut_bs_dirty_load(&bs, NULL);
3817 
3818 	spdk_bs_open_blob(bs, blobid2, blob_op_with_handle_complete, NULL);
3819 	poll_threads();
3820 	CU_ASSERT(g_bserrno == 0);
3821 	CU_ASSERT(g_blob != NULL);
3822 	blob = g_blob;
3823 
3824 	/* Get the xattrs */
3825 	value = NULL;
3826 	rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len);
3827 	CU_ASSERT(rc == 0);
3828 	SPDK_CU_ASSERT_FATAL(value != NULL);
3829 	CU_ASSERT(*(uint64_t *)value == length);
3830 	CU_ASSERT(value_len == 8);
3831 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10);
3832 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3833 
3834 	spdk_blob_close(blob, blob_op_complete, NULL);
3835 	poll_threads();
3836 	CU_ASSERT(g_bserrno == 0);
3837 	spdk_bs_delete_blob(bs, blobid2, blob_op_complete, NULL);
3838 	poll_threads();
3839 	CU_ASSERT(g_bserrno == 0);
3840 
3841 	free_clusters = spdk_bs_free_cluster_count(bs);
3842 
3843 	ut_bs_dirty_load(&bs, NULL);
3844 
3845 	spdk_bs_open_blob(bs, blobid2, blob_op_with_handle_complete, NULL);
3846 	poll_threads();
3847 	CU_ASSERT(g_bserrno != 0);
3848 	CU_ASSERT(g_blob == NULL);
3849 
3850 	spdk_bs_open_blob(bs, blobid1, blob_op_with_handle_complete, NULL);
3851 	poll_threads();
3852 	CU_ASSERT(g_bserrno == 0);
3853 	CU_ASSERT(g_blob != NULL);
3854 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3855 	spdk_blob_close(g_blob, blob_op_complete, NULL);
3856 	poll_threads();
3857 	CU_ASSERT(g_bserrno == 0);
3858 
3859 	ut_bs_reload(&bs, NULL);
3860 
3861 	/* Create second blob */
3862 	spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL);
3863 	poll_threads();
3864 	CU_ASSERT(g_bserrno == 0);
3865 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3866 	blobid2 = g_blobid;
3867 
3868 	/* Create third blob */
3869 	spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL);
3870 	poll_threads();
3871 	CU_ASSERT(g_bserrno == 0);
3872 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3873 	blobid3 = g_blobid;
3874 
3875 	spdk_bs_open_blob(bs, blobid2, blob_op_with_handle_complete, NULL);
3876 	poll_threads();
3877 	CU_ASSERT(g_bserrno == 0);
3878 	CU_ASSERT(g_blob != NULL);
3879 	blob = g_blob;
3880 
3881 	/* Set some xattrs for second blob */
3882 	rc = spdk_blob_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1);
3883 	CU_ASSERT(rc == 0);
3884 
3885 	length = 5432;
3886 	rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
3887 	CU_ASSERT(rc == 0);
3888 
3889 	spdk_blob_close(blob, blob_op_complete, NULL);
3890 	poll_threads();
3891 	CU_ASSERT(g_bserrno == 0);
3892 	blob = NULL;
3893 	g_blob = NULL;
3894 	g_blobid = SPDK_BLOBID_INVALID;
3895 
3896 	spdk_bs_open_blob(bs, blobid3, blob_op_with_handle_complete, NULL);
3897 	poll_threads();
3898 	CU_ASSERT(g_bserrno == 0);
3899 	CU_ASSERT(g_blob != NULL);
3900 	blob = g_blob;
3901 
3902 	/* Set some xattrs for third blob */
3903 	rc = spdk_blob_set_xattr(blob, "name", "log2.txt", strlen("log2.txt") + 1);
3904 	CU_ASSERT(rc == 0);
3905 
3906 	length = 5432;
3907 	rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
3908 	CU_ASSERT(rc == 0);
3909 
3910 	spdk_blob_close(blob, blob_op_complete, NULL);
3911 	poll_threads();
3912 	CU_ASSERT(g_bserrno == 0);
3913 	blob = NULL;
3914 	g_blob = NULL;
3915 	g_blobid = SPDK_BLOBID_INVALID;
3916 
3917 	/* Mark second blob as invalid */
3918 	page_num = _spdk_bs_blobid_to_page(blobid2);
3919 
3920 	index = DEV_BUFFER_BLOCKLEN * (bs->md_start + page_num);
3921 	page = (struct spdk_blob_md_page *)&g_dev_buffer[index];
3922 	page->sequence_num = 1;
3923 	page->crc = _spdk_blob_md_page_calc_crc(page);
3924 
3925 	free_clusters = spdk_bs_free_cluster_count(bs);
3926 
3927 	ut_bs_dirty_load(&bs, NULL);
3928 
3929 	spdk_bs_open_blob(bs, blobid2, blob_op_with_handle_complete, NULL);
3930 	poll_threads();
3931 	CU_ASSERT(g_bserrno != 0);
3932 	CU_ASSERT(g_blob == NULL);
3933 
3934 	spdk_bs_open_blob(bs, blobid3, blob_op_with_handle_complete, NULL);
3935 	poll_threads();
3936 	CU_ASSERT(g_bserrno == 0);
3937 	CU_ASSERT(g_blob != NULL);
3938 	blob = g_blob;
3939 
3940 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3941 
3942 	spdk_blob_close(blob, blob_op_complete, NULL);
3943 	poll_threads();
3944 	CU_ASSERT(g_bserrno == 0);
3945 	blob = NULL;
3946 	g_blob = NULL;
3947 	g_blobid = SPDK_BLOBID_INVALID;
3948 
3949 	spdk_bs_unload(bs, bs_op_complete, NULL);
3950 	poll_threads();
3951 	CU_ASSERT(g_bserrno == 0);
3952 	g_bs = NULL;
3953 }
3954 
3955 static void
3956 blob_flags(void)
3957 {
3958 	struct spdk_blob_store *bs;
3959 	struct spdk_bs_dev *dev;
3960 	spdk_blob_id blobid_invalid, blobid_data_ro, blobid_md_ro;
3961 	struct spdk_blob *blob_invalid, *blob_data_ro, *blob_md_ro;
3962 	struct spdk_blob_opts blob_opts;
3963 	int rc;
3964 
3965 	dev = init_dev();
3966 	ut_spdk_blob_opts_init(&blob_opts);
3967 
3968 	/* Initialize a new blob store */
3969 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
3970 	poll_threads();
3971 	CU_ASSERT(g_bserrno == 0);
3972 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3973 	bs = g_bs;
3974 
3975 	/* Create three blobs - one each for testing invalid, data_ro and md_ro flags. */
3976 	spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL);
3977 	poll_threads();
3978 	CU_ASSERT(g_bserrno == 0);
3979 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3980 	blobid_invalid = g_blobid;
3981 
3982 	spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL);
3983 	poll_threads();
3984 	CU_ASSERT(g_bserrno == 0);
3985 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3986 	blobid_data_ro = g_blobid;
3987 
3988 	blob_opts.clear_method = BLOB_CLEAR_WITH_WRITE_ZEROES;
3989 	spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL);
3990 	poll_threads();
3991 	CU_ASSERT(g_bserrno == 0);
3992 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3993 	blobid_md_ro = g_blobid;
3994 
3995 	spdk_bs_open_blob(bs, blobid_invalid, blob_op_with_handle_complete, NULL);
3996 	poll_threads();
3997 	CU_ASSERT(g_bserrno == 0);
3998 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3999 	blob_invalid = g_blob;
4000 
4001 	spdk_bs_open_blob(bs, blobid_data_ro, blob_op_with_handle_complete, NULL);
4002 	poll_threads();
4003 	CU_ASSERT(g_bserrno == 0);
4004 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4005 	blob_data_ro = g_blob;
4006 
4007 	spdk_bs_open_blob(bs, blobid_md_ro, 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_md_ro = g_blob;
4012 	CU_ASSERT((blob_md_ro->md_ro_flags & SPDK_BLOB_MD_RO_FLAGS_MASK) == BLOB_CLEAR_WITH_WRITE_ZEROES);
4013 
4014 	/* Change the size of blob_data_ro to check if flags are serialized
4015 	 * when blob has non zero number of extents */
4016 	spdk_blob_resize(blob_data_ro, 10, blob_op_complete, NULL);
4017 	poll_threads();
4018 	CU_ASSERT(g_bserrno == 0);
4019 
4020 	/* Set the xattr to check if flags are serialized
4021 	 * when blob has non zero number of xattrs */
4022 	rc = spdk_blob_set_xattr(blob_md_ro, "name", "log.txt", strlen("log.txt") + 1);
4023 	CU_ASSERT(rc == 0);
4024 
4025 	blob_invalid->invalid_flags = (1ULL << 63);
4026 	blob_invalid->state = SPDK_BLOB_STATE_DIRTY;
4027 	blob_data_ro->data_ro_flags = (1ULL << 62);
4028 	blob_data_ro->state = SPDK_BLOB_STATE_DIRTY;
4029 	blob_md_ro->md_ro_flags = (1ULL << 61);
4030 	blob_md_ro->state = SPDK_BLOB_STATE_DIRTY;
4031 
4032 	g_bserrno = -1;
4033 	spdk_blob_sync_md(blob_invalid, blob_op_complete, NULL);
4034 	poll_threads();
4035 	CU_ASSERT(g_bserrno == 0);
4036 	g_bserrno = -1;
4037 	spdk_blob_sync_md(blob_data_ro, blob_op_complete, NULL);
4038 	poll_threads();
4039 	CU_ASSERT(g_bserrno == 0);
4040 	g_bserrno = -1;
4041 	spdk_blob_sync_md(blob_md_ro, blob_op_complete, NULL);
4042 	poll_threads();
4043 	CU_ASSERT(g_bserrno == 0);
4044 
4045 	g_bserrno = -1;
4046 	spdk_blob_close(blob_invalid, blob_op_complete, NULL);
4047 	poll_threads();
4048 	CU_ASSERT(g_bserrno == 0);
4049 	blob_invalid = NULL;
4050 	g_bserrno = -1;
4051 	spdk_blob_close(blob_data_ro, blob_op_complete, NULL);
4052 	poll_threads();
4053 	CU_ASSERT(g_bserrno == 0);
4054 	blob_data_ro = NULL;
4055 	g_bserrno = -1;
4056 	spdk_blob_close(blob_md_ro, blob_op_complete, NULL);
4057 	poll_threads();
4058 	CU_ASSERT(g_bserrno == 0);
4059 	blob_md_ro = NULL;
4060 
4061 	g_blob = NULL;
4062 	g_blobid = SPDK_BLOBID_INVALID;
4063 
4064 	ut_bs_reload(&bs, NULL);
4065 
4066 	g_blob = NULL;
4067 	g_bserrno = 0;
4068 	spdk_bs_open_blob(bs, blobid_invalid, blob_op_with_handle_complete, NULL);
4069 	poll_threads();
4070 	CU_ASSERT(g_bserrno != 0);
4071 	CU_ASSERT(g_blob == NULL);
4072 
4073 	g_blob = NULL;
4074 	g_bserrno = -1;
4075 	spdk_bs_open_blob(bs, blobid_data_ro, blob_op_with_handle_complete, NULL);
4076 	poll_threads();
4077 	CU_ASSERT(g_bserrno == 0);
4078 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4079 	blob_data_ro = g_blob;
4080 	/* If an unknown data_ro flag was found, the blob should be marked both data and md read-only. */
4081 	CU_ASSERT(blob_data_ro->data_ro == true);
4082 	CU_ASSERT(blob_data_ro->md_ro == true);
4083 	CU_ASSERT(spdk_blob_get_num_clusters(blob_data_ro) == 10);
4084 
4085 	g_blob = NULL;
4086 	g_bserrno = -1;
4087 	spdk_bs_open_blob(bs, blobid_md_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_md_ro = g_blob;
4092 	CU_ASSERT(blob_md_ro->data_ro == false);
4093 	CU_ASSERT(blob_md_ro->md_ro == true);
4094 
4095 	g_bserrno = -1;
4096 	spdk_blob_sync_md(blob_md_ro, blob_op_complete, NULL);
4097 	poll_threads();
4098 	CU_ASSERT(g_bserrno == 0);
4099 
4100 	spdk_blob_close(blob_data_ro, blob_op_complete, NULL);
4101 	poll_threads();
4102 	CU_ASSERT(g_bserrno == 0);
4103 	spdk_blob_close(blob_md_ro, blob_op_complete, NULL);
4104 	poll_threads();
4105 	CU_ASSERT(g_bserrno == 0);
4106 
4107 	spdk_bs_unload(bs, bs_op_complete, NULL);
4108 	poll_threads();
4109 	CU_ASSERT(g_bserrno == 0);
4110 }
4111 
4112 static void
4113 bs_version(void)
4114 {
4115 	struct spdk_bs_super_block *super;
4116 	struct spdk_blob_store *bs;
4117 	struct spdk_bs_dev *dev;
4118 	struct spdk_blob_opts blob_opts;
4119 	spdk_blob_id blobid;
4120 
4121 	dev = init_dev();
4122 
4123 	/* Initialize a new blob store */
4124 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
4125 	poll_threads();
4126 	CU_ASSERT(g_bserrno == 0);
4127 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
4128 	bs = g_bs;
4129 
4130 	/* Unload the blob store */
4131 	spdk_bs_unload(bs, bs_op_complete, NULL);
4132 	poll_threads();
4133 	CU_ASSERT(g_bserrno == 0);
4134 	g_bs = NULL;
4135 
4136 	/*
4137 	 * Change the bs version on disk.  This will allow us to
4138 	 *  test that the version does not get modified automatically
4139 	 *  when loading and unloading the blobstore.
4140 	 */
4141 	super = (struct spdk_bs_super_block *)&g_dev_buffer[0];
4142 	CU_ASSERT(super->version == SPDK_BS_VERSION);
4143 	CU_ASSERT(super->clean == 1);
4144 	super->version = 2;
4145 	/*
4146 	 * Version 2 metadata does not have a used blobid mask, so clear
4147 	 *  those fields in the super block and zero the corresponding
4148 	 *  region on "disk".  We will use this to ensure blob IDs are
4149 	 *  correctly reconstructed.
4150 	 */
4151 	memset(&g_dev_buffer[super->used_blobid_mask_start * SPDK_BS_PAGE_SIZE], 0,
4152 	       super->used_blobid_mask_len * SPDK_BS_PAGE_SIZE);
4153 	super->used_blobid_mask_start = 0;
4154 	super->used_blobid_mask_len = 0;
4155 	super->crc = _spdk_blob_md_page_calc_crc(super);
4156 
4157 	/* Load an existing blob store */
4158 	dev = init_dev();
4159 	spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL);
4160 	poll_threads();
4161 	CU_ASSERT(g_bserrno == 0);
4162 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
4163 	CU_ASSERT(super->clean == 1);
4164 	bs = g_bs;
4165 
4166 	/*
4167 	 * Create a blob - just to make sure that when we unload it
4168 	 *  results in writing the super block (since metadata pages
4169 	 *  were allocated.
4170 	 */
4171 	ut_spdk_blob_opts_init(&blob_opts);
4172 	spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL);
4173 	poll_threads();
4174 	CU_ASSERT(g_bserrno == 0);
4175 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
4176 	blobid = g_blobid;
4177 
4178 	/* Unload the blob store */
4179 	spdk_bs_unload(bs, bs_op_complete, NULL);
4180 	poll_threads();
4181 	CU_ASSERT(g_bserrno == 0);
4182 	g_bs = NULL;
4183 	CU_ASSERT(super->version == 2);
4184 	CU_ASSERT(super->used_blobid_mask_start == 0);
4185 	CU_ASSERT(super->used_blobid_mask_len == 0);
4186 
4187 	dev = init_dev();
4188 	spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL);
4189 	poll_threads();
4190 	CU_ASSERT(g_bserrno == 0);
4191 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
4192 	bs = g_bs;
4193 
4194 	g_blob = NULL;
4195 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
4196 	poll_threads();
4197 	CU_ASSERT(g_bserrno == 0);
4198 	CU_ASSERT(g_blob != NULL);
4199 
4200 	spdk_blob_close(g_blob, blob_op_complete, NULL);
4201 	poll_threads();
4202 	CU_ASSERT(g_bserrno == 0);
4203 
4204 	spdk_bs_unload(bs, bs_op_complete, NULL);
4205 	poll_threads();
4206 	CU_ASSERT(g_bserrno == 0);
4207 	g_bs = NULL;
4208 	CU_ASSERT(super->version == 2);
4209 	CU_ASSERT(super->used_blobid_mask_start == 0);
4210 	CU_ASSERT(super->used_blobid_mask_len == 0);
4211 }
4212 
4213 static void
4214 blob_set_xattrs(void)
4215 {
4216 	struct spdk_blob_store *bs;
4217 	struct spdk_bs_dev *dev;
4218 	struct spdk_blob *blob;
4219 	struct spdk_blob_opts opts;
4220 	spdk_blob_id blobid;
4221 	const void *value;
4222 	size_t value_len;
4223 	char *xattr;
4224 	size_t xattr_length;
4225 	int rc;
4226 
4227 	dev = init_dev();
4228 
4229 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
4230 	poll_threads();
4231 	CU_ASSERT(g_bserrno == 0);
4232 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
4233 	bs = g_bs;
4234 
4235 	/* Create blob with extra attributes */
4236 	ut_spdk_blob_opts_init(&opts);
4237 
4238 	opts.xattrs.names = g_xattr_names;
4239 	opts.xattrs.get_value = _get_xattr_value;
4240 	opts.xattrs.count = 3;
4241 	opts.xattrs.ctx = &g_ctx;
4242 
4243 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
4244 	poll_threads();
4245 	CU_ASSERT(g_bserrno == 0);
4246 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
4247 	blobid = g_blobid;
4248 
4249 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
4250 	poll_threads();
4251 	CU_ASSERT(g_bserrno == 0);
4252 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4253 	blob = g_blob;
4254 
4255 	/* Get the xattrs */
4256 	value = NULL;
4257 
4258 	rc = spdk_blob_get_xattr_value(blob, g_xattr_names[0], &value, &value_len);
4259 	CU_ASSERT(rc == 0);
4260 	SPDK_CU_ASSERT_FATAL(value != NULL);
4261 	CU_ASSERT(value_len == strlen(g_xattr_values[0]));
4262 	CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len);
4263 
4264 	rc = spdk_blob_get_xattr_value(blob, g_xattr_names[1], &value, &value_len);
4265 	CU_ASSERT(rc == 0);
4266 	SPDK_CU_ASSERT_FATAL(value != NULL);
4267 	CU_ASSERT(value_len == strlen(g_xattr_values[1]));
4268 	CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len);
4269 
4270 	rc = spdk_blob_get_xattr_value(blob, g_xattr_names[2], &value, &value_len);
4271 	CU_ASSERT(rc == 0);
4272 	SPDK_CU_ASSERT_FATAL(value != NULL);
4273 	CU_ASSERT(value_len == strlen(g_xattr_values[2]));
4274 	CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len);
4275 
4276 	/* Try to get non existing attribute */
4277 
4278 	rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len);
4279 	CU_ASSERT(rc == -ENOENT);
4280 
4281 	/* Try xattr exceeding maximum length of descriptor in single page */
4282 	xattr_length = SPDK_BS_MAX_DESC_SIZE - sizeof(struct spdk_blob_md_descriptor_xattr) -
4283 		       strlen("large_xattr") + 1;
4284 	xattr = calloc(xattr_length, sizeof(char));
4285 	SPDK_CU_ASSERT_FATAL(xattr != NULL);
4286 	rc = spdk_blob_set_xattr(blob, "large_xattr", xattr, xattr_length);
4287 	free(xattr);
4288 	SPDK_CU_ASSERT_FATAL(rc == -ENOMEM);
4289 
4290 	spdk_blob_close(blob, blob_op_complete, NULL);
4291 	poll_threads();
4292 	CU_ASSERT(g_bserrno == 0);
4293 	blob = NULL;
4294 	g_blob = NULL;
4295 	g_blobid = SPDK_BLOBID_INVALID;
4296 
4297 	/* NULL callback */
4298 	ut_spdk_blob_opts_init(&opts);
4299 	opts.xattrs.names = g_xattr_names;
4300 	opts.xattrs.get_value = NULL;
4301 	opts.xattrs.count = 1;
4302 	opts.xattrs.ctx = &g_ctx;
4303 
4304 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
4305 	poll_threads();
4306 	CU_ASSERT(g_bserrno == -EINVAL);
4307 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
4308 
4309 	/* NULL values */
4310 	ut_spdk_blob_opts_init(&opts);
4311 	opts.xattrs.names = g_xattr_names;
4312 	opts.xattrs.get_value = _get_xattr_value_null;
4313 	opts.xattrs.count = 1;
4314 	opts.xattrs.ctx = NULL;
4315 
4316 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
4317 	poll_threads();
4318 	CU_ASSERT(g_bserrno == -EINVAL);
4319 
4320 	spdk_bs_unload(bs, bs_op_complete, NULL);
4321 	poll_threads();
4322 	CU_ASSERT(g_bserrno == 0);
4323 	g_bs = NULL;
4324 
4325 }
4326 
4327 static void
4328 blob_thin_prov_alloc(void)
4329 {
4330 	struct spdk_blob_store *bs;
4331 	struct spdk_bs_dev *dev;
4332 	struct spdk_blob *blob;
4333 	struct spdk_blob_opts opts;
4334 	spdk_blob_id blobid;
4335 	uint64_t free_clusters;
4336 
4337 	dev = init_dev();
4338 
4339 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
4340 	poll_threads();
4341 	CU_ASSERT(g_bserrno == 0);
4342 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
4343 	bs = g_bs;
4344 	free_clusters = spdk_bs_free_cluster_count(bs);
4345 
4346 	/* Set blob as thin provisioned */
4347 	ut_spdk_blob_opts_init(&opts);
4348 	opts.thin_provision = true;
4349 
4350 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
4351 	poll_threads();
4352 	CU_ASSERT(g_bserrno == 0);
4353 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
4354 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
4355 	blobid = g_blobid;
4356 
4357 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
4358 	poll_threads();
4359 	CU_ASSERT(g_bserrno == 0);
4360 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4361 	blob = g_blob;
4362 
4363 	CU_ASSERT(blob->active.num_clusters == 0);
4364 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0);
4365 
4366 	/* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */
4367 	spdk_blob_resize(blob, 5, blob_op_complete, NULL);
4368 	poll_threads();
4369 	CU_ASSERT(g_bserrno == 0);
4370 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
4371 	CU_ASSERT(blob->active.num_clusters == 5);
4372 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5);
4373 
4374 	/* Grow it to 1TB - still unallocated */
4375 	spdk_blob_resize(blob, 262144, blob_op_complete, NULL);
4376 	poll_threads();
4377 	CU_ASSERT(g_bserrno == 0);
4378 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
4379 	CU_ASSERT(blob->active.num_clusters == 262144);
4380 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 262144);
4381 
4382 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
4383 	poll_threads();
4384 	CU_ASSERT(g_bserrno == 0);
4385 	/* Sync must not change anything */
4386 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
4387 	CU_ASSERT(blob->active.num_clusters == 262144);
4388 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 262144);
4389 	/* Since clusters are not allocated,
4390 	 * number of metadata pages is expected to be minimal.
4391 	 */
4392 	CU_ASSERT(blob->active.num_pages == 1);
4393 
4394 	/* Shrink the blob to 3 clusters - still unallocated */
4395 	spdk_blob_resize(blob, 3, blob_op_complete, NULL);
4396 	poll_threads();
4397 	CU_ASSERT(g_bserrno == 0);
4398 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
4399 	CU_ASSERT(blob->active.num_clusters == 3);
4400 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 3);
4401 
4402 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
4403 	poll_threads();
4404 	CU_ASSERT(g_bserrno == 0);
4405 	/* Sync must not change anything */
4406 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
4407 	CU_ASSERT(blob->active.num_clusters == 3);
4408 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 3);
4409 
4410 	spdk_blob_close(blob, blob_op_complete, NULL);
4411 	poll_threads();
4412 	CU_ASSERT(g_bserrno == 0);
4413 
4414 	ut_bs_reload(&bs, NULL);
4415 
4416 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
4417 	poll_threads();
4418 	CU_ASSERT(g_bserrno == 0);
4419 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4420 	blob = g_blob;
4421 
4422 	/* Check that clusters allocation and size is still the same */
4423 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
4424 	CU_ASSERT(blob->active.num_clusters == 3);
4425 
4426 	spdk_blob_close(blob, blob_op_complete, NULL);
4427 	poll_threads();
4428 	CU_ASSERT(g_bserrno == 0);
4429 
4430 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
4431 	poll_threads();
4432 	CU_ASSERT(g_bserrno == 0);
4433 
4434 	spdk_bs_unload(bs, bs_op_complete, NULL);
4435 	poll_threads();
4436 	CU_ASSERT(g_bserrno == 0);
4437 	g_bs = NULL;
4438 }
4439 
4440 static void
4441 blob_insert_cluster_msg(void)
4442 {
4443 	struct spdk_blob_store *bs;
4444 	struct spdk_bs_dev *dev;
4445 	struct spdk_blob *blob;
4446 	struct spdk_blob_opts opts;
4447 	spdk_blob_id blobid;
4448 	uint64_t free_clusters;
4449 	uint64_t new_cluster = 0;
4450 	uint32_t cluster_num = 3;
4451 	uint32_t extent_page = 0;
4452 
4453 	dev = init_dev();
4454 
4455 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
4456 	poll_threads();
4457 	CU_ASSERT(g_bserrno == 0);
4458 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
4459 	bs = g_bs;
4460 	free_clusters = spdk_bs_free_cluster_count(bs);
4461 
4462 	/* Set blob as thin provisioned */
4463 	ut_spdk_blob_opts_init(&opts);
4464 	opts.thin_provision = true;
4465 	opts.num_clusters = 4;
4466 
4467 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
4468 	poll_threads();
4469 	CU_ASSERT(g_bserrno == 0);
4470 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
4471 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
4472 	blobid = g_blobid;
4473 
4474 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
4475 	poll_threads();
4476 	CU_ASSERT(g_bserrno == 0);
4477 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4478 	blob = g_blob;
4479 
4480 	CU_ASSERT(blob->active.num_clusters == 4);
4481 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 4);
4482 	CU_ASSERT(blob->active.clusters[cluster_num] == 0);
4483 
4484 	/* Specify cluster_num to allocate and new_cluster will be returned to insert on md_thread.
4485 	 * This is to simulate behaviour when cluster is allocated after blob creation.
4486 	 * Such as _spdk_bs_allocate_and_copy_cluster(). */
4487 	_spdk_bs_allocate_cluster(blob, cluster_num, &new_cluster, &extent_page, false);
4488 	CU_ASSERT(blob->active.clusters[cluster_num] == 0);
4489 
4490 	_spdk_blob_insert_cluster_on_md_thread(blob, cluster_num, new_cluster, extent_page,
4491 					       blob_op_complete, NULL);
4492 	poll_threads();
4493 
4494 	CU_ASSERT(blob->active.clusters[cluster_num] != 0);
4495 
4496 	spdk_blob_close(blob, blob_op_complete, NULL);
4497 	poll_threads();
4498 	CU_ASSERT(g_bserrno == 0);
4499 
4500 	ut_bs_reload(&bs, NULL);
4501 
4502 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
4503 	poll_threads();
4504 	CU_ASSERT(g_bserrno == 0);
4505 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4506 	blob = g_blob;
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 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
4515 	poll_threads();
4516 	CU_ASSERT(g_bserrno == 0);
4517 
4518 	spdk_bs_unload(bs, bs_op_complete, NULL);
4519 	poll_threads();
4520 	CU_ASSERT(g_bserrno == 0);
4521 	g_bs = NULL;
4522 }
4523 
4524 static void
4525 blob_thin_prov_rw(void)
4526 {
4527 	static const uint8_t zero[10 * 4096] = { 0 };
4528 	struct spdk_blob_store *bs;
4529 	struct spdk_bs_dev *dev;
4530 	struct spdk_blob *blob;
4531 	struct spdk_io_channel *channel, *channel_thread1;
4532 	struct spdk_blob_opts opts;
4533 	spdk_blob_id blobid;
4534 	uint64_t free_clusters;
4535 	uint64_t page_size;
4536 	uint8_t payload_read[10 * 4096];
4537 	uint8_t payload_write[10 * 4096];
4538 	uint64_t write_bytes;
4539 	uint64_t read_bytes;
4540 
4541 	dev = init_dev();
4542 
4543 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
4544 	poll_threads();
4545 	CU_ASSERT(g_bserrno == 0);
4546 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
4547 	bs = g_bs;
4548 	free_clusters = spdk_bs_free_cluster_count(bs);
4549 	page_size = spdk_bs_get_page_size(bs);
4550 
4551 	channel = spdk_bs_alloc_io_channel(bs);
4552 	CU_ASSERT(channel != NULL);
4553 
4554 	ut_spdk_blob_opts_init(&opts);
4555 	opts.thin_provision = true;
4556 
4557 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
4558 	poll_threads();
4559 	CU_ASSERT(g_bserrno == 0);
4560 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
4561 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
4562 	blobid = g_blobid;
4563 
4564 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
4565 	poll_threads();
4566 	CU_ASSERT(g_bserrno == 0);
4567 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4568 	blob = g_blob;
4569 
4570 	CU_ASSERT(blob->active.num_clusters == 0);
4571 
4572 	/* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */
4573 	spdk_blob_resize(blob, 5, blob_op_complete, NULL);
4574 	poll_threads();
4575 	CU_ASSERT(g_bserrno == 0);
4576 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
4577 	CU_ASSERT(blob->active.num_clusters == 5);
4578 
4579 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
4580 	poll_threads();
4581 	CU_ASSERT(g_bserrno == 0);
4582 	/* Sync must not change anything */
4583 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
4584 	CU_ASSERT(blob->active.num_clusters == 5);
4585 
4586 	/* Payload should be all zeros from unallocated clusters */
4587 	memset(payload_read, 0xFF, sizeof(payload_read));
4588 	spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL);
4589 	poll_threads();
4590 	CU_ASSERT(g_bserrno == 0);
4591 	CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0);
4592 
4593 	write_bytes = g_dev_write_bytes;
4594 	read_bytes = g_dev_read_bytes;
4595 
4596 	/* Perform write on thread 1. That will allocate cluster on thread 0 via send_msg */
4597 	set_thread(1);
4598 	channel_thread1 = spdk_bs_alloc_io_channel(bs);
4599 	CU_ASSERT(channel_thread1 != NULL);
4600 	memset(payload_write, 0xE5, sizeof(payload_write));
4601 	spdk_blob_io_write(blob, channel_thread1, payload_write, 4, 10, blob_op_complete, NULL);
4602 	CU_ASSERT(free_clusters - 1 == spdk_bs_free_cluster_count(bs));
4603 	/* Perform write on thread 0. That will try to allocate cluster,
4604 	 * but fail due to another thread issuing the cluster allocation first. */
4605 	set_thread(0);
4606 	memset(payload_write, 0xE5, sizeof(payload_write));
4607 	spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL);
4608 	CU_ASSERT(free_clusters - 2 == spdk_bs_free_cluster_count(bs));
4609 	poll_threads();
4610 	CU_ASSERT(g_bserrno == 0);
4611 	CU_ASSERT(free_clusters - 1 == spdk_bs_free_cluster_count(bs));
4612 	/* For thin-provisioned blob we need to write 20 pages plus one page metadata and
4613 	 * read 0 bytes */
4614 	if (g_use_extent_table) {
4615 		/* Add one more page for EXTENT_PAGE write */
4616 		CU_ASSERT(g_dev_write_bytes - write_bytes == page_size * 22);
4617 	} else {
4618 		CU_ASSERT(g_dev_write_bytes - write_bytes == page_size * 21);
4619 	}
4620 	CU_ASSERT(g_dev_read_bytes - read_bytes == 0);
4621 
4622 	spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL);
4623 	poll_threads();
4624 	CU_ASSERT(g_bserrno == 0);
4625 	CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0);
4626 
4627 	spdk_blob_close(blob, blob_op_complete, NULL);
4628 	poll_threads();
4629 	CU_ASSERT(g_bserrno == 0);
4630 
4631 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
4632 	poll_threads();
4633 	CU_ASSERT(g_bserrno == 0);
4634 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
4635 
4636 	set_thread(1);
4637 	spdk_bs_free_io_channel(channel_thread1);
4638 	set_thread(0);
4639 	spdk_bs_free_io_channel(channel);
4640 	poll_threads();
4641 
4642 	/* Unload the blob store */
4643 	spdk_bs_unload(bs, bs_op_complete, NULL);
4644 	poll_threads();
4645 	CU_ASSERT(g_bserrno == 0);
4646 	g_bs = NULL;
4647 	g_blob = NULL;
4648 	g_blobid = 0;
4649 }
4650 
4651 static void
4652 blob_thin_prov_rle(void)
4653 {
4654 	static const uint8_t zero[10 * 4096] = { 0 };
4655 	struct spdk_blob_store *bs;
4656 	struct spdk_bs_dev *dev;
4657 	struct spdk_blob *blob;
4658 	struct spdk_io_channel *channel;
4659 	struct spdk_blob_opts opts;
4660 	spdk_blob_id blobid;
4661 	uint64_t free_clusters;
4662 	uint64_t page_size;
4663 	uint8_t payload_read[10 * 4096];
4664 	uint8_t payload_write[10 * 4096];
4665 	uint64_t write_bytes;
4666 	uint64_t read_bytes;
4667 	uint64_t io_unit;
4668 
4669 	dev = init_dev();
4670 
4671 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
4672 	poll_threads();
4673 	CU_ASSERT(g_bserrno == 0);
4674 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
4675 	bs = g_bs;
4676 	free_clusters = spdk_bs_free_cluster_count(bs);
4677 	page_size = spdk_bs_get_page_size(bs);
4678 
4679 	ut_spdk_blob_opts_init(&opts);
4680 	opts.thin_provision = true;
4681 	opts.num_clusters = 5;
4682 
4683 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
4684 	poll_threads();
4685 	CU_ASSERT(g_bserrno == 0);
4686 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
4687 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
4688 	blobid = g_blobid;
4689 
4690 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
4691 	poll_threads();
4692 	CU_ASSERT(g_bserrno == 0);
4693 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4694 	blob = g_blob;
4695 
4696 	channel = spdk_bs_alloc_io_channel(bs);
4697 	CU_ASSERT(channel != NULL);
4698 
4699 	/* Target specifically second cluster in a blob as first allocation */
4700 	io_unit = _spdk_bs_cluster_to_page(bs, 1) * _spdk_bs_io_unit_per_page(bs);
4701 
4702 	/* Payload should be all zeros from unallocated clusters */
4703 	memset(payload_read, 0xFF, sizeof(payload_read));
4704 	spdk_blob_io_read(blob, channel, payload_read, io_unit, 10, blob_op_complete, NULL);
4705 	poll_threads();
4706 	CU_ASSERT(g_bserrno == 0);
4707 	CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0);
4708 
4709 	write_bytes = g_dev_write_bytes;
4710 	read_bytes = g_dev_read_bytes;
4711 
4712 	/* Issue write to second cluster in a blob */
4713 	memset(payload_write, 0xE5, sizeof(payload_write));
4714 	spdk_blob_io_write(blob, channel, payload_write, io_unit, 10, blob_op_complete, NULL);
4715 	poll_threads();
4716 	CU_ASSERT(g_bserrno == 0);
4717 	CU_ASSERT(free_clusters - 1 == spdk_bs_free_cluster_count(bs));
4718 	/* For thin-provisioned blob we need to write 10 pages plus one page metadata and
4719 	 * read 0 bytes */
4720 	if (g_use_extent_table) {
4721 		/* Add one more page for EXTENT_PAGE write */
4722 		CU_ASSERT(g_dev_write_bytes - write_bytes == page_size * 12);
4723 	} else {
4724 		CU_ASSERT(g_dev_write_bytes - write_bytes == page_size * 11);
4725 	}
4726 	CU_ASSERT(g_dev_read_bytes - read_bytes == 0);
4727 
4728 	spdk_blob_io_read(blob, channel, payload_read, io_unit, 10, blob_op_complete, NULL);
4729 	poll_threads();
4730 	CU_ASSERT(g_bserrno == 0);
4731 	CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0);
4732 
4733 	spdk_bs_free_io_channel(channel);
4734 	poll_threads();
4735 
4736 	spdk_blob_close(blob, blob_op_complete, NULL);
4737 	poll_threads();
4738 	CU_ASSERT(g_bserrno == 0);
4739 
4740 	ut_bs_reload(&bs, NULL);
4741 
4742 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
4743 	poll_threads();
4744 	CU_ASSERT(g_bserrno == 0);
4745 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4746 	blob = g_blob;
4747 
4748 	channel = spdk_bs_alloc_io_channel(bs);
4749 	CU_ASSERT(channel != NULL);
4750 
4751 	/* Read second cluster after blob reload to confirm data written */
4752 	spdk_blob_io_read(blob, channel, payload_read, io_unit, 10, blob_op_complete, NULL);
4753 	poll_threads();
4754 	CU_ASSERT(g_bserrno == 0);
4755 	CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0);
4756 
4757 	spdk_bs_free_io_channel(channel);
4758 	poll_threads();
4759 
4760 	spdk_blob_close(blob, blob_op_complete, NULL);
4761 	poll_threads();
4762 	CU_ASSERT(g_bserrno == 0);
4763 
4764 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
4765 	poll_threads();
4766 	CU_ASSERT(g_bserrno == 0);
4767 
4768 	spdk_bs_unload(bs, bs_op_complete, NULL);
4769 	poll_threads();
4770 	CU_ASSERT(g_bserrno == 0);
4771 	g_bs = NULL;
4772 }
4773 
4774 static void
4775 blob_thin_prov_rw_iov(void)
4776 {
4777 	static const uint8_t zero[10 * 4096] = { 0 };
4778 	struct spdk_blob_store *bs;
4779 	struct spdk_bs_dev *dev;
4780 	struct spdk_blob *blob;
4781 	struct spdk_io_channel *channel;
4782 	struct spdk_blob_opts opts;
4783 	spdk_blob_id blobid;
4784 	uint64_t free_clusters;
4785 	uint8_t payload_read[10 * 4096];
4786 	uint8_t payload_write[10 * 4096];
4787 	struct iovec iov_read[3];
4788 	struct iovec iov_write[3];
4789 
4790 	dev = init_dev();
4791 
4792 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
4793 	poll_threads();
4794 	CU_ASSERT(g_bserrno == 0);
4795 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
4796 	bs = g_bs;
4797 	free_clusters = spdk_bs_free_cluster_count(bs);
4798 
4799 	channel = spdk_bs_alloc_io_channel(bs);
4800 	CU_ASSERT(channel != NULL);
4801 
4802 	ut_spdk_blob_opts_init(&opts);
4803 	opts.thin_provision = true;
4804 
4805 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
4806 	poll_threads();
4807 	CU_ASSERT(g_bserrno == 0);
4808 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
4809 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
4810 	blobid = g_blobid;
4811 
4812 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
4813 	poll_threads();
4814 	CU_ASSERT(g_bserrno == 0);
4815 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4816 	blob = g_blob;
4817 
4818 	CU_ASSERT(blob->active.num_clusters == 0);
4819 
4820 	/* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */
4821 	spdk_blob_resize(blob, 5, blob_op_complete, NULL);
4822 	poll_threads();
4823 	CU_ASSERT(g_bserrno == 0);
4824 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
4825 	CU_ASSERT(blob->active.num_clusters == 5);
4826 
4827 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
4828 	poll_threads();
4829 	CU_ASSERT(g_bserrno == 0);
4830 	/* Sync must not change anything */
4831 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
4832 	CU_ASSERT(blob->active.num_clusters == 5);
4833 
4834 	/* Payload should be all zeros from unallocated clusters */
4835 	memset(payload_read, 0xAA, sizeof(payload_read));
4836 	iov_read[0].iov_base = payload_read;
4837 	iov_read[0].iov_len = 3 * 4096;
4838 	iov_read[1].iov_base = payload_read + 3 * 4096;
4839 	iov_read[1].iov_len = 4 * 4096;
4840 	iov_read[2].iov_base = payload_read + 7 * 4096;
4841 	iov_read[2].iov_len = 3 * 4096;
4842 	spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL);
4843 	poll_threads();
4844 	CU_ASSERT(g_bserrno == 0);
4845 	CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0);
4846 
4847 	memset(payload_write, 0xE5, sizeof(payload_write));
4848 	iov_write[0].iov_base = payload_write;
4849 	iov_write[0].iov_len = 1 * 4096;
4850 	iov_write[1].iov_base = payload_write + 1 * 4096;
4851 	iov_write[1].iov_len = 5 * 4096;
4852 	iov_write[2].iov_base = payload_write + 6 * 4096;
4853 	iov_write[2].iov_len = 4 * 4096;
4854 
4855 	spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL);
4856 	poll_threads();
4857 	CU_ASSERT(g_bserrno == 0);
4858 
4859 	memset(payload_read, 0xAA, sizeof(payload_read));
4860 	iov_read[0].iov_base = payload_read;
4861 	iov_read[0].iov_len = 3 * 4096;
4862 	iov_read[1].iov_base = payload_read + 3 * 4096;
4863 	iov_read[1].iov_len = 4 * 4096;
4864 	iov_read[2].iov_base = payload_read + 7 * 4096;
4865 	iov_read[2].iov_len = 3 * 4096;
4866 	spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL);
4867 	poll_threads();
4868 	CU_ASSERT(g_bserrno == 0);
4869 	CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0);
4870 
4871 	spdk_blob_close(blob, blob_op_complete, NULL);
4872 	poll_threads();
4873 	CU_ASSERT(g_bserrno == 0);
4874 
4875 	spdk_bs_free_io_channel(channel);
4876 	poll_threads();
4877 
4878 	/* Unload the blob store */
4879 	spdk_bs_unload(bs, bs_op_complete, NULL);
4880 	poll_threads();
4881 	CU_ASSERT(g_bserrno == 0);
4882 	g_bs = NULL;
4883 	g_blob = NULL;
4884 	g_blobid = 0;
4885 }
4886 
4887 struct iter_ctx {
4888 	int		current_iter;
4889 	spdk_blob_id	blobid[4];
4890 };
4891 
4892 static void
4893 test_iter(void *arg, struct spdk_blob *blob, int bserrno)
4894 {
4895 	struct iter_ctx *iter_ctx = arg;
4896 	spdk_blob_id blobid;
4897 
4898 	CU_ASSERT(bserrno == 0);
4899 	blobid = spdk_blob_get_id(blob);
4900 	CU_ASSERT(blobid == iter_ctx->blobid[iter_ctx->current_iter++]);
4901 }
4902 
4903 static void
4904 bs_load_iter(void)
4905 {
4906 	struct spdk_blob_store *bs;
4907 	struct spdk_bs_dev *dev;
4908 	struct iter_ctx iter_ctx = { 0 };
4909 	struct spdk_blob *blob;
4910 	int i, rc;
4911 	struct spdk_bs_opts opts;
4912 	struct spdk_blob_opts blob_opts;
4913 
4914 	dev = init_dev();
4915 	spdk_bs_opts_init(&opts);
4916 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
4917 
4918 	/* Initialize a new blob store */
4919 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
4920 	poll_threads();
4921 	CU_ASSERT(g_bserrno == 0);
4922 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
4923 	bs = g_bs;
4924 
4925 	ut_spdk_blob_opts_init(&blob_opts);
4926 
4927 	for (i = 0; i < 4; i++) {
4928 		g_bserrno = -1;
4929 		g_blobid = SPDK_BLOBID_INVALID;
4930 		spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL);
4931 		poll_threads();
4932 		CU_ASSERT(g_bserrno == 0);
4933 		CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
4934 		iter_ctx.blobid[i] = g_blobid;
4935 
4936 		g_bserrno = -1;
4937 		g_blob = NULL;
4938 		spdk_bs_open_blob(bs, g_blobid, blob_op_with_handle_complete, NULL);
4939 		poll_threads();
4940 		CU_ASSERT(g_bserrno == 0);
4941 		CU_ASSERT(g_blob != NULL);
4942 		blob = g_blob;
4943 
4944 		/* Just save the blobid as an xattr for testing purposes. */
4945 		rc = spdk_blob_set_xattr(blob, "blobid", &g_blobid, sizeof(g_blobid));
4946 		CU_ASSERT(rc == 0);
4947 
4948 		/* Resize the blob */
4949 		spdk_blob_resize(blob, i, blob_op_complete, NULL);
4950 		poll_threads();
4951 		CU_ASSERT(g_bserrno == 0);
4952 
4953 		spdk_blob_close(blob, blob_op_complete, NULL);
4954 		poll_threads();
4955 		CU_ASSERT(g_bserrno == 0);
4956 	}
4957 
4958 	g_bserrno = -1;
4959 	spdk_bs_unload(bs, bs_op_complete, NULL);
4960 	poll_threads();
4961 	CU_ASSERT(g_bserrno == 0);
4962 
4963 	dev = init_dev();
4964 	spdk_bs_opts_init(&opts);
4965 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
4966 	opts.iter_cb_fn = test_iter;
4967 	opts.iter_cb_arg = &iter_ctx;
4968 
4969 	/* Test blob iteration during load after a clean shutdown. */
4970 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
4971 	poll_threads();
4972 	CU_ASSERT(g_bserrno == 0);
4973 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
4974 	bs = g_bs;
4975 
4976 	/* Dirty shutdown */
4977 	_spdk_bs_free(bs);
4978 
4979 	dev = init_dev();
4980 	spdk_bs_opts_init(&opts);
4981 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
4982 	opts.iter_cb_fn = test_iter;
4983 	iter_ctx.current_iter = 0;
4984 	opts.iter_cb_arg = &iter_ctx;
4985 
4986 	/* Test blob iteration during load after a dirty shutdown. */
4987 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
4988 	poll_threads();
4989 	CU_ASSERT(g_bserrno == 0);
4990 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
4991 	bs = g_bs;
4992 
4993 	spdk_bs_unload(bs, bs_op_complete, NULL);
4994 	poll_threads();
4995 	CU_ASSERT(g_bserrno == 0);
4996 	g_bs = NULL;
4997 }
4998 
4999 static void
5000 blob_snapshot_rw(void)
5001 {
5002 	static const uint8_t zero[10 * 4096] = { 0 };
5003 	struct spdk_blob_store *bs;
5004 	struct spdk_bs_dev *dev;
5005 	struct spdk_blob *blob, *snapshot;
5006 	struct spdk_io_channel *channel;
5007 	struct spdk_blob_opts opts;
5008 	spdk_blob_id blobid, snapshotid;
5009 	uint64_t free_clusters;
5010 	uint64_t cluster_size;
5011 	uint64_t page_size;
5012 	uint8_t payload_read[10 * 4096];
5013 	uint8_t payload_write[10 * 4096];
5014 	uint64_t write_bytes;
5015 	uint64_t read_bytes;
5016 
5017 	dev = init_dev();
5018 
5019 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
5020 	poll_threads();
5021 	CU_ASSERT(g_bserrno == 0);
5022 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
5023 	bs = g_bs;
5024 	free_clusters = spdk_bs_free_cluster_count(bs);
5025 	cluster_size = spdk_bs_get_cluster_size(bs);
5026 	page_size = spdk_bs_get_page_size(bs);
5027 
5028 	channel = spdk_bs_alloc_io_channel(bs);
5029 	CU_ASSERT(channel != NULL);
5030 
5031 	ut_spdk_blob_opts_init(&opts);
5032 	opts.thin_provision = true;
5033 	opts.num_clusters = 5;
5034 
5035 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
5036 	poll_threads();
5037 	CU_ASSERT(g_bserrno == 0);
5038 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
5039 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
5040 	blobid = g_blobid;
5041 
5042 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
5043 	poll_threads();
5044 	CU_ASSERT(g_bserrno == 0);
5045 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
5046 	blob = g_blob;
5047 
5048 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5);
5049 
5050 	memset(payload_read, 0xFF, sizeof(payload_read));
5051 	spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL);
5052 	poll_threads();
5053 	CU_ASSERT(g_bserrno == 0);
5054 	CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0);
5055 
5056 	memset(payload_write, 0xE5, sizeof(payload_write));
5057 	spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL);
5058 	poll_threads();
5059 	CU_ASSERT(g_bserrno == 0);
5060 	CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs));
5061 
5062 	/* Create snapshot from blob */
5063 	spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL);
5064 	poll_threads();
5065 	CU_ASSERT(g_bserrno == 0);
5066 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
5067 	snapshotid = g_blobid;
5068 
5069 	spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL);
5070 	poll_threads();
5071 	CU_ASSERT(g_bserrno == 0);
5072 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
5073 	snapshot = g_blob;
5074 	CU_ASSERT(snapshot->data_ro == true);
5075 	CU_ASSERT(snapshot->md_ro == true);
5076 
5077 	CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 5);
5078 
5079 	write_bytes = g_dev_write_bytes;
5080 	read_bytes = g_dev_read_bytes;
5081 
5082 	memset(payload_write, 0xAA, sizeof(payload_write));
5083 	spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL);
5084 	poll_threads();
5085 	CU_ASSERT(g_bserrno == 0);
5086 	CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs));
5087 
5088 	/* For a clone we need to allocate and copy one cluster, update one page of metadata
5089 	 * and then write 10 pages of payload.
5090 	 */
5091 	if (g_use_extent_table) {
5092 		/* Add one more page for EXTENT_PAGE write */
5093 		CU_ASSERT(g_dev_write_bytes - write_bytes == page_size * 12 + cluster_size);
5094 	} else {
5095 		CU_ASSERT(g_dev_write_bytes - write_bytes == page_size * 11 + cluster_size);
5096 	}
5097 	CU_ASSERT(g_dev_read_bytes - read_bytes == cluster_size);
5098 
5099 	spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL);
5100 	poll_threads();
5101 	CU_ASSERT(g_bserrno == 0);
5102 	CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0);
5103 
5104 	/* Data on snapshot should not change after write to clone */
5105 	memset(payload_write, 0xE5, sizeof(payload_write));
5106 	spdk_blob_io_read(snapshot, channel, payload_read, 4, 10, blob_op_complete, NULL);
5107 	poll_threads();
5108 	CU_ASSERT(g_bserrno == 0);
5109 	CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0);
5110 
5111 	spdk_blob_close(blob, blob_op_complete, NULL);
5112 	poll_threads();
5113 	CU_ASSERT(g_bserrno == 0);
5114 
5115 	spdk_blob_close(snapshot, blob_op_complete, NULL);
5116 	poll_threads();
5117 	CU_ASSERT(g_bserrno == 0);
5118 
5119 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
5120 	poll_threads();
5121 	CU_ASSERT(g_bserrno == 0);
5122 
5123 	spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL);
5124 	poll_threads();
5125 	CU_ASSERT(g_bserrno == 0);
5126 
5127 	spdk_bs_free_io_channel(channel);
5128 	poll_threads();
5129 
5130 	/* Unload the blob store */
5131 	spdk_bs_unload(bs, bs_op_complete, NULL);
5132 	poll_threads();
5133 	CU_ASSERT(g_bserrno == 0);
5134 	g_bs = NULL;
5135 	g_blob = NULL;
5136 	g_blobid = 0;
5137 }
5138 
5139 static void
5140 blob_snapshot_rw_iov(void)
5141 {
5142 	static const uint8_t zero[10 * 4096] = { 0 };
5143 	struct spdk_blob_store *bs;
5144 	struct spdk_bs_dev *dev;
5145 	struct spdk_blob *blob, *snapshot;
5146 	struct spdk_io_channel *channel;
5147 	struct spdk_blob_opts opts;
5148 	spdk_blob_id blobid, snapshotid;
5149 	uint64_t free_clusters;
5150 	uint8_t payload_read[10 * 4096];
5151 	uint8_t payload_write[10 * 4096];
5152 	struct iovec iov_read[3];
5153 	struct iovec iov_write[3];
5154 
5155 	dev = init_dev();
5156 
5157 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
5158 	poll_threads();
5159 	CU_ASSERT(g_bserrno == 0);
5160 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
5161 	bs = g_bs;
5162 	free_clusters = spdk_bs_free_cluster_count(bs);
5163 
5164 	channel = spdk_bs_alloc_io_channel(bs);
5165 	CU_ASSERT(channel != NULL);
5166 
5167 	ut_spdk_blob_opts_init(&opts);
5168 	opts.thin_provision = true;
5169 	opts.num_clusters = 5;
5170 
5171 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
5172 	poll_threads();
5173 	CU_ASSERT(g_bserrno == 0);
5174 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
5175 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
5176 	blobid = g_blobid;
5177 
5178 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
5179 	poll_threads();
5180 	CU_ASSERT(g_bserrno == 0);
5181 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
5182 	blob = g_blob;
5183 
5184 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5);
5185 
5186 	/* Create snapshot from blob */
5187 	spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL);
5188 	poll_threads();
5189 	CU_ASSERT(g_bserrno == 0);
5190 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
5191 	snapshotid = g_blobid;
5192 
5193 	spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL);
5194 	poll_threads();
5195 	CU_ASSERT(g_bserrno == 0);
5196 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
5197 	snapshot = g_blob;
5198 	CU_ASSERT(snapshot->data_ro == true);
5199 	CU_ASSERT(snapshot->md_ro == true);
5200 	CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 5);
5201 
5202 	/* Payload should be all zeros from unallocated clusters */
5203 	memset(payload_read, 0xAA, sizeof(payload_read));
5204 	iov_read[0].iov_base = payload_read;
5205 	iov_read[0].iov_len = 3 * 4096;
5206 	iov_read[1].iov_base = payload_read + 3 * 4096;
5207 	iov_read[1].iov_len = 4 * 4096;
5208 	iov_read[2].iov_base = payload_read + 7 * 4096;
5209 	iov_read[2].iov_len = 3 * 4096;
5210 	spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL);
5211 	poll_threads();
5212 	CU_ASSERT(g_bserrno == 0);
5213 	CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0);
5214 
5215 	memset(payload_write, 0xE5, sizeof(payload_write));
5216 	iov_write[0].iov_base = payload_write;
5217 	iov_write[0].iov_len = 1 * 4096;
5218 	iov_write[1].iov_base = payload_write + 1 * 4096;
5219 	iov_write[1].iov_len = 5 * 4096;
5220 	iov_write[2].iov_base = payload_write + 6 * 4096;
5221 	iov_write[2].iov_len = 4 * 4096;
5222 
5223 	spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL);
5224 	poll_threads();
5225 	CU_ASSERT(g_bserrno == 0);
5226 
5227 	memset(payload_read, 0xAA, sizeof(payload_read));
5228 	iov_read[0].iov_base = payload_read;
5229 	iov_read[0].iov_len = 3 * 4096;
5230 	iov_read[1].iov_base = payload_read + 3 * 4096;
5231 	iov_read[1].iov_len = 4 * 4096;
5232 	iov_read[2].iov_base = payload_read + 7 * 4096;
5233 	iov_read[2].iov_len = 3 * 4096;
5234 	spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL);
5235 	poll_threads();
5236 	CU_ASSERT(g_bserrno == 0);
5237 	CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0);
5238 
5239 	spdk_blob_close(blob, blob_op_complete, NULL);
5240 	poll_threads();
5241 	CU_ASSERT(g_bserrno == 0);
5242 
5243 	spdk_blob_close(snapshot, blob_op_complete, NULL);
5244 	poll_threads();
5245 	CU_ASSERT(g_bserrno == 0);
5246 
5247 	spdk_bs_free_io_channel(channel);
5248 	poll_threads();
5249 
5250 	/* Unload the blob store */
5251 	spdk_bs_unload(bs, bs_op_complete, NULL);
5252 	poll_threads();
5253 	CU_ASSERT(g_bserrno == 0);
5254 	g_bs = NULL;
5255 	g_blob = NULL;
5256 	g_blobid = 0;
5257 }
5258 
5259 /**
5260  * Inflate / decouple parent rw unit tests.
5261  *
5262  * --------------
5263  * original blob:         0         1         2         3         4
5264  *                   ,---------+---------+---------+---------+---------.
5265  *         snapshot  |xxxxxxxxx|xxxxxxxxx|xxxxxxxxx|xxxxxxxxx|    -    |
5266  *                   +---------+---------+---------+---------+---------+
5267  *         snapshot2 |    -    |yyyyyyyyy|    -    |yyyyyyyyy|    -    |
5268  *                   +---------+---------+---------+---------+---------+
5269  *         blob      |    -    |zzzzzzzzz|    -    |    -    |    -    |
5270  *                   '---------+---------+---------+---------+---------'
5271  *                   .         .         .         .         .         .
5272  * --------          .         .         .         .         .         .
5273  * inflate:          .         .         .         .         .         .
5274  *                   ,---------+---------+---------+---------+---------.
5275  *         blob      |xxxxxxxxx|zzzzzzzzz|xxxxxxxxx|yyyyyyyyy|000000000|
5276  *                   '---------+---------+---------+---------+---------'
5277  *
5278  *         NOTE: needs to allocate 4 clusters, thin provisioning removed, dependency
5279  *               on snapshot2 and snapshot removed .         .         .
5280  *                   .         .         .         .         .         .
5281  * ----------------  .         .         .         .         .         .
5282  * decouple parent:  .         .         .         .         .         .
5283  *                   ,---------+---------+---------+---------+---------.
5284  *         snapshot  |xxxxxxxxx|xxxxxxxxx|xxxxxxxxx|xxxxxxxxx|    -    |
5285  *                   +---------+---------+---------+---------+---------+
5286  *         blob      |    -    |zzzzzzzzz|    -    |yyyyyyyyy|    -    |
5287  *                   '---------+---------+---------+---------+---------'
5288  *
5289  *         NOTE: needs to allocate 1 cluster, 3 clusters unallocated, dependency
5290  *               on snapshot2 removed and on snapshot still exists. Snapshot2
5291  *               should remain a clone of snapshot.
5292  */
5293 static void
5294 _blob_inflate_rw(bool decouple_parent)
5295 {
5296 	struct spdk_blob_store *bs;
5297 	struct spdk_bs_dev *dev;
5298 	struct spdk_blob *blob, *snapshot, *snapshot2;
5299 	struct spdk_io_channel *channel;
5300 	struct spdk_blob_opts opts;
5301 	spdk_blob_id blobid, snapshotid, snapshot2id;
5302 	uint64_t free_clusters;
5303 	uint64_t cluster_size;
5304 
5305 	uint64_t payload_size;
5306 	uint8_t *payload_read;
5307 	uint8_t *payload_write;
5308 	uint8_t *payload_clone;
5309 
5310 	uint64_t pages_per_cluster;
5311 	uint64_t pages_per_payload;
5312 
5313 	int i;
5314 	spdk_blob_id ids[2];
5315 	size_t count;
5316 
5317 	dev = init_dev();
5318 
5319 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
5320 	poll_threads();
5321 	CU_ASSERT(g_bserrno == 0);
5322 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
5323 	bs = g_bs;
5324 
5325 	free_clusters = spdk_bs_free_cluster_count(bs);
5326 	cluster_size = spdk_bs_get_cluster_size(bs);
5327 	pages_per_cluster = cluster_size / spdk_bs_get_page_size(bs);
5328 	pages_per_payload = pages_per_cluster * 5;
5329 
5330 	payload_size = cluster_size * 5;
5331 
5332 	payload_read = malloc(payload_size);
5333 	SPDK_CU_ASSERT_FATAL(payload_read != NULL);
5334 
5335 	payload_write = malloc(payload_size);
5336 	SPDK_CU_ASSERT_FATAL(payload_write != NULL);
5337 
5338 	payload_clone = malloc(payload_size);
5339 	SPDK_CU_ASSERT_FATAL(payload_clone != NULL);
5340 
5341 	channel = spdk_bs_alloc_io_channel(bs);
5342 	SPDK_CU_ASSERT_FATAL(channel != NULL);
5343 
5344 	/* Create blob */
5345 	ut_spdk_blob_opts_init(&opts);
5346 	opts.thin_provision = true;
5347 	opts.num_clusters = 5;
5348 
5349 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
5350 	poll_threads();
5351 	CU_ASSERT(g_bserrno == 0);
5352 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
5353 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
5354 	blobid = g_blobid;
5355 
5356 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
5357 	poll_threads();
5358 	CU_ASSERT(g_bserrno == 0);
5359 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
5360 	blob = g_blob;
5361 
5362 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5);
5363 
5364 	/* 1) Initial read should return zeroed payload */
5365 	memset(payload_read, 0xFF, payload_size);
5366 	spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload,
5367 			  blob_op_complete, NULL);
5368 	poll_threads();
5369 	CU_ASSERT(g_bserrno == 0);
5370 	CU_ASSERT(spdk_mem_all_zero(payload_read, payload_size));
5371 
5372 	/* Fill whole blob with a pattern, except last cluster (to be sure it
5373 	 * isn't allocated) */
5374 	memset(payload_write, 0xE5, payload_size - cluster_size);
5375 	spdk_blob_io_write(blob, channel, payload_write, 0, pages_per_payload -
5376 			   pages_per_cluster, blob_op_complete, NULL);
5377 	poll_threads();
5378 	CU_ASSERT(g_bserrno == 0);
5379 	CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs));
5380 
5381 	/* 2) Create snapshot from blob (first level) */
5382 	spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL);
5383 	poll_threads();
5384 	CU_ASSERT(g_bserrno == 0);
5385 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
5386 	snapshotid = g_blobid;
5387 
5388 	spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL);
5389 	poll_threads();
5390 	CU_ASSERT(g_bserrno == 0);
5391 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
5392 	snapshot = g_blob;
5393 	CU_ASSERT(snapshot->data_ro == true);
5394 	CU_ASSERT(snapshot->md_ro == true);
5395 
5396 	CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 5);
5397 
5398 	/* Write every second cluster with a pattern.
5399 	 *
5400 	 * Last cluster shouldn't be written, to be sure that snapshot nor clone
5401 	 * doesn't allocate it.
5402 	 *
5403 	 * payload_clone stores expected result on "blob" read at the time and
5404 	 * is used only to check data consistency on clone before and after
5405 	 * inflation. Initially we fill it with a backing snapshots pattern
5406 	 * used before.
5407 	 */
5408 	memset(payload_clone, 0xE5, payload_size - cluster_size);
5409 	memset(payload_clone + payload_size - cluster_size, 0x00, cluster_size);
5410 	memset(payload_write, 0xAA, payload_size);
5411 	for (i = 1; i < 5; i += 2) {
5412 		spdk_blob_io_write(blob, channel, payload_write, i * pages_per_cluster,
5413 				   pages_per_cluster, blob_op_complete, NULL);
5414 		poll_threads();
5415 		CU_ASSERT(g_bserrno == 0);
5416 
5417 		/* Update expected result */
5418 		memcpy(payload_clone + (cluster_size * i), payload_write,
5419 		       cluster_size);
5420 	}
5421 	CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs));
5422 
5423 	/* Check data consistency on clone */
5424 	memset(payload_read, 0xFF, payload_size);
5425 	spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload,
5426 			  blob_op_complete, NULL);
5427 	poll_threads();
5428 	CU_ASSERT(g_bserrno == 0);
5429 	CU_ASSERT(memcmp(payload_clone, payload_read, payload_size) == 0);
5430 
5431 	/* 3) Create second levels snapshot from blob */
5432 	spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL);
5433 	poll_threads();
5434 	CU_ASSERT(g_bserrno == 0);
5435 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
5436 	snapshot2id = g_blobid;
5437 
5438 	spdk_bs_open_blob(bs, snapshot2id, blob_op_with_handle_complete, NULL);
5439 	poll_threads();
5440 	CU_ASSERT(g_bserrno == 0);
5441 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
5442 	snapshot2 = g_blob;
5443 	CU_ASSERT(snapshot2->data_ro == true);
5444 	CU_ASSERT(snapshot2->md_ro == true);
5445 
5446 	CU_ASSERT(spdk_blob_get_num_clusters(snapshot2) == 5);
5447 
5448 	CU_ASSERT(snapshot2->parent_id == snapshotid);
5449 
5450 	/* Write one cluster on the top level blob. This cluster (1) covers
5451 	 * already allocated cluster in the snapshot2, so shouldn't be inflated
5452 	 * at all */
5453 	spdk_blob_io_write(blob, channel, payload_write, pages_per_cluster,
5454 			   pages_per_cluster, blob_op_complete, NULL);
5455 	poll_threads();
5456 	CU_ASSERT(g_bserrno == 0);
5457 
5458 	/* Update expected result */
5459 	memcpy(payload_clone + cluster_size, payload_write, cluster_size);
5460 
5461 	/* Check data consistency on clone */
5462 	memset(payload_read, 0xFF, payload_size);
5463 	spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload,
5464 			  blob_op_complete, NULL);
5465 	poll_threads();
5466 	CU_ASSERT(g_bserrno == 0);
5467 	CU_ASSERT(memcmp(payload_clone, payload_read, payload_size) == 0);
5468 
5469 
5470 	/* Close all blobs */
5471 	spdk_blob_close(blob, blob_op_complete, NULL);
5472 	poll_threads();
5473 	CU_ASSERT(g_bserrno == 0);
5474 
5475 	spdk_blob_close(snapshot2, blob_op_complete, NULL);
5476 	poll_threads();
5477 	CU_ASSERT(g_bserrno == 0);
5478 
5479 	spdk_blob_close(snapshot, blob_op_complete, NULL);
5480 	poll_threads();
5481 	CU_ASSERT(g_bserrno == 0);
5482 
5483 	/* Check snapshot-clone relations */
5484 	count = 2;
5485 	CU_ASSERT(spdk_blob_get_clones(bs, snapshotid, ids, &count) == 0);
5486 	CU_ASSERT(count == 1);
5487 	CU_ASSERT(ids[0] == snapshot2id);
5488 
5489 	count = 2;
5490 	CU_ASSERT(spdk_blob_get_clones(bs, snapshot2id, ids, &count) == 0);
5491 	CU_ASSERT(count == 1);
5492 	CU_ASSERT(ids[0] == blobid);
5493 
5494 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshot2id);
5495 
5496 	free_clusters = spdk_bs_free_cluster_count(bs);
5497 	if (!decouple_parent) {
5498 		/* Do full blob inflation */
5499 		spdk_bs_inflate_blob(bs, channel, blobid, blob_op_complete, NULL);
5500 		poll_threads();
5501 		CU_ASSERT(g_bserrno == 0);
5502 
5503 		/* All clusters should be inflated (except one already allocated
5504 		 * in a top level blob) */
5505 		CU_ASSERT(spdk_bs_free_cluster_count(bs) == free_clusters - 4);
5506 
5507 		/* Check if relation tree updated correctly */
5508 		count = 2;
5509 		CU_ASSERT(spdk_blob_get_clones(bs, snapshotid, ids, &count) == 0);
5510 
5511 		/* snapshotid have one clone */
5512 		CU_ASSERT(count == 1);
5513 		CU_ASSERT(ids[0] == snapshot2id);
5514 
5515 		/* snapshot2id have no clones */
5516 		count = 2;
5517 		CU_ASSERT(spdk_blob_get_clones(bs, snapshot2id, ids, &count) == 0);
5518 		CU_ASSERT(count == 0);
5519 
5520 		CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == SPDK_BLOBID_INVALID);
5521 	} else {
5522 		/* Decouple parent of blob */
5523 		spdk_bs_blob_decouple_parent(bs, channel, blobid, blob_op_complete, NULL);
5524 		poll_threads();
5525 		CU_ASSERT(g_bserrno == 0);
5526 
5527 		/* Only one cluster from a parent should be inflated (second one
5528 		 * is covered by a cluster written on a top level blob, and
5529 		 * already allocated) */
5530 		CU_ASSERT(spdk_bs_free_cluster_count(bs) == free_clusters - 1);
5531 
5532 		/* Check if relation tree updated correctly */
5533 		count = 2;
5534 		CU_ASSERT(spdk_blob_get_clones(bs, snapshotid, ids, &count) == 0);
5535 
5536 		/* snapshotid have two clones now */
5537 		CU_ASSERT(count == 2);
5538 		CU_ASSERT(ids[0] == blobid || ids[1] == blobid);
5539 		CU_ASSERT(ids[0] == snapshot2id || ids[1] == snapshot2id);
5540 
5541 		/* snapshot2id have no clones */
5542 		count = 2;
5543 		CU_ASSERT(spdk_blob_get_clones(bs, snapshot2id, ids, &count) == 0);
5544 		CU_ASSERT(count == 0);
5545 
5546 		CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid);
5547 	}
5548 
5549 	/* Try to delete snapshot2 (should pass) */
5550 	spdk_bs_delete_blob(bs, snapshot2id, blob_op_complete, NULL);
5551 	poll_threads();
5552 	CU_ASSERT(g_bserrno == 0);
5553 
5554 	/* Try to delete base snapshot */
5555 	spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL);
5556 	poll_threads();
5557 	CU_ASSERT(g_bserrno == 0);
5558 
5559 	/* Reopen blob after snapshot deletion */
5560 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
5561 	poll_threads();
5562 	CU_ASSERT(g_bserrno == 0);
5563 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
5564 	blob = g_blob;
5565 
5566 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5);
5567 
5568 	/* Check data consistency on inflated blob */
5569 	memset(payload_read, 0xFF, payload_size);
5570 	spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload,
5571 			  blob_op_complete, NULL);
5572 	poll_threads();
5573 	CU_ASSERT(g_bserrno == 0);
5574 	CU_ASSERT(memcmp(payload_clone, payload_read, payload_size) == 0);
5575 
5576 	spdk_blob_close(blob, blob_op_complete, NULL);
5577 	poll_threads();
5578 	CU_ASSERT(g_bserrno == 0);
5579 
5580 	spdk_bs_free_io_channel(channel);
5581 	poll_threads();
5582 
5583 	/* Unload the blob store */
5584 	spdk_bs_unload(bs, bs_op_complete, NULL);
5585 	poll_threads();
5586 	CU_ASSERT(g_bserrno == 0);
5587 	g_bs = NULL;
5588 	g_blob = NULL;
5589 	g_blobid = 0;
5590 
5591 	free(payload_read);
5592 	free(payload_write);
5593 	free(payload_clone);
5594 }
5595 
5596 static void
5597 blob_inflate_rw(void)
5598 {
5599 	_blob_inflate_rw(false);
5600 	_blob_inflate_rw(true);
5601 }
5602 
5603 /**
5604  * Snapshot-clones relation test
5605  *
5606  *         snapshot
5607  *            |
5608  *      +-----+-----+
5609  *      |           |
5610  *   blob(ro)   snapshot2
5611  *      |           |
5612  *   clone2      clone
5613  */
5614 static void
5615 blob_relations(void)
5616 {
5617 	struct spdk_blob_store *bs;
5618 	struct spdk_bs_dev *dev;
5619 	struct spdk_bs_opts bs_opts;
5620 	struct spdk_blob_opts opts;
5621 	struct spdk_blob *blob, *snapshot, *snapshot2, *clone, *clone2;
5622 	spdk_blob_id blobid, cloneid, snapshotid, cloneid2, snapshotid2;
5623 	int rc;
5624 	size_t count;
5625 	spdk_blob_id ids[10] = {};
5626 
5627 	dev = init_dev();
5628 	spdk_bs_opts_init(&bs_opts);
5629 	snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE");
5630 
5631 	spdk_bs_init(dev, &bs_opts, bs_op_with_handle_complete, NULL);
5632 	poll_threads();
5633 	CU_ASSERT(g_bserrno == 0);
5634 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
5635 	bs = g_bs;
5636 
5637 	/* 1. Create blob with 10 clusters */
5638 
5639 	ut_spdk_blob_opts_init(&opts);
5640 	opts.num_clusters = 10;
5641 
5642 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
5643 	poll_threads();
5644 	CU_ASSERT(g_bserrno == 0);
5645 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
5646 	blobid = g_blobid;
5647 
5648 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
5649 	poll_threads();
5650 	CU_ASSERT(g_bserrno == 0);
5651 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
5652 	blob = g_blob;
5653 
5654 	CU_ASSERT(!spdk_blob_is_read_only(blob));
5655 	CU_ASSERT(!spdk_blob_is_snapshot(blob));
5656 	CU_ASSERT(!spdk_blob_is_clone(blob));
5657 	CU_ASSERT(!spdk_blob_is_thin_provisioned(blob));
5658 
5659 	/* blob should not have underlying snapshot nor clones */
5660 	CU_ASSERT(blob->parent_id == SPDK_BLOBID_INVALID);
5661 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == SPDK_BLOBID_INVALID);
5662 	count = SPDK_COUNTOF(ids);
5663 	rc = spdk_blob_get_clones(bs, blobid, ids, &count);
5664 	CU_ASSERT(rc == 0);
5665 	CU_ASSERT(count == 0);
5666 
5667 
5668 	/* 2. Create snapshot */
5669 
5670 	spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL);
5671 	poll_threads();
5672 	CU_ASSERT(g_bserrno == 0);
5673 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
5674 	snapshotid = g_blobid;
5675 
5676 	spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL);
5677 	poll_threads();
5678 	CU_ASSERT(g_bserrno == 0);
5679 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
5680 	snapshot = g_blob;
5681 
5682 	CU_ASSERT(spdk_blob_is_read_only(snapshot));
5683 	CU_ASSERT(spdk_blob_is_snapshot(snapshot));
5684 	CU_ASSERT(!spdk_blob_is_clone(snapshot));
5685 	CU_ASSERT(snapshot->parent_id == SPDK_BLOBID_INVALID);
5686 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid) == SPDK_BLOBID_INVALID);
5687 
5688 	/* Check if original blob is converted to the clone of snapshot */
5689 	CU_ASSERT(!spdk_blob_is_read_only(blob));
5690 	CU_ASSERT(!spdk_blob_is_snapshot(blob));
5691 	CU_ASSERT(spdk_blob_is_clone(blob));
5692 	CU_ASSERT(spdk_blob_is_thin_provisioned(blob));
5693 	CU_ASSERT(blob->parent_id == snapshotid);
5694 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid);
5695 
5696 	count = SPDK_COUNTOF(ids);
5697 	rc = spdk_blob_get_clones(bs, snapshotid, ids, &count);
5698 	CU_ASSERT(rc == 0);
5699 	CU_ASSERT(count == 1);
5700 	CU_ASSERT(ids[0] == blobid);
5701 
5702 
5703 	/* 3. Create clone from snapshot */
5704 
5705 	spdk_bs_create_clone(bs, snapshotid, NULL, blob_op_with_id_complete, NULL);
5706 	poll_threads();
5707 	CU_ASSERT(g_bserrno == 0);
5708 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
5709 	cloneid = g_blobid;
5710 
5711 	spdk_bs_open_blob(bs, cloneid, blob_op_with_handle_complete, NULL);
5712 	poll_threads();
5713 	CU_ASSERT(g_bserrno == 0);
5714 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
5715 	clone = g_blob;
5716 
5717 	CU_ASSERT(!spdk_blob_is_read_only(clone));
5718 	CU_ASSERT(!spdk_blob_is_snapshot(clone));
5719 	CU_ASSERT(spdk_blob_is_clone(clone));
5720 	CU_ASSERT(spdk_blob_is_thin_provisioned(clone));
5721 	CU_ASSERT(clone->parent_id == snapshotid);
5722 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid);
5723 
5724 	count = SPDK_COUNTOF(ids);
5725 	rc = spdk_blob_get_clones(bs, cloneid, ids, &count);
5726 	CU_ASSERT(rc == 0);
5727 	CU_ASSERT(count == 0);
5728 
5729 	/* Check if clone is on the snapshot's list */
5730 	count = SPDK_COUNTOF(ids);
5731 	rc = spdk_blob_get_clones(bs, snapshotid, ids, &count);
5732 	CU_ASSERT(rc == 0);
5733 	CU_ASSERT(ids[0] == blobid || ids[1] == blobid);
5734 	CU_ASSERT(ids[0] == cloneid || ids[1] == cloneid);
5735 
5736 
5737 	/* 4. Create snapshot of the clone */
5738 
5739 	spdk_bs_create_snapshot(bs, cloneid, NULL, blob_op_with_id_complete, NULL);
5740 	poll_threads();
5741 	CU_ASSERT(g_bserrno == 0);
5742 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
5743 	snapshotid2 = g_blobid;
5744 
5745 	spdk_bs_open_blob(bs, snapshotid2, blob_op_with_handle_complete, NULL);
5746 	poll_threads();
5747 	CU_ASSERT(g_bserrno == 0);
5748 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
5749 	snapshot2 = g_blob;
5750 
5751 	CU_ASSERT(spdk_blob_is_read_only(snapshot2));
5752 	CU_ASSERT(spdk_blob_is_snapshot(snapshot2));
5753 	CU_ASSERT(spdk_blob_is_clone(snapshot2));
5754 	CU_ASSERT(snapshot2->parent_id == snapshotid);
5755 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid2) == snapshotid);
5756 
5757 	/* Check if clone is converted to the clone of snapshot2 and snapshot2
5758 	 * is a child of snapshot */
5759 	CU_ASSERT(!spdk_blob_is_read_only(clone));
5760 	CU_ASSERT(!spdk_blob_is_snapshot(clone));
5761 	CU_ASSERT(spdk_blob_is_clone(clone));
5762 	CU_ASSERT(spdk_blob_is_thin_provisioned(clone));
5763 	CU_ASSERT(clone->parent_id == snapshotid2);
5764 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid2);
5765 
5766 	count = SPDK_COUNTOF(ids);
5767 	rc = spdk_blob_get_clones(bs, snapshotid2, ids, &count);
5768 	CU_ASSERT(rc == 0);
5769 	CU_ASSERT(count == 1);
5770 	CU_ASSERT(ids[0] == cloneid);
5771 
5772 
5773 	/* 5. Try to create clone from read only blob */
5774 
5775 	/* Mark blob as read only */
5776 	spdk_blob_set_read_only(blob);
5777 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
5778 	poll_threads();
5779 	CU_ASSERT(g_bserrno == 0);
5780 
5781 	/* Check if previously created blob is read only clone */
5782 	CU_ASSERT(spdk_blob_is_read_only(blob));
5783 	CU_ASSERT(!spdk_blob_is_snapshot(blob));
5784 	CU_ASSERT(spdk_blob_is_clone(blob));
5785 	CU_ASSERT(spdk_blob_is_thin_provisioned(blob));
5786 
5787 	/* Create clone from read only blob */
5788 	spdk_bs_create_clone(bs, blobid, NULL, blob_op_with_id_complete, NULL);
5789 	poll_threads();
5790 	CU_ASSERT(g_bserrno == 0);
5791 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
5792 	cloneid2 = g_blobid;
5793 
5794 	spdk_bs_open_blob(bs, cloneid2, blob_op_with_handle_complete, NULL);
5795 	poll_threads();
5796 	CU_ASSERT(g_bserrno == 0);
5797 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
5798 	clone2 = g_blob;
5799 
5800 	CU_ASSERT(!spdk_blob_is_read_only(clone2));
5801 	CU_ASSERT(!spdk_blob_is_snapshot(clone2));
5802 	CU_ASSERT(spdk_blob_is_clone(clone2));
5803 	CU_ASSERT(spdk_blob_is_thin_provisioned(clone2));
5804 
5805 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid2) == blobid);
5806 
5807 	count = SPDK_COUNTOF(ids);
5808 	rc = spdk_blob_get_clones(bs, blobid, ids, &count);
5809 	CU_ASSERT(rc == 0);
5810 
5811 	CU_ASSERT(count == 1);
5812 	CU_ASSERT(ids[0] == cloneid2);
5813 
5814 	/* Close blobs */
5815 
5816 	spdk_blob_close(clone2, blob_op_complete, NULL);
5817 	poll_threads();
5818 	CU_ASSERT(g_bserrno == 0);
5819 
5820 	spdk_blob_close(blob, blob_op_complete, NULL);
5821 	poll_threads();
5822 	CU_ASSERT(g_bserrno == 0);
5823 
5824 	spdk_blob_close(clone, blob_op_complete, NULL);
5825 	poll_threads();
5826 	CU_ASSERT(g_bserrno == 0);
5827 
5828 	spdk_blob_close(snapshot, blob_op_complete, NULL);
5829 	poll_threads();
5830 	CU_ASSERT(g_bserrno == 0);
5831 
5832 	spdk_blob_close(snapshot2, blob_op_complete, NULL);
5833 	poll_threads();
5834 	CU_ASSERT(g_bserrno == 0);
5835 
5836 	/* Try to delete snapshot with more than 1 clone */
5837 	spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL);
5838 	poll_threads();
5839 	CU_ASSERT(g_bserrno != 0);
5840 
5841 	ut_bs_reload(&bs, &bs_opts);
5842 
5843 	/* NULL ids array should return number of clones in count */
5844 	count = SPDK_COUNTOF(ids);
5845 	rc = spdk_blob_get_clones(bs, snapshotid, NULL, &count);
5846 	CU_ASSERT(rc == -ENOMEM);
5847 	CU_ASSERT(count == 2);
5848 
5849 	/* incorrect array size */
5850 	count = 1;
5851 	rc = spdk_blob_get_clones(bs, snapshotid, ids, &count);
5852 	CU_ASSERT(rc == -ENOMEM);
5853 	CU_ASSERT(count == 2);
5854 
5855 
5856 	/* Verify structure of loaded blob store */
5857 
5858 	/* snapshot */
5859 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid) == SPDK_BLOBID_INVALID);
5860 
5861 	count = SPDK_COUNTOF(ids);
5862 	rc = spdk_blob_get_clones(bs, snapshotid, ids, &count);
5863 	CU_ASSERT(rc == 0);
5864 	CU_ASSERT(count == 2);
5865 	CU_ASSERT(ids[0] == blobid || ids[1] == blobid);
5866 	CU_ASSERT(ids[0] == snapshotid2 || ids[1] == snapshotid2);
5867 
5868 	/* blob */
5869 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid);
5870 	count = SPDK_COUNTOF(ids);
5871 	rc = spdk_blob_get_clones(bs, blobid, ids, &count);
5872 	CU_ASSERT(rc == 0);
5873 	CU_ASSERT(count == 1);
5874 	CU_ASSERT(ids[0] == cloneid2);
5875 
5876 	/* clone */
5877 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid2);
5878 	count = SPDK_COUNTOF(ids);
5879 	rc = spdk_blob_get_clones(bs, cloneid, ids, &count);
5880 	CU_ASSERT(rc == 0);
5881 	CU_ASSERT(count == 0);
5882 
5883 	/* snapshot2 */
5884 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid2) == snapshotid);
5885 	count = SPDK_COUNTOF(ids);
5886 	rc = spdk_blob_get_clones(bs, snapshotid2, ids, &count);
5887 	CU_ASSERT(rc == 0);
5888 	CU_ASSERT(count == 1);
5889 	CU_ASSERT(ids[0] == cloneid);
5890 
5891 	/* clone2 */
5892 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid2) == blobid);
5893 	count = SPDK_COUNTOF(ids);
5894 	rc = spdk_blob_get_clones(bs, cloneid2, ids, &count);
5895 	CU_ASSERT(rc == 0);
5896 	CU_ASSERT(count == 0);
5897 
5898 	/* Try to delete blob that user should not be able to remove */
5899 
5900 	spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL);
5901 	poll_threads();
5902 	CU_ASSERT(g_bserrno != 0);
5903 
5904 	/* Remove all blobs */
5905 
5906 	spdk_bs_delete_blob(bs, cloneid, blob_op_complete, NULL);
5907 	poll_threads();
5908 	CU_ASSERT(g_bserrno == 0);
5909 
5910 	spdk_bs_delete_blob(bs, snapshotid2, blob_op_complete, NULL);
5911 	poll_threads();
5912 	CU_ASSERT(g_bserrno == 0);
5913 
5914 	spdk_bs_delete_blob(bs, cloneid2, blob_op_complete, NULL);
5915 	poll_threads();
5916 	CU_ASSERT(g_bserrno == 0);
5917 
5918 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
5919 	poll_threads();
5920 	CU_ASSERT(g_bserrno == 0);
5921 
5922 	spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL);
5923 	poll_threads();
5924 	CU_ASSERT(g_bserrno == 0);
5925 
5926 	spdk_bs_unload(bs, bs_op_complete, NULL);
5927 	poll_threads();
5928 	CU_ASSERT(g_bserrno == 0);
5929 
5930 	g_bs = NULL;
5931 }
5932 
5933 /**
5934  * Snapshot-clones relation test 2
5935  *
5936  *         snapshot1
5937  *            |
5938  *         snapshot2
5939  *            |
5940  *      +-----+-----+
5941  *      |           |
5942  *   blob(ro)   snapshot3
5943  *      |           |
5944  *      |       snapshot4
5945  *      |        |     |
5946  *   clone2   clone  clone3
5947  */
5948 static void
5949 blob_relations2(void)
5950 {
5951 	struct spdk_blob_store *bs;
5952 	struct spdk_bs_dev *dev;
5953 	struct spdk_bs_opts bs_opts;
5954 	struct spdk_blob_opts opts;
5955 	struct spdk_blob *blob, *snapshot1, *snapshot2, *snapshot3, *snapshot4, *clone, *clone2;
5956 	spdk_blob_id blobid, snapshotid1, snapshotid2, snapshotid3, snapshotid4, cloneid, cloneid2,
5957 		     cloneid3;
5958 	int rc;
5959 	size_t count;
5960 	spdk_blob_id ids[10] = {};
5961 
5962 	dev = init_dev();
5963 	spdk_bs_opts_init(&bs_opts);
5964 	snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE");
5965 
5966 	spdk_bs_init(dev, &bs_opts, bs_op_with_handle_complete, NULL);
5967 	poll_threads();
5968 	CU_ASSERT(g_bserrno == 0);
5969 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
5970 	bs = g_bs;
5971 
5972 	/* 1. Create blob with 10 clusters */
5973 
5974 	ut_spdk_blob_opts_init(&opts);
5975 	opts.num_clusters = 10;
5976 
5977 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
5978 	poll_threads();
5979 	CU_ASSERT(g_bserrno == 0);
5980 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
5981 	blobid = g_blobid;
5982 
5983 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
5984 	poll_threads();
5985 	CU_ASSERT(g_bserrno == 0);
5986 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
5987 	blob = g_blob;
5988 
5989 	/* 2. Create snapshot1 */
5990 
5991 	spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL);
5992 	poll_threads();
5993 	CU_ASSERT(g_bserrno == 0);
5994 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
5995 	snapshotid1 = g_blobid;
5996 
5997 	spdk_bs_open_blob(bs, snapshotid1, blob_op_with_handle_complete, NULL);
5998 	poll_threads();
5999 	CU_ASSERT(g_bserrno == 0);
6000 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
6001 	snapshot1 = g_blob;
6002 
6003 	CU_ASSERT(snapshot1->parent_id == SPDK_BLOBID_INVALID);
6004 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid1) == SPDK_BLOBID_INVALID);
6005 
6006 	CU_ASSERT(blob->parent_id == snapshotid1);
6007 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid1);
6008 
6009 	/* Check if blob is the clone of snapshot1 */
6010 	CU_ASSERT(blob->parent_id == snapshotid1);
6011 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid1);
6012 
6013 	count = SPDK_COUNTOF(ids);
6014 	rc = spdk_blob_get_clones(bs, snapshotid1, ids, &count);
6015 	CU_ASSERT(rc == 0);
6016 	CU_ASSERT(count == 1);
6017 	CU_ASSERT(ids[0] == blobid);
6018 
6019 	/* 3. Create another snapshot */
6020 
6021 	spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL);
6022 	poll_threads();
6023 	CU_ASSERT(g_bserrno == 0);
6024 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
6025 	snapshotid2 = g_blobid;
6026 
6027 	spdk_bs_open_blob(bs, snapshotid2, blob_op_with_handle_complete, NULL);
6028 	poll_threads();
6029 	CU_ASSERT(g_bserrno == 0);
6030 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
6031 	snapshot2 = g_blob;
6032 
6033 	CU_ASSERT(spdk_blob_is_clone(snapshot2));
6034 	CU_ASSERT(snapshot2->parent_id == snapshotid1);
6035 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid2) == snapshotid1);
6036 
6037 	/* Check if snapshot2 is the clone of snapshot1 and blob
6038 	 * is a child of snapshot2 */
6039 	CU_ASSERT(blob->parent_id == snapshotid2);
6040 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid2);
6041 
6042 	count = SPDK_COUNTOF(ids);
6043 	rc = spdk_blob_get_clones(bs, snapshotid2, ids, &count);
6044 	CU_ASSERT(rc == 0);
6045 	CU_ASSERT(count == 1);
6046 	CU_ASSERT(ids[0] == blobid);
6047 
6048 	/* 4. Create clone from snapshot */
6049 
6050 	spdk_bs_create_clone(bs, snapshotid2, NULL, blob_op_with_id_complete, NULL);
6051 	poll_threads();
6052 	CU_ASSERT(g_bserrno == 0);
6053 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
6054 	cloneid = g_blobid;
6055 
6056 	spdk_bs_open_blob(bs, cloneid, blob_op_with_handle_complete, NULL);
6057 	poll_threads();
6058 	CU_ASSERT(g_bserrno == 0);
6059 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
6060 	clone = g_blob;
6061 
6062 	CU_ASSERT(clone->parent_id == snapshotid2);
6063 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid2);
6064 
6065 	/* Check if clone is on the snapshot's list */
6066 	count = SPDK_COUNTOF(ids);
6067 	rc = spdk_blob_get_clones(bs, snapshotid2, ids, &count);
6068 	CU_ASSERT(rc == 0);
6069 	CU_ASSERT(count == 2);
6070 	CU_ASSERT(ids[0] == blobid || ids[1] == blobid);
6071 	CU_ASSERT(ids[0] == cloneid || ids[1] == cloneid);
6072 
6073 	/* 5. Create snapshot of the clone */
6074 
6075 	spdk_bs_create_snapshot(bs, cloneid, NULL, blob_op_with_id_complete, NULL);
6076 	poll_threads();
6077 	CU_ASSERT(g_bserrno == 0);
6078 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
6079 	snapshotid3 = g_blobid;
6080 
6081 	spdk_bs_open_blob(bs, snapshotid3, blob_op_with_handle_complete, NULL);
6082 	poll_threads();
6083 	CU_ASSERT(g_bserrno == 0);
6084 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
6085 	snapshot3 = g_blob;
6086 
6087 	CU_ASSERT(snapshot3->parent_id == snapshotid2);
6088 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid3) == snapshotid2);
6089 
6090 	/* Check if clone is converted to the clone of snapshot3 and snapshot3
6091 	 * is a child of snapshot2 */
6092 	CU_ASSERT(clone->parent_id == snapshotid3);
6093 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid3);
6094 
6095 	count = SPDK_COUNTOF(ids);
6096 	rc = spdk_blob_get_clones(bs, snapshotid3, ids, &count);
6097 	CU_ASSERT(rc == 0);
6098 	CU_ASSERT(count == 1);
6099 	CU_ASSERT(ids[0] == cloneid);
6100 
6101 	/* 6. Create another snapshot of the clone */
6102 
6103 	spdk_bs_create_snapshot(bs, cloneid, NULL, blob_op_with_id_complete, NULL);
6104 	poll_threads();
6105 	CU_ASSERT(g_bserrno == 0);
6106 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
6107 	snapshotid4 = g_blobid;
6108 
6109 	spdk_bs_open_blob(bs, snapshotid4, blob_op_with_handle_complete, NULL);
6110 	poll_threads();
6111 	CU_ASSERT(g_bserrno == 0);
6112 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
6113 	snapshot4 = g_blob;
6114 
6115 	CU_ASSERT(snapshot4->parent_id == snapshotid3);
6116 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid4) == snapshotid3);
6117 
6118 	/* Check if clone is converted to the clone of snapshot4 and snapshot4
6119 	 * is a child of snapshot3 */
6120 	CU_ASSERT(clone->parent_id == snapshotid4);
6121 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid4);
6122 
6123 	count = SPDK_COUNTOF(ids);
6124 	rc = spdk_blob_get_clones(bs, snapshotid4, ids, &count);
6125 	CU_ASSERT(rc == 0);
6126 	CU_ASSERT(count == 1);
6127 	CU_ASSERT(ids[0] == cloneid);
6128 
6129 	/* 7. Remove snapshot 4 */
6130 
6131 	spdk_blob_close(snapshot4, blob_op_complete, NULL);
6132 	poll_threads();
6133 	CU_ASSERT(g_bserrno == 0);
6134 
6135 	spdk_bs_delete_blob(bs, snapshotid4, blob_op_complete, NULL);
6136 	poll_threads();
6137 	CU_ASSERT(g_bserrno == 0);
6138 
6139 	/* Check if relations are back to state from before creating snapshot 4 */
6140 	CU_ASSERT(clone->parent_id == snapshotid3);
6141 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid3);
6142 
6143 	count = SPDK_COUNTOF(ids);
6144 	rc = spdk_blob_get_clones(bs, snapshotid3, ids, &count);
6145 	CU_ASSERT(rc == 0);
6146 	CU_ASSERT(count == 1);
6147 	CU_ASSERT(ids[0] == cloneid);
6148 
6149 	/* 8. Create second clone of snapshot 3 and try to remove snapshot 3 */
6150 
6151 	spdk_bs_create_clone(bs, snapshotid3, NULL, blob_op_with_id_complete, NULL);
6152 	poll_threads();
6153 	CU_ASSERT(g_bserrno == 0);
6154 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
6155 	cloneid3 = g_blobid;
6156 
6157 	spdk_bs_delete_blob(bs, snapshotid3, blob_op_complete, NULL);
6158 	poll_threads();
6159 	CU_ASSERT(g_bserrno != 0);
6160 
6161 	/* 9. Open snapshot 3 again and try to remove it while clone 3 is closed */
6162 
6163 	spdk_bs_open_blob(bs, snapshotid3, blob_op_with_handle_complete, NULL);
6164 	poll_threads();
6165 	CU_ASSERT(g_bserrno == 0);
6166 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
6167 	snapshot3 = g_blob;
6168 
6169 	spdk_bs_delete_blob(bs, snapshotid3, blob_op_complete, NULL);
6170 	poll_threads();
6171 	CU_ASSERT(g_bserrno != 0);
6172 
6173 	spdk_blob_close(snapshot3, blob_op_complete, NULL);
6174 	poll_threads();
6175 	CU_ASSERT(g_bserrno == 0);
6176 
6177 	spdk_bs_delete_blob(bs, cloneid3, blob_op_complete, NULL);
6178 	poll_threads();
6179 	CU_ASSERT(g_bserrno == 0);
6180 
6181 	/* 10. Remove snapshot 1 */
6182 
6183 	spdk_blob_close(snapshot1, blob_op_complete, NULL);
6184 	poll_threads();
6185 	CU_ASSERT(g_bserrno == 0);
6186 
6187 	spdk_bs_delete_blob(bs, snapshotid1, blob_op_complete, NULL);
6188 	poll_threads();
6189 	CU_ASSERT(g_bserrno == 0);
6190 
6191 	/* Check if relations are back to state from before creating snapshot 4 (before step 6) */
6192 	CU_ASSERT(snapshot2->parent_id == SPDK_BLOBID_INVALID);
6193 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid2) == SPDK_BLOBID_INVALID);
6194 
6195 	count = SPDK_COUNTOF(ids);
6196 	rc = spdk_blob_get_clones(bs, snapshotid2, ids, &count);
6197 	CU_ASSERT(rc == 0);
6198 	CU_ASSERT(count == 2);
6199 	CU_ASSERT(ids[0] == blobid || ids[1] == blobid);
6200 	CU_ASSERT(ids[0] == snapshotid3 || ids[1] == snapshotid3);
6201 
6202 	/* 11. Try to create clone from read only blob */
6203 
6204 	/* Mark blob as read only */
6205 	spdk_blob_set_read_only(blob);
6206 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
6207 	poll_threads();
6208 	CU_ASSERT(g_bserrno == 0);
6209 
6210 	/* Create clone from read only blob */
6211 	spdk_bs_create_clone(bs, blobid, NULL, blob_op_with_id_complete, NULL);
6212 	poll_threads();
6213 	CU_ASSERT(g_bserrno == 0);
6214 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
6215 	cloneid2 = g_blobid;
6216 
6217 	spdk_bs_open_blob(bs, cloneid2, blob_op_with_handle_complete, NULL);
6218 	poll_threads();
6219 	CU_ASSERT(g_bserrno == 0);
6220 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
6221 	clone2 = g_blob;
6222 
6223 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid2) == blobid);
6224 
6225 	count = SPDK_COUNTOF(ids);
6226 	rc = spdk_blob_get_clones(bs, blobid, ids, &count);
6227 	CU_ASSERT(rc == 0);
6228 	CU_ASSERT(count == 1);
6229 	CU_ASSERT(ids[0] == cloneid2);
6230 
6231 	/* Close blobs */
6232 
6233 	spdk_blob_close(clone2, blob_op_complete, NULL);
6234 	poll_threads();
6235 	CU_ASSERT(g_bserrno == 0);
6236 
6237 	spdk_blob_close(blob, blob_op_complete, NULL);
6238 	poll_threads();
6239 	CU_ASSERT(g_bserrno == 0);
6240 
6241 	spdk_blob_close(clone, blob_op_complete, NULL);
6242 	poll_threads();
6243 	CU_ASSERT(g_bserrno == 0);
6244 
6245 	spdk_blob_close(snapshot2, blob_op_complete, NULL);
6246 	poll_threads();
6247 	CU_ASSERT(g_bserrno == 0);
6248 
6249 	spdk_blob_close(snapshot3, blob_op_complete, NULL);
6250 	poll_threads();
6251 	CU_ASSERT(g_bserrno == 0);
6252 
6253 	ut_bs_reload(&bs, &bs_opts);
6254 
6255 	/* Verify structure of loaded blob store */
6256 
6257 	/* snapshot2 */
6258 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid2) == SPDK_BLOBID_INVALID);
6259 
6260 	count = SPDK_COUNTOF(ids);
6261 	rc = spdk_blob_get_clones(bs, snapshotid2, ids, &count);
6262 	CU_ASSERT(rc == 0);
6263 	CU_ASSERT(count == 2);
6264 	CU_ASSERT(ids[0] == blobid || ids[1] == blobid);
6265 	CU_ASSERT(ids[0] == snapshotid3 || ids[1] == snapshotid3);
6266 
6267 	/* blob */
6268 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid2);
6269 	count = SPDK_COUNTOF(ids);
6270 	rc = spdk_blob_get_clones(bs, blobid, ids, &count);
6271 	CU_ASSERT(rc == 0);
6272 	CU_ASSERT(count == 1);
6273 	CU_ASSERT(ids[0] == cloneid2);
6274 
6275 	/* clone */
6276 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid3);
6277 	count = SPDK_COUNTOF(ids);
6278 	rc = spdk_blob_get_clones(bs, cloneid, ids, &count);
6279 	CU_ASSERT(rc == 0);
6280 	CU_ASSERT(count == 0);
6281 
6282 	/* snapshot3 */
6283 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid3) == snapshotid2);
6284 	count = SPDK_COUNTOF(ids);
6285 	rc = spdk_blob_get_clones(bs, snapshotid3, ids, &count);
6286 	CU_ASSERT(rc == 0);
6287 	CU_ASSERT(count == 1);
6288 	CU_ASSERT(ids[0] == cloneid);
6289 
6290 	/* clone2 */
6291 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid2) == blobid);
6292 	count = SPDK_COUNTOF(ids);
6293 	rc = spdk_blob_get_clones(bs, cloneid2, ids, &count);
6294 	CU_ASSERT(rc == 0);
6295 	CU_ASSERT(count == 0);
6296 
6297 	/* Try to delete all blobs in the worse possible order */
6298 
6299 	spdk_bs_delete_blob(bs, snapshotid2, blob_op_complete, NULL);
6300 	poll_threads();
6301 	CU_ASSERT(g_bserrno != 0);
6302 
6303 	spdk_bs_delete_blob(bs, snapshotid3, blob_op_complete, NULL);
6304 	poll_threads();
6305 	CU_ASSERT(g_bserrno == 0);
6306 
6307 	spdk_bs_delete_blob(bs, snapshotid2, blob_op_complete, NULL);
6308 	poll_threads();
6309 	CU_ASSERT(g_bserrno != 0);
6310 
6311 	spdk_bs_delete_blob(bs, cloneid, blob_op_complete, NULL);
6312 	poll_threads();
6313 	CU_ASSERT(g_bserrno == 0);
6314 
6315 	spdk_bs_delete_blob(bs, snapshotid2, blob_op_complete, NULL);
6316 	poll_threads();
6317 	CU_ASSERT(g_bserrno == 0);
6318 
6319 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
6320 	poll_threads();
6321 	CU_ASSERT(g_bserrno == 0);
6322 
6323 	spdk_bs_delete_blob(bs, cloneid2, blob_op_complete, NULL);
6324 	poll_threads();
6325 	CU_ASSERT(g_bserrno == 0);
6326 
6327 	spdk_bs_unload(bs, bs_op_complete, NULL);
6328 	poll_threads();
6329 	CU_ASSERT(g_bserrno == 0);
6330 
6331 	g_bs = NULL;
6332 }
6333 
6334 static void
6335 blob_delete_snapshot_power_failure(void)
6336 {
6337 	struct spdk_blob_store *bs;
6338 	struct spdk_bs_dev *dev;
6339 	struct spdk_blob_opts opts;
6340 	struct spdk_blob *blob, *snapshot;
6341 	struct spdk_power_failure_thresholds thresholds = {};
6342 	spdk_blob_id blobid, snapshotid;
6343 	const void *value;
6344 	size_t value_len;
6345 	size_t count;
6346 	spdk_blob_id ids[3] = {};
6347 	int rc;
6348 	bool deleted = false;
6349 
6350 	dev = init_dev();
6351 
6352 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
6353 	poll_threads();
6354 	CU_ASSERT(g_bserrno == 0);
6355 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
6356 	bs = g_bs;
6357 
6358 	/* Create blob */
6359 	ut_spdk_blob_opts_init(&opts);
6360 	opts.num_clusters = 10;
6361 
6362 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
6363 	poll_threads();
6364 	CU_ASSERT(g_bserrno == 0);
6365 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
6366 	blobid = g_blobid;
6367 
6368 	/* Create snapshot */
6369 	spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL);
6370 	poll_threads();
6371 	CU_ASSERT(g_bserrno == 0);
6372 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
6373 	snapshotid = g_blobid;
6374 	SPDK_CU_ASSERT_FATAL(spdk_bit_array_get(bs->used_clusters, 1));
6375 	SPDK_CU_ASSERT_FATAL(!spdk_bit_array_get(bs->used_clusters, 11));
6376 
6377 	thresholds.general_threshold = 1;
6378 	while (!deleted) {
6379 		dev_set_power_failure_thresholds(thresholds);
6380 
6381 		spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL);
6382 		poll_threads();
6383 
6384 		/* Do not shut down cleanly. Assumption is that after snapshot deletion
6385 		 * reports success, changes to both blobs should already persisted. */
6386 		dev_reset_power_failure_event();
6387 		ut_bs_dirty_load(&bs, NULL);
6388 
6389 		SPDK_CU_ASSERT_FATAL(spdk_bit_array_get(bs->used_clusters, 1));
6390 		SPDK_CU_ASSERT_FATAL(!spdk_bit_array_get(bs->used_clusters, 11));
6391 
6392 		spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
6393 		poll_threads();
6394 		CU_ASSERT(g_bserrno == 0);
6395 		SPDK_CU_ASSERT_FATAL(g_blob != NULL);
6396 		blob = g_blob;
6397 		SPDK_CU_ASSERT_FATAL(spdk_blob_is_thin_provisioned(blob) == true);
6398 
6399 		spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL);
6400 		poll_threads();
6401 
6402 		if (g_bserrno == 0) {
6403 			SPDK_CU_ASSERT_FATAL(g_blob != NULL);
6404 			snapshot = g_blob;
6405 			CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid);
6406 			count = SPDK_COUNTOF(ids);
6407 			rc = spdk_blob_get_clones(bs, snapshotid, ids, &count);
6408 			CU_ASSERT(rc == 0);
6409 			CU_ASSERT(count == 1);
6410 			CU_ASSERT(ids[0] == blobid);
6411 			rc = spdk_blob_get_xattr_value(snapshot, SNAPSHOT_PENDING_REMOVAL, &value, &value_len);
6412 			CU_ASSERT(rc != 0);
6413 			SPDK_CU_ASSERT_FATAL(spdk_blob_is_thin_provisioned(snapshot) == false);
6414 
6415 			spdk_blob_close(snapshot, blob_op_complete, NULL);
6416 			poll_threads();
6417 			CU_ASSERT(g_bserrno == 0);
6418 		} else {
6419 			CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == SPDK_BLOBID_INVALID);
6420 			deleted = true;
6421 		}
6422 
6423 		spdk_blob_close(blob, blob_op_complete, NULL);
6424 		poll_threads();
6425 		CU_ASSERT(g_bserrno == 0);
6426 
6427 		/* Reload blobstore to have the same starting conditions (as the previous blobstore load
6428 		 * may trigger cleanup after power failure or may not) */
6429 		ut_bs_reload(&bs, NULL);
6430 		SPDK_CU_ASSERT_FATAL(spdk_bit_array_get(bs->used_clusters, 1));
6431 		SPDK_CU_ASSERT_FATAL(!spdk_bit_array_get(bs->used_clusters, 11));
6432 
6433 		thresholds.general_threshold++;
6434 	}
6435 
6436 	spdk_bs_unload(bs, bs_op_complete, NULL);
6437 	poll_threads();
6438 	CU_ASSERT(g_bserrno == 0);
6439 	g_bs = NULL;
6440 }
6441 
6442 static void
6443 blob_create_snapshot_power_failure(void)
6444 {
6445 	struct spdk_blob_store *bs;
6446 	struct spdk_bs_dev *dev;
6447 	struct spdk_blob_opts opts;
6448 	struct spdk_blob *blob, *snapshot;
6449 	struct spdk_power_failure_thresholds thresholds = {};
6450 	spdk_blob_id blobid, snapshotid;
6451 	const void *value;
6452 	size_t value_len;
6453 	size_t count;
6454 	spdk_blob_id ids[3] = {};
6455 	int rc;
6456 	bool created = false;
6457 
6458 	dev = init_dev();
6459 
6460 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
6461 	poll_threads();
6462 	CU_ASSERT(g_bserrno == 0);
6463 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
6464 	bs = g_bs;
6465 
6466 	/* Create blob */
6467 	ut_spdk_blob_opts_init(&opts);
6468 	opts.num_clusters = 10;
6469 
6470 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
6471 	poll_threads();
6472 	CU_ASSERT(g_bserrno == 0);
6473 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
6474 	blobid = g_blobid;
6475 	SPDK_CU_ASSERT_FATAL(spdk_bit_array_get(bs->used_clusters, 1));
6476 	SPDK_CU_ASSERT_FATAL(!spdk_bit_array_get(bs->used_clusters, 11));
6477 
6478 	thresholds.general_threshold = 1;
6479 	while (!created) {
6480 		dev_set_power_failure_thresholds(thresholds);
6481 
6482 		/* Create snapshot */
6483 		spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL);
6484 		poll_threads();
6485 		snapshotid = g_blobid;
6486 		SPDK_CU_ASSERT_FATAL(spdk_bit_array_get(bs->used_clusters, 1));
6487 		SPDK_CU_ASSERT_FATAL(!spdk_bit_array_get(bs->used_clusters, 11));
6488 
6489 		/* Do not shut down cleanly. Assumption is that after create snapshot
6490 		 * reports success, both blobs should be power-fail safe. */
6491 		dev_reset_power_failure_event();
6492 		ut_bs_dirty_load(&bs, NULL);
6493 
6494 		SPDK_CU_ASSERT_FATAL(spdk_bit_array_get(bs->used_clusters, 1));
6495 		SPDK_CU_ASSERT_FATAL(!spdk_bit_array_get(bs->used_clusters, 11));
6496 
6497 		spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
6498 		poll_threads();
6499 		CU_ASSERT(g_bserrno == 0);
6500 		SPDK_CU_ASSERT_FATAL(g_blob != NULL);
6501 		blob = g_blob;
6502 
6503 		if (snapshotid != SPDK_BLOBID_INVALID) {
6504 			spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL);
6505 			poll_threads();
6506 		}
6507 
6508 		if ((snapshotid != SPDK_BLOBID_INVALID) && (g_bserrno == 0)) {
6509 			SPDK_CU_ASSERT_FATAL(g_blob != NULL);
6510 			snapshot = g_blob;
6511 			SPDK_CU_ASSERT_FATAL(spdk_blob_is_thin_provisioned(blob) == true);
6512 			SPDK_CU_ASSERT_FATAL(spdk_blob_is_thin_provisioned(snapshot) == false);
6513 			CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid);
6514 			count = SPDK_COUNTOF(ids);
6515 			rc = spdk_blob_get_clones(bs, snapshotid, ids, &count);
6516 			CU_ASSERT(rc == 0);
6517 			CU_ASSERT(count == 1);
6518 			CU_ASSERT(ids[0] == blobid);
6519 			rc = spdk_blob_get_xattr_value(snapshot, SNAPSHOT_IN_PROGRESS, &value, &value_len);
6520 			CU_ASSERT(rc != 0);
6521 
6522 			spdk_blob_close(snapshot, blob_op_complete, NULL);
6523 			poll_threads();
6524 			CU_ASSERT(g_bserrno == 0);
6525 			created = true;
6526 		} else {
6527 			CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == SPDK_BLOBID_INVALID);
6528 			SPDK_CU_ASSERT_FATAL(spdk_blob_is_thin_provisioned(blob) == false);
6529 		}
6530 
6531 		spdk_blob_close(blob, blob_op_complete, NULL);
6532 		poll_threads();
6533 		CU_ASSERT(g_bserrno == 0);
6534 
6535 		/* Reload blobstore to have the same starting conditions (as the previous blobstore load
6536 		 * may trigger cleanup after power failure or may not) */
6537 		ut_bs_reload(&bs, NULL);
6538 		SPDK_CU_ASSERT_FATAL(spdk_bit_array_get(bs->used_clusters, 1));
6539 		SPDK_CU_ASSERT_FATAL(!spdk_bit_array_get(bs->used_clusters, 11));
6540 
6541 		thresholds.general_threshold++;
6542 	}
6543 
6544 	spdk_bs_unload(bs, bs_op_complete, NULL);
6545 	poll_threads();
6546 	CU_ASSERT(g_bserrno == 0);
6547 	g_bs = NULL;
6548 }
6549 
6550 static void
6551 test_io_write(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel)
6552 {
6553 	uint8_t payload_ff[64 * 512];
6554 	uint8_t payload_aa[64 * 512];
6555 	uint8_t payload_00[64 * 512];
6556 	uint8_t *cluster0, *cluster1;
6557 
6558 	memset(payload_ff, 0xFF, sizeof(payload_ff));
6559 	memset(payload_aa, 0xAA, sizeof(payload_aa));
6560 	memset(payload_00, 0x00, sizeof(payload_00));
6561 
6562 	/* Try to perform I/O with io unit = 512 */
6563 	spdk_blob_io_write(blob, channel, payload_ff, 0, 1, blob_op_complete, NULL);
6564 	poll_threads();
6565 	CU_ASSERT(g_bserrno == 0);
6566 
6567 	/* If thin provisioned is set cluster should be allocated now */
6568 	SPDK_CU_ASSERT_FATAL(blob->active.clusters[0] != 0);
6569 	cluster0 = &g_dev_buffer[blob->active.clusters[0] * dev->blocklen];
6570 
6571 	/* Each character 0-F symbolizes single io_unit containing 512 bytes block filled with that character.
6572 	* Each page is separated by |. Whole block [...] symbolizes one cluster (containing 4 pages). */
6573 	/* cluster0: [ F000 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */
6574 	CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0);
6575 	CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 31 * 512) == 0);
6576 
6577 	/* Verify write with offset on first page */
6578 	spdk_blob_io_write(blob, channel, payload_ff, 2, 1, blob_op_complete, NULL);
6579 	poll_threads();
6580 	CU_ASSERT(g_bserrno == 0);
6581 
6582 	/* cluster0: [ F0F0 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */
6583 	CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0);
6584 	CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0);
6585 	CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0);
6586 	CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0);
6587 	CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_00, 28 * 512) == 0);
6588 
6589 	/* Verify write with offset on first page */
6590 	spdk_blob_io_write(blob, channel, payload_ff, 4, 4, blob_op_complete, NULL);
6591 	poll_threads();
6592 
6593 	/* cluster0: [ F0F0 FFFF | 0000 0000 | 0000 0000 | 0000 0000 ] */
6594 	CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0);
6595 	CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0);
6596 	CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0);
6597 	CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0);
6598 	CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_ff, 4 * 512) == 0);
6599 	CU_ASSERT(memcmp(cluster0 + 8 * 512, payload_00, 24 * 512) == 0);
6600 
6601 	/* Verify write with offset on second page */
6602 	spdk_blob_io_write(blob, channel, payload_ff, 8, 4, blob_op_complete, NULL);
6603 	poll_threads();
6604 
6605 	/* cluster0: [ F0F0 FFFF | FFFF 0000 | 0000 0000 | 0000 0000 ] */
6606 	CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0);
6607 	CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0);
6608 	CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0);
6609 	CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0);
6610 	CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_ff, 8 * 512) == 0);
6611 	CU_ASSERT(memcmp(cluster0 + 12 * 512, payload_00, 20 * 512) == 0);
6612 
6613 	/* Verify write across multiple pages */
6614 	spdk_blob_io_write(blob, channel, payload_aa, 4, 8, blob_op_complete, NULL);
6615 	poll_threads();
6616 
6617 	/* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 0000 ] */
6618 	CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0);
6619 	CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0);
6620 	CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0);
6621 	CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0);
6622 	CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0);
6623 	CU_ASSERT(memcmp(cluster0 + 12 * 512, payload_00, 20 * 512) == 0);
6624 
6625 	/* Verify write across multiple clusters */
6626 	spdk_blob_io_write(blob, channel, payload_ff, 28, 8, blob_op_complete, NULL);
6627 	poll_threads();
6628 
6629 	SPDK_CU_ASSERT_FATAL(blob->active.clusters[1] != 0);
6630 	cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen];
6631 
6632 	/* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ]
6633 	 * cluster1: [ FFFF 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */
6634 	CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0);
6635 	CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0);
6636 	CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0);
6637 	CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0);
6638 	CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0);
6639 	CU_ASSERT(memcmp(cluster0 + 28 * 512, payload_ff, 4 * 512) == 0);
6640 
6641 	CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_ff, 4 * 512) == 0);
6642 	CU_ASSERT(memcmp(cluster1 + 4 * 512, payload_00, 28 * 512) == 0);
6643 
6644 	/* Verify write to second cluster */
6645 	spdk_blob_io_write(blob, channel, payload_ff, 32 + 12, 2, blob_op_complete, NULL);
6646 	poll_threads();
6647 
6648 	SPDK_CU_ASSERT_FATAL(blob->active.clusters[1] != 0);
6649 	cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen];
6650 
6651 	/* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ]
6652 	 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] */
6653 	CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0);
6654 	CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0);
6655 	CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0);
6656 	CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0);
6657 	CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0);
6658 	CU_ASSERT(memcmp(cluster0 + 28 * 512, payload_ff, 4 * 512) == 0);
6659 
6660 	CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_ff, 4 * 512) == 0);
6661 	CU_ASSERT(memcmp(cluster1 + 4 * 512, payload_00, 8 * 512) == 0);
6662 	CU_ASSERT(memcmp(cluster1 + 12 * 512, payload_ff, 2 * 512) == 0);
6663 	CU_ASSERT(memcmp(cluster1 + 14 * 512, payload_00, 18 * 512) == 0);
6664 }
6665 
6666 static void
6667 test_io_read(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel)
6668 {
6669 	uint8_t payload_read[64 * 512];
6670 	uint8_t payload_ff[64 * 512];
6671 	uint8_t payload_aa[64 * 512];
6672 	uint8_t payload_00[64 * 512];
6673 
6674 	memset(payload_ff, 0xFF, sizeof(payload_ff));
6675 	memset(payload_aa, 0xAA, sizeof(payload_aa));
6676 	memset(payload_00, 0x00, sizeof(payload_00));
6677 
6678 	/* Read only first io unit */
6679 	/* cluster0: [ (F)0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ]
6680 	 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ]
6681 	 * payload_read: F000 0000 | 0000 0000 ... */
6682 	memset(payload_read, 0x00, sizeof(payload_read));
6683 	spdk_blob_io_read(blob, channel, payload_read, 0, 1, blob_op_complete, NULL);
6684 	poll_threads();
6685 	CU_ASSERT(g_bserrno == 0);
6686 	CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0);
6687 	CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 31 * 512) == 0);
6688 
6689 	/* Read four io_units starting from offset = 2
6690 	 * cluster0: [ F0(F0 AA)AA | AAAA 0000 | 0000 0000 | 0000 FFFF ]
6691 	 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ]
6692 	 * payload_read: F0AA 0000 | 0000 0000 ... */
6693 
6694 	memset(payload_read, 0x00, sizeof(payload_read));
6695 	spdk_blob_io_read(blob, channel, payload_read, 2, 4, blob_op_complete, NULL);
6696 	poll_threads();
6697 	CU_ASSERT(g_bserrno == 0);
6698 
6699 	CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0);
6700 	CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 512) == 0);
6701 	CU_ASSERT(memcmp(payload_read + 2 * 512, payload_aa, 512) == 0);
6702 	CU_ASSERT(memcmp(payload_read + 3 * 512, payload_aa, 512) == 0);
6703 	CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 28 * 512) == 0);
6704 
6705 	/* Read eight io_units across multiple pages
6706 	 * cluster0: [ F0F0 (AAAA | AAAA) 0000 | 0000 0000 | 0000 FFFF ]
6707 	 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ]
6708 	 * payload_read: AAAA AAAA | 0000 0000 ... */
6709 	memset(payload_read, 0x00, sizeof(payload_read));
6710 	spdk_blob_io_read(blob, channel, payload_read, 4, 8, blob_op_complete, NULL);
6711 	poll_threads();
6712 	CU_ASSERT(g_bserrno == 0);
6713 
6714 	CU_ASSERT(memcmp(payload_read + 0 * 512, payload_aa, 8 * 512) == 0);
6715 	CU_ASSERT(memcmp(payload_read + 8 * 512, payload_00, 24 * 512) == 0);
6716 
6717 	/* Read eight io_units across multiple clusters
6718 	 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 (FFFF ]
6719 	 * cluster1: [ FFFF) 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ]
6720 	 * payload_read: FFFF FFFF | 0000 0000 ... */
6721 	memset(payload_read, 0x00, sizeof(payload_read));
6722 	spdk_blob_io_read(blob, channel, payload_read, 28, 8, blob_op_complete, NULL);
6723 	poll_threads();
6724 	CU_ASSERT(g_bserrno == 0);
6725 
6726 	CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 8 * 512) == 0);
6727 	CU_ASSERT(memcmp(payload_read + 8 * 512, payload_00, 24 * 512) == 0);
6728 
6729 	/* Read four io_units from second cluster
6730 	 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ]
6731 	 * cluster1: [ FFFF 0000 | 00(00 FF)00 | 0000 0000 | 0000 0000 ]
6732 	 * payload_read: 00FF 0000 | 0000 0000 ... */
6733 	memset(payload_read, 0x00, sizeof(payload_read));
6734 	spdk_blob_io_read(blob, channel, payload_read, 32 + 10, 4, blob_op_complete, NULL);
6735 	poll_threads();
6736 	CU_ASSERT(g_bserrno == 0);
6737 
6738 	CU_ASSERT(memcmp(payload_read + 0 * 512, payload_00, 2 * 512) == 0);
6739 	CU_ASSERT(memcmp(payload_read + 2 * 512, payload_ff, 2 * 512) == 0);
6740 	CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 28 * 512) == 0);
6741 
6742 	/* Read second cluster
6743 	 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ]
6744 	 * cluster1: [ (FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000) ]
6745 	 * payload_read: FFFF 0000 | 0000 FF00 ... */
6746 	memset(payload_read, 0x00, sizeof(payload_read));
6747 	spdk_blob_io_read(blob, channel, payload_read, 32, 32, blob_op_complete, NULL);
6748 	poll_threads();
6749 	CU_ASSERT(g_bserrno == 0);
6750 	CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 4 * 512) == 0);
6751 	CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 8 * 512) == 0);
6752 	CU_ASSERT(memcmp(payload_read + 12 * 512, payload_ff, 2 * 512) == 0);
6753 	CU_ASSERT(memcmp(payload_read + 14 * 512, payload_00, 18 * 512) == 0);
6754 
6755 	/* Read whole two clusters
6756 	 * cluster0: [ (F0F0 AAAA | AAAA) 0000 | 0000 0000 | 0000 FFFF ]
6757 	 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000) ] */
6758 	memset(payload_read, 0x00, sizeof(payload_read));
6759 	spdk_blob_io_read(blob, channel, payload_read, 0, 64, blob_op_complete, NULL);
6760 	poll_threads();
6761 	CU_ASSERT(g_bserrno == 0);
6762 
6763 	CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0);
6764 	CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 512) == 0);
6765 	CU_ASSERT(memcmp(payload_read + 2 * 512, payload_ff, 512) == 0);
6766 	CU_ASSERT(memcmp(payload_read + 3 * 512, payload_00, 512) == 0);
6767 	CU_ASSERT(memcmp(payload_read + 4 * 512, payload_aa, 8 * 512) == 0);
6768 	CU_ASSERT(memcmp(payload_read + 28 * 512, payload_ff, 4 * 512) == 0);
6769 
6770 	CU_ASSERT(memcmp(payload_read + (32 + 0) * 512, payload_ff, 4 * 512) == 0);
6771 	CU_ASSERT(memcmp(payload_read + (32 + 4) * 512, payload_00, 8 * 512) == 0);
6772 	CU_ASSERT(memcmp(payload_read + (32 + 12) * 512, payload_ff, 2 * 512) == 0);
6773 	CU_ASSERT(memcmp(payload_read + (32 + 14) * 512, payload_00, 18 * 512) == 0);
6774 }
6775 
6776 
6777 static void
6778 test_io_unmap(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel)
6779 {
6780 	uint8_t payload_ff[64 * 512];
6781 	uint8_t payload_aa[64 * 512];
6782 	uint8_t payload_00[64 * 512];
6783 	uint8_t *cluster0, *cluster1;
6784 
6785 	memset(payload_ff, 0xFF, sizeof(payload_ff));
6786 	memset(payload_aa, 0xAA, sizeof(payload_aa));
6787 	memset(payload_00, 0x00, sizeof(payload_00));
6788 
6789 	cluster0 = &g_dev_buffer[blob->active.clusters[0] * dev->blocklen];
6790 	cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen];
6791 
6792 	/* Unmap */
6793 	spdk_blob_io_unmap(blob, channel, 0, 64, blob_op_complete, NULL);
6794 	poll_threads();
6795 
6796 	CU_ASSERT(g_bserrno == 0);
6797 
6798 	CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_00, 32 * 512) == 0);
6799 	CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_00, 32 * 512) == 0);
6800 }
6801 
6802 static void
6803 test_io_zeroes(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel)
6804 {
6805 	uint8_t payload_ff[64 * 512];
6806 	uint8_t payload_aa[64 * 512];
6807 	uint8_t payload_00[64 * 512];
6808 	uint8_t *cluster0, *cluster1;
6809 
6810 	memset(payload_ff, 0xFF, sizeof(payload_ff));
6811 	memset(payload_aa, 0xAA, sizeof(payload_aa));
6812 	memset(payload_00, 0x00, sizeof(payload_00));
6813 
6814 	cluster0 = &g_dev_buffer[blob->active.clusters[0] * dev->blocklen];
6815 	cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen];
6816 
6817 	/* Write zeroes  */
6818 	spdk_blob_io_write_zeroes(blob, channel, 0, 64, blob_op_complete, NULL);
6819 	poll_threads();
6820 
6821 	CU_ASSERT(g_bserrno == 0);
6822 
6823 	CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_00, 32 * 512) == 0);
6824 	CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_00, 32 * 512) == 0);
6825 }
6826 
6827 
6828 static void
6829 test_iov_write(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel)
6830 {
6831 	uint8_t payload_ff[64 * 512];
6832 	uint8_t payload_aa[64 * 512];
6833 	uint8_t payload_00[64 * 512];
6834 	uint8_t *cluster0, *cluster1;
6835 	struct iovec iov[4];
6836 
6837 	memset(payload_ff, 0xFF, sizeof(payload_ff));
6838 	memset(payload_aa, 0xAA, sizeof(payload_aa));
6839 	memset(payload_00, 0x00, sizeof(payload_00));
6840 
6841 	/* Try to perform I/O with io unit = 512 */
6842 	iov[0].iov_base = payload_ff;
6843 	iov[0].iov_len = 1 * 512;
6844 	spdk_blob_io_writev(blob, channel, iov, 1, 0, 1, blob_op_complete, NULL);
6845 	poll_threads();
6846 	CU_ASSERT(g_bserrno == 0);
6847 
6848 	/* If thin provisioned is set cluster should be allocated now */
6849 	SPDK_CU_ASSERT_FATAL(blob->active.clusters[0] != 0);
6850 	cluster0 = &g_dev_buffer[blob->active.clusters[0] * dev->blocklen];
6851 
6852 	/* Each character 0-F symbolizes single io_unit containing 512 bytes block filled with that character.
6853 	* Each page is separated by |. Whole block [...] symbolizes one cluster (containing 4 pages). */
6854 	/* cluster0: [ F000 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */
6855 	CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0);
6856 	CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 31 * 512) == 0);
6857 
6858 	/* Verify write with offset on first page */
6859 	iov[0].iov_base = payload_ff;
6860 	iov[0].iov_len = 1 * 512;
6861 	spdk_blob_io_writev(blob, channel, iov, 1, 2, 1, blob_op_complete, NULL);
6862 	poll_threads();
6863 	CU_ASSERT(g_bserrno == 0);
6864 
6865 	/* cluster0: [ F0F0 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */
6866 	CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0);
6867 	CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0);
6868 	CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0);
6869 	CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0);
6870 	CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_00, 28 * 512) == 0);
6871 
6872 	/* Verify write with offset on first page */
6873 	iov[0].iov_base = payload_ff;
6874 	iov[0].iov_len = 4 * 512;
6875 	spdk_blob_io_writev(blob, channel, iov, 1, 4, 4, blob_op_complete, NULL);
6876 	poll_threads();
6877 
6878 	/* cluster0: [ F0F0 FFFF | 0000 0000 | 0000 0000 | 0000 0000 ] */
6879 	CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0);
6880 	CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0);
6881 	CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0);
6882 	CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0);
6883 	CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_ff, 4 * 512) == 0);
6884 	CU_ASSERT(memcmp(cluster0 + 8 * 512, payload_00, 24 * 512) == 0);
6885 
6886 	/* Verify write with offset on second page */
6887 	iov[0].iov_base = payload_ff;
6888 	iov[0].iov_len = 4 * 512;
6889 	spdk_blob_io_writev(blob, channel, iov, 1, 8, 4, blob_op_complete, NULL);
6890 	poll_threads();
6891 
6892 	/* cluster0: [ F0F0 FFFF | FFFF 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, 8 * 512) == 0);
6898 	CU_ASSERT(memcmp(cluster0 + 12 * 512, payload_00, 20 * 512) == 0);
6899 
6900 	/* Verify write across multiple pages */
6901 	iov[0].iov_base = payload_aa;
6902 	iov[0].iov_len = 8 * 512;
6903 	spdk_blob_io_writev(blob, channel, iov, 1, 4, 8, blob_op_complete, NULL);
6904 	poll_threads();
6905 
6906 	/* cluster0: [ F0F0 AAAA | AAAA 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_aa, 8 * 512) == 0);
6912 	CU_ASSERT(memcmp(cluster0 + 12 * 512, payload_00, 20 * 512) == 0);
6913 
6914 	/* Verify write across multiple clusters */
6915 
6916 	iov[0].iov_base = payload_ff;
6917 	iov[0].iov_len = 8 * 512;
6918 	spdk_blob_io_writev(blob, channel, iov, 1, 28, 8, blob_op_complete, NULL);
6919 	poll_threads();
6920 
6921 	SPDK_CU_ASSERT_FATAL(blob->active.clusters[1] != 0);
6922 	cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen];
6923 
6924 	/* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ]
6925 	 * cluster1: [ FFFF 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */
6926 	CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0);
6927 	CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0);
6928 	CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0);
6929 	CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0);
6930 	CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0);
6931 	CU_ASSERT(memcmp(cluster0 + 12 * 512, payload_00, 16 * 512) == 0);
6932 	CU_ASSERT(memcmp(cluster0 + 28 * 512, payload_ff, 4 * 512) == 0);
6933 
6934 	CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_ff, 4 * 512) == 0);
6935 	CU_ASSERT(memcmp(cluster1 + 4 * 512, payload_00, 28 * 512) == 0);
6936 
6937 	/* Verify write to second cluster */
6938 
6939 	iov[0].iov_base = payload_ff;
6940 	iov[0].iov_len = 2 * 512;
6941 	spdk_blob_io_writev(blob, channel, iov, 1, 32 + 12, 2, blob_op_complete, NULL);
6942 	poll_threads();
6943 
6944 	SPDK_CU_ASSERT_FATAL(blob->active.clusters[1] != 0);
6945 	cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen];
6946 
6947 	/* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ]
6948 	 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] */
6949 	CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0);
6950 	CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0);
6951 	CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0);
6952 	CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0);
6953 	CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0);
6954 	CU_ASSERT(memcmp(cluster0 + 28 * 512, payload_ff, 4 * 512) == 0);
6955 
6956 	CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_ff, 4 * 512) == 0);
6957 	CU_ASSERT(memcmp(cluster1 + 4 * 512, payload_00, 8 * 512) == 0);
6958 	CU_ASSERT(memcmp(cluster1 + 12 * 512, payload_ff, 2 * 512) == 0);
6959 	CU_ASSERT(memcmp(cluster1 + 14 * 512, payload_00, 18 * 512) == 0);
6960 }
6961 
6962 static void
6963 test_iov_read(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel)
6964 {
6965 	uint8_t payload_read[64 * 512];
6966 	uint8_t payload_ff[64 * 512];
6967 	uint8_t payload_aa[64 * 512];
6968 	uint8_t payload_00[64 * 512];
6969 	struct iovec iov[4];
6970 
6971 	memset(payload_ff, 0xFF, sizeof(payload_ff));
6972 	memset(payload_aa, 0xAA, sizeof(payload_aa));
6973 	memset(payload_00, 0x00, sizeof(payload_00));
6974 
6975 	/* Read only first io unit */
6976 	/* cluster0: [ (F)0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ]
6977 	 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ]
6978 	 * payload_read: F000 0000 | 0000 0000 ... */
6979 	memset(payload_read, 0x00, sizeof(payload_read));
6980 	iov[0].iov_base = payload_read;
6981 	iov[0].iov_len = 1 * 512;
6982 	spdk_blob_io_readv(blob, channel, iov, 1, 0, 1, blob_op_complete, NULL);
6983 	poll_threads();
6984 
6985 	CU_ASSERT(g_bserrno == 0);
6986 	CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0);
6987 	CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 31 * 512) == 0);
6988 
6989 	/* Read four io_units starting from offset = 2
6990 	 * cluster0: [ F0(F0 AA)AA | AAAA 0000 | 0000 0000 | 0000 FFFF ]
6991 	 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ]
6992 	 * payload_read: F0AA 0000 | 0000 0000 ... */
6993 
6994 	memset(payload_read, 0x00, sizeof(payload_read));
6995 	iov[0].iov_base = payload_read;
6996 	iov[0].iov_len = 4 * 512;
6997 	spdk_blob_io_readv(blob, channel, iov, 1, 2, 4, blob_op_complete, NULL);
6998 	poll_threads();
6999 	CU_ASSERT(g_bserrno == 0);
7000 
7001 	CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0);
7002 	CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 512) == 0);
7003 	CU_ASSERT(memcmp(payload_read + 2 * 512, payload_aa, 512) == 0);
7004 	CU_ASSERT(memcmp(payload_read + 3 * 512, payload_aa, 512) == 0);
7005 	CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 28 * 512) == 0);
7006 
7007 	/* Read eight io_units across multiple pages
7008 	 * cluster0: [ F0F0 (AAAA | AAAA) 0000 | 0000 0000 | 0000 FFFF ]
7009 	 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ]
7010 	 * payload_read: AAAA AAAA | 0000 0000 ... */
7011 	memset(payload_read, 0x00, sizeof(payload_read));
7012 	iov[0].iov_base = payload_read;
7013 	iov[0].iov_len = 4 * 512;
7014 	iov[1].iov_base = payload_read + 4 * 512;
7015 	iov[1].iov_len = 4 * 512;
7016 	spdk_blob_io_readv(blob, channel, iov, 2, 4, 8, blob_op_complete, NULL);
7017 	poll_threads();
7018 	CU_ASSERT(g_bserrno == 0);
7019 
7020 	CU_ASSERT(memcmp(payload_read + 0 * 512, payload_aa, 8 * 512) == 0);
7021 	CU_ASSERT(memcmp(payload_read + 8 * 512, payload_00, 24 * 512) == 0);
7022 
7023 	/* Read eight io_units across multiple clusters
7024 	 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 (FFFF ]
7025 	 * cluster1: [ FFFF) 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ]
7026 	 * payload_read: FFFF FFFF | 0000 0000 ... */
7027 	memset(payload_read, 0x00, sizeof(payload_read));
7028 	iov[0].iov_base = payload_read;
7029 	iov[0].iov_len = 2 * 512;
7030 	iov[1].iov_base = payload_read + 2 * 512;
7031 	iov[1].iov_len = 2 * 512;
7032 	iov[2].iov_base = payload_read + 4 * 512;
7033 	iov[2].iov_len = 2 * 512;
7034 	iov[3].iov_base = payload_read + 6 * 512;
7035 	iov[3].iov_len = 2 * 512;
7036 	spdk_blob_io_readv(blob, channel, iov, 4, 28, 8, blob_op_complete, NULL);
7037 	poll_threads();
7038 	CU_ASSERT(g_bserrno == 0);
7039 
7040 	CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 8 * 512) == 0);
7041 	CU_ASSERT(memcmp(payload_read + 8 * 512, payload_00, 24 * 512) == 0);
7042 
7043 	/* Read four io_units from second cluster
7044 	 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ]
7045 	 * cluster1: [ FFFF 0000 | 00(00 FF)00 | 0000 0000 | 0000 0000 ]
7046 	 * payload_read: 00FF 0000 | 0000 0000 ... */
7047 	memset(payload_read, 0x00, sizeof(payload_read));
7048 	iov[0].iov_base = payload_read;
7049 	iov[0].iov_len = 1 * 512;
7050 	iov[1].iov_base = payload_read + 1 * 512;
7051 	iov[1].iov_len = 3 * 512;
7052 	spdk_blob_io_readv(blob, channel, iov, 2, 32 + 10, 4, blob_op_complete, NULL);
7053 	poll_threads();
7054 	CU_ASSERT(g_bserrno == 0);
7055 
7056 	CU_ASSERT(memcmp(payload_read + 0 * 512, payload_00, 2 * 512) == 0);
7057 	CU_ASSERT(memcmp(payload_read + 2 * 512, payload_ff, 2 * 512) == 0);
7058 	CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 28 * 512) == 0);
7059 
7060 	/* Read second cluster
7061 	 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ]
7062 	 * cluster1: [ (FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000) ]
7063 	 * payload_read: FFFF 0000 | 0000 FF00 ... */
7064 	memset(payload_read, 0x00, sizeof(payload_read));
7065 	iov[0].iov_base = payload_read;
7066 	iov[0].iov_len = 1 * 512;
7067 	iov[1].iov_base = payload_read + 1 * 512;
7068 	iov[1].iov_len = 2 * 512;
7069 	iov[2].iov_base = payload_read + 3 * 512;
7070 	iov[2].iov_len = 4 * 512;
7071 	iov[3].iov_base = payload_read + 7 * 512;
7072 	iov[3].iov_len = 25 * 512;
7073 	spdk_blob_io_readv(blob, channel, iov, 4, 32, 32, blob_op_complete, NULL);
7074 	poll_threads();
7075 	CU_ASSERT(g_bserrno == 0);
7076 	CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 4 * 512) == 0);
7077 	CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 8 * 512) == 0);
7078 	CU_ASSERT(memcmp(payload_read + 12 * 512, payload_ff, 2 * 512) == 0);
7079 	CU_ASSERT(memcmp(payload_read + 14 * 512, payload_00, 18 * 512) == 0);
7080 
7081 	/* Read whole two clusters
7082 	 * cluster0: [ (F0F0 AAAA | AAAA) 0000 | 0000 0000 | 0000 FFFF ]
7083 	 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000) ] */
7084 	memset(payload_read, 0x00, sizeof(payload_read));
7085 	iov[0].iov_base = payload_read;
7086 	iov[0].iov_len = 1 * 512;
7087 	iov[1].iov_base = payload_read + 1 * 512;
7088 	iov[1].iov_len = 8 * 512;
7089 	iov[2].iov_base = payload_read + 9 * 512;
7090 	iov[2].iov_len = 16 * 512;
7091 	iov[3].iov_base = payload_read + 25 * 512;
7092 	iov[3].iov_len = 39 * 512;
7093 	spdk_blob_io_readv(blob, channel, iov, 4, 0, 64, blob_op_complete, NULL);
7094 	poll_threads();
7095 	CU_ASSERT(g_bserrno == 0);
7096 
7097 	CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0);
7098 	CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 512) == 0);
7099 	CU_ASSERT(memcmp(payload_read + 2 * 512, payload_ff, 512) == 0);
7100 	CU_ASSERT(memcmp(payload_read + 3 * 512, payload_00, 512) == 0);
7101 	CU_ASSERT(memcmp(payload_read + 4 * 512, payload_aa, 8 * 512) == 0);
7102 	CU_ASSERT(memcmp(payload_read + 28 * 512, payload_ff, 4 * 512) == 0);
7103 
7104 	CU_ASSERT(memcmp(payload_read + (32 + 0) * 512, payload_ff, 4 * 512) == 0);
7105 	CU_ASSERT(memcmp(payload_read + (32 + 4) * 512, payload_00, 8 * 512) == 0);
7106 	CU_ASSERT(memcmp(payload_read + (32 + 12) * 512, payload_ff, 2 * 512) == 0);
7107 	CU_ASSERT(memcmp(payload_read + (32 + 14) * 512, payload_00, 18 * 512) == 0);
7108 }
7109 
7110 static void
7111 blob_io_unit(void)
7112 {
7113 	struct spdk_bs_opts bsopts;
7114 	struct spdk_blob_opts opts;
7115 	struct spdk_blob_store *bs;
7116 	struct spdk_bs_dev *dev;
7117 	struct spdk_blob *blob, *snapshot, *clone;
7118 	spdk_blob_id blobid;
7119 	struct spdk_io_channel *channel;
7120 
7121 	/* Create dev with 512 bytes io unit size */
7122 
7123 	spdk_bs_opts_init(&bsopts);
7124 	bsopts.cluster_sz = SPDK_BS_PAGE_SIZE * 4;	/* 8 * 4 = 32 io_unit */
7125 	snprintf(bsopts.bstype.bstype, sizeof(bsopts.bstype.bstype), "TESTTYPE");
7126 
7127 	/* Try to initialize a new blob store with unsupported io_unit */
7128 	dev = init_dev();
7129 	dev->blocklen = 512;
7130 	dev->blockcnt =  DEV_BUFFER_SIZE / dev->blocklen;
7131 
7132 	/* Initialize a new blob store */
7133 	spdk_bs_init(dev, &bsopts, bs_op_with_handle_complete, NULL);
7134 	poll_threads();
7135 	CU_ASSERT(g_bserrno == 0);
7136 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
7137 	bs = g_bs;
7138 
7139 	CU_ASSERT(spdk_bs_get_io_unit_size(bs) == 512);
7140 	channel = spdk_bs_alloc_io_channel(bs);
7141 
7142 	/* Create thick provisioned blob */
7143 	ut_spdk_blob_opts_init(&opts);
7144 	opts.thin_provision = false;
7145 	opts.num_clusters = 32;
7146 
7147 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
7148 	poll_threads();
7149 
7150 	CU_ASSERT(g_bserrno == 0);
7151 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
7152 	blobid = g_blobid;
7153 
7154 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
7155 	poll_threads();
7156 	CU_ASSERT(g_bserrno == 0);
7157 	CU_ASSERT(g_blob != NULL);
7158 	blob = g_blob;
7159 
7160 	test_io_write(dev, blob, channel);
7161 	test_io_read(dev, blob, channel);
7162 	test_io_zeroes(dev, blob, channel);
7163 
7164 	test_iov_write(dev, blob, channel);
7165 	test_iov_read(dev, blob, channel);
7166 
7167 	test_io_unmap(dev, blob, channel);
7168 
7169 	spdk_blob_close(blob, blob_op_complete, NULL);
7170 	poll_threads();
7171 	CU_ASSERT(g_bserrno == 0);
7172 	blob = NULL;
7173 	g_blob = NULL;
7174 
7175 	/* Create thin provisioned blob */
7176 
7177 	ut_spdk_blob_opts_init(&opts);
7178 	opts.thin_provision = true;
7179 	opts.num_clusters = 32;
7180 
7181 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
7182 	poll_threads();
7183 	CU_ASSERT(g_bserrno == 0);
7184 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
7185 	blobid = g_blobid;
7186 
7187 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
7188 	poll_threads();
7189 	CU_ASSERT(g_bserrno == 0);
7190 	CU_ASSERT(g_blob != NULL);
7191 	blob = g_blob;
7192 
7193 	test_io_write(dev, blob, channel);
7194 	test_io_read(dev, blob, channel);
7195 
7196 	test_io_zeroes(dev, blob, channel);
7197 
7198 	test_iov_write(dev, blob, channel);
7199 	test_iov_read(dev, blob, channel);
7200 
7201 	/* Create snapshot */
7202 
7203 	spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL);
7204 	poll_threads();
7205 	CU_ASSERT(g_bserrno == 0);
7206 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
7207 	blobid = g_blobid;
7208 
7209 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
7210 	poll_threads();
7211 	CU_ASSERT(g_bserrno == 0);
7212 	CU_ASSERT(g_blob != NULL);
7213 	snapshot = g_blob;
7214 
7215 	spdk_bs_create_clone(bs, blobid, NULL, blob_op_with_id_complete, NULL);
7216 	poll_threads();
7217 	CU_ASSERT(g_bserrno == 0);
7218 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
7219 	blobid = g_blobid;
7220 
7221 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
7222 	poll_threads();
7223 	CU_ASSERT(g_bserrno == 0);
7224 	CU_ASSERT(g_blob != NULL);
7225 	clone = g_blob;
7226 
7227 	test_io_read(dev, blob, channel);
7228 	test_io_read(dev, snapshot, channel);
7229 	test_io_read(dev, clone, channel);
7230 
7231 	test_iov_read(dev, blob, channel);
7232 	test_iov_read(dev, snapshot, channel);
7233 	test_iov_read(dev, clone, channel);
7234 
7235 	/* Inflate clone */
7236 
7237 	spdk_bs_inflate_blob(bs, channel, blobid, blob_op_complete, NULL);
7238 	poll_threads();
7239 
7240 	CU_ASSERT(g_bserrno == 0);
7241 
7242 	test_io_read(dev, clone, channel);
7243 
7244 	test_io_unmap(dev, clone, channel);
7245 
7246 	test_iov_write(dev, clone, channel);
7247 	test_iov_read(dev, clone, channel);
7248 
7249 	spdk_blob_close(blob, blob_op_complete, NULL);
7250 	spdk_blob_close(snapshot, blob_op_complete, NULL);
7251 	spdk_blob_close(clone, blob_op_complete, NULL);
7252 	poll_threads();
7253 	CU_ASSERT(g_bserrno == 0);
7254 	blob = NULL;
7255 	g_blob = NULL;
7256 
7257 	spdk_bs_free_io_channel(channel);
7258 	poll_threads();
7259 
7260 	/* Unload the blob store */
7261 	spdk_bs_unload(bs, bs_op_complete, NULL);
7262 	poll_threads();
7263 	CU_ASSERT(g_bserrno == 0);
7264 	g_bs = NULL;
7265 	g_blob = NULL;
7266 	g_blobid = 0;
7267 }
7268 
7269 static void
7270 blob_io_unit_compatiblity(void)
7271 {
7272 	struct spdk_bs_opts bsopts;
7273 	struct spdk_blob_store *bs;
7274 	struct spdk_bs_dev *dev;
7275 	struct spdk_bs_super_block *super;
7276 
7277 	/* Create dev with 512 bytes io unit size */
7278 
7279 	spdk_bs_opts_init(&bsopts);
7280 	bsopts.cluster_sz = SPDK_BS_PAGE_SIZE * 4;	/* 8 * 4 = 32 io_unit */
7281 	snprintf(bsopts.bstype.bstype, sizeof(bsopts.bstype.bstype), "TESTTYPE");
7282 
7283 	/* Try to initialize a new blob store with unsupported io_unit */
7284 	dev = init_dev();
7285 	dev->blocklen = 512;
7286 	dev->blockcnt =  DEV_BUFFER_SIZE / dev->blocklen;
7287 
7288 	/* Initialize a new blob store */
7289 	spdk_bs_init(dev, &bsopts, bs_op_with_handle_complete, NULL);
7290 	poll_threads();
7291 	CU_ASSERT(g_bserrno == 0);
7292 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
7293 	bs = g_bs;
7294 
7295 	CU_ASSERT(spdk_bs_get_io_unit_size(bs) == 512);
7296 
7297 	/* Unload the blob store */
7298 	spdk_bs_unload(bs, bs_op_complete, NULL);
7299 	poll_threads();
7300 	CU_ASSERT(g_bserrno == 0);
7301 
7302 	/* Modify super block to behave like older version.
7303 	 * Check if loaded io unit size equals SPDK_BS_PAGE_SIZE */
7304 	super = (struct spdk_bs_super_block *)&g_dev_buffer[0];
7305 	super->io_unit_size = 0;
7306 	super->crc = _spdk_blob_md_page_calc_crc(super);
7307 
7308 	dev = init_dev();
7309 	dev->blocklen = 512;
7310 	dev->blockcnt =  DEV_BUFFER_SIZE / dev->blocklen;
7311 
7312 	spdk_bs_load(dev, &bsopts, bs_op_with_handle_complete, NULL);
7313 	poll_threads();
7314 	CU_ASSERT(g_bserrno == 0);
7315 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
7316 	bs = g_bs;
7317 
7318 	CU_ASSERT(spdk_bs_get_io_unit_size(bs) == SPDK_BS_PAGE_SIZE);
7319 
7320 	/* Unload the blob store */
7321 	spdk_bs_unload(bs, bs_op_complete, NULL);
7322 	poll_threads();
7323 	CU_ASSERT(g_bserrno == 0);
7324 
7325 	g_bs = NULL;
7326 	g_blob = NULL;
7327 	g_blobid = 0;
7328 }
7329 
7330 static void
7331 blob_simultaneous_operations(void)
7332 {
7333 	struct spdk_blob_store *bs;
7334 	struct spdk_bs_dev *dev;
7335 	struct spdk_blob_opts opts;
7336 	struct spdk_blob *blob, *snapshot;
7337 	spdk_blob_id blobid, snapshotid;
7338 	struct spdk_io_channel *channel;
7339 
7340 	dev = init_dev();
7341 
7342 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
7343 	poll_threads();
7344 	CU_ASSERT(g_bserrno == 0);
7345 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
7346 	bs = g_bs;
7347 
7348 	channel = spdk_bs_alloc_io_channel(bs);
7349 	SPDK_CU_ASSERT_FATAL(channel != NULL);
7350 
7351 	ut_spdk_blob_opts_init(&opts);
7352 	opts.num_clusters = 10;
7353 
7354 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
7355 	poll_threads();
7356 	CU_ASSERT(g_bserrno == 0);
7357 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
7358 	blobid = g_blobid;
7359 
7360 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
7361 	poll_threads();
7362 	CU_ASSERT(g_bserrno == 0);
7363 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
7364 	blob = g_blob;
7365 
7366 	/* Create snapshot and try to remove blob in the same time:
7367 	 * - snapshot should be created successfully
7368 	 * - delete operation should fail w -EBUSY */
7369 	CU_ASSERT(blob->locked_operation_in_progress == false);
7370 	spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL);
7371 	CU_ASSERT(blob->locked_operation_in_progress == true);
7372 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
7373 	CU_ASSERT(blob->locked_operation_in_progress == true);
7374 	/* Deletion failure */
7375 	CU_ASSERT(g_bserrno == -EBUSY);
7376 	poll_threads();
7377 	CU_ASSERT(blob->locked_operation_in_progress == false);
7378 	/* Snapshot creation success */
7379 	CU_ASSERT(g_bserrno == 0);
7380 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
7381 
7382 	snapshotid = g_blobid;
7383 
7384 	spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL);
7385 	poll_threads();
7386 	CU_ASSERT(g_bserrno == 0);
7387 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
7388 	snapshot = g_blob;
7389 
7390 	/* Inflate blob and try to remove blob in the same time:
7391 	 * - blob should be inflated successfully
7392 	 * - delete operation should fail w -EBUSY */
7393 	CU_ASSERT(blob->locked_operation_in_progress == false);
7394 	spdk_bs_inflate_blob(bs, channel, blobid, blob_op_complete, NULL);
7395 	CU_ASSERT(blob->locked_operation_in_progress == true);
7396 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
7397 	CU_ASSERT(blob->locked_operation_in_progress == true);
7398 	/* Deletion failure */
7399 	CU_ASSERT(g_bserrno == -EBUSY);
7400 	poll_threads();
7401 	CU_ASSERT(blob->locked_operation_in_progress == false);
7402 	/* Inflation success */
7403 	CU_ASSERT(g_bserrno == 0);
7404 
7405 	/* Clone snapshot and try to remove snapshot in the same time:
7406 	 * - snapshot should be cloned successfully
7407 	 * - delete operation should fail w -EBUSY */
7408 	CU_ASSERT(blob->locked_operation_in_progress == false);
7409 	spdk_bs_create_clone(bs, snapshotid, NULL, blob_op_with_id_complete, NULL);
7410 	spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL);
7411 	/* Deletion failure */
7412 	CU_ASSERT(g_bserrno == -EBUSY);
7413 	poll_threads();
7414 	CU_ASSERT(blob->locked_operation_in_progress == false);
7415 	/* Clone created */
7416 	CU_ASSERT(g_bserrno == 0);
7417 
7418 	/* Resize blob and try to remove blob in the same time:
7419 	 * - blob should be resized successfully
7420 	 * - delete operation should fail w -EBUSY */
7421 	CU_ASSERT(blob->locked_operation_in_progress == false);
7422 	spdk_blob_resize(blob, 50, blob_op_complete, NULL);
7423 	CU_ASSERT(blob->locked_operation_in_progress == true);
7424 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
7425 	CU_ASSERT(blob->locked_operation_in_progress == true);
7426 	/* Deletion failure */
7427 	CU_ASSERT(g_bserrno == -EBUSY);
7428 	poll_threads();
7429 	CU_ASSERT(blob->locked_operation_in_progress == false);
7430 	/* Blob resized successfully */
7431 	CU_ASSERT(g_bserrno == 0);
7432 
7433 	/* Issue two consecutive blob syncs, neither should fail.
7434 	 * Force sync to actually occur by marking blob dirty each time.
7435 	 * Execution of sync should not be enough to complete the operation,
7436 	 * since disk I/O is required to complete it. */
7437 	g_bserrno = -1;
7438 
7439 	blob->state = SPDK_BLOB_STATE_DIRTY;
7440 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
7441 	SPDK_CU_ASSERT_FATAL(g_bserrno == -1);
7442 
7443 	blob->state = SPDK_BLOB_STATE_DIRTY;
7444 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
7445 	SPDK_CU_ASSERT_FATAL(g_bserrno == -1);
7446 
7447 	uint32_t completions = 0;
7448 	while (completions < 2) {
7449 		SPDK_CU_ASSERT_FATAL(poll_thread_times(0, 1));
7450 		if (g_bserrno == 0) {
7451 			g_bserrno = -1;
7452 			completions++;
7453 		}
7454 		/* Never should the g_bserrno be other than -1.
7455 		 * It would mean that either of syncs failed. */
7456 		SPDK_CU_ASSERT_FATAL(g_bserrno == -1);
7457 	}
7458 
7459 	spdk_blob_close(blob, blob_op_complete, NULL);
7460 	poll_threads();
7461 	CU_ASSERT(g_bserrno == 0);
7462 
7463 	spdk_blob_close(snapshot, blob_op_complete, NULL);
7464 	poll_threads();
7465 	CU_ASSERT(g_bserrno == 0);
7466 
7467 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
7468 	poll_threads();
7469 	CU_ASSERT(g_bserrno == 0);
7470 
7471 	spdk_bs_unload(bs, bs_op_complete, NULL);
7472 	poll_threads();
7473 	CU_ASSERT(g_bserrno == 0);
7474 	g_bs = NULL;
7475 
7476 	spdk_bs_free_io_channel(channel);
7477 	poll_threads();
7478 }
7479 
7480 static void
7481 blob_persist(void)
7482 {
7483 	struct spdk_blob_store *bs;
7484 	struct spdk_bs_dev *dev;
7485 	struct spdk_blob_opts opts;
7486 	struct spdk_blob *blob;
7487 	spdk_blob_id blobid;
7488 	struct spdk_io_channel *channel;
7489 	char *xattr;
7490 	size_t xattr_length;
7491 	int rc;
7492 	uint32_t page_count_clear, page_count_xattr;
7493 	uint64_t poller_iterations;
7494 	bool run_poller;
7495 
7496 	dev = init_dev();
7497 
7498 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
7499 	poll_threads();
7500 	CU_ASSERT(g_bserrno == 0);
7501 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
7502 	bs = g_bs;
7503 
7504 	channel = spdk_bs_alloc_io_channel(bs);
7505 	SPDK_CU_ASSERT_FATAL(channel != NULL);
7506 
7507 	ut_spdk_blob_opts_init(&opts);
7508 	opts.num_clusters = 10;
7509 
7510 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
7511 	poll_threads();
7512 	CU_ASSERT(g_bserrno == 0);
7513 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
7514 	blobid = g_blobid;
7515 
7516 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
7517 	poll_threads();
7518 	CU_ASSERT(g_bserrno == 0);
7519 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
7520 	blob = g_blob;
7521 
7522 	/* Save the amount of md pages used after creation of a blob.
7523 	 * This should be consistent after removing xattr. */
7524 	page_count_clear = spdk_bit_array_count_set(bs->used_md_pages);
7525 	SPDK_CU_ASSERT_FATAL(blob->active.num_pages + blob->active.num_extent_pages == page_count_clear);
7526 	SPDK_CU_ASSERT_FATAL(blob->clean.num_pages + blob->clean.num_extent_pages == page_count_clear);
7527 
7528 	/* Add xattr with maximum length of descriptor to exceed single metadata page. */
7529 	xattr_length = SPDK_BS_MAX_DESC_SIZE - sizeof(struct spdk_blob_md_descriptor_xattr) -
7530 		       strlen("large_xattr");
7531 	xattr = calloc(xattr_length, sizeof(char));
7532 	SPDK_CU_ASSERT_FATAL(xattr != NULL);
7533 
7534 	rc = spdk_blob_set_xattr(blob, "large_xattr", xattr, xattr_length);
7535 	SPDK_CU_ASSERT_FATAL(rc == 0);
7536 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
7537 	poll_threads();
7538 	SPDK_CU_ASSERT_FATAL(g_bserrno == 0);
7539 
7540 	/* Save the amount of md pages used after adding the large xattr */
7541 	page_count_xattr = spdk_bit_array_count_set(bs->used_md_pages);
7542 	SPDK_CU_ASSERT_FATAL(blob->active.num_pages + blob->active.num_extent_pages == page_count_xattr);
7543 	SPDK_CU_ASSERT_FATAL(blob->clean.num_pages + blob->clean.num_extent_pages == page_count_xattr);
7544 
7545 	/* Add xattr to a blob and sync it. While sync is occuring, remove the xattr and sync again.
7546 	 * Interrupt the first sync after increasing number of poller iterations, until it succeeds.
7547 	 * Expectation is that after second sync completes no xattr is saved in metadata. */
7548 	poller_iterations = 1;
7549 	run_poller = true;
7550 	while (run_poller) {
7551 		rc = spdk_blob_set_xattr(blob, "large_xattr", xattr, xattr_length);
7552 		SPDK_CU_ASSERT_FATAL(rc == 0);
7553 		g_bserrno = -1;
7554 		spdk_blob_sync_md(blob, blob_op_complete, NULL);
7555 		poll_thread_times(0, poller_iterations);
7556 		if (g_bserrno == 0) {
7557 			/* Poller iteration count was high enough for first sync to complete.
7558 			 * Verify that blob takes up enough of md_pages to store the xattr. */
7559 			SPDK_CU_ASSERT_FATAL(blob->active.num_pages + blob->active.num_extent_pages == page_count_xattr);
7560 			SPDK_CU_ASSERT_FATAL(blob->clean.num_pages + blob->clean.num_extent_pages == page_count_xattr);
7561 			SPDK_CU_ASSERT_FATAL(spdk_bit_array_count_set(bs->used_md_pages) == page_count_xattr);
7562 			run_poller = false;
7563 		}
7564 		rc = spdk_blob_remove_xattr(blob, "large_xattr");
7565 		SPDK_CU_ASSERT_FATAL(rc == 0);
7566 		spdk_blob_sync_md(blob, blob_op_complete, NULL);
7567 		poll_threads();
7568 		SPDK_CU_ASSERT_FATAL(g_bserrno == 0);
7569 		SPDK_CU_ASSERT_FATAL(blob->active.num_pages + blob->active.num_extent_pages == page_count_clear);
7570 		SPDK_CU_ASSERT_FATAL(blob->clean.num_pages + blob->clean.num_extent_pages == page_count_clear);
7571 		SPDK_CU_ASSERT_FATAL(spdk_bit_array_count_set(bs->used_md_pages) == page_count_clear);
7572 
7573 		/* Reload bs and re-open blob to verify that xattr was not persisted. */
7574 		spdk_blob_close(blob, blob_op_complete, NULL);
7575 		poll_threads();
7576 		CU_ASSERT(g_bserrno == 0);
7577 
7578 		ut_bs_reload(&bs, NULL);
7579 
7580 		spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
7581 		poll_threads();
7582 		CU_ASSERT(g_bserrno == 0);
7583 		SPDK_CU_ASSERT_FATAL(g_blob != NULL);
7584 		blob = g_blob;
7585 
7586 		rc = spdk_blob_get_xattr_value(blob, "large_xattr", (const void **)&xattr, &xattr_length);
7587 		SPDK_CU_ASSERT_FATAL(rc == -ENOENT);
7588 
7589 		poller_iterations++;
7590 		/* Stop at high iteration count to prevent infinite loop.
7591 		 * This value should be enough for first md sync to complete in any case. */
7592 		SPDK_CU_ASSERT_FATAL(poller_iterations < 50);
7593 	}
7594 
7595 	free(xattr);
7596 
7597 	spdk_blob_close(blob, blob_op_complete, NULL);
7598 	poll_threads();
7599 	CU_ASSERT(g_bserrno == 0);
7600 
7601 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
7602 	poll_threads();
7603 	CU_ASSERT(g_bserrno == 0);
7604 
7605 	spdk_bs_unload(bs, bs_op_complete, NULL);
7606 	poll_threads();
7607 	CU_ASSERT(g_bserrno == 0);
7608 	g_bs = NULL;
7609 
7610 	spdk_bs_free_io_channel(channel);
7611 	poll_threads();
7612 }
7613 
7614 int main(int argc, char **argv)
7615 {
7616 	CU_pSuite	suite = NULL;
7617 	unsigned int	num_failures;
7618 
7619 	CU_set_error_action(CUEA_ABORT);
7620 	CU_initialize_registry();
7621 
7622 	suite = CU_add_suite("blob", NULL, NULL);
7623 
7624 	CU_ADD_TEST(suite, blob_init);
7625 	CU_ADD_TEST(suite, blob_open);
7626 	CU_ADD_TEST(suite, blob_create);
7627 	CU_ADD_TEST(suite, blob_create_internal);
7628 	CU_ADD_TEST(suite, blob_thin_provision);
7629 	CU_ADD_TEST(suite, blob_snapshot);
7630 	CU_ADD_TEST(suite, blob_clone);
7631 	CU_ADD_TEST(suite, blob_inflate);
7632 	CU_ADD_TEST(suite, blob_delete);
7633 	CU_ADD_TEST(suite, blob_resize);
7634 	CU_ADD_TEST(suite, blob_read_only);
7635 	CU_ADD_TEST(suite, channel_ops);
7636 	CU_ADD_TEST(suite, blob_super);
7637 	CU_ADD_TEST(suite, blob_write);
7638 	CU_ADD_TEST(suite, blob_read);
7639 	CU_ADD_TEST(suite, blob_rw_verify);
7640 	CU_ADD_TEST(suite, blob_rw_verify_iov);
7641 	CU_ADD_TEST(suite, blob_rw_verify_iov_nomem);
7642 	CU_ADD_TEST(suite, blob_rw_iov_read_only);
7643 	CU_ADD_TEST(suite, blob_unmap);
7644 	CU_ADD_TEST(suite, blob_iter);
7645 	CU_ADD_TEST(suite, blob_xattr);
7646 	CU_ADD_TEST(suite, bs_load);
7647 	CU_ADD_TEST(suite, bs_load_pending_removal);
7648 	CU_ADD_TEST(suite, bs_load_custom_cluster_size);
7649 	CU_ADD_TEST(suite, bs_unload);
7650 	CU_ADD_TEST(suite, bs_cluster_sz);
7651 	CU_ADD_TEST(suite, bs_usable_clusters);
7652 	CU_ADD_TEST(suite, bs_resize_md);
7653 	CU_ADD_TEST(suite, bs_destroy);
7654 	CU_ADD_TEST(suite, bs_type);
7655 	CU_ADD_TEST(suite, bs_super_block);
7656 	CU_ADD_TEST(suite, blob_serialize);
7657 	CU_ADD_TEST(suite, blob_crc);
7658 	CU_ADD_TEST(suite, super_block_crc);
7659 	CU_ADD_TEST(suite, blob_dirty_shutdown);
7660 	CU_ADD_TEST(suite, blob_flags);
7661 	CU_ADD_TEST(suite, bs_version);
7662 	CU_ADD_TEST(suite, blob_set_xattrs);
7663 	CU_ADD_TEST(suite, blob_thin_prov_alloc);
7664 	CU_ADD_TEST(suite, blob_insert_cluster_msg);
7665 	CU_ADD_TEST(suite, blob_thin_prov_rw);
7666 	CU_ADD_TEST(suite, blob_thin_prov_rle);
7667 	CU_ADD_TEST(suite, blob_thin_prov_rw_iov);
7668 	CU_ADD_TEST(suite, bs_load_iter);
7669 	CU_ADD_TEST(suite, blob_snapshot_rw);
7670 	CU_ADD_TEST(suite, blob_snapshot_rw_iov);
7671 	CU_ADD_TEST(suite, blob_relations);
7672 	CU_ADD_TEST(suite, blob_relations2);
7673 	CU_ADD_TEST(suite, blob_delete_snapshot_power_failure);
7674 	CU_ADD_TEST(suite, blob_create_snapshot_power_failure);
7675 	CU_ADD_TEST(suite, blob_inflate_rw);
7676 	CU_ADD_TEST(suite, blob_snapshot_freeze_io);
7677 	CU_ADD_TEST(suite, blob_operation_split_rw);
7678 	CU_ADD_TEST(suite, blob_operation_split_rw_iov);
7679 	CU_ADD_TEST(suite, blob_io_unit);
7680 	CU_ADD_TEST(suite, blob_io_unit_compatiblity);
7681 	CU_ADD_TEST(suite, blob_simultaneous_operations);
7682 	CU_ADD_TEST(suite, blob_persist);
7683 
7684 	allocate_threads(2);
7685 	set_thread(0);
7686 
7687 	g_dev_buffer = calloc(1, DEV_BUFFER_SIZE);
7688 
7689 	CU_basic_set_mode(CU_BRM_VERBOSE);
7690 	g_use_extent_table = false;
7691 	CU_basic_run_tests();
7692 	num_failures = CU_get_number_of_failures();
7693 	g_use_extent_table = true;
7694 	CU_basic_run_tests();
7695 	num_failures += CU_get_number_of_failures();
7696 	CU_cleanup_registry();
7697 
7698 	free(g_dev_buffer);
7699 
7700 	free_threads();
7701 
7702 	return num_failures;
7703 }
7704