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