xref: /spdk/test/unit/lib/blob/blob.c/blob_ut.c (revision da7673f71f15e27a7853ad18f3f07058d73e7274)
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 
40 #include "common/lib/test_env.c"
41 #include "../bs_dev_common.c"
42 #include "blob/blobstore.c"
43 #include "blob/request.c"
44 #include "blob/zeroes.c"
45 #include "blob/blob_bs_dev.c"
46 
47 struct spdk_blob_store *g_bs;
48 spdk_blob_id g_blobid;
49 struct spdk_blob *g_blob;
50 int g_bserrno;
51 struct spdk_xattr_names *g_names;
52 int g_done;
53 char *g_xattr_names[] = {"first", "second", "third"};
54 char *g_xattr_values[] = {"one", "two", "three"};
55 uint64_t g_ctx = 1729;
56 
57 struct spdk_bs_super_block_ver1 {
58 	uint8_t		signature[8];
59 	uint32_t        version;
60 	uint32_t        length;
61 	uint32_t	clean; /* If there was a clean shutdown, this is 1. */
62 	spdk_blob_id	super_blob;
63 
64 	uint32_t	cluster_size; /* In bytes */
65 
66 	uint32_t	used_page_mask_start; /* Offset from beginning of disk, in pages */
67 	uint32_t	used_page_mask_len; /* Count, in pages */
68 
69 	uint32_t	used_cluster_mask_start; /* Offset from beginning of disk, in pages */
70 	uint32_t	used_cluster_mask_len; /* Count, in pages */
71 
72 	uint32_t	md_start; /* Offset from beginning of disk, in pages */
73 	uint32_t	md_len; /* Count, in pages */
74 
75 	uint8_t		reserved[4036];
76 	uint32_t	crc;
77 } __attribute__((packed));
78 SPDK_STATIC_ASSERT(sizeof(struct spdk_bs_super_block_ver1) == 0x1000, "Invalid super block size");
79 
80 
81 static void
82 _get_xattr_value(void *arg, const char *name,
83 		 const void **value, size_t *value_len)
84 {
85 	uint64_t i;
86 
87 	SPDK_CU_ASSERT_FATAL(value_len != NULL);
88 	SPDK_CU_ASSERT_FATAL(value != NULL);
89 	CU_ASSERT(arg == &g_ctx)
90 
91 	for (i = 0; i < sizeof(g_xattr_names); i++) {
92 		if (!strcmp(name, g_xattr_names[i])) {
93 			*value_len = strlen(g_xattr_values[i]);
94 			*value = g_xattr_values[i];
95 			break;
96 		}
97 	}
98 }
99 
100 static void
101 _get_xattr_value_null(void *arg, const char *name,
102 		      const void **value, size_t *value_len)
103 {
104 	SPDK_CU_ASSERT_FATAL(value_len != NULL);
105 	SPDK_CU_ASSERT_FATAL(value != NULL);
106 	CU_ASSERT(arg == NULL)
107 
108 	*value_len = 0;
109 	*value = NULL;
110 }
111 
112 
113 
114 static void
115 bs_op_complete(void *cb_arg, int bserrno)
116 {
117 	g_bserrno = bserrno;
118 }
119 
120 static void
121 bs_op_with_handle_complete(void *cb_arg, struct spdk_blob_store *bs,
122 			   int bserrno)
123 {
124 	g_bs = bs;
125 	g_bserrno = bserrno;
126 }
127 
128 static void
129 blob_op_complete(void *cb_arg, int bserrno)
130 {
131 	g_bserrno = bserrno;
132 }
133 
134 static void
135 blob_op_with_id_complete(void *cb_arg, spdk_blob_id blobid, int bserrno)
136 {
137 	g_blobid = blobid;
138 	g_bserrno = bserrno;
139 }
140 
141 static void
142 blob_op_with_handle_complete(void *cb_arg, struct spdk_blob *blb, int bserrno)
143 {
144 	g_blob = blb;
145 	g_bserrno = bserrno;
146 }
147 
148 static void
149 blob_init(void)
150 {
151 	struct spdk_bs_dev *dev;
152 
153 	dev = init_dev();
154 
155 	/* should fail for an unsupported blocklen */
156 	dev->blocklen = 500;
157 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
158 	CU_ASSERT(g_bserrno == -EINVAL);
159 
160 	dev = init_dev();
161 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
162 	CU_ASSERT(g_bserrno == 0);
163 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
164 
165 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
166 	CU_ASSERT(g_bserrno == 0);
167 	g_bs = NULL;
168 }
169 
170 static void
171 blob_super(void)
172 {
173 	struct spdk_blob_store *bs;
174 	struct spdk_bs_dev *dev;
175 	spdk_blob_id blobid;
176 
177 	dev = init_dev();
178 
179 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
180 	CU_ASSERT(g_bserrno == 0);
181 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
182 	bs = g_bs;
183 
184 	/* Get the super blob without having set one */
185 	spdk_bs_get_super(bs, blob_op_with_id_complete, NULL);
186 	CU_ASSERT(g_bserrno == -ENOENT);
187 	CU_ASSERT(g_blobid == SPDK_BLOBID_INVALID);
188 
189 	/* Create a blob */
190 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
191 	CU_ASSERT(g_bserrno == 0);
192 	CU_ASSERT(g_blobid !=  SPDK_BLOBID_INVALID);
193 	blobid = g_blobid;
194 
195 	/* Set the blob as the super blob */
196 	spdk_bs_set_super(bs, blobid, blob_op_complete, NULL);
197 	CU_ASSERT(g_bserrno == 0);
198 
199 	/* Get the super blob */
200 	spdk_bs_get_super(bs, blob_op_with_id_complete, NULL);
201 	CU_ASSERT(g_bserrno == 0);
202 	CU_ASSERT(blobid == g_blobid);
203 
204 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
205 	CU_ASSERT(g_bserrno == 0);
206 	g_bs = NULL;
207 }
208 
209 static void
210 blob_open(void)
211 {
212 	struct spdk_blob_store *bs;
213 	struct spdk_bs_dev *dev;
214 	struct spdk_blob *blob;
215 	spdk_blob_id blobid, blobid2;
216 
217 	dev = init_dev();
218 
219 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
220 	CU_ASSERT(g_bserrno == 0);
221 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
222 	bs = g_bs;
223 
224 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
225 	CU_ASSERT(g_bserrno == 0);
226 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
227 	blobid = g_blobid;
228 
229 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
230 	CU_ASSERT(g_bserrno == 0);
231 	CU_ASSERT(g_blob != NULL);
232 	blob = g_blob;
233 
234 	blobid2 = spdk_blob_get_id(blob);
235 	CU_ASSERT(blobid == blobid2);
236 
237 	/* Try to open file again.  It should return success. */
238 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
239 	CU_ASSERT(g_bserrno == 0);
240 	CU_ASSERT(blob == g_blob);
241 
242 	spdk_blob_close(blob, blob_op_complete, NULL);
243 	CU_ASSERT(g_bserrno == 0);
244 
245 	/*
246 	 * Close the file a second time, releasing the second reference.  This
247 	 *  should succeed.
248 	 */
249 	blob = g_blob;
250 	spdk_blob_close(blob, blob_op_complete, NULL);
251 	CU_ASSERT(g_bserrno == 0);
252 
253 	/*
254 	 * Try to open file again.  It should succeed.  This tests the case
255 	 *  where the file is opened, closed, then re-opened again.
256 	 */
257 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
258 	CU_ASSERT(g_bserrno == 0);
259 	CU_ASSERT(g_blob != NULL);
260 	blob = g_blob;
261 
262 	spdk_blob_close(blob, blob_op_complete, NULL);
263 	CU_ASSERT(g_bserrno == 0);
264 
265 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
266 	CU_ASSERT(g_bserrno == 0);
267 	g_bs = NULL;
268 }
269 
270 static void
271 blob_create(void)
272 {
273 	struct spdk_blob_store *bs;
274 	struct spdk_bs_dev *dev;
275 	struct spdk_blob *blob;
276 	struct spdk_blob_opts opts;
277 	spdk_blob_id blobid;
278 
279 	dev = init_dev();
280 
281 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
282 	CU_ASSERT(g_bserrno == 0);
283 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
284 	bs = g_bs;
285 
286 	/* Create blob with 10 clusters */
287 
288 	spdk_blob_opts_init(&opts);
289 	opts.num_clusters = 10;
290 
291 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
292 	CU_ASSERT(g_bserrno == 0);
293 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
294 	blobid = g_blobid;
295 
296 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
297 	CU_ASSERT(g_bserrno == 0);
298 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
299 	blob = g_blob;
300 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10)
301 
302 	spdk_blob_close(blob, blob_op_complete, NULL);
303 	CU_ASSERT(g_bserrno == 0);
304 
305 	/* Create blob with 0 clusters */
306 
307 	spdk_blob_opts_init(&opts);
308 	opts.num_clusters = 0;
309 
310 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
311 	CU_ASSERT(g_bserrno == 0);
312 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
313 	blobid = g_blobid;
314 
315 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
316 	CU_ASSERT(g_bserrno == 0);
317 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
318 	blob = g_blob;
319 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0)
320 
321 	spdk_blob_close(blob, blob_op_complete, NULL);
322 	CU_ASSERT(g_bserrno == 0);
323 
324 	/* Create blob with default options (opts == NULL) */
325 
326 	spdk_bs_create_blob_ext(bs, NULL, blob_op_with_id_complete, NULL);
327 	CU_ASSERT(g_bserrno == 0);
328 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
329 	blobid = g_blobid;
330 
331 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
332 	CU_ASSERT(g_bserrno == 0);
333 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
334 	blob = g_blob;
335 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0)
336 
337 	spdk_blob_close(blob, blob_op_complete, NULL);
338 	CU_ASSERT(g_bserrno == 0);
339 
340 	/* Try to create blob with size larger than blobstore */
341 
342 	spdk_blob_opts_init(&opts);
343 	opts.num_clusters = bs->total_clusters + 1;
344 
345 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
346 	CU_ASSERT(g_bserrno == -ENOSPC);
347 
348 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
349 	CU_ASSERT(g_bserrno == 0);
350 	g_bs = NULL;
351 
352 }
353 
354 static void
355 blob_create_internal(void)
356 {
357 	struct spdk_blob_store *bs;
358 	struct spdk_bs_dev *dev;
359 	struct spdk_blob *blob;
360 	struct spdk_blob_opts opts;
361 	struct spdk_blob_xattr_opts internal_xattrs;
362 	const void *value;
363 	size_t value_len;
364 	spdk_blob_id blobid;
365 	int rc;
366 
367 	dev = init_dev();
368 
369 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
370 	CU_ASSERT(g_bserrno == 0);
371 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
372 	bs = g_bs;
373 
374 	/* Create blob with custom xattrs */
375 
376 	spdk_blob_opts_init(&opts);
377 	_spdk_blob_xattrs_init(&internal_xattrs);
378 	internal_xattrs.count = 3;
379 	internal_xattrs.names = g_xattr_names;
380 	internal_xattrs.get_value = _get_xattr_value;
381 	internal_xattrs.ctx = &g_ctx;
382 
383 	_spdk_bs_create_blob(bs, &opts, &internal_xattrs, blob_op_with_id_complete, NULL);
384 	CU_ASSERT(g_bserrno == 0);
385 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
386 	blobid = g_blobid;
387 
388 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
389 	CU_ASSERT(g_bserrno == 0);
390 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
391 	blob = g_blob;
392 
393 	rc = _spdk_blob_get_xattr_value(blob, g_xattr_names[0], &value, &value_len, true);
394 	CU_ASSERT(rc == 0);
395 	SPDK_CU_ASSERT_FATAL(value != NULL);
396 	CU_ASSERT(value_len == strlen(g_xattr_values[0]));
397 	CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len);
398 
399 	rc = _spdk_blob_get_xattr_value(blob, g_xattr_names[1], &value, &value_len, true);
400 	CU_ASSERT(rc == 0);
401 	SPDK_CU_ASSERT_FATAL(value != NULL);
402 	CU_ASSERT(value_len == strlen(g_xattr_values[1]));
403 	CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len);
404 
405 	rc = _spdk_blob_get_xattr_value(blob, g_xattr_names[2], &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[2]));
409 	CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len);
410 
411 	rc = spdk_blob_get_xattr_value(blob, g_xattr_names[0], &value, &value_len);
412 	CU_ASSERT(rc != 0);
413 
414 	rc = spdk_blob_get_xattr_value(blob, g_xattr_names[1], &value, &value_len);
415 	CU_ASSERT(rc != 0);
416 
417 	rc = spdk_blob_get_xattr_value(blob, g_xattr_names[2], &value, &value_len);
418 	CU_ASSERT(rc != 0);
419 
420 	spdk_blob_close(blob, blob_op_complete, NULL);
421 	CU_ASSERT(g_bserrno == 0);
422 
423 	/* Create blob with NULL internal options  */
424 
425 	_spdk_bs_create_blob(bs, NULL, NULL, blob_op_with_id_complete, NULL);
426 	CU_ASSERT(g_bserrno == 0);
427 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
428 	blobid = g_blobid;
429 
430 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
431 	CU_ASSERT(g_bserrno == 0);
432 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
433 	CU_ASSERT(TAILQ_FIRST(&g_blob->xattrs_internal) == NULL);
434 
435 	blob = g_blob;
436 
437 	spdk_blob_close(blob, blob_op_complete, NULL);
438 	CU_ASSERT(g_bserrno == 0);
439 
440 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
441 	CU_ASSERT(g_bserrno == 0);
442 	g_bs = NULL;
443 
444 }
445 
446 static void
447 blob_thin_provision(void)
448 {
449 	struct spdk_blob_store *bs;
450 	struct spdk_bs_dev *dev;
451 	struct spdk_blob *blob;
452 	struct spdk_blob_opts opts;
453 	struct spdk_bs_opts bs_opts;
454 	spdk_blob_id blobid;
455 
456 	dev = init_dev();
457 	spdk_bs_opts_init(&bs_opts);
458 	snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE");
459 
460 	/* Initialize a new blob store */
461 	spdk_bs_init(dev, &bs_opts, bs_op_with_handle_complete, NULL);
462 	CU_ASSERT(g_bserrno == 0);
463 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
464 
465 	bs = g_bs;
466 
467 	/* Create blob with thin provisioning enabled */
468 
469 	spdk_blob_opts_init(&opts);
470 	opts.thin_provision = true;
471 	opts.num_clusters = 10;
472 
473 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
474 	CU_ASSERT(g_bserrno == 0);
475 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
476 	blobid = g_blobid;
477 
478 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
479 	CU_ASSERT(g_bserrno == 0);
480 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
481 	blob = g_blob;
482 	CU_ASSERT(blob->invalid_flags & SPDK_BLOB_THIN_PROV);
483 
484 	spdk_blob_close(blob, blob_op_complete, NULL);
485 	CU_ASSERT(g_bserrno == 0);
486 
487 	/* Do not shut down cleanly.  This makes sure that when we load again
488 	 *  and try to recover a valid used_cluster map, that blobstore will
489 	 *  ignore clusters with index 0 since these are unallocated clusters.
490 	 */
491 
492 	/* Load an existing blob store and check if invalid_flags is set */
493 	dev = init_dev();
494 	snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE");
495 	spdk_bs_load(dev, &bs_opts, bs_op_with_handle_complete, NULL);
496 	CU_ASSERT(g_bserrno == 0);
497 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
498 
499 	bs = g_bs;
500 
501 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
502 	CU_ASSERT(g_bserrno == 0);
503 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
504 	blob = g_blob;
505 	CU_ASSERT(blob->invalid_flags & SPDK_BLOB_THIN_PROV);
506 
507 	spdk_blob_close(blob, blob_op_complete, NULL);
508 	CU_ASSERT(g_bserrno == 0);
509 
510 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
511 	CU_ASSERT(g_bserrno == 0);
512 	g_bs = NULL;
513 }
514 
515 static void
516 blob_snapshot(void)
517 {
518 	struct spdk_blob_store *bs;
519 	struct spdk_bs_dev *dev;
520 	struct spdk_blob *blob;
521 	struct spdk_blob *snapshot, *snapshot2;
522 	struct spdk_blob_bs_dev *blob_bs_dev;
523 	struct spdk_blob_opts opts;
524 	struct spdk_blob_xattr_opts xattrs;
525 	spdk_blob_id blobid;
526 	spdk_blob_id snapshotid;
527 	const void *value;
528 	size_t value_len;
529 	int rc;
530 
531 	dev = init_dev();
532 
533 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
534 	CU_ASSERT(g_bserrno == 0);
535 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
536 	bs = g_bs;
537 
538 	/* Create blob with 10 clusters */
539 	spdk_blob_opts_init(&opts);
540 	opts.num_clusters = 10;
541 
542 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
543 	CU_ASSERT(g_bserrno == 0);
544 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
545 	blobid = g_blobid;
546 
547 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
548 	CU_ASSERT(g_bserrno == 0);
549 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
550 	blob = g_blob;
551 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10)
552 
553 	/* Create snapshot from blob */
554 	spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL);
555 	CU_ASSERT(g_bserrno == 0);
556 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
557 	snapshotid = g_blobid;
558 
559 	spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL);
560 	CU_ASSERT(g_bserrno == 0);
561 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
562 	snapshot = g_blob;
563 	CU_ASSERT(snapshot->data_ro == true)
564 	CU_ASSERT(snapshot->md_ro == true)
565 	CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 10)
566 
567 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10)
568 	CU_ASSERT(blob->invalid_flags & SPDK_BLOB_THIN_PROV);
569 	CU_ASSERT(spdk_mem_all_zero(blob->active.clusters,
570 				    blob->active.num_clusters * sizeof(blob->active.clusters[0])));
571 
572 	/* Try to create snapshot from clone with xattrs */
573 	xattrs.names = g_xattr_names;
574 	xattrs.get_value = _get_xattr_value;
575 	xattrs.count = 3;
576 	xattrs.ctx = &g_ctx;
577 	spdk_bs_create_snapshot(bs, blobid, &xattrs, blob_op_with_id_complete, NULL);
578 	CU_ASSERT(g_bserrno == 0);
579 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
580 	blobid = g_blobid;
581 
582 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
583 	CU_ASSERT(g_bserrno == 0);
584 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
585 	snapshot2 = g_blob;
586 	CU_ASSERT(snapshot2->data_ro == true)
587 	CU_ASSERT(snapshot2->md_ro == true)
588 	CU_ASSERT(spdk_blob_get_num_clusters(snapshot2) == 10)
589 
590 	/* Confirm that blob is backed by snapshot2 and snapshot2 is backed by snapshot */
591 	CU_ASSERT(snapshot->back_bs_dev == NULL);
592 	SPDK_CU_ASSERT_FATAL(blob->back_bs_dev != NULL);
593 	SPDK_CU_ASSERT_FATAL(snapshot2->back_bs_dev != NULL);
594 
595 	blob_bs_dev = (struct spdk_blob_bs_dev *)blob->back_bs_dev;
596 	CU_ASSERT(blob_bs_dev->blob == snapshot2);
597 
598 	blob_bs_dev = (struct spdk_blob_bs_dev *)snapshot2->back_bs_dev;
599 	CU_ASSERT(blob_bs_dev->blob == snapshot);
600 
601 	rc = spdk_blob_get_xattr_value(snapshot2, g_xattr_names[0], &value, &value_len);
602 	CU_ASSERT(rc == 0);
603 	SPDK_CU_ASSERT_FATAL(value != NULL);
604 	CU_ASSERT(value_len == strlen(g_xattr_values[0]));
605 	CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len);
606 
607 	rc = spdk_blob_get_xattr_value(snapshot2, g_xattr_names[1], &value, &value_len);
608 	CU_ASSERT(rc == 0);
609 	SPDK_CU_ASSERT_FATAL(value != NULL);
610 	CU_ASSERT(value_len == strlen(g_xattr_values[1]));
611 	CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len);
612 
613 	rc = spdk_blob_get_xattr_value(snapshot2, g_xattr_names[2], &value, &value_len);
614 	CU_ASSERT(rc == 0);
615 	SPDK_CU_ASSERT_FATAL(value != NULL);
616 	CU_ASSERT(value_len == strlen(g_xattr_values[2]));
617 	CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len);
618 
619 	/* Try to create snapshot from snapshot */
620 	spdk_bs_create_snapshot(bs, snapshotid, NULL, blob_op_with_id_complete, NULL);
621 	CU_ASSERT(g_bserrno == -EINVAL);
622 	CU_ASSERT(g_blobid == SPDK_BLOBID_INVALID);
623 
624 	spdk_blob_close(blob, blob_op_complete, NULL);
625 	CU_ASSERT(g_bserrno == 0);
626 
627 	spdk_blob_close(snapshot, blob_op_complete, NULL);
628 	CU_ASSERT(g_bserrno == 0);
629 
630 	spdk_blob_close(snapshot2, blob_op_complete, NULL);
631 	CU_ASSERT(g_bserrno == 0);
632 
633 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
634 	CU_ASSERT(g_bserrno == 0);
635 	g_bs = NULL;
636 }
637 
638 static void
639 blob_clone(void)
640 {
641 	struct spdk_blob_store *bs;
642 	struct spdk_bs_dev *dev;
643 	struct spdk_blob_opts opts;
644 	struct spdk_blob *blob, *snapshot, *clone;
645 	spdk_blob_id blobid, cloneid, snapshotid;
646 	struct spdk_blob_xattr_opts xattrs;
647 	const void *value;
648 	size_t value_len;
649 	int rc;
650 
651 	dev = init_dev();
652 
653 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
654 	CU_ASSERT(g_bserrno == 0);
655 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
656 	bs = g_bs;
657 
658 	/* Create blob with 10 clusters */
659 
660 	spdk_blob_opts_init(&opts);
661 	opts.num_clusters = 10;
662 
663 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
664 	CU_ASSERT(g_bserrno == 0);
665 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
666 	blobid = g_blobid;
667 
668 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
669 	CU_ASSERT(g_bserrno == 0);
670 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
671 	blob = g_blob;
672 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10)
673 
674 	/* Create snapshot */
675 	spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL);
676 	CU_ASSERT(g_bserrno == 0);
677 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
678 	snapshotid = g_blobid;
679 
680 	spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL);
681 	CU_ASSERT(g_bserrno == 0);
682 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
683 	snapshot = g_blob;
684 	CU_ASSERT(snapshot->data_ro == true)
685 	CU_ASSERT(snapshot->md_ro == true)
686 	CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 10);
687 
688 	spdk_blob_close(snapshot, blob_op_complete, NULL);
689 	CU_ASSERT(g_bserrno == 0);
690 
691 	/* Create clone from snapshot with xattrs */
692 	xattrs.names = g_xattr_names;
693 	xattrs.get_value = _get_xattr_value;
694 	xattrs.count = 3;
695 	xattrs.ctx = &g_ctx;
696 
697 	spdk_bs_create_clone(bs, snapshotid, &xattrs, blob_op_with_id_complete, NULL);
698 	CU_ASSERT(g_bserrno == 0);
699 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
700 	cloneid = g_blobid;
701 
702 	spdk_bs_open_blob(bs, cloneid, blob_op_with_handle_complete, NULL);
703 	CU_ASSERT(g_bserrno == 0);
704 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
705 	clone = g_blob;
706 	CU_ASSERT(clone->data_ro == false)
707 	CU_ASSERT(clone->md_ro == false)
708 	CU_ASSERT(spdk_blob_get_num_clusters(clone) == 10);
709 
710 	rc = spdk_blob_get_xattr_value(clone, g_xattr_names[0], &value, &value_len);
711 	CU_ASSERT(rc == 0);
712 	SPDK_CU_ASSERT_FATAL(value != NULL);
713 	CU_ASSERT(value_len == strlen(g_xattr_values[0]));
714 	CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len);
715 
716 	rc = spdk_blob_get_xattr_value(clone, g_xattr_names[1], &value, &value_len);
717 	CU_ASSERT(rc == 0);
718 	SPDK_CU_ASSERT_FATAL(value != NULL);
719 	CU_ASSERT(value_len == strlen(g_xattr_values[1]));
720 	CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len);
721 
722 	rc = spdk_blob_get_xattr_value(clone, g_xattr_names[2], &value, &value_len);
723 	CU_ASSERT(rc == 0);
724 	SPDK_CU_ASSERT_FATAL(value != NULL);
725 	CU_ASSERT(value_len == strlen(g_xattr_values[2]));
726 	CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len);
727 
728 
729 	spdk_blob_close(clone, blob_op_complete, NULL);
730 	CU_ASSERT(g_bserrno == 0);
731 
732 	/* Try to create clone from not read only blob */
733 	spdk_bs_create_clone(bs, blobid, NULL, blob_op_with_id_complete, NULL);
734 	CU_ASSERT(g_bserrno == -EINVAL);
735 	CU_ASSERT(g_blobid == SPDK_BLOBID_INVALID);
736 
737 	/* Mark blob as read only */
738 	spdk_blob_set_read_only(blob);
739 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
740 	CU_ASSERT(g_bserrno == 0);
741 
742 	/* Create clone from read only blob */
743 	spdk_bs_create_clone(bs, blobid, NULL, blob_op_with_id_complete, NULL);
744 	CU_ASSERT(g_bserrno == 0);
745 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
746 	cloneid = g_blobid;
747 
748 	spdk_bs_open_blob(bs, cloneid, blob_op_with_handle_complete, NULL);
749 	CU_ASSERT(g_bserrno == 0);
750 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
751 	clone = g_blob;
752 	CU_ASSERT(clone->data_ro == false)
753 	CU_ASSERT(clone->md_ro == false)
754 	CU_ASSERT(spdk_blob_get_num_clusters(clone) == 10);
755 
756 	spdk_blob_close(clone, blob_op_complete, NULL);
757 	CU_ASSERT(g_bserrno == 0);
758 
759 	spdk_blob_close(blob, blob_op_complete, NULL);
760 	CU_ASSERT(g_bserrno == 0);
761 
762 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
763 	CU_ASSERT(g_bserrno == 0);
764 	g_bs = NULL;
765 
766 }
767 
768 static void
769 blob_inflate(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;
775 	spdk_blob_id blobid, snapshotid;
776 	struct spdk_io_channel *channel;
777 	uint64_t free_clusters;
778 
779 	dev = init_dev();
780 
781 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
782 	CU_ASSERT(g_bserrno == 0);
783 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
784 	bs = g_bs;
785 
786 	channel = spdk_bs_alloc_io_channel(bs);
787 	SPDK_CU_ASSERT_FATAL(channel != NULL);
788 
789 	/* Create blob with 10 clusters */
790 
791 	spdk_blob_opts_init(&opts);
792 	opts.num_clusters = 10;
793 
794 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
795 	CU_ASSERT(g_bserrno == 0);
796 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
797 	blobid = g_blobid;
798 
799 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
800 	CU_ASSERT(g_bserrno == 0);
801 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
802 	blob = g_blob;
803 
804 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10)
805 	CU_ASSERT(spdk_blob_is_thin_provisioned(blob) == false);
806 
807 	/* Create snapshot */
808 
809 	spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL);
810 	CU_ASSERT(g_bserrno == 0);
811 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
812 	snapshotid = g_blobid;
813 
814 	CU_ASSERT(spdk_blob_is_thin_provisioned(blob) == true);
815 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10)
816 
817 	spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL);
818 	CU_ASSERT(g_bserrno == 0);
819 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
820 	snapshot = g_blob;
821 	CU_ASSERT(snapshot->data_ro == true)
822 	CU_ASSERT(snapshot->md_ro == true)
823 	CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 10);
824 
825 	spdk_blob_close(snapshot, blob_op_complete, NULL);
826 	CU_ASSERT(g_bserrno == 0);
827 
828 	free_clusters = spdk_bs_free_cluster_count(bs);
829 
830 	/* Inflate blob */
831 	spdk_bs_inflate_blob(bs, channel, blobid, blob_op_complete, NULL);
832 	CU_ASSERT(g_bserrno == 0);
833 
834 	/* All 10 clusters should be allocated from blob store */
835 	CU_ASSERT(spdk_bs_free_cluster_count(bs) == free_clusters - 10);
836 
837 	/* Now, it should be possible to delete snapshot */
838 	spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL);
839 	CU_ASSERT(g_bserrno == 0);
840 
841 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10)
842 	CU_ASSERT(spdk_blob_is_thin_provisioned(blob) == false);
843 
844 	spdk_blob_close(blob, blob_op_complete, NULL);
845 	CU_ASSERT(g_bserrno == 0);
846 
847 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
848 	CU_ASSERT(g_bserrno == 0);
849 	g_bs = NULL;
850 
851 	spdk_bs_free_io_channel(channel);
852 }
853 
854 static void
855 blob_delete(void)
856 {
857 	struct spdk_blob_store *bs;
858 	struct spdk_bs_dev *dev;
859 	spdk_blob_id blobid;
860 
861 	dev = init_dev();
862 
863 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
864 	CU_ASSERT(g_bserrno == 0);
865 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
866 	bs = g_bs;
867 
868 	/* Create a blob and then delete it. */
869 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
870 	CU_ASSERT(g_bserrno == 0);
871 	CU_ASSERT(g_blobid > 0);
872 	blobid = g_blobid;
873 
874 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
875 	CU_ASSERT(g_bserrno == 0);
876 
877 	/* Try to open the blob */
878 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
879 	CU_ASSERT(g_bserrno == -ENOENT);
880 
881 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
882 	CU_ASSERT(g_bserrno == 0);
883 	g_bs = NULL;
884 }
885 
886 static void
887 blob_resize(void)
888 {
889 	struct spdk_blob_store *bs;
890 	struct spdk_bs_dev *dev;
891 	struct spdk_blob *blob;
892 	spdk_blob_id blobid;
893 	uint64_t free_clusters;
894 
895 	dev = init_dev();
896 
897 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
898 	CU_ASSERT(g_bserrno == 0);
899 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
900 	bs = g_bs;
901 	free_clusters = spdk_bs_free_cluster_count(bs);
902 
903 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
904 	CU_ASSERT(g_bserrno == 0);
905 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
906 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
907 	blobid = g_blobid;
908 
909 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
910 	CU_ASSERT(g_bserrno == 0);
911 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
912 	blob = g_blob;
913 
914 	/* Confirm that resize fails if blob is marked read-only. */
915 	blob->md_ro = true;
916 	spdk_blob_resize(blob, 5, blob_op_complete, NULL);
917 	CU_ASSERT(g_bserrno == -EPERM);
918 	blob->md_ro = false;
919 
920 	/* The blob started at 0 clusters. Resize it to be 5. */
921 	spdk_blob_resize(blob, 5, blob_op_complete, NULL);
922 	CU_ASSERT(g_bserrno == 0);
923 	CU_ASSERT((free_clusters - 5) == spdk_bs_free_cluster_count(bs));
924 
925 	/* Shrink the blob to 3 clusters. This will not actually release
926 	 * the old clusters until the blob is synced.
927 	 */
928 	spdk_blob_resize(blob, 3, blob_op_complete, NULL);
929 	CU_ASSERT(g_bserrno == 0);
930 	/* Verify there are still 5 clusters in use */
931 	CU_ASSERT((free_clusters - 5) == spdk_bs_free_cluster_count(bs));
932 
933 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
934 	CU_ASSERT(g_bserrno == 0);
935 	/* Now there are only 3 clusters in use */
936 	CU_ASSERT((free_clusters - 3) == spdk_bs_free_cluster_count(bs));
937 
938 	/* Resize the blob to be 10 clusters. Growth takes effect immediately. */
939 	spdk_blob_resize(blob, 10, blob_op_complete, NULL);
940 	CU_ASSERT(g_bserrno == 0);
941 	CU_ASSERT((free_clusters - 10) == spdk_bs_free_cluster_count(bs));
942 
943 	/* Try to resize the blob to size larger than blobstore. */
944 	spdk_blob_resize(blob, bs->total_clusters + 1, blob_op_complete, NULL);
945 	CU_ASSERT(g_bserrno == -ENOSPC);
946 
947 	spdk_blob_close(blob, blob_op_complete, NULL);
948 	CU_ASSERT(g_bserrno == 0);
949 
950 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
951 	CU_ASSERT(g_bserrno == 0);
952 
953 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
954 	CU_ASSERT(g_bserrno == 0);
955 	g_bs = NULL;
956 }
957 
958 static void
959 blob_read_only(void)
960 {
961 	struct spdk_blob_store *bs;
962 	struct spdk_bs_dev *dev;
963 	struct spdk_blob *blob;
964 	struct spdk_bs_opts opts;
965 	spdk_blob_id blobid;
966 	int rc;
967 
968 	dev = init_dev();
969 	spdk_bs_opts_init(&opts);
970 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
971 
972 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
973 	CU_ASSERT(g_bserrno == 0);
974 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
975 	bs = g_bs;
976 
977 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
978 	CU_ASSERT(g_bserrno == 0);
979 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
980 	blobid = g_blobid;
981 
982 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
983 	CU_ASSERT(g_bserrno == 0);
984 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
985 	blob = g_blob;
986 
987 	rc = spdk_blob_set_read_only(blob);
988 	CU_ASSERT(rc == 0);
989 
990 	CU_ASSERT(blob->data_ro == false);
991 	CU_ASSERT(blob->md_ro == false);
992 
993 	spdk_blob_sync_md(blob, bs_op_complete, NULL);
994 
995 	CU_ASSERT(blob->data_ro == true);
996 	CU_ASSERT(blob->md_ro == true);
997 	CU_ASSERT(blob->data_ro_flags & SPDK_BLOB_READ_ONLY);
998 
999 	spdk_blob_close(blob, blob_op_complete, NULL);
1000 	CU_ASSERT(g_bserrno == 0);
1001 
1002 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1003 	CU_ASSERT(g_bserrno == 0);
1004 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1005 	blob = g_blob;
1006 
1007 	CU_ASSERT(blob->data_ro == true);
1008 	CU_ASSERT(blob->md_ro == true);
1009 	CU_ASSERT(blob->data_ro_flags & SPDK_BLOB_READ_ONLY);
1010 
1011 	spdk_blob_close(blob, blob_op_complete, NULL);
1012 	CU_ASSERT(g_bserrno == 0);
1013 
1014 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1015 	CU_ASSERT(g_bserrno == 0);
1016 	g_bs = NULL;
1017 	g_blob = NULL;
1018 	g_blobid = 0;
1019 
1020 	/* Load an existing blob store */
1021 	dev = init_dev();
1022 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
1023 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1024 	CU_ASSERT(g_bserrno == 0);
1025 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1026 
1027 	spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
1028 	CU_ASSERT(g_bserrno == 0);
1029 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1030 	blob = g_blob;
1031 
1032 	CU_ASSERT(blob->data_ro == true);
1033 	CU_ASSERT(blob->md_ro == true);
1034 	CU_ASSERT(blob->data_ro_flags & SPDK_BLOB_READ_ONLY);
1035 
1036 	spdk_blob_close(blob, blob_op_complete, NULL);
1037 	CU_ASSERT(g_bserrno == 0);
1038 
1039 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1040 	CU_ASSERT(g_bserrno == 0);
1041 
1042 }
1043 
1044 static void
1045 channel_ops(void)
1046 {
1047 	struct spdk_blob_store *bs;
1048 	struct spdk_bs_dev *dev;
1049 	struct spdk_io_channel *channel;
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 
1058 	channel = spdk_bs_alloc_io_channel(bs);
1059 	CU_ASSERT(channel != NULL);
1060 
1061 	spdk_bs_free_io_channel(channel);
1062 
1063 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1064 	CU_ASSERT(g_bserrno == 0);
1065 	g_bs = NULL;
1066 }
1067 
1068 static void
1069 blob_write(void)
1070 {
1071 	struct spdk_blob_store *bs;
1072 	struct spdk_bs_dev *dev;
1073 	struct spdk_blob *blob;
1074 	struct spdk_io_channel *channel;
1075 	spdk_blob_id blobid;
1076 	uint64_t pages_per_cluster;
1077 	uint8_t payload[10 * 4096];
1078 
1079 	dev = init_dev();
1080 
1081 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1082 	CU_ASSERT(g_bserrno == 0);
1083 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1084 	bs = g_bs;
1085 
1086 	pages_per_cluster = spdk_bs_get_cluster_size(bs) / spdk_bs_get_page_size(bs);
1087 
1088 	channel = spdk_bs_alloc_io_channel(bs);
1089 	CU_ASSERT(channel != NULL);
1090 
1091 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
1092 	CU_ASSERT(g_bserrno == 0);
1093 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1094 	blobid = g_blobid;
1095 
1096 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1097 	CU_ASSERT(g_bserrno == 0);
1098 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1099 	blob = g_blob;
1100 
1101 	/* Write to a blob with 0 size */
1102 	spdk_blob_io_write(blob, channel, payload, 0, 1, blob_op_complete, NULL);
1103 	CU_ASSERT(g_bserrno == -EINVAL);
1104 
1105 	/* Resize the blob */
1106 	spdk_blob_resize(blob, 5, blob_op_complete, NULL);
1107 	CU_ASSERT(g_bserrno == 0);
1108 
1109 	/* Confirm that write fails if blob is marked read-only. */
1110 	blob->data_ro = true;
1111 	spdk_blob_io_write(blob, channel, payload, 0, 1, blob_op_complete, NULL);
1112 	CU_ASSERT(g_bserrno == -EPERM);
1113 	blob->data_ro = false;
1114 
1115 	/* Write to the blob */
1116 	spdk_blob_io_write(blob, channel, payload, 0, 1, blob_op_complete, NULL);
1117 	CU_ASSERT(g_bserrno == 0);
1118 
1119 	/* Write starting beyond the end */
1120 	spdk_blob_io_write(blob, channel, payload, 5 * pages_per_cluster, 1, blob_op_complete,
1121 			   NULL);
1122 	CU_ASSERT(g_bserrno == -EINVAL);
1123 
1124 	/* Write starting at a valid location but going off the end */
1125 	spdk_blob_io_write(blob, channel, payload, 4 * pages_per_cluster, pages_per_cluster + 1,
1126 			   blob_op_complete, NULL);
1127 	CU_ASSERT(g_bserrno == -EINVAL);
1128 
1129 	spdk_blob_close(blob, blob_op_complete, NULL);
1130 	CU_ASSERT(g_bserrno == 0);
1131 
1132 	spdk_bs_free_io_channel(channel);
1133 
1134 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1135 	CU_ASSERT(g_bserrno == 0);
1136 	g_bs = NULL;
1137 }
1138 
1139 static void
1140 blob_read(void)
1141 {
1142 	struct spdk_blob_store *bs;
1143 	struct spdk_bs_dev *dev;
1144 	struct spdk_blob *blob;
1145 	struct spdk_io_channel *channel;
1146 	spdk_blob_id blobid;
1147 	uint64_t pages_per_cluster;
1148 	uint8_t payload[10 * 4096];
1149 
1150 	dev = init_dev();
1151 
1152 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1153 	CU_ASSERT(g_bserrno == 0);
1154 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1155 	bs = g_bs;
1156 
1157 	pages_per_cluster = spdk_bs_get_cluster_size(bs) / spdk_bs_get_page_size(bs);
1158 
1159 	channel = spdk_bs_alloc_io_channel(bs);
1160 	CU_ASSERT(channel != NULL);
1161 
1162 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
1163 	CU_ASSERT(g_bserrno == 0);
1164 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1165 	blobid = g_blobid;
1166 
1167 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1168 	CU_ASSERT(g_bserrno == 0);
1169 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1170 	blob = g_blob;
1171 
1172 	/* Read from a blob with 0 size */
1173 	spdk_blob_io_read(blob, channel, payload, 0, 1, blob_op_complete, NULL);
1174 	CU_ASSERT(g_bserrno == -EINVAL);
1175 
1176 	/* Resize the blob */
1177 	spdk_blob_resize(blob, 5, blob_op_complete, NULL);
1178 	CU_ASSERT(g_bserrno == 0);
1179 
1180 	/* Confirm that read passes if blob is marked read-only. */
1181 	blob->data_ro = true;
1182 	spdk_blob_io_read(blob, channel, payload, 0, 1, blob_op_complete, NULL);
1183 	CU_ASSERT(g_bserrno == 0);
1184 	blob->data_ro = false;
1185 
1186 	/* Read from the blob */
1187 	spdk_blob_io_read(blob, channel, payload, 0, 1, blob_op_complete, NULL);
1188 	CU_ASSERT(g_bserrno == 0);
1189 
1190 	/* Read starting beyond the end */
1191 	spdk_blob_io_read(blob, channel, payload, 5 * pages_per_cluster, 1, blob_op_complete,
1192 			  NULL);
1193 	CU_ASSERT(g_bserrno == -EINVAL);
1194 
1195 	/* Read starting at a valid location but going off the end */
1196 	spdk_blob_io_read(blob, channel, payload, 4 * pages_per_cluster, pages_per_cluster + 1,
1197 			  blob_op_complete, NULL);
1198 	CU_ASSERT(g_bserrno == -EINVAL);
1199 
1200 	spdk_blob_close(blob, blob_op_complete, NULL);
1201 	CU_ASSERT(g_bserrno == 0);
1202 
1203 	spdk_bs_free_io_channel(channel);
1204 
1205 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1206 	CU_ASSERT(g_bserrno == 0);
1207 	g_bs = NULL;
1208 }
1209 
1210 static void
1211 blob_rw_verify(void)
1212 {
1213 	struct spdk_blob_store *bs;
1214 	struct spdk_bs_dev *dev;
1215 	struct spdk_blob *blob;
1216 	struct spdk_io_channel *channel;
1217 	spdk_blob_id blobid;
1218 	uint8_t payload_read[10 * 4096];
1219 	uint8_t payload_write[10 * 4096];
1220 
1221 	dev = init_dev();
1222 
1223 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1224 	CU_ASSERT(g_bserrno == 0);
1225 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1226 	bs = g_bs;
1227 
1228 	channel = spdk_bs_alloc_io_channel(bs);
1229 	CU_ASSERT(channel != NULL);
1230 
1231 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
1232 	CU_ASSERT(g_bserrno == 0);
1233 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1234 	blobid = g_blobid;
1235 
1236 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1237 	CU_ASSERT(g_bserrno == 0);
1238 	CU_ASSERT(g_blob != NULL);
1239 	blob = g_blob;
1240 
1241 	spdk_blob_resize(blob, 32, blob_op_complete, NULL);
1242 	CU_ASSERT(g_bserrno == 0);
1243 
1244 	memset(payload_write, 0xE5, sizeof(payload_write));
1245 	spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL);
1246 	CU_ASSERT(g_bserrno == 0);
1247 
1248 	memset(payload_read, 0x00, sizeof(payload_read));
1249 	spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL);
1250 	CU_ASSERT(g_bserrno == 0);
1251 	CU_ASSERT(memcmp(payload_write, payload_read, 4 * 4096) == 0);
1252 
1253 	spdk_blob_close(blob, blob_op_complete, NULL);
1254 	CU_ASSERT(g_bserrno == 0);
1255 
1256 	spdk_bs_free_io_channel(channel);
1257 
1258 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1259 	CU_ASSERT(g_bserrno == 0);
1260 	g_bs = NULL;
1261 }
1262 
1263 static void
1264 blob_rw_verify_iov(void)
1265 {
1266 	struct spdk_blob_store *bs;
1267 	struct spdk_bs_dev *dev;
1268 	struct spdk_blob *blob;
1269 	struct spdk_io_channel *channel;
1270 	spdk_blob_id blobid;
1271 	uint8_t payload_read[10 * 4096];
1272 	uint8_t payload_write[10 * 4096];
1273 	struct iovec iov_read[3];
1274 	struct iovec iov_write[3];
1275 	void *buf;
1276 
1277 	dev = init_dev();
1278 	memset(g_dev_buffer, 0, DEV_BUFFER_SIZE);
1279 
1280 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1281 	CU_ASSERT(g_bserrno == 0);
1282 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1283 	bs = g_bs;
1284 
1285 	channel = spdk_bs_alloc_io_channel(bs);
1286 	CU_ASSERT(channel != NULL);
1287 
1288 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
1289 	CU_ASSERT(g_bserrno == 0);
1290 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1291 	blobid = g_blobid;
1292 
1293 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1294 	CU_ASSERT(g_bserrno == 0);
1295 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1296 	blob = g_blob;
1297 
1298 	spdk_blob_resize(blob, 2, blob_op_complete, NULL);
1299 	CU_ASSERT(g_bserrno == 0);
1300 
1301 	/*
1302 	 * Manually adjust the offset of the blob's second cluster.  This allows
1303 	 *  us to make sure that the readv/write code correctly accounts for I/O
1304 	 *  that cross cluster boundaries.  Start by asserting that the allocated
1305 	 *  clusters are where we expect before modifying the second cluster.
1306 	 */
1307 	CU_ASSERT(blob->active.clusters[0] == 1 * 256);
1308 	CU_ASSERT(blob->active.clusters[1] == 2 * 256);
1309 	blob->active.clusters[1] = 3 * 256;
1310 
1311 	memset(payload_write, 0xE5, sizeof(payload_write));
1312 	iov_write[0].iov_base = payload_write;
1313 	iov_write[0].iov_len = 1 * 4096;
1314 	iov_write[1].iov_base = payload_write + 1 * 4096;
1315 	iov_write[1].iov_len = 5 * 4096;
1316 	iov_write[2].iov_base = payload_write + 6 * 4096;
1317 	iov_write[2].iov_len = 4 * 4096;
1318 	/*
1319 	 * Choose a page offset just before the cluster boundary.  The first 6 pages of payload
1320 	 *  will get written to the first cluster, the last 4 to the second cluster.
1321 	 */
1322 	spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL);
1323 	CU_ASSERT(g_bserrno == 0);
1324 
1325 	memset(payload_read, 0xAA, sizeof(payload_read));
1326 	iov_read[0].iov_base = payload_read;
1327 	iov_read[0].iov_len = 3 * 4096;
1328 	iov_read[1].iov_base = payload_read + 3 * 4096;
1329 	iov_read[1].iov_len = 4 * 4096;
1330 	iov_read[2].iov_base = payload_read + 7 * 4096;
1331 	iov_read[2].iov_len = 3 * 4096;
1332 	spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL);
1333 	CU_ASSERT(g_bserrno == 0);
1334 	CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0);
1335 
1336 	buf = calloc(1, 256 * 4096);
1337 	SPDK_CU_ASSERT_FATAL(buf != NULL);
1338 	/* Check that cluster 2 on "disk" was not modified. */
1339 	CU_ASSERT(memcmp(buf, &g_dev_buffer[512 * 4096], 256 * 4096) == 0);
1340 	free(buf);
1341 
1342 	spdk_blob_close(blob, blob_op_complete, NULL);
1343 	CU_ASSERT(g_bserrno == 0);
1344 
1345 	spdk_bs_free_io_channel(channel);
1346 
1347 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1348 	CU_ASSERT(g_bserrno == 0);
1349 	g_bs = NULL;
1350 }
1351 
1352 static uint32_t
1353 bs_channel_get_req_count(struct spdk_io_channel *_channel)
1354 {
1355 	struct spdk_bs_channel *channel = spdk_io_channel_get_ctx(_channel);
1356 	struct spdk_bs_request_set *set;
1357 	uint32_t count = 0;
1358 
1359 	TAILQ_FOREACH(set, &channel->reqs, link) {
1360 		count++;
1361 	}
1362 
1363 	return count;
1364 }
1365 
1366 static void
1367 blob_rw_verify_iov_nomem(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_write[10 * 4096];
1375 	struct iovec iov_write[3];
1376 	uint32_t req_count;
1377 
1378 	dev = init_dev();
1379 	memset(g_dev_buffer, 0, DEV_BUFFER_SIZE);
1380 
1381 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1382 	CU_ASSERT(g_bserrno == 0);
1383 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1384 	bs = g_bs;
1385 
1386 	channel = spdk_bs_alloc_io_channel(bs);
1387 	CU_ASSERT(channel != NULL);
1388 
1389 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
1390 	CU_ASSERT(g_bserrno == 0);
1391 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1392 	blobid = g_blobid;
1393 
1394 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1395 	CU_ASSERT(g_bserrno == 0);
1396 	CU_ASSERT(g_blob != NULL);
1397 	blob = g_blob;
1398 
1399 	spdk_blob_resize(blob, 2, blob_op_complete, NULL);
1400 	CU_ASSERT(g_bserrno == 0);
1401 
1402 	/*
1403 	 * Choose a page offset just before the cluster boundary.  The first 6 pages of payload
1404 	 *  will get written to the first cluster, the last 4 to the second cluster.
1405 	 */
1406 	iov_write[0].iov_base = payload_write;
1407 	iov_write[0].iov_len = 1 * 4096;
1408 	iov_write[1].iov_base = payload_write + 1 * 4096;
1409 	iov_write[1].iov_len = 5 * 4096;
1410 	iov_write[2].iov_base = payload_write + 6 * 4096;
1411 	iov_write[2].iov_len = 4 * 4096;
1412 	MOCK_SET(calloc, void *, NULL);
1413 	req_count = bs_channel_get_req_count(channel);
1414 	spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL);
1415 	CU_ASSERT(g_bserrno = -ENOMEM);
1416 	CU_ASSERT(req_count == bs_channel_get_req_count(channel));
1417 	MOCK_SET(calloc, void *, (void *)MOCK_PASS_THRU);
1418 
1419 	spdk_blob_close(blob, blob_op_complete, NULL);
1420 	CU_ASSERT(g_bserrno == 0);
1421 
1422 	spdk_bs_free_io_channel(channel);
1423 
1424 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1425 	CU_ASSERT(g_bserrno == 0);
1426 	g_bs = NULL;
1427 }
1428 
1429 static void
1430 blob_rw_iov_read_only(void)
1431 {
1432 	struct spdk_blob_store *bs;
1433 	struct spdk_bs_dev *dev;
1434 	struct spdk_blob *blob;
1435 	struct spdk_io_channel *channel;
1436 	spdk_blob_id blobid;
1437 	uint8_t payload_read[4096];
1438 	uint8_t payload_write[4096];
1439 	struct iovec iov_read;
1440 	struct iovec iov_write;
1441 
1442 	dev = init_dev();
1443 	memset(g_dev_buffer, 0, DEV_BUFFER_SIZE);
1444 
1445 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1446 	CU_ASSERT(g_bserrno == 0);
1447 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1448 	bs = g_bs;
1449 
1450 	channel = spdk_bs_alloc_io_channel(bs);
1451 	CU_ASSERT(channel != NULL);
1452 
1453 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
1454 	CU_ASSERT(g_bserrno == 0);
1455 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1456 	blobid = g_blobid;
1457 
1458 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1459 	CU_ASSERT(g_bserrno == 0);
1460 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1461 	blob = g_blob;
1462 
1463 	spdk_blob_resize(blob, 2, blob_op_complete, NULL);
1464 	CU_ASSERT(g_bserrno == 0);
1465 
1466 	/* Verify that writev failed if read_only flag is set. */
1467 	blob->data_ro = true;
1468 	iov_write.iov_base = payload_write;
1469 	iov_write.iov_len = sizeof(payload_write);
1470 	spdk_blob_io_writev(blob, channel, &iov_write, 1, 0, 1, blob_op_complete, NULL);
1471 	CU_ASSERT(g_bserrno == -EPERM);
1472 
1473 	/* Verify that reads pass if data_ro flag is set. */
1474 	iov_read.iov_base = payload_read;
1475 	iov_read.iov_len = sizeof(payload_read);
1476 	spdk_blob_io_readv(blob, channel, &iov_read, 1, 0, 1, blob_op_complete, NULL);
1477 	CU_ASSERT(g_bserrno == 0);
1478 
1479 	spdk_blob_close(blob, blob_op_complete, NULL);
1480 	CU_ASSERT(g_bserrno == 0);
1481 
1482 	spdk_bs_free_io_channel(channel);
1483 
1484 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1485 	CU_ASSERT(g_bserrno == 0);
1486 	g_bs = NULL;
1487 }
1488 
1489 static void
1490 blob_unmap(void)
1491 {
1492 	struct spdk_blob_store *bs;
1493 	struct spdk_bs_dev *dev;
1494 	struct spdk_blob *blob;
1495 	struct spdk_io_channel *channel;
1496 	spdk_blob_id blobid;
1497 	struct spdk_blob_opts opts;
1498 	uint8_t payload[4096];
1499 	int i;
1500 
1501 	dev = init_dev();
1502 
1503 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1504 	CU_ASSERT(g_bserrno == 0);
1505 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1506 	bs = g_bs;
1507 
1508 	channel = spdk_bs_alloc_io_channel(bs);
1509 	CU_ASSERT(channel != NULL);
1510 
1511 	spdk_blob_opts_init(&opts);
1512 	opts.num_clusters = 10;
1513 
1514 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
1515 	CU_ASSERT(g_bserrno == 0);
1516 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1517 	blobid = g_blobid;
1518 
1519 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1520 	CU_ASSERT(g_bserrno == 0);
1521 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1522 	blob = g_blob;
1523 
1524 	spdk_blob_resize(blob, 10, blob_op_complete, NULL);
1525 	CU_ASSERT(g_bserrno == 0);
1526 
1527 	memset(payload, 0, sizeof(payload));
1528 	payload[0] = 0xFF;
1529 
1530 	/*
1531 	 * Set first byte of every cluster to 0xFF.
1532 	 * First cluster on device is reserved so let's start from cluster number 1
1533 	 */
1534 	for (i = 1; i < 11; i++) {
1535 		g_dev_buffer[i * SPDK_BLOB_OPTS_CLUSTER_SZ] = 0xFF;
1536 	}
1537 
1538 	/* Confirm writes */
1539 	for (i = 0; i < 10; i++) {
1540 		payload[0] = 0;
1541 		spdk_blob_io_read(blob, channel, &payload, i * SPDK_BLOB_OPTS_CLUSTER_SZ / 4096, 1,
1542 				  blob_op_complete, NULL);
1543 		CU_ASSERT(g_bserrno == 0);
1544 		CU_ASSERT(payload[0] == 0xFF);
1545 	}
1546 
1547 	/* Mark some clusters as unallocated */
1548 	blob->active.clusters[1] = 0;
1549 	blob->active.clusters[2] = 0;
1550 	blob->active.clusters[3] = 0;
1551 	blob->active.clusters[6] = 0;
1552 	blob->active.clusters[8] = 0;
1553 
1554 	/* Unmap clusters by resizing to 0 */
1555 	spdk_blob_resize(blob, 0, blob_op_complete, NULL);
1556 	CU_ASSERT(g_bserrno == 0);
1557 
1558 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
1559 	CU_ASSERT(g_bserrno == 0);
1560 
1561 	/* Confirm that only 'allocated' clusters were unmaped */
1562 	for (i = 1; i < 11; i++) {
1563 		switch (i) {
1564 		case 2:
1565 		case 3:
1566 		case 4:
1567 		case 7:
1568 		case 9:
1569 			CU_ASSERT(g_dev_buffer[i * SPDK_BLOB_OPTS_CLUSTER_SZ] == 0xFF);
1570 			break;
1571 		default:
1572 			CU_ASSERT(g_dev_buffer[i * SPDK_BLOB_OPTS_CLUSTER_SZ] == 0);
1573 			break;
1574 		}
1575 	}
1576 
1577 	spdk_blob_close(blob, blob_op_complete, NULL);
1578 	CU_ASSERT(g_bserrno == 0);
1579 
1580 	spdk_bs_free_io_channel(channel);
1581 
1582 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1583 	CU_ASSERT(g_bserrno == 0);
1584 	g_bs = NULL;
1585 }
1586 
1587 
1588 static void
1589 blob_iter(void)
1590 {
1591 	struct spdk_blob_store *bs;
1592 	struct spdk_bs_dev *dev;
1593 	struct spdk_blob *blob;
1594 	spdk_blob_id blobid;
1595 
1596 	dev = init_dev();
1597 
1598 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1599 	CU_ASSERT(g_bserrno == 0);
1600 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1601 	bs = g_bs;
1602 
1603 	spdk_bs_iter_first(bs, blob_op_with_handle_complete, NULL);
1604 	CU_ASSERT(g_blob == NULL);
1605 	CU_ASSERT(g_bserrno == -ENOENT);
1606 
1607 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
1608 	CU_ASSERT(g_bserrno == 0);
1609 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1610 	blobid = g_blobid;
1611 
1612 	spdk_bs_iter_first(bs, blob_op_with_handle_complete, NULL);
1613 	CU_ASSERT(g_blob != NULL);
1614 	CU_ASSERT(g_bserrno == 0);
1615 	blob = g_blob;
1616 	CU_ASSERT(spdk_blob_get_id(blob) == blobid);
1617 
1618 	spdk_bs_iter_next(bs, blob, blob_op_with_handle_complete, NULL);
1619 	CU_ASSERT(g_blob == NULL);
1620 	CU_ASSERT(g_bserrno == -ENOENT);
1621 
1622 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1623 	CU_ASSERT(g_bserrno == 0);
1624 	g_bs = NULL;
1625 }
1626 
1627 static void
1628 blob_xattr(void)
1629 {
1630 	struct spdk_blob_store *bs;
1631 	struct spdk_bs_dev *dev;
1632 	struct spdk_blob *blob;
1633 	spdk_blob_id blobid;
1634 	uint64_t length;
1635 	int rc;
1636 	const char *name1, *name2;
1637 	const void *value;
1638 	size_t value_len;
1639 	struct spdk_xattr_names *names;
1640 
1641 	dev = init_dev();
1642 
1643 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1644 	CU_ASSERT(g_bserrno == 0);
1645 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1646 	bs = g_bs;
1647 
1648 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
1649 	CU_ASSERT(g_bserrno == 0);
1650 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1651 	blobid = g_blobid;
1652 
1653 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1654 	CU_ASSERT(g_bserrno == 0);
1655 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1656 	blob = g_blob;
1657 
1658 	/* Test that set_xattr fails if md_ro flag is set. */
1659 	blob->md_ro = true;
1660 	rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1);
1661 	CU_ASSERT(rc == -EPERM);
1662 
1663 	blob->md_ro = false;
1664 	rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1);
1665 	CU_ASSERT(rc == 0);
1666 
1667 	length = 2345;
1668 	rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
1669 	CU_ASSERT(rc == 0);
1670 
1671 	/* Overwrite "length" xattr. */
1672 	length = 3456;
1673 	rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
1674 	CU_ASSERT(rc == 0);
1675 
1676 	/* get_xattr should still work even if md_ro flag is set. */
1677 	value = NULL;
1678 	blob->md_ro = true;
1679 	rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len);
1680 	CU_ASSERT(rc == 0);
1681 	SPDK_CU_ASSERT_FATAL(value != NULL);
1682 	CU_ASSERT(*(uint64_t *)value == length);
1683 	CU_ASSERT(value_len == 8);
1684 	blob->md_ro = false;
1685 
1686 	rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len);
1687 	CU_ASSERT(rc == -ENOENT);
1688 
1689 	names = NULL;
1690 	rc = spdk_blob_get_xattr_names(blob, &names);
1691 	CU_ASSERT(rc == 0);
1692 	SPDK_CU_ASSERT_FATAL(names != NULL);
1693 	CU_ASSERT(spdk_xattr_names_get_count(names) == 2);
1694 	name1 = spdk_xattr_names_get_name(names, 0);
1695 	SPDK_CU_ASSERT_FATAL(name1 != NULL);
1696 	CU_ASSERT(!strcmp(name1, "name") || !strcmp(name1, "length"));
1697 	name2 = spdk_xattr_names_get_name(names, 1);
1698 	SPDK_CU_ASSERT_FATAL(name2 != NULL);
1699 	CU_ASSERT(!strcmp(name2, "name") || !strcmp(name2, "length"));
1700 	CU_ASSERT(strcmp(name1, name2));
1701 	spdk_xattr_names_free(names);
1702 
1703 	/* Confirm that remove_xattr fails if md_ro is set to true. */
1704 	blob->md_ro = true;
1705 	rc = spdk_blob_remove_xattr(blob, "name");
1706 	CU_ASSERT(rc == -EPERM);
1707 
1708 	blob->md_ro = false;
1709 	rc = spdk_blob_remove_xattr(blob, "name");
1710 	CU_ASSERT(rc == 0);
1711 
1712 	rc = spdk_blob_remove_xattr(blob, "foobar");
1713 	CU_ASSERT(rc == -ENOENT);
1714 
1715 	/* Set internal xattr */
1716 	length = 7898;
1717 	rc = _spdk_blob_set_xattr(blob, "internal", &length, sizeof(length), true);
1718 	CU_ASSERT(rc == 0);
1719 	rc = _spdk_blob_get_xattr_value(blob, "internal", &value, &value_len, true);
1720 	CU_ASSERT(rc == 0);
1721 	CU_ASSERT(*(uint64_t *)value == length);
1722 	/* try to get public xattr with same name */
1723 	rc = spdk_blob_get_xattr_value(blob, "internal", &value, &value_len);
1724 	CU_ASSERT(rc != 0);
1725 	rc = _spdk_blob_get_xattr_value(blob, "internal", &value, &value_len, false);
1726 	CU_ASSERT(rc != 0);
1727 	/* Check if SPDK_BLOB_INTERNAL_XATTR is set */
1728 	CU_ASSERT((blob->invalid_flags & SPDK_BLOB_INTERNAL_XATTR) ==
1729 		  SPDK_BLOB_INTERNAL_XATTR)
1730 
1731 	spdk_blob_close(blob, blob_op_complete, NULL);
1732 
1733 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1734 
1735 	/* Check if xattrs are persisted */
1736 	dev = init_dev();
1737 
1738 	spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL);
1739 	CU_ASSERT(g_bserrno == 0);
1740 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1741 
1742 	bs = g_bs;
1743 
1744 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1745 	CU_ASSERT(g_bserrno == 0);
1746 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1747 	blob = g_blob;
1748 
1749 	rc = _spdk_blob_get_xattr_value(blob, "internal", &value, &value_len, true);
1750 	CU_ASSERT(rc == 0);
1751 	CU_ASSERT(*(uint64_t *)value == length);
1752 
1753 	/* try to get internal xattr trough public call */
1754 	rc = spdk_blob_get_xattr_value(blob, "internal", &value, &value_len);
1755 	CU_ASSERT(rc != 0);
1756 
1757 	rc = _spdk_blob_remove_xattr(blob, "internal", true);
1758 	CU_ASSERT(rc == 0);
1759 
1760 	CU_ASSERT((blob->invalid_flags & SPDK_BLOB_INTERNAL_XATTR) == 0);
1761 
1762 	CU_ASSERT(g_bserrno == 0);
1763 	g_bs = NULL;
1764 }
1765 
1766 static void
1767 bs_load(void)
1768 {
1769 	struct spdk_bs_dev *dev;
1770 	spdk_blob_id blobid;
1771 	struct spdk_blob *blob;
1772 	struct spdk_bs_super_block *super_block;
1773 	uint64_t length;
1774 	int rc;
1775 	const void *value;
1776 	size_t value_len;
1777 	struct spdk_bs_opts opts;
1778 
1779 	dev = init_dev();
1780 	spdk_bs_opts_init(&opts);
1781 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
1782 
1783 	/* Initialize a new blob store */
1784 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
1785 	CU_ASSERT(g_bserrno == 0);
1786 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1787 
1788 	/* Try to open a blobid that does not exist */
1789 	spdk_bs_open_blob(g_bs, 0, blob_op_with_handle_complete, NULL);
1790 	CU_ASSERT(g_bserrno == -ENOENT);
1791 	CU_ASSERT(g_blob == NULL);
1792 
1793 	/* Create a blob */
1794 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
1795 	CU_ASSERT(g_bserrno == 0);
1796 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1797 	blobid = g_blobid;
1798 
1799 	spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
1800 	CU_ASSERT(g_bserrno == 0);
1801 	CU_ASSERT(g_blob != NULL);
1802 	blob = g_blob;
1803 
1804 	/* Try again to open valid blob but without the upper bit set */
1805 	spdk_bs_open_blob(g_bs, blobid & 0xFFFFFFFF, blob_op_with_handle_complete, NULL);
1806 	CU_ASSERT(g_bserrno == -ENOENT);
1807 	CU_ASSERT(g_blob == NULL);
1808 
1809 	/* Set some xattrs */
1810 	rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1);
1811 	CU_ASSERT(rc == 0);
1812 
1813 	length = 2345;
1814 	rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
1815 	CU_ASSERT(rc == 0);
1816 
1817 	/* Resize the blob */
1818 	spdk_blob_resize(blob, 10, blob_op_complete, NULL);
1819 	CU_ASSERT(g_bserrno == 0);
1820 
1821 	spdk_blob_close(blob, blob_op_complete, NULL);
1822 	CU_ASSERT(g_bserrno == 0);
1823 	blob = NULL;
1824 	g_blob = NULL;
1825 	g_blobid = SPDK_BLOBID_INVALID;
1826 
1827 	/* Unload the blob store */
1828 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1829 	CU_ASSERT(g_bserrno == 0);
1830 	g_bs = NULL;
1831 	g_blob = NULL;
1832 	g_blobid = 0;
1833 
1834 	super_block = (struct spdk_bs_super_block *)g_dev_buffer;
1835 	CU_ASSERT(super_block->clean == 1);
1836 
1837 	/* Load should fail for device with an unsupported blocklen */
1838 	dev = init_dev();
1839 	dev->blocklen = SPDK_BS_PAGE_SIZE * 2;
1840 	spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL);
1841 	CU_ASSERT(g_bserrno == -EINVAL);
1842 
1843 	/* Load should when max_md_ops is set to zero */
1844 	dev = init_dev();
1845 	spdk_bs_opts_init(&opts);
1846 	opts.max_md_ops = 0;
1847 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1848 	CU_ASSERT(g_bserrno == -EINVAL);
1849 
1850 	/* Load should when max_channel_ops is set to zero */
1851 	dev = init_dev();
1852 	spdk_bs_opts_init(&opts);
1853 	opts.max_channel_ops = 0;
1854 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1855 	CU_ASSERT(g_bserrno == -EINVAL);
1856 
1857 	/* Load an existing blob store */
1858 	dev = init_dev();
1859 	spdk_bs_opts_init(&opts);
1860 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
1861 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1862 	CU_ASSERT(g_bserrno == 0);
1863 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1864 
1865 	super_block = (struct spdk_bs_super_block *)g_dev_buffer;
1866 	CU_ASSERT(super_block->clean == 1);
1867 
1868 	spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
1869 	CU_ASSERT(g_bserrno == 0);
1870 	CU_ASSERT(g_blob != NULL);
1871 	blob = g_blob;
1872 
1873 	/* Verify that blobstore is marked dirty after first metadata sync */
1874 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
1875 	CU_ASSERT(super_block->clean == 1);
1876 
1877 	/* Get the xattrs */
1878 	value = NULL;
1879 	rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len);
1880 	CU_ASSERT(rc == 0);
1881 	SPDK_CU_ASSERT_FATAL(value != NULL);
1882 	CU_ASSERT(*(uint64_t *)value == length);
1883 	CU_ASSERT(value_len == 8);
1884 
1885 	rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len);
1886 	CU_ASSERT(rc == -ENOENT);
1887 
1888 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10);
1889 
1890 	spdk_blob_close(blob, blob_op_complete, NULL);
1891 	CU_ASSERT(g_bserrno == 0);
1892 	blob = NULL;
1893 	g_blob = NULL;
1894 	g_blobid = SPDK_BLOBID_INVALID;
1895 
1896 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1897 	CU_ASSERT(g_bserrno == 0);
1898 	g_bs = NULL;
1899 }
1900 
1901 static void
1902 bs_type(void)
1903 {
1904 	struct spdk_bs_dev *dev;
1905 	struct spdk_bs_opts opts;
1906 
1907 	dev = init_dev();
1908 	spdk_bs_opts_init(&opts);
1909 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
1910 
1911 	/* Initialize a new blob store */
1912 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
1913 	CU_ASSERT(g_bserrno == 0);
1914 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1915 
1916 	/* Unload the blob store */
1917 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1918 	CU_ASSERT(g_bserrno == 0);
1919 	g_bs = NULL;
1920 	g_blob = NULL;
1921 	g_blobid = 0;
1922 
1923 	/* Load non existing blobstore type */
1924 	dev = init_dev();
1925 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "NONEXISTING");
1926 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1927 	CU_ASSERT(g_bserrno != 0);
1928 
1929 	/* Load with empty blobstore type */
1930 	dev = init_dev();
1931 	memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype));
1932 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1933 	CU_ASSERT(g_bserrno == 0);
1934 
1935 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1936 	CU_ASSERT(g_bserrno == 0);
1937 	g_bs = NULL;
1938 
1939 	/* Initialize a new blob store with empty bstype */
1940 	dev = init_dev();
1941 	memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype));
1942 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1943 	CU_ASSERT(g_bserrno == 0);
1944 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1945 
1946 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1947 	CU_ASSERT(g_bserrno == 0);
1948 	g_bs = NULL;
1949 
1950 	/* Load non existing blobstore type */
1951 	dev = init_dev();
1952 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "NONEXISTING");
1953 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1954 	CU_ASSERT(g_bserrno != 0);
1955 
1956 	/* Load with empty blobstore type */
1957 	dev = init_dev();
1958 	memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype));
1959 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1960 	CU_ASSERT(g_bserrno == 0);
1961 
1962 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1963 	CU_ASSERT(g_bserrno == 0);
1964 	g_bs = NULL;
1965 }
1966 
1967 static void
1968 bs_super_block(void)
1969 {
1970 	struct spdk_bs_dev *dev;
1971 	struct spdk_bs_super_block *super_block;
1972 	struct spdk_bs_opts opts;
1973 	struct spdk_bs_super_block_ver1 super_block_v1;
1974 
1975 	dev = init_dev();
1976 	spdk_bs_opts_init(&opts);
1977 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
1978 
1979 	/* Initialize a new blob store */
1980 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
1981 	CU_ASSERT(g_bserrno == 0);
1982 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1983 
1984 	/* Unload the blob store */
1985 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1986 	CU_ASSERT(g_bserrno == 0);
1987 	g_bs = NULL;
1988 	g_blob = NULL;
1989 	g_blobid = 0;
1990 
1991 	/* Load an existing blob store with version newer than supported */
1992 	super_block = (struct spdk_bs_super_block *)g_dev_buffer;
1993 	super_block->version++;
1994 
1995 	dev = init_dev();
1996 	memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype));
1997 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1998 	CU_ASSERT(g_bserrno != 0);
1999 
2000 	/* Create a new blob store with super block version 1 */
2001 	dev = init_dev();
2002 	super_block_v1.version = 1;
2003 	memcpy(super_block_v1.signature, "SPDKBLOB", sizeof(super_block_v1.signature));
2004 	super_block_v1.length = 0x1000;
2005 	super_block_v1.clean = 1;
2006 	super_block_v1.super_blob = 0xFFFFFFFFFFFFFFFF;
2007 	super_block_v1.cluster_size = 0x100000;
2008 	super_block_v1.used_page_mask_start = 0x01;
2009 	super_block_v1.used_page_mask_len = 0x01;
2010 	super_block_v1.used_cluster_mask_start = 0x02;
2011 	super_block_v1.used_cluster_mask_len = 0x01;
2012 	super_block_v1.md_start = 0x03;
2013 	super_block_v1.md_len = 0x40;
2014 	memset(super_block_v1.reserved, 0, 4036);
2015 	super_block_v1.crc = _spdk_blob_md_page_calc_crc(&super_block_v1);
2016 	memcpy(g_dev_buffer, &super_block_v1, sizeof(struct spdk_bs_super_block_ver1));
2017 
2018 	memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype));
2019 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2020 	CU_ASSERT(g_bserrno == 0);
2021 
2022 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2023 	CU_ASSERT(g_bserrno == 0);
2024 	g_bs = NULL;
2025 }
2026 
2027 /*
2028  * Create a blobstore and then unload it.
2029  */
2030 static void
2031 bs_unload(void)
2032 {
2033 	struct spdk_bs_dev *dev;
2034 	struct spdk_blob_store *bs;
2035 	spdk_blob_id blobid;
2036 	struct spdk_blob *blob;
2037 
2038 	dev = init_dev();
2039 
2040 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
2041 	CU_ASSERT(g_bserrno == 0);
2042 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2043 	bs = g_bs;
2044 
2045 	/* Create a blob and open it. */
2046 	g_bserrno = -1;
2047 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
2048 	CU_ASSERT(g_bserrno == 0);
2049 	CU_ASSERT(g_blobid > 0);
2050 	blobid = g_blobid;
2051 
2052 	g_bserrno = -1;
2053 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
2054 	CU_ASSERT(g_bserrno == 0);
2055 	CU_ASSERT(g_blob != NULL);
2056 	blob = g_blob;
2057 
2058 	/* Try to unload blobstore, should fail with open blob */
2059 	g_bserrno = -1;
2060 	spdk_bs_unload(bs, bs_op_complete, NULL);
2061 	CU_ASSERT(g_bserrno == -EBUSY);
2062 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2063 
2064 	/* Close the blob, then successfully unload blobstore */
2065 	g_bserrno = -1;
2066 	spdk_blob_close(blob, blob_op_complete, NULL);
2067 	CU_ASSERT(g_bserrno == 0);
2068 
2069 	g_bserrno = -1;
2070 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2071 	CU_ASSERT(g_bserrno == 0);
2072 	g_bs = NULL;
2073 }
2074 
2075 /*
2076  * Create a blobstore with a cluster size different than the default, and ensure it is
2077  *  persisted.
2078  */
2079 static void
2080 bs_cluster_sz(void)
2081 {
2082 	struct spdk_bs_dev *dev;
2083 	struct spdk_bs_opts opts;
2084 	uint32_t cluster_sz;
2085 
2086 	/* Set cluster size to zero */
2087 	dev = init_dev();
2088 	spdk_bs_opts_init(&opts);
2089 	opts.cluster_sz = 0;
2090 
2091 	/* Initialize a new blob store */
2092 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2093 	CU_ASSERT(g_bserrno == -EINVAL);
2094 	SPDK_CU_ASSERT_FATAL(g_bs == NULL);
2095 
2096 	/*
2097 	 * Set cluster size to blobstore page size,
2098 	 * to work it is required to be at least twice the blobstore page size.
2099 	 */
2100 	dev = init_dev();
2101 	spdk_bs_opts_init(&opts);
2102 	opts.cluster_sz = SPDK_BS_PAGE_SIZE;
2103 
2104 	/* Initialize a new blob store */
2105 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2106 	CU_ASSERT(g_bserrno == -ENOMEM);
2107 	SPDK_CU_ASSERT_FATAL(g_bs == NULL);
2108 
2109 	/*
2110 	 * Set cluster size to lower than page size,
2111 	 * to work it is required to be at least twice the blobstore page size.
2112 	 */
2113 	dev = init_dev();
2114 	spdk_bs_opts_init(&opts);
2115 	opts.cluster_sz = SPDK_BS_PAGE_SIZE - 1;
2116 
2117 	/* Initialize a new blob store */
2118 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2119 	CU_ASSERT(g_bserrno == -ENOMEM);
2120 	SPDK_CU_ASSERT_FATAL(g_bs == NULL);
2121 
2122 	/* Set cluster size to twice the default */
2123 	dev = init_dev();
2124 	spdk_bs_opts_init(&opts);
2125 	opts.cluster_sz *= 2;
2126 	cluster_sz = opts.cluster_sz;
2127 
2128 	/* Initialize a new blob store */
2129 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2130 	CU_ASSERT(g_bserrno == 0);
2131 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2132 
2133 	CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz);
2134 
2135 	/* Unload the blob store */
2136 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2137 	CU_ASSERT(g_bserrno == 0);
2138 	g_bs = NULL;
2139 	g_blob = NULL;
2140 	g_blobid = 0;
2141 
2142 	dev = init_dev();
2143 	/* Load an existing blob store */
2144 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2145 	CU_ASSERT(g_bserrno == 0);
2146 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2147 
2148 	CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz);
2149 
2150 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2151 	CU_ASSERT(g_bserrno == 0);
2152 	g_bs = NULL;
2153 }
2154 
2155 /*
2156  * Create a blobstore, reload it and ensure total usable cluster count
2157  *  stays the same.
2158  */
2159 static void
2160 bs_usable_clusters(void)
2161 {
2162 	struct spdk_bs_dev *dev;
2163 	struct spdk_bs_opts opts;
2164 	uint32_t clusters;
2165 	int i;
2166 
2167 	/* Init blobstore */
2168 	dev = init_dev();
2169 	spdk_bs_opts_init(&opts);
2170 
2171 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2172 	CU_ASSERT(g_bserrno == 0);
2173 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2174 
2175 	clusters = spdk_bs_total_data_cluster_count(g_bs);
2176 
2177 	/* Unload the blob store */
2178 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2179 	CU_ASSERT(g_bserrno == 0);
2180 	g_bs = NULL;
2181 
2182 	dev = init_dev();
2183 	/* Load an existing blob store */
2184 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2185 	CU_ASSERT(g_bserrno == 0);
2186 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2187 
2188 	CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters);
2189 
2190 	/* Create and resize blobs to make sure that useable cluster count won't change */
2191 	for (i = 0; i < 4; i++) {
2192 		g_bserrno = -1;
2193 		g_blobid = SPDK_BLOBID_INVALID;
2194 		spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
2195 		CU_ASSERT(g_bserrno == 0);
2196 		CU_ASSERT(g_blobid !=  SPDK_BLOBID_INVALID);
2197 
2198 		g_bserrno = -1;
2199 		g_blob = NULL;
2200 		spdk_bs_open_blob(g_bs, g_blobid, blob_op_with_handle_complete, NULL);
2201 		CU_ASSERT(g_bserrno == 0);
2202 		CU_ASSERT(g_blob !=  NULL);
2203 
2204 		spdk_blob_resize(g_blob, 10, blob_op_complete, NULL);
2205 		CU_ASSERT(g_bserrno == 0);
2206 
2207 		g_bserrno = -1;
2208 		spdk_blob_close(g_blob, blob_op_complete, NULL);
2209 		CU_ASSERT(g_bserrno == 0);
2210 
2211 		CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters);
2212 	}
2213 
2214 	/* Reload the blob store to make sure that nothing changed */
2215 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2216 	CU_ASSERT(g_bserrno == 0);
2217 	g_bs = NULL;
2218 
2219 	dev = init_dev();
2220 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2221 	CU_ASSERT(g_bserrno == 0);
2222 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2223 
2224 	CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters);
2225 
2226 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2227 	CU_ASSERT(g_bserrno == 0);
2228 	g_bs = NULL;
2229 }
2230 
2231 /*
2232  * Test resizing of the metadata blob.  This requires creating enough blobs
2233  *  so that one cluster is not enough to fit the metadata for those blobs.
2234  *  To induce this condition to happen more quickly, we reduce the cluster
2235  *  size to 16KB, which means only 4 4KB blob metadata pages can fit.
2236  */
2237 static void
2238 bs_resize_md(void)
2239 {
2240 	const int CLUSTER_PAGE_COUNT = 4;
2241 	const int NUM_BLOBS = CLUSTER_PAGE_COUNT * 4;
2242 	struct spdk_bs_dev *dev;
2243 	struct spdk_bs_opts opts;
2244 	uint32_t cluster_sz;
2245 	spdk_blob_id blobids[NUM_BLOBS];
2246 	int i;
2247 
2248 
2249 	dev = init_dev();
2250 	spdk_bs_opts_init(&opts);
2251 	opts.cluster_sz = CLUSTER_PAGE_COUNT * 4096;
2252 	cluster_sz = opts.cluster_sz;
2253 
2254 	/* Initialize a new blob store */
2255 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2256 	CU_ASSERT(g_bserrno == 0);
2257 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2258 
2259 	CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz);
2260 
2261 	for (i = 0; i < NUM_BLOBS; i++) {
2262 		g_bserrno = -1;
2263 		g_blobid = SPDK_BLOBID_INVALID;
2264 		spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
2265 		CU_ASSERT(g_bserrno == 0);
2266 		CU_ASSERT(g_blobid !=  SPDK_BLOBID_INVALID);
2267 		blobids[i] = g_blobid;
2268 	}
2269 
2270 	/* Unload the blob store */
2271 	g_bserrno = -1;
2272 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2273 	CU_ASSERT(g_bserrno == 0);
2274 
2275 	/* Load an existing blob store */
2276 	g_bserrno = -1;
2277 	g_bs = NULL;
2278 	dev = init_dev();
2279 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2280 	CU_ASSERT(g_bserrno == 0);
2281 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2282 
2283 	CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz);
2284 
2285 	for (i = 0; i < NUM_BLOBS; i++) {
2286 		g_bserrno = -1;
2287 		g_blob = NULL;
2288 		spdk_bs_open_blob(g_bs, blobids[i], blob_op_with_handle_complete, NULL);
2289 		CU_ASSERT(g_bserrno == 0);
2290 		CU_ASSERT(g_blob !=  NULL);
2291 		g_bserrno = -1;
2292 		spdk_blob_close(g_blob, blob_op_complete, NULL);
2293 		CU_ASSERT(g_bserrno == 0);
2294 	}
2295 
2296 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2297 	CU_ASSERT(g_bserrno == 0);
2298 	g_bs = NULL;
2299 }
2300 
2301 static void
2302 bs_destroy(void)
2303 {
2304 	struct spdk_bs_dev *dev;
2305 	struct spdk_bs_opts opts;
2306 
2307 	/* Initialize a new blob store */
2308 	dev = init_dev();
2309 	spdk_bs_opts_init(&opts);
2310 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2311 	CU_ASSERT(g_bserrno == 0);
2312 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2313 
2314 	/* Destroy the blob store */
2315 	g_bserrno = -1;
2316 	spdk_bs_destroy(g_bs, bs_op_complete, NULL);
2317 	CU_ASSERT(g_bserrno == 0);
2318 
2319 	/* Loading an non-existent blob store should fail. */
2320 	g_bs = NULL;
2321 	dev = init_dev();
2322 
2323 	g_bserrno = 0;
2324 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2325 	CU_ASSERT(g_bserrno != 0);
2326 }
2327 
2328 /* Try to hit all of the corner cases associated with serializing
2329  * a blob to disk
2330  */
2331 static void
2332 blob_serialize(void)
2333 {
2334 	struct spdk_bs_dev *dev;
2335 	struct spdk_bs_opts opts;
2336 	struct spdk_blob_store *bs;
2337 	spdk_blob_id blobid[2];
2338 	struct spdk_blob *blob[2];
2339 	uint64_t i;
2340 	char *value;
2341 	int rc;
2342 
2343 	dev = init_dev();
2344 
2345 	/* Initialize a new blobstore with very small clusters */
2346 	spdk_bs_opts_init(&opts);
2347 	opts.cluster_sz = dev->blocklen * 8;
2348 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2349 	CU_ASSERT(g_bserrno == 0);
2350 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2351 	bs = g_bs;
2352 
2353 	/* Create and open two blobs */
2354 	for (i = 0; i < 2; i++) {
2355 		spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
2356 		CU_ASSERT(g_bserrno == 0);
2357 		CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2358 		blobid[i] = g_blobid;
2359 
2360 		/* Open a blob */
2361 		spdk_bs_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL);
2362 		CU_ASSERT(g_bserrno == 0);
2363 		CU_ASSERT(g_blob != NULL);
2364 		blob[i] = g_blob;
2365 
2366 		/* Set a fairly large xattr on both blobs to eat up
2367 		 * metadata space
2368 		 */
2369 		value = calloc(dev->blocklen - 64, sizeof(char));
2370 		SPDK_CU_ASSERT_FATAL(value != NULL);
2371 		memset(value, i, dev->blocklen / 2);
2372 		rc = spdk_blob_set_xattr(blob[i], "name", value, dev->blocklen - 64);
2373 		CU_ASSERT(rc == 0);
2374 		free(value);
2375 	}
2376 
2377 	/* Resize the blobs, alternating 1 cluster at a time.
2378 	 * This thwarts run length encoding and will cause spill
2379 	 * over of the extents.
2380 	 */
2381 	for (i = 0; i < 6; i++) {
2382 		spdk_blob_resize(blob[i % 2], (i / 2) + 1, blob_op_complete, NULL);
2383 		CU_ASSERT(g_bserrno == 0);
2384 	}
2385 
2386 	for (i = 0; i < 2; i++) {
2387 		spdk_blob_sync_md(blob[i], blob_op_complete, NULL);
2388 		CU_ASSERT(g_bserrno == 0);
2389 	}
2390 
2391 	/* Close the blobs */
2392 	for (i = 0; i < 2; i++) {
2393 		spdk_blob_close(blob[i], blob_op_complete, NULL);
2394 		CU_ASSERT(g_bserrno == 0);
2395 	}
2396 
2397 	/* Unload the blobstore */
2398 	spdk_bs_unload(bs, bs_op_complete, NULL);
2399 	CU_ASSERT(g_bserrno == 0);
2400 	g_bs = NULL;
2401 	g_blob = NULL;
2402 	g_blobid = 0;
2403 	bs = NULL;
2404 
2405 	dev = init_dev();
2406 	/* Load an existing blob store */
2407 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2408 	CU_ASSERT(g_bserrno == 0);
2409 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2410 	bs = g_bs;
2411 
2412 	for (i = 0; i < 2; i++) {
2413 		blob[i] = NULL;
2414 
2415 		spdk_bs_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL);
2416 		CU_ASSERT(g_bserrno == 0);
2417 		CU_ASSERT(g_blob != NULL);
2418 		blob[i] = g_blob;
2419 
2420 		CU_ASSERT(spdk_blob_get_num_clusters(blob[i]) == 3);
2421 
2422 		spdk_blob_close(blob[i], blob_op_complete, NULL);
2423 		CU_ASSERT(g_bserrno == 0);
2424 	}
2425 
2426 	spdk_bs_unload(bs, bs_op_complete, NULL);
2427 	CU_ASSERT(g_bserrno == 0);
2428 	g_bs = NULL;
2429 }
2430 
2431 static void
2432 blob_crc(void)
2433 {
2434 	struct spdk_blob_store *bs;
2435 	struct spdk_bs_dev *dev;
2436 	struct spdk_blob *blob;
2437 	spdk_blob_id blobid;
2438 	uint32_t page_num;
2439 	int index;
2440 	struct spdk_blob_md_page *page;
2441 
2442 	dev = init_dev();
2443 
2444 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
2445 	CU_ASSERT(g_bserrno == 0);
2446 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2447 	bs = g_bs;
2448 
2449 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
2450 	CU_ASSERT(g_bserrno == 0);
2451 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2452 	blobid = g_blobid;
2453 
2454 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
2455 	CU_ASSERT(g_bserrno == 0);
2456 	CU_ASSERT(g_blob != NULL);
2457 	blob = g_blob;
2458 
2459 	spdk_blob_close(blob, blob_op_complete, NULL);
2460 	CU_ASSERT(g_bserrno == 0);
2461 
2462 	page_num = _spdk_bs_blobid_to_page(blobid);
2463 	index = DEV_BUFFER_BLOCKLEN * (bs->md_start + page_num);
2464 	page = (struct spdk_blob_md_page *)&g_dev_buffer[index];
2465 	page->crc = 0;
2466 
2467 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
2468 	CU_ASSERT(g_bserrno == -EINVAL);
2469 	CU_ASSERT(g_blob == NULL);
2470 	g_bserrno = 0;
2471 
2472 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
2473 	CU_ASSERT(g_bserrno == -EINVAL);
2474 
2475 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2476 	CU_ASSERT(g_bserrno == 0);
2477 	g_bs = NULL;
2478 }
2479 
2480 static void
2481 super_block_crc(void)
2482 {
2483 	struct spdk_bs_dev *dev;
2484 	struct spdk_bs_super_block *super_block;
2485 	struct spdk_bs_opts opts;
2486 
2487 	dev = init_dev();
2488 	spdk_bs_opts_init(&opts);
2489 
2490 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
2491 	CU_ASSERT(g_bserrno == 0);
2492 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2493 
2494 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2495 	CU_ASSERT(g_bserrno == 0);
2496 	g_bs = NULL;
2497 
2498 	super_block = (struct spdk_bs_super_block *)g_dev_buffer;
2499 	super_block->crc = 0;
2500 	dev = init_dev();
2501 
2502 	/* Load an existing blob store */
2503 	g_bserrno = 0;
2504 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2505 	CU_ASSERT(g_bserrno == -EILSEQ);
2506 }
2507 
2508 /* For blob dirty shutdown test case we do the following sub-test cases:
2509  * 1 Initialize new blob store and create 1 super blob with some xattrs, then we
2510  *   dirty shutdown and reload the blob store and verify the xattrs.
2511  * 2 Resize the blob from 10 clusters to 20 clusters and then dirty shutdown,
2512  *   reload the blob store and verify the clusters number.
2513  * 3 Create the second blob and then dirty shutdown, reload the blob store
2514  *   and verify the second blob.
2515  * 4 Delete the second blob and then dirty shutdown, reload the blob store
2516  *   and verify the second blob is invalid.
2517  * 5 Create the second blob again and also create the third blob, modify the
2518  *   md of second blob which makes the md invalid, and then dirty shutdown,
2519  *   reload the blob store verify the second blob, it should invalid and also
2520  *   verify the third blob, it should correct.
2521  */
2522 static void
2523 blob_dirty_shutdown(void)
2524 {
2525 	int rc;
2526 	int index;
2527 	struct spdk_bs_dev *dev;
2528 	spdk_blob_id blobid1, blobid2, blobid3;
2529 	struct spdk_blob *blob;
2530 	uint64_t length;
2531 	uint64_t free_clusters;
2532 	const void *value;
2533 	size_t value_len;
2534 	uint32_t page_num;
2535 	struct spdk_blob_md_page *page;
2536 	struct spdk_bs_opts opts;
2537 
2538 	dev = init_dev();
2539 	spdk_bs_opts_init(&opts);
2540 	/* Initialize a new blob store */
2541 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
2542 	CU_ASSERT(g_bserrno == 0);
2543 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2544 
2545 	/* Create first blob */
2546 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
2547 	CU_ASSERT(g_bserrno == 0);
2548 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2549 	blobid1 = g_blobid;
2550 
2551 	spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL);
2552 	CU_ASSERT(g_bserrno == 0);
2553 	CU_ASSERT(g_blob != NULL);
2554 	blob = g_blob;
2555 
2556 	/* Set some xattrs */
2557 	rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1);
2558 	CU_ASSERT(rc == 0);
2559 
2560 	length = 2345;
2561 	rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
2562 	CU_ASSERT(rc == 0);
2563 
2564 	/* Resize the blob */
2565 	spdk_blob_resize(blob, 10, blob_op_complete, NULL);
2566 	CU_ASSERT(g_bserrno == 0);
2567 
2568 	/* Set the blob as the super blob */
2569 	spdk_bs_set_super(g_bs, blobid1, blob_op_complete, NULL);
2570 	CU_ASSERT(g_bserrno == 0);
2571 
2572 	free_clusters = spdk_bs_free_cluster_count(g_bs);
2573 
2574 	spdk_blob_close(blob, blob_op_complete, NULL);
2575 	blob = NULL;
2576 	g_blob = NULL;
2577 	g_blobid = SPDK_BLOBID_INVALID;
2578 
2579 	/* Dirty shutdown */
2580 	_spdk_bs_free(g_bs);
2581 
2582 	/* reload blobstore */
2583 	dev = init_dev();
2584 	spdk_bs_opts_init(&opts);
2585 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2586 	CU_ASSERT(g_bserrno == 0);
2587 
2588 	/* Get the super blob */
2589 	spdk_bs_get_super(g_bs, blob_op_with_id_complete, NULL);
2590 	CU_ASSERT(g_bserrno == 0);
2591 	CU_ASSERT(blobid1 == g_blobid);
2592 
2593 	spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL);
2594 	CU_ASSERT(g_bserrno == 0);
2595 	CU_ASSERT(g_blob != NULL);
2596 	blob = g_blob;
2597 
2598 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs));
2599 
2600 	/* Get the xattrs */
2601 	value = NULL;
2602 	rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len);
2603 	CU_ASSERT(rc == 0);
2604 	SPDK_CU_ASSERT_FATAL(value != NULL);
2605 	CU_ASSERT(*(uint64_t *)value == length);
2606 	CU_ASSERT(value_len == 8);
2607 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10);
2608 
2609 	/* Resize the blob */
2610 	spdk_blob_resize(blob, 20, blob_op_complete, NULL);
2611 	CU_ASSERT(g_bserrno == 0);
2612 
2613 	free_clusters = spdk_bs_free_cluster_count(g_bs);
2614 
2615 	spdk_blob_close(blob, blob_op_complete, NULL);
2616 	CU_ASSERT(g_bserrno == 0);
2617 	blob = NULL;
2618 	g_blob = NULL;
2619 	g_blobid = SPDK_BLOBID_INVALID;
2620 
2621 	/* Dirty shutdown */
2622 	_spdk_bs_free(g_bs);
2623 
2624 	/* reload the blobstore */
2625 	dev = init_dev();
2626 	spdk_bs_opts_init(&opts);
2627 	/* Load an existing blob store */
2628 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2629 	CU_ASSERT(g_bserrno == 0);
2630 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2631 	spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL);
2632 	CU_ASSERT(g_bserrno == 0);
2633 	CU_ASSERT(g_blob != NULL);
2634 	blob = g_blob;
2635 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 20);
2636 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs));
2637 
2638 	spdk_blob_close(blob, blob_op_complete, NULL);
2639 	CU_ASSERT(g_bserrno == 0);
2640 	blob = NULL;
2641 	g_blob = NULL;
2642 	g_blobid = SPDK_BLOBID_INVALID;
2643 
2644 	/* Create second blob */
2645 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
2646 	CU_ASSERT(g_bserrno == 0);
2647 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2648 	blobid2 = g_blobid;
2649 
2650 	spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL);
2651 	CU_ASSERT(g_bserrno == 0);
2652 	CU_ASSERT(g_blob != NULL);
2653 	blob = g_blob;
2654 
2655 	/* Set some xattrs */
2656 	rc = spdk_blob_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1);
2657 	CU_ASSERT(rc == 0);
2658 
2659 	length = 5432;
2660 	rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
2661 	CU_ASSERT(rc == 0);
2662 
2663 	/* Resize the blob */
2664 	spdk_blob_resize(blob, 10, blob_op_complete, NULL);
2665 	CU_ASSERT(g_bserrno == 0);
2666 
2667 	free_clusters = spdk_bs_free_cluster_count(g_bs);
2668 
2669 	spdk_blob_close(blob, blob_op_complete, NULL);
2670 	blob = NULL;
2671 	g_blob = NULL;
2672 	g_blobid = SPDK_BLOBID_INVALID;
2673 
2674 	/* Dirty shutdown */
2675 	_spdk_bs_free(g_bs);
2676 
2677 	/* reload the blobstore */
2678 	dev = init_dev();
2679 	spdk_bs_opts_init(&opts);
2680 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2681 	CU_ASSERT(g_bserrno == 0);
2682 
2683 	spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL);
2684 	CU_ASSERT(g_bserrno == 0);
2685 	CU_ASSERT(g_blob != NULL);
2686 	blob = g_blob;
2687 
2688 	/* Get the xattrs */
2689 	value = NULL;
2690 	rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len);
2691 	CU_ASSERT(rc == 0);
2692 	SPDK_CU_ASSERT_FATAL(value != NULL);
2693 	CU_ASSERT(*(uint64_t *)value == length);
2694 	CU_ASSERT(value_len == 8);
2695 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10);
2696 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs));
2697 
2698 	spdk_blob_close(blob, blob_op_complete, NULL);
2699 	CU_ASSERT(g_bserrno == 0);
2700 	spdk_bs_delete_blob(g_bs, blobid2, blob_op_complete, NULL);
2701 	CU_ASSERT(g_bserrno == 0);
2702 
2703 	free_clusters = spdk_bs_free_cluster_count(g_bs);
2704 
2705 	/* Dirty shutdown */
2706 	_spdk_bs_free(g_bs);
2707 	/* reload the blobstore */
2708 	dev = init_dev();
2709 	spdk_bs_opts_init(&opts);
2710 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2711 	CU_ASSERT(g_bserrno == 0);
2712 
2713 	spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL);
2714 	CU_ASSERT(g_bserrno != 0);
2715 	CU_ASSERT(g_blob == NULL);
2716 
2717 	spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL);
2718 	CU_ASSERT(g_bserrno == 0);
2719 	CU_ASSERT(g_blob != NULL);
2720 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs));
2721 	spdk_blob_close(g_blob, blob_op_complete, NULL);
2722 	CU_ASSERT(g_bserrno == 0);
2723 
2724 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2725 	CU_ASSERT(g_bserrno == 0);
2726 	g_bs = NULL;
2727 
2728 	/* reload the blobstore */
2729 	dev = init_dev();
2730 	spdk_bs_opts_init(&opts);
2731 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2732 	CU_ASSERT(g_bserrno == 0);
2733 
2734 	/* Create second blob */
2735 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
2736 	CU_ASSERT(g_bserrno == 0);
2737 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2738 	blobid2 = g_blobid;
2739 
2740 	/* Create third blob */
2741 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
2742 	CU_ASSERT(g_bserrno == 0);
2743 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2744 	blobid3 = g_blobid;
2745 
2746 	spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL);
2747 	CU_ASSERT(g_bserrno == 0);
2748 	CU_ASSERT(g_blob != NULL);
2749 	blob = g_blob;
2750 
2751 	/* Set some xattrs for second blob */
2752 	rc = spdk_blob_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1);
2753 	CU_ASSERT(rc == 0);
2754 
2755 	length = 5432;
2756 	rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
2757 	CU_ASSERT(rc == 0);
2758 
2759 	spdk_blob_close(blob, blob_op_complete, NULL);
2760 	blob = NULL;
2761 	g_blob = NULL;
2762 	g_blobid = SPDK_BLOBID_INVALID;
2763 
2764 	spdk_bs_open_blob(g_bs, blobid3, blob_op_with_handle_complete, NULL);
2765 	CU_ASSERT(g_bserrno == 0);
2766 	CU_ASSERT(g_blob != NULL);
2767 	blob = g_blob;
2768 
2769 	/* Set some xattrs for third blob */
2770 	rc = spdk_blob_set_xattr(blob, "name", "log2.txt", strlen("log2.txt") + 1);
2771 	CU_ASSERT(rc == 0);
2772 
2773 	length = 5432;
2774 	rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
2775 	CU_ASSERT(rc == 0);
2776 
2777 	spdk_blob_close(blob, blob_op_complete, NULL);
2778 	blob = NULL;
2779 	g_blob = NULL;
2780 	g_blobid = SPDK_BLOBID_INVALID;
2781 
2782 	/* Mark second blob as invalid */
2783 	page_num = _spdk_bs_blobid_to_page(blobid2);
2784 
2785 	index = DEV_BUFFER_BLOCKLEN * (g_bs->md_start + page_num);
2786 	page = (struct spdk_blob_md_page *)&g_dev_buffer[index];
2787 	page->sequence_num = 1;
2788 	page->crc = _spdk_blob_md_page_calc_crc(page);
2789 
2790 	free_clusters = spdk_bs_free_cluster_count(g_bs);
2791 
2792 	/* Dirty shutdown */
2793 	_spdk_bs_free(g_bs);
2794 	/* reload the blobstore */
2795 	dev = init_dev();
2796 	spdk_bs_opts_init(&opts);
2797 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2798 	CU_ASSERT(g_bserrno == 0);
2799 
2800 	spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL);
2801 	CU_ASSERT(g_bserrno != 0);
2802 	CU_ASSERT(g_blob == NULL);
2803 
2804 	spdk_bs_open_blob(g_bs, blobid3, blob_op_with_handle_complete, NULL);
2805 	CU_ASSERT(g_bserrno == 0);
2806 	CU_ASSERT(g_blob != NULL);
2807 	blob = g_blob;
2808 
2809 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs));
2810 
2811 	spdk_blob_close(blob, blob_op_complete, NULL);
2812 	blob = NULL;
2813 	g_blob = NULL;
2814 	g_blobid = SPDK_BLOBID_INVALID;
2815 
2816 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2817 	CU_ASSERT(g_bserrno == 0);
2818 	g_bs = NULL;
2819 }
2820 
2821 static void
2822 blob_flags(void)
2823 {
2824 	struct spdk_bs_dev *dev;
2825 	spdk_blob_id blobid_invalid, blobid_data_ro, blobid_md_ro;
2826 	struct spdk_blob *blob_invalid, *blob_data_ro, *blob_md_ro;
2827 	struct spdk_bs_opts opts;
2828 	int rc;
2829 
2830 	dev = init_dev();
2831 	spdk_bs_opts_init(&opts);
2832 
2833 	/* Initialize a new blob store */
2834 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2835 	CU_ASSERT(g_bserrno == 0);
2836 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2837 
2838 	/* Create three blobs - one each for testing invalid, data_ro and md_ro flags. */
2839 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
2840 	CU_ASSERT(g_bserrno == 0);
2841 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2842 	blobid_invalid = g_blobid;
2843 
2844 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
2845 	CU_ASSERT(g_bserrno == 0);
2846 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2847 	blobid_data_ro = g_blobid;
2848 
2849 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
2850 	CU_ASSERT(g_bserrno == 0);
2851 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2852 	blobid_md_ro = g_blobid;
2853 
2854 	spdk_bs_open_blob(g_bs, blobid_invalid, blob_op_with_handle_complete, NULL);
2855 	CU_ASSERT(g_bserrno == 0);
2856 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
2857 	blob_invalid = g_blob;
2858 
2859 	spdk_bs_open_blob(g_bs, blobid_data_ro, blob_op_with_handle_complete, NULL);
2860 	CU_ASSERT(g_bserrno == 0);
2861 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
2862 	blob_data_ro = g_blob;
2863 
2864 	spdk_bs_open_blob(g_bs, blobid_md_ro, blob_op_with_handle_complete, NULL);
2865 	CU_ASSERT(g_bserrno == 0);
2866 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
2867 	blob_md_ro = g_blob;
2868 
2869 	/* Change the size of blob_data_ro to check if flags are serialized
2870 	 * when blob has non zero number of extents */
2871 	spdk_blob_resize(blob_data_ro, 10, blob_op_complete, NULL);
2872 	CU_ASSERT(g_bserrno == 0);
2873 
2874 	/* Set the xattr to check if flags are serialized
2875 	 * when blob has non zero number of xattrs */
2876 	rc = spdk_blob_set_xattr(blob_md_ro, "name", "log.txt", strlen("log.txt") + 1);
2877 	CU_ASSERT(rc == 0);
2878 
2879 	blob_invalid->invalid_flags = (1ULL << 63);
2880 	blob_invalid->state = SPDK_BLOB_STATE_DIRTY;
2881 	blob_data_ro->data_ro_flags = (1ULL << 62);
2882 	blob_data_ro->state = SPDK_BLOB_STATE_DIRTY;
2883 	blob_md_ro->md_ro_flags = (1ULL << 61);
2884 	blob_md_ro->state = SPDK_BLOB_STATE_DIRTY;
2885 
2886 	g_bserrno = -1;
2887 	spdk_blob_sync_md(blob_invalid, blob_op_complete, NULL);
2888 	CU_ASSERT(g_bserrno == 0);
2889 	g_bserrno = -1;
2890 	spdk_blob_sync_md(blob_data_ro, blob_op_complete, NULL);
2891 	CU_ASSERT(g_bserrno == 0);
2892 	g_bserrno = -1;
2893 	spdk_blob_sync_md(blob_md_ro, blob_op_complete, NULL);
2894 	CU_ASSERT(g_bserrno == 0);
2895 
2896 	g_bserrno = -1;
2897 	spdk_blob_close(blob_invalid, blob_op_complete, NULL);
2898 	CU_ASSERT(g_bserrno == 0);
2899 	blob_invalid = NULL;
2900 	g_bserrno = -1;
2901 	spdk_blob_close(blob_data_ro, blob_op_complete, NULL);
2902 	CU_ASSERT(g_bserrno == 0);
2903 	blob_data_ro = NULL;
2904 	g_bserrno = -1;
2905 	spdk_blob_close(blob_md_ro, blob_op_complete, NULL);
2906 	CU_ASSERT(g_bserrno == 0);
2907 	blob_md_ro = NULL;
2908 
2909 	g_blob = NULL;
2910 	g_blobid = SPDK_BLOBID_INVALID;
2911 
2912 	/* Unload the blob store */
2913 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2914 	CU_ASSERT(g_bserrno == 0);
2915 	g_bs = NULL;
2916 
2917 	/* Load an existing blob store */
2918 	dev = init_dev();
2919 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2920 	CU_ASSERT(g_bserrno == 0);
2921 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2922 
2923 	g_blob = NULL;
2924 	g_bserrno = 0;
2925 	spdk_bs_open_blob(g_bs, blobid_invalid, blob_op_with_handle_complete, NULL);
2926 	CU_ASSERT(g_bserrno != 0);
2927 	CU_ASSERT(g_blob == NULL);
2928 
2929 	g_blob = NULL;
2930 	g_bserrno = -1;
2931 	spdk_bs_open_blob(g_bs, blobid_data_ro, blob_op_with_handle_complete, NULL);
2932 	CU_ASSERT(g_bserrno == 0);
2933 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
2934 	blob_data_ro = g_blob;
2935 	/* If an unknown data_ro flag was found, the blob should be marked both data and md read-only. */
2936 	CU_ASSERT(blob_data_ro->data_ro == true);
2937 	CU_ASSERT(blob_data_ro->md_ro == true);
2938 	CU_ASSERT(spdk_blob_get_num_clusters(blob_data_ro) == 10);
2939 
2940 	g_blob = NULL;
2941 	g_bserrno = -1;
2942 	spdk_bs_open_blob(g_bs, blobid_md_ro, blob_op_with_handle_complete, NULL);
2943 	CU_ASSERT(g_bserrno == 0);
2944 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
2945 	blob_md_ro = g_blob;
2946 	CU_ASSERT(blob_md_ro->data_ro == false);
2947 	CU_ASSERT(blob_md_ro->md_ro == true);
2948 
2949 	g_bserrno = -1;
2950 	spdk_blob_sync_md(blob_md_ro, blob_op_complete, NULL);
2951 	CU_ASSERT(g_bserrno == 0);
2952 
2953 	spdk_blob_close(blob_data_ro, blob_op_complete, NULL);
2954 	CU_ASSERT(g_bserrno == 0);
2955 	spdk_blob_close(blob_md_ro, blob_op_complete, NULL);
2956 	CU_ASSERT(g_bserrno == 0);
2957 
2958 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2959 	CU_ASSERT(g_bserrno == 0);
2960 }
2961 
2962 static void
2963 bs_version(void)
2964 {
2965 	struct spdk_bs_super_block *super;
2966 	struct spdk_bs_dev *dev;
2967 	struct spdk_bs_opts opts;
2968 	spdk_blob_id blobid;
2969 
2970 	dev = init_dev();
2971 	spdk_bs_opts_init(&opts);
2972 
2973 	/* Initialize a new blob store */
2974 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2975 	CU_ASSERT(g_bserrno == 0);
2976 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2977 
2978 	/* Unload the blob store */
2979 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2980 	CU_ASSERT(g_bserrno == 0);
2981 	g_bs = NULL;
2982 
2983 	/*
2984 	 * Change the bs version on disk.  This will allow us to
2985 	 *  test that the version does not get modified automatically
2986 	 *  when loading and unloading the blobstore.
2987 	 */
2988 	super = (struct spdk_bs_super_block *)&g_dev_buffer[0];
2989 	CU_ASSERT(super->version == SPDK_BS_VERSION);
2990 	CU_ASSERT(super->clean == 1);
2991 	super->version = 2;
2992 	/*
2993 	 * Version 2 metadata does not have a used blobid mask, so clear
2994 	 *  those fields in the super block and zero the corresponding
2995 	 *  region on "disk".  We will use this to ensure blob IDs are
2996 	 *  correctly reconstructed.
2997 	 */
2998 	memset(&g_dev_buffer[super->used_blobid_mask_start * SPDK_BS_PAGE_SIZE], 0,
2999 	       super->used_blobid_mask_len * SPDK_BS_PAGE_SIZE);
3000 	super->used_blobid_mask_start = 0;
3001 	super->used_blobid_mask_len = 0;
3002 	super->crc = _spdk_blob_md_page_calc_crc(super);
3003 
3004 	/* Load an existing blob store */
3005 	dev = init_dev();
3006 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
3007 	CU_ASSERT(g_bserrno == 0);
3008 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3009 	CU_ASSERT(super->clean == 0);
3010 
3011 	/*
3012 	 * Create a blob - just to make sure that when we unload it
3013 	 *  results in writing the super block (since metadata pages
3014 	 *  were allocated.
3015 	 */
3016 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
3017 	CU_ASSERT(g_bserrno == 0);
3018 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3019 	blobid = g_blobid;
3020 
3021 	/* Unload the blob store */
3022 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3023 	CU_ASSERT(g_bserrno == 0);
3024 	g_bs = NULL;
3025 	CU_ASSERT(super->version == 2);
3026 	CU_ASSERT(super->used_blobid_mask_start == 0);
3027 	CU_ASSERT(super->used_blobid_mask_len == 0);
3028 
3029 	dev = init_dev();
3030 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
3031 	CU_ASSERT(g_bserrno == 0);
3032 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3033 
3034 	g_blob = NULL;
3035 	spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
3036 	CU_ASSERT(g_bserrno == 0);
3037 	CU_ASSERT(g_blob != NULL);
3038 
3039 	spdk_blob_close(g_blob, blob_op_complete, NULL);
3040 	CU_ASSERT(g_bserrno == 0);
3041 
3042 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3043 	CU_ASSERT(g_bserrno == 0);
3044 	g_bs = NULL;
3045 	CU_ASSERT(super->version == 2);
3046 	CU_ASSERT(super->used_blobid_mask_start == 0);
3047 	CU_ASSERT(super->used_blobid_mask_len == 0);
3048 }
3049 
3050 static void
3051 blob_set_xattrs(void)
3052 {
3053 	struct spdk_blob_store *bs;
3054 	struct spdk_bs_dev *dev;
3055 	struct spdk_blob *blob;
3056 	struct spdk_blob_opts opts;
3057 	spdk_blob_id blobid;
3058 	const void *value;
3059 	size_t value_len;
3060 	int rc;
3061 
3062 	dev = init_dev();
3063 
3064 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
3065 	CU_ASSERT(g_bserrno == 0);
3066 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3067 	bs = g_bs;
3068 
3069 	/* Create blob with extra attributes */
3070 	spdk_blob_opts_init(&opts);
3071 
3072 	opts.xattrs.names = g_xattr_names;
3073 	opts.xattrs.get_value = _get_xattr_value;
3074 	opts.xattrs.count = 3;
3075 	opts.xattrs.ctx = &g_ctx;
3076 
3077 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
3078 	CU_ASSERT(g_bserrno == 0);
3079 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3080 	blobid = g_blobid;
3081 
3082 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
3083 	CU_ASSERT(g_bserrno == 0);
3084 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3085 	blob = g_blob;
3086 
3087 	/* Get the xattrs */
3088 	value = NULL;
3089 
3090 	rc = spdk_blob_get_xattr_value(blob, g_xattr_names[0], &value, &value_len);
3091 	CU_ASSERT(rc == 0);
3092 	SPDK_CU_ASSERT_FATAL(value != NULL);
3093 	CU_ASSERT(value_len == strlen(g_xattr_values[0]));
3094 	CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len);
3095 
3096 	rc = spdk_blob_get_xattr_value(blob, g_xattr_names[1], &value, &value_len);
3097 	CU_ASSERT(rc == 0);
3098 	SPDK_CU_ASSERT_FATAL(value != NULL);
3099 	CU_ASSERT(value_len == strlen(g_xattr_values[1]));
3100 	CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len);
3101 
3102 	rc = spdk_blob_get_xattr_value(blob, g_xattr_names[2], &value, &value_len);
3103 	CU_ASSERT(rc == 0);
3104 	SPDK_CU_ASSERT_FATAL(value != NULL);
3105 	CU_ASSERT(value_len == strlen(g_xattr_values[2]));
3106 	CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len);
3107 
3108 	/* Try to get non existing attribute */
3109 
3110 	rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len);
3111 	CU_ASSERT(rc == -ENOENT);
3112 
3113 	spdk_blob_close(blob, blob_op_complete, NULL);
3114 	CU_ASSERT(g_bserrno == 0);
3115 	blob = NULL;
3116 	g_blob = NULL;
3117 	g_blobid = SPDK_BLOBID_INVALID;
3118 
3119 	/* NULL callback */
3120 	spdk_blob_opts_init(&opts);
3121 	opts.xattrs.names = g_xattr_names;
3122 	opts.xattrs.get_value = NULL;
3123 	opts.xattrs.count = 1;
3124 	opts.xattrs.ctx = &g_ctx;
3125 
3126 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
3127 	CU_ASSERT(g_bserrno == -EINVAL);
3128 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3129 
3130 	/* NULL values */
3131 	spdk_blob_opts_init(&opts);
3132 	opts.xattrs.names = g_xattr_names;
3133 	opts.xattrs.get_value = _get_xattr_value_null;
3134 	opts.xattrs.count = 1;
3135 	opts.xattrs.ctx = NULL;
3136 
3137 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
3138 	CU_ASSERT(g_bserrno == -EINVAL);
3139 
3140 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3141 	CU_ASSERT(g_bserrno == 0);
3142 	g_bs = NULL;
3143 
3144 }
3145 
3146 static void
3147 blob_thin_prov_alloc(void)
3148 {
3149 	struct spdk_blob_store *bs;
3150 	struct spdk_bs_dev *dev;
3151 	struct spdk_blob *blob;
3152 	struct spdk_blob_opts opts;
3153 	spdk_blob_id blobid;
3154 	uint64_t free_clusters;
3155 
3156 	dev = init_dev();
3157 
3158 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
3159 	CU_ASSERT(g_bserrno == 0);
3160 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3161 	bs = g_bs;
3162 	free_clusters = spdk_bs_free_cluster_count(bs);
3163 
3164 	/* Set blob as thin provisioned */
3165 	spdk_blob_opts_init(&opts);
3166 	opts.thin_provision = true;
3167 
3168 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
3169 	CU_ASSERT(g_bserrno == 0);
3170 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3171 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3172 	blobid = g_blobid;
3173 
3174 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
3175 	CU_ASSERT(g_bserrno == 0);
3176 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3177 	blob = g_blob;
3178 
3179 	CU_ASSERT(blob->active.num_clusters == 0);
3180 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0);
3181 
3182 	/* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */
3183 	spdk_blob_resize(blob, 5, blob_op_complete, NULL);
3184 	CU_ASSERT(g_bserrno == 0);
3185 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3186 	CU_ASSERT(blob->active.num_clusters == 5);
3187 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5);
3188 
3189 	/* Shrink the blob to 3 clusters - still unallocated */
3190 	spdk_blob_resize(blob, 3, blob_op_complete, NULL);
3191 	CU_ASSERT(g_bserrno == 0);
3192 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3193 	CU_ASSERT(blob->active.num_clusters == 3);
3194 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 3);
3195 
3196 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
3197 	CU_ASSERT(g_bserrno == 0);
3198 	/* Sync must not change anything */
3199 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3200 	CU_ASSERT(blob->active.num_clusters == 3);
3201 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 3);
3202 
3203 	spdk_blob_close(blob, blob_op_complete, NULL);
3204 	CU_ASSERT(g_bserrno == 0);
3205 
3206 	/* Unload the blob store */
3207 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3208 	CU_ASSERT(g_bserrno == 0);
3209 	g_bs = NULL;
3210 	g_blob = NULL;
3211 	g_blobid = 0;
3212 
3213 	/* Load an existing blob store */
3214 	dev = init_dev();
3215 	spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL);
3216 	CU_ASSERT(g_bserrno == 0);
3217 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3218 
3219 	bs = g_bs;
3220 
3221 	spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
3222 	CU_ASSERT(g_bserrno == 0);
3223 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3224 	blob = g_blob;
3225 
3226 	/* Check that clusters allocation and size is still the same */
3227 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3228 	CU_ASSERT(blob->active.num_clusters == 3);
3229 
3230 	spdk_blob_close(blob, blob_op_complete, NULL);
3231 	CU_ASSERT(g_bserrno == 0);
3232 
3233 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
3234 	CU_ASSERT(g_bserrno == 0);
3235 
3236 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3237 	CU_ASSERT(g_bserrno == 0);
3238 	g_bs = NULL;
3239 }
3240 
3241 static void
3242 blob_insert_cluster_msg(void)
3243 {
3244 	struct spdk_blob_store *bs;
3245 	struct spdk_bs_dev *dev;
3246 	struct spdk_blob *blob;
3247 	struct spdk_blob_opts opts;
3248 	spdk_blob_id blobid;
3249 	uint64_t free_clusters;
3250 
3251 	dev = init_dev();
3252 
3253 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
3254 	CU_ASSERT(g_bserrno == 0);
3255 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3256 	bs = g_bs;
3257 	free_clusters = spdk_bs_free_cluster_count(bs);
3258 
3259 	/* Set blob as thin provisioned */
3260 	spdk_blob_opts_init(&opts);
3261 	opts.thin_provision = true;
3262 	opts.num_clusters = 4;
3263 
3264 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
3265 	CU_ASSERT(g_bserrno == 0);
3266 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3267 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3268 	blobid = g_blobid;
3269 
3270 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
3271 	CU_ASSERT(g_bserrno == 0);
3272 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3273 	blob = g_blob;
3274 
3275 	CU_ASSERT(blob->active.num_clusters == 4);
3276 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 4);
3277 	CU_ASSERT(blob->active.clusters[1] == 0);
3278 
3279 	_spdk_bs_claim_cluster(bs, 0xF);
3280 	_spdk_blob_insert_cluster_on_md_thread(blob, 1, 0xF, blob_op_complete, NULL);
3281 
3282 	CU_ASSERT(blob->active.clusters[1] != 0);
3283 
3284 	spdk_blob_close(blob, blob_op_complete, NULL);
3285 	CU_ASSERT(g_bserrno == 0);
3286 
3287 	/* Unload the blob store */
3288 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3289 	CU_ASSERT(g_bserrno == 0);
3290 	g_bs = NULL;
3291 	g_blob = NULL;
3292 	g_blobid = 0;
3293 
3294 	/* Load an existing blob store */
3295 	dev = init_dev();
3296 	spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL);
3297 	CU_ASSERT(g_bserrno == 0);
3298 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3299 
3300 	bs = g_bs;
3301 
3302 	spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
3303 	CU_ASSERT(g_bserrno == 0);
3304 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3305 	blob = g_blob;
3306 
3307 	CU_ASSERT(blob->active.clusters[1] != 0);
3308 
3309 	spdk_blob_close(blob, blob_op_complete, NULL);
3310 	CU_ASSERT(g_bserrno == 0);
3311 
3312 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
3313 	CU_ASSERT(g_bserrno == 0);
3314 
3315 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3316 	CU_ASSERT(g_bserrno == 0);
3317 	g_bs = NULL;
3318 }
3319 
3320 static void
3321 blob_thin_prov_rw(void)
3322 {
3323 	static const uint8_t zero[10 * 4096] = { 0 };
3324 	struct spdk_blob_store *bs;
3325 	struct spdk_bs_dev *dev;
3326 	struct spdk_blob *blob;
3327 	struct spdk_io_channel *channel;
3328 	struct spdk_blob_opts opts;
3329 	spdk_blob_id blobid;
3330 	uint64_t free_clusters;
3331 	uint8_t payload_read[10 * 4096];
3332 	uint8_t payload_write[10 * 4096];
3333 
3334 	dev = init_dev();
3335 
3336 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
3337 	CU_ASSERT(g_bserrno == 0);
3338 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3339 	bs = g_bs;
3340 	free_clusters = spdk_bs_free_cluster_count(bs);
3341 
3342 	channel = spdk_bs_alloc_io_channel(bs);
3343 	CU_ASSERT(channel != NULL);
3344 
3345 	spdk_blob_opts_init(&opts);
3346 	opts.thin_provision = true;
3347 
3348 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
3349 	CU_ASSERT(g_bserrno == 0);
3350 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3351 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3352 	blobid = g_blobid;
3353 
3354 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
3355 	CU_ASSERT(g_bserrno == 0);
3356 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3357 	blob = g_blob;
3358 
3359 	CU_ASSERT(blob->active.num_clusters == 0);
3360 
3361 	/* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */
3362 	spdk_blob_resize(blob, 5, blob_op_complete, NULL);
3363 	CU_ASSERT(g_bserrno == 0);
3364 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3365 	CU_ASSERT(blob->active.num_clusters == 5);
3366 
3367 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
3368 	CU_ASSERT(g_bserrno == 0);
3369 	/* Sync must not change anything */
3370 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3371 	CU_ASSERT(blob->active.num_clusters == 5);
3372 
3373 	/* Payload should be all zeros from unallocated clusters */
3374 	memset(payload_read, 0xFF, sizeof(payload_read));
3375 	spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL);
3376 	CU_ASSERT(g_bserrno == 0);
3377 	CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0);
3378 
3379 	memset(payload_write, 0xE5, sizeof(payload_write));
3380 	spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL);
3381 	CU_ASSERT(g_bserrno == 0);
3382 	CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs));
3383 
3384 	spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL);
3385 	CU_ASSERT(g_bserrno == 0);
3386 	CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0);
3387 
3388 	spdk_blob_close(blob, blob_op_complete, NULL);
3389 	CU_ASSERT(g_bserrno == 0);
3390 
3391 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
3392 	CU_ASSERT(g_bserrno == 0);
3393 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3394 
3395 	spdk_bs_free_io_channel(channel);
3396 
3397 	/* Unload the blob store */
3398 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3399 	CU_ASSERT(g_bserrno == 0);
3400 	g_bs = NULL;
3401 	g_blob = NULL;
3402 	g_blobid = 0;
3403 }
3404 
3405 static void
3406 blob_thin_prov_rw_iov(void)
3407 {
3408 	static const uint8_t zero[10 * 4096] = { 0 };
3409 	struct spdk_blob_store *bs;
3410 	struct spdk_bs_dev *dev;
3411 	struct spdk_blob *blob;
3412 	struct spdk_io_channel *channel;
3413 	struct spdk_blob_opts opts;
3414 	spdk_blob_id blobid;
3415 	uint64_t free_clusters;
3416 	uint8_t payload_read[10 * 4096];
3417 	uint8_t payload_write[10 * 4096];
3418 	struct iovec iov_read[3];
3419 	struct iovec iov_write[3];
3420 
3421 	dev = init_dev();
3422 
3423 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
3424 	CU_ASSERT(g_bserrno == 0);
3425 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3426 	bs = g_bs;
3427 	free_clusters = spdk_bs_free_cluster_count(bs);
3428 
3429 	channel = spdk_bs_alloc_io_channel(bs);
3430 	CU_ASSERT(channel != NULL);
3431 
3432 	spdk_blob_opts_init(&opts);
3433 	opts.thin_provision = true;
3434 
3435 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
3436 	CU_ASSERT(g_bserrno == 0);
3437 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3438 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3439 	blobid = g_blobid;
3440 
3441 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
3442 	CU_ASSERT(g_bserrno == 0);
3443 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3444 	blob = g_blob;
3445 
3446 	CU_ASSERT(blob->active.num_clusters == 0);
3447 
3448 	/* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */
3449 	spdk_blob_resize(blob, 5, blob_op_complete, NULL);
3450 	CU_ASSERT(g_bserrno == 0);
3451 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3452 	CU_ASSERT(blob->active.num_clusters == 5);
3453 
3454 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
3455 	CU_ASSERT(g_bserrno == 0);
3456 	/* Sync must not change anything */
3457 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3458 	CU_ASSERT(blob->active.num_clusters == 5);
3459 
3460 	/* Payload should be all zeros from unallocated clusters */
3461 	memset(payload_read, 0xAA, sizeof(payload_read));
3462 	iov_read[0].iov_base = payload_read;
3463 	iov_read[0].iov_len = 3 * 4096;
3464 	iov_read[1].iov_base = payload_read + 3 * 4096;
3465 	iov_read[1].iov_len = 4 * 4096;
3466 	iov_read[2].iov_base = payload_read + 7 * 4096;
3467 	iov_read[2].iov_len = 3 * 4096;
3468 	spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL);
3469 	CU_ASSERT(g_bserrno == 0);
3470 	CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0);
3471 
3472 	memset(payload_write, 0xE5, sizeof(payload_write));
3473 	iov_write[0].iov_base = payload_write;
3474 	iov_write[0].iov_len = 1 * 4096;
3475 	iov_write[1].iov_base = payload_write + 1 * 4096;
3476 	iov_write[1].iov_len = 5 * 4096;
3477 	iov_write[2].iov_base = payload_write + 6 * 4096;
3478 	iov_write[2].iov_len = 4 * 4096;
3479 
3480 	spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL);
3481 	CU_ASSERT(g_bserrno == 0);
3482 
3483 	memset(payload_read, 0xAA, sizeof(payload_read));
3484 	iov_read[0].iov_base = payload_read;
3485 	iov_read[0].iov_len = 3 * 4096;
3486 	iov_read[1].iov_base = payload_read + 3 * 4096;
3487 	iov_read[1].iov_len = 4 * 4096;
3488 	iov_read[2].iov_base = payload_read + 7 * 4096;
3489 	iov_read[2].iov_len = 3 * 4096;
3490 	spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL);
3491 	CU_ASSERT(g_bserrno == 0);
3492 	CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0);
3493 
3494 	spdk_blob_close(blob, blob_op_complete, NULL);
3495 	CU_ASSERT(g_bserrno == 0);
3496 
3497 	spdk_bs_free_io_channel(channel);
3498 
3499 	/* Unload the blob store */
3500 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3501 	CU_ASSERT(g_bserrno == 0);
3502 	g_bs = NULL;
3503 	g_blob = NULL;
3504 	g_blobid = 0;
3505 }
3506 
3507 struct iter_ctx {
3508 	int		current_iter;
3509 	spdk_blob_id	blobid[4];
3510 };
3511 
3512 static void
3513 test_iter(void *arg, struct spdk_blob *blob, int bserrno)
3514 {
3515 	struct iter_ctx *iter_ctx = arg;
3516 	spdk_blob_id blobid;
3517 
3518 	CU_ASSERT(bserrno == 0);
3519 	blobid = spdk_blob_get_id(blob);
3520 	CU_ASSERT(blobid == iter_ctx->blobid[iter_ctx->current_iter++]);
3521 }
3522 
3523 static void
3524 bs_load_iter(void)
3525 {
3526 	struct spdk_bs_dev *dev;
3527 	struct iter_ctx iter_ctx = { 0 };
3528 	struct spdk_blob *blob;
3529 	int i, rc;
3530 	struct spdk_bs_opts opts;
3531 
3532 	dev = init_dev();
3533 	spdk_bs_opts_init(&opts);
3534 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
3535 
3536 	/* Initialize a new blob store */
3537 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
3538 	CU_ASSERT(g_bserrno == 0);
3539 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3540 
3541 	for (i = 0; i < 4; i++) {
3542 		g_bserrno = -1;
3543 		g_blobid = SPDK_BLOBID_INVALID;
3544 		spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
3545 		CU_ASSERT(g_bserrno == 0);
3546 		CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3547 		iter_ctx.blobid[i] = g_blobid;
3548 
3549 		g_bserrno = -1;
3550 		g_blob = NULL;
3551 		spdk_bs_open_blob(g_bs, g_blobid, blob_op_with_handle_complete, NULL);
3552 		CU_ASSERT(g_bserrno == 0);
3553 		CU_ASSERT(g_blob != NULL);
3554 		blob = g_blob;
3555 
3556 		/* Just save the blobid as an xattr for testing purposes. */
3557 		rc = spdk_blob_set_xattr(blob, "blobid", &g_blobid, sizeof(g_blobid));
3558 		CU_ASSERT(rc == 0);
3559 
3560 		/* Resize the blob */
3561 		spdk_blob_resize(blob, i, blob_op_complete, NULL);
3562 		CU_ASSERT(g_bserrno == 0);
3563 
3564 		spdk_blob_close(blob, blob_op_complete, NULL);
3565 		CU_ASSERT(g_bserrno == 0);
3566 	}
3567 
3568 	g_bserrno = -1;
3569 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3570 	CU_ASSERT(g_bserrno == 0);
3571 
3572 	dev = init_dev();
3573 	spdk_bs_opts_init(&opts);
3574 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
3575 	opts.iter_cb_fn = test_iter;
3576 	opts.iter_cb_arg = &iter_ctx;
3577 
3578 	/* Test blob iteration during load after a clean shutdown. */
3579 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
3580 	CU_ASSERT(g_bserrno == 0);
3581 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3582 
3583 	/* Dirty shutdown */
3584 	_spdk_bs_free(g_bs);
3585 
3586 	dev = init_dev();
3587 	spdk_bs_opts_init(&opts);
3588 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
3589 	opts.iter_cb_fn = test_iter;
3590 	iter_ctx.current_iter = 0;
3591 	opts.iter_cb_arg = &iter_ctx;
3592 
3593 	/* Test blob iteration during load after a dirty shutdown. */
3594 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
3595 	CU_ASSERT(g_bserrno == 0);
3596 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3597 
3598 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3599 	CU_ASSERT(g_bserrno == 0);
3600 	g_bs = NULL;
3601 }
3602 
3603 static void
3604 blob_snapshot_rw(void)
3605 {
3606 	static const uint8_t zero[10 * 4096] = { 0 };
3607 	struct spdk_blob_store *bs;
3608 	struct spdk_bs_dev *dev;
3609 	struct spdk_blob *blob, *snapshot;
3610 	struct spdk_io_channel *channel;
3611 	struct spdk_blob_opts opts;
3612 	spdk_blob_id blobid, snapshotid;
3613 	uint64_t free_clusters;
3614 	uint8_t payload_read[10 * 4096];
3615 	uint8_t payload_write[10 * 4096];
3616 
3617 	dev = init_dev();
3618 
3619 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
3620 	CU_ASSERT(g_bserrno == 0);
3621 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3622 	bs = g_bs;
3623 	free_clusters = spdk_bs_free_cluster_count(bs);
3624 
3625 	channel = spdk_bs_alloc_io_channel(bs);
3626 	CU_ASSERT(channel != NULL);
3627 
3628 	spdk_blob_opts_init(&opts);
3629 	opts.thin_provision = true;
3630 	opts.num_clusters = 5;
3631 
3632 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
3633 	CU_ASSERT(g_bserrno == 0);
3634 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3635 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3636 	blobid = g_blobid;
3637 
3638 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
3639 	CU_ASSERT(g_bserrno == 0);
3640 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3641 	blob = g_blob;
3642 
3643 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5);
3644 
3645 	memset(payload_read, 0xFF, sizeof(payload_read));
3646 	spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL);
3647 	CU_ASSERT(g_bserrno == 0);
3648 	CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0);
3649 
3650 	memset(payload_write, 0xE5, sizeof(payload_write));
3651 	spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL);
3652 	CU_ASSERT(g_bserrno == 0);
3653 	CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs));
3654 
3655 	/* Create snapshot from blob */
3656 	spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL);
3657 	CU_ASSERT(g_bserrno == 0);
3658 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3659 	snapshotid = g_blobid;
3660 
3661 	spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL);
3662 	CU_ASSERT(g_bserrno == 0);
3663 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3664 	snapshot = g_blob;
3665 	CU_ASSERT(snapshot->data_ro == true)
3666 	CU_ASSERT(snapshot->md_ro == true)
3667 
3668 	CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 5)
3669 
3670 	memset(payload_write, 0xAA, sizeof(payload_write));
3671 	spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL);
3672 	CU_ASSERT(g_bserrno == 0);
3673 	CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs));
3674 
3675 	spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL);
3676 	CU_ASSERT(g_bserrno == 0);
3677 	CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0);
3678 
3679 	/* Data on snapshot should not change after write to clone */
3680 	memset(payload_write, 0xE5, sizeof(payload_write));
3681 	spdk_blob_io_read(snapshot, channel, payload_read, 4, 10, blob_op_complete, NULL);
3682 	CU_ASSERT(g_bserrno == 0);
3683 	CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0);
3684 
3685 	spdk_blob_close(blob, blob_op_complete, NULL);
3686 	CU_ASSERT(g_bserrno == 0);
3687 
3688 	spdk_blob_close(snapshot, blob_op_complete, NULL);
3689 	CU_ASSERT(g_bserrno == 0);
3690 
3691 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
3692 	CU_ASSERT(g_bserrno == 0);
3693 
3694 	spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL);
3695 	CU_ASSERT(g_bserrno == 0);
3696 
3697 	spdk_bs_free_io_channel(channel);
3698 
3699 	/* Unload the blob store */
3700 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3701 	CU_ASSERT(g_bserrno == 0);
3702 	g_bs = NULL;
3703 	g_blob = NULL;
3704 	g_blobid = 0;
3705 }
3706 
3707 static void
3708 blob_snapshot_rw_iov(void)
3709 {
3710 	static const uint8_t zero[10 * 4096] = { 0 };
3711 	struct spdk_blob_store *bs;
3712 	struct spdk_bs_dev *dev;
3713 	struct spdk_blob *blob, *snapshot;
3714 	struct spdk_io_channel *channel;
3715 	struct spdk_blob_opts opts;
3716 	spdk_blob_id blobid, snapshotid;
3717 	uint64_t free_clusters;
3718 	uint8_t payload_read[10 * 4096];
3719 	uint8_t payload_write[10 * 4096];
3720 	struct iovec iov_read[3];
3721 	struct iovec iov_write[3];
3722 
3723 	dev = init_dev();
3724 
3725 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
3726 	CU_ASSERT(g_bserrno == 0);
3727 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3728 	bs = g_bs;
3729 	free_clusters = spdk_bs_free_cluster_count(bs);
3730 
3731 	channel = spdk_bs_alloc_io_channel(bs);
3732 	CU_ASSERT(channel != NULL);
3733 
3734 	spdk_blob_opts_init(&opts);
3735 	opts.thin_provision = true;
3736 	opts.num_clusters = 5;
3737 
3738 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
3739 	CU_ASSERT(g_bserrno == 0);
3740 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3741 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3742 	blobid = g_blobid;
3743 
3744 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
3745 	CU_ASSERT(g_bserrno == 0);
3746 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3747 	blob = g_blob;
3748 
3749 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5);
3750 
3751 	/* Create snapshot from blob */
3752 	spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL);
3753 	CU_ASSERT(g_bserrno == 0);
3754 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3755 	snapshotid = g_blobid;
3756 
3757 	spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL);
3758 	CU_ASSERT(g_bserrno == 0);
3759 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3760 	snapshot = g_blob;
3761 	CU_ASSERT(snapshot->data_ro == true)
3762 	CU_ASSERT(snapshot->md_ro == true)
3763 	CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 5);
3764 
3765 	/* Payload should be all zeros from unallocated clusters */
3766 	memset(payload_read, 0xAA, sizeof(payload_read));
3767 	iov_read[0].iov_base = payload_read;
3768 	iov_read[0].iov_len = 3 * 4096;
3769 	iov_read[1].iov_base = payload_read + 3 * 4096;
3770 	iov_read[1].iov_len = 4 * 4096;
3771 	iov_read[2].iov_base = payload_read + 7 * 4096;
3772 	iov_read[2].iov_len = 3 * 4096;
3773 	spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL);
3774 	CU_ASSERT(g_bserrno == 0);
3775 	CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0);
3776 
3777 	memset(payload_write, 0xE5, sizeof(payload_write));
3778 	iov_write[0].iov_base = payload_write;
3779 	iov_write[0].iov_len = 1 * 4096;
3780 	iov_write[1].iov_base = payload_write + 1 * 4096;
3781 	iov_write[1].iov_len = 5 * 4096;
3782 	iov_write[2].iov_base = payload_write + 6 * 4096;
3783 	iov_write[2].iov_len = 4 * 4096;
3784 
3785 	spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL);
3786 	CU_ASSERT(g_bserrno == 0);
3787 
3788 	memset(payload_read, 0xAA, sizeof(payload_read));
3789 	iov_read[0].iov_base = payload_read;
3790 	iov_read[0].iov_len = 3 * 4096;
3791 	iov_read[1].iov_base = payload_read + 3 * 4096;
3792 	iov_read[1].iov_len = 4 * 4096;
3793 	iov_read[2].iov_base = payload_read + 7 * 4096;
3794 	iov_read[2].iov_len = 3 * 4096;
3795 	spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL);
3796 	CU_ASSERT(g_bserrno == 0);
3797 	CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0);
3798 
3799 	spdk_blob_close(blob, blob_op_complete, NULL);
3800 	CU_ASSERT(g_bserrno == 0);
3801 
3802 	spdk_blob_close(snapshot, blob_op_complete, NULL);
3803 	CU_ASSERT(g_bserrno == 0);
3804 
3805 	spdk_bs_free_io_channel(channel);
3806 
3807 	/* Unload the blob store */
3808 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3809 	CU_ASSERT(g_bserrno == 0);
3810 	g_bs = NULL;
3811 	g_blob = NULL;
3812 	g_blobid = 0;
3813 }
3814 
3815 static void
3816 blob_inflate_rw(void)
3817 {
3818 	static uint8_t *zero;
3819 	struct spdk_blob_store *bs;
3820 	struct spdk_bs_dev *dev;
3821 	struct spdk_blob *blob, *snapshot;
3822 	struct spdk_io_channel *channel;
3823 	struct spdk_blob_opts opts;
3824 	spdk_blob_id blobid, snapshotid;
3825 	uint64_t free_clusters;
3826 	uint64_t cluster_size;
3827 
3828 	uint64_t payload_size;
3829 	uint8_t *payload_read;
3830 	uint8_t *payload_write;
3831 	uint8_t *payload_clone;
3832 
3833 	uint64_t pages_per_cluster;
3834 	uint64_t pages_per_payload;
3835 
3836 	int i;
3837 
3838 	dev = init_dev();
3839 
3840 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
3841 	CU_ASSERT(g_bserrno == 0);
3842 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3843 	bs = g_bs;
3844 
3845 	free_clusters = spdk_bs_free_cluster_count(bs);
3846 	cluster_size = spdk_bs_get_cluster_size(bs);
3847 	pages_per_cluster = cluster_size / spdk_bs_get_page_size(bs);
3848 	pages_per_payload = pages_per_cluster * 5;
3849 
3850 	payload_size = cluster_size * 5;
3851 
3852 	payload_read = malloc(payload_size);
3853 	SPDK_CU_ASSERT_FATAL(payload_read != NULL);
3854 
3855 	payload_write = malloc(payload_size);
3856 	SPDK_CU_ASSERT_FATAL(payload_write != NULL);
3857 
3858 	payload_clone = malloc(payload_size);
3859 	SPDK_CU_ASSERT_FATAL(payload_clone != NULL);
3860 
3861 	zero = calloc(1, payload_size);
3862 	SPDK_CU_ASSERT_FATAL(zero != NULL);
3863 
3864 	channel = spdk_bs_alloc_io_channel(bs);
3865 	SPDK_CU_ASSERT_FATAL(channel != NULL);
3866 
3867 	/* Create blob */
3868 	spdk_blob_opts_init(&opts);
3869 	opts.thin_provision = true;
3870 	opts.num_clusters = 5;
3871 
3872 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
3873 	CU_ASSERT(g_bserrno == 0);
3874 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3875 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3876 	blobid = g_blobid;
3877 
3878 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
3879 	CU_ASSERT(g_bserrno == 0);
3880 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3881 	blob = g_blob;
3882 
3883 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5);
3884 
3885 	/* Initial read should return zeroed payload */
3886 	memset(payload_read, 0xFF, payload_size);
3887 	spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, blob_op_complete, NULL);
3888 	CU_ASSERT(g_bserrno == 0);
3889 	CU_ASSERT(memcmp(zero, payload_read, payload_size) == 0);
3890 
3891 	/* Fill whole blob with a pattern */
3892 	memset(payload_write, 0xE5, payload_size);
3893 	spdk_blob_io_write(blob, channel, payload_write, 0, pages_per_payload,
3894 			   blob_op_complete, NULL);
3895 	CU_ASSERT(g_bserrno == 0);
3896 	CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs));
3897 
3898 	/* Create snapshot from blob */
3899 	spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL);
3900 	CU_ASSERT(g_bserrno == 0);
3901 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3902 	snapshotid = g_blobid;
3903 
3904 	spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL);
3905 	CU_ASSERT(g_bserrno == 0);
3906 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3907 	snapshot = g_blob;
3908 	CU_ASSERT(snapshot->data_ro == true)
3909 	CU_ASSERT(snapshot->md_ro == true)
3910 
3911 	CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 5)
3912 
3913 	/* Write every second cluster with a pattern.
3914 	 *
3915 	 * payload_clone stores expected result on "blob" read at the time and
3916 	 * is used only to check data consistency on clone before and after
3917 	 * inflation. Initially we fill it with a backing snapshots pattern
3918 	 * used before.
3919 	 */
3920 	memset(payload_clone, 0xE5, payload_size);
3921 	memset(payload_write, 0xAA, payload_size);
3922 	for (i = 1; i < 5; i += 2) {
3923 		spdk_blob_io_write(blob, channel, payload_write, i * pages_per_cluster,
3924 				   pages_per_cluster, blob_op_complete, NULL);
3925 		CU_ASSERT(g_bserrno == 0);
3926 
3927 		/* Update expected result */
3928 		memcpy(payload_clone + (cluster_size * i), payload_write,
3929 		       cluster_size);
3930 	}
3931 	CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs));
3932 
3933 	/* Check data consistency on clone */
3934 	memset(payload_read, 0xFF, payload_size);
3935 	spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload,
3936 			  blob_op_complete, NULL);
3937 	CU_ASSERT(g_bserrno == 0);
3938 	CU_ASSERT(memcmp(payload_clone, payload_read, payload_size) == 0);
3939 
3940 	/* Close all blobs */
3941 	spdk_blob_close(blob, blob_op_complete, NULL);
3942 	CU_ASSERT(g_bserrno == 0);
3943 
3944 	spdk_blob_close(snapshot, blob_op_complete, NULL);
3945 	CU_ASSERT(g_bserrno == 0);
3946 
3947 	/* Inflate blob */
3948 	spdk_bs_inflate_blob(bs, channel, blobid, blob_op_complete, NULL);
3949 	CU_ASSERT(g_bserrno == 0);
3950 
3951 	/* Try to delete snapshot (should pass) */
3952 	spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL);
3953 	CU_ASSERT(g_bserrno == 0);
3954 
3955 	/* Reopen blob after snapshot deletion */
3956 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
3957 	CU_ASSERT(g_bserrno == 0);
3958 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3959 	blob = g_blob;
3960 
3961 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5);
3962 
3963 	/* Check data consistency on inflated blob */
3964 	memset(payload_read, 0xFF, payload_size);
3965 	spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, blob_op_complete, NULL);
3966 	CU_ASSERT(g_bserrno == 0);
3967 	CU_ASSERT(memcmp(payload_clone, payload_read, payload_size) == 0);
3968 
3969 	spdk_blob_close(blob, blob_op_complete, NULL);
3970 	CU_ASSERT(g_bserrno == 0);
3971 
3972 	spdk_bs_free_io_channel(channel);
3973 
3974 	/* Unload the blob store */
3975 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3976 	CU_ASSERT(g_bserrno == 0);
3977 	g_bs = NULL;
3978 	g_blob = NULL;
3979 	g_blobid = 0;
3980 
3981 	free(payload_read);
3982 	free(payload_write);
3983 	free(payload_clone);
3984 	free(zero);
3985 }
3986 
3987 /**
3988  * Snapshot-clones relation test
3989  *
3990  *      snapshot
3991  *          |
3992  *     +----+----+
3993  *     |         |
3994  *   blob      clone
3995  *     |
3996  *  clone2
3997  */
3998 static void
3999 blob_relations(void)
4000 {
4001 	struct spdk_blob_store *bs;
4002 	struct spdk_bs_dev *dev;
4003 	struct spdk_bs_opts bs_opts;
4004 	struct spdk_blob_opts opts;
4005 	struct spdk_blob *blob, *snapshot, *clone, *clone2;
4006 	spdk_blob_id blobid, cloneid, snapshotid, cloneid2;
4007 	int rc;
4008 	size_t count;
4009 	spdk_blob_id ids[10];
4010 
4011 	dev = init_dev();
4012 	spdk_bs_opts_init(&bs_opts);
4013 	snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE");
4014 
4015 	spdk_bs_init(dev, &bs_opts, bs_op_with_handle_complete, NULL);
4016 	CU_ASSERT(g_bserrno == 0);
4017 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
4018 	bs = g_bs;
4019 
4020 	/* 1. Create blob with 10 clusters */
4021 
4022 	spdk_blob_opts_init(&opts);
4023 	opts.num_clusters = 10;
4024 
4025 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
4026 	CU_ASSERT(g_bserrno == 0);
4027 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
4028 	blobid = g_blobid;
4029 
4030 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
4031 	CU_ASSERT(g_bserrno == 0);
4032 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4033 	blob = g_blob;
4034 
4035 	CU_ASSERT(!spdk_blob_is_read_only(blob));
4036 	CU_ASSERT(!spdk_blob_is_snapshot(blob));
4037 	CU_ASSERT(!spdk_blob_is_clone(blob));
4038 	CU_ASSERT(!spdk_blob_is_thin_provisioned(blob));
4039 
4040 	/* blob should not have underlying snapshot nor clones */
4041 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == SPDK_BLOBID_INVALID);
4042 	count = SPDK_COUNTOF(ids);
4043 	rc = spdk_blob_get_clones(bs, blobid, ids, &count);
4044 	CU_ASSERT(rc == 0);
4045 	CU_ASSERT(count == 0);
4046 
4047 
4048 	/* 2. Create snapshot */
4049 
4050 	spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL);
4051 	CU_ASSERT(g_bserrno == 0);
4052 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
4053 	snapshotid = g_blobid;
4054 
4055 	spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL);
4056 	CU_ASSERT(g_bserrno == 0);
4057 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4058 	snapshot = g_blob;
4059 
4060 	CU_ASSERT(spdk_blob_is_read_only(snapshot));
4061 	CU_ASSERT(spdk_blob_is_snapshot(snapshot));
4062 	CU_ASSERT(!spdk_blob_is_clone(snapshot));
4063 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid) == SPDK_BLOBID_INVALID);
4064 
4065 	/* Check if original blob is converted to the clone of snapshot */
4066 	CU_ASSERT(!spdk_blob_is_read_only(blob));
4067 	CU_ASSERT(!spdk_blob_is_snapshot(blob));
4068 	CU_ASSERT(spdk_blob_is_clone(blob));
4069 	CU_ASSERT(spdk_blob_is_thin_provisioned(blob));
4070 
4071 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid);
4072 
4073 	count = SPDK_COUNTOF(ids);
4074 	rc = spdk_blob_get_clones(bs, snapshotid, ids, &count);
4075 	CU_ASSERT(rc == 0);
4076 	CU_ASSERT(count == 1);
4077 	CU_ASSERT(ids[0] == blobid);
4078 
4079 
4080 	/* 3. Create clone from snapshot */
4081 
4082 	spdk_bs_create_clone(bs, snapshotid, NULL, blob_op_with_id_complete, NULL);
4083 	CU_ASSERT(g_bserrno == 0);
4084 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
4085 	cloneid = g_blobid;
4086 
4087 	spdk_bs_open_blob(bs, cloneid, blob_op_with_handle_complete, NULL);
4088 	CU_ASSERT(g_bserrno == 0);
4089 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4090 	clone = g_blob;
4091 
4092 	CU_ASSERT(!spdk_blob_is_read_only(clone));
4093 	CU_ASSERT(!spdk_blob_is_snapshot(clone));
4094 	CU_ASSERT(spdk_blob_is_clone(clone));
4095 	CU_ASSERT(spdk_blob_is_thin_provisioned(clone));
4096 
4097 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid);
4098 
4099 	count = SPDK_COUNTOF(ids);
4100 	rc = spdk_blob_get_clones(bs, cloneid, ids, &count);
4101 	CU_ASSERT(rc == 0);
4102 	CU_ASSERT(count == 0);
4103 
4104 	/* Check if clone is on the snapshot's list */
4105 	count = SPDK_COUNTOF(ids);
4106 	rc = spdk_blob_get_clones(bs, snapshotid, ids, &count);
4107 	CU_ASSERT(rc == 0);
4108 	CU_ASSERT(ids[0] == blobid || ids[1] == blobid);
4109 	CU_ASSERT(ids[0] == cloneid || ids[1] == cloneid);
4110 
4111 
4112 	/* 4. Try to create clone from read only blob */
4113 
4114 	/* Mark blob as read only */
4115 	spdk_blob_set_read_only(blob);
4116 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
4117 	CU_ASSERT(g_bserrno == 0);
4118 
4119 	/* Check if previously created blob is read only clone */
4120 	CU_ASSERT(spdk_blob_is_read_only(blob));
4121 	CU_ASSERT(!spdk_blob_is_snapshot(blob));
4122 	CU_ASSERT(spdk_blob_is_clone(blob));
4123 	CU_ASSERT(spdk_blob_is_thin_provisioned(blob));
4124 
4125 	/* Create clone from read only blob */
4126 	spdk_bs_create_clone(bs, blobid, NULL, blob_op_with_id_complete, NULL);
4127 	CU_ASSERT(g_bserrno == 0);
4128 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
4129 	cloneid2 = g_blobid;
4130 
4131 	spdk_bs_open_blob(bs, cloneid2, blob_op_with_handle_complete, NULL);
4132 	CU_ASSERT(g_bserrno == 0);
4133 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4134 	clone2 = g_blob;
4135 
4136 	CU_ASSERT(!spdk_blob_is_read_only(clone2));
4137 	CU_ASSERT(!spdk_blob_is_snapshot(clone2));
4138 	CU_ASSERT(spdk_blob_is_clone(clone2));
4139 	CU_ASSERT(spdk_blob_is_thin_provisioned(clone2));
4140 
4141 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid2) == blobid);
4142 
4143 	count = SPDK_COUNTOF(ids);
4144 	rc = spdk_blob_get_clones(bs, blobid, ids, &count);
4145 	CU_ASSERT(rc == 0);
4146 
4147 	CU_ASSERT(count == 1);
4148 	CU_ASSERT(ids[0] == cloneid2);
4149 
4150 	/* Close blobs */
4151 
4152 	spdk_blob_close(clone2, blob_op_complete, NULL);
4153 	CU_ASSERT(g_bserrno == 0);
4154 
4155 	spdk_blob_close(blob, blob_op_complete, NULL);
4156 	CU_ASSERT(g_bserrno == 0);
4157 
4158 	spdk_blob_close(clone, blob_op_complete, NULL);
4159 	CU_ASSERT(g_bserrno == 0);
4160 
4161 	spdk_blob_close(snapshot, blob_op_complete, NULL);
4162 	CU_ASSERT(g_bserrno == 0);
4163 
4164 	/* Try to delete snapshot with created clones */
4165 	spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL);
4166 	CU_ASSERT(g_bserrno != 0);
4167 
4168 	spdk_bs_unload(bs, bs_op_complete, NULL);
4169 	CU_ASSERT(g_bserrno == 0);
4170 	g_bs = NULL;
4171 
4172 	/* Load an existing blob store */
4173 	dev = init_dev();
4174 	snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE");
4175 
4176 	spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL);
4177 	CU_ASSERT(g_bserrno == 0);
4178 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
4179 	bs = g_bs;
4180 
4181 
4182 	/* NULL ids array should return number of clones in count */
4183 	count = SPDK_COUNTOF(ids);
4184 	rc = spdk_blob_get_clones(bs, snapshotid, NULL, &count);
4185 	CU_ASSERT(rc == -ENOMEM);
4186 	CU_ASSERT(count == 2);
4187 
4188 	/* incorrect array size */
4189 	count = 1;
4190 	rc = spdk_blob_get_clones(bs, snapshotid, ids, &count);
4191 	CU_ASSERT(rc == -ENOMEM);
4192 	CU_ASSERT(count == 2);
4193 
4194 
4195 	/* Verify structure of loaded blob store */
4196 
4197 	/* snapshot */
4198 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid) == SPDK_BLOBID_INVALID);
4199 
4200 	count = SPDK_COUNTOF(ids);
4201 	rc = spdk_blob_get_clones(bs, snapshotid, ids, &count);
4202 	CU_ASSERT(rc == 0);
4203 	CU_ASSERT(count == 2);
4204 	CU_ASSERT(ids[0] == blobid || ids[1] == blobid);
4205 	CU_ASSERT(ids[0] == cloneid || ids[1] == cloneid);
4206 
4207 	/* blob */
4208 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid);
4209 	count = SPDK_COUNTOF(ids);
4210 	rc = spdk_blob_get_clones(bs, blobid, ids, &count);
4211 	CU_ASSERT(rc == 0);
4212 	CU_ASSERT(count == 1);
4213 	CU_ASSERT(ids[0] == cloneid2);
4214 
4215 	/* clone */
4216 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid);
4217 	count = SPDK_COUNTOF(ids);
4218 	rc = spdk_blob_get_clones(bs, cloneid, ids, &count);
4219 	CU_ASSERT(rc == 0);
4220 	CU_ASSERT(count == 0);
4221 
4222 	/* clone2 */
4223 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid2) == blobid);
4224 	count = SPDK_COUNTOF(ids);
4225 	rc = spdk_blob_get_clones(bs, cloneid2, ids, &count);
4226 	CU_ASSERT(rc == 0);
4227 	CU_ASSERT(count == 0);
4228 
4229 	/* Try to delete all blobs */
4230 	spdk_bs_delete_blob(bs, cloneid, blob_op_complete, NULL);
4231 	CU_ASSERT(g_bserrno == 0);
4232 
4233 	/* Try to delete snapshot with clones */
4234 	spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL);
4235 	CU_ASSERT(g_bserrno != 0);
4236 
4237 	/* Try to delete ro blob with clones */
4238 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
4239 	CU_ASSERT(g_bserrno != 0);
4240 
4241 	spdk_bs_delete_blob(bs, cloneid2, blob_op_complete, NULL);
4242 	CU_ASSERT(g_bserrno == 0);
4243 
4244 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
4245 	CU_ASSERT(g_bserrno == 0);
4246 
4247 	spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL);
4248 	CU_ASSERT(g_bserrno == 0);
4249 
4250 	spdk_bs_unload(bs, bs_op_complete, NULL);
4251 	CU_ASSERT(g_bserrno == 0);
4252 
4253 	g_bs = NULL;
4254 }
4255 
4256 int main(int argc, char **argv)
4257 {
4258 	CU_pSuite	suite = NULL;
4259 	unsigned int	num_failures;
4260 
4261 	if (CU_initialize_registry() != CUE_SUCCESS) {
4262 		return CU_get_error();
4263 	}
4264 
4265 	suite = CU_add_suite("blob", NULL, NULL);
4266 	if (suite == NULL) {
4267 		CU_cleanup_registry();
4268 		return CU_get_error();
4269 	}
4270 
4271 	if (
4272 		CU_add_test(suite, "blob_init", blob_init) == NULL ||
4273 		CU_add_test(suite, "blob_open", blob_open) == NULL ||
4274 		CU_add_test(suite, "blob_create", blob_create) == NULL ||
4275 		CU_add_test(suite, "blob_create_internal", blob_create_internal) == NULL ||
4276 		CU_add_test(suite, "blob_thin_provision", blob_thin_provision) == NULL ||
4277 		CU_add_test(suite, "blob_snapshot", blob_snapshot) == NULL ||
4278 		CU_add_test(suite, "blob_clone", blob_clone) == NULL ||
4279 		CU_add_test(suite, "blob_inflate", blob_inflate) == NULL ||
4280 		CU_add_test(suite, "blob_delete", blob_delete) == NULL ||
4281 		CU_add_test(suite, "blob_resize", blob_resize) == NULL ||
4282 		CU_add_test(suite, "blob_read_only", blob_read_only) == NULL ||
4283 		CU_add_test(suite, "channel_ops", channel_ops) == NULL ||
4284 		CU_add_test(suite, "blob_super", blob_super) == NULL ||
4285 		CU_add_test(suite, "blob_write", blob_write) == NULL ||
4286 		CU_add_test(suite, "blob_read", blob_read) == NULL ||
4287 		CU_add_test(suite, "blob_rw_verify", blob_rw_verify) == NULL ||
4288 		CU_add_test(suite, "blob_rw_verify_iov", blob_rw_verify_iov) == NULL ||
4289 		CU_add_test(suite, "blob_rw_verify_iov_nomem", blob_rw_verify_iov_nomem) == NULL ||
4290 		CU_add_test(suite, "blob_rw_iov_read_only", blob_rw_iov_read_only) == NULL ||
4291 		CU_add_test(suite, "blob_unmap", blob_unmap) == NULL ||
4292 		CU_add_test(suite, "blob_iter", blob_iter) == NULL ||
4293 		CU_add_test(suite, "blob_xattr", blob_xattr) == NULL ||
4294 		CU_add_test(suite, "bs_load", bs_load) == NULL ||
4295 		CU_add_test(suite, "bs_unload", bs_unload) == NULL ||
4296 		CU_add_test(suite, "bs_cluster_sz", bs_cluster_sz) == NULL ||
4297 		CU_add_test(suite, "bs_usable_clusters", bs_usable_clusters) == NULL ||
4298 		CU_add_test(suite, "bs_resize_md", bs_resize_md) == NULL ||
4299 		CU_add_test(suite, "bs_destroy", bs_destroy) == NULL ||
4300 		CU_add_test(suite, "bs_type", bs_type) == NULL ||
4301 		CU_add_test(suite, "bs_super_block", bs_super_block) == NULL ||
4302 		CU_add_test(suite, "blob_serialize", blob_serialize) == NULL ||
4303 		CU_add_test(suite, "blob_crc", blob_crc) == NULL ||
4304 		CU_add_test(suite, "super_block_crc", super_block_crc) == NULL ||
4305 		CU_add_test(suite, "blob_dirty_shutdown", blob_dirty_shutdown) == NULL ||
4306 		CU_add_test(suite, "blob_flags", blob_flags) == NULL ||
4307 		CU_add_test(suite, "bs_version", bs_version) == NULL ||
4308 		CU_add_test(suite, "blob_set_xattrs", blob_set_xattrs) == NULL ||
4309 		CU_add_test(suite, "blob_thin_prov_alloc", blob_thin_prov_alloc) == NULL ||
4310 		CU_add_test(suite, "blob_insert_cluster_msg", blob_insert_cluster_msg) == NULL ||
4311 		CU_add_test(suite, "blob_thin_prov_rw", blob_thin_prov_rw) == NULL ||
4312 		CU_add_test(suite, "blob_thin_prov_rw_iov", blob_thin_prov_rw_iov) == NULL ||
4313 		CU_add_test(suite, "bs_load_iter", bs_load_iter) == NULL ||
4314 		CU_add_test(suite, "blob_snapshot_rw", blob_snapshot_rw) == NULL ||
4315 		CU_add_test(suite, "blob_snapshot_rw_iov", blob_snapshot_rw_iov) == NULL ||
4316 		CU_add_test(suite, "blob_inflate_rw", blob_inflate_rw) == NULL ||
4317 		CU_add_test(suite, "blob_relations", blob_relations) == NULL
4318 	) {
4319 		CU_cleanup_registry();
4320 		return CU_get_error();
4321 	}
4322 
4323 	g_dev_buffer = calloc(1, DEV_BUFFER_SIZE);
4324 	spdk_allocate_thread(_bs_send_msg, NULL, NULL, NULL, "thread0");
4325 	CU_basic_set_mode(CU_BRM_VERBOSE);
4326 	CU_basic_run_tests();
4327 	num_failures = CU_get_number_of_failures();
4328 	CU_cleanup_registry();
4329 	spdk_free_thread();
4330 	free(g_dev_buffer);
4331 	return num_failures;
4332 }
4333