xref: /spdk/test/unit/lib/blob/blob.c/blob_ut.c (revision 62db4ac2cfb386a962d3c1d9d066b1bcc609073a)
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/test_env.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 
82 static void
83 _get_xattr_value(void *arg, const char *name,
84 		 const void **value, size_t *value_len)
85 {
86 	uint64_t i;
87 
88 	SPDK_CU_ASSERT_FATAL(value_len != NULL);
89 	SPDK_CU_ASSERT_FATAL(value != NULL);
90 	CU_ASSERT(arg == &g_ctx)
91 
92 	for (i = 0; i < sizeof(g_xattr_names); i++) {
93 		if (!strcmp(name, g_xattr_names[i])) {
94 			*value_len = strlen(g_xattr_values[i]);
95 			*value = g_xattr_values[i];
96 			break;
97 		}
98 	}
99 }
100 
101 static void
102 _get_xattr_value_null(void *arg, const char *name,
103 		      const void **value, size_t *value_len)
104 {
105 	SPDK_CU_ASSERT_FATAL(value_len != NULL);
106 	SPDK_CU_ASSERT_FATAL(value != NULL);
107 	CU_ASSERT(arg == NULL)
108 
109 	*value_len = 0;
110 	*value = NULL;
111 }
112 
113 static int
114 _get_snapshots_count(struct spdk_blob_store *bs)
115 {
116 	struct spdk_blob_list *snapshot = NULL;
117 	int count = 0;
118 
119 	TAILQ_FOREACH(snapshot, &bs->snapshots, link) {
120 		count += 1;
121 	}
122 
123 	return count;
124 }
125 
126 static void
127 bs_op_complete(void *cb_arg, int bserrno)
128 {
129 	g_bserrno = bserrno;
130 }
131 
132 static void
133 bs_op_with_handle_complete(void *cb_arg, struct spdk_blob_store *bs,
134 			   int bserrno)
135 {
136 	g_bs = bs;
137 	g_bserrno = bserrno;
138 }
139 
140 static void
141 blob_op_complete(void *cb_arg, int bserrno)
142 {
143 	g_bserrno = bserrno;
144 }
145 
146 static void
147 blob_op_with_id_complete(void *cb_arg, spdk_blob_id blobid, int bserrno)
148 {
149 	g_blobid = blobid;
150 	g_bserrno = bserrno;
151 }
152 
153 static void
154 blob_op_with_handle_complete(void *cb_arg, struct spdk_blob *blb, int bserrno)
155 {
156 	g_blob = blb;
157 	g_bserrno = bserrno;
158 }
159 
160 static void
161 blob_init(void)
162 {
163 	struct spdk_bs_dev *dev;
164 
165 	dev = init_dev();
166 
167 	/* should fail for an unsupported blocklen */
168 	dev->blocklen = 500;
169 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
170 	CU_ASSERT(g_bserrno == -EINVAL);
171 
172 	dev = init_dev();
173 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
174 	CU_ASSERT(g_bserrno == 0);
175 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
176 
177 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
178 	CU_ASSERT(g_bserrno == 0);
179 	g_bs = NULL;
180 }
181 
182 static void
183 blob_super(void)
184 {
185 	struct spdk_blob_store *bs;
186 	struct spdk_bs_dev *dev;
187 	spdk_blob_id blobid;
188 
189 	dev = init_dev();
190 
191 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
192 	CU_ASSERT(g_bserrno == 0);
193 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
194 	bs = g_bs;
195 
196 	/* Get the super blob without having set one */
197 	spdk_bs_get_super(bs, blob_op_with_id_complete, NULL);
198 	CU_ASSERT(g_bserrno == -ENOENT);
199 	CU_ASSERT(g_blobid == SPDK_BLOBID_INVALID);
200 
201 	/* Create a blob */
202 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
203 	CU_ASSERT(g_bserrno == 0);
204 	CU_ASSERT(g_blobid !=  SPDK_BLOBID_INVALID);
205 	blobid = g_blobid;
206 
207 	/* Set the blob as the super blob */
208 	spdk_bs_set_super(bs, blobid, blob_op_complete, NULL);
209 	CU_ASSERT(g_bserrno == 0);
210 
211 	/* Get the super blob */
212 	spdk_bs_get_super(bs, blob_op_with_id_complete, NULL);
213 	CU_ASSERT(g_bserrno == 0);
214 	CU_ASSERT(blobid == g_blobid);
215 
216 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
217 	CU_ASSERT(g_bserrno == 0);
218 	g_bs = NULL;
219 }
220 
221 static void
222 blob_open(void)
223 {
224 	struct spdk_blob_store *bs;
225 	struct spdk_bs_dev *dev;
226 	struct spdk_blob *blob;
227 	spdk_blob_id blobid, blobid2;
228 
229 	dev = init_dev();
230 
231 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
232 	CU_ASSERT(g_bserrno == 0);
233 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
234 	bs = g_bs;
235 
236 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
237 	CU_ASSERT(g_bserrno == 0);
238 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
239 	blobid = g_blobid;
240 
241 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
242 	CU_ASSERT(g_bserrno == 0);
243 	CU_ASSERT(g_blob != NULL);
244 	blob = g_blob;
245 
246 	blobid2 = spdk_blob_get_id(blob);
247 	CU_ASSERT(blobid == blobid2);
248 
249 	/* Try to open file again.  It should return success. */
250 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
251 	CU_ASSERT(g_bserrno == 0);
252 	CU_ASSERT(blob == g_blob);
253 
254 	spdk_blob_close(blob, blob_op_complete, NULL);
255 	CU_ASSERT(g_bserrno == 0);
256 
257 	/*
258 	 * Close the file a second time, releasing the second reference.  This
259 	 *  should succeed.
260 	 */
261 	blob = g_blob;
262 	spdk_blob_close(blob, blob_op_complete, NULL);
263 	CU_ASSERT(g_bserrno == 0);
264 
265 	/*
266 	 * Try to open file again.  It should succeed.  This tests the case
267 	 *  where the file is opened, closed, then re-opened again.
268 	 */
269 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
270 	CU_ASSERT(g_bserrno == 0);
271 	CU_ASSERT(g_blob != NULL);
272 	blob = g_blob;
273 
274 	spdk_blob_close(blob, blob_op_complete, NULL);
275 	CU_ASSERT(g_bserrno == 0);
276 
277 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
278 	CU_ASSERT(g_bserrno == 0);
279 	g_bs = NULL;
280 }
281 
282 static void
283 blob_create(void)
284 {
285 	struct spdk_blob_store *bs;
286 	struct spdk_bs_dev *dev;
287 	struct spdk_blob *blob;
288 	struct spdk_blob_opts opts;
289 	spdk_blob_id blobid;
290 
291 	dev = init_dev();
292 
293 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
294 	CU_ASSERT(g_bserrno == 0);
295 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
296 	bs = g_bs;
297 
298 	/* Create blob with 10 clusters */
299 
300 	spdk_blob_opts_init(&opts);
301 	opts.num_clusters = 10;
302 
303 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
304 	CU_ASSERT(g_bserrno == 0);
305 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
306 	blobid = g_blobid;
307 
308 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
309 	CU_ASSERT(g_bserrno == 0);
310 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
311 	blob = g_blob;
312 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10)
313 
314 	spdk_blob_close(blob, blob_op_complete, NULL);
315 	CU_ASSERT(g_bserrno == 0);
316 
317 	/* Create blob with 0 clusters */
318 
319 	spdk_blob_opts_init(&opts);
320 	opts.num_clusters = 0;
321 
322 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
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 	CU_ASSERT(g_bserrno == 0);
329 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
330 	blob = g_blob;
331 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0)
332 
333 	spdk_blob_close(blob, blob_op_complete, NULL);
334 	CU_ASSERT(g_bserrno == 0);
335 
336 	/* Create blob with default options (opts == NULL) */
337 
338 	spdk_bs_create_blob_ext(bs, NULL, blob_op_with_id_complete, NULL);
339 	CU_ASSERT(g_bserrno == 0);
340 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
341 	blobid = g_blobid;
342 
343 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
344 	CU_ASSERT(g_bserrno == 0);
345 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
346 	blob = g_blob;
347 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0)
348 
349 	spdk_blob_close(blob, blob_op_complete, NULL);
350 	CU_ASSERT(g_bserrno == 0);
351 
352 	/* Try to create blob with size larger than blobstore */
353 
354 	spdk_blob_opts_init(&opts);
355 	opts.num_clusters = bs->total_clusters + 1;
356 
357 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
358 	CU_ASSERT(g_bserrno == -ENOSPC);
359 
360 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
361 	CU_ASSERT(g_bserrno == 0);
362 	g_bs = NULL;
363 
364 }
365 
366 static void
367 blob_create_internal(void)
368 {
369 	struct spdk_blob_store *bs;
370 	struct spdk_bs_dev *dev;
371 	struct spdk_blob *blob;
372 	struct spdk_blob_opts opts;
373 	struct spdk_blob_xattr_opts internal_xattrs;
374 	const void *value;
375 	size_t value_len;
376 	spdk_blob_id blobid;
377 	int rc;
378 
379 	dev = init_dev();
380 
381 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
382 	CU_ASSERT(g_bserrno == 0);
383 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
384 	bs = g_bs;
385 
386 	/* Create blob with custom xattrs */
387 
388 	spdk_blob_opts_init(&opts);
389 	_spdk_blob_xattrs_init(&internal_xattrs);
390 	internal_xattrs.count = 3;
391 	internal_xattrs.names = g_xattr_names;
392 	internal_xattrs.get_value = _get_xattr_value;
393 	internal_xattrs.ctx = &g_ctx;
394 
395 	_spdk_bs_create_blob(bs, &opts, &internal_xattrs, blob_op_with_id_complete, NULL);
396 	CU_ASSERT(g_bserrno == 0);
397 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
398 	blobid = g_blobid;
399 
400 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
401 	CU_ASSERT(g_bserrno == 0);
402 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
403 	blob = g_blob;
404 
405 	rc = _spdk_blob_get_xattr_value(blob, g_xattr_names[0], &value, &value_len, true);
406 	CU_ASSERT(rc == 0);
407 	SPDK_CU_ASSERT_FATAL(value != NULL);
408 	CU_ASSERT(value_len == strlen(g_xattr_values[0]));
409 	CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len);
410 
411 	rc = _spdk_blob_get_xattr_value(blob, g_xattr_names[1], &value, &value_len, true);
412 	CU_ASSERT(rc == 0);
413 	SPDK_CU_ASSERT_FATAL(value != NULL);
414 	CU_ASSERT(value_len == strlen(g_xattr_values[1]));
415 	CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len);
416 
417 	rc = _spdk_blob_get_xattr_value(blob, g_xattr_names[2], &value, &value_len, true);
418 	CU_ASSERT(rc == 0);
419 	SPDK_CU_ASSERT_FATAL(value != NULL);
420 	CU_ASSERT(value_len == strlen(g_xattr_values[2]));
421 	CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len);
422 
423 	rc = spdk_blob_get_xattr_value(blob, g_xattr_names[0], &value, &value_len);
424 	CU_ASSERT(rc != 0);
425 
426 	rc = spdk_blob_get_xattr_value(blob, g_xattr_names[1], &value, &value_len);
427 	CU_ASSERT(rc != 0);
428 
429 	rc = spdk_blob_get_xattr_value(blob, g_xattr_names[2], &value, &value_len);
430 	CU_ASSERT(rc != 0);
431 
432 	spdk_blob_close(blob, blob_op_complete, NULL);
433 	CU_ASSERT(g_bserrno == 0);
434 
435 	/* Create blob with NULL internal options  */
436 
437 	_spdk_bs_create_blob(bs, NULL, NULL, blob_op_with_id_complete, NULL);
438 	CU_ASSERT(g_bserrno == 0);
439 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
440 	blobid = g_blobid;
441 
442 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
443 	CU_ASSERT(g_bserrno == 0);
444 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
445 	CU_ASSERT(TAILQ_FIRST(&g_blob->xattrs_internal) == NULL);
446 
447 	blob = g_blob;
448 
449 	spdk_blob_close(blob, blob_op_complete, NULL);
450 	CU_ASSERT(g_bserrno == 0);
451 
452 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
453 	CU_ASSERT(g_bserrno == 0);
454 	g_bs = NULL;
455 
456 }
457 
458 static void
459 blob_thin_provision(void)
460 {
461 	struct spdk_blob_store *bs;
462 	struct spdk_bs_dev *dev;
463 	struct spdk_blob *blob;
464 	struct spdk_blob_opts opts;
465 	struct spdk_bs_opts bs_opts;
466 	spdk_blob_id blobid;
467 
468 	dev = init_dev();
469 	spdk_bs_opts_init(&bs_opts);
470 	snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE");
471 
472 	/* Initialize a new blob store */
473 	spdk_bs_init(dev, &bs_opts, bs_op_with_handle_complete, NULL);
474 	CU_ASSERT(g_bserrno == 0);
475 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
476 
477 	bs = g_bs;
478 
479 	/* Create blob with thin provisioning enabled */
480 
481 	spdk_blob_opts_init(&opts);
482 	opts.thin_provision = true;
483 	opts.num_clusters = 10;
484 
485 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
486 	CU_ASSERT(g_bserrno == 0);
487 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
488 	blobid = g_blobid;
489 
490 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
491 	CU_ASSERT(g_bserrno == 0);
492 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
493 	blob = g_blob;
494 	CU_ASSERT(blob->invalid_flags & SPDK_BLOB_THIN_PROV);
495 
496 	spdk_blob_close(blob, blob_op_complete, NULL);
497 	CU_ASSERT(g_bserrno == 0);
498 
499 	/* Do not shut down cleanly.  This makes sure that when we load again
500 	 *  and try to recover a valid used_cluster map, that blobstore will
501 	 *  ignore clusters with index 0 since these are unallocated clusters.
502 	 */
503 
504 	/* Load an existing blob store and check if invalid_flags is set */
505 	dev = init_dev();
506 	snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE");
507 	spdk_bs_load(dev, &bs_opts, bs_op_with_handle_complete, NULL);
508 	CU_ASSERT(g_bserrno == 0);
509 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
510 
511 	bs = g_bs;
512 
513 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
514 	CU_ASSERT(g_bserrno == 0);
515 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
516 	blob = g_blob;
517 	CU_ASSERT(blob->invalid_flags & SPDK_BLOB_THIN_PROV);
518 
519 	spdk_blob_close(blob, blob_op_complete, NULL);
520 	CU_ASSERT(g_bserrno == 0);
521 
522 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
523 	CU_ASSERT(g_bserrno == 0);
524 	g_bs = NULL;
525 }
526 
527 static void
528 blob_snapshot(void)
529 {
530 	struct spdk_blob_store *bs;
531 	struct spdk_bs_dev *dev;
532 	struct spdk_blob *blob;
533 	struct spdk_blob *snapshot, *snapshot2;
534 	struct spdk_blob_bs_dev *blob_bs_dev;
535 	struct spdk_blob_opts opts;
536 	struct spdk_blob_xattr_opts xattrs;
537 	spdk_blob_id blobid;
538 	spdk_blob_id snapshotid;
539 	spdk_blob_id snapshotid2;
540 	const void *value;
541 	size_t value_len;
542 	int rc;
543 
544 	dev = init_dev();
545 
546 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
547 	CU_ASSERT(g_bserrno == 0);
548 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
549 	bs = g_bs;
550 
551 	/* Create blob with 10 clusters */
552 	spdk_blob_opts_init(&opts);
553 	opts.num_clusters = 10;
554 
555 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
556 	CU_ASSERT(g_bserrno == 0);
557 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
558 	blobid = g_blobid;
559 
560 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
561 	CU_ASSERT(g_bserrno == 0);
562 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
563 	blob = g_blob;
564 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10)
565 
566 	/* Create snapshot from blob */
567 	CU_ASSERT_EQUAL(_get_snapshots_count(bs), 0);
568 	spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL);
569 	CU_ASSERT(g_bserrno == 0);
570 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
571 	CU_ASSERT_EQUAL(_get_snapshots_count(bs), 1);
572 	snapshotid = g_blobid;
573 
574 	spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL);
575 	CU_ASSERT(g_bserrno == 0);
576 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
577 	snapshot = g_blob;
578 	CU_ASSERT(snapshot->data_ro == true)
579 	CU_ASSERT(snapshot->md_ro == true)
580 	CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 10)
581 
582 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10)
583 	CU_ASSERT(blob->invalid_flags & SPDK_BLOB_THIN_PROV);
584 	CU_ASSERT(spdk_mem_all_zero(blob->active.clusters,
585 				    blob->active.num_clusters * sizeof(blob->active.clusters[0])));
586 
587 	/* Try to create snapshot from clone with xattrs */
588 	xattrs.names = g_xattr_names;
589 	xattrs.get_value = _get_xattr_value;
590 	xattrs.count = 3;
591 	xattrs.ctx = &g_ctx;
592 	spdk_bs_create_snapshot(bs, blobid, &xattrs, blob_op_with_id_complete, NULL);
593 	CU_ASSERT(g_bserrno == 0);
594 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
595 	CU_ASSERT_EQUAL(_get_snapshots_count(bs), 2);
596 	snapshotid2 = g_blobid;
597 
598 	spdk_bs_open_blob(bs, snapshotid2, blob_op_with_handle_complete, NULL);
599 	CU_ASSERT(g_bserrno == 0);
600 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
601 	snapshot2 = g_blob;
602 	CU_ASSERT(snapshot2->data_ro == true)
603 	CU_ASSERT(snapshot2->md_ro == true)
604 	CU_ASSERT(spdk_blob_get_num_clusters(snapshot2) == 10)
605 
606 	/* Confirm that blob is backed by snapshot2 and snapshot2 is backed by snapshot */
607 	CU_ASSERT(snapshot->back_bs_dev == NULL);
608 	SPDK_CU_ASSERT_FATAL(blob->back_bs_dev != NULL);
609 	SPDK_CU_ASSERT_FATAL(snapshot2->back_bs_dev != NULL);
610 
611 	blob_bs_dev = (struct spdk_blob_bs_dev *)blob->back_bs_dev;
612 	CU_ASSERT(blob_bs_dev->blob == snapshot2);
613 
614 	blob_bs_dev = (struct spdk_blob_bs_dev *)snapshot2->back_bs_dev;
615 	CU_ASSERT(blob_bs_dev->blob == snapshot);
616 
617 	rc = spdk_blob_get_xattr_value(snapshot2, g_xattr_names[0], &value, &value_len);
618 	CU_ASSERT(rc == 0);
619 	SPDK_CU_ASSERT_FATAL(value != NULL);
620 	CU_ASSERT(value_len == strlen(g_xattr_values[0]));
621 	CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len);
622 
623 	rc = spdk_blob_get_xattr_value(snapshot2, g_xattr_names[1], &value, &value_len);
624 	CU_ASSERT(rc == 0);
625 	SPDK_CU_ASSERT_FATAL(value != NULL);
626 	CU_ASSERT(value_len == strlen(g_xattr_values[1]));
627 	CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len);
628 
629 	rc = spdk_blob_get_xattr_value(snapshot2, g_xattr_names[2], &value, &value_len);
630 	CU_ASSERT(rc == 0);
631 	SPDK_CU_ASSERT_FATAL(value != NULL);
632 	CU_ASSERT(value_len == strlen(g_xattr_values[2]));
633 	CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len);
634 
635 	/* Try to create snapshot from snapshot */
636 	spdk_bs_create_snapshot(bs, snapshotid, NULL, blob_op_with_id_complete, NULL);
637 	CU_ASSERT(g_bserrno == -EINVAL);
638 	CU_ASSERT(g_blobid == SPDK_BLOBID_INVALID);
639 	CU_ASSERT_EQUAL(_get_snapshots_count(bs), 2);
640 
641 	spdk_blob_close(blob, blob_op_complete, NULL);
642 	CU_ASSERT(g_bserrno == 0);
643 
644 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
645 	CU_ASSERT(g_bserrno == 0);
646 	CU_ASSERT_EQUAL(_get_snapshots_count(bs), 2);
647 
648 	spdk_blob_close(snapshot2, blob_op_complete, NULL);
649 	CU_ASSERT(g_bserrno == 0);
650 
651 	spdk_bs_delete_blob(bs, snapshotid2, blob_op_complete, NULL);
652 	CU_ASSERT(g_bserrno == 0);
653 	CU_ASSERT_EQUAL(_get_snapshots_count(bs), 1);
654 
655 	spdk_blob_close(snapshot, blob_op_complete, NULL);
656 	CU_ASSERT(g_bserrno == 0);
657 
658 	spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL);
659 	CU_ASSERT(g_bserrno == 0);
660 	CU_ASSERT_EQUAL(_get_snapshots_count(bs), 0);
661 
662 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
663 	CU_ASSERT(g_bserrno == 0);
664 	g_bs = NULL;
665 }
666 
667 static void
668 blob_snapshot_freeze_io(void)
669 {
670 	struct spdk_io_channel *channel;
671 	struct spdk_bs_channel *bs_channel;
672 	struct spdk_blob_store *bs;
673 	struct spdk_bs_dev *dev;
674 	struct spdk_blob *blob;
675 	struct spdk_blob_opts opts;
676 	spdk_blob_id blobid;
677 	uint32_t num_of_pages = 10;
678 	uint8_t payload_read[num_of_pages * SPDK_BS_PAGE_SIZE];
679 	uint8_t payload_write[num_of_pages * SPDK_BS_PAGE_SIZE];
680 	uint8_t payload_zero[num_of_pages * SPDK_BS_PAGE_SIZE];
681 
682 	memset(payload_write, 0xE5, sizeof(payload_write));
683 	memset(payload_read, 0x00, sizeof(payload_read));
684 	memset(payload_zero, 0x00, sizeof(payload_zero));
685 
686 	dev = init_dev();
687 	memset(g_dev_buffer, 0, DEV_BUFFER_SIZE);
688 
689 	/* Test freeze I/O during snapshot */
690 
691 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
692 	CU_ASSERT(g_bserrno == 0);
693 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
694 	bs = g_bs;
695 
696 	channel = spdk_bs_alloc_io_channel(bs);
697 	bs_channel = spdk_io_channel_get_ctx(channel);
698 
699 	/* Create blob with 10 clusters */
700 	spdk_blob_opts_init(&opts);
701 	opts.num_clusters = 10;
702 	opts.thin_provision = false;
703 
704 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
705 	CU_ASSERT(g_bserrno == 0);
706 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
707 	blobid = g_blobid;
708 
709 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
710 	CU_ASSERT(g_bserrno == 0);
711 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
712 	blob = g_blob;
713 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10);
714 
715 	/* Enable explicitly calling callbacks. On each read/write to back device
716 	 * execution will stop and wait until _bs_flush_scheduler is called */
717 	g_scheduler_delay = true;
718 
719 	spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL);
720 
721 	/* This is implementation specific.
722 	 * Flag 'frozen_io' is set in _spdk_bs_snapshot_freeze_cpl callback.
723 	 * Four async I/O operations happen before that. */
724 
725 	_bs_flush_scheduler(4);
726 
727 	CU_ASSERT(TAILQ_EMPTY(&bs_channel->queued_io));
728 
729 	/* Blob I/O should be frozen here */
730 	CU_ASSERT(blob->frozen_refcnt == 1);
731 
732 	/* Write to the blob */
733 	spdk_blob_io_write(blob, channel, payload_write, 0, num_of_pages, blob_op_complete, NULL);
734 
735 	/* Verify that I/O is queued */
736 	CU_ASSERT(!TAILQ_EMPTY(&bs_channel->queued_io));
737 	/* Verify that payload is not written to disk */
738 	CU_ASSERT(memcmp(payload_zero, &g_dev_buffer[blob->active.clusters[0]*SPDK_BS_PAGE_SIZE],
739 			 SPDK_BS_PAGE_SIZE) == 0);
740 
741 	/* Disable scheduler delay.
742 	 * Finish all operations including spdk_bs_create_snapshot */
743 	g_scheduler_delay = false;
744 	_bs_flush_scheduler(1);
745 
746 	/* Verify snapshot */
747 	CU_ASSERT(g_bserrno == 0);
748 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
749 
750 	/* Verify that blob has unset frozen_io */
751 	CU_ASSERT(blob->frozen_refcnt == 0);
752 
753 	/* Verify that postponed I/O completed successfully by comparing payload */
754 	spdk_blob_io_read(blob, channel, payload_read, 0, num_of_pages, blob_op_complete, NULL);
755 	CU_ASSERT(g_bserrno == 0);
756 	CU_ASSERT(memcmp(payload_write, payload_read, num_of_pages * SPDK_BS_PAGE_SIZE) == 0);
757 
758 	spdk_blob_close(blob, blob_op_complete, NULL);
759 	CU_ASSERT(g_bserrno == 0);
760 
761 	spdk_bs_free_io_channel(channel);
762 
763 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
764 	CU_ASSERT(g_bserrno == 0);
765 	g_bs = NULL;
766 }
767 
768 static void
769 blob_clone(void)
770 {
771 	struct spdk_blob_store *bs;
772 	struct spdk_bs_dev *dev;
773 	struct spdk_blob_opts opts;
774 	struct spdk_blob *blob, *snapshot, *clone;
775 	spdk_blob_id blobid, cloneid, snapshotid;
776 	struct spdk_blob_xattr_opts xattrs;
777 	const void *value;
778 	size_t value_len;
779 	int rc;
780 
781 	dev = init_dev();
782 
783 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
784 	CU_ASSERT(g_bserrno == 0);
785 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
786 	bs = g_bs;
787 
788 	/* Create blob with 10 clusters */
789 
790 	spdk_blob_opts_init(&opts);
791 	opts.num_clusters = 10;
792 
793 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
794 	CU_ASSERT(g_bserrno == 0);
795 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
796 	blobid = g_blobid;
797 
798 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
799 	CU_ASSERT(g_bserrno == 0);
800 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
801 	blob = g_blob;
802 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10)
803 
804 	/* Create snapshot */
805 	spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL);
806 	CU_ASSERT(g_bserrno == 0);
807 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
808 	snapshotid = g_blobid;
809 
810 	spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL);
811 	CU_ASSERT(g_bserrno == 0);
812 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
813 	snapshot = g_blob;
814 	CU_ASSERT(snapshot->data_ro == true)
815 	CU_ASSERT(snapshot->md_ro == true)
816 	CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 10);
817 
818 	spdk_blob_close(snapshot, blob_op_complete, NULL);
819 	CU_ASSERT(g_bserrno == 0);
820 
821 	/* Create clone from snapshot with xattrs */
822 	xattrs.names = g_xattr_names;
823 	xattrs.get_value = _get_xattr_value;
824 	xattrs.count = 3;
825 	xattrs.ctx = &g_ctx;
826 
827 	spdk_bs_create_clone(bs, snapshotid, &xattrs, blob_op_with_id_complete, NULL);
828 	CU_ASSERT(g_bserrno == 0);
829 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
830 	cloneid = g_blobid;
831 
832 	spdk_bs_open_blob(bs, cloneid, blob_op_with_handle_complete, NULL);
833 	CU_ASSERT(g_bserrno == 0);
834 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
835 	clone = g_blob;
836 	CU_ASSERT(clone->data_ro == false)
837 	CU_ASSERT(clone->md_ro == false)
838 	CU_ASSERT(spdk_blob_get_num_clusters(clone) == 10);
839 
840 	rc = spdk_blob_get_xattr_value(clone, g_xattr_names[0], &value, &value_len);
841 	CU_ASSERT(rc == 0);
842 	SPDK_CU_ASSERT_FATAL(value != NULL);
843 	CU_ASSERT(value_len == strlen(g_xattr_values[0]));
844 	CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len);
845 
846 	rc = spdk_blob_get_xattr_value(clone, g_xattr_names[1], &value, &value_len);
847 	CU_ASSERT(rc == 0);
848 	SPDK_CU_ASSERT_FATAL(value != NULL);
849 	CU_ASSERT(value_len == strlen(g_xattr_values[1]));
850 	CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len);
851 
852 	rc = spdk_blob_get_xattr_value(clone, g_xattr_names[2], &value, &value_len);
853 	CU_ASSERT(rc == 0);
854 	SPDK_CU_ASSERT_FATAL(value != NULL);
855 	CU_ASSERT(value_len == strlen(g_xattr_values[2]));
856 	CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len);
857 
858 
859 	spdk_blob_close(clone, blob_op_complete, NULL);
860 	CU_ASSERT(g_bserrno == 0);
861 
862 	/* Try to create clone from not read only blob */
863 	spdk_bs_create_clone(bs, blobid, NULL, blob_op_with_id_complete, NULL);
864 	CU_ASSERT(g_bserrno == -EINVAL);
865 	CU_ASSERT(g_blobid == SPDK_BLOBID_INVALID);
866 
867 	/* Mark blob as read only */
868 	spdk_blob_set_read_only(blob);
869 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
870 	CU_ASSERT(g_bserrno == 0);
871 
872 	/* Create clone from read only blob */
873 	spdk_bs_create_clone(bs, blobid, NULL, blob_op_with_id_complete, NULL);
874 	CU_ASSERT(g_bserrno == 0);
875 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
876 	cloneid = g_blobid;
877 
878 	spdk_bs_open_blob(bs, cloneid, blob_op_with_handle_complete, NULL);
879 	CU_ASSERT(g_bserrno == 0);
880 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
881 	clone = g_blob;
882 	CU_ASSERT(clone->data_ro == false)
883 	CU_ASSERT(clone->md_ro == false)
884 	CU_ASSERT(spdk_blob_get_num_clusters(clone) == 10);
885 
886 	spdk_blob_close(clone, blob_op_complete, NULL);
887 	CU_ASSERT(g_bserrno == 0);
888 
889 	spdk_blob_close(blob, blob_op_complete, NULL);
890 	CU_ASSERT(g_bserrno == 0);
891 
892 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
893 	CU_ASSERT(g_bserrno == 0);
894 	g_bs = NULL;
895 
896 }
897 
898 static void
899 _blob_inflate(bool decouple_parent)
900 {
901 	struct spdk_blob_store *bs;
902 	struct spdk_bs_dev *dev;
903 	struct spdk_blob_opts opts;
904 	struct spdk_blob *blob, *snapshot;
905 	spdk_blob_id blobid, snapshotid;
906 	struct spdk_io_channel *channel;
907 	uint64_t free_clusters;
908 
909 	dev = init_dev();
910 
911 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
912 	CU_ASSERT(g_bserrno == 0);
913 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
914 	bs = g_bs;
915 
916 	channel = spdk_bs_alloc_io_channel(bs);
917 	SPDK_CU_ASSERT_FATAL(channel != NULL);
918 
919 	/* Create blob with 10 clusters */
920 
921 	spdk_blob_opts_init(&opts);
922 	opts.num_clusters = 10;
923 	opts.thin_provision = true;
924 
925 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
926 	CU_ASSERT(g_bserrno == 0);
927 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
928 	blobid = g_blobid;
929 
930 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
931 	CU_ASSERT(g_bserrno == 0);
932 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
933 	blob = g_blob;
934 
935 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10)
936 	CU_ASSERT(spdk_blob_is_thin_provisioned(blob) == true);
937 
938 	/* 1) Blob with no parent */
939 	if (decouple_parent) {
940 		/* Decouple parent of blob with no parent (should fail) */
941 		spdk_bs_blob_decouple_parent(bs, channel, blobid, blob_op_complete, NULL);
942 		CU_ASSERT(g_bserrno != 0);
943 	} else {
944 		/* Inflate of thin blob with no parent should made it thick */
945 		spdk_bs_inflate_blob(bs, channel, blobid, blob_op_complete, NULL);
946 		CU_ASSERT(g_bserrno == 0);
947 		CU_ASSERT(spdk_blob_is_thin_provisioned(blob) == false);
948 	}
949 
950 	spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL);
951 	CU_ASSERT(g_bserrno == 0);
952 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
953 	snapshotid = g_blobid;
954 
955 	CU_ASSERT(spdk_blob_is_thin_provisioned(blob) == true);
956 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10)
957 
958 	spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL);
959 	CU_ASSERT(g_bserrno == 0);
960 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
961 	snapshot = g_blob;
962 	CU_ASSERT(snapshot->data_ro == true)
963 	CU_ASSERT(snapshot->md_ro == true)
964 	CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 10);
965 
966 	spdk_blob_close(snapshot, blob_op_complete, NULL);
967 	CU_ASSERT(g_bserrno == 0);
968 
969 	free_clusters = spdk_bs_free_cluster_count(bs);
970 
971 	/* 2) Blob with parent */
972 	if (!decouple_parent) {
973 		/* Do full blob inflation */
974 		spdk_bs_inflate_blob(bs, channel, blobid, blob_op_complete, NULL);
975 		CU_ASSERT(g_bserrno == 0);
976 		/* all 10 clusters should be allocated */
977 		CU_ASSERT(spdk_bs_free_cluster_count(bs) == free_clusters - 10);
978 	} else {
979 		/* Decouple parent of blob */
980 		spdk_bs_blob_decouple_parent(bs, channel, blobid, blob_op_complete, NULL);
981 		CU_ASSERT(g_bserrno == 0);
982 		/* when only parent is removed, none of the clusters should be allocated */
983 		CU_ASSERT(spdk_bs_free_cluster_count(bs) == free_clusters);
984 	}
985 
986 	/* Now, it should be possible to delete snapshot */
987 	spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL);
988 	CU_ASSERT(g_bserrno == 0);
989 
990 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10)
991 	CU_ASSERT(spdk_blob_is_thin_provisioned(blob) == decouple_parent);
992 
993 	spdk_blob_close(blob, blob_op_complete, NULL);
994 	CU_ASSERT(g_bserrno == 0);
995 
996 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
997 	CU_ASSERT(g_bserrno == 0);
998 	g_bs = NULL;
999 
1000 	spdk_bs_free_io_channel(channel);
1001 }
1002 
1003 static void
1004 blob_inflate(void)
1005 {
1006 	_blob_inflate(false);
1007 	_blob_inflate(true);
1008 }
1009 
1010 static void
1011 blob_delete(void)
1012 {
1013 	struct spdk_blob_store *bs;
1014 	struct spdk_bs_dev *dev;
1015 	spdk_blob_id blobid;
1016 
1017 	dev = init_dev();
1018 
1019 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1020 	CU_ASSERT(g_bserrno == 0);
1021 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1022 	bs = g_bs;
1023 
1024 	/* Create a blob and then delete it. */
1025 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
1026 	CU_ASSERT(g_bserrno == 0);
1027 	CU_ASSERT(g_blobid > 0);
1028 	blobid = g_blobid;
1029 
1030 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
1031 	CU_ASSERT(g_bserrno == 0);
1032 
1033 	/* Try to open the blob */
1034 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1035 	CU_ASSERT(g_bserrno == -ENOENT);
1036 
1037 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1038 	CU_ASSERT(g_bserrno == 0);
1039 	g_bs = NULL;
1040 }
1041 
1042 static void
1043 blob_resize(void)
1044 {
1045 	struct spdk_blob_store *bs;
1046 	struct spdk_bs_dev *dev;
1047 	struct spdk_blob *blob;
1048 	spdk_blob_id blobid;
1049 	uint64_t free_clusters;
1050 
1051 	dev = init_dev();
1052 
1053 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1054 	CU_ASSERT(g_bserrno == 0);
1055 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1056 	bs = g_bs;
1057 	free_clusters = spdk_bs_free_cluster_count(bs);
1058 
1059 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
1060 	CU_ASSERT(g_bserrno == 0);
1061 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1062 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
1063 	blobid = g_blobid;
1064 
1065 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1066 	CU_ASSERT(g_bserrno == 0);
1067 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1068 	blob = g_blob;
1069 
1070 	/* Confirm that resize fails if blob is marked read-only. */
1071 	blob->md_ro = true;
1072 	spdk_blob_resize(blob, 5, blob_op_complete, NULL);
1073 	CU_ASSERT(g_bserrno == -EPERM);
1074 	blob->md_ro = false;
1075 
1076 	/* The blob started at 0 clusters. Resize it to be 5. */
1077 	spdk_blob_resize(blob, 5, blob_op_complete, NULL);
1078 	CU_ASSERT(g_bserrno == 0);
1079 	CU_ASSERT((free_clusters - 5) == spdk_bs_free_cluster_count(bs));
1080 
1081 	/* Shrink the blob to 3 clusters. This will not actually release
1082 	 * the old clusters until the blob is synced.
1083 	 */
1084 	spdk_blob_resize(blob, 3, blob_op_complete, NULL);
1085 	CU_ASSERT(g_bserrno == 0);
1086 	/* Verify there are still 5 clusters in use */
1087 	CU_ASSERT((free_clusters - 5) == spdk_bs_free_cluster_count(bs));
1088 
1089 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
1090 	CU_ASSERT(g_bserrno == 0);
1091 	/* Now there are only 3 clusters in use */
1092 	CU_ASSERT((free_clusters - 3) == spdk_bs_free_cluster_count(bs));
1093 
1094 	/* Resize the blob to be 10 clusters. Growth takes effect immediately. */
1095 	spdk_blob_resize(blob, 10, blob_op_complete, NULL);
1096 	CU_ASSERT(g_bserrno == 0);
1097 	CU_ASSERT((free_clusters - 10) == spdk_bs_free_cluster_count(bs));
1098 
1099 	/* Try to resize the blob to size larger than blobstore. */
1100 	spdk_blob_resize(blob, bs->total_clusters + 1, blob_op_complete, NULL);
1101 	CU_ASSERT(g_bserrno == -ENOSPC);
1102 
1103 	spdk_blob_close(blob, blob_op_complete, NULL);
1104 	CU_ASSERT(g_bserrno == 0);
1105 
1106 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
1107 	CU_ASSERT(g_bserrno == 0);
1108 
1109 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1110 	CU_ASSERT(g_bserrno == 0);
1111 	g_bs = NULL;
1112 }
1113 
1114 static void
1115 blob_read_only(void)
1116 {
1117 	struct spdk_blob_store *bs;
1118 	struct spdk_bs_dev *dev;
1119 	struct spdk_blob *blob;
1120 	struct spdk_bs_opts opts;
1121 	spdk_blob_id blobid;
1122 	int rc;
1123 
1124 	dev = init_dev();
1125 	spdk_bs_opts_init(&opts);
1126 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
1127 
1128 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
1129 	CU_ASSERT(g_bserrno == 0);
1130 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1131 	bs = g_bs;
1132 
1133 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
1134 	CU_ASSERT(g_bserrno == 0);
1135 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1136 	blobid = g_blobid;
1137 
1138 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1139 	CU_ASSERT(g_bserrno == 0);
1140 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1141 	blob = g_blob;
1142 
1143 	rc = spdk_blob_set_read_only(blob);
1144 	CU_ASSERT(rc == 0);
1145 
1146 	CU_ASSERT(blob->data_ro == false);
1147 	CU_ASSERT(blob->md_ro == false);
1148 
1149 	spdk_blob_sync_md(blob, bs_op_complete, NULL);
1150 
1151 	CU_ASSERT(blob->data_ro == true);
1152 	CU_ASSERT(blob->md_ro == true);
1153 	CU_ASSERT(blob->data_ro_flags & SPDK_BLOB_READ_ONLY);
1154 
1155 	spdk_blob_close(blob, blob_op_complete, NULL);
1156 	CU_ASSERT(g_bserrno == 0);
1157 
1158 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1159 	CU_ASSERT(g_bserrno == 0);
1160 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1161 	blob = g_blob;
1162 
1163 	CU_ASSERT(blob->data_ro == true);
1164 	CU_ASSERT(blob->md_ro == true);
1165 	CU_ASSERT(blob->data_ro_flags & SPDK_BLOB_READ_ONLY);
1166 
1167 	spdk_blob_close(blob, blob_op_complete, NULL);
1168 	CU_ASSERT(g_bserrno == 0);
1169 
1170 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1171 	CU_ASSERT(g_bserrno == 0);
1172 	g_bs = NULL;
1173 	g_blob = NULL;
1174 	g_blobid = 0;
1175 
1176 	/* Load an existing blob store */
1177 	dev = init_dev();
1178 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
1179 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1180 	CU_ASSERT(g_bserrno == 0);
1181 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1182 
1183 	spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
1184 	CU_ASSERT(g_bserrno == 0);
1185 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1186 	blob = g_blob;
1187 
1188 	CU_ASSERT(blob->data_ro == true);
1189 	CU_ASSERT(blob->md_ro == true);
1190 	CU_ASSERT(blob->data_ro_flags & SPDK_BLOB_READ_ONLY);
1191 
1192 	spdk_blob_close(blob, blob_op_complete, NULL);
1193 	CU_ASSERT(g_bserrno == 0);
1194 
1195 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1196 	CU_ASSERT(g_bserrno == 0);
1197 
1198 }
1199 
1200 static void
1201 channel_ops(void)
1202 {
1203 	struct spdk_blob_store *bs;
1204 	struct spdk_bs_dev *dev;
1205 	struct spdk_io_channel *channel;
1206 
1207 	dev = init_dev();
1208 
1209 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1210 	CU_ASSERT(g_bserrno == 0);
1211 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1212 	bs = g_bs;
1213 
1214 	channel = spdk_bs_alloc_io_channel(bs);
1215 	CU_ASSERT(channel != NULL);
1216 
1217 	spdk_bs_free_io_channel(channel);
1218 
1219 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1220 	CU_ASSERT(g_bserrno == 0);
1221 	g_bs = NULL;
1222 }
1223 
1224 static void
1225 blob_write(void)
1226 {
1227 	struct spdk_blob_store *bs;
1228 	struct spdk_bs_dev *dev;
1229 	struct spdk_blob *blob;
1230 	struct spdk_io_channel *channel;
1231 	spdk_blob_id blobid;
1232 	uint64_t pages_per_cluster;
1233 	uint8_t payload[10 * 4096];
1234 
1235 	dev = init_dev();
1236 
1237 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1238 	CU_ASSERT(g_bserrno == 0);
1239 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1240 	bs = g_bs;
1241 
1242 	pages_per_cluster = spdk_bs_get_cluster_size(bs) / spdk_bs_get_page_size(bs);
1243 
1244 	channel = spdk_bs_alloc_io_channel(bs);
1245 	CU_ASSERT(channel != NULL);
1246 
1247 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
1248 	CU_ASSERT(g_bserrno == 0);
1249 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1250 	blobid = g_blobid;
1251 
1252 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1253 	CU_ASSERT(g_bserrno == 0);
1254 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1255 	blob = g_blob;
1256 
1257 	/* Write to a blob with 0 size */
1258 	spdk_blob_io_write(blob, channel, payload, 0, 1, blob_op_complete, NULL);
1259 	CU_ASSERT(g_bserrno == -EINVAL);
1260 
1261 	/* Resize the blob */
1262 	spdk_blob_resize(blob, 5, blob_op_complete, NULL);
1263 	CU_ASSERT(g_bserrno == 0);
1264 
1265 	/* Confirm that write fails if blob is marked read-only. */
1266 	blob->data_ro = true;
1267 	spdk_blob_io_write(blob, channel, payload, 0, 1, blob_op_complete, NULL);
1268 	CU_ASSERT(g_bserrno == -EPERM);
1269 	blob->data_ro = false;
1270 
1271 	/* Write to the blob */
1272 	spdk_blob_io_write(blob, channel, payload, 0, 1, blob_op_complete, NULL);
1273 	CU_ASSERT(g_bserrno == 0);
1274 
1275 	/* Write starting beyond the end */
1276 	spdk_blob_io_write(blob, channel, payload, 5 * pages_per_cluster, 1, blob_op_complete,
1277 			   NULL);
1278 	CU_ASSERT(g_bserrno == -EINVAL);
1279 
1280 	/* Write starting at a valid location but going off the end */
1281 	spdk_blob_io_write(blob, channel, payload, 4 * pages_per_cluster, pages_per_cluster + 1,
1282 			   blob_op_complete, NULL);
1283 	CU_ASSERT(g_bserrno == -EINVAL);
1284 
1285 	spdk_blob_close(blob, blob_op_complete, NULL);
1286 	CU_ASSERT(g_bserrno == 0);
1287 
1288 	spdk_bs_free_io_channel(channel);
1289 
1290 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1291 	CU_ASSERT(g_bserrno == 0);
1292 	g_bs = NULL;
1293 }
1294 
1295 static void
1296 blob_read(void)
1297 {
1298 	struct spdk_blob_store *bs;
1299 	struct spdk_bs_dev *dev;
1300 	struct spdk_blob *blob;
1301 	struct spdk_io_channel *channel;
1302 	spdk_blob_id blobid;
1303 	uint64_t pages_per_cluster;
1304 	uint8_t payload[10 * 4096];
1305 
1306 	dev = init_dev();
1307 
1308 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1309 	CU_ASSERT(g_bserrno == 0);
1310 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1311 	bs = g_bs;
1312 
1313 	pages_per_cluster = spdk_bs_get_cluster_size(bs) / spdk_bs_get_page_size(bs);
1314 
1315 	channel = spdk_bs_alloc_io_channel(bs);
1316 	CU_ASSERT(channel != NULL);
1317 
1318 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
1319 	CU_ASSERT(g_bserrno == 0);
1320 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1321 	blobid = g_blobid;
1322 
1323 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1324 	CU_ASSERT(g_bserrno == 0);
1325 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1326 	blob = g_blob;
1327 
1328 	/* Read from a blob with 0 size */
1329 	spdk_blob_io_read(blob, channel, payload, 0, 1, blob_op_complete, NULL);
1330 	CU_ASSERT(g_bserrno == -EINVAL);
1331 
1332 	/* Resize the blob */
1333 	spdk_blob_resize(blob, 5, blob_op_complete, NULL);
1334 	CU_ASSERT(g_bserrno == 0);
1335 
1336 	/* Confirm that read passes if blob is marked read-only. */
1337 	blob->data_ro = true;
1338 	spdk_blob_io_read(blob, channel, payload, 0, 1, blob_op_complete, NULL);
1339 	CU_ASSERT(g_bserrno == 0);
1340 	blob->data_ro = false;
1341 
1342 	/* Read from the blob */
1343 	spdk_blob_io_read(blob, channel, payload, 0, 1, blob_op_complete, NULL);
1344 	CU_ASSERT(g_bserrno == 0);
1345 
1346 	/* Read starting beyond the end */
1347 	spdk_blob_io_read(blob, channel, payload, 5 * pages_per_cluster, 1, blob_op_complete,
1348 			  NULL);
1349 	CU_ASSERT(g_bserrno == -EINVAL);
1350 
1351 	/* Read starting at a valid location but going off the end */
1352 	spdk_blob_io_read(blob, channel, payload, 4 * pages_per_cluster, pages_per_cluster + 1,
1353 			  blob_op_complete, NULL);
1354 	CU_ASSERT(g_bserrno == -EINVAL);
1355 
1356 	spdk_blob_close(blob, blob_op_complete, NULL);
1357 	CU_ASSERT(g_bserrno == 0);
1358 
1359 	spdk_bs_free_io_channel(channel);
1360 
1361 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1362 	CU_ASSERT(g_bserrno == 0);
1363 	g_bs = NULL;
1364 }
1365 
1366 static void
1367 blob_rw_verify(void)
1368 {
1369 	struct spdk_blob_store *bs;
1370 	struct spdk_bs_dev *dev;
1371 	struct spdk_blob *blob;
1372 	struct spdk_io_channel *channel;
1373 	spdk_blob_id blobid;
1374 	uint8_t payload_read[10 * 4096];
1375 	uint8_t payload_write[10 * 4096];
1376 
1377 	dev = init_dev();
1378 
1379 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1380 	CU_ASSERT(g_bserrno == 0);
1381 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1382 	bs = g_bs;
1383 
1384 	channel = spdk_bs_alloc_io_channel(bs);
1385 	CU_ASSERT(channel != NULL);
1386 
1387 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
1388 	CU_ASSERT(g_bserrno == 0);
1389 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1390 	blobid = g_blobid;
1391 
1392 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1393 	CU_ASSERT(g_bserrno == 0);
1394 	CU_ASSERT(g_blob != NULL);
1395 	blob = g_blob;
1396 
1397 	spdk_blob_resize(blob, 32, blob_op_complete, NULL);
1398 	CU_ASSERT(g_bserrno == 0);
1399 
1400 	memset(payload_write, 0xE5, sizeof(payload_write));
1401 	spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL);
1402 	CU_ASSERT(g_bserrno == 0);
1403 
1404 	memset(payload_read, 0x00, sizeof(payload_read));
1405 	spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL);
1406 	CU_ASSERT(g_bserrno == 0);
1407 	CU_ASSERT(memcmp(payload_write, payload_read, 4 * 4096) == 0);
1408 
1409 	spdk_blob_close(blob, blob_op_complete, NULL);
1410 	CU_ASSERT(g_bserrno == 0);
1411 
1412 	spdk_bs_free_io_channel(channel);
1413 
1414 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1415 	CU_ASSERT(g_bserrno == 0);
1416 	g_bs = NULL;
1417 }
1418 
1419 static void
1420 blob_rw_verify_iov(void)
1421 {
1422 	struct spdk_blob_store *bs;
1423 	struct spdk_bs_dev *dev;
1424 	struct spdk_blob *blob;
1425 	struct spdk_io_channel *channel;
1426 	spdk_blob_id blobid;
1427 	uint8_t payload_read[10 * 4096];
1428 	uint8_t payload_write[10 * 4096];
1429 	struct iovec iov_read[3];
1430 	struct iovec iov_write[3];
1431 	void *buf;
1432 
1433 	dev = init_dev();
1434 	memset(g_dev_buffer, 0, DEV_BUFFER_SIZE);
1435 
1436 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1437 	CU_ASSERT(g_bserrno == 0);
1438 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1439 	bs = g_bs;
1440 
1441 	channel = spdk_bs_alloc_io_channel(bs);
1442 	CU_ASSERT(channel != NULL);
1443 
1444 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
1445 	CU_ASSERT(g_bserrno == 0);
1446 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1447 	blobid = g_blobid;
1448 
1449 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1450 	CU_ASSERT(g_bserrno == 0);
1451 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1452 	blob = g_blob;
1453 
1454 	spdk_blob_resize(blob, 2, blob_op_complete, NULL);
1455 	CU_ASSERT(g_bserrno == 0);
1456 
1457 	/*
1458 	 * Manually adjust the offset of the blob's second cluster.  This allows
1459 	 *  us to make sure that the readv/write code correctly accounts for I/O
1460 	 *  that cross cluster boundaries.  Start by asserting that the allocated
1461 	 *  clusters are where we expect before modifying the second cluster.
1462 	 */
1463 	CU_ASSERT(blob->active.clusters[0] == 1 * 256);
1464 	CU_ASSERT(blob->active.clusters[1] == 2 * 256);
1465 	blob->active.clusters[1] = 3 * 256;
1466 
1467 	memset(payload_write, 0xE5, sizeof(payload_write));
1468 	iov_write[0].iov_base = payload_write;
1469 	iov_write[0].iov_len = 1 * 4096;
1470 	iov_write[1].iov_base = payload_write + 1 * 4096;
1471 	iov_write[1].iov_len = 5 * 4096;
1472 	iov_write[2].iov_base = payload_write + 6 * 4096;
1473 	iov_write[2].iov_len = 4 * 4096;
1474 	/*
1475 	 * Choose a page offset just before the cluster boundary.  The first 6 pages of payload
1476 	 *  will get written to the first cluster, the last 4 to the second cluster.
1477 	 */
1478 	spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL);
1479 	CU_ASSERT(g_bserrno == 0);
1480 
1481 	memset(payload_read, 0xAA, sizeof(payload_read));
1482 	iov_read[0].iov_base = payload_read;
1483 	iov_read[0].iov_len = 3 * 4096;
1484 	iov_read[1].iov_base = payload_read + 3 * 4096;
1485 	iov_read[1].iov_len = 4 * 4096;
1486 	iov_read[2].iov_base = payload_read + 7 * 4096;
1487 	iov_read[2].iov_len = 3 * 4096;
1488 	spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL);
1489 	CU_ASSERT(g_bserrno == 0);
1490 	CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0);
1491 
1492 	buf = calloc(1, 256 * 4096);
1493 	SPDK_CU_ASSERT_FATAL(buf != NULL);
1494 	/* Check that cluster 2 on "disk" was not modified. */
1495 	CU_ASSERT(memcmp(buf, &g_dev_buffer[512 * 4096], 256 * 4096) == 0);
1496 	free(buf);
1497 
1498 	spdk_blob_close(blob, blob_op_complete, NULL);
1499 	CU_ASSERT(g_bserrno == 0);
1500 
1501 	spdk_bs_free_io_channel(channel);
1502 
1503 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1504 	CU_ASSERT(g_bserrno == 0);
1505 	g_bs = NULL;
1506 }
1507 
1508 static uint32_t
1509 bs_channel_get_req_count(struct spdk_io_channel *_channel)
1510 {
1511 	struct spdk_bs_channel *channel = spdk_io_channel_get_ctx(_channel);
1512 	struct spdk_bs_request_set *set;
1513 	uint32_t count = 0;
1514 
1515 	TAILQ_FOREACH(set, &channel->reqs, link) {
1516 		count++;
1517 	}
1518 
1519 	return count;
1520 }
1521 
1522 static void
1523 blob_rw_verify_iov_nomem(void)
1524 {
1525 	struct spdk_blob_store *bs;
1526 	struct spdk_bs_dev *dev;
1527 	struct spdk_blob *blob;
1528 	struct spdk_io_channel *channel;
1529 	spdk_blob_id blobid;
1530 	uint8_t payload_write[10 * 4096];
1531 	struct iovec iov_write[3];
1532 	uint32_t req_count;
1533 
1534 	dev = init_dev();
1535 	memset(g_dev_buffer, 0, DEV_BUFFER_SIZE);
1536 
1537 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1538 	CU_ASSERT(g_bserrno == 0);
1539 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1540 	bs = g_bs;
1541 
1542 	channel = spdk_bs_alloc_io_channel(bs);
1543 	CU_ASSERT(channel != NULL);
1544 
1545 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
1546 	CU_ASSERT(g_bserrno == 0);
1547 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1548 	blobid = g_blobid;
1549 
1550 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1551 	CU_ASSERT(g_bserrno == 0);
1552 	CU_ASSERT(g_blob != NULL);
1553 	blob = g_blob;
1554 
1555 	spdk_blob_resize(blob, 2, blob_op_complete, NULL);
1556 	CU_ASSERT(g_bserrno == 0);
1557 
1558 	/*
1559 	 * Choose a page offset just before the cluster boundary.  The first 6 pages of payload
1560 	 *  will get written to the first cluster, the last 4 to the second cluster.
1561 	 */
1562 	iov_write[0].iov_base = payload_write;
1563 	iov_write[0].iov_len = 1 * 4096;
1564 	iov_write[1].iov_base = payload_write + 1 * 4096;
1565 	iov_write[1].iov_len = 5 * 4096;
1566 	iov_write[2].iov_base = payload_write + 6 * 4096;
1567 	iov_write[2].iov_len = 4 * 4096;
1568 	MOCK_SET(calloc, NULL);
1569 	req_count = bs_channel_get_req_count(channel);
1570 	spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL);
1571 	CU_ASSERT(g_bserrno = -ENOMEM);
1572 	CU_ASSERT(req_count == bs_channel_get_req_count(channel));
1573 	MOCK_CLEAR(calloc);
1574 
1575 	spdk_blob_close(blob, blob_op_complete, NULL);
1576 	CU_ASSERT(g_bserrno == 0);
1577 
1578 	spdk_bs_free_io_channel(channel);
1579 
1580 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1581 	CU_ASSERT(g_bserrno == 0);
1582 	g_bs = NULL;
1583 }
1584 
1585 static void
1586 blob_rw_iov_read_only(void)
1587 {
1588 	struct spdk_blob_store *bs;
1589 	struct spdk_bs_dev *dev;
1590 	struct spdk_blob *blob;
1591 	struct spdk_io_channel *channel;
1592 	spdk_blob_id blobid;
1593 	uint8_t payload_read[4096];
1594 	uint8_t payload_write[4096];
1595 	struct iovec iov_read;
1596 	struct iovec iov_write;
1597 
1598 	dev = init_dev();
1599 	memset(g_dev_buffer, 0, DEV_BUFFER_SIZE);
1600 
1601 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1602 	CU_ASSERT(g_bserrno == 0);
1603 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1604 	bs = g_bs;
1605 
1606 	channel = spdk_bs_alloc_io_channel(bs);
1607 	CU_ASSERT(channel != NULL);
1608 
1609 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
1610 	CU_ASSERT(g_bserrno == 0);
1611 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1612 	blobid = g_blobid;
1613 
1614 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1615 	CU_ASSERT(g_bserrno == 0);
1616 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1617 	blob = g_blob;
1618 
1619 	spdk_blob_resize(blob, 2, blob_op_complete, NULL);
1620 	CU_ASSERT(g_bserrno == 0);
1621 
1622 	/* Verify that writev failed if read_only flag is set. */
1623 	blob->data_ro = true;
1624 	iov_write.iov_base = payload_write;
1625 	iov_write.iov_len = sizeof(payload_write);
1626 	spdk_blob_io_writev(blob, channel, &iov_write, 1, 0, 1, blob_op_complete, NULL);
1627 	CU_ASSERT(g_bserrno == -EPERM);
1628 
1629 	/* Verify that reads pass if data_ro flag is set. */
1630 	iov_read.iov_base = payload_read;
1631 	iov_read.iov_len = sizeof(payload_read);
1632 	spdk_blob_io_readv(blob, channel, &iov_read, 1, 0, 1, blob_op_complete, NULL);
1633 	CU_ASSERT(g_bserrno == 0);
1634 
1635 	spdk_blob_close(blob, blob_op_complete, NULL);
1636 	CU_ASSERT(g_bserrno == 0);
1637 
1638 	spdk_bs_free_io_channel(channel);
1639 
1640 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1641 	CU_ASSERT(g_bserrno == 0);
1642 	g_bs = NULL;
1643 }
1644 
1645 static void
1646 _blob_io_read_no_split(struct spdk_blob *blob, struct spdk_io_channel *channel,
1647 		       uint8_t *payload, uint64_t offset, uint64_t length,
1648 		       spdk_blob_op_complete cb_fn, void *cb_arg)
1649 {
1650 	uint64_t i;
1651 	uint8_t *buf;
1652 	uint64_t page_size = spdk_bs_get_page_size(blob->bs);
1653 
1654 	/* To be sure that operation is NOT splitted, read one page at the time */
1655 	buf = payload;
1656 	for (i = 0; i < length; i++) {
1657 		spdk_blob_io_read(blob, channel, buf, i + offset, 1, blob_op_complete, NULL);
1658 		if (g_bserrno != 0) {
1659 			/* Pass the error code up */
1660 			break;
1661 		}
1662 		buf += page_size;
1663 	}
1664 
1665 	cb_fn(cb_arg, g_bserrno);
1666 }
1667 
1668 static void
1669 _blob_io_write_no_split(struct spdk_blob *blob, struct spdk_io_channel *channel,
1670 			uint8_t *payload, uint64_t offset, uint64_t length,
1671 			spdk_blob_op_complete cb_fn, void *cb_arg)
1672 {
1673 	uint64_t i;
1674 	uint8_t *buf;
1675 	uint64_t page_size = spdk_bs_get_page_size(blob->bs);
1676 
1677 	/* To be sure that operation is NOT splitted, write one page at the time */
1678 	buf = payload;
1679 	for (i = 0; i < length; i++) {
1680 		spdk_blob_io_write(blob, channel, buf, i + offset, 1, blob_op_complete, NULL);
1681 		if (g_bserrno != 0) {
1682 			/* Pass the error code up */
1683 			break;
1684 		}
1685 		buf += page_size;
1686 	}
1687 
1688 	cb_fn(cb_arg, g_bserrno);
1689 }
1690 
1691 static void
1692 blob_operation_split_rw(void)
1693 {
1694 	struct spdk_blob_store *bs;
1695 	struct spdk_bs_dev *dev;
1696 	struct spdk_blob *blob;
1697 	struct spdk_io_channel *channel;
1698 	struct spdk_blob_opts opts;
1699 	spdk_blob_id blobid;
1700 	uint64_t cluster_size;
1701 
1702 	uint64_t payload_size;
1703 	uint8_t *payload_read;
1704 	uint8_t *payload_write;
1705 	uint8_t *payload_pattern;
1706 
1707 	uint64_t page_size;
1708 	uint64_t pages_per_cluster;
1709 	uint64_t pages_per_payload;
1710 
1711 	uint64_t i;
1712 
1713 	dev = init_dev();
1714 
1715 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1716 	CU_ASSERT(g_bserrno == 0);
1717 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1718 	bs = g_bs;
1719 
1720 	cluster_size = spdk_bs_get_cluster_size(bs);
1721 	page_size = spdk_bs_get_page_size(bs);
1722 	pages_per_cluster = cluster_size / page_size;
1723 	pages_per_payload = pages_per_cluster * 5;
1724 	payload_size = cluster_size * 5;
1725 
1726 	payload_read = malloc(payload_size);
1727 	SPDK_CU_ASSERT_FATAL(payload_read != NULL);
1728 
1729 	payload_write = malloc(payload_size);
1730 	SPDK_CU_ASSERT_FATAL(payload_write != NULL);
1731 
1732 	payload_pattern = malloc(payload_size);
1733 	SPDK_CU_ASSERT_FATAL(payload_pattern != NULL);
1734 
1735 	/* Prepare random pattern to write */
1736 	memset(payload_pattern, 0xFF, payload_size);
1737 	for (i = 0; i < pages_per_payload; i++) {
1738 		*((uint64_t *)(payload_pattern + page_size * i)) = (i + 1);
1739 	}
1740 
1741 	channel = spdk_bs_alloc_io_channel(bs);
1742 	SPDK_CU_ASSERT_FATAL(channel != NULL);
1743 
1744 	/* Create blob */
1745 	spdk_blob_opts_init(&opts);
1746 	opts.thin_provision = false;
1747 	opts.num_clusters = 5;
1748 
1749 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
1750 	CU_ASSERT(g_bserrno == 0);
1751 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1752 	blobid = g_blobid;
1753 
1754 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1755 	CU_ASSERT(g_bserrno == 0);
1756 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1757 	blob = g_blob;
1758 
1759 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5);
1760 
1761 	/* Initial read should return zeroed payload */
1762 	memset(payload_read, 0xFF, payload_size);
1763 	spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, blob_op_complete, NULL);
1764 	CU_ASSERT(g_bserrno == 0);
1765 	CU_ASSERT(spdk_mem_all_zero(payload_read, payload_size));
1766 
1767 	/* Fill whole blob except last page */
1768 	spdk_blob_io_write(blob, channel, payload_pattern, 0, pages_per_payload - 1,
1769 			   blob_op_complete, NULL);
1770 	CU_ASSERT(g_bserrno == 0);
1771 
1772 	/* Write last page with a pattern */
1773 	spdk_blob_io_write(blob, channel, payload_pattern, pages_per_payload - 1, 1,
1774 			   blob_op_complete, NULL);
1775 	CU_ASSERT(g_bserrno == 0);
1776 
1777 	/* Read whole blob and check consistency */
1778 	memset(payload_read, 0xFF, payload_size);
1779 	spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, blob_op_complete, NULL);
1780 	CU_ASSERT(g_bserrno == 0);
1781 	CU_ASSERT(memcmp(payload_pattern, payload_read, payload_size - page_size) == 0);
1782 	CU_ASSERT(memcmp(payload_pattern, payload_read + payload_size - page_size, page_size) == 0);
1783 
1784 	/* Fill whole blob except first page */
1785 	spdk_blob_io_write(blob, channel, payload_pattern, 1, pages_per_payload - 1,
1786 			   blob_op_complete, NULL);
1787 	CU_ASSERT(g_bserrno == 0);
1788 
1789 	/* Write first page with a pattern */
1790 	spdk_blob_io_write(blob, channel, payload_pattern, 0, 1,
1791 			   blob_op_complete, NULL);
1792 	CU_ASSERT(g_bserrno == 0);
1793 
1794 	/* Read whole blob and check consistency */
1795 	memset(payload_read, 0xFF, payload_size);
1796 	spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, blob_op_complete, NULL);
1797 	CU_ASSERT(g_bserrno == 0);
1798 	CU_ASSERT(memcmp(payload_pattern, payload_read + page_size, payload_size - page_size) == 0);
1799 	CU_ASSERT(memcmp(payload_pattern, payload_read, page_size) == 0);
1800 
1801 
1802 	/* Fill whole blob with a pattern (5 clusters) */
1803 
1804 	/* 1. Read test. */
1805 	_blob_io_write_no_split(blob, channel, payload_pattern, 0, pages_per_payload,
1806 				blob_op_complete, NULL);
1807 	CU_ASSERT(g_bserrno == 0);
1808 
1809 	memset(payload_read, 0xFF, payload_size);
1810 	spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, blob_op_complete, NULL);
1811 	CU_ASSERT(g_bserrno == 0);
1812 	CU_ASSERT(memcmp(payload_pattern, payload_read, payload_size) == 0);
1813 
1814 	/* 2. Write test. */
1815 	spdk_blob_io_write(blob, channel, payload_pattern, 0, pages_per_payload,
1816 			   blob_op_complete, NULL);
1817 	CU_ASSERT(g_bserrno == 0);
1818 
1819 	memset(payload_read, 0xFF, payload_size);
1820 	_blob_io_read_no_split(blob, channel, payload_read, 0, pages_per_payload, blob_op_complete, NULL);
1821 	CU_ASSERT(g_bserrno == 0);
1822 	CU_ASSERT(memcmp(payload_pattern, payload_read, payload_size) == 0);
1823 
1824 	spdk_blob_close(blob, blob_op_complete, NULL);
1825 	CU_ASSERT(g_bserrno == 0);
1826 
1827 	spdk_bs_free_io_channel(channel);
1828 
1829 	/* Unload the blob store */
1830 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1831 	CU_ASSERT(g_bserrno == 0);
1832 	g_bs = NULL;
1833 	g_blob = NULL;
1834 	g_blobid = 0;
1835 
1836 	free(payload_read);
1837 	free(payload_write);
1838 	free(payload_pattern);
1839 }
1840 
1841 static void
1842 blob_operation_split_rw_iov(void)
1843 {
1844 	struct spdk_blob_store *bs;
1845 	struct spdk_bs_dev *dev;
1846 	struct spdk_blob *blob;
1847 	struct spdk_io_channel *channel;
1848 	struct spdk_blob_opts opts;
1849 	spdk_blob_id blobid;
1850 	uint64_t cluster_size;
1851 
1852 	uint64_t payload_size;
1853 	uint8_t *payload_read;
1854 	uint8_t *payload_write;
1855 	uint8_t *payload_pattern;
1856 
1857 	uint64_t page_size;
1858 	uint64_t pages_per_cluster;
1859 	uint64_t pages_per_payload;
1860 
1861 	struct iovec iov_read[2];
1862 	struct iovec iov_write[2];
1863 
1864 	uint64_t i, j;
1865 
1866 	dev = init_dev();
1867 
1868 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1869 	CU_ASSERT(g_bserrno == 0);
1870 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1871 	bs = g_bs;
1872 
1873 	cluster_size = spdk_bs_get_cluster_size(bs);
1874 	page_size = spdk_bs_get_page_size(bs);
1875 	pages_per_cluster = cluster_size / page_size;
1876 	pages_per_payload = pages_per_cluster * 5;
1877 	payload_size = cluster_size * 5;
1878 
1879 	payload_read = malloc(payload_size);
1880 	SPDK_CU_ASSERT_FATAL(payload_read != NULL);
1881 
1882 	payload_write = malloc(payload_size);
1883 	SPDK_CU_ASSERT_FATAL(payload_write != NULL);
1884 
1885 	payload_pattern = malloc(payload_size);
1886 	SPDK_CU_ASSERT_FATAL(payload_pattern != NULL);
1887 
1888 	/* Prepare random pattern to write */
1889 	for (i = 0; i < pages_per_payload; i++) {
1890 		for (j = 0; j < page_size / sizeof(uint64_t); j++) {
1891 			uint64_t *tmp;
1892 
1893 			tmp = (uint64_t *)payload_pattern;
1894 			tmp += ((page_size * i) / sizeof(uint64_t)) + j;
1895 			*tmp = i + 1;
1896 		}
1897 	}
1898 
1899 	channel = spdk_bs_alloc_io_channel(bs);
1900 	SPDK_CU_ASSERT_FATAL(channel != NULL);
1901 
1902 	/* Create blob */
1903 	spdk_blob_opts_init(&opts);
1904 	opts.thin_provision = false;
1905 	opts.num_clusters = 5;
1906 
1907 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
1908 	CU_ASSERT(g_bserrno == 0);
1909 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1910 	blobid = g_blobid;
1911 
1912 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1913 	CU_ASSERT(g_bserrno == 0);
1914 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1915 	blob = g_blob;
1916 
1917 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5);
1918 
1919 	/* Initial read should return zeroes payload */
1920 	memset(payload_read, 0xFF, payload_size);
1921 	iov_read[0].iov_base = payload_read;
1922 	iov_read[0].iov_len = cluster_size * 3;
1923 	iov_read[1].iov_base = payload_read + cluster_size * 3;
1924 	iov_read[1].iov_len = cluster_size * 2;
1925 	spdk_blob_io_readv(blob, channel, iov_read, 2, 0, pages_per_payload, blob_op_complete, NULL);
1926 	CU_ASSERT(g_bserrno == 0);
1927 	CU_ASSERT(spdk_mem_all_zero(payload_read, payload_size));
1928 
1929 	/* First of iovs fills whole blob except last page and second of iovs writes last page
1930 	 *  with a pattern. */
1931 	iov_write[0].iov_base = payload_pattern;
1932 	iov_write[0].iov_len = payload_size - page_size;
1933 	iov_write[1].iov_base = payload_pattern;
1934 	iov_write[1].iov_len = page_size;
1935 	spdk_blob_io_writev(blob, channel, iov_write, 2, 0, pages_per_payload, blob_op_complete, NULL);
1936 	CU_ASSERT(g_bserrno == 0);
1937 
1938 	/* Read whole blob and check consistency */
1939 	memset(payload_read, 0xFF, payload_size);
1940 	iov_read[0].iov_base = payload_read;
1941 	iov_read[0].iov_len = cluster_size * 2;
1942 	iov_read[1].iov_base = payload_read + cluster_size * 2;
1943 	iov_read[1].iov_len = cluster_size * 3;
1944 	spdk_blob_io_readv(blob, channel, iov_read, 2, 0, pages_per_payload, blob_op_complete, NULL);
1945 	CU_ASSERT(g_bserrno == 0);
1946 	CU_ASSERT(memcmp(payload_pattern, payload_read, payload_size - page_size) == 0);
1947 	CU_ASSERT(memcmp(payload_pattern, payload_read + payload_size - page_size, page_size) == 0);
1948 
1949 	/* First of iovs fills only first page and second of iovs writes whole blob except
1950 	 *  first page with a pattern. */
1951 	iov_write[0].iov_base = payload_pattern;
1952 	iov_write[0].iov_len = page_size;
1953 	iov_write[1].iov_base = payload_pattern;
1954 	iov_write[1].iov_len = payload_size - page_size;
1955 	spdk_blob_io_writev(blob, channel, iov_write, 2, 0, pages_per_payload, blob_op_complete, NULL);
1956 	CU_ASSERT(g_bserrno == 0);
1957 
1958 	/* Read whole blob and check consistency */
1959 	memset(payload_read, 0xFF, payload_size);
1960 	iov_read[0].iov_base = payload_read;
1961 	iov_read[0].iov_len = cluster_size * 4;
1962 	iov_read[1].iov_base = payload_read + cluster_size * 4;
1963 	iov_read[1].iov_len = cluster_size;
1964 	spdk_blob_io_readv(blob, channel, iov_read, 2, 0, pages_per_payload, blob_op_complete, NULL);
1965 	CU_ASSERT(g_bserrno == 0);
1966 	CU_ASSERT(memcmp(payload_pattern, payload_read + page_size, payload_size - page_size) == 0);
1967 	CU_ASSERT(memcmp(payload_pattern, payload_read, page_size) == 0);
1968 
1969 
1970 	/* Fill whole blob with a pattern (5 clusters) */
1971 
1972 	/* 1. Read test. */
1973 	_blob_io_write_no_split(blob, channel, payload_pattern, 0, pages_per_payload,
1974 				blob_op_complete, NULL);
1975 	CU_ASSERT(g_bserrno == 0);
1976 
1977 	memset(payload_read, 0xFF, payload_size);
1978 	iov_read[0].iov_base = payload_read;
1979 	iov_read[0].iov_len = cluster_size;
1980 	iov_read[1].iov_base = payload_read + cluster_size;
1981 	iov_read[1].iov_len = cluster_size * 4;
1982 	spdk_blob_io_readv(blob, channel, iov_read, 2, 0, pages_per_payload, blob_op_complete, NULL);
1983 	CU_ASSERT(g_bserrno == 0);
1984 	CU_ASSERT(memcmp(payload_pattern, payload_read, payload_size) == 0);
1985 
1986 	/* 2. Write test. */
1987 	iov_write[0].iov_base = payload_read;
1988 	iov_write[0].iov_len = cluster_size * 2;
1989 	iov_write[1].iov_base = payload_read + cluster_size * 2;
1990 	iov_write[1].iov_len = cluster_size * 3;
1991 	spdk_blob_io_writev(blob, channel, iov_write, 2, 0, pages_per_payload, blob_op_complete, NULL);
1992 	CU_ASSERT(g_bserrno == 0);
1993 
1994 	memset(payload_read, 0xFF, payload_size);
1995 	_blob_io_read_no_split(blob, channel, payload_read, 0, pages_per_payload, blob_op_complete, NULL);
1996 	CU_ASSERT(g_bserrno == 0);
1997 	CU_ASSERT(memcmp(payload_pattern, payload_read, payload_size) == 0);
1998 
1999 	spdk_blob_close(blob, blob_op_complete, NULL);
2000 	CU_ASSERT(g_bserrno == 0);
2001 
2002 	spdk_bs_free_io_channel(channel);
2003 
2004 	/* Unload the blob store */
2005 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2006 	CU_ASSERT(g_bserrno == 0);
2007 	g_bs = NULL;
2008 	g_blob = NULL;
2009 	g_blobid = 0;
2010 
2011 	free(payload_read);
2012 	free(payload_write);
2013 	free(payload_pattern);
2014 }
2015 
2016 static void
2017 blob_unmap(void)
2018 {
2019 	struct spdk_blob_store *bs;
2020 	struct spdk_bs_dev *dev;
2021 	struct spdk_blob *blob;
2022 	struct spdk_io_channel *channel;
2023 	spdk_blob_id blobid;
2024 	struct spdk_blob_opts opts;
2025 	uint8_t payload[4096];
2026 	int i;
2027 
2028 	dev = init_dev();
2029 
2030 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
2031 	CU_ASSERT(g_bserrno == 0);
2032 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2033 	bs = g_bs;
2034 
2035 	channel = spdk_bs_alloc_io_channel(bs);
2036 	CU_ASSERT(channel != NULL);
2037 
2038 	spdk_blob_opts_init(&opts);
2039 	opts.num_clusters = 10;
2040 
2041 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
2042 	CU_ASSERT(g_bserrno == 0);
2043 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2044 	blobid = g_blobid;
2045 
2046 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
2047 	CU_ASSERT(g_bserrno == 0);
2048 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
2049 	blob = g_blob;
2050 
2051 	spdk_blob_resize(blob, 10, blob_op_complete, NULL);
2052 	CU_ASSERT(g_bserrno == 0);
2053 
2054 	memset(payload, 0, sizeof(payload));
2055 	payload[0] = 0xFF;
2056 
2057 	/*
2058 	 * Set first byte of every cluster to 0xFF.
2059 	 * First cluster on device is reserved so let's start from cluster number 1
2060 	 */
2061 	for (i = 1; i < 11; i++) {
2062 		g_dev_buffer[i * SPDK_BLOB_OPTS_CLUSTER_SZ] = 0xFF;
2063 	}
2064 
2065 	/* Confirm writes */
2066 	for (i = 0; i < 10; i++) {
2067 		payload[0] = 0;
2068 		spdk_blob_io_read(blob, channel, &payload, i * SPDK_BLOB_OPTS_CLUSTER_SZ / 4096, 1,
2069 				  blob_op_complete, NULL);
2070 		CU_ASSERT(g_bserrno == 0);
2071 		CU_ASSERT(payload[0] == 0xFF);
2072 	}
2073 
2074 	/* Mark some clusters as unallocated */
2075 	blob->active.clusters[1] = 0;
2076 	blob->active.clusters[2] = 0;
2077 	blob->active.clusters[3] = 0;
2078 	blob->active.clusters[6] = 0;
2079 	blob->active.clusters[8] = 0;
2080 
2081 	/* Unmap clusters by resizing to 0 */
2082 	spdk_blob_resize(blob, 0, blob_op_complete, NULL);
2083 	CU_ASSERT(g_bserrno == 0);
2084 
2085 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
2086 	CU_ASSERT(g_bserrno == 0);
2087 
2088 	/* Confirm that only 'allocated' clusters were unmapped */
2089 	for (i = 1; i < 11; i++) {
2090 		switch (i) {
2091 		case 2:
2092 		case 3:
2093 		case 4:
2094 		case 7:
2095 		case 9:
2096 			CU_ASSERT(g_dev_buffer[i * SPDK_BLOB_OPTS_CLUSTER_SZ] == 0xFF);
2097 			break;
2098 		default:
2099 			CU_ASSERT(g_dev_buffer[i * SPDK_BLOB_OPTS_CLUSTER_SZ] == 0);
2100 			break;
2101 		}
2102 	}
2103 
2104 	spdk_blob_close(blob, blob_op_complete, NULL);
2105 	CU_ASSERT(g_bserrno == 0);
2106 
2107 	spdk_bs_free_io_channel(channel);
2108 
2109 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2110 	CU_ASSERT(g_bserrno == 0);
2111 	g_bs = NULL;
2112 }
2113 
2114 
2115 static void
2116 blob_iter(void)
2117 {
2118 	struct spdk_blob_store *bs;
2119 	struct spdk_bs_dev *dev;
2120 	struct spdk_blob *blob;
2121 	spdk_blob_id blobid;
2122 
2123 	dev = init_dev();
2124 
2125 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
2126 	CU_ASSERT(g_bserrno == 0);
2127 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2128 	bs = g_bs;
2129 
2130 	spdk_bs_iter_first(bs, blob_op_with_handle_complete, NULL);
2131 	CU_ASSERT(g_blob == NULL);
2132 	CU_ASSERT(g_bserrno == -ENOENT);
2133 
2134 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
2135 	CU_ASSERT(g_bserrno == 0);
2136 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2137 	blobid = g_blobid;
2138 
2139 	spdk_bs_iter_first(bs, blob_op_with_handle_complete, NULL);
2140 	CU_ASSERT(g_blob != NULL);
2141 	CU_ASSERT(g_bserrno == 0);
2142 	blob = g_blob;
2143 	CU_ASSERT(spdk_blob_get_id(blob) == blobid);
2144 
2145 	spdk_bs_iter_next(bs, blob, blob_op_with_handle_complete, NULL);
2146 	CU_ASSERT(g_blob == NULL);
2147 	CU_ASSERT(g_bserrno == -ENOENT);
2148 
2149 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2150 	CU_ASSERT(g_bserrno == 0);
2151 	g_bs = NULL;
2152 }
2153 
2154 static void
2155 blob_xattr(void)
2156 {
2157 	struct spdk_blob_store *bs;
2158 	struct spdk_bs_dev *dev;
2159 	struct spdk_blob *blob;
2160 	spdk_blob_id blobid;
2161 	uint64_t length;
2162 	int rc;
2163 	const char *name1, *name2;
2164 	const void *value;
2165 	size_t value_len;
2166 	struct spdk_xattr_names *names;
2167 
2168 	dev = init_dev();
2169 
2170 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
2171 	CU_ASSERT(g_bserrno == 0);
2172 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2173 	bs = g_bs;
2174 
2175 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
2176 	CU_ASSERT(g_bserrno == 0);
2177 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2178 	blobid = g_blobid;
2179 
2180 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
2181 	CU_ASSERT(g_bserrno == 0);
2182 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
2183 	blob = g_blob;
2184 
2185 	/* Test that set_xattr fails if md_ro flag is set. */
2186 	blob->md_ro = true;
2187 	rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1);
2188 	CU_ASSERT(rc == -EPERM);
2189 
2190 	blob->md_ro = false;
2191 	rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1);
2192 	CU_ASSERT(rc == 0);
2193 
2194 	length = 2345;
2195 	rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
2196 	CU_ASSERT(rc == 0);
2197 
2198 	/* Overwrite "length" xattr. */
2199 	length = 3456;
2200 	rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
2201 	CU_ASSERT(rc == 0);
2202 
2203 	/* get_xattr should still work even if md_ro flag is set. */
2204 	value = NULL;
2205 	blob->md_ro = true;
2206 	rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len);
2207 	CU_ASSERT(rc == 0);
2208 	SPDK_CU_ASSERT_FATAL(value != NULL);
2209 	CU_ASSERT(*(uint64_t *)value == length);
2210 	CU_ASSERT(value_len == 8);
2211 	blob->md_ro = false;
2212 
2213 	rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len);
2214 	CU_ASSERT(rc == -ENOENT);
2215 
2216 	names = NULL;
2217 	rc = spdk_blob_get_xattr_names(blob, &names);
2218 	CU_ASSERT(rc == 0);
2219 	SPDK_CU_ASSERT_FATAL(names != NULL);
2220 	CU_ASSERT(spdk_xattr_names_get_count(names) == 2);
2221 	name1 = spdk_xattr_names_get_name(names, 0);
2222 	SPDK_CU_ASSERT_FATAL(name1 != NULL);
2223 	CU_ASSERT(!strcmp(name1, "name") || !strcmp(name1, "length"));
2224 	name2 = spdk_xattr_names_get_name(names, 1);
2225 	SPDK_CU_ASSERT_FATAL(name2 != NULL);
2226 	CU_ASSERT(!strcmp(name2, "name") || !strcmp(name2, "length"));
2227 	CU_ASSERT(strcmp(name1, name2));
2228 	spdk_xattr_names_free(names);
2229 
2230 	/* Confirm that remove_xattr fails if md_ro is set to true. */
2231 	blob->md_ro = true;
2232 	rc = spdk_blob_remove_xattr(blob, "name");
2233 	CU_ASSERT(rc == -EPERM);
2234 
2235 	blob->md_ro = false;
2236 	rc = spdk_blob_remove_xattr(blob, "name");
2237 	CU_ASSERT(rc == 0);
2238 
2239 	rc = spdk_blob_remove_xattr(blob, "foobar");
2240 	CU_ASSERT(rc == -ENOENT);
2241 
2242 	/* Set internal xattr */
2243 	length = 7898;
2244 	rc = _spdk_blob_set_xattr(blob, "internal", &length, sizeof(length), true);
2245 	CU_ASSERT(rc == 0);
2246 	rc = _spdk_blob_get_xattr_value(blob, "internal", &value, &value_len, true);
2247 	CU_ASSERT(rc == 0);
2248 	CU_ASSERT(*(uint64_t *)value == length);
2249 	/* try to get public xattr with same name */
2250 	rc = spdk_blob_get_xattr_value(blob, "internal", &value, &value_len);
2251 	CU_ASSERT(rc != 0);
2252 	rc = _spdk_blob_get_xattr_value(blob, "internal", &value, &value_len, false);
2253 	CU_ASSERT(rc != 0);
2254 	/* Check if SPDK_BLOB_INTERNAL_XATTR is set */
2255 	CU_ASSERT((blob->invalid_flags & SPDK_BLOB_INTERNAL_XATTR) ==
2256 		  SPDK_BLOB_INTERNAL_XATTR)
2257 
2258 	spdk_blob_close(blob, blob_op_complete, NULL);
2259 
2260 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2261 
2262 	/* Check if xattrs are persisted */
2263 	dev = init_dev();
2264 
2265 	spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL);
2266 	CU_ASSERT(g_bserrno == 0);
2267 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2268 
2269 	bs = g_bs;
2270 
2271 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
2272 	CU_ASSERT(g_bserrno == 0);
2273 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
2274 	blob = g_blob;
2275 
2276 	rc = _spdk_blob_get_xattr_value(blob, "internal", &value, &value_len, true);
2277 	CU_ASSERT(rc == 0);
2278 	CU_ASSERT(*(uint64_t *)value == length);
2279 
2280 	/* try to get internal xattr trough public call */
2281 	rc = spdk_blob_get_xattr_value(blob, "internal", &value, &value_len);
2282 	CU_ASSERT(rc != 0);
2283 
2284 	rc = _spdk_blob_remove_xattr(blob, "internal", true);
2285 	CU_ASSERT(rc == 0);
2286 
2287 	CU_ASSERT((blob->invalid_flags & SPDK_BLOB_INTERNAL_XATTR) == 0);
2288 
2289 	CU_ASSERT(g_bserrno == 0);
2290 	g_bs = NULL;
2291 }
2292 
2293 static void
2294 bs_load(void)
2295 {
2296 	struct spdk_bs_dev *dev;
2297 	spdk_blob_id blobid;
2298 	struct spdk_blob *blob;
2299 	struct spdk_bs_super_block *super_block;
2300 	uint64_t length;
2301 	int rc;
2302 	const void *value;
2303 	size_t value_len;
2304 	struct spdk_bs_opts opts;
2305 
2306 	dev = init_dev();
2307 	spdk_bs_opts_init(&opts);
2308 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
2309 
2310 	/* Initialize a new blob store */
2311 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2312 	CU_ASSERT(g_bserrno == 0);
2313 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2314 
2315 	/* Try to open a blobid that does not exist */
2316 	spdk_bs_open_blob(g_bs, 0, blob_op_with_handle_complete, NULL);
2317 	CU_ASSERT(g_bserrno == -ENOENT);
2318 	CU_ASSERT(g_blob == NULL);
2319 
2320 	/* Create a blob */
2321 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
2322 	CU_ASSERT(g_bserrno == 0);
2323 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2324 	blobid = g_blobid;
2325 
2326 	spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
2327 	CU_ASSERT(g_bserrno == 0);
2328 	CU_ASSERT(g_blob != NULL);
2329 	blob = g_blob;
2330 
2331 	/* Try again to open valid blob but without the upper bit set */
2332 	spdk_bs_open_blob(g_bs, blobid & 0xFFFFFFFF, blob_op_with_handle_complete, NULL);
2333 	CU_ASSERT(g_bserrno == -ENOENT);
2334 	CU_ASSERT(g_blob == NULL);
2335 
2336 	/* Set some xattrs */
2337 	rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1);
2338 	CU_ASSERT(rc == 0);
2339 
2340 	length = 2345;
2341 	rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
2342 	CU_ASSERT(rc == 0);
2343 
2344 	/* Resize the blob */
2345 	spdk_blob_resize(blob, 10, blob_op_complete, NULL);
2346 	CU_ASSERT(g_bserrno == 0);
2347 
2348 	spdk_blob_close(blob, blob_op_complete, NULL);
2349 	CU_ASSERT(g_bserrno == 0);
2350 	blob = NULL;
2351 	g_blob = NULL;
2352 	g_blobid = SPDK_BLOBID_INVALID;
2353 
2354 	/* Unload the blob store */
2355 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2356 	CU_ASSERT(g_bserrno == 0);
2357 	g_bs = NULL;
2358 	g_blob = NULL;
2359 	g_blobid = 0;
2360 
2361 	super_block = (struct spdk_bs_super_block *)g_dev_buffer;
2362 	CU_ASSERT(super_block->clean == 1);
2363 
2364 	/* Load should fail for device with an unsupported blocklen */
2365 	dev = init_dev();
2366 	dev->blocklen = SPDK_BS_PAGE_SIZE * 2;
2367 	spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL);
2368 	CU_ASSERT(g_bserrno == -EINVAL);
2369 
2370 	/* Load should when max_md_ops is set to zero */
2371 	dev = init_dev();
2372 	spdk_bs_opts_init(&opts);
2373 	opts.max_md_ops = 0;
2374 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2375 	CU_ASSERT(g_bserrno == -EINVAL);
2376 
2377 	/* Load should when max_channel_ops is set to zero */
2378 	dev = init_dev();
2379 	spdk_bs_opts_init(&opts);
2380 	opts.max_channel_ops = 0;
2381 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2382 	CU_ASSERT(g_bserrno == -EINVAL);
2383 
2384 	/* Load an existing blob store */
2385 	dev = init_dev();
2386 	spdk_bs_opts_init(&opts);
2387 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
2388 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2389 	CU_ASSERT(g_bserrno == 0);
2390 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2391 
2392 	super_block = (struct spdk_bs_super_block *)g_dev_buffer;
2393 	CU_ASSERT(super_block->clean == 1);
2394 	CU_ASSERT(super_block->size == dev->blockcnt * dev->blocklen);
2395 
2396 	spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
2397 	CU_ASSERT(g_bserrno == 0);
2398 	CU_ASSERT(g_blob != NULL);
2399 	blob = g_blob;
2400 
2401 	/* Verify that blobstore is marked dirty after first metadata sync */
2402 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
2403 	CU_ASSERT(super_block->clean == 1);
2404 
2405 	/* Get the xattrs */
2406 	value = NULL;
2407 	rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len);
2408 	CU_ASSERT(rc == 0);
2409 	SPDK_CU_ASSERT_FATAL(value != NULL);
2410 	CU_ASSERT(*(uint64_t *)value == length);
2411 	CU_ASSERT(value_len == 8);
2412 
2413 	rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len);
2414 	CU_ASSERT(rc == -ENOENT);
2415 
2416 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10);
2417 
2418 	spdk_blob_close(blob, blob_op_complete, NULL);
2419 	CU_ASSERT(g_bserrno == 0);
2420 	blob = NULL;
2421 	g_blob = NULL;
2422 
2423 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2424 	CU_ASSERT(g_bserrno == 0);
2425 	g_bs = NULL;
2426 
2427 	/* Load should fail: bdev size < saved size */
2428 	dev = init_dev();
2429 	dev->blockcnt /= 2;
2430 
2431 	spdk_bs_opts_init(&opts);
2432 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
2433 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2434 
2435 	CU_ASSERT(g_bserrno == -EILSEQ);
2436 
2437 	/* Load should succeed: bdev size > saved size */
2438 	dev = init_dev();
2439 	dev->blockcnt *= 4;
2440 
2441 	spdk_bs_opts_init(&opts);
2442 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
2443 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2444 
2445 	CU_ASSERT(g_bserrno == 0);
2446 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2447 
2448 
2449 	/* Test compatibility mode */
2450 
2451 	dev = init_dev();
2452 	super_block->size = 0;
2453 	super_block->crc = _spdk_blob_md_page_calc_crc(super_block);
2454 
2455 	spdk_bs_opts_init(&opts);
2456 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
2457 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2458 	CU_ASSERT(g_bserrno == 0);
2459 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2460 
2461 	/* Create a blob */
2462 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
2463 	CU_ASSERT(g_bserrno == 0);
2464 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2465 
2466 	/* Blobstore should update number of blocks in super_block */
2467 	CU_ASSERT(super_block->size == dev->blockcnt * dev->blocklen);
2468 	CU_ASSERT(super_block->clean == 0);
2469 
2470 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2471 	CU_ASSERT(g_bserrno == 0);
2472 	CU_ASSERT(super_block->clean == 1);
2473 	g_bs = NULL;
2474 
2475 }
2476 
2477 static void
2478 bs_load_custom_cluster_size(void)
2479 {
2480 	struct spdk_bs_dev *dev;
2481 	struct spdk_bs_super_block *super_block;
2482 	struct spdk_bs_opts opts;
2483 	uint32_t custom_cluster_size = 4194304; /* 4MiB */
2484 	uint32_t cluster_sz;
2485 	uint64_t total_clusters;
2486 
2487 	dev = init_dev();
2488 	spdk_bs_opts_init(&opts);
2489 	opts.cluster_sz = custom_cluster_size;
2490 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
2491 
2492 	/* Initialize a new blob store */
2493 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2494 	CU_ASSERT(g_bserrno == 0);
2495 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2496 	cluster_sz = g_bs->cluster_sz;
2497 	total_clusters = g_bs->total_clusters;
2498 
2499 	/* Unload the blob store */
2500 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2501 	CU_ASSERT(g_bserrno == 0);
2502 	g_bs = NULL;
2503 	g_blob = NULL;
2504 	g_blobid = 0;
2505 
2506 	super_block = (struct spdk_bs_super_block *)g_dev_buffer;
2507 	CU_ASSERT(super_block->clean == 1);
2508 
2509 	/* Load an existing blob store */
2510 	dev = init_dev();
2511 	spdk_bs_opts_init(&opts);
2512 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
2513 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2514 	CU_ASSERT(g_bserrno == 0);
2515 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2516 	/* Compare cluster size and number to one after initialization */
2517 	CU_ASSERT(cluster_sz == g_bs->cluster_sz);
2518 	CU_ASSERT(total_clusters == g_bs->total_clusters);
2519 
2520 	super_block = (struct spdk_bs_super_block *)g_dev_buffer;
2521 	CU_ASSERT(super_block->clean == 1);
2522 	CU_ASSERT(super_block->size == dev->blockcnt * dev->blocklen);
2523 
2524 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2525 	CU_ASSERT(g_bserrno == 0);
2526 	CU_ASSERT(super_block->clean == 1);
2527 	g_bs = NULL;
2528 }
2529 
2530 static void
2531 bs_type(void)
2532 {
2533 	struct spdk_bs_dev *dev;
2534 	struct spdk_bs_opts opts;
2535 
2536 	dev = init_dev();
2537 	spdk_bs_opts_init(&opts);
2538 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
2539 
2540 	/* Initialize a new blob store */
2541 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2542 	CU_ASSERT(g_bserrno == 0);
2543 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2544 
2545 	/* Unload the blob store */
2546 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2547 	CU_ASSERT(g_bserrno == 0);
2548 	g_bs = NULL;
2549 	g_blob = NULL;
2550 	g_blobid = 0;
2551 
2552 	/* Load non existing blobstore type */
2553 	dev = init_dev();
2554 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "NONEXISTING");
2555 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2556 	CU_ASSERT(g_bserrno != 0);
2557 
2558 	/* Load with empty blobstore type */
2559 	dev = init_dev();
2560 	memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype));
2561 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2562 	CU_ASSERT(g_bserrno == 0);
2563 
2564 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2565 	CU_ASSERT(g_bserrno == 0);
2566 	g_bs = NULL;
2567 
2568 	/* Initialize a new blob store with empty bstype */
2569 	dev = init_dev();
2570 	memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype));
2571 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
2572 	CU_ASSERT(g_bserrno == 0);
2573 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2574 
2575 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2576 	CU_ASSERT(g_bserrno == 0);
2577 	g_bs = NULL;
2578 
2579 	/* Load non existing blobstore type */
2580 	dev = init_dev();
2581 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "NONEXISTING");
2582 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2583 	CU_ASSERT(g_bserrno != 0);
2584 
2585 	/* Load with empty blobstore type */
2586 	dev = init_dev();
2587 	memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype));
2588 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2589 	CU_ASSERT(g_bserrno == 0);
2590 
2591 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2592 	CU_ASSERT(g_bserrno == 0);
2593 	g_bs = NULL;
2594 }
2595 
2596 static void
2597 bs_super_block(void)
2598 {
2599 	struct spdk_bs_dev *dev;
2600 	struct spdk_bs_super_block *super_block;
2601 	struct spdk_bs_opts opts;
2602 	struct spdk_bs_super_block_ver1 super_block_v1;
2603 
2604 	dev = init_dev();
2605 	spdk_bs_opts_init(&opts);
2606 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
2607 
2608 	/* Initialize a new blob store */
2609 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2610 	CU_ASSERT(g_bserrno == 0);
2611 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2612 
2613 	/* Unload the blob store */
2614 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2615 	CU_ASSERT(g_bserrno == 0);
2616 	g_bs = NULL;
2617 	g_blob = NULL;
2618 	g_blobid = 0;
2619 
2620 	/* Load an existing blob store with version newer than supported */
2621 	super_block = (struct spdk_bs_super_block *)g_dev_buffer;
2622 	super_block->version++;
2623 
2624 	dev = init_dev();
2625 	memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype));
2626 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2627 	CU_ASSERT(g_bserrno != 0);
2628 
2629 	/* Create a new blob store with super block version 1 */
2630 	dev = init_dev();
2631 	super_block_v1.version = 1;
2632 	memcpy(super_block_v1.signature, "SPDKBLOB", sizeof(super_block_v1.signature));
2633 	super_block_v1.length = 0x1000;
2634 	super_block_v1.clean = 1;
2635 	super_block_v1.super_blob = 0xFFFFFFFFFFFFFFFF;
2636 	super_block_v1.cluster_size = 0x100000;
2637 	super_block_v1.used_page_mask_start = 0x01;
2638 	super_block_v1.used_page_mask_len = 0x01;
2639 	super_block_v1.used_cluster_mask_start = 0x02;
2640 	super_block_v1.used_cluster_mask_len = 0x01;
2641 	super_block_v1.md_start = 0x03;
2642 	super_block_v1.md_len = 0x40;
2643 	memset(super_block_v1.reserved, 0, 4036);
2644 	super_block_v1.crc = _spdk_blob_md_page_calc_crc(&super_block_v1);
2645 	memcpy(g_dev_buffer, &super_block_v1, sizeof(struct spdk_bs_super_block_ver1));
2646 
2647 	memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype));
2648 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2649 	CU_ASSERT(g_bserrno == 0);
2650 
2651 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2652 	CU_ASSERT(g_bserrno == 0);
2653 	g_bs = NULL;
2654 }
2655 
2656 /*
2657  * Create a blobstore and then unload it.
2658  */
2659 static void
2660 bs_unload(void)
2661 {
2662 	struct spdk_bs_dev *dev;
2663 	struct spdk_blob_store *bs;
2664 	spdk_blob_id blobid;
2665 	struct spdk_blob *blob;
2666 
2667 	dev = init_dev();
2668 
2669 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
2670 	CU_ASSERT(g_bserrno == 0);
2671 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2672 	bs = g_bs;
2673 
2674 	/* Create a blob and open it. */
2675 	g_bserrno = -1;
2676 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
2677 	CU_ASSERT(g_bserrno == 0);
2678 	CU_ASSERT(g_blobid > 0);
2679 	blobid = g_blobid;
2680 
2681 	g_bserrno = -1;
2682 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
2683 	CU_ASSERT(g_bserrno == 0);
2684 	CU_ASSERT(g_blob != NULL);
2685 	blob = g_blob;
2686 
2687 	/* Try to unload blobstore, should fail with open blob */
2688 	g_bserrno = -1;
2689 	spdk_bs_unload(bs, bs_op_complete, NULL);
2690 	CU_ASSERT(g_bserrno == -EBUSY);
2691 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2692 
2693 	/* Close the blob, then successfully unload blobstore */
2694 	g_bserrno = -1;
2695 	spdk_blob_close(blob, blob_op_complete, NULL);
2696 	CU_ASSERT(g_bserrno == 0);
2697 
2698 	g_bserrno = -1;
2699 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2700 	CU_ASSERT(g_bserrno == 0);
2701 	g_bs = NULL;
2702 }
2703 
2704 /*
2705  * Create a blobstore with a cluster size different than the default, and ensure it is
2706  *  persisted.
2707  */
2708 static void
2709 bs_cluster_sz(void)
2710 {
2711 	struct spdk_bs_dev *dev;
2712 	struct spdk_bs_opts opts;
2713 	uint32_t cluster_sz;
2714 
2715 	/* Set cluster size to zero */
2716 	dev = init_dev();
2717 	spdk_bs_opts_init(&opts);
2718 	opts.cluster_sz = 0;
2719 
2720 	/* Initialize a new blob store */
2721 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2722 	CU_ASSERT(g_bserrno == -EINVAL);
2723 	SPDK_CU_ASSERT_FATAL(g_bs == NULL);
2724 
2725 	/*
2726 	 * Set cluster size to blobstore page size,
2727 	 * to work it is required to be at least twice the blobstore page size.
2728 	 */
2729 	dev = init_dev();
2730 	spdk_bs_opts_init(&opts);
2731 	opts.cluster_sz = SPDK_BS_PAGE_SIZE;
2732 
2733 	/* Initialize a new blob store */
2734 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2735 	CU_ASSERT(g_bserrno == -ENOMEM);
2736 	SPDK_CU_ASSERT_FATAL(g_bs == NULL);
2737 
2738 	/*
2739 	 * Set cluster size to lower than page size,
2740 	 * to work it is required to be at least twice the blobstore page size.
2741 	 */
2742 	dev = init_dev();
2743 	spdk_bs_opts_init(&opts);
2744 	opts.cluster_sz = SPDK_BS_PAGE_SIZE - 1;
2745 
2746 	/* Initialize a new blob store */
2747 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2748 	CU_ASSERT(g_bserrno == -EINVAL);
2749 	SPDK_CU_ASSERT_FATAL(g_bs == NULL);
2750 
2751 	/* Set cluster size to twice the default */
2752 	dev = init_dev();
2753 	spdk_bs_opts_init(&opts);
2754 	opts.cluster_sz *= 2;
2755 	cluster_sz = opts.cluster_sz;
2756 
2757 	/* Initialize a new blob store */
2758 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2759 	CU_ASSERT(g_bserrno == 0);
2760 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2761 
2762 	CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz);
2763 
2764 	/* Unload the blob store */
2765 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2766 	CU_ASSERT(g_bserrno == 0);
2767 	g_bs = NULL;
2768 	g_blob = NULL;
2769 	g_blobid = 0;
2770 
2771 	dev = init_dev();
2772 	/* Load an existing blob store */
2773 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2774 	CU_ASSERT(g_bserrno == 0);
2775 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2776 
2777 	CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz);
2778 
2779 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2780 	CU_ASSERT(g_bserrno == 0);
2781 	g_bs = NULL;
2782 }
2783 
2784 /*
2785  * Create a blobstore, reload it and ensure total usable cluster count
2786  *  stays the same.
2787  */
2788 static void
2789 bs_usable_clusters(void)
2790 {
2791 	struct spdk_bs_dev *dev;
2792 	struct spdk_bs_opts opts;
2793 	uint32_t clusters;
2794 	int i;
2795 
2796 	/* Init blobstore */
2797 	dev = init_dev();
2798 	spdk_bs_opts_init(&opts);
2799 
2800 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2801 	CU_ASSERT(g_bserrno == 0);
2802 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2803 
2804 	clusters = spdk_bs_total_data_cluster_count(g_bs);
2805 
2806 	/* Unload the blob store */
2807 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2808 	CU_ASSERT(g_bserrno == 0);
2809 	g_bs = NULL;
2810 
2811 	dev = init_dev();
2812 	/* Load an existing blob store */
2813 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2814 	CU_ASSERT(g_bserrno == 0);
2815 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2816 
2817 	CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters);
2818 
2819 	/* Create and resize blobs to make sure that useable cluster count won't change */
2820 	for (i = 0; i < 4; i++) {
2821 		g_bserrno = -1;
2822 		g_blobid = SPDK_BLOBID_INVALID;
2823 		spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
2824 		CU_ASSERT(g_bserrno == 0);
2825 		CU_ASSERT(g_blobid !=  SPDK_BLOBID_INVALID);
2826 
2827 		g_bserrno = -1;
2828 		g_blob = NULL;
2829 		spdk_bs_open_blob(g_bs, g_blobid, blob_op_with_handle_complete, NULL);
2830 		CU_ASSERT(g_bserrno == 0);
2831 		CU_ASSERT(g_blob !=  NULL);
2832 
2833 		spdk_blob_resize(g_blob, 10, blob_op_complete, NULL);
2834 		CU_ASSERT(g_bserrno == 0);
2835 
2836 		g_bserrno = -1;
2837 		spdk_blob_close(g_blob, blob_op_complete, NULL);
2838 		CU_ASSERT(g_bserrno == 0);
2839 
2840 		CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters);
2841 	}
2842 
2843 	/* Reload the blob store to make sure that nothing changed */
2844 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2845 	CU_ASSERT(g_bserrno == 0);
2846 	g_bs = NULL;
2847 
2848 	dev = init_dev();
2849 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2850 	CU_ASSERT(g_bserrno == 0);
2851 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2852 
2853 	CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters);
2854 
2855 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2856 	CU_ASSERT(g_bserrno == 0);
2857 	g_bs = NULL;
2858 }
2859 
2860 /*
2861  * Test resizing of the metadata blob.  This requires creating enough blobs
2862  *  so that one cluster is not enough to fit the metadata for those blobs.
2863  *  To induce this condition to happen more quickly, we reduce the cluster
2864  *  size to 16KB, which means only 4 4KB blob metadata pages can fit.
2865  */
2866 static void
2867 bs_resize_md(void)
2868 {
2869 	const int CLUSTER_PAGE_COUNT = 4;
2870 	const int NUM_BLOBS = CLUSTER_PAGE_COUNT * 4;
2871 	struct spdk_bs_dev *dev;
2872 	struct spdk_bs_opts opts;
2873 	uint32_t cluster_sz;
2874 	spdk_blob_id blobids[NUM_BLOBS];
2875 	int i;
2876 
2877 
2878 	dev = init_dev();
2879 	spdk_bs_opts_init(&opts);
2880 	opts.cluster_sz = CLUSTER_PAGE_COUNT * 4096;
2881 	cluster_sz = opts.cluster_sz;
2882 
2883 	/* Initialize a new blob store */
2884 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2885 	CU_ASSERT(g_bserrno == 0);
2886 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2887 
2888 	CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz);
2889 
2890 	for (i = 0; i < NUM_BLOBS; i++) {
2891 		g_bserrno = -1;
2892 		g_blobid = SPDK_BLOBID_INVALID;
2893 		spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
2894 		CU_ASSERT(g_bserrno == 0);
2895 		CU_ASSERT(g_blobid !=  SPDK_BLOBID_INVALID);
2896 		blobids[i] = g_blobid;
2897 	}
2898 
2899 	/* Unload the blob store */
2900 	g_bserrno = -1;
2901 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2902 	CU_ASSERT(g_bserrno == 0);
2903 
2904 	/* Load an existing blob store */
2905 	g_bserrno = -1;
2906 	g_bs = NULL;
2907 	dev = init_dev();
2908 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2909 	CU_ASSERT(g_bserrno == 0);
2910 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2911 
2912 	CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz);
2913 
2914 	for (i = 0; i < NUM_BLOBS; i++) {
2915 		g_bserrno = -1;
2916 		g_blob = NULL;
2917 		spdk_bs_open_blob(g_bs, blobids[i], blob_op_with_handle_complete, NULL);
2918 		CU_ASSERT(g_bserrno == 0);
2919 		CU_ASSERT(g_blob !=  NULL);
2920 		g_bserrno = -1;
2921 		spdk_blob_close(g_blob, blob_op_complete, NULL);
2922 		CU_ASSERT(g_bserrno == 0);
2923 	}
2924 
2925 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2926 	CU_ASSERT(g_bserrno == 0);
2927 	g_bs = NULL;
2928 }
2929 
2930 static void
2931 bs_destroy(void)
2932 {
2933 	struct spdk_bs_dev *dev;
2934 	struct spdk_bs_opts opts;
2935 
2936 	/* Initialize a new blob store */
2937 	dev = init_dev();
2938 	spdk_bs_opts_init(&opts);
2939 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2940 	CU_ASSERT(g_bserrno == 0);
2941 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2942 
2943 	/* Destroy the blob store */
2944 	g_bserrno = -1;
2945 	spdk_bs_destroy(g_bs, bs_op_complete, NULL);
2946 	CU_ASSERT(g_bserrno == 0);
2947 
2948 	/* Loading an non-existent blob store should fail. */
2949 	g_bs = NULL;
2950 	dev = init_dev();
2951 
2952 	g_bserrno = 0;
2953 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2954 	CU_ASSERT(g_bserrno != 0);
2955 }
2956 
2957 /* Try to hit all of the corner cases associated with serializing
2958  * a blob to disk
2959  */
2960 static void
2961 blob_serialize(void)
2962 {
2963 	struct spdk_bs_dev *dev;
2964 	struct spdk_bs_opts opts;
2965 	struct spdk_blob_store *bs;
2966 	spdk_blob_id blobid[2];
2967 	struct spdk_blob *blob[2];
2968 	uint64_t i;
2969 	char *value;
2970 	int rc;
2971 
2972 	dev = init_dev();
2973 
2974 	/* Initialize a new blobstore with very small clusters */
2975 	spdk_bs_opts_init(&opts);
2976 	opts.cluster_sz = dev->blocklen * 8;
2977 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2978 	CU_ASSERT(g_bserrno == 0);
2979 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2980 	bs = g_bs;
2981 
2982 	/* Create and open two blobs */
2983 	for (i = 0; i < 2; i++) {
2984 		spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
2985 		CU_ASSERT(g_bserrno == 0);
2986 		CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2987 		blobid[i] = g_blobid;
2988 
2989 		/* Open a blob */
2990 		spdk_bs_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL);
2991 		CU_ASSERT(g_bserrno == 0);
2992 		CU_ASSERT(g_blob != NULL);
2993 		blob[i] = g_blob;
2994 
2995 		/* Set a fairly large xattr on both blobs to eat up
2996 		 * metadata space
2997 		 */
2998 		value = calloc(dev->blocklen - 64, sizeof(char));
2999 		SPDK_CU_ASSERT_FATAL(value != NULL);
3000 		memset(value, i, dev->blocklen / 2);
3001 		rc = spdk_blob_set_xattr(blob[i], "name", value, dev->blocklen - 64);
3002 		CU_ASSERT(rc == 0);
3003 		free(value);
3004 	}
3005 
3006 	/* Resize the blobs, alternating 1 cluster at a time.
3007 	 * This thwarts run length encoding and will cause spill
3008 	 * over of the extents.
3009 	 */
3010 	for (i = 0; i < 6; i++) {
3011 		spdk_blob_resize(blob[i % 2], (i / 2) + 1, blob_op_complete, NULL);
3012 		CU_ASSERT(g_bserrno == 0);
3013 	}
3014 
3015 	for (i = 0; i < 2; i++) {
3016 		spdk_blob_sync_md(blob[i], blob_op_complete, NULL);
3017 		CU_ASSERT(g_bserrno == 0);
3018 	}
3019 
3020 	/* Close the blobs */
3021 	for (i = 0; i < 2; i++) {
3022 		spdk_blob_close(blob[i], blob_op_complete, NULL);
3023 		CU_ASSERT(g_bserrno == 0);
3024 	}
3025 
3026 	/* Unload the blobstore */
3027 	spdk_bs_unload(bs, bs_op_complete, NULL);
3028 	CU_ASSERT(g_bserrno == 0);
3029 	g_bs = NULL;
3030 	g_blob = NULL;
3031 	g_blobid = 0;
3032 	bs = NULL;
3033 
3034 	dev = init_dev();
3035 	/* Load an existing blob store */
3036 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
3037 	CU_ASSERT(g_bserrno == 0);
3038 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3039 	bs = g_bs;
3040 
3041 	for (i = 0; i < 2; i++) {
3042 		blob[i] = NULL;
3043 
3044 		spdk_bs_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL);
3045 		CU_ASSERT(g_bserrno == 0);
3046 		CU_ASSERT(g_blob != NULL);
3047 		blob[i] = g_blob;
3048 
3049 		CU_ASSERT(spdk_blob_get_num_clusters(blob[i]) == 3);
3050 
3051 		spdk_blob_close(blob[i], blob_op_complete, NULL);
3052 		CU_ASSERT(g_bserrno == 0);
3053 	}
3054 
3055 	spdk_bs_unload(bs, bs_op_complete, NULL);
3056 	CU_ASSERT(g_bserrno == 0);
3057 	g_bs = NULL;
3058 }
3059 
3060 static void
3061 blob_crc(void)
3062 {
3063 	struct spdk_blob_store *bs;
3064 	struct spdk_bs_dev *dev;
3065 	struct spdk_blob *blob;
3066 	spdk_blob_id blobid;
3067 	uint32_t page_num;
3068 	int index;
3069 	struct spdk_blob_md_page *page;
3070 
3071 	dev = init_dev();
3072 
3073 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
3074 	CU_ASSERT(g_bserrno == 0);
3075 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3076 	bs = g_bs;
3077 
3078 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
3079 	CU_ASSERT(g_bserrno == 0);
3080 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3081 	blobid = g_blobid;
3082 
3083 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
3084 	CU_ASSERT(g_bserrno == 0);
3085 	CU_ASSERT(g_blob != NULL);
3086 	blob = g_blob;
3087 
3088 	spdk_blob_close(blob, blob_op_complete, NULL);
3089 	CU_ASSERT(g_bserrno == 0);
3090 
3091 	page_num = _spdk_bs_blobid_to_page(blobid);
3092 	index = DEV_BUFFER_BLOCKLEN * (bs->md_start + page_num);
3093 	page = (struct spdk_blob_md_page *)&g_dev_buffer[index];
3094 	page->crc = 0;
3095 
3096 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
3097 	CU_ASSERT(g_bserrno == -EINVAL);
3098 	CU_ASSERT(g_blob == NULL);
3099 	g_bserrno = 0;
3100 
3101 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
3102 	CU_ASSERT(g_bserrno == -EINVAL);
3103 
3104 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3105 	CU_ASSERT(g_bserrno == 0);
3106 	g_bs = NULL;
3107 }
3108 
3109 static void
3110 super_block_crc(void)
3111 {
3112 	struct spdk_bs_dev *dev;
3113 	struct spdk_bs_super_block *super_block;
3114 	struct spdk_bs_opts opts;
3115 
3116 	dev = init_dev();
3117 	spdk_bs_opts_init(&opts);
3118 
3119 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
3120 	CU_ASSERT(g_bserrno == 0);
3121 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3122 
3123 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3124 	CU_ASSERT(g_bserrno == 0);
3125 	g_bs = NULL;
3126 
3127 	super_block = (struct spdk_bs_super_block *)g_dev_buffer;
3128 	super_block->crc = 0;
3129 	dev = init_dev();
3130 
3131 	/* Load an existing blob store */
3132 	g_bserrno = 0;
3133 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
3134 	CU_ASSERT(g_bserrno == -EILSEQ);
3135 }
3136 
3137 /* For blob dirty shutdown test case we do the following sub-test cases:
3138  * 1 Initialize new blob store and create 1 super blob with some xattrs, then we
3139  *   dirty shutdown and reload the blob store and verify the xattrs.
3140  * 2 Resize the blob from 10 clusters to 20 clusters and then dirty shutdown,
3141  *   reload the blob store and verify the clusters number.
3142  * 3 Create the second blob and then dirty shutdown, reload the blob store
3143  *   and verify the second blob.
3144  * 4 Delete the second blob and then dirty shutdown, reload the blob store
3145  *   and verify the second blob is invalid.
3146  * 5 Create the second blob again and also create the third blob, modify the
3147  *   md of second blob which makes the md invalid, and then dirty shutdown,
3148  *   reload the blob store verify the second blob, it should invalid and also
3149  *   verify the third blob, it should correct.
3150  */
3151 static void
3152 blob_dirty_shutdown(void)
3153 {
3154 	int rc;
3155 	int index;
3156 	struct spdk_bs_dev *dev;
3157 	spdk_blob_id blobid1, blobid2, blobid3;
3158 	struct spdk_blob *blob;
3159 	uint64_t length;
3160 	uint64_t free_clusters;
3161 	const void *value;
3162 	size_t value_len;
3163 	uint32_t page_num;
3164 	struct spdk_blob_md_page *page;
3165 	struct spdk_bs_opts opts;
3166 
3167 	dev = init_dev();
3168 	spdk_bs_opts_init(&opts);
3169 	/* Initialize a new blob store */
3170 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
3171 	CU_ASSERT(g_bserrno == 0);
3172 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3173 
3174 	/* Create first blob */
3175 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
3176 	CU_ASSERT(g_bserrno == 0);
3177 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3178 	blobid1 = g_blobid;
3179 
3180 	spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL);
3181 	CU_ASSERT(g_bserrno == 0);
3182 	CU_ASSERT(g_blob != NULL);
3183 	blob = g_blob;
3184 
3185 	/* Set some xattrs */
3186 	rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1);
3187 	CU_ASSERT(rc == 0);
3188 
3189 	length = 2345;
3190 	rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
3191 	CU_ASSERT(rc == 0);
3192 
3193 	/* Resize the blob */
3194 	spdk_blob_resize(blob, 10, blob_op_complete, NULL);
3195 	CU_ASSERT(g_bserrno == 0);
3196 
3197 	/* Set the blob as the super blob */
3198 	spdk_bs_set_super(g_bs, blobid1, blob_op_complete, NULL);
3199 	CU_ASSERT(g_bserrno == 0);
3200 
3201 	free_clusters = spdk_bs_free_cluster_count(g_bs);
3202 
3203 	spdk_blob_close(blob, blob_op_complete, NULL);
3204 	blob = NULL;
3205 	g_blob = NULL;
3206 	g_blobid = SPDK_BLOBID_INVALID;
3207 
3208 	/* Dirty shutdown */
3209 	_spdk_bs_free(g_bs);
3210 
3211 	/* reload blobstore */
3212 	dev = init_dev();
3213 	spdk_bs_opts_init(&opts);
3214 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
3215 	CU_ASSERT(g_bserrno == 0);
3216 
3217 	/* Get the super blob */
3218 	spdk_bs_get_super(g_bs, blob_op_with_id_complete, NULL);
3219 	CU_ASSERT(g_bserrno == 0);
3220 	CU_ASSERT(blobid1 == g_blobid);
3221 
3222 	spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL);
3223 	CU_ASSERT(g_bserrno == 0);
3224 	CU_ASSERT(g_blob != NULL);
3225 	blob = g_blob;
3226 
3227 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs));
3228 
3229 	/* Get the xattrs */
3230 	value = NULL;
3231 	rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len);
3232 	CU_ASSERT(rc == 0);
3233 	SPDK_CU_ASSERT_FATAL(value != NULL);
3234 	CU_ASSERT(*(uint64_t *)value == length);
3235 	CU_ASSERT(value_len == 8);
3236 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10);
3237 
3238 	/* Resize the blob */
3239 	spdk_blob_resize(blob, 20, blob_op_complete, NULL);
3240 	CU_ASSERT(g_bserrno == 0);
3241 
3242 	free_clusters = spdk_bs_free_cluster_count(g_bs);
3243 
3244 	spdk_blob_close(blob, blob_op_complete, NULL);
3245 	CU_ASSERT(g_bserrno == 0);
3246 	blob = NULL;
3247 	g_blob = NULL;
3248 	g_blobid = SPDK_BLOBID_INVALID;
3249 
3250 	/* Dirty shutdown */
3251 	_spdk_bs_free(g_bs);
3252 
3253 	/* reload the blobstore */
3254 	dev = init_dev();
3255 	spdk_bs_opts_init(&opts);
3256 	/* Load an existing blob store */
3257 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
3258 	CU_ASSERT(g_bserrno == 0);
3259 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3260 	spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL);
3261 	CU_ASSERT(g_bserrno == 0);
3262 	CU_ASSERT(g_blob != NULL);
3263 	blob = g_blob;
3264 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 20);
3265 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs));
3266 
3267 	spdk_blob_close(blob, blob_op_complete, NULL);
3268 	CU_ASSERT(g_bserrno == 0);
3269 	blob = NULL;
3270 	g_blob = NULL;
3271 	g_blobid = SPDK_BLOBID_INVALID;
3272 
3273 	/* Create second blob */
3274 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
3275 	CU_ASSERT(g_bserrno == 0);
3276 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3277 	blobid2 = g_blobid;
3278 
3279 	spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL);
3280 	CU_ASSERT(g_bserrno == 0);
3281 	CU_ASSERT(g_blob != NULL);
3282 	blob = g_blob;
3283 
3284 	/* Set some xattrs */
3285 	rc = spdk_blob_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1);
3286 	CU_ASSERT(rc == 0);
3287 
3288 	length = 5432;
3289 	rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
3290 	CU_ASSERT(rc == 0);
3291 
3292 	/* Resize the blob */
3293 	spdk_blob_resize(blob, 10, blob_op_complete, NULL);
3294 	CU_ASSERT(g_bserrno == 0);
3295 
3296 	free_clusters = spdk_bs_free_cluster_count(g_bs);
3297 
3298 	spdk_blob_close(blob, blob_op_complete, NULL);
3299 	blob = NULL;
3300 	g_blob = NULL;
3301 	g_blobid = SPDK_BLOBID_INVALID;
3302 
3303 	/* Dirty shutdown */
3304 	_spdk_bs_free(g_bs);
3305 
3306 	/* reload the blobstore */
3307 	dev = init_dev();
3308 	spdk_bs_opts_init(&opts);
3309 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
3310 	CU_ASSERT(g_bserrno == 0);
3311 
3312 	spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL);
3313 	CU_ASSERT(g_bserrno == 0);
3314 	CU_ASSERT(g_blob != NULL);
3315 	blob = g_blob;
3316 
3317 	/* Get the xattrs */
3318 	value = NULL;
3319 	rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len);
3320 	CU_ASSERT(rc == 0);
3321 	SPDK_CU_ASSERT_FATAL(value != NULL);
3322 	CU_ASSERT(*(uint64_t *)value == length);
3323 	CU_ASSERT(value_len == 8);
3324 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10);
3325 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs));
3326 
3327 	spdk_blob_close(blob, blob_op_complete, NULL);
3328 	CU_ASSERT(g_bserrno == 0);
3329 	spdk_bs_delete_blob(g_bs, blobid2, blob_op_complete, NULL);
3330 	CU_ASSERT(g_bserrno == 0);
3331 
3332 	free_clusters = spdk_bs_free_cluster_count(g_bs);
3333 
3334 	/* Dirty shutdown */
3335 	_spdk_bs_free(g_bs);
3336 	/* reload the blobstore */
3337 	dev = init_dev();
3338 	spdk_bs_opts_init(&opts);
3339 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
3340 	CU_ASSERT(g_bserrno == 0);
3341 
3342 	spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL);
3343 	CU_ASSERT(g_bserrno != 0);
3344 	CU_ASSERT(g_blob == NULL);
3345 
3346 	spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL);
3347 	CU_ASSERT(g_bserrno == 0);
3348 	CU_ASSERT(g_blob != NULL);
3349 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs));
3350 	spdk_blob_close(g_blob, blob_op_complete, NULL);
3351 	CU_ASSERT(g_bserrno == 0);
3352 
3353 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3354 	CU_ASSERT(g_bserrno == 0);
3355 	g_bs = NULL;
3356 
3357 	/* reload the blobstore */
3358 	dev = init_dev();
3359 	spdk_bs_opts_init(&opts);
3360 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
3361 	CU_ASSERT(g_bserrno == 0);
3362 
3363 	/* Create second blob */
3364 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
3365 	CU_ASSERT(g_bserrno == 0);
3366 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3367 	blobid2 = g_blobid;
3368 
3369 	/* Create third blob */
3370 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
3371 	CU_ASSERT(g_bserrno == 0);
3372 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3373 	blobid3 = g_blobid;
3374 
3375 	spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL);
3376 	CU_ASSERT(g_bserrno == 0);
3377 	CU_ASSERT(g_blob != NULL);
3378 	blob = g_blob;
3379 
3380 	/* Set some xattrs for second blob */
3381 	rc = spdk_blob_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1);
3382 	CU_ASSERT(rc == 0);
3383 
3384 	length = 5432;
3385 	rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
3386 	CU_ASSERT(rc == 0);
3387 
3388 	spdk_blob_close(blob, blob_op_complete, NULL);
3389 	blob = NULL;
3390 	g_blob = NULL;
3391 	g_blobid = SPDK_BLOBID_INVALID;
3392 
3393 	spdk_bs_open_blob(g_bs, blobid3, blob_op_with_handle_complete, NULL);
3394 	CU_ASSERT(g_bserrno == 0);
3395 	CU_ASSERT(g_blob != NULL);
3396 	blob = g_blob;
3397 
3398 	/* Set some xattrs for third blob */
3399 	rc = spdk_blob_set_xattr(blob, "name", "log2.txt", strlen("log2.txt") + 1);
3400 	CU_ASSERT(rc == 0);
3401 
3402 	length = 5432;
3403 	rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
3404 	CU_ASSERT(rc == 0);
3405 
3406 	spdk_blob_close(blob, blob_op_complete, NULL);
3407 	blob = NULL;
3408 	g_blob = NULL;
3409 	g_blobid = SPDK_BLOBID_INVALID;
3410 
3411 	/* Mark second blob as invalid */
3412 	page_num = _spdk_bs_blobid_to_page(blobid2);
3413 
3414 	index = DEV_BUFFER_BLOCKLEN * (g_bs->md_start + page_num);
3415 	page = (struct spdk_blob_md_page *)&g_dev_buffer[index];
3416 	page->sequence_num = 1;
3417 	page->crc = _spdk_blob_md_page_calc_crc(page);
3418 
3419 	free_clusters = spdk_bs_free_cluster_count(g_bs);
3420 
3421 	/* Dirty shutdown */
3422 	_spdk_bs_free(g_bs);
3423 	/* reload the blobstore */
3424 	dev = init_dev();
3425 	spdk_bs_opts_init(&opts);
3426 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
3427 	CU_ASSERT(g_bserrno == 0);
3428 
3429 	spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL);
3430 	CU_ASSERT(g_bserrno != 0);
3431 	CU_ASSERT(g_blob == NULL);
3432 
3433 	spdk_bs_open_blob(g_bs, blobid3, blob_op_with_handle_complete, NULL);
3434 	CU_ASSERT(g_bserrno == 0);
3435 	CU_ASSERT(g_blob != NULL);
3436 	blob = g_blob;
3437 
3438 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs));
3439 
3440 	spdk_blob_close(blob, blob_op_complete, NULL);
3441 	blob = NULL;
3442 	g_blob = NULL;
3443 	g_blobid = SPDK_BLOBID_INVALID;
3444 
3445 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3446 	CU_ASSERT(g_bserrno == 0);
3447 	g_bs = NULL;
3448 }
3449 
3450 static void
3451 blob_flags(void)
3452 {
3453 	struct spdk_bs_dev *dev;
3454 	spdk_blob_id blobid_invalid, blobid_data_ro, blobid_md_ro;
3455 	struct spdk_blob *blob_invalid, *blob_data_ro, *blob_md_ro;
3456 	struct spdk_bs_opts opts;
3457 	int rc;
3458 
3459 	dev = init_dev();
3460 	spdk_bs_opts_init(&opts);
3461 
3462 	/* Initialize a new blob store */
3463 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
3464 	CU_ASSERT(g_bserrno == 0);
3465 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3466 
3467 	/* Create three blobs - one each for testing invalid, data_ro and md_ro flags. */
3468 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
3469 	CU_ASSERT(g_bserrno == 0);
3470 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3471 	blobid_invalid = g_blobid;
3472 
3473 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
3474 	CU_ASSERT(g_bserrno == 0);
3475 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3476 	blobid_data_ro = g_blobid;
3477 
3478 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
3479 	CU_ASSERT(g_bserrno == 0);
3480 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3481 	blobid_md_ro = g_blobid;
3482 
3483 	spdk_bs_open_blob(g_bs, blobid_invalid, blob_op_with_handle_complete, NULL);
3484 	CU_ASSERT(g_bserrno == 0);
3485 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3486 	blob_invalid = g_blob;
3487 
3488 	spdk_bs_open_blob(g_bs, blobid_data_ro, blob_op_with_handle_complete, NULL);
3489 	CU_ASSERT(g_bserrno == 0);
3490 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3491 	blob_data_ro = g_blob;
3492 
3493 	spdk_bs_open_blob(g_bs, blobid_md_ro, blob_op_with_handle_complete, NULL);
3494 	CU_ASSERT(g_bserrno == 0);
3495 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3496 	blob_md_ro = g_blob;
3497 
3498 	/* Change the size of blob_data_ro to check if flags are serialized
3499 	 * when blob has non zero number of extents */
3500 	spdk_blob_resize(blob_data_ro, 10, blob_op_complete, NULL);
3501 	CU_ASSERT(g_bserrno == 0);
3502 
3503 	/* Set the xattr to check if flags are serialized
3504 	 * when blob has non zero number of xattrs */
3505 	rc = spdk_blob_set_xattr(blob_md_ro, "name", "log.txt", strlen("log.txt") + 1);
3506 	CU_ASSERT(rc == 0);
3507 
3508 	blob_invalid->invalid_flags = (1ULL << 63);
3509 	blob_invalid->state = SPDK_BLOB_STATE_DIRTY;
3510 	blob_data_ro->data_ro_flags = (1ULL << 62);
3511 	blob_data_ro->state = SPDK_BLOB_STATE_DIRTY;
3512 	blob_md_ro->md_ro_flags = (1ULL << 61);
3513 	blob_md_ro->state = SPDK_BLOB_STATE_DIRTY;
3514 
3515 	g_bserrno = -1;
3516 	spdk_blob_sync_md(blob_invalid, blob_op_complete, NULL);
3517 	CU_ASSERT(g_bserrno == 0);
3518 	g_bserrno = -1;
3519 	spdk_blob_sync_md(blob_data_ro, blob_op_complete, NULL);
3520 	CU_ASSERT(g_bserrno == 0);
3521 	g_bserrno = -1;
3522 	spdk_blob_sync_md(blob_md_ro, blob_op_complete, NULL);
3523 	CU_ASSERT(g_bserrno == 0);
3524 
3525 	g_bserrno = -1;
3526 	spdk_blob_close(blob_invalid, blob_op_complete, NULL);
3527 	CU_ASSERT(g_bserrno == 0);
3528 	blob_invalid = NULL;
3529 	g_bserrno = -1;
3530 	spdk_blob_close(blob_data_ro, blob_op_complete, NULL);
3531 	CU_ASSERT(g_bserrno == 0);
3532 	blob_data_ro = NULL;
3533 	g_bserrno = -1;
3534 	spdk_blob_close(blob_md_ro, blob_op_complete, NULL);
3535 	CU_ASSERT(g_bserrno == 0);
3536 	blob_md_ro = NULL;
3537 
3538 	g_blob = NULL;
3539 	g_blobid = SPDK_BLOBID_INVALID;
3540 
3541 	/* Unload the blob store */
3542 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3543 	CU_ASSERT(g_bserrno == 0);
3544 	g_bs = NULL;
3545 
3546 	/* Load an existing blob store */
3547 	dev = init_dev();
3548 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
3549 	CU_ASSERT(g_bserrno == 0);
3550 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3551 
3552 	g_blob = NULL;
3553 	g_bserrno = 0;
3554 	spdk_bs_open_blob(g_bs, blobid_invalid, blob_op_with_handle_complete, NULL);
3555 	CU_ASSERT(g_bserrno != 0);
3556 	CU_ASSERT(g_blob == NULL);
3557 
3558 	g_blob = NULL;
3559 	g_bserrno = -1;
3560 	spdk_bs_open_blob(g_bs, blobid_data_ro, blob_op_with_handle_complete, NULL);
3561 	CU_ASSERT(g_bserrno == 0);
3562 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3563 	blob_data_ro = g_blob;
3564 	/* If an unknown data_ro flag was found, the blob should be marked both data and md read-only. */
3565 	CU_ASSERT(blob_data_ro->data_ro == true);
3566 	CU_ASSERT(blob_data_ro->md_ro == true);
3567 	CU_ASSERT(spdk_blob_get_num_clusters(blob_data_ro) == 10);
3568 
3569 	g_blob = NULL;
3570 	g_bserrno = -1;
3571 	spdk_bs_open_blob(g_bs, blobid_md_ro, blob_op_with_handle_complete, NULL);
3572 	CU_ASSERT(g_bserrno == 0);
3573 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3574 	blob_md_ro = g_blob;
3575 	CU_ASSERT(blob_md_ro->data_ro == false);
3576 	CU_ASSERT(blob_md_ro->md_ro == true);
3577 
3578 	g_bserrno = -1;
3579 	spdk_blob_sync_md(blob_md_ro, blob_op_complete, NULL);
3580 	CU_ASSERT(g_bserrno == 0);
3581 
3582 	spdk_blob_close(blob_data_ro, blob_op_complete, NULL);
3583 	CU_ASSERT(g_bserrno == 0);
3584 	spdk_blob_close(blob_md_ro, blob_op_complete, NULL);
3585 	CU_ASSERT(g_bserrno == 0);
3586 
3587 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3588 	CU_ASSERT(g_bserrno == 0);
3589 }
3590 
3591 static void
3592 bs_version(void)
3593 {
3594 	struct spdk_bs_super_block *super;
3595 	struct spdk_bs_dev *dev;
3596 	struct spdk_bs_opts opts;
3597 	spdk_blob_id blobid;
3598 
3599 	dev = init_dev();
3600 	spdk_bs_opts_init(&opts);
3601 
3602 	/* Initialize a new blob store */
3603 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
3604 	CU_ASSERT(g_bserrno == 0);
3605 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3606 
3607 	/* Unload the blob store */
3608 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3609 	CU_ASSERT(g_bserrno == 0);
3610 	g_bs = NULL;
3611 
3612 	/*
3613 	 * Change the bs version on disk.  This will allow us to
3614 	 *  test that the version does not get modified automatically
3615 	 *  when loading and unloading the blobstore.
3616 	 */
3617 	super = (struct spdk_bs_super_block *)&g_dev_buffer[0];
3618 	CU_ASSERT(super->version == SPDK_BS_VERSION);
3619 	CU_ASSERT(super->clean == 1);
3620 	super->version = 2;
3621 	/*
3622 	 * Version 2 metadata does not have a used blobid mask, so clear
3623 	 *  those fields in the super block and zero the corresponding
3624 	 *  region on "disk".  We will use this to ensure blob IDs are
3625 	 *  correctly reconstructed.
3626 	 */
3627 	memset(&g_dev_buffer[super->used_blobid_mask_start * SPDK_BS_PAGE_SIZE], 0,
3628 	       super->used_blobid_mask_len * SPDK_BS_PAGE_SIZE);
3629 	super->used_blobid_mask_start = 0;
3630 	super->used_blobid_mask_len = 0;
3631 	super->crc = _spdk_blob_md_page_calc_crc(super);
3632 
3633 	/* Load an existing blob store */
3634 	dev = init_dev();
3635 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
3636 	CU_ASSERT(g_bserrno == 0);
3637 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3638 	CU_ASSERT(super->clean == 1);
3639 
3640 	/*
3641 	 * Create a blob - just to make sure that when we unload it
3642 	 *  results in writing the super block (since metadata pages
3643 	 *  were allocated.
3644 	 */
3645 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
3646 	CU_ASSERT(g_bserrno == 0);
3647 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3648 	blobid = g_blobid;
3649 
3650 	/* Unload the blob store */
3651 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3652 	CU_ASSERT(g_bserrno == 0);
3653 	g_bs = NULL;
3654 	CU_ASSERT(super->version == 2);
3655 	CU_ASSERT(super->used_blobid_mask_start == 0);
3656 	CU_ASSERT(super->used_blobid_mask_len == 0);
3657 
3658 	dev = init_dev();
3659 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
3660 	CU_ASSERT(g_bserrno == 0);
3661 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3662 
3663 	g_blob = NULL;
3664 	spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
3665 	CU_ASSERT(g_bserrno == 0);
3666 	CU_ASSERT(g_blob != NULL);
3667 
3668 	spdk_blob_close(g_blob, blob_op_complete, NULL);
3669 	CU_ASSERT(g_bserrno == 0);
3670 
3671 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3672 	CU_ASSERT(g_bserrno == 0);
3673 	g_bs = NULL;
3674 	CU_ASSERT(super->version == 2);
3675 	CU_ASSERT(super->used_blobid_mask_start == 0);
3676 	CU_ASSERT(super->used_blobid_mask_len == 0);
3677 }
3678 
3679 static void
3680 blob_set_xattrs(void)
3681 {
3682 	struct spdk_blob_store *bs;
3683 	struct spdk_bs_dev *dev;
3684 	struct spdk_blob *blob;
3685 	struct spdk_blob_opts opts;
3686 	spdk_blob_id blobid;
3687 	const void *value;
3688 	size_t value_len;
3689 	int rc;
3690 
3691 	dev = init_dev();
3692 
3693 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
3694 	CU_ASSERT(g_bserrno == 0);
3695 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3696 	bs = g_bs;
3697 
3698 	/* Create blob with extra attributes */
3699 	spdk_blob_opts_init(&opts);
3700 
3701 	opts.xattrs.names = g_xattr_names;
3702 	opts.xattrs.get_value = _get_xattr_value;
3703 	opts.xattrs.count = 3;
3704 	opts.xattrs.ctx = &g_ctx;
3705 
3706 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
3707 	CU_ASSERT(g_bserrno == 0);
3708 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3709 	blobid = g_blobid;
3710 
3711 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
3712 	CU_ASSERT(g_bserrno == 0);
3713 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3714 	blob = g_blob;
3715 
3716 	/* Get the xattrs */
3717 	value = NULL;
3718 
3719 	rc = spdk_blob_get_xattr_value(blob, g_xattr_names[0], &value, &value_len);
3720 	CU_ASSERT(rc == 0);
3721 	SPDK_CU_ASSERT_FATAL(value != NULL);
3722 	CU_ASSERT(value_len == strlen(g_xattr_values[0]));
3723 	CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len);
3724 
3725 	rc = spdk_blob_get_xattr_value(blob, g_xattr_names[1], &value, &value_len);
3726 	CU_ASSERT(rc == 0);
3727 	SPDK_CU_ASSERT_FATAL(value != NULL);
3728 	CU_ASSERT(value_len == strlen(g_xattr_values[1]));
3729 	CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len);
3730 
3731 	rc = spdk_blob_get_xattr_value(blob, g_xattr_names[2], &value, &value_len);
3732 	CU_ASSERT(rc == 0);
3733 	SPDK_CU_ASSERT_FATAL(value != NULL);
3734 	CU_ASSERT(value_len == strlen(g_xattr_values[2]));
3735 	CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len);
3736 
3737 	/* Try to get non existing attribute */
3738 
3739 	rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len);
3740 	CU_ASSERT(rc == -ENOENT);
3741 
3742 	spdk_blob_close(blob, blob_op_complete, NULL);
3743 	CU_ASSERT(g_bserrno == 0);
3744 	blob = NULL;
3745 	g_blob = NULL;
3746 	g_blobid = SPDK_BLOBID_INVALID;
3747 
3748 	/* NULL callback */
3749 	spdk_blob_opts_init(&opts);
3750 	opts.xattrs.names = g_xattr_names;
3751 	opts.xattrs.get_value = NULL;
3752 	opts.xattrs.count = 1;
3753 	opts.xattrs.ctx = &g_ctx;
3754 
3755 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
3756 	CU_ASSERT(g_bserrno == -EINVAL);
3757 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3758 
3759 	/* NULL values */
3760 	spdk_blob_opts_init(&opts);
3761 	opts.xattrs.names = g_xattr_names;
3762 	opts.xattrs.get_value = _get_xattr_value_null;
3763 	opts.xattrs.count = 1;
3764 	opts.xattrs.ctx = NULL;
3765 
3766 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
3767 	CU_ASSERT(g_bserrno == -EINVAL);
3768 
3769 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3770 	CU_ASSERT(g_bserrno == 0);
3771 	g_bs = NULL;
3772 
3773 }
3774 
3775 static void
3776 blob_thin_prov_alloc(void)
3777 {
3778 	struct spdk_blob_store *bs;
3779 	struct spdk_bs_dev *dev;
3780 	struct spdk_blob *blob;
3781 	struct spdk_blob_opts opts;
3782 	spdk_blob_id blobid;
3783 	uint64_t free_clusters;
3784 
3785 	dev = init_dev();
3786 
3787 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
3788 	CU_ASSERT(g_bserrno == 0);
3789 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3790 	bs = g_bs;
3791 	free_clusters = spdk_bs_free_cluster_count(bs);
3792 
3793 	/* Set blob as thin provisioned */
3794 	spdk_blob_opts_init(&opts);
3795 	opts.thin_provision = true;
3796 
3797 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
3798 	CU_ASSERT(g_bserrno == 0);
3799 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3800 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3801 	blobid = g_blobid;
3802 
3803 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
3804 	CU_ASSERT(g_bserrno == 0);
3805 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3806 	blob = g_blob;
3807 
3808 	CU_ASSERT(blob->active.num_clusters == 0);
3809 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0);
3810 
3811 	/* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */
3812 	spdk_blob_resize(blob, 5, blob_op_complete, NULL);
3813 	CU_ASSERT(g_bserrno == 0);
3814 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3815 	CU_ASSERT(blob->active.num_clusters == 5);
3816 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5);
3817 
3818 	/* Grow it to 1TB - still unallocated */
3819 	spdk_blob_resize(blob, 262144, blob_op_complete, NULL);
3820 	CU_ASSERT(g_bserrno == 0);
3821 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3822 	CU_ASSERT(blob->active.num_clusters == 262144);
3823 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 262144);
3824 
3825 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
3826 	CU_ASSERT(g_bserrno == 0);
3827 	/* Sync must not change anything */
3828 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3829 	CU_ASSERT(blob->active.num_clusters == 262144);
3830 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 262144);
3831 	/* Since clusters are not allocated,
3832 	 * number of metadata pages is expected to be minimal.
3833 	 */
3834 	CU_ASSERT(blob->active.num_pages == 1);
3835 
3836 	/* Shrink the blob to 3 clusters - still unallocated */
3837 	spdk_blob_resize(blob, 3, blob_op_complete, NULL);
3838 	CU_ASSERT(g_bserrno == 0);
3839 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3840 	CU_ASSERT(blob->active.num_clusters == 3);
3841 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 3);
3842 
3843 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
3844 	CU_ASSERT(g_bserrno == 0);
3845 	/* Sync must not change anything */
3846 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3847 	CU_ASSERT(blob->active.num_clusters == 3);
3848 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 3);
3849 
3850 	spdk_blob_close(blob, blob_op_complete, NULL);
3851 	CU_ASSERT(g_bserrno == 0);
3852 
3853 	/* Unload the blob store */
3854 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3855 	CU_ASSERT(g_bserrno == 0);
3856 	g_bs = NULL;
3857 	g_blob = NULL;
3858 	g_blobid = 0;
3859 
3860 	/* Load an existing blob store */
3861 	dev = init_dev();
3862 	spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL);
3863 	CU_ASSERT(g_bserrno == 0);
3864 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3865 
3866 	bs = g_bs;
3867 
3868 	spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
3869 	CU_ASSERT(g_bserrno == 0);
3870 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3871 	blob = g_blob;
3872 
3873 	/* Check that clusters allocation and size is still the same */
3874 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3875 	CU_ASSERT(blob->active.num_clusters == 3);
3876 
3877 	spdk_blob_close(blob, blob_op_complete, NULL);
3878 	CU_ASSERT(g_bserrno == 0);
3879 
3880 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
3881 	CU_ASSERT(g_bserrno == 0);
3882 
3883 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3884 	CU_ASSERT(g_bserrno == 0);
3885 	g_bs = NULL;
3886 }
3887 
3888 static void
3889 blob_insert_cluster_msg(void)
3890 {
3891 	struct spdk_blob_store *bs;
3892 	struct spdk_bs_dev *dev;
3893 	struct spdk_blob *blob;
3894 	struct spdk_blob_opts opts;
3895 	spdk_blob_id blobid;
3896 	uint64_t free_clusters;
3897 
3898 	dev = init_dev();
3899 
3900 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
3901 	CU_ASSERT(g_bserrno == 0);
3902 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3903 	bs = g_bs;
3904 	free_clusters = spdk_bs_free_cluster_count(bs);
3905 
3906 	/* Set blob as thin provisioned */
3907 	spdk_blob_opts_init(&opts);
3908 	opts.thin_provision = true;
3909 	opts.num_clusters = 4;
3910 
3911 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
3912 	CU_ASSERT(g_bserrno == 0);
3913 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3914 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3915 	blobid = g_blobid;
3916 
3917 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
3918 	CU_ASSERT(g_bserrno == 0);
3919 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3920 	blob = g_blob;
3921 
3922 	CU_ASSERT(blob->active.num_clusters == 4);
3923 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 4);
3924 	CU_ASSERT(blob->active.clusters[1] == 0);
3925 
3926 	_spdk_bs_claim_cluster(bs, 0xF);
3927 	_spdk_blob_insert_cluster_on_md_thread(blob, 1, 0xF, blob_op_complete, NULL);
3928 
3929 	CU_ASSERT(blob->active.clusters[1] != 0);
3930 
3931 	spdk_blob_close(blob, blob_op_complete, NULL);
3932 	CU_ASSERT(g_bserrno == 0);
3933 
3934 	/* Unload the blob store */
3935 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3936 	CU_ASSERT(g_bserrno == 0);
3937 	g_bs = NULL;
3938 	g_blob = NULL;
3939 	g_blobid = 0;
3940 
3941 	/* Load an existing blob store */
3942 	dev = init_dev();
3943 	spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL);
3944 	CU_ASSERT(g_bserrno == 0);
3945 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3946 
3947 	bs = g_bs;
3948 
3949 	spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
3950 	CU_ASSERT(g_bserrno == 0);
3951 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3952 	blob = g_blob;
3953 
3954 	CU_ASSERT(blob->active.clusters[1] != 0);
3955 
3956 	spdk_blob_close(blob, blob_op_complete, NULL);
3957 	CU_ASSERT(g_bserrno == 0);
3958 
3959 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
3960 	CU_ASSERT(g_bserrno == 0);
3961 
3962 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3963 	CU_ASSERT(g_bserrno == 0);
3964 	g_bs = NULL;
3965 }
3966 
3967 static void
3968 blob_thin_prov_rw(void)
3969 {
3970 	static const uint8_t zero[10 * 4096] = { 0 };
3971 	struct spdk_blob_store *bs;
3972 	struct spdk_bs_dev *dev;
3973 	struct spdk_blob *blob;
3974 	struct spdk_io_channel *channel;
3975 	struct spdk_blob_opts opts;
3976 	spdk_blob_id blobid;
3977 	uint64_t free_clusters;
3978 	uint64_t page_size;
3979 	uint8_t payload_read[10 * 4096];
3980 	uint8_t payload_write[10 * 4096];
3981 	uint64_t write_bytes;
3982 	uint64_t read_bytes;
3983 
3984 	dev = init_dev();
3985 
3986 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
3987 	CU_ASSERT(g_bserrno == 0);
3988 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3989 	bs = g_bs;
3990 	free_clusters = spdk_bs_free_cluster_count(bs);
3991 	page_size = spdk_bs_get_page_size(bs);
3992 
3993 	channel = spdk_bs_alloc_io_channel(bs);
3994 	CU_ASSERT(channel != NULL);
3995 
3996 	spdk_blob_opts_init(&opts);
3997 	opts.thin_provision = true;
3998 
3999 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
4000 	CU_ASSERT(g_bserrno == 0);
4001 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
4002 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
4003 	blobid = g_blobid;
4004 
4005 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
4006 	CU_ASSERT(g_bserrno == 0);
4007 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4008 	blob = g_blob;
4009 
4010 	CU_ASSERT(blob->active.num_clusters == 0);
4011 
4012 	/* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */
4013 	spdk_blob_resize(blob, 5, blob_op_complete, NULL);
4014 	CU_ASSERT(g_bserrno == 0);
4015 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
4016 	CU_ASSERT(blob->active.num_clusters == 5);
4017 
4018 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
4019 	CU_ASSERT(g_bserrno == 0);
4020 	/* Sync must not change anything */
4021 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
4022 	CU_ASSERT(blob->active.num_clusters == 5);
4023 
4024 	/* Payload should be all zeros from unallocated clusters */
4025 	memset(payload_read, 0xFF, sizeof(payload_read));
4026 	spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL);
4027 	CU_ASSERT(g_bserrno == 0);
4028 	CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0);
4029 
4030 	write_bytes = g_dev_write_bytes;
4031 	read_bytes = g_dev_read_bytes;
4032 
4033 	memset(payload_write, 0xE5, sizeof(payload_write));
4034 	spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL);
4035 	CU_ASSERT(g_bserrno == 0);
4036 	CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs));
4037 	/* For thin-provisioned blob we need to write 10 pages plus one page metadata and
4038 	 * read 0 bytes */
4039 	CU_ASSERT(g_dev_write_bytes - write_bytes == page_size * 11);
4040 	CU_ASSERT(g_dev_read_bytes - read_bytes == 0);
4041 
4042 	spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL);
4043 	CU_ASSERT(g_bserrno == 0);
4044 	CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0);
4045 
4046 	spdk_blob_close(blob, blob_op_complete, NULL);
4047 	CU_ASSERT(g_bserrno == 0);
4048 
4049 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
4050 	CU_ASSERT(g_bserrno == 0);
4051 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
4052 
4053 	spdk_bs_free_io_channel(channel);
4054 
4055 	/* Unload the blob store */
4056 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
4057 	CU_ASSERT(g_bserrno == 0);
4058 	g_bs = NULL;
4059 	g_blob = NULL;
4060 	g_blobid = 0;
4061 }
4062 
4063 static void
4064 blob_thin_prov_rw_iov(void)
4065 {
4066 	static const uint8_t zero[10 * 4096] = { 0 };
4067 	struct spdk_blob_store *bs;
4068 	struct spdk_bs_dev *dev;
4069 	struct spdk_blob *blob;
4070 	struct spdk_io_channel *channel;
4071 	struct spdk_blob_opts opts;
4072 	spdk_blob_id blobid;
4073 	uint64_t free_clusters;
4074 	uint8_t payload_read[10 * 4096];
4075 	uint8_t payload_write[10 * 4096];
4076 	struct iovec iov_read[3];
4077 	struct iovec iov_write[3];
4078 
4079 	dev = init_dev();
4080 
4081 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
4082 	CU_ASSERT(g_bserrno == 0);
4083 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
4084 	bs = g_bs;
4085 	free_clusters = spdk_bs_free_cluster_count(bs);
4086 
4087 	channel = spdk_bs_alloc_io_channel(bs);
4088 	CU_ASSERT(channel != NULL);
4089 
4090 	spdk_blob_opts_init(&opts);
4091 	opts.thin_provision = true;
4092 
4093 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
4094 	CU_ASSERT(g_bserrno == 0);
4095 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
4096 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
4097 	blobid = g_blobid;
4098 
4099 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
4100 	CU_ASSERT(g_bserrno == 0);
4101 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4102 	blob = g_blob;
4103 
4104 	CU_ASSERT(blob->active.num_clusters == 0);
4105 
4106 	/* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */
4107 	spdk_blob_resize(blob, 5, blob_op_complete, NULL);
4108 	CU_ASSERT(g_bserrno == 0);
4109 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
4110 	CU_ASSERT(blob->active.num_clusters == 5);
4111 
4112 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
4113 	CU_ASSERT(g_bserrno == 0);
4114 	/* Sync must not change anything */
4115 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
4116 	CU_ASSERT(blob->active.num_clusters == 5);
4117 
4118 	/* Payload should be all zeros from unallocated clusters */
4119 	memset(payload_read, 0xAA, sizeof(payload_read));
4120 	iov_read[0].iov_base = payload_read;
4121 	iov_read[0].iov_len = 3 * 4096;
4122 	iov_read[1].iov_base = payload_read + 3 * 4096;
4123 	iov_read[1].iov_len = 4 * 4096;
4124 	iov_read[2].iov_base = payload_read + 7 * 4096;
4125 	iov_read[2].iov_len = 3 * 4096;
4126 	spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL);
4127 	CU_ASSERT(g_bserrno == 0);
4128 	CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0);
4129 
4130 	memset(payload_write, 0xE5, sizeof(payload_write));
4131 	iov_write[0].iov_base = payload_write;
4132 	iov_write[0].iov_len = 1 * 4096;
4133 	iov_write[1].iov_base = payload_write + 1 * 4096;
4134 	iov_write[1].iov_len = 5 * 4096;
4135 	iov_write[2].iov_base = payload_write + 6 * 4096;
4136 	iov_write[2].iov_len = 4 * 4096;
4137 
4138 	spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL);
4139 	CU_ASSERT(g_bserrno == 0);
4140 
4141 	memset(payload_read, 0xAA, sizeof(payload_read));
4142 	iov_read[0].iov_base = payload_read;
4143 	iov_read[0].iov_len = 3 * 4096;
4144 	iov_read[1].iov_base = payload_read + 3 * 4096;
4145 	iov_read[1].iov_len = 4 * 4096;
4146 	iov_read[2].iov_base = payload_read + 7 * 4096;
4147 	iov_read[2].iov_len = 3 * 4096;
4148 	spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL);
4149 	CU_ASSERT(g_bserrno == 0);
4150 	CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0);
4151 
4152 	spdk_blob_close(blob, blob_op_complete, NULL);
4153 	CU_ASSERT(g_bserrno == 0);
4154 
4155 	spdk_bs_free_io_channel(channel);
4156 
4157 	/* Unload the blob store */
4158 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
4159 	CU_ASSERT(g_bserrno == 0);
4160 	g_bs = NULL;
4161 	g_blob = NULL;
4162 	g_blobid = 0;
4163 }
4164 
4165 struct iter_ctx {
4166 	int		current_iter;
4167 	spdk_blob_id	blobid[4];
4168 };
4169 
4170 static void
4171 test_iter(void *arg, struct spdk_blob *blob, int bserrno)
4172 {
4173 	struct iter_ctx *iter_ctx = arg;
4174 	spdk_blob_id blobid;
4175 
4176 	CU_ASSERT(bserrno == 0);
4177 	blobid = spdk_blob_get_id(blob);
4178 	CU_ASSERT(blobid == iter_ctx->blobid[iter_ctx->current_iter++]);
4179 }
4180 
4181 static void
4182 bs_load_iter(void)
4183 {
4184 	struct spdk_bs_dev *dev;
4185 	struct iter_ctx iter_ctx = { 0 };
4186 	struct spdk_blob *blob;
4187 	int i, rc;
4188 	struct spdk_bs_opts opts;
4189 
4190 	dev = init_dev();
4191 	spdk_bs_opts_init(&opts);
4192 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
4193 
4194 	/* Initialize a new blob store */
4195 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
4196 	CU_ASSERT(g_bserrno == 0);
4197 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
4198 
4199 	for (i = 0; i < 4; i++) {
4200 		g_bserrno = -1;
4201 		g_blobid = SPDK_BLOBID_INVALID;
4202 		spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
4203 		CU_ASSERT(g_bserrno == 0);
4204 		CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
4205 		iter_ctx.blobid[i] = g_blobid;
4206 
4207 		g_bserrno = -1;
4208 		g_blob = NULL;
4209 		spdk_bs_open_blob(g_bs, g_blobid, blob_op_with_handle_complete, NULL);
4210 		CU_ASSERT(g_bserrno == 0);
4211 		CU_ASSERT(g_blob != NULL);
4212 		blob = g_blob;
4213 
4214 		/* Just save the blobid as an xattr for testing purposes. */
4215 		rc = spdk_blob_set_xattr(blob, "blobid", &g_blobid, sizeof(g_blobid));
4216 		CU_ASSERT(rc == 0);
4217 
4218 		/* Resize the blob */
4219 		spdk_blob_resize(blob, i, blob_op_complete, NULL);
4220 		CU_ASSERT(g_bserrno == 0);
4221 
4222 		spdk_blob_close(blob, blob_op_complete, NULL);
4223 		CU_ASSERT(g_bserrno == 0);
4224 	}
4225 
4226 	g_bserrno = -1;
4227 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
4228 	CU_ASSERT(g_bserrno == 0);
4229 
4230 	dev = init_dev();
4231 	spdk_bs_opts_init(&opts);
4232 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
4233 	opts.iter_cb_fn = test_iter;
4234 	opts.iter_cb_arg = &iter_ctx;
4235 
4236 	/* Test blob iteration during load after a clean shutdown. */
4237 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
4238 	CU_ASSERT(g_bserrno == 0);
4239 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
4240 
4241 	/* Dirty shutdown */
4242 	_spdk_bs_free(g_bs);
4243 
4244 	dev = init_dev();
4245 	spdk_bs_opts_init(&opts);
4246 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
4247 	opts.iter_cb_fn = test_iter;
4248 	iter_ctx.current_iter = 0;
4249 	opts.iter_cb_arg = &iter_ctx;
4250 
4251 	/* Test blob iteration during load after a dirty shutdown. */
4252 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
4253 	CU_ASSERT(g_bserrno == 0);
4254 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
4255 
4256 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
4257 	CU_ASSERT(g_bserrno == 0);
4258 	g_bs = NULL;
4259 }
4260 
4261 static void
4262 blob_snapshot_rw(void)
4263 {
4264 	static const uint8_t zero[10 * 4096] = { 0 };
4265 	struct spdk_blob_store *bs;
4266 	struct spdk_bs_dev *dev;
4267 	struct spdk_blob *blob, *snapshot;
4268 	struct spdk_io_channel *channel;
4269 	struct spdk_blob_opts opts;
4270 	spdk_blob_id blobid, snapshotid;
4271 	uint64_t free_clusters;
4272 	uint64_t cluster_size;
4273 	uint64_t page_size;
4274 	uint8_t payload_read[10 * 4096];
4275 	uint8_t payload_write[10 * 4096];
4276 	uint64_t write_bytes;
4277 	uint64_t read_bytes;
4278 
4279 	dev = init_dev();
4280 
4281 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
4282 	CU_ASSERT(g_bserrno == 0);
4283 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
4284 	bs = g_bs;
4285 	free_clusters = spdk_bs_free_cluster_count(bs);
4286 	cluster_size = spdk_bs_get_cluster_size(bs);
4287 	page_size = spdk_bs_get_page_size(bs);
4288 
4289 	channel = spdk_bs_alloc_io_channel(bs);
4290 	CU_ASSERT(channel != NULL);
4291 
4292 	spdk_blob_opts_init(&opts);
4293 	opts.thin_provision = true;
4294 	opts.num_clusters = 5;
4295 
4296 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
4297 	CU_ASSERT(g_bserrno == 0);
4298 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
4299 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
4300 	blobid = g_blobid;
4301 
4302 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
4303 	CU_ASSERT(g_bserrno == 0);
4304 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4305 	blob = g_blob;
4306 
4307 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5);
4308 
4309 	memset(payload_read, 0xFF, sizeof(payload_read));
4310 	spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL);
4311 	CU_ASSERT(g_bserrno == 0);
4312 	CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0);
4313 
4314 	memset(payload_write, 0xE5, sizeof(payload_write));
4315 	spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL);
4316 	CU_ASSERT(g_bserrno == 0);
4317 	CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs));
4318 
4319 	/* Create snapshot from blob */
4320 	spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL);
4321 	CU_ASSERT(g_bserrno == 0);
4322 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
4323 	snapshotid = g_blobid;
4324 
4325 	spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL);
4326 	CU_ASSERT(g_bserrno == 0);
4327 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4328 	snapshot = g_blob;
4329 	CU_ASSERT(snapshot->data_ro == true)
4330 	CU_ASSERT(snapshot->md_ro == true)
4331 
4332 	CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 5)
4333 
4334 	write_bytes = g_dev_write_bytes;
4335 	read_bytes = g_dev_read_bytes;
4336 
4337 	memset(payload_write, 0xAA, sizeof(payload_write));
4338 	spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL);
4339 	CU_ASSERT(g_bserrno == 0);
4340 	CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs));
4341 
4342 	/* For a clone we need to allocate and copy one cluster, update one page of metadata
4343 	 * and then write 10 pages of payload.
4344 	 */
4345 	CU_ASSERT(g_dev_write_bytes - write_bytes == page_size * 11 + cluster_size);
4346 	CU_ASSERT(g_dev_read_bytes - read_bytes == cluster_size);
4347 
4348 	spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL);
4349 	CU_ASSERT(g_bserrno == 0);
4350 	CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0);
4351 
4352 	/* Data on snapshot should not change after write to clone */
4353 	memset(payload_write, 0xE5, sizeof(payload_write));
4354 	spdk_blob_io_read(snapshot, channel, payload_read, 4, 10, blob_op_complete, NULL);
4355 	CU_ASSERT(g_bserrno == 0);
4356 	CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0);
4357 
4358 	spdk_blob_close(blob, blob_op_complete, NULL);
4359 	CU_ASSERT(g_bserrno == 0);
4360 
4361 	spdk_blob_close(snapshot, blob_op_complete, NULL);
4362 	CU_ASSERT(g_bserrno == 0);
4363 
4364 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
4365 	CU_ASSERT(g_bserrno == 0);
4366 
4367 	spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL);
4368 	CU_ASSERT(g_bserrno == 0);
4369 
4370 	spdk_bs_free_io_channel(channel);
4371 
4372 	/* Unload the blob store */
4373 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
4374 	CU_ASSERT(g_bserrno == 0);
4375 	g_bs = NULL;
4376 	g_blob = NULL;
4377 	g_blobid = 0;
4378 }
4379 
4380 static void
4381 blob_snapshot_rw_iov(void)
4382 {
4383 	static const uint8_t zero[10 * 4096] = { 0 };
4384 	struct spdk_blob_store *bs;
4385 	struct spdk_bs_dev *dev;
4386 	struct spdk_blob *blob, *snapshot;
4387 	struct spdk_io_channel *channel;
4388 	struct spdk_blob_opts opts;
4389 	spdk_blob_id blobid, snapshotid;
4390 	uint64_t free_clusters;
4391 	uint8_t payload_read[10 * 4096];
4392 	uint8_t payload_write[10 * 4096];
4393 	struct iovec iov_read[3];
4394 	struct iovec iov_write[3];
4395 
4396 	dev = init_dev();
4397 
4398 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
4399 	CU_ASSERT(g_bserrno == 0);
4400 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
4401 	bs = g_bs;
4402 	free_clusters = spdk_bs_free_cluster_count(bs);
4403 
4404 	channel = spdk_bs_alloc_io_channel(bs);
4405 	CU_ASSERT(channel != NULL);
4406 
4407 	spdk_blob_opts_init(&opts);
4408 	opts.thin_provision = true;
4409 	opts.num_clusters = 5;
4410 
4411 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
4412 	CU_ASSERT(g_bserrno == 0);
4413 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
4414 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
4415 	blobid = g_blobid;
4416 
4417 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
4418 	CU_ASSERT(g_bserrno == 0);
4419 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4420 	blob = g_blob;
4421 
4422 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5);
4423 
4424 	/* Create snapshot from blob */
4425 	spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL);
4426 	CU_ASSERT(g_bserrno == 0);
4427 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
4428 	snapshotid = g_blobid;
4429 
4430 	spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL);
4431 	CU_ASSERT(g_bserrno == 0);
4432 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4433 	snapshot = g_blob;
4434 	CU_ASSERT(snapshot->data_ro == true)
4435 	CU_ASSERT(snapshot->md_ro == true)
4436 	CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 5);
4437 
4438 	/* Payload should be all zeros from unallocated clusters */
4439 	memset(payload_read, 0xAA, sizeof(payload_read));
4440 	iov_read[0].iov_base = payload_read;
4441 	iov_read[0].iov_len = 3 * 4096;
4442 	iov_read[1].iov_base = payload_read + 3 * 4096;
4443 	iov_read[1].iov_len = 4 * 4096;
4444 	iov_read[2].iov_base = payload_read + 7 * 4096;
4445 	iov_read[2].iov_len = 3 * 4096;
4446 	spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL);
4447 	CU_ASSERT(g_bserrno == 0);
4448 	CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0);
4449 
4450 	memset(payload_write, 0xE5, sizeof(payload_write));
4451 	iov_write[0].iov_base = payload_write;
4452 	iov_write[0].iov_len = 1 * 4096;
4453 	iov_write[1].iov_base = payload_write + 1 * 4096;
4454 	iov_write[1].iov_len = 5 * 4096;
4455 	iov_write[2].iov_base = payload_write + 6 * 4096;
4456 	iov_write[2].iov_len = 4 * 4096;
4457 
4458 	spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL);
4459 	CU_ASSERT(g_bserrno == 0);
4460 
4461 	memset(payload_read, 0xAA, sizeof(payload_read));
4462 	iov_read[0].iov_base = payload_read;
4463 	iov_read[0].iov_len = 3 * 4096;
4464 	iov_read[1].iov_base = payload_read + 3 * 4096;
4465 	iov_read[1].iov_len = 4 * 4096;
4466 	iov_read[2].iov_base = payload_read + 7 * 4096;
4467 	iov_read[2].iov_len = 3 * 4096;
4468 	spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL);
4469 	CU_ASSERT(g_bserrno == 0);
4470 	CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0);
4471 
4472 	spdk_blob_close(blob, blob_op_complete, NULL);
4473 	CU_ASSERT(g_bserrno == 0);
4474 
4475 	spdk_blob_close(snapshot, blob_op_complete, NULL);
4476 	CU_ASSERT(g_bserrno == 0);
4477 
4478 	spdk_bs_free_io_channel(channel);
4479 
4480 	/* Unload the blob store */
4481 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
4482 	CU_ASSERT(g_bserrno == 0);
4483 	g_bs = NULL;
4484 	g_blob = NULL;
4485 	g_blobid = 0;
4486 }
4487 
4488 /**
4489  * Inflate / decouple parent rw unit tests.
4490  *
4491  * --------------
4492  * original blob:         0         1         2         3         4
4493  *                   ,---------+---------+---------+---------+---------.
4494  *         snapshot  |xxxxxxxxx|xxxxxxxxx|xxxxxxxxx|xxxxxxxxx|    -    |
4495  *                   +---------+---------+---------+---------+---------+
4496  *         snapshot2 |    -    |yyyyyyyyy|    -    |yyyyyyyyy|    -    |
4497  *                   +---------+---------+---------+---------+---------+
4498  *         blob      |    -    |zzzzzzzzz|    -    |    -    |    -    |
4499  *                   '---------+---------+---------+---------+---------'
4500  *                   .         .         .         .         .         .
4501  * --------          .         .         .         .         .         .
4502  * inflate:          .         .         .         .         .         .
4503  *                   ,---------+---------+---------+---------+---------.
4504  *         blob      |xxxxxxxxx|zzzzzzzzz|xxxxxxxxx|yyyyyyyyy|000000000|
4505  *                   '---------+---------+---------+---------+---------'
4506  *
4507  *         NOTE: needs to allocate 4 clusters, thin provisioning removed, dependency
4508  *               on snapshot2 and snapshot removed .         .         .
4509  *                   .         .         .         .         .         .
4510  * ----------------  .         .         .         .         .         .
4511  * decouple parent:  .         .         .         .         .         .
4512  *                   ,---------+---------+---------+---------+---------.
4513  *         snapshot  |xxxxxxxxx|xxxxxxxxx|xxxxxxxxx|xxxxxxxxx|    -    |
4514  *                   +---------+---------+---------+---------+---------+
4515  *         blob      |    -    |zzzzzzzzz|    -    |yyyyyyyyy|    -    |
4516  *                   '---------+---------+---------+---------+---------'
4517  *
4518  *         NOTE: needs to allocate 1 cluster, 3 clusters unallocated, dependency
4519  *               on snapshot2 removed and on snapshot still exists. Snapshot2
4520  *               should remain a clone of snapshot.
4521  */
4522 static void
4523 _blob_inflate_rw(bool decouple_parent)
4524 {
4525 	struct spdk_blob_store *bs;
4526 	struct spdk_bs_dev *dev;
4527 	struct spdk_blob *blob, *snapshot, *snapshot2;
4528 	struct spdk_io_channel *channel;
4529 	struct spdk_blob_opts opts;
4530 	spdk_blob_id blobid, snapshotid, snapshot2id;
4531 	uint64_t free_clusters;
4532 	uint64_t cluster_size;
4533 
4534 	uint64_t payload_size;
4535 	uint8_t *payload_read;
4536 	uint8_t *payload_write;
4537 	uint8_t *payload_clone;
4538 
4539 	uint64_t pages_per_cluster;
4540 	uint64_t pages_per_payload;
4541 
4542 	int i;
4543 	spdk_blob_id ids[2];
4544 	size_t count;
4545 
4546 	dev = init_dev();
4547 
4548 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
4549 	CU_ASSERT(g_bserrno == 0);
4550 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
4551 	bs = g_bs;
4552 
4553 	free_clusters = spdk_bs_free_cluster_count(bs);
4554 	cluster_size = spdk_bs_get_cluster_size(bs);
4555 	pages_per_cluster = cluster_size / spdk_bs_get_page_size(bs);
4556 	pages_per_payload = pages_per_cluster * 5;
4557 
4558 	payload_size = cluster_size * 5;
4559 
4560 	payload_read = malloc(payload_size);
4561 	SPDK_CU_ASSERT_FATAL(payload_read != NULL);
4562 
4563 	payload_write = malloc(payload_size);
4564 	SPDK_CU_ASSERT_FATAL(payload_write != NULL);
4565 
4566 	payload_clone = malloc(payload_size);
4567 	SPDK_CU_ASSERT_FATAL(payload_clone != NULL);
4568 
4569 	channel = spdk_bs_alloc_io_channel(bs);
4570 	SPDK_CU_ASSERT_FATAL(channel != NULL);
4571 
4572 	/* Create blob */
4573 	spdk_blob_opts_init(&opts);
4574 	opts.thin_provision = true;
4575 	opts.num_clusters = 5;
4576 
4577 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
4578 	CU_ASSERT(g_bserrno == 0);
4579 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
4580 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
4581 	blobid = g_blobid;
4582 
4583 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
4584 	CU_ASSERT(g_bserrno == 0);
4585 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4586 	blob = g_blob;
4587 
4588 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5);
4589 
4590 	/* 1) Initial read should return zeroed payload */
4591 	memset(payload_read, 0xFF, payload_size);
4592 	spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload,
4593 			  blob_op_complete, NULL);
4594 	CU_ASSERT(g_bserrno == 0);
4595 	CU_ASSERT(spdk_mem_all_zero(payload_read, payload_size));
4596 
4597 	/* Fill whole blob with a pattern, except last cluster (to be sure it
4598 	 * isn't allocated) */
4599 	memset(payload_write, 0xE5, payload_size - cluster_size);
4600 	spdk_blob_io_write(blob, channel, payload_write, 0, pages_per_payload -
4601 			   pages_per_cluster, blob_op_complete, NULL);
4602 	CU_ASSERT(g_bserrno == 0);
4603 	CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs));
4604 
4605 	/* 2) Create snapshot from blob (first level) */
4606 	spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL);
4607 	CU_ASSERT(g_bserrno == 0);
4608 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
4609 	snapshotid = g_blobid;
4610 
4611 	spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL);
4612 	CU_ASSERT(g_bserrno == 0);
4613 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4614 	snapshot = g_blob;
4615 	CU_ASSERT(snapshot->data_ro == true)
4616 	CU_ASSERT(snapshot->md_ro == true)
4617 
4618 	CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 5)
4619 
4620 	/* Write every second cluster with a pattern.
4621 	 *
4622 	 * Last cluster shouldn't be written, to be sure that snapshot nor clone
4623 	 * doesn't allocate it.
4624 	 *
4625 	 * payload_clone stores expected result on "blob" read at the time and
4626 	 * is used only to check data consistency on clone before and after
4627 	 * inflation. Initially we fill it with a backing snapshots pattern
4628 	 * used before.
4629 	 */
4630 	memset(payload_clone, 0xE5, payload_size - cluster_size);
4631 	memset(payload_clone + payload_size - cluster_size, 0x00, cluster_size);
4632 	memset(payload_write, 0xAA, payload_size);
4633 	for (i = 1; i < 5; i += 2) {
4634 		spdk_blob_io_write(blob, channel, payload_write, i * pages_per_cluster,
4635 				   pages_per_cluster, blob_op_complete, NULL);
4636 		CU_ASSERT(g_bserrno == 0);
4637 
4638 		/* Update expected result */
4639 		memcpy(payload_clone + (cluster_size * i), payload_write,
4640 		       cluster_size);
4641 	}
4642 	CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs));
4643 
4644 	/* Check data consistency on clone */
4645 	memset(payload_read, 0xFF, payload_size);
4646 	spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload,
4647 			  blob_op_complete, NULL);
4648 	CU_ASSERT(g_bserrno == 0);
4649 	CU_ASSERT(memcmp(payload_clone, payload_read, payload_size) == 0);
4650 
4651 	/* 3) Create second levels snapshot from blob */
4652 	spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL);
4653 	CU_ASSERT(g_bserrno == 0);
4654 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
4655 	snapshot2id = g_blobid;
4656 
4657 	spdk_bs_open_blob(bs, snapshot2id, blob_op_with_handle_complete, NULL);
4658 	CU_ASSERT(g_bserrno == 0);
4659 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4660 	snapshot2 = g_blob;
4661 	CU_ASSERT(snapshot2->data_ro == true)
4662 	CU_ASSERT(snapshot2->md_ro == true)
4663 
4664 	CU_ASSERT(spdk_blob_get_num_clusters(snapshot2) == 5)
4665 
4666 	CU_ASSERT(snapshot2->parent_id == snapshotid);
4667 
4668 	/* Write one cluster on the top level blob. This cluster (1) covers
4669 	 * already allocated cluster in the snapshot2, so shouldn't be inflated
4670 	 * at all */
4671 	spdk_blob_io_write(blob, channel, payload_write, pages_per_cluster,
4672 			   pages_per_cluster, blob_op_complete, NULL);
4673 	CU_ASSERT(g_bserrno == 0);
4674 
4675 	/* Update expected result */
4676 	memcpy(payload_clone + cluster_size, payload_write, cluster_size);
4677 
4678 	/* Check data consistency on clone */
4679 	memset(payload_read, 0xFF, payload_size);
4680 	spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload,
4681 			  blob_op_complete, NULL);
4682 	CU_ASSERT(g_bserrno == 0);
4683 	CU_ASSERT(memcmp(payload_clone, payload_read, payload_size) == 0);
4684 
4685 
4686 	/* Close all blobs */
4687 	spdk_blob_close(blob, blob_op_complete, NULL);
4688 	CU_ASSERT(g_bserrno == 0);
4689 
4690 	spdk_blob_close(snapshot2, blob_op_complete, NULL);
4691 	CU_ASSERT(g_bserrno == 0);
4692 
4693 	spdk_blob_close(snapshot, blob_op_complete, NULL);
4694 	CU_ASSERT(g_bserrno == 0);
4695 
4696 	/* Check snapshot-clone relations */
4697 	count = 2;
4698 	CU_ASSERT(spdk_blob_get_clones(bs, snapshotid, ids, &count) == 0);
4699 	CU_ASSERT(count == 1);
4700 	CU_ASSERT(ids[0] == snapshot2id);
4701 
4702 	count = 2;
4703 	CU_ASSERT(spdk_blob_get_clones(bs, snapshot2id, ids, &count) == 0);
4704 	CU_ASSERT(count == 1);
4705 	CU_ASSERT(ids[0] == blobid);
4706 
4707 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshot2id);
4708 
4709 	free_clusters = spdk_bs_free_cluster_count(bs);
4710 	if (!decouple_parent) {
4711 		/* Do full blob inflation */
4712 		spdk_bs_inflate_blob(bs, channel, blobid, blob_op_complete, NULL);
4713 		CU_ASSERT(g_bserrno == 0);
4714 
4715 		/* All clusters should be inflated (except one already allocated
4716 		 * in a top level blob) */
4717 		CU_ASSERT(spdk_bs_free_cluster_count(bs) == free_clusters - 4);
4718 
4719 		/* Check if relation tree updated correctly */
4720 		count = 2;
4721 		CU_ASSERT(spdk_blob_get_clones(bs, snapshotid, ids, &count) == 0);
4722 
4723 		/* snapshotid have one clone */
4724 		CU_ASSERT(count == 1);
4725 		CU_ASSERT(ids[0] == snapshot2id);
4726 
4727 		/* snapshot2id have no clones */
4728 		count = 2;
4729 		CU_ASSERT(spdk_blob_get_clones(bs, snapshot2id, ids, &count) == 0);
4730 		CU_ASSERT(count == 0);
4731 
4732 		CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == SPDK_BLOBID_INVALID);
4733 	} else {
4734 		/* Decouple parent of blob */
4735 		spdk_bs_blob_decouple_parent(bs, channel, blobid, blob_op_complete, NULL);
4736 		CU_ASSERT(g_bserrno == 0);
4737 
4738 		/* Only one cluster from a parent should be inflated (second one
4739 		 * is covered by a cluster written on a top level blob, and
4740 		 * already allocated) */
4741 		CU_ASSERT(spdk_bs_free_cluster_count(bs) == free_clusters - 1);
4742 
4743 		/* Check if relation tree updated correctly */
4744 		count = 2;
4745 		CU_ASSERT(spdk_blob_get_clones(bs, snapshotid, ids, &count) == 0);
4746 
4747 		/* snapshotid have two clones now */
4748 		CU_ASSERT(count == 2);
4749 		CU_ASSERT(ids[0] == blobid || ids[1] == blobid);
4750 		CU_ASSERT(ids[0] == snapshot2id || ids[1] == snapshot2id);
4751 
4752 		/* snapshot2id have no clones */
4753 		count = 2;
4754 		CU_ASSERT(spdk_blob_get_clones(bs, snapshot2id, ids, &count) == 0);
4755 		CU_ASSERT(count == 0);
4756 
4757 		CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid);
4758 	}
4759 
4760 	/* Try to delete snapshot2 (should pass) */
4761 	spdk_bs_delete_blob(bs, snapshot2id, blob_op_complete, NULL);
4762 	CU_ASSERT(g_bserrno == 0);
4763 
4764 	/* Try to delete base snapshot (for decouple_parent should fail while
4765 	 * dependency still exists) */
4766 	spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL);
4767 	CU_ASSERT(decouple_parent || g_bserrno == 0);
4768 	CU_ASSERT(!decouple_parent || g_bserrno != 0);
4769 
4770 	/* Reopen blob after snapshot deletion */
4771 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
4772 	CU_ASSERT(g_bserrno == 0);
4773 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4774 	blob = g_blob;
4775 
4776 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5);
4777 
4778 	/* Check data consistency on inflated blob */
4779 	memset(payload_read, 0xFF, payload_size);
4780 	spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload,
4781 			  blob_op_complete, NULL);
4782 	CU_ASSERT(g_bserrno == 0);
4783 	CU_ASSERT(memcmp(payload_clone, payload_read, payload_size) == 0);
4784 
4785 	spdk_blob_close(blob, blob_op_complete, NULL);
4786 	CU_ASSERT(g_bserrno == 0);
4787 
4788 	spdk_bs_free_io_channel(channel);
4789 
4790 	/* Unload the blob store */
4791 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
4792 	CU_ASSERT(g_bserrno == 0);
4793 	g_bs = NULL;
4794 	g_blob = NULL;
4795 	g_blobid = 0;
4796 
4797 	free(payload_read);
4798 	free(payload_write);
4799 	free(payload_clone);
4800 }
4801 
4802 static void
4803 blob_inflate_rw(void)
4804 {
4805 	_blob_inflate_rw(false);
4806 	_blob_inflate_rw(true);
4807 }
4808 
4809 /**
4810  * Snapshot-clones relation test
4811  *
4812  *         snapshot
4813  *            |
4814  *      +-----+-----+
4815  *      |           |
4816  *   blob(ro)   snapshot2
4817  *      |           |
4818  *   clone2      clone
4819  */
4820 static void
4821 blob_relations(void)
4822 {
4823 	struct spdk_blob_store *bs;
4824 	struct spdk_bs_dev *dev;
4825 	struct spdk_bs_opts bs_opts;
4826 	struct spdk_blob_opts opts;
4827 	struct spdk_blob *blob, *snapshot, *snapshot2, *clone, *clone2;
4828 	spdk_blob_id blobid, cloneid, snapshotid, cloneid2, snapshotid2;
4829 	int rc;
4830 	size_t count;
4831 	spdk_blob_id ids[10] = {};
4832 
4833 	dev = init_dev();
4834 	spdk_bs_opts_init(&bs_opts);
4835 	snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE");
4836 
4837 	spdk_bs_init(dev, &bs_opts, bs_op_with_handle_complete, NULL);
4838 	CU_ASSERT(g_bserrno == 0);
4839 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
4840 	bs = g_bs;
4841 
4842 	/* 1. Create blob with 10 clusters */
4843 
4844 	spdk_blob_opts_init(&opts);
4845 	opts.num_clusters = 10;
4846 
4847 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
4848 	CU_ASSERT(g_bserrno == 0);
4849 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
4850 	blobid = g_blobid;
4851 
4852 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
4853 	CU_ASSERT(g_bserrno == 0);
4854 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4855 	blob = g_blob;
4856 
4857 	CU_ASSERT(!spdk_blob_is_read_only(blob));
4858 	CU_ASSERT(!spdk_blob_is_snapshot(blob));
4859 	CU_ASSERT(!spdk_blob_is_clone(blob));
4860 	CU_ASSERT(!spdk_blob_is_thin_provisioned(blob));
4861 
4862 	/* blob should not have underlying snapshot nor clones */
4863 	CU_ASSERT(blob->parent_id == SPDK_BLOBID_INVALID);
4864 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == SPDK_BLOBID_INVALID);
4865 	count = SPDK_COUNTOF(ids);
4866 	rc = spdk_blob_get_clones(bs, blobid, ids, &count);
4867 	CU_ASSERT(rc == 0);
4868 	CU_ASSERT(count == 0);
4869 
4870 
4871 	/* 2. Create snapshot */
4872 
4873 	spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL);
4874 	CU_ASSERT(g_bserrno == 0);
4875 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
4876 	snapshotid = g_blobid;
4877 
4878 	spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL);
4879 	CU_ASSERT(g_bserrno == 0);
4880 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4881 	snapshot = g_blob;
4882 
4883 	CU_ASSERT(spdk_blob_is_read_only(snapshot));
4884 	CU_ASSERT(spdk_blob_is_snapshot(snapshot));
4885 	CU_ASSERT(!spdk_blob_is_clone(snapshot));
4886 	CU_ASSERT(snapshot->parent_id == SPDK_BLOBID_INVALID);
4887 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid) == SPDK_BLOBID_INVALID);
4888 
4889 	/* Check if original blob is converted to the clone of snapshot */
4890 	CU_ASSERT(!spdk_blob_is_read_only(blob));
4891 	CU_ASSERT(!spdk_blob_is_snapshot(blob));
4892 	CU_ASSERT(spdk_blob_is_clone(blob));
4893 	CU_ASSERT(spdk_blob_is_thin_provisioned(blob));
4894 	CU_ASSERT(blob->parent_id == snapshotid);
4895 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid);
4896 
4897 	count = SPDK_COUNTOF(ids);
4898 	rc = spdk_blob_get_clones(bs, snapshotid, ids, &count);
4899 	CU_ASSERT(rc == 0);
4900 	CU_ASSERT(count == 1);
4901 	CU_ASSERT(ids[0] == blobid);
4902 
4903 
4904 	/* 3. Create clone from snapshot */
4905 
4906 	spdk_bs_create_clone(bs, snapshotid, NULL, blob_op_with_id_complete, NULL);
4907 	CU_ASSERT(g_bserrno == 0);
4908 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
4909 	cloneid = g_blobid;
4910 
4911 	spdk_bs_open_blob(bs, cloneid, blob_op_with_handle_complete, NULL);
4912 	CU_ASSERT(g_bserrno == 0);
4913 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4914 	clone = g_blob;
4915 
4916 	CU_ASSERT(!spdk_blob_is_read_only(clone));
4917 	CU_ASSERT(!spdk_blob_is_snapshot(clone));
4918 	CU_ASSERT(spdk_blob_is_clone(clone));
4919 	CU_ASSERT(spdk_blob_is_thin_provisioned(clone));
4920 	CU_ASSERT(clone->parent_id == snapshotid);
4921 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid);
4922 
4923 	count = SPDK_COUNTOF(ids);
4924 	rc = spdk_blob_get_clones(bs, cloneid, ids, &count);
4925 	CU_ASSERT(rc == 0);
4926 	CU_ASSERT(count == 0);
4927 
4928 	/* Check if clone is on the snapshot's list */
4929 	count = SPDK_COUNTOF(ids);
4930 	rc = spdk_blob_get_clones(bs, snapshotid, ids, &count);
4931 	CU_ASSERT(rc == 0);
4932 	CU_ASSERT(ids[0] == blobid || ids[1] == blobid);
4933 	CU_ASSERT(ids[0] == cloneid || ids[1] == cloneid);
4934 
4935 
4936 	/* 4. Create snapshot of the clone */
4937 
4938 	spdk_bs_create_snapshot(bs, cloneid, NULL, blob_op_with_id_complete, NULL);
4939 	CU_ASSERT(g_bserrno == 0);
4940 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
4941 	snapshotid2 = g_blobid;
4942 
4943 	spdk_bs_open_blob(bs, snapshotid2, blob_op_with_handle_complete, NULL);
4944 	CU_ASSERT(g_bserrno == 0);
4945 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4946 	snapshot2 = g_blob;
4947 
4948 	CU_ASSERT(spdk_blob_is_read_only(snapshot2));
4949 	CU_ASSERT(spdk_blob_is_snapshot(snapshot2));
4950 	CU_ASSERT(spdk_blob_is_clone(snapshot2));
4951 	CU_ASSERT(snapshot2->parent_id == snapshotid);
4952 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid2) == snapshotid);
4953 
4954 	/* Check if clone is converted to the clone of snapshot2 and snapshot2
4955 	 * is a child of snapshot */
4956 	CU_ASSERT(!spdk_blob_is_read_only(clone));
4957 	CU_ASSERT(!spdk_blob_is_snapshot(clone));
4958 	CU_ASSERT(spdk_blob_is_clone(clone));
4959 	CU_ASSERT(spdk_blob_is_thin_provisioned(clone));
4960 	CU_ASSERT(clone->parent_id == snapshotid2);
4961 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid2);
4962 
4963 	count = SPDK_COUNTOF(ids);
4964 	rc = spdk_blob_get_clones(bs, snapshotid2, ids, &count);
4965 	CU_ASSERT(rc == 0);
4966 	CU_ASSERT(count == 1);
4967 	CU_ASSERT(ids[0] == cloneid);
4968 
4969 
4970 	/* 5. Try to create clone from read only blob */
4971 
4972 	/* Mark blob as read only */
4973 	spdk_blob_set_read_only(blob);
4974 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
4975 	CU_ASSERT(g_bserrno == 0);
4976 
4977 	/* Check if previously created blob is read only clone */
4978 	CU_ASSERT(spdk_blob_is_read_only(blob));
4979 	CU_ASSERT(!spdk_blob_is_snapshot(blob));
4980 	CU_ASSERT(spdk_blob_is_clone(blob));
4981 	CU_ASSERT(spdk_blob_is_thin_provisioned(blob));
4982 
4983 	/* Create clone from read only blob */
4984 	spdk_bs_create_clone(bs, blobid, NULL, blob_op_with_id_complete, NULL);
4985 	CU_ASSERT(g_bserrno == 0);
4986 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
4987 	cloneid2 = g_blobid;
4988 
4989 	spdk_bs_open_blob(bs, cloneid2, blob_op_with_handle_complete, NULL);
4990 	CU_ASSERT(g_bserrno == 0);
4991 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4992 	clone2 = g_blob;
4993 
4994 	CU_ASSERT(!spdk_blob_is_read_only(clone2));
4995 	CU_ASSERT(!spdk_blob_is_snapshot(clone2));
4996 	CU_ASSERT(spdk_blob_is_clone(clone2));
4997 	CU_ASSERT(spdk_blob_is_thin_provisioned(clone2));
4998 
4999 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid2) == blobid);
5000 
5001 	count = SPDK_COUNTOF(ids);
5002 	rc = spdk_blob_get_clones(bs, blobid, ids, &count);
5003 	CU_ASSERT(rc == 0);
5004 
5005 	CU_ASSERT(count == 1);
5006 	CU_ASSERT(ids[0] == cloneid2);
5007 
5008 	/* Close blobs */
5009 
5010 	spdk_blob_close(clone2, blob_op_complete, NULL);
5011 	CU_ASSERT(g_bserrno == 0);
5012 
5013 	spdk_blob_close(blob, blob_op_complete, NULL);
5014 	CU_ASSERT(g_bserrno == 0);
5015 
5016 	spdk_blob_close(clone, blob_op_complete, NULL);
5017 	CU_ASSERT(g_bserrno == 0);
5018 
5019 	spdk_blob_close(snapshot, blob_op_complete, NULL);
5020 	CU_ASSERT(g_bserrno == 0);
5021 
5022 	spdk_blob_close(snapshot2, blob_op_complete, NULL);
5023 	CU_ASSERT(g_bserrno == 0);
5024 
5025 	/* Try to delete snapshot with created clones */
5026 	spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL);
5027 	CU_ASSERT(g_bserrno != 0);
5028 
5029 	spdk_bs_delete_blob(bs, snapshotid2, blob_op_complete, NULL);
5030 	CU_ASSERT(g_bserrno != 0);
5031 
5032 	spdk_bs_unload(bs, bs_op_complete, NULL);
5033 	CU_ASSERT(g_bserrno == 0);
5034 	g_bs = NULL;
5035 
5036 	/* Load an existing blob store */
5037 	dev = init_dev();
5038 	snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE");
5039 
5040 	spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL);
5041 	CU_ASSERT(g_bserrno == 0);
5042 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
5043 	bs = g_bs;
5044 
5045 
5046 	/* NULL ids array should return number of clones in count */
5047 	count = SPDK_COUNTOF(ids);
5048 	rc = spdk_blob_get_clones(bs, snapshotid, NULL, &count);
5049 	CU_ASSERT(rc == -ENOMEM);
5050 	CU_ASSERT(count == 2);
5051 
5052 	/* incorrect array size */
5053 	count = 1;
5054 	rc = spdk_blob_get_clones(bs, snapshotid, ids, &count);
5055 	CU_ASSERT(rc == -ENOMEM);
5056 	CU_ASSERT(count == 2);
5057 
5058 
5059 	/* Verify structure of loaded blob store */
5060 
5061 	/* snapshot */
5062 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid) == SPDK_BLOBID_INVALID);
5063 
5064 	count = SPDK_COUNTOF(ids);
5065 	rc = spdk_blob_get_clones(bs, snapshotid, ids, &count);
5066 	CU_ASSERT(rc == 0);
5067 	CU_ASSERT(count == 2);
5068 	CU_ASSERT(ids[0] == blobid || ids[1] == blobid);
5069 	CU_ASSERT(ids[0] == snapshotid2 || ids[1] == snapshotid2);
5070 
5071 	/* blob */
5072 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid);
5073 	count = SPDK_COUNTOF(ids);
5074 	rc = spdk_blob_get_clones(bs, blobid, ids, &count);
5075 	CU_ASSERT(rc == 0);
5076 	CU_ASSERT(count == 1);
5077 	CU_ASSERT(ids[0] == cloneid2);
5078 
5079 	/* clone */
5080 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid2);
5081 	count = SPDK_COUNTOF(ids);
5082 	rc = spdk_blob_get_clones(bs, cloneid, ids, &count);
5083 	CU_ASSERT(rc == 0);
5084 	CU_ASSERT(count == 0);
5085 
5086 	/* snapshot2 */
5087 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid2) == snapshotid);
5088 	count = SPDK_COUNTOF(ids);
5089 	rc = spdk_blob_get_clones(bs, snapshotid2, ids, &count);
5090 	CU_ASSERT(rc == 0);
5091 	CU_ASSERT(count == 1);
5092 	CU_ASSERT(ids[0] == cloneid);
5093 
5094 	/* clone2 */
5095 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid2) == blobid);
5096 	count = SPDK_COUNTOF(ids);
5097 	rc = spdk_blob_get_clones(bs, cloneid2, ids, &count);
5098 	CU_ASSERT(rc == 0);
5099 	CU_ASSERT(count == 0);
5100 
5101 	/* Try to delete all blobs in the worse possible order */
5102 
5103 	spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL);
5104 	CU_ASSERT(g_bserrno != 0);
5105 
5106 	spdk_bs_delete_blob(bs, snapshotid2, blob_op_complete, NULL);
5107 	CU_ASSERT(g_bserrno != 0);
5108 
5109 	spdk_bs_delete_blob(bs, cloneid, blob_op_complete, NULL);
5110 	CU_ASSERT(g_bserrno == 0);
5111 
5112 	spdk_bs_delete_blob(bs, snapshotid2, blob_op_complete, NULL);
5113 	CU_ASSERT(g_bserrno == 0);
5114 
5115 	spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL);
5116 	CU_ASSERT(g_bserrno != 0);
5117 
5118 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
5119 	CU_ASSERT(g_bserrno != 0);
5120 
5121 	spdk_bs_delete_blob(bs, cloneid2, blob_op_complete, NULL);
5122 	CU_ASSERT(g_bserrno == 0);
5123 
5124 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
5125 	CU_ASSERT(g_bserrno == 0);
5126 
5127 	spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL);
5128 	CU_ASSERT(g_bserrno == 0);
5129 
5130 	spdk_bs_unload(bs, bs_op_complete, NULL);
5131 	CU_ASSERT(g_bserrno == 0);
5132 
5133 	g_bs = NULL;
5134 }
5135 
5136 static void
5137 test_io_write(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel)
5138 {
5139 	uint8_t payload_ff[64 * 512];
5140 	uint8_t payload_aa[64 * 512];
5141 	uint8_t payload_00[64 * 512];
5142 	uint8_t *cluster0, *cluster1;
5143 
5144 	memset(payload_ff, 0xFF, sizeof(payload_ff));
5145 	memset(payload_aa, 0xAA, sizeof(payload_aa));
5146 	memset(payload_00, 0x00, sizeof(payload_00));
5147 
5148 	/* Try to perform I/O with io unit = 512 */
5149 	spdk_blob_io_write(blob, channel, payload_ff, 0, 1, blob_op_complete, NULL);
5150 	CU_ASSERT(g_bserrno == 0);
5151 
5152 	/* If thin provisioned is set cluster should be allocated now */
5153 	SPDK_CU_ASSERT_FATAL(blob->active.clusters[0] != 0);
5154 	cluster0 = &g_dev_buffer[blob->active.clusters[0] * dev->blocklen];
5155 
5156 	/* Each character 0-F symbolizes single io_unit containing 512 bytes block filled with that character.
5157 	* Each page is separated by |. Whole block [...] symbolizes one cluster (containing 4 pages). */
5158 	/* cluster0: [ F000 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */
5159 	CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0);
5160 	CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 31 * 512) == 0);
5161 
5162 	/* Verify write with offset on first page */
5163 	spdk_blob_io_write(blob, channel, payload_ff, 2, 1, blob_op_complete, NULL);
5164 	CU_ASSERT(g_bserrno == 0);
5165 
5166 	/* cluster0: [ F0F0 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */
5167 	CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0);
5168 	CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0);
5169 	CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0);
5170 	CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0);
5171 	CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_00, 28 * 512) == 0);
5172 
5173 	/* Verify write with offset on first page */
5174 	spdk_blob_io_write(blob, channel, payload_ff, 4, 4, blob_op_complete, NULL);
5175 
5176 	/* cluster0: [ F0F0 FFFF | 0000 0000 | 0000 0000 | 0000 0000 ] */
5177 	CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0);
5178 	CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0);
5179 	CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0);
5180 	CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0);
5181 	CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_ff, 4 * 512) == 0);
5182 	CU_ASSERT(memcmp(cluster0 + 8 * 512, payload_00, 24 * 512) == 0);
5183 
5184 	/* Verify write with offset on second page */
5185 	spdk_blob_io_write(blob, channel, payload_ff, 8, 4, blob_op_complete, NULL);
5186 
5187 	/* cluster0: [ F0F0 FFFF | FFFF 0000 | 0000 0000 | 0000 0000 ] */
5188 	CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0);
5189 	CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0);
5190 	CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0);
5191 	CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0);
5192 	CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_ff, 8 * 512) == 0);
5193 	CU_ASSERT(memcmp(cluster0 + 12 * 512, payload_00, 20 * 512) == 0);
5194 
5195 	/* Verify write across multiple pages */
5196 	spdk_blob_io_write(blob, channel, payload_aa, 4, 8, blob_op_complete, NULL);
5197 
5198 	/* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 0000 ] */
5199 	CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0);
5200 	CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0);
5201 	CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0);
5202 	CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0);
5203 	CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0);
5204 	CU_ASSERT(memcmp(cluster0 + 12 * 512, payload_00, 20 * 512) == 0);
5205 
5206 	/* Verify write across multiple clusters */
5207 	spdk_blob_io_write(blob, channel, payload_ff, 28, 8, blob_op_complete, NULL);
5208 
5209 	SPDK_CU_ASSERT_FATAL(blob->active.clusters[1] != 0);
5210 	cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen];
5211 
5212 	/* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ]
5213 	 * cluster1: [ FFFF 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */
5214 	CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0);
5215 	CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0);
5216 	CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0);
5217 	CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0);
5218 	CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0);
5219 	CU_ASSERT(memcmp(cluster0 + 28 * 512, payload_ff, 4 * 512) == 0);
5220 
5221 	CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_ff, 4 * 512) == 0);
5222 	CU_ASSERT(memcmp(cluster1 + 4 * 512, payload_00, 28 * 512) == 0);
5223 
5224 	/* Verify write to second cluster */
5225 	spdk_blob_io_write(blob, channel, payload_ff, 32 + 12, 2, blob_op_complete, NULL);
5226 
5227 	SPDK_CU_ASSERT_FATAL(blob->active.clusters[1] != 0);
5228 	cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen];
5229 
5230 	/* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ]
5231 	 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] */
5232 	CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0);
5233 	CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0);
5234 	CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0);
5235 	CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0);
5236 	CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0);
5237 	CU_ASSERT(memcmp(cluster0 + 28 * 512, payload_ff, 4 * 512) == 0);
5238 
5239 	CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_ff, 4 * 512) == 0);
5240 	CU_ASSERT(memcmp(cluster1 + 4 * 512, payload_00, 8 * 512) == 0);
5241 	CU_ASSERT(memcmp(cluster1 + 12 * 512, payload_ff, 2 * 512) == 0);
5242 	CU_ASSERT(memcmp(cluster1 + 14 * 512, payload_00, 18 * 512) == 0);
5243 }
5244 
5245 static void
5246 test_io_read(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel)
5247 {
5248 	uint8_t payload_read[64 * 512];
5249 	uint8_t payload_ff[64 * 512];
5250 	uint8_t payload_aa[64 * 512];
5251 	uint8_t payload_00[64 * 512];
5252 
5253 	memset(payload_ff, 0xFF, sizeof(payload_ff));
5254 	memset(payload_aa, 0xAA, sizeof(payload_aa));
5255 	memset(payload_00, 0x00, sizeof(payload_00));
5256 
5257 	/* Read only first io unit */
5258 	/* cluster0: [ (F)0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ]
5259 	 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ]
5260 	 * payload_read: F000 0000 | 0000 0000 ... */
5261 	memset(payload_read, 0x00, sizeof(payload_read));
5262 	spdk_blob_io_read(blob, channel, payload_read, 0, 1, blob_op_complete, NULL);
5263 	CU_ASSERT(g_bserrno == 0);
5264 	CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0);
5265 	CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 31 * 512) == 0);
5266 
5267 	/* Read four io_units starting from offset = 2
5268 	 * cluster0: [ F0(F0 AA)AA | AAAA 0000 | 0000 0000 | 0000 FFFF ]
5269 	 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ]
5270 	 * payload_read: F0AA 0000 | 0000 0000 ... */
5271 
5272 	memset(payload_read, 0x00, sizeof(payload_read));
5273 	spdk_blob_io_read(blob, channel, payload_read, 2, 4, blob_op_complete, NULL);
5274 	CU_ASSERT(g_bserrno == 0);
5275 
5276 	CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0);
5277 	CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 512) == 0);
5278 	CU_ASSERT(memcmp(payload_read + 2 * 512, payload_aa, 512) == 0);
5279 	CU_ASSERT(memcmp(payload_read + 3 * 512, payload_aa, 512) == 0);
5280 	CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 28 * 512) == 0);
5281 
5282 	/* Read eight io_units across multiple pages
5283 	 * cluster0: [ F0F0 (AAAA | AAAA) 0000 | 0000 0000 | 0000 FFFF ]
5284 	 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ]
5285 	 * payload_read: AAAA AAAA | 0000 0000 ... */
5286 	memset(payload_read, 0x00, sizeof(payload_read));
5287 	spdk_blob_io_read(blob, channel, payload_read, 4, 8, blob_op_complete, NULL);
5288 	CU_ASSERT(g_bserrno == 0);
5289 
5290 	CU_ASSERT(memcmp(payload_read + 0 * 512, payload_aa, 8 * 512) == 0);
5291 	CU_ASSERT(memcmp(payload_read + 8 * 512, payload_00, 24 * 512) == 0);
5292 
5293 	/* Read eight io_units across multiple clusters
5294 	 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 (FFFF ]
5295 	 * cluster1: [ FFFF) 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ]
5296 	 * payload_read: FFFF FFFF | 0000 0000 ... */
5297 	memset(payload_read, 0x00, sizeof(payload_read));
5298 	spdk_blob_io_read(blob, channel, payload_read, 28, 8, blob_op_complete, NULL);
5299 	CU_ASSERT(g_bserrno == 0);
5300 
5301 	CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 8 * 512) == 0);
5302 	CU_ASSERT(memcmp(payload_read + 8 * 512, payload_00, 24 * 512) == 0);
5303 
5304 	/* Read four io_units from second cluster
5305 	 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ]
5306 	 * cluster1: [ FFFF 0000 | 00(00 FF)00 | 0000 0000 | 0000 0000 ]
5307 	 * payload_read: 00FF 0000 | 0000 0000 ... */
5308 	memset(payload_read, 0x00, sizeof(payload_read));
5309 	spdk_blob_io_read(blob, channel, payload_read, 32 + 10, 4, blob_op_complete, NULL);
5310 	CU_ASSERT(g_bserrno == 0);
5311 
5312 	CU_ASSERT(memcmp(payload_read + 0 * 512, payload_00, 2 * 512) == 0);
5313 	CU_ASSERT(memcmp(payload_read + 2 * 512, payload_ff, 2 * 512) == 0);
5314 	CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 28 * 512) == 0);
5315 
5316 	/* Read second cluster
5317 	 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ]
5318 	 * cluster1: [ (FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000) ]
5319 	 * payload_read: FFFF 0000 | 0000 FF00 ... */
5320 	memset(payload_read, 0x00, sizeof(payload_read));
5321 	spdk_blob_io_read(blob, channel, payload_read, 32, 32, blob_op_complete, NULL);
5322 	CU_ASSERT(g_bserrno == 0);
5323 	CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 4 * 512) == 0);
5324 	CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 8 * 512) == 0);
5325 	CU_ASSERT(memcmp(payload_read + 12 * 512, payload_ff, 2 * 512) == 0);
5326 	CU_ASSERT(memcmp(payload_read + 14 * 512, payload_00, 18 * 512) == 0);
5327 
5328 	/* Read whole two clusters
5329 	 * cluster0: [ (F0F0 AAAA | AAAA) 0000 | 0000 0000 | 0000 FFFF ]
5330 	 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000) ] */
5331 	memset(payload_read, 0x00, sizeof(payload_read));
5332 	spdk_blob_io_read(blob, channel, payload_read, 0, 64, blob_op_complete, NULL);
5333 	CU_ASSERT(g_bserrno == 0);
5334 
5335 	CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0);
5336 	CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 512) == 0);
5337 	CU_ASSERT(memcmp(payload_read + 2 * 512, payload_ff, 512) == 0);
5338 	CU_ASSERT(memcmp(payload_read + 3 * 512, payload_00, 512) == 0);
5339 	CU_ASSERT(memcmp(payload_read + 4 * 512, payload_aa, 8 * 512) == 0);
5340 	CU_ASSERT(memcmp(payload_read + 28 * 512, payload_ff, 4 * 512) == 0);
5341 
5342 	CU_ASSERT(memcmp(payload_read + (32 + 0) * 512, payload_ff, 4 * 512) == 0);
5343 	CU_ASSERT(memcmp(payload_read + (32 + 4) * 512, payload_00, 8 * 512) == 0);
5344 	CU_ASSERT(memcmp(payload_read + (32 + 12) * 512, payload_ff, 2 * 512) == 0);
5345 	CU_ASSERT(memcmp(payload_read + (32 + 14) * 512, payload_00, 18 * 512) == 0);
5346 }
5347 
5348 
5349 static void
5350 test_io_unmap(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel)
5351 {
5352 	uint8_t payload_ff[64 * 512];
5353 	uint8_t payload_aa[64 * 512];
5354 	uint8_t payload_00[64 * 512];
5355 	uint8_t *cluster0, *cluster1;
5356 
5357 	memset(payload_ff, 0xFF, sizeof(payload_ff));
5358 	memset(payload_aa, 0xAA, sizeof(payload_aa));
5359 	memset(payload_00, 0x00, sizeof(payload_00));
5360 
5361 	cluster0 = &g_dev_buffer[blob->active.clusters[0] * dev->blocklen];
5362 	cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen];
5363 
5364 	/* Unmap */
5365 	spdk_blob_io_unmap(blob, channel, 0, 64, blob_op_complete, NULL);
5366 
5367 	CU_ASSERT(g_bserrno == 0);
5368 
5369 	CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_00, 32 * 512) == 0);
5370 	CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_00, 32 * 512) == 0);
5371 }
5372 
5373 static void
5374 test_io_zeroes(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel)
5375 {
5376 	uint8_t payload_ff[64 * 512];
5377 	uint8_t payload_aa[64 * 512];
5378 	uint8_t payload_00[64 * 512];
5379 	uint8_t *cluster0, *cluster1;
5380 
5381 	memset(payload_ff, 0xFF, sizeof(payload_ff));
5382 	memset(payload_aa, 0xAA, sizeof(payload_aa));
5383 	memset(payload_00, 0x00, sizeof(payload_00));
5384 
5385 	cluster0 = &g_dev_buffer[blob->active.clusters[0] * dev->blocklen];
5386 	cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen];
5387 
5388 	/* Write zeroes  */
5389 	spdk_blob_io_write_zeroes(blob, channel, 0, 64, blob_op_complete, NULL);
5390 
5391 	CU_ASSERT(g_bserrno == 0);
5392 
5393 	CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_00, 32 * 512) == 0);
5394 	CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_00, 32 * 512) == 0);
5395 }
5396 
5397 
5398 static void
5399 test_iov_write(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel)
5400 {
5401 	uint8_t payload_ff[64 * 512];
5402 	uint8_t payload_aa[64 * 512];
5403 	uint8_t payload_00[64 * 512];
5404 	uint8_t *cluster0, *cluster1;
5405 	struct iovec iov[4];
5406 
5407 	memset(payload_ff, 0xFF, sizeof(payload_ff));
5408 	memset(payload_aa, 0xAA, sizeof(payload_aa));
5409 	memset(payload_00, 0x00, sizeof(payload_00));
5410 
5411 	/* Try to perform I/O with io unit = 512 */
5412 	iov[0].iov_base = payload_ff;
5413 	iov[0].iov_len = 1 * 512;
5414 	spdk_blob_io_writev(blob, channel, iov, 1, 0, 1, blob_op_complete, NULL);
5415 	CU_ASSERT(g_bserrno == 0);
5416 
5417 	/* If thin provisioned is set cluster should be allocated now */
5418 	SPDK_CU_ASSERT_FATAL(blob->active.clusters[0] != 0);
5419 	cluster0 = &g_dev_buffer[blob->active.clusters[0] * dev->blocklen];
5420 
5421 	/* Each character 0-F symbolizes single io_unit containing 512 bytes block filled with that character.
5422 	* Each page is separated by |. Whole block [...] symbolizes one cluster (containing 4 pages). */
5423 	/* cluster0: [ F000 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */
5424 	CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0);
5425 	CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 31 * 512) == 0);
5426 
5427 	/* Verify write with offset on first page */
5428 	iov[0].iov_base = payload_ff;
5429 	iov[0].iov_len = 1 * 512;
5430 	spdk_blob_io_writev(blob, channel, iov, 1, 2, 1, blob_op_complete, NULL);
5431 	CU_ASSERT(g_bserrno == 0);
5432 
5433 	/* cluster0: [ F0F0 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */
5434 	CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0);
5435 	CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0);
5436 	CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0);
5437 	CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0);
5438 	CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_00, 28 * 512) == 0);
5439 
5440 	/* Verify write with offset on first page */
5441 	iov[0].iov_base = payload_ff;
5442 	iov[0].iov_len = 4 * 512;
5443 	spdk_blob_io_writev(blob, channel, iov, 1, 4, 4, blob_op_complete, NULL);
5444 
5445 	/* cluster0: [ F0F0 FFFF | 0000 0000 | 0000 0000 | 0000 0000 ] */
5446 	CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0);
5447 	CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0);
5448 	CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0);
5449 	CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0);
5450 	CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_ff, 4 * 512) == 0);
5451 	CU_ASSERT(memcmp(cluster0 + 8 * 512, payload_00, 24 * 512) == 0);
5452 
5453 	/* Verify write with offset on second page */
5454 	iov[0].iov_base = payload_ff;
5455 	iov[0].iov_len = 4 * 512;
5456 	spdk_blob_io_writev(blob, channel, iov, 1, 8, 4, blob_op_complete, NULL);
5457 
5458 	/* cluster0: [ F0F0 FFFF | FFFF 0000 | 0000 0000 | 0000 0000 ] */
5459 	CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0);
5460 	CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0);
5461 	CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0);
5462 	CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0);
5463 	CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_ff, 8 * 512) == 0);
5464 	CU_ASSERT(memcmp(cluster0 + 12 * 512, payload_00, 20 * 512) == 0);
5465 
5466 	/* Verify write across multiple pages */
5467 	iov[0].iov_base = payload_aa;
5468 	iov[0].iov_len = 8 * 512;
5469 	spdk_blob_io_writev(blob, channel, iov, 1, 4, 8, blob_op_complete, NULL);
5470 
5471 	/* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 0000 ] */
5472 	CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0);
5473 	CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0);
5474 	CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0);
5475 	CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0);
5476 	CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0);
5477 	CU_ASSERT(memcmp(cluster0 + 12 * 512, payload_00, 20 * 512) == 0);
5478 
5479 	/* Verify write across multiple clusters */
5480 
5481 	iov[0].iov_base = payload_ff;
5482 	iov[0].iov_len = 8 * 512;
5483 	spdk_blob_io_writev(blob, channel, iov, 1, 28, 8, blob_op_complete, NULL);
5484 
5485 	SPDK_CU_ASSERT_FATAL(blob->active.clusters[1] != 0);
5486 	cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen];
5487 
5488 	/* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ]
5489 	 * cluster1: [ FFFF 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */
5490 	CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0);
5491 	CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0);
5492 	CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0);
5493 	CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0);
5494 	CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0);
5495 	CU_ASSERT(memcmp(cluster0 + 12 * 512, payload_00, 16 * 512) == 0);
5496 	CU_ASSERT(memcmp(cluster0 + 28 * 512, payload_ff, 4 * 512) == 0);
5497 
5498 	CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_ff, 4 * 512) == 0);
5499 	CU_ASSERT(memcmp(cluster1 + 4 * 512, payload_00, 28 * 512) == 0);
5500 
5501 	/* Verify write to second cluster */
5502 
5503 	iov[0].iov_base = payload_ff;
5504 	iov[0].iov_len = 2 * 512;
5505 	spdk_blob_io_writev(blob, channel, iov, 1, 32 + 12, 2, blob_op_complete, NULL);
5506 
5507 	SPDK_CU_ASSERT_FATAL(blob->active.clusters[1] != 0);
5508 	cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen];
5509 
5510 	/* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ]
5511 	 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] */
5512 	CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0);
5513 	CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0);
5514 	CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0);
5515 	CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0);
5516 	CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0);
5517 	CU_ASSERT(memcmp(cluster0 + 28 * 512, payload_ff, 4 * 512) == 0);
5518 
5519 	CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_ff, 4 * 512) == 0);
5520 	CU_ASSERT(memcmp(cluster1 + 4 * 512, payload_00, 8 * 512) == 0);
5521 	CU_ASSERT(memcmp(cluster1 + 12 * 512, payload_ff, 2 * 512) == 0);
5522 	CU_ASSERT(memcmp(cluster1 + 14 * 512, payload_00, 18 * 512) == 0);
5523 }
5524 
5525 static void
5526 test_iov_read(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel)
5527 {
5528 	uint8_t payload_read[64 * 512];
5529 	uint8_t payload_ff[64 * 512];
5530 	uint8_t payload_aa[64 * 512];
5531 	uint8_t payload_00[64 * 512];
5532 	struct iovec iov[4];
5533 
5534 	memset(payload_ff, 0xFF, sizeof(payload_ff));
5535 	memset(payload_aa, 0xAA, sizeof(payload_aa));
5536 	memset(payload_00, 0x00, sizeof(payload_00));
5537 
5538 	/* Read only first io unit */
5539 	/* cluster0: [ (F)0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ]
5540 	 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ]
5541 	 * payload_read: F000 0000 | 0000 0000 ... */
5542 	memset(payload_read, 0x00, sizeof(payload_read));
5543 	iov[0].iov_base = payload_read;
5544 	iov[0].iov_len = 1 * 512;
5545 	spdk_blob_io_readv(blob, channel, iov, 1, 0, 1, blob_op_complete, NULL);
5546 
5547 	CU_ASSERT(g_bserrno == 0);
5548 	CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0);
5549 	CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 31 * 512) == 0);
5550 
5551 	/* Read four io_units starting from offset = 2
5552 	 * cluster0: [ F0(F0 AA)AA | AAAA 0000 | 0000 0000 | 0000 FFFF ]
5553 	 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ]
5554 	 * payload_read: F0AA 0000 | 0000 0000 ... */
5555 
5556 	memset(payload_read, 0x00, sizeof(payload_read));
5557 	iov[0].iov_base = payload_read;
5558 	iov[0].iov_len = 4 * 512;
5559 	spdk_blob_io_readv(blob, channel, iov, 1, 2, 4, blob_op_complete, NULL);
5560 	CU_ASSERT(g_bserrno == 0);
5561 
5562 	CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0);
5563 	CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 512) == 0);
5564 	CU_ASSERT(memcmp(payload_read + 2 * 512, payload_aa, 512) == 0);
5565 	CU_ASSERT(memcmp(payload_read + 3 * 512, payload_aa, 512) == 0);
5566 	CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 28 * 512) == 0);
5567 
5568 	/* Read eight io_units across multiple pages
5569 	 * cluster0: [ F0F0 (AAAA | AAAA) 0000 | 0000 0000 | 0000 FFFF ]
5570 	 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ]
5571 	 * payload_read: AAAA AAAA | 0000 0000 ... */
5572 	memset(payload_read, 0x00, sizeof(payload_read));
5573 	iov[0].iov_base = payload_read;
5574 	iov[0].iov_len = 4 * 512;
5575 	iov[1].iov_base = payload_read + 4 * 512;
5576 	iov[1].iov_len = 4 * 512;
5577 	spdk_blob_io_readv(blob, channel, iov, 2, 4, 8, blob_op_complete, NULL);
5578 	CU_ASSERT(g_bserrno == 0);
5579 
5580 	CU_ASSERT(memcmp(payload_read + 0 * 512, payload_aa, 8 * 512) == 0);
5581 	CU_ASSERT(memcmp(payload_read + 8 * 512, payload_00, 24 * 512) == 0);
5582 
5583 	/* Read eight io_units across multiple clusters
5584 	 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 (FFFF ]
5585 	 * cluster1: [ FFFF) 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ]
5586 	 * payload_read: FFFF FFFF | 0000 0000 ... */
5587 	memset(payload_read, 0x00, sizeof(payload_read));
5588 	iov[0].iov_base = payload_read;
5589 	iov[0].iov_len = 2 * 512;
5590 	iov[1].iov_base = payload_read + 2 * 512;
5591 	iov[1].iov_len = 2 * 512;
5592 	iov[2].iov_base = payload_read + 4 * 512;
5593 	iov[2].iov_len = 2 * 512;
5594 	iov[3].iov_base = payload_read + 6 * 512;
5595 	iov[3].iov_len = 2 * 512;
5596 	spdk_blob_io_readv(blob, channel, iov, 4, 28, 8, blob_op_complete, NULL);
5597 	CU_ASSERT(g_bserrno == 0);
5598 
5599 	CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 8 * 512) == 0);
5600 	CU_ASSERT(memcmp(payload_read + 8 * 512, payload_00, 24 * 512) == 0);
5601 
5602 	/* Read four io_units from second cluster
5603 	 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ]
5604 	 * cluster1: [ FFFF 0000 | 00(00 FF)00 | 0000 0000 | 0000 0000 ]
5605 	 * payload_read: 00FF 0000 | 0000 0000 ... */
5606 	memset(payload_read, 0x00, sizeof(payload_read));
5607 	iov[0].iov_base = payload_read;
5608 	iov[0].iov_len = 1 * 512;
5609 	iov[1].iov_base = payload_read + 1 * 512;
5610 	iov[1].iov_len = 3 * 512;
5611 	spdk_blob_io_readv(blob, channel, iov, 2, 32 + 10, 4, blob_op_complete, NULL);
5612 	CU_ASSERT(g_bserrno == 0);
5613 
5614 	CU_ASSERT(memcmp(payload_read + 0 * 512, payload_00, 2 * 512) == 0);
5615 	CU_ASSERT(memcmp(payload_read + 2 * 512, payload_ff, 2 * 512) == 0);
5616 	CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 28 * 512) == 0);
5617 
5618 	/* Read second cluster
5619 	 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ]
5620 	 * cluster1: [ (FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000) ]
5621 	 * payload_read: FFFF 0000 | 0000 FF00 ... */
5622 	memset(payload_read, 0x00, sizeof(payload_read));
5623 	iov[0].iov_base = payload_read;
5624 	iov[0].iov_len = 1 * 512;
5625 	iov[1].iov_base = payload_read + 1 * 512;
5626 	iov[1].iov_len = 2 * 512;
5627 	iov[2].iov_base = payload_read + 3 * 512;
5628 	iov[2].iov_len = 4 * 512;
5629 	iov[3].iov_base = payload_read + 7 * 512;
5630 	iov[3].iov_len = 25 * 512;
5631 	spdk_blob_io_readv(blob, channel, iov, 4, 32, 32, blob_op_complete, NULL);
5632 	CU_ASSERT(g_bserrno == 0);
5633 	CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 4 * 512) == 0);
5634 	CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 8 * 512) == 0);
5635 	CU_ASSERT(memcmp(payload_read + 12 * 512, payload_ff, 2 * 512) == 0);
5636 	CU_ASSERT(memcmp(payload_read + 14 * 512, payload_00, 18 * 512) == 0);
5637 
5638 	/* Read whole two clusters
5639 	 * cluster0: [ (F0F0 AAAA | AAAA) 0000 | 0000 0000 | 0000 FFFF ]
5640 	 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000) ] */
5641 	memset(payload_read, 0x00, sizeof(payload_read));
5642 	iov[0].iov_base = payload_read;
5643 	iov[0].iov_len = 1 * 512;
5644 	iov[1].iov_base = payload_read + 1 * 512;
5645 	iov[1].iov_len = 8 * 512;
5646 	iov[2].iov_base = payload_read + 9 * 512;
5647 	iov[2].iov_len = 16 * 512;
5648 	iov[3].iov_base = payload_read + 25 * 512;
5649 	iov[3].iov_len = 39 * 512;
5650 	spdk_blob_io_readv(blob, channel, iov, 4, 0, 64, blob_op_complete, NULL);
5651 	CU_ASSERT(g_bserrno == 0);
5652 
5653 	CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0);
5654 	CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 512) == 0);
5655 	CU_ASSERT(memcmp(payload_read + 2 * 512, payload_ff, 512) == 0);
5656 	CU_ASSERT(memcmp(payload_read + 3 * 512, payload_00, 512) == 0);
5657 	CU_ASSERT(memcmp(payload_read + 4 * 512, payload_aa, 8 * 512) == 0);
5658 	CU_ASSERT(memcmp(payload_read + 28 * 512, payload_ff, 4 * 512) == 0);
5659 
5660 	CU_ASSERT(memcmp(payload_read + (32 + 0) * 512, payload_ff, 4 * 512) == 0);
5661 	CU_ASSERT(memcmp(payload_read + (32 + 4) * 512, payload_00, 8 * 512) == 0);
5662 	CU_ASSERT(memcmp(payload_read + (32 + 12) * 512, payload_ff, 2 * 512) == 0);
5663 	CU_ASSERT(memcmp(payload_read + (32 + 14) * 512, payload_00, 18 * 512) == 0);
5664 }
5665 
5666 static void
5667 blob_io_unit(void)
5668 {
5669 	struct spdk_bs_opts bsopts;
5670 	struct spdk_blob_opts opts;
5671 	struct spdk_bs_dev *dev;
5672 	struct spdk_blob *blob, *snapshot, *clone;
5673 	spdk_blob_id blobid;
5674 	struct spdk_io_channel *channel;
5675 
5676 	/* Create dev with 512 bytes io unit size */
5677 
5678 	spdk_bs_opts_init(&bsopts);
5679 	bsopts.cluster_sz = SPDK_BS_PAGE_SIZE * 4;	/* 8 * 4 = 32 io_unit */
5680 	snprintf(bsopts.bstype.bstype, sizeof(bsopts.bstype.bstype), "TESTTYPE");
5681 
5682 	/* Try to initialize a new blob store with unsupported io_unit */
5683 	dev = init_dev();
5684 	dev->blocklen = 512;
5685 	dev->blockcnt =  DEV_BUFFER_SIZE / dev->blocklen;
5686 
5687 	/* Initialize a new blob store */
5688 	spdk_bs_init(dev, &bsopts, bs_op_with_handle_complete, NULL);
5689 	CU_ASSERT(g_bserrno == 0);
5690 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
5691 
5692 	CU_ASSERT(spdk_bs_get_io_unit_size(g_bs) == 512);
5693 	channel = spdk_bs_alloc_io_channel(g_bs);
5694 
5695 	/* Create thick provisioned blob */
5696 	spdk_blob_opts_init(&opts);
5697 	opts.thin_provision = false;
5698 	opts.num_clusters = 32;
5699 
5700 	spdk_bs_create_blob_ext(g_bs, &opts, blob_op_with_id_complete, NULL);
5701 
5702 	CU_ASSERT(g_bserrno == 0);
5703 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
5704 	blobid = g_blobid;
5705 
5706 	spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
5707 	CU_ASSERT(g_bserrno == 0);
5708 	CU_ASSERT(g_blob != NULL);
5709 	blob = g_blob;
5710 
5711 	test_io_write(dev, blob, channel);
5712 	test_io_read(dev, blob, channel);
5713 	test_io_zeroes(dev, blob, channel);
5714 
5715 	test_iov_write(dev, blob, channel);
5716 	test_iov_read(dev, blob, channel);
5717 
5718 	test_io_unmap(dev, blob, channel);
5719 
5720 	spdk_blob_close(blob, blob_op_complete, NULL);
5721 	CU_ASSERT(g_bserrno == 0);
5722 	blob = NULL;
5723 	g_blob = NULL;
5724 
5725 	/* Create thin provisioned blob */
5726 
5727 	spdk_blob_opts_init(&opts);
5728 	opts.thin_provision = true;
5729 	opts.num_clusters = 32;
5730 
5731 	spdk_bs_create_blob_ext(g_bs, &opts, blob_op_with_id_complete, NULL);
5732 	CU_ASSERT(g_bserrno == 0);
5733 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
5734 	blobid = g_blobid;
5735 
5736 	spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
5737 	CU_ASSERT(g_bserrno == 0);
5738 	CU_ASSERT(g_blob != NULL);
5739 	blob = g_blob;
5740 
5741 	test_io_write(dev, blob, channel);
5742 	test_io_read(dev, blob, channel);
5743 
5744 	test_io_zeroes(dev, blob, channel);
5745 
5746 	test_iov_write(dev, blob, channel);
5747 	test_iov_read(dev, blob, channel);
5748 
5749 	/* Create snapshot */
5750 
5751 	spdk_bs_create_snapshot(g_bs, blobid, NULL, blob_op_with_id_complete, NULL);
5752 	CU_ASSERT(g_bserrno == 0);
5753 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
5754 	blobid = g_blobid;
5755 
5756 	spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
5757 	CU_ASSERT(g_bserrno == 0);
5758 	CU_ASSERT(g_blob != NULL);
5759 	snapshot = g_blob;
5760 
5761 	spdk_bs_create_clone(g_bs, blobid, NULL, blob_op_with_id_complete, NULL);
5762 	CU_ASSERT(g_bserrno == 0);
5763 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
5764 	blobid = g_blobid;
5765 
5766 	spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
5767 	CU_ASSERT(g_bserrno == 0);
5768 	CU_ASSERT(g_blob != NULL);
5769 	clone = g_blob;
5770 
5771 	test_io_read(dev, blob, channel);
5772 	test_io_read(dev, snapshot, channel);
5773 	test_io_read(dev, clone, channel);
5774 
5775 	test_iov_read(dev, blob, channel);
5776 	test_iov_read(dev, snapshot, channel);
5777 	test_iov_read(dev, clone, channel);
5778 
5779 	/* Inflate clone */
5780 
5781 	spdk_bs_inflate_blob(g_bs, channel, blobid, blob_op_complete, NULL);
5782 
5783 	CU_ASSERT(g_bserrno == 0);
5784 
5785 	test_io_read(dev, clone, channel);
5786 
5787 	test_io_unmap(dev, clone, channel);
5788 
5789 	test_iov_write(dev, clone, channel);
5790 	test_iov_read(dev, clone, channel);
5791 
5792 	spdk_blob_close(blob, blob_op_complete, NULL);
5793 	spdk_blob_close(snapshot, blob_op_complete, NULL);
5794 	spdk_blob_close(clone, blob_op_complete, NULL);
5795 	CU_ASSERT(g_bserrno == 0);
5796 	blob = NULL;
5797 	g_blob = NULL;
5798 
5799 	/* Unload the blob store */
5800 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
5801 	CU_ASSERT(g_bserrno == 0);
5802 	g_bs = NULL;
5803 	g_blob = NULL;
5804 	g_blobid = 0;
5805 }
5806 
5807 static void
5808 blob_io_unit_compatiblity(void)
5809 {
5810 	struct spdk_bs_opts bsopts;
5811 	struct spdk_bs_dev *dev;
5812 	struct spdk_bs_super_block *super;
5813 
5814 	/* Create dev with 512 bytes io unit size */
5815 
5816 	spdk_bs_opts_init(&bsopts);
5817 	bsopts.cluster_sz = SPDK_BS_PAGE_SIZE * 4;	/* 8 * 4 = 32 io_unit */
5818 	snprintf(bsopts.bstype.bstype, sizeof(bsopts.bstype.bstype), "TESTTYPE");
5819 
5820 	/* Try to initialize a new blob store with unsupported io_unit */
5821 	dev = init_dev();
5822 	dev->blocklen = 512;
5823 	dev->blockcnt =  DEV_BUFFER_SIZE / dev->blocklen;
5824 
5825 	/* Initialize a new blob store */
5826 	spdk_bs_init(dev, &bsopts, bs_op_with_handle_complete, NULL);
5827 	CU_ASSERT(g_bserrno == 0);
5828 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
5829 
5830 	CU_ASSERT(spdk_bs_get_io_unit_size(g_bs) == 512);
5831 
5832 	/* Unload the blob store */
5833 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
5834 	CU_ASSERT(g_bserrno == 0);
5835 
5836 	/* Modify super block to behave like older version.
5837 	 * Check if loaded io unit size equals SPDK_BS_PAGE_SIZE */
5838 	super = (struct spdk_bs_super_block *)&g_dev_buffer[0];
5839 	super->io_unit_size = 0;
5840 	super->crc = _spdk_blob_md_page_calc_crc(super);
5841 
5842 	dev = init_dev();
5843 	dev->blocklen = 512;
5844 	dev->blockcnt =  DEV_BUFFER_SIZE / dev->blocklen;
5845 
5846 	spdk_bs_load(dev, &bsopts, bs_op_with_handle_complete, NULL);
5847 	CU_ASSERT(g_bserrno == 0);
5848 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
5849 
5850 	CU_ASSERT(spdk_bs_get_io_unit_size(g_bs) == SPDK_BS_PAGE_SIZE);
5851 
5852 	/* Unload the blob store */
5853 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
5854 	CU_ASSERT(g_bserrno == 0);
5855 
5856 	g_bs = NULL;
5857 	g_blob = NULL;
5858 	g_blobid = 0;
5859 }
5860 
5861 int main(int argc, char **argv)
5862 {
5863 	struct spdk_thread *thread;
5864 	CU_pSuite	suite = NULL;
5865 	unsigned int	num_failures;
5866 
5867 	if (CU_initialize_registry() != CUE_SUCCESS) {
5868 		return CU_get_error();
5869 	}
5870 
5871 	suite = CU_add_suite("blob", NULL, NULL);
5872 	if (suite == NULL) {
5873 		CU_cleanup_registry();
5874 		return CU_get_error();
5875 	}
5876 
5877 	if (
5878 		CU_add_test(suite, "blob_init", blob_init) == NULL ||
5879 		CU_add_test(suite, "blob_open", blob_open) == NULL ||
5880 		CU_add_test(suite, "blob_create", blob_create) == NULL ||
5881 		CU_add_test(suite, "blob_create_internal", blob_create_internal) == NULL ||
5882 		CU_add_test(suite, "blob_thin_provision", blob_thin_provision) == NULL ||
5883 		CU_add_test(suite, "blob_snapshot", blob_snapshot) == NULL ||
5884 		CU_add_test(suite, "blob_clone", blob_clone) == NULL ||
5885 		CU_add_test(suite, "blob_inflate", blob_inflate) == NULL ||
5886 		CU_add_test(suite, "blob_delete", blob_delete) == NULL ||
5887 		CU_add_test(suite, "blob_resize", blob_resize) == NULL ||
5888 		CU_add_test(suite, "blob_read_only", blob_read_only) == NULL ||
5889 		CU_add_test(suite, "channel_ops", channel_ops) == NULL ||
5890 		CU_add_test(suite, "blob_super", blob_super) == NULL ||
5891 		CU_add_test(suite, "blob_write", blob_write) == NULL ||
5892 		CU_add_test(suite, "blob_read", blob_read) == NULL ||
5893 		CU_add_test(suite, "blob_rw_verify", blob_rw_verify) == NULL ||
5894 		CU_add_test(suite, "blob_rw_verify_iov", blob_rw_verify_iov) == NULL ||
5895 		CU_add_test(suite, "blob_rw_verify_iov_nomem", blob_rw_verify_iov_nomem) == NULL ||
5896 		CU_add_test(suite, "blob_rw_iov_read_only", blob_rw_iov_read_only) == NULL ||
5897 		CU_add_test(suite, "blob_unmap", blob_unmap) == NULL ||
5898 		CU_add_test(suite, "blob_iter", blob_iter) == NULL ||
5899 		CU_add_test(suite, "blob_xattr", blob_xattr) == NULL ||
5900 		CU_add_test(suite, "bs_load", bs_load) == NULL ||
5901 		CU_add_test(suite, "bs_load_custom_cluster_size", bs_load_custom_cluster_size) == NULL ||
5902 		CU_add_test(suite, "bs_unload", bs_unload) == NULL ||
5903 		CU_add_test(suite, "bs_cluster_sz", bs_cluster_sz) == NULL ||
5904 		CU_add_test(suite, "bs_usable_clusters", bs_usable_clusters) == NULL ||
5905 		CU_add_test(suite, "bs_resize_md", bs_resize_md) == NULL ||
5906 		CU_add_test(suite, "bs_destroy", bs_destroy) == NULL ||
5907 		CU_add_test(suite, "bs_type", bs_type) == NULL ||
5908 		CU_add_test(suite, "bs_super_block", bs_super_block) == NULL ||
5909 		CU_add_test(suite, "blob_serialize", blob_serialize) == NULL ||
5910 		CU_add_test(suite, "blob_crc", blob_crc) == NULL ||
5911 		CU_add_test(suite, "super_block_crc", super_block_crc) == NULL ||
5912 		CU_add_test(suite, "blob_dirty_shutdown", blob_dirty_shutdown) == NULL ||
5913 		CU_add_test(suite, "blob_flags", blob_flags) == NULL ||
5914 		CU_add_test(suite, "bs_version", bs_version) == NULL ||
5915 		CU_add_test(suite, "blob_set_xattrs", blob_set_xattrs) == NULL ||
5916 		CU_add_test(suite, "blob_thin_prov_alloc", blob_thin_prov_alloc) == NULL ||
5917 		CU_add_test(suite, "blob_insert_cluster_msg", blob_insert_cluster_msg) == NULL ||
5918 		CU_add_test(suite, "blob_thin_prov_rw", blob_thin_prov_rw) == NULL ||
5919 		CU_add_test(suite, "blob_thin_prov_rw_iov", blob_thin_prov_rw_iov) == NULL ||
5920 		CU_add_test(suite, "bs_load_iter", bs_load_iter) == NULL ||
5921 		CU_add_test(suite, "blob_snapshot_rw", blob_snapshot_rw) == NULL ||
5922 		CU_add_test(suite, "blob_snapshot_rw_iov", blob_snapshot_rw_iov) == NULL ||
5923 		CU_add_test(suite, "blob_relations", blob_relations) == NULL ||
5924 		CU_add_test(suite, "blob_inflate_rw", blob_inflate_rw) == NULL ||
5925 		CU_add_test(suite, "blob_snapshot_freeze_io", blob_snapshot_freeze_io) == NULL ||
5926 		CU_add_test(suite, "blob_operation_split_rw", blob_operation_split_rw) == NULL ||
5927 		CU_add_test(suite, "blob_operation_split_rw_iov", blob_operation_split_rw_iov) == NULL ||
5928 		CU_add_test(suite, "blob_io_unit", blob_io_unit) == NULL ||
5929 		CU_add_test(suite, "blob_io_unit_compatiblity", blob_io_unit_compatiblity) == NULL
5930 	) {
5931 		CU_cleanup_registry();
5932 		return CU_get_error();
5933 	}
5934 
5935 	g_dev_buffer = calloc(1, DEV_BUFFER_SIZE);
5936 	thread = spdk_allocate_thread(_bs_send_msg, NULL, NULL, NULL, "thread0");
5937 	spdk_set_thread(thread);
5938 	CU_basic_set_mode(CU_BRM_VERBOSE);
5939 	CU_basic_run_tests();
5940 	num_failures = CU_get_number_of_failures();
5941 	CU_cleanup_registry();
5942 	spdk_free_thread();
5943 	free(g_dev_buffer);
5944 	return num_failures;
5945 }
5946