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