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