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