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