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