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