xref: /spdk/test/unit/lib/blob/blob.c/blob_ut.c (revision fa68a0fdbd11c085a2975699c65a5b7237ccbadb)
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_delete(void)
810 {
811 	struct spdk_blob_store *bs;
812 	struct spdk_bs_dev *dev;
813 	spdk_blob_id blobid;
814 
815 	dev = init_dev();
816 
817 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
818 	CU_ASSERT(g_bserrno == 0);
819 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
820 	bs = g_bs;
821 
822 	/* Create a blob and then delete it. */
823 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
824 	CU_ASSERT(g_bserrno == 0);
825 	CU_ASSERT(g_blobid > 0);
826 	blobid = g_blobid;
827 
828 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
829 	CU_ASSERT(g_bserrno == 0);
830 
831 	/* Try to open the blob */
832 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
833 	CU_ASSERT(g_bserrno == -ENOENT);
834 
835 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
836 	CU_ASSERT(g_bserrno == 0);
837 	g_bs = NULL;
838 }
839 
840 static void
841 blob_resize(void)
842 {
843 	struct spdk_blob_store *bs;
844 	struct spdk_bs_dev *dev;
845 	struct spdk_blob *blob;
846 	spdk_blob_id blobid;
847 	uint64_t free_clusters;
848 
849 	dev = init_dev();
850 
851 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
852 	CU_ASSERT(g_bserrno == 0);
853 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
854 	bs = g_bs;
855 	free_clusters = spdk_bs_free_cluster_count(bs);
856 
857 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
858 	CU_ASSERT(g_bserrno == 0);
859 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
860 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
861 	blobid = g_blobid;
862 
863 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
864 	CU_ASSERT(g_bserrno == 0);
865 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
866 	blob = g_blob;
867 
868 	/* Confirm that resize fails if blob is marked read-only. */
869 	blob->md_ro = true;
870 	spdk_blob_resize(blob, 5, blob_op_complete, NULL);
871 	CU_ASSERT(g_bserrno == -EPERM);
872 	blob->md_ro = false;
873 
874 	/* The blob started at 0 clusters. Resize it to be 5. */
875 	spdk_blob_resize(blob, 5, blob_op_complete, NULL);
876 	CU_ASSERT(g_bserrno == 0);
877 	CU_ASSERT((free_clusters - 5) == spdk_bs_free_cluster_count(bs));
878 
879 	/* Shrink the blob to 3 clusters. This will not actually release
880 	 * the old clusters until the blob is synced.
881 	 */
882 	spdk_blob_resize(blob, 3, blob_op_complete, NULL);
883 	CU_ASSERT(g_bserrno == 0);
884 	/* Verify there are still 5 clusters in use */
885 	CU_ASSERT((free_clusters - 5) == spdk_bs_free_cluster_count(bs));
886 
887 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
888 	CU_ASSERT(g_bserrno == 0);
889 	/* Now there are only 3 clusters in use */
890 	CU_ASSERT((free_clusters - 3) == spdk_bs_free_cluster_count(bs));
891 
892 	/* Resize the blob to be 10 clusters. Growth takes effect immediately. */
893 	spdk_blob_resize(blob, 10, blob_op_complete, NULL);
894 	CU_ASSERT(g_bserrno == 0);
895 	CU_ASSERT((free_clusters - 10) == spdk_bs_free_cluster_count(bs));
896 
897 	/* Try to resize the blob to size larger than blobstore. */
898 	spdk_blob_resize(blob, bs->total_clusters + 1, blob_op_complete, NULL);
899 	CU_ASSERT(g_bserrno == -ENOSPC);
900 
901 	spdk_blob_close(blob, blob_op_complete, NULL);
902 	CU_ASSERT(g_bserrno == 0);
903 
904 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
905 	CU_ASSERT(g_bserrno == 0);
906 
907 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
908 	CU_ASSERT(g_bserrno == 0);
909 	g_bs = NULL;
910 }
911 
912 static void
913 blob_read_only(void)
914 {
915 	struct spdk_blob_store *bs;
916 	struct spdk_bs_dev *dev;
917 	struct spdk_blob *blob;
918 	struct spdk_bs_opts opts;
919 	spdk_blob_id blobid;
920 	int rc;
921 
922 	dev = init_dev();
923 	spdk_bs_opts_init(&opts);
924 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
925 
926 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
927 	CU_ASSERT(g_bserrno == 0);
928 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
929 	bs = g_bs;
930 
931 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
932 	CU_ASSERT(g_bserrno == 0);
933 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
934 	blobid = g_blobid;
935 
936 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
937 	CU_ASSERT(g_bserrno == 0);
938 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
939 	blob = g_blob;
940 
941 	rc = spdk_blob_set_read_only(blob);
942 	CU_ASSERT(rc == 0);
943 
944 	CU_ASSERT(blob->data_ro == false);
945 	CU_ASSERT(blob->md_ro == false);
946 
947 	spdk_blob_sync_md(blob, bs_op_complete, NULL);
948 
949 	CU_ASSERT(blob->data_ro == true);
950 	CU_ASSERT(blob->md_ro == true);
951 	CU_ASSERT(blob->data_ro_flags & SPDK_BLOB_READ_ONLY);
952 
953 	spdk_blob_close(blob, blob_op_complete, NULL);
954 	CU_ASSERT(g_bserrno == 0);
955 
956 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
957 	CU_ASSERT(g_bserrno == 0);
958 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
959 	blob = g_blob;
960 
961 	CU_ASSERT(blob->data_ro == true);
962 	CU_ASSERT(blob->md_ro == true);
963 	CU_ASSERT(blob->data_ro_flags & SPDK_BLOB_READ_ONLY);
964 
965 	spdk_blob_close(blob, blob_op_complete, NULL);
966 	CU_ASSERT(g_bserrno == 0);
967 
968 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
969 	CU_ASSERT(g_bserrno == 0);
970 	g_bs = NULL;
971 	g_blob = NULL;
972 	g_blobid = 0;
973 
974 	/* Load an existing blob store */
975 	dev = init_dev();
976 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
977 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
978 	CU_ASSERT(g_bserrno == 0);
979 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
980 
981 	spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
982 	CU_ASSERT(g_bserrno == 0);
983 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
984 	blob = g_blob;
985 
986 	CU_ASSERT(blob->data_ro == true);
987 	CU_ASSERT(blob->md_ro == true);
988 	CU_ASSERT(blob->data_ro_flags & SPDK_BLOB_READ_ONLY);
989 
990 	spdk_blob_close(blob, 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 
996 }
997 
998 static void
999 channel_ops(void)
1000 {
1001 	struct spdk_blob_store *bs;
1002 	struct spdk_bs_dev *dev;
1003 	struct spdk_io_channel *channel;
1004 
1005 	dev = init_dev();
1006 
1007 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1008 	CU_ASSERT(g_bserrno == 0);
1009 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1010 	bs = g_bs;
1011 
1012 	channel = spdk_bs_alloc_io_channel(bs);
1013 	CU_ASSERT(channel != NULL);
1014 
1015 	spdk_bs_free_io_channel(channel);
1016 
1017 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1018 	CU_ASSERT(g_bserrno == 0);
1019 	g_bs = NULL;
1020 }
1021 
1022 static void
1023 blob_write(void)
1024 {
1025 	struct spdk_blob_store *bs;
1026 	struct spdk_bs_dev *dev;
1027 	struct spdk_blob *blob;
1028 	struct spdk_io_channel *channel;
1029 	spdk_blob_id blobid;
1030 	uint64_t pages_per_cluster;
1031 	uint8_t payload[10 * 4096];
1032 
1033 	dev = init_dev();
1034 
1035 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1036 	CU_ASSERT(g_bserrno == 0);
1037 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1038 	bs = g_bs;
1039 
1040 	pages_per_cluster = spdk_bs_get_cluster_size(bs) / spdk_bs_get_page_size(bs);
1041 
1042 	channel = spdk_bs_alloc_io_channel(bs);
1043 	CU_ASSERT(channel != NULL);
1044 
1045 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
1046 	CU_ASSERT(g_bserrno == 0);
1047 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1048 	blobid = g_blobid;
1049 
1050 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1051 	CU_ASSERT(g_bserrno == 0);
1052 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1053 	blob = g_blob;
1054 
1055 	/* Write to a blob with 0 size */
1056 	spdk_blob_io_write(blob, channel, payload, 0, 1, blob_op_complete, NULL);
1057 	CU_ASSERT(g_bserrno == -EINVAL);
1058 
1059 	/* Resize the blob */
1060 	spdk_blob_resize(blob, 5, blob_op_complete, NULL);
1061 	CU_ASSERT(g_bserrno == 0);
1062 
1063 	/* Confirm that write fails if blob is marked read-only. */
1064 	blob->data_ro = true;
1065 	spdk_blob_io_write(blob, channel, payload, 0, 1, blob_op_complete, NULL);
1066 	CU_ASSERT(g_bserrno == -EPERM);
1067 	blob->data_ro = false;
1068 
1069 	/* Write to the blob */
1070 	spdk_blob_io_write(blob, channel, payload, 0, 1, blob_op_complete, NULL);
1071 	CU_ASSERT(g_bserrno == 0);
1072 
1073 	/* Write starting beyond the end */
1074 	spdk_blob_io_write(blob, channel, payload, 5 * pages_per_cluster, 1, blob_op_complete,
1075 			   NULL);
1076 	CU_ASSERT(g_bserrno == -EINVAL);
1077 
1078 	/* Write starting at a valid location but going off the end */
1079 	spdk_blob_io_write(blob, channel, payload, 4 * pages_per_cluster, pages_per_cluster + 1,
1080 			   blob_op_complete, NULL);
1081 	CU_ASSERT(g_bserrno == -EINVAL);
1082 
1083 	spdk_blob_close(blob, blob_op_complete, NULL);
1084 	CU_ASSERT(g_bserrno == 0);
1085 
1086 	spdk_bs_free_io_channel(channel);
1087 
1088 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1089 	CU_ASSERT(g_bserrno == 0);
1090 	g_bs = NULL;
1091 }
1092 
1093 static void
1094 blob_read(void)
1095 {
1096 	struct spdk_blob_store *bs;
1097 	struct spdk_bs_dev *dev;
1098 	struct spdk_blob *blob;
1099 	struct spdk_io_channel *channel;
1100 	spdk_blob_id blobid;
1101 	uint64_t pages_per_cluster;
1102 	uint8_t payload[10 * 4096];
1103 
1104 	dev = init_dev();
1105 
1106 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1107 	CU_ASSERT(g_bserrno == 0);
1108 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1109 	bs = g_bs;
1110 
1111 	pages_per_cluster = spdk_bs_get_cluster_size(bs) / spdk_bs_get_page_size(bs);
1112 
1113 	channel = spdk_bs_alloc_io_channel(bs);
1114 	CU_ASSERT(channel != NULL);
1115 
1116 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
1117 	CU_ASSERT(g_bserrno == 0);
1118 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1119 	blobid = g_blobid;
1120 
1121 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1122 	CU_ASSERT(g_bserrno == 0);
1123 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1124 	blob = g_blob;
1125 
1126 	/* Read from a blob with 0 size */
1127 	spdk_blob_io_read(blob, channel, payload, 0, 1, blob_op_complete, NULL);
1128 	CU_ASSERT(g_bserrno == -EINVAL);
1129 
1130 	/* Resize the blob */
1131 	spdk_blob_resize(blob, 5, blob_op_complete, NULL);
1132 	CU_ASSERT(g_bserrno == 0);
1133 
1134 	/* Confirm that read passes if blob is marked read-only. */
1135 	blob->data_ro = true;
1136 	spdk_blob_io_read(blob, channel, payload, 0, 1, blob_op_complete, NULL);
1137 	CU_ASSERT(g_bserrno == 0);
1138 	blob->data_ro = false;
1139 
1140 	/* Read from the blob */
1141 	spdk_blob_io_read(blob, channel, payload, 0, 1, blob_op_complete, NULL);
1142 	CU_ASSERT(g_bserrno == 0);
1143 
1144 	/* Read starting beyond the end */
1145 	spdk_blob_io_read(blob, channel, payload, 5 * pages_per_cluster, 1, blob_op_complete,
1146 			  NULL);
1147 	CU_ASSERT(g_bserrno == -EINVAL);
1148 
1149 	/* Read starting at a valid location but going off the end */
1150 	spdk_blob_io_read(blob, channel, payload, 4 * pages_per_cluster, pages_per_cluster + 1,
1151 			  blob_op_complete, NULL);
1152 	CU_ASSERT(g_bserrno == -EINVAL);
1153 
1154 	spdk_blob_close(blob, blob_op_complete, NULL);
1155 	CU_ASSERT(g_bserrno == 0);
1156 
1157 	spdk_bs_free_io_channel(channel);
1158 
1159 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1160 	CU_ASSERT(g_bserrno == 0);
1161 	g_bs = NULL;
1162 }
1163 
1164 static void
1165 blob_rw_verify(void)
1166 {
1167 	struct spdk_blob_store *bs;
1168 	struct spdk_bs_dev *dev;
1169 	struct spdk_blob *blob;
1170 	struct spdk_io_channel *channel;
1171 	spdk_blob_id blobid;
1172 	uint8_t payload_read[10 * 4096];
1173 	uint8_t payload_write[10 * 4096];
1174 
1175 	dev = init_dev();
1176 
1177 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1178 	CU_ASSERT(g_bserrno == 0);
1179 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1180 	bs = g_bs;
1181 
1182 	channel = spdk_bs_alloc_io_channel(bs);
1183 	CU_ASSERT(channel != NULL);
1184 
1185 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
1186 	CU_ASSERT(g_bserrno == 0);
1187 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1188 	blobid = g_blobid;
1189 
1190 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1191 	CU_ASSERT(g_bserrno == 0);
1192 	CU_ASSERT(g_blob != NULL);
1193 	blob = g_blob;
1194 
1195 	spdk_blob_resize(blob, 32, blob_op_complete, NULL);
1196 	CU_ASSERT(g_bserrno == 0);
1197 
1198 	memset(payload_write, 0xE5, sizeof(payload_write));
1199 	spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL);
1200 	CU_ASSERT(g_bserrno == 0);
1201 
1202 	memset(payload_read, 0x00, sizeof(payload_read));
1203 	spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL);
1204 	CU_ASSERT(g_bserrno == 0);
1205 	CU_ASSERT(memcmp(payload_write, payload_read, 4 * 4096) == 0);
1206 
1207 	spdk_blob_close(blob, blob_op_complete, NULL);
1208 	CU_ASSERT(g_bserrno == 0);
1209 
1210 	spdk_bs_free_io_channel(channel);
1211 
1212 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1213 	CU_ASSERT(g_bserrno == 0);
1214 	g_bs = NULL;
1215 }
1216 
1217 static void
1218 blob_rw_verify_iov(void)
1219 {
1220 	struct spdk_blob_store *bs;
1221 	struct spdk_bs_dev *dev;
1222 	struct spdk_blob *blob;
1223 	struct spdk_io_channel *channel;
1224 	spdk_blob_id blobid;
1225 	uint8_t payload_read[10 * 4096];
1226 	uint8_t payload_write[10 * 4096];
1227 	struct iovec iov_read[3];
1228 	struct iovec iov_write[3];
1229 	void *buf;
1230 
1231 	dev = init_dev();
1232 	memset(g_dev_buffer, 0, DEV_BUFFER_SIZE);
1233 
1234 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1235 	CU_ASSERT(g_bserrno == 0);
1236 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1237 	bs = g_bs;
1238 
1239 	channel = spdk_bs_alloc_io_channel(bs);
1240 	CU_ASSERT(channel != NULL);
1241 
1242 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
1243 	CU_ASSERT(g_bserrno == 0);
1244 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1245 	blobid = g_blobid;
1246 
1247 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1248 	CU_ASSERT(g_bserrno == 0);
1249 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1250 	blob = g_blob;
1251 
1252 	spdk_blob_resize(blob, 2, blob_op_complete, NULL);
1253 	CU_ASSERT(g_bserrno == 0);
1254 
1255 	/*
1256 	 * Manually adjust the offset of the blob's second cluster.  This allows
1257 	 *  us to make sure that the readv/write code correctly accounts for I/O
1258 	 *  that cross cluster boundaries.  Start by asserting that the allocated
1259 	 *  clusters are where we expect before modifying the second cluster.
1260 	 */
1261 	CU_ASSERT(blob->active.clusters[0] == 1 * 256);
1262 	CU_ASSERT(blob->active.clusters[1] == 2 * 256);
1263 	blob->active.clusters[1] = 3 * 256;
1264 
1265 	memset(payload_write, 0xE5, sizeof(payload_write));
1266 	iov_write[0].iov_base = payload_write;
1267 	iov_write[0].iov_len = 1 * 4096;
1268 	iov_write[1].iov_base = payload_write + 1 * 4096;
1269 	iov_write[1].iov_len = 5 * 4096;
1270 	iov_write[2].iov_base = payload_write + 6 * 4096;
1271 	iov_write[2].iov_len = 4 * 4096;
1272 	/*
1273 	 * Choose a page offset just before the cluster boundary.  The first 6 pages of payload
1274 	 *  will get written to the first cluster, the last 4 to the second cluster.
1275 	 */
1276 	spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL);
1277 	CU_ASSERT(g_bserrno == 0);
1278 
1279 	memset(payload_read, 0xAA, sizeof(payload_read));
1280 	iov_read[0].iov_base = payload_read;
1281 	iov_read[0].iov_len = 3 * 4096;
1282 	iov_read[1].iov_base = payload_read + 3 * 4096;
1283 	iov_read[1].iov_len = 4 * 4096;
1284 	iov_read[2].iov_base = payload_read + 7 * 4096;
1285 	iov_read[2].iov_len = 3 * 4096;
1286 	spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL);
1287 	CU_ASSERT(g_bserrno == 0);
1288 	CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0);
1289 
1290 	buf = calloc(1, 256 * 4096);
1291 	SPDK_CU_ASSERT_FATAL(buf != NULL);
1292 	/* Check that cluster 2 on "disk" was not modified. */
1293 	CU_ASSERT(memcmp(buf, &g_dev_buffer[512 * 4096], 256 * 4096) == 0);
1294 	free(buf);
1295 
1296 	spdk_blob_close(blob, blob_op_complete, NULL);
1297 	CU_ASSERT(g_bserrno == 0);
1298 
1299 	spdk_bs_free_io_channel(channel);
1300 
1301 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1302 	CU_ASSERT(g_bserrno == 0);
1303 	g_bs = NULL;
1304 }
1305 
1306 static uint32_t
1307 bs_channel_get_req_count(struct spdk_io_channel *_channel)
1308 {
1309 	struct spdk_bs_channel *channel = spdk_io_channel_get_ctx(_channel);
1310 	struct spdk_bs_request_set *set;
1311 	uint32_t count = 0;
1312 
1313 	TAILQ_FOREACH(set, &channel->reqs, link) {
1314 		count++;
1315 	}
1316 
1317 	return count;
1318 }
1319 
1320 static void
1321 blob_rw_verify_iov_nomem(void)
1322 {
1323 	struct spdk_blob_store *bs;
1324 	struct spdk_bs_dev *dev;
1325 	struct spdk_blob *blob;
1326 	struct spdk_io_channel *channel;
1327 	spdk_blob_id blobid;
1328 	uint8_t payload_write[10 * 4096];
1329 	struct iovec iov_write[3];
1330 	uint32_t req_count;
1331 
1332 	dev = init_dev();
1333 	memset(g_dev_buffer, 0, DEV_BUFFER_SIZE);
1334 
1335 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1336 	CU_ASSERT(g_bserrno == 0);
1337 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1338 	bs = g_bs;
1339 
1340 	channel = spdk_bs_alloc_io_channel(bs);
1341 	CU_ASSERT(channel != NULL);
1342 
1343 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
1344 	CU_ASSERT(g_bserrno == 0);
1345 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1346 	blobid = g_blobid;
1347 
1348 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1349 	CU_ASSERT(g_bserrno == 0);
1350 	CU_ASSERT(g_blob != NULL);
1351 	blob = g_blob;
1352 
1353 	spdk_blob_resize(blob, 2, blob_op_complete, NULL);
1354 	CU_ASSERT(g_bserrno == 0);
1355 
1356 	/*
1357 	 * Choose a page offset just before the cluster boundary.  The first 6 pages of payload
1358 	 *  will get written to the first cluster, the last 4 to the second cluster.
1359 	 */
1360 	iov_write[0].iov_base = payload_write;
1361 	iov_write[0].iov_len = 1 * 4096;
1362 	iov_write[1].iov_base = payload_write + 1 * 4096;
1363 	iov_write[1].iov_len = 5 * 4096;
1364 	iov_write[2].iov_base = payload_write + 6 * 4096;
1365 	iov_write[2].iov_len = 4 * 4096;
1366 	MOCK_SET(calloc, void *, NULL);
1367 	req_count = bs_channel_get_req_count(channel);
1368 	spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL);
1369 	CU_ASSERT(g_bserrno = -ENOMEM);
1370 	CU_ASSERT(req_count == bs_channel_get_req_count(channel));
1371 	MOCK_SET(calloc, void *, (void *)MOCK_PASS_THRU);
1372 
1373 	spdk_blob_close(blob, blob_op_complete, NULL);
1374 	CU_ASSERT(g_bserrno == 0);
1375 
1376 	spdk_bs_free_io_channel(channel);
1377 
1378 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1379 	CU_ASSERT(g_bserrno == 0);
1380 	g_bs = NULL;
1381 }
1382 
1383 static void
1384 blob_rw_iov_read_only(void)
1385 {
1386 	struct spdk_blob_store *bs;
1387 	struct spdk_bs_dev *dev;
1388 	struct spdk_blob *blob;
1389 	struct spdk_io_channel *channel;
1390 	spdk_blob_id blobid;
1391 	uint8_t payload_read[4096];
1392 	uint8_t payload_write[4096];
1393 	struct iovec iov_read;
1394 	struct iovec iov_write;
1395 
1396 	dev = init_dev();
1397 	memset(g_dev_buffer, 0, DEV_BUFFER_SIZE);
1398 
1399 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1400 	CU_ASSERT(g_bserrno == 0);
1401 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1402 	bs = g_bs;
1403 
1404 	channel = spdk_bs_alloc_io_channel(bs);
1405 	CU_ASSERT(channel != NULL);
1406 
1407 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
1408 	CU_ASSERT(g_bserrno == 0);
1409 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1410 	blobid = g_blobid;
1411 
1412 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1413 	CU_ASSERT(g_bserrno == 0);
1414 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1415 	blob = g_blob;
1416 
1417 	spdk_blob_resize(blob, 2, blob_op_complete, NULL);
1418 	CU_ASSERT(g_bserrno == 0);
1419 
1420 	/* Verify that writev failed if read_only flag is set. */
1421 	blob->data_ro = true;
1422 	iov_write.iov_base = payload_write;
1423 	iov_write.iov_len = sizeof(payload_write);
1424 	spdk_blob_io_writev(blob, channel, &iov_write, 1, 0, 1, blob_op_complete, NULL);
1425 	CU_ASSERT(g_bserrno == -EPERM);
1426 
1427 	/* Verify that reads pass if data_ro flag is set. */
1428 	iov_read.iov_base = payload_read;
1429 	iov_read.iov_len = sizeof(payload_read);
1430 	spdk_blob_io_readv(blob, channel, &iov_read, 1, 0, 1, blob_op_complete, NULL);
1431 	CU_ASSERT(g_bserrno == 0);
1432 
1433 	spdk_blob_close(blob, blob_op_complete, NULL);
1434 	CU_ASSERT(g_bserrno == 0);
1435 
1436 	spdk_bs_free_io_channel(channel);
1437 
1438 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1439 	CU_ASSERT(g_bserrno == 0);
1440 	g_bs = NULL;
1441 }
1442 
1443 static void
1444 blob_unmap(void)
1445 {
1446 	struct spdk_blob_store *bs;
1447 	struct spdk_bs_dev *dev;
1448 	struct spdk_blob *blob;
1449 	struct spdk_io_channel *channel;
1450 	spdk_blob_id blobid;
1451 	struct spdk_blob_opts opts;
1452 	uint8_t payload[4096];
1453 	int i;
1454 
1455 	dev = init_dev();
1456 
1457 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1458 	CU_ASSERT(g_bserrno == 0);
1459 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1460 	bs = g_bs;
1461 
1462 	channel = spdk_bs_alloc_io_channel(bs);
1463 	CU_ASSERT(channel != NULL);
1464 
1465 	spdk_blob_opts_init(&opts);
1466 	opts.num_clusters = 10;
1467 
1468 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
1469 	CU_ASSERT(g_bserrno == 0);
1470 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1471 	blobid = g_blobid;
1472 
1473 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1474 	CU_ASSERT(g_bserrno == 0);
1475 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1476 	blob = g_blob;
1477 
1478 	spdk_blob_resize(blob, 10, blob_op_complete, NULL);
1479 	CU_ASSERT(g_bserrno == 0);
1480 
1481 	memset(payload, 0, sizeof(payload));
1482 	payload[0] = 0xFF;
1483 
1484 	/*
1485 	 * Set first byte of every cluster to 0xFF.
1486 	 * First cluster on device is reserved so let's start from cluster number 1
1487 	 */
1488 	for (i = 1; i < 11; i++) {
1489 		g_dev_buffer[i * SPDK_BLOB_OPTS_CLUSTER_SZ] = 0xFF;
1490 	}
1491 
1492 	/* Confirm writes */
1493 	for (i = 0; i < 10; i++) {
1494 		payload[0] = 0;
1495 		spdk_blob_io_read(blob, channel, &payload, i * SPDK_BLOB_OPTS_CLUSTER_SZ / 4096, 1,
1496 				  blob_op_complete, NULL);
1497 		CU_ASSERT(g_bserrno == 0);
1498 		CU_ASSERT(payload[0] == 0xFF);
1499 	}
1500 
1501 	/* Mark some clusters as unallocated */
1502 	blob->active.clusters[1] = 0;
1503 	blob->active.clusters[2] = 0;
1504 	blob->active.clusters[3] = 0;
1505 	blob->active.clusters[6] = 0;
1506 	blob->active.clusters[8] = 0;
1507 
1508 	/* Unmap clusters by resizing to 0 */
1509 	spdk_blob_resize(blob, 0, blob_op_complete, NULL);
1510 	CU_ASSERT(g_bserrno == 0);
1511 
1512 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
1513 	CU_ASSERT(g_bserrno == 0);
1514 
1515 	/* Confirm that only 'allocated' clusters were unmaped */
1516 	for (i = 1; i < 11; i++) {
1517 		switch (i) {
1518 		case 2:
1519 		case 3:
1520 		case 4:
1521 		case 7:
1522 		case 9:
1523 			CU_ASSERT(g_dev_buffer[i * SPDK_BLOB_OPTS_CLUSTER_SZ] == 0xFF);
1524 			break;
1525 		default:
1526 			CU_ASSERT(g_dev_buffer[i * SPDK_BLOB_OPTS_CLUSTER_SZ] == 0);
1527 			break;
1528 		}
1529 	}
1530 
1531 	spdk_blob_close(blob, blob_op_complete, NULL);
1532 	CU_ASSERT(g_bserrno == 0);
1533 
1534 	spdk_bs_free_io_channel(channel);
1535 
1536 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1537 	CU_ASSERT(g_bserrno == 0);
1538 	g_bs = NULL;
1539 }
1540 
1541 
1542 static void
1543 blob_iter(void)
1544 {
1545 	struct spdk_blob_store *bs;
1546 	struct spdk_bs_dev *dev;
1547 	struct spdk_blob *blob;
1548 	spdk_blob_id blobid;
1549 
1550 	dev = init_dev();
1551 
1552 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1553 	CU_ASSERT(g_bserrno == 0);
1554 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1555 	bs = g_bs;
1556 
1557 	spdk_bs_iter_first(bs, blob_op_with_handle_complete, NULL);
1558 	CU_ASSERT(g_blob == NULL);
1559 	CU_ASSERT(g_bserrno == -ENOENT);
1560 
1561 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
1562 	CU_ASSERT(g_bserrno == 0);
1563 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1564 	blobid = g_blobid;
1565 
1566 	spdk_bs_iter_first(bs, blob_op_with_handle_complete, NULL);
1567 	CU_ASSERT(g_blob != NULL);
1568 	CU_ASSERT(g_bserrno == 0);
1569 	blob = g_blob;
1570 	CU_ASSERT(spdk_blob_get_id(blob) == blobid);
1571 
1572 	spdk_bs_iter_next(bs, blob, blob_op_with_handle_complete, NULL);
1573 	CU_ASSERT(g_blob == NULL);
1574 	CU_ASSERT(g_bserrno == -ENOENT);
1575 
1576 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1577 	CU_ASSERT(g_bserrno == 0);
1578 	g_bs = NULL;
1579 }
1580 
1581 static void
1582 blob_xattr(void)
1583 {
1584 	struct spdk_blob_store *bs;
1585 	struct spdk_bs_dev *dev;
1586 	struct spdk_blob *blob;
1587 	spdk_blob_id blobid;
1588 	uint64_t length;
1589 	int rc;
1590 	const char *name1, *name2;
1591 	const void *value;
1592 	size_t value_len;
1593 	struct spdk_xattr_names *names;
1594 
1595 	dev = init_dev();
1596 
1597 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1598 	CU_ASSERT(g_bserrno == 0);
1599 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1600 	bs = g_bs;
1601 
1602 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
1603 	CU_ASSERT(g_bserrno == 0);
1604 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1605 	blobid = g_blobid;
1606 
1607 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1608 	CU_ASSERT(g_bserrno == 0);
1609 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1610 	blob = g_blob;
1611 
1612 	/* Test that set_xattr fails if md_ro flag is set. */
1613 	blob->md_ro = true;
1614 	rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1);
1615 	CU_ASSERT(rc == -EPERM);
1616 
1617 	blob->md_ro = false;
1618 	rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1);
1619 	CU_ASSERT(rc == 0);
1620 
1621 	length = 2345;
1622 	rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
1623 	CU_ASSERT(rc == 0);
1624 
1625 	/* Overwrite "length" xattr. */
1626 	length = 3456;
1627 	rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
1628 	CU_ASSERT(rc == 0);
1629 
1630 	/* get_xattr should still work even if md_ro flag is set. */
1631 	value = NULL;
1632 	blob->md_ro = true;
1633 	rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len);
1634 	CU_ASSERT(rc == 0);
1635 	SPDK_CU_ASSERT_FATAL(value != NULL);
1636 	CU_ASSERT(*(uint64_t *)value == length);
1637 	CU_ASSERT(value_len == 8);
1638 	blob->md_ro = false;
1639 
1640 	rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len);
1641 	CU_ASSERT(rc == -ENOENT);
1642 
1643 	names = NULL;
1644 	rc = spdk_blob_get_xattr_names(blob, &names);
1645 	CU_ASSERT(rc == 0);
1646 	SPDK_CU_ASSERT_FATAL(names != NULL);
1647 	CU_ASSERT(spdk_xattr_names_get_count(names) == 2);
1648 	name1 = spdk_xattr_names_get_name(names, 0);
1649 	SPDK_CU_ASSERT_FATAL(name1 != NULL);
1650 	CU_ASSERT(!strcmp(name1, "name") || !strcmp(name1, "length"));
1651 	name2 = spdk_xattr_names_get_name(names, 1);
1652 	SPDK_CU_ASSERT_FATAL(name2 != NULL);
1653 	CU_ASSERT(!strcmp(name2, "name") || !strcmp(name2, "length"));
1654 	CU_ASSERT(strcmp(name1, name2));
1655 	spdk_xattr_names_free(names);
1656 
1657 	/* Confirm that remove_xattr fails if md_ro is set to true. */
1658 	blob->md_ro = true;
1659 	rc = spdk_blob_remove_xattr(blob, "name");
1660 	CU_ASSERT(rc == -EPERM);
1661 
1662 	blob->md_ro = false;
1663 	rc = spdk_blob_remove_xattr(blob, "name");
1664 	CU_ASSERT(rc == 0);
1665 
1666 	rc = spdk_blob_remove_xattr(blob, "foobar");
1667 	CU_ASSERT(rc == -ENOENT);
1668 
1669 	/* Set internal xattr */
1670 	length = 7898;
1671 	rc = _spdk_blob_set_xattr(blob, "internal", &length, sizeof(length), true);
1672 	CU_ASSERT(rc == 0);
1673 	rc = _spdk_blob_get_xattr_value(blob, "internal", &value, &value_len, true);
1674 	CU_ASSERT(rc == 0);
1675 	CU_ASSERT(*(uint64_t *)value == length);
1676 	/* try to get public xattr with same name */
1677 	rc = spdk_blob_get_xattr_value(blob, "internal", &value, &value_len);
1678 	CU_ASSERT(rc != 0);
1679 	rc = _spdk_blob_get_xattr_value(blob, "internal", &value, &value_len, false);
1680 	CU_ASSERT(rc != 0);
1681 	/* Check if SPDK_BLOB_INTERNAL_XATTR is set */
1682 	CU_ASSERT((blob->invalid_flags & SPDK_BLOB_INTERNAL_XATTR) ==
1683 		  SPDK_BLOB_INTERNAL_XATTR)
1684 
1685 	spdk_blob_close(blob, blob_op_complete, NULL);
1686 
1687 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1688 
1689 	/* Check if xattrs are persisted */
1690 	dev = init_dev();
1691 
1692 	spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL);
1693 	CU_ASSERT(g_bserrno == 0);
1694 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1695 
1696 	bs = g_bs;
1697 
1698 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1699 	CU_ASSERT(g_bserrno == 0);
1700 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1701 	blob = g_blob;
1702 
1703 	rc = _spdk_blob_get_xattr_value(blob, "internal", &value, &value_len, true);
1704 	CU_ASSERT(rc == 0);
1705 	CU_ASSERT(*(uint64_t *)value == length);
1706 
1707 	/* try to get internal xattr trough public call */
1708 	rc = spdk_blob_get_xattr_value(blob, "internal", &value, &value_len);
1709 	CU_ASSERT(rc != 0);
1710 
1711 	rc = _spdk_blob_remove_xattr(blob, "internal", true);
1712 	CU_ASSERT(rc == 0);
1713 
1714 	CU_ASSERT((blob->invalid_flags & SPDK_BLOB_INTERNAL_XATTR) == 0);
1715 
1716 	CU_ASSERT(g_bserrno == 0);
1717 	g_bs = NULL;
1718 }
1719 
1720 static void
1721 bs_load(void)
1722 {
1723 	struct spdk_bs_dev *dev;
1724 	spdk_blob_id blobid;
1725 	struct spdk_blob *blob;
1726 	struct spdk_bs_super_block *super_block;
1727 	uint64_t length;
1728 	int rc;
1729 	const void *value;
1730 	size_t value_len;
1731 	struct spdk_bs_opts opts;
1732 
1733 	dev = init_dev();
1734 	spdk_bs_opts_init(&opts);
1735 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
1736 
1737 	/* Initialize a new blob store */
1738 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
1739 	CU_ASSERT(g_bserrno == 0);
1740 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1741 
1742 	/* Try to open a blobid that does not exist */
1743 	spdk_bs_open_blob(g_bs, 0, blob_op_with_handle_complete, NULL);
1744 	CU_ASSERT(g_bserrno == -ENOENT);
1745 	CU_ASSERT(g_blob == NULL);
1746 
1747 	/* Create a blob */
1748 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
1749 	CU_ASSERT(g_bserrno == 0);
1750 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1751 	blobid = g_blobid;
1752 
1753 	spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
1754 	CU_ASSERT(g_bserrno == 0);
1755 	CU_ASSERT(g_blob != NULL);
1756 	blob = g_blob;
1757 
1758 	/* Try again to open valid blob but without the upper bit set */
1759 	spdk_bs_open_blob(g_bs, blobid & 0xFFFFFFFF, blob_op_with_handle_complete, NULL);
1760 	CU_ASSERT(g_bserrno == -ENOENT);
1761 	CU_ASSERT(g_blob == NULL);
1762 
1763 	/* Set some xattrs */
1764 	rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1);
1765 	CU_ASSERT(rc == 0);
1766 
1767 	length = 2345;
1768 	rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
1769 	CU_ASSERT(rc == 0);
1770 
1771 	/* Resize the blob */
1772 	spdk_blob_resize(blob, 10, blob_op_complete, NULL);
1773 	CU_ASSERT(g_bserrno == 0);
1774 
1775 	spdk_blob_close(blob, blob_op_complete, NULL);
1776 	CU_ASSERT(g_bserrno == 0);
1777 	blob = NULL;
1778 	g_blob = NULL;
1779 	g_blobid = SPDK_BLOBID_INVALID;
1780 
1781 	/* Unload the blob store */
1782 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1783 	CU_ASSERT(g_bserrno == 0);
1784 	g_bs = NULL;
1785 	g_blob = NULL;
1786 	g_blobid = 0;
1787 
1788 	super_block = (struct spdk_bs_super_block *)g_dev_buffer;
1789 	CU_ASSERT(super_block->clean == 1);
1790 
1791 	/* Load should fail for device with an unsupported blocklen */
1792 	dev = init_dev();
1793 	dev->blocklen = SPDK_BS_PAGE_SIZE * 2;
1794 	spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL);
1795 	CU_ASSERT(g_bserrno == -EINVAL);
1796 
1797 	/* Load should when max_md_ops is set to zero */
1798 	dev = init_dev();
1799 	spdk_bs_opts_init(&opts);
1800 	opts.max_md_ops = 0;
1801 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1802 	CU_ASSERT(g_bserrno == -EINVAL);
1803 
1804 	/* Load should when max_channel_ops is set to zero */
1805 	dev = init_dev();
1806 	spdk_bs_opts_init(&opts);
1807 	opts.max_channel_ops = 0;
1808 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1809 	CU_ASSERT(g_bserrno == -EINVAL);
1810 
1811 	/* Load an existing blob store */
1812 	dev = init_dev();
1813 	spdk_bs_opts_init(&opts);
1814 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
1815 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1816 	CU_ASSERT(g_bserrno == 0);
1817 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1818 
1819 	super_block = (struct spdk_bs_super_block *)g_dev_buffer;
1820 	CU_ASSERT(super_block->clean == 0);
1821 
1822 	spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
1823 	CU_ASSERT(g_bserrno == 0);
1824 	CU_ASSERT(g_blob != NULL);
1825 	blob = g_blob;
1826 
1827 	/* Get the xattrs */
1828 	value = NULL;
1829 	rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len);
1830 	CU_ASSERT(rc == 0);
1831 	SPDK_CU_ASSERT_FATAL(value != NULL);
1832 	CU_ASSERT(*(uint64_t *)value == length);
1833 	CU_ASSERT(value_len == 8);
1834 
1835 	rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len);
1836 	CU_ASSERT(rc == -ENOENT);
1837 
1838 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10);
1839 
1840 	spdk_blob_close(blob, blob_op_complete, NULL);
1841 	CU_ASSERT(g_bserrno == 0);
1842 	blob = NULL;
1843 	g_blob = NULL;
1844 	g_blobid = SPDK_BLOBID_INVALID;
1845 
1846 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1847 	CU_ASSERT(g_bserrno == 0);
1848 	g_bs = NULL;
1849 }
1850 
1851 static void
1852 bs_type(void)
1853 {
1854 	struct spdk_bs_dev *dev;
1855 	struct spdk_bs_opts opts;
1856 
1857 	dev = init_dev();
1858 	spdk_bs_opts_init(&opts);
1859 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
1860 
1861 	/* Initialize a new blob store */
1862 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
1863 	CU_ASSERT(g_bserrno == 0);
1864 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1865 
1866 	/* Unload the blob store */
1867 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1868 	CU_ASSERT(g_bserrno == 0);
1869 	g_bs = NULL;
1870 	g_blob = NULL;
1871 	g_blobid = 0;
1872 
1873 	/* Load non existing blobstore type */
1874 	dev = init_dev();
1875 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "NONEXISTING");
1876 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1877 	CU_ASSERT(g_bserrno != 0);
1878 
1879 	/* Load with empty blobstore type */
1880 	dev = init_dev();
1881 	memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype));
1882 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1883 	CU_ASSERT(g_bserrno == 0);
1884 
1885 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1886 	CU_ASSERT(g_bserrno == 0);
1887 	g_bs = NULL;
1888 
1889 	/* Initialize a new blob store with empty bstype */
1890 	dev = init_dev();
1891 	memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype));
1892 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1893 	CU_ASSERT(g_bserrno == 0);
1894 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1895 
1896 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1897 	CU_ASSERT(g_bserrno == 0);
1898 	g_bs = NULL;
1899 
1900 	/* Load non existing blobstore type */
1901 	dev = init_dev();
1902 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "NONEXISTING");
1903 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1904 	CU_ASSERT(g_bserrno != 0);
1905 
1906 	/* Load with empty blobstore type */
1907 	dev = init_dev();
1908 	memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype));
1909 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1910 	CU_ASSERT(g_bserrno == 0);
1911 
1912 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1913 	CU_ASSERT(g_bserrno == 0);
1914 	g_bs = NULL;
1915 }
1916 
1917 static void
1918 bs_super_block(void)
1919 {
1920 	struct spdk_bs_dev *dev;
1921 	struct spdk_bs_super_block *super_block;
1922 	struct spdk_bs_opts opts;
1923 	struct spdk_bs_super_block_ver1 super_block_v1;
1924 
1925 	dev = init_dev();
1926 	spdk_bs_opts_init(&opts);
1927 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
1928 
1929 	/* Initialize a new blob store */
1930 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
1931 	CU_ASSERT(g_bserrno == 0);
1932 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1933 
1934 	/* Unload the blob store */
1935 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1936 	CU_ASSERT(g_bserrno == 0);
1937 	g_bs = NULL;
1938 	g_blob = NULL;
1939 	g_blobid = 0;
1940 
1941 	/* Load an existing blob store with version newer than supported */
1942 	super_block = (struct spdk_bs_super_block *)g_dev_buffer;
1943 	super_block->version++;
1944 
1945 	dev = init_dev();
1946 	memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype));
1947 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1948 	CU_ASSERT(g_bserrno != 0);
1949 
1950 	/* Create a new blob store with super block version 1 */
1951 	dev = init_dev();
1952 	super_block_v1.version = 1;
1953 	memcpy(super_block_v1.signature, "SPDKBLOB", sizeof(super_block_v1.signature));
1954 	super_block_v1.length = 0x1000;
1955 	super_block_v1.clean = 1;
1956 	super_block_v1.super_blob = 0xFFFFFFFFFFFFFFFF;
1957 	super_block_v1.cluster_size = 0x100000;
1958 	super_block_v1.used_page_mask_start = 0x01;
1959 	super_block_v1.used_page_mask_len = 0x01;
1960 	super_block_v1.used_cluster_mask_start = 0x02;
1961 	super_block_v1.used_cluster_mask_len = 0x01;
1962 	super_block_v1.md_start = 0x03;
1963 	super_block_v1.md_len = 0x40;
1964 	memset(super_block_v1.reserved, 0, 4036);
1965 	super_block_v1.crc = _spdk_blob_md_page_calc_crc(&super_block_v1);
1966 	memcpy(g_dev_buffer, &super_block_v1, sizeof(struct spdk_bs_super_block_ver1));
1967 
1968 	memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype));
1969 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1970 	CU_ASSERT(g_bserrno == 0);
1971 
1972 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1973 	CU_ASSERT(g_bserrno == 0);
1974 	g_bs = NULL;
1975 }
1976 
1977 /*
1978  * Create a blobstore and then unload it.
1979  */
1980 static void
1981 bs_unload(void)
1982 {
1983 	struct spdk_bs_dev *dev;
1984 	struct spdk_blob_store *bs;
1985 	spdk_blob_id blobid;
1986 	struct spdk_blob *blob;
1987 
1988 	dev = init_dev();
1989 
1990 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1991 	CU_ASSERT(g_bserrno == 0);
1992 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1993 	bs = g_bs;
1994 
1995 	/* Create a blob and open it. */
1996 	g_bserrno = -1;
1997 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
1998 	CU_ASSERT(g_bserrno == 0);
1999 	CU_ASSERT(g_blobid > 0);
2000 	blobid = g_blobid;
2001 
2002 	g_bserrno = -1;
2003 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
2004 	CU_ASSERT(g_bserrno == 0);
2005 	CU_ASSERT(g_blob != NULL);
2006 	blob = g_blob;
2007 
2008 	/* Try to unload blobstore, should fail with open blob */
2009 	g_bserrno = -1;
2010 	spdk_bs_unload(bs, bs_op_complete, NULL);
2011 	CU_ASSERT(g_bserrno == -EBUSY);
2012 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2013 
2014 	/* Close the blob, then successfully unload blobstore */
2015 	g_bserrno = -1;
2016 	spdk_blob_close(blob, blob_op_complete, NULL);
2017 	CU_ASSERT(g_bserrno == 0);
2018 
2019 	g_bserrno = -1;
2020 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2021 	CU_ASSERT(g_bserrno == 0);
2022 	g_bs = NULL;
2023 }
2024 
2025 /*
2026  * Create a blobstore with a cluster size different than the default, and ensure it is
2027  *  persisted.
2028  */
2029 static void
2030 bs_cluster_sz(void)
2031 {
2032 	struct spdk_bs_dev *dev;
2033 	struct spdk_bs_opts opts;
2034 	uint32_t cluster_sz;
2035 
2036 	/* Set cluster size to zero */
2037 	dev = init_dev();
2038 	spdk_bs_opts_init(&opts);
2039 	opts.cluster_sz = 0;
2040 
2041 	/* Initialize a new blob store */
2042 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2043 	CU_ASSERT(g_bserrno == -EINVAL);
2044 	SPDK_CU_ASSERT_FATAL(g_bs == NULL);
2045 
2046 	/*
2047 	 * Set cluster size to blobstore page size,
2048 	 * to work it is required to be at least twice the blobstore page size.
2049 	 */
2050 	dev = init_dev();
2051 	spdk_bs_opts_init(&opts);
2052 	opts.cluster_sz = SPDK_BS_PAGE_SIZE;
2053 
2054 	/* Initialize a new blob store */
2055 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2056 	CU_ASSERT(g_bserrno == -ENOMEM);
2057 	SPDK_CU_ASSERT_FATAL(g_bs == NULL);
2058 
2059 	/*
2060 	 * Set cluster size to lower than page size,
2061 	 * to work it is required to be at least twice the blobstore page size.
2062 	 */
2063 	dev = init_dev();
2064 	spdk_bs_opts_init(&opts);
2065 	opts.cluster_sz = SPDK_BS_PAGE_SIZE - 1;
2066 
2067 	/* Initialize a new blob store */
2068 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2069 	CU_ASSERT(g_bserrno == -ENOMEM);
2070 	SPDK_CU_ASSERT_FATAL(g_bs == NULL);
2071 
2072 	/* Set cluster size to twice the default */
2073 	dev = init_dev();
2074 	spdk_bs_opts_init(&opts);
2075 	opts.cluster_sz *= 2;
2076 	cluster_sz = opts.cluster_sz;
2077 
2078 	/* Initialize a new blob store */
2079 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2080 	CU_ASSERT(g_bserrno == 0);
2081 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2082 
2083 	CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz);
2084 
2085 	/* Unload the blob store */
2086 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2087 	CU_ASSERT(g_bserrno == 0);
2088 	g_bs = NULL;
2089 	g_blob = NULL;
2090 	g_blobid = 0;
2091 
2092 	dev = init_dev();
2093 	/* Load an existing blob store */
2094 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2095 	CU_ASSERT(g_bserrno == 0);
2096 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2097 
2098 	CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz);
2099 
2100 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2101 	CU_ASSERT(g_bserrno == 0);
2102 	g_bs = NULL;
2103 }
2104 
2105 /*
2106  * Create a blobstore, reload it and ensure total usable cluster count
2107  *  stays the same.
2108  */
2109 static void
2110 bs_usable_clusters(void)
2111 {
2112 	struct spdk_bs_dev *dev;
2113 	struct spdk_bs_opts opts;
2114 	uint32_t clusters;
2115 	int i;
2116 
2117 	/* Init blobstore */
2118 	dev = init_dev();
2119 	spdk_bs_opts_init(&opts);
2120 
2121 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2122 	CU_ASSERT(g_bserrno == 0);
2123 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2124 
2125 	clusters = spdk_bs_total_data_cluster_count(g_bs);
2126 
2127 	/* Unload the blob store */
2128 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2129 	CU_ASSERT(g_bserrno == 0);
2130 	g_bs = NULL;
2131 
2132 	dev = init_dev();
2133 	/* Load an existing blob store */
2134 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2135 	CU_ASSERT(g_bserrno == 0);
2136 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2137 
2138 	CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters);
2139 
2140 	/* Create and resize blobs to make sure that useable cluster count won't change */
2141 	for (i = 0; i < 4; i++) {
2142 		g_bserrno = -1;
2143 		g_blobid = SPDK_BLOBID_INVALID;
2144 		spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
2145 		CU_ASSERT(g_bserrno == 0);
2146 		CU_ASSERT(g_blobid !=  SPDK_BLOBID_INVALID);
2147 
2148 		g_bserrno = -1;
2149 		g_blob = NULL;
2150 		spdk_bs_open_blob(g_bs, g_blobid, blob_op_with_handle_complete, NULL);
2151 		CU_ASSERT(g_bserrno == 0);
2152 		CU_ASSERT(g_blob !=  NULL);
2153 
2154 		spdk_blob_resize(g_blob, 10, blob_op_complete, NULL);
2155 		CU_ASSERT(g_bserrno == 0);
2156 
2157 		g_bserrno = -1;
2158 		spdk_blob_close(g_blob, blob_op_complete, NULL);
2159 		CU_ASSERT(g_bserrno == 0);
2160 
2161 		CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters);
2162 	}
2163 
2164 	/* Reload the blob store to make sure that nothing changed */
2165 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2166 	CU_ASSERT(g_bserrno == 0);
2167 	g_bs = NULL;
2168 
2169 	dev = init_dev();
2170 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2171 	CU_ASSERT(g_bserrno == 0);
2172 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2173 
2174 	CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters);
2175 
2176 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2177 	CU_ASSERT(g_bserrno == 0);
2178 	g_bs = NULL;
2179 }
2180 
2181 /*
2182  * Test resizing of the metadata blob.  This requires creating enough blobs
2183  *  so that one cluster is not enough to fit the metadata for those blobs.
2184  *  To induce this condition to happen more quickly, we reduce the cluster
2185  *  size to 16KB, which means only 4 4KB blob metadata pages can fit.
2186  */
2187 static void
2188 bs_resize_md(void)
2189 {
2190 	const int CLUSTER_PAGE_COUNT = 4;
2191 	const int NUM_BLOBS = CLUSTER_PAGE_COUNT * 4;
2192 	struct spdk_bs_dev *dev;
2193 	struct spdk_bs_opts opts;
2194 	uint32_t cluster_sz;
2195 	spdk_blob_id blobids[NUM_BLOBS];
2196 	int i;
2197 
2198 
2199 	dev = init_dev();
2200 	spdk_bs_opts_init(&opts);
2201 	opts.cluster_sz = CLUSTER_PAGE_COUNT * 4096;
2202 	cluster_sz = opts.cluster_sz;
2203 
2204 	/* Initialize a new blob store */
2205 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2206 	CU_ASSERT(g_bserrno == 0);
2207 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2208 
2209 	CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz);
2210 
2211 	for (i = 0; i < NUM_BLOBS; i++) {
2212 		g_bserrno = -1;
2213 		g_blobid = SPDK_BLOBID_INVALID;
2214 		spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
2215 		CU_ASSERT(g_bserrno == 0);
2216 		CU_ASSERT(g_blobid !=  SPDK_BLOBID_INVALID);
2217 		blobids[i] = g_blobid;
2218 	}
2219 
2220 	/* Unload the blob store */
2221 	g_bserrno = -1;
2222 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2223 	CU_ASSERT(g_bserrno == 0);
2224 
2225 	/* Load an existing blob store */
2226 	g_bserrno = -1;
2227 	g_bs = NULL;
2228 	dev = init_dev();
2229 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2230 	CU_ASSERT(g_bserrno == 0);
2231 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2232 
2233 	CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz);
2234 
2235 	for (i = 0; i < NUM_BLOBS; i++) {
2236 		g_bserrno = -1;
2237 		g_blob = NULL;
2238 		spdk_bs_open_blob(g_bs, blobids[i], blob_op_with_handle_complete, NULL);
2239 		CU_ASSERT(g_bserrno == 0);
2240 		CU_ASSERT(g_blob !=  NULL);
2241 		g_bserrno = -1;
2242 		spdk_blob_close(g_blob, blob_op_complete, NULL);
2243 		CU_ASSERT(g_bserrno == 0);
2244 	}
2245 
2246 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2247 	CU_ASSERT(g_bserrno == 0);
2248 	g_bs = NULL;
2249 }
2250 
2251 static void
2252 bs_destroy(void)
2253 {
2254 	struct spdk_bs_dev *dev;
2255 	struct spdk_bs_opts opts;
2256 
2257 	/* Initialize a new blob store */
2258 	dev = init_dev();
2259 	spdk_bs_opts_init(&opts);
2260 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2261 	CU_ASSERT(g_bserrno == 0);
2262 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2263 
2264 	/* Destroy the blob store */
2265 	g_bserrno = -1;
2266 	spdk_bs_destroy(g_bs, bs_op_complete, NULL);
2267 	CU_ASSERT(g_bserrno == 0);
2268 
2269 	/* Loading an non-existent blob store should fail. */
2270 	g_bs = NULL;
2271 	dev = init_dev();
2272 
2273 	g_bserrno = 0;
2274 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2275 	CU_ASSERT(g_bserrno != 0);
2276 }
2277 
2278 /* Try to hit all of the corner cases associated with serializing
2279  * a blob to disk
2280  */
2281 static void
2282 blob_serialize(void)
2283 {
2284 	struct spdk_bs_dev *dev;
2285 	struct spdk_bs_opts opts;
2286 	struct spdk_blob_store *bs;
2287 	spdk_blob_id blobid[2];
2288 	struct spdk_blob *blob[2];
2289 	uint64_t i;
2290 	char *value;
2291 	int rc;
2292 
2293 	dev = init_dev();
2294 
2295 	/* Initialize a new blobstore with very small clusters */
2296 	spdk_bs_opts_init(&opts);
2297 	opts.cluster_sz = dev->blocklen * 8;
2298 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2299 	CU_ASSERT(g_bserrno == 0);
2300 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2301 	bs = g_bs;
2302 
2303 	/* Create and open two blobs */
2304 	for (i = 0; i < 2; i++) {
2305 		spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
2306 		CU_ASSERT(g_bserrno == 0);
2307 		CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2308 		blobid[i] = g_blobid;
2309 
2310 		/* Open a blob */
2311 		spdk_bs_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL);
2312 		CU_ASSERT(g_bserrno == 0);
2313 		CU_ASSERT(g_blob != NULL);
2314 		blob[i] = g_blob;
2315 
2316 		/* Set a fairly large xattr on both blobs to eat up
2317 		 * metadata space
2318 		 */
2319 		value = calloc(dev->blocklen - 64, sizeof(char));
2320 		SPDK_CU_ASSERT_FATAL(value != NULL);
2321 		memset(value, i, dev->blocklen / 2);
2322 		rc = spdk_blob_set_xattr(blob[i], "name", value, dev->blocklen - 64);
2323 		CU_ASSERT(rc == 0);
2324 		free(value);
2325 	}
2326 
2327 	/* Resize the blobs, alternating 1 cluster at a time.
2328 	 * This thwarts run length encoding and will cause spill
2329 	 * over of the extents.
2330 	 */
2331 	for (i = 0; i < 6; i++) {
2332 		spdk_blob_resize(blob[i % 2], (i / 2) + 1, blob_op_complete, NULL);
2333 		CU_ASSERT(g_bserrno == 0);
2334 	}
2335 
2336 	for (i = 0; i < 2; i++) {
2337 		spdk_blob_sync_md(blob[i], blob_op_complete, NULL);
2338 		CU_ASSERT(g_bserrno == 0);
2339 	}
2340 
2341 	/* Close the blobs */
2342 	for (i = 0; i < 2; i++) {
2343 		spdk_blob_close(blob[i], blob_op_complete, NULL);
2344 		CU_ASSERT(g_bserrno == 0);
2345 	}
2346 
2347 	/* Unload the blobstore */
2348 	spdk_bs_unload(bs, bs_op_complete, NULL);
2349 	CU_ASSERT(g_bserrno == 0);
2350 	g_bs = NULL;
2351 	g_blob = NULL;
2352 	g_blobid = 0;
2353 	bs = NULL;
2354 
2355 	dev = init_dev();
2356 	/* Load an existing blob store */
2357 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2358 	CU_ASSERT(g_bserrno == 0);
2359 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2360 	bs = g_bs;
2361 
2362 	for (i = 0; i < 2; i++) {
2363 		blob[i] = NULL;
2364 
2365 		spdk_bs_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL);
2366 		CU_ASSERT(g_bserrno == 0);
2367 		CU_ASSERT(g_blob != NULL);
2368 		blob[i] = g_blob;
2369 
2370 		CU_ASSERT(spdk_blob_get_num_clusters(blob[i]) == 3);
2371 
2372 		spdk_blob_close(blob[i], blob_op_complete, NULL);
2373 		CU_ASSERT(g_bserrno == 0);
2374 	}
2375 
2376 	spdk_bs_unload(bs, bs_op_complete, NULL);
2377 	CU_ASSERT(g_bserrno == 0);
2378 	g_bs = NULL;
2379 }
2380 
2381 static void
2382 blob_crc(void)
2383 {
2384 	struct spdk_blob_store *bs;
2385 	struct spdk_bs_dev *dev;
2386 	struct spdk_blob *blob;
2387 	spdk_blob_id blobid;
2388 	uint32_t page_num;
2389 	int index;
2390 	struct spdk_blob_md_page *page;
2391 
2392 	dev = init_dev();
2393 
2394 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
2395 	CU_ASSERT(g_bserrno == 0);
2396 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2397 	bs = g_bs;
2398 
2399 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
2400 	CU_ASSERT(g_bserrno == 0);
2401 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2402 	blobid = g_blobid;
2403 
2404 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
2405 	CU_ASSERT(g_bserrno == 0);
2406 	CU_ASSERT(g_blob != NULL);
2407 	blob = g_blob;
2408 
2409 	spdk_blob_close(blob, blob_op_complete, NULL);
2410 	CU_ASSERT(g_bserrno == 0);
2411 
2412 	page_num = _spdk_bs_blobid_to_page(blobid);
2413 	index = DEV_BUFFER_BLOCKLEN * (bs->md_start + page_num);
2414 	page = (struct spdk_blob_md_page *)&g_dev_buffer[index];
2415 	page->crc = 0;
2416 
2417 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
2418 	CU_ASSERT(g_bserrno == -EINVAL);
2419 	CU_ASSERT(g_blob == NULL);
2420 	g_bserrno = 0;
2421 
2422 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
2423 	CU_ASSERT(g_bserrno == -EINVAL);
2424 
2425 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2426 	CU_ASSERT(g_bserrno == 0);
2427 	g_bs = NULL;
2428 }
2429 
2430 static void
2431 super_block_crc(void)
2432 {
2433 	struct spdk_bs_dev *dev;
2434 	struct spdk_bs_super_block *super_block;
2435 	struct spdk_bs_opts opts;
2436 
2437 	dev = init_dev();
2438 	spdk_bs_opts_init(&opts);
2439 
2440 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
2441 	CU_ASSERT(g_bserrno == 0);
2442 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2443 
2444 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2445 	CU_ASSERT(g_bserrno == 0);
2446 	g_bs = NULL;
2447 
2448 	super_block = (struct spdk_bs_super_block *)g_dev_buffer;
2449 	super_block->crc = 0;
2450 	dev = init_dev();
2451 
2452 	/* Load an existing blob store */
2453 	g_bserrno = 0;
2454 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2455 	CU_ASSERT(g_bserrno == -EILSEQ);
2456 }
2457 
2458 /* For blob dirty shutdown test case we do the following sub-test cases:
2459  * 1 Initialize new blob store and create 1 super blob with some xattrs, then we
2460  *   dirty shutdown and reload the blob store and verify the xattrs.
2461  * 2 Resize the blob from 10 clusters to 20 clusters and then dirty shutdown,
2462  *   reload the blob store and verify the clusters number.
2463  * 3 Create the second blob and then dirty shutdown, reload the blob store
2464  *   and verify the second blob.
2465  * 4 Delete the second blob and then dirty shutdown, reload the blob store
2466  *   and verify the second blob is invalid.
2467  * 5 Create the second blob again and also create the third blob, modify the
2468  *   md of second blob which makes the md invalid, and then dirty shutdown,
2469  *   reload the blob store verify the second blob, it should invalid and also
2470  *   verify the third blob, it should correct.
2471  */
2472 static void
2473 blob_dirty_shutdown(void)
2474 {
2475 	int rc;
2476 	int index;
2477 	struct spdk_bs_dev *dev;
2478 	spdk_blob_id blobid1, blobid2, blobid3;
2479 	struct spdk_blob *blob;
2480 	uint64_t length;
2481 	uint64_t free_clusters;
2482 	const void *value;
2483 	size_t value_len;
2484 	uint32_t page_num;
2485 	struct spdk_blob_md_page *page;
2486 	struct spdk_bs_opts opts;
2487 
2488 	dev = init_dev();
2489 	spdk_bs_opts_init(&opts);
2490 	/* Initialize a new blob store */
2491 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
2492 	CU_ASSERT(g_bserrno == 0);
2493 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2494 
2495 	/* Create first blob */
2496 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
2497 	CU_ASSERT(g_bserrno == 0);
2498 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2499 	blobid1 = g_blobid;
2500 
2501 	spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL);
2502 	CU_ASSERT(g_bserrno == 0);
2503 	CU_ASSERT(g_blob != NULL);
2504 	blob = g_blob;
2505 
2506 	/* Set some xattrs */
2507 	rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1);
2508 	CU_ASSERT(rc == 0);
2509 
2510 	length = 2345;
2511 	rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
2512 	CU_ASSERT(rc == 0);
2513 
2514 	/* Resize the blob */
2515 	spdk_blob_resize(blob, 10, blob_op_complete, NULL);
2516 	CU_ASSERT(g_bserrno == 0);
2517 
2518 	/* Set the blob as the super blob */
2519 	spdk_bs_set_super(g_bs, blobid1, blob_op_complete, NULL);
2520 	CU_ASSERT(g_bserrno == 0);
2521 
2522 	free_clusters = spdk_bs_free_cluster_count(g_bs);
2523 
2524 	spdk_blob_close(blob, blob_op_complete, NULL);
2525 	blob = NULL;
2526 	g_blob = NULL;
2527 	g_blobid = SPDK_BLOBID_INVALID;
2528 
2529 	/* Dirty shutdown */
2530 	_spdk_bs_free(g_bs);
2531 
2532 	/* reload blobstore */
2533 	dev = init_dev();
2534 	spdk_bs_opts_init(&opts);
2535 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2536 	CU_ASSERT(g_bserrno == 0);
2537 
2538 	/* Get the super blob */
2539 	spdk_bs_get_super(g_bs, blob_op_with_id_complete, NULL);
2540 	CU_ASSERT(g_bserrno == 0);
2541 	CU_ASSERT(blobid1 == g_blobid);
2542 
2543 	spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL);
2544 	CU_ASSERT(g_bserrno == 0);
2545 	CU_ASSERT(g_blob != NULL);
2546 	blob = g_blob;
2547 
2548 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs));
2549 
2550 	/* Get the xattrs */
2551 	value = NULL;
2552 	rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len);
2553 	CU_ASSERT(rc == 0);
2554 	SPDK_CU_ASSERT_FATAL(value != NULL);
2555 	CU_ASSERT(*(uint64_t *)value == length);
2556 	CU_ASSERT(value_len == 8);
2557 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10);
2558 
2559 	/* Resize the blob */
2560 	spdk_blob_resize(blob, 20, blob_op_complete, NULL);
2561 	CU_ASSERT(g_bserrno == 0);
2562 
2563 	free_clusters = spdk_bs_free_cluster_count(g_bs);
2564 
2565 	spdk_blob_close(blob, blob_op_complete, NULL);
2566 	CU_ASSERT(g_bserrno == 0);
2567 	blob = NULL;
2568 	g_blob = NULL;
2569 	g_blobid = SPDK_BLOBID_INVALID;
2570 
2571 	/* Dirty shutdown */
2572 	_spdk_bs_free(g_bs);
2573 
2574 	/* reload the blobstore */
2575 	dev = init_dev();
2576 	spdk_bs_opts_init(&opts);
2577 	/* Load an existing blob store */
2578 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2579 	CU_ASSERT(g_bserrno == 0);
2580 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2581 	spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL);
2582 	CU_ASSERT(g_bserrno == 0);
2583 	CU_ASSERT(g_blob != NULL);
2584 	blob = g_blob;
2585 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 20);
2586 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs));
2587 
2588 	spdk_blob_close(blob, blob_op_complete, NULL);
2589 	CU_ASSERT(g_bserrno == 0);
2590 	blob = NULL;
2591 	g_blob = NULL;
2592 	g_blobid = SPDK_BLOBID_INVALID;
2593 
2594 	/* Create second blob */
2595 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
2596 	CU_ASSERT(g_bserrno == 0);
2597 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2598 	blobid2 = g_blobid;
2599 
2600 	spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL);
2601 	CU_ASSERT(g_bserrno == 0);
2602 	CU_ASSERT(g_blob != NULL);
2603 	blob = g_blob;
2604 
2605 	/* Set some xattrs */
2606 	rc = spdk_blob_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1);
2607 	CU_ASSERT(rc == 0);
2608 
2609 	length = 5432;
2610 	rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
2611 	CU_ASSERT(rc == 0);
2612 
2613 	/* Resize the blob */
2614 	spdk_blob_resize(blob, 10, blob_op_complete, NULL);
2615 	CU_ASSERT(g_bserrno == 0);
2616 
2617 	free_clusters = spdk_bs_free_cluster_count(g_bs);
2618 
2619 	spdk_blob_close(blob, blob_op_complete, NULL);
2620 	blob = NULL;
2621 	g_blob = NULL;
2622 	g_blobid = SPDK_BLOBID_INVALID;
2623 
2624 	/* Dirty shutdown */
2625 	_spdk_bs_free(g_bs);
2626 
2627 	/* reload the blobstore */
2628 	dev = init_dev();
2629 	spdk_bs_opts_init(&opts);
2630 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2631 	CU_ASSERT(g_bserrno == 0);
2632 
2633 	spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL);
2634 	CU_ASSERT(g_bserrno == 0);
2635 	CU_ASSERT(g_blob != NULL);
2636 	blob = g_blob;
2637 
2638 	/* Get the xattrs */
2639 	value = NULL;
2640 	rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len);
2641 	CU_ASSERT(rc == 0);
2642 	SPDK_CU_ASSERT_FATAL(value != NULL);
2643 	CU_ASSERT(*(uint64_t *)value == length);
2644 	CU_ASSERT(value_len == 8);
2645 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10);
2646 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs));
2647 
2648 	spdk_blob_close(blob, blob_op_complete, NULL);
2649 	CU_ASSERT(g_bserrno == 0);
2650 	spdk_bs_delete_blob(g_bs, blobid2, blob_op_complete, NULL);
2651 	CU_ASSERT(g_bserrno == 0);
2652 
2653 	free_clusters = spdk_bs_free_cluster_count(g_bs);
2654 
2655 	/* Dirty shutdown */
2656 	_spdk_bs_free(g_bs);
2657 	/* reload the blobstore */
2658 	dev = init_dev();
2659 	spdk_bs_opts_init(&opts);
2660 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2661 	CU_ASSERT(g_bserrno == 0);
2662 
2663 	spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL);
2664 	CU_ASSERT(g_bserrno != 0);
2665 	CU_ASSERT(g_blob == NULL);
2666 
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 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs));
2671 	spdk_blob_close(g_blob, blob_op_complete, NULL);
2672 	CU_ASSERT(g_bserrno == 0);
2673 
2674 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2675 	CU_ASSERT(g_bserrno == 0);
2676 	g_bs = NULL;
2677 
2678 	/* reload the blobstore */
2679 	dev = init_dev();
2680 	spdk_bs_opts_init(&opts);
2681 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2682 	CU_ASSERT(g_bserrno == 0);
2683 
2684 	/* Create second blob */
2685 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
2686 	CU_ASSERT(g_bserrno == 0);
2687 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2688 	blobid2 = g_blobid;
2689 
2690 	/* Create third blob */
2691 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
2692 	CU_ASSERT(g_bserrno == 0);
2693 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2694 	blobid3 = g_blobid;
2695 
2696 	spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL);
2697 	CU_ASSERT(g_bserrno == 0);
2698 	CU_ASSERT(g_blob != NULL);
2699 	blob = g_blob;
2700 
2701 	/* Set some xattrs for second blob */
2702 	rc = spdk_blob_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1);
2703 	CU_ASSERT(rc == 0);
2704 
2705 	length = 5432;
2706 	rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
2707 	CU_ASSERT(rc == 0);
2708 
2709 	spdk_blob_close(blob, blob_op_complete, NULL);
2710 	blob = NULL;
2711 	g_blob = NULL;
2712 	g_blobid = SPDK_BLOBID_INVALID;
2713 
2714 	spdk_bs_open_blob(g_bs, blobid3, blob_op_with_handle_complete, NULL);
2715 	CU_ASSERT(g_bserrno == 0);
2716 	CU_ASSERT(g_blob != NULL);
2717 	blob = g_blob;
2718 
2719 	/* Set some xattrs for third blob */
2720 	rc = spdk_blob_set_xattr(blob, "name", "log2.txt", strlen("log2.txt") + 1);
2721 	CU_ASSERT(rc == 0);
2722 
2723 	length = 5432;
2724 	rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
2725 	CU_ASSERT(rc == 0);
2726 
2727 	spdk_blob_close(blob, blob_op_complete, NULL);
2728 	blob = NULL;
2729 	g_blob = NULL;
2730 	g_blobid = SPDK_BLOBID_INVALID;
2731 
2732 	/* Mark second blob as invalid */
2733 	page_num = _spdk_bs_blobid_to_page(blobid2);
2734 
2735 	index = DEV_BUFFER_BLOCKLEN * (g_bs->md_start + page_num);
2736 	page = (struct spdk_blob_md_page *)&g_dev_buffer[index];
2737 	page->sequence_num = 1;
2738 	page->crc = _spdk_blob_md_page_calc_crc(page);
2739 
2740 	free_clusters = spdk_bs_free_cluster_count(g_bs);
2741 
2742 	/* Dirty shutdown */
2743 	_spdk_bs_free(g_bs);
2744 	/* reload the blobstore */
2745 	dev = init_dev();
2746 	spdk_bs_opts_init(&opts);
2747 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2748 	CU_ASSERT(g_bserrno == 0);
2749 
2750 	spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL);
2751 	CU_ASSERT(g_bserrno != 0);
2752 	CU_ASSERT(g_blob == NULL);
2753 
2754 	spdk_bs_open_blob(g_bs, blobid3, blob_op_with_handle_complete, NULL);
2755 	CU_ASSERT(g_bserrno == 0);
2756 	CU_ASSERT(g_blob != NULL);
2757 	blob = g_blob;
2758 
2759 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs));
2760 
2761 	spdk_blob_close(blob, blob_op_complete, NULL);
2762 	blob = NULL;
2763 	g_blob = NULL;
2764 	g_blobid = SPDK_BLOBID_INVALID;
2765 
2766 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2767 	CU_ASSERT(g_bserrno == 0);
2768 	g_bs = NULL;
2769 }
2770 
2771 static void
2772 blob_flags(void)
2773 {
2774 	struct spdk_bs_dev *dev;
2775 	spdk_blob_id blobid_invalid, blobid_data_ro, blobid_md_ro;
2776 	struct spdk_blob *blob_invalid, *blob_data_ro, *blob_md_ro;
2777 	struct spdk_bs_opts opts;
2778 	int rc;
2779 
2780 	dev = init_dev();
2781 	spdk_bs_opts_init(&opts);
2782 
2783 	/* Initialize a new blob store */
2784 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2785 	CU_ASSERT(g_bserrno == 0);
2786 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2787 
2788 	/* Create three blobs - one each for testing invalid, data_ro and md_ro flags. */
2789 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
2790 	CU_ASSERT(g_bserrno == 0);
2791 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2792 	blobid_invalid = g_blobid;
2793 
2794 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
2795 	CU_ASSERT(g_bserrno == 0);
2796 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2797 	blobid_data_ro = g_blobid;
2798 
2799 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
2800 	CU_ASSERT(g_bserrno == 0);
2801 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2802 	blobid_md_ro = g_blobid;
2803 
2804 	spdk_bs_open_blob(g_bs, blobid_invalid, blob_op_with_handle_complete, NULL);
2805 	CU_ASSERT(g_bserrno == 0);
2806 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
2807 	blob_invalid = g_blob;
2808 
2809 	spdk_bs_open_blob(g_bs, blobid_data_ro, blob_op_with_handle_complete, NULL);
2810 	CU_ASSERT(g_bserrno == 0);
2811 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
2812 	blob_data_ro = g_blob;
2813 
2814 	spdk_bs_open_blob(g_bs, blobid_md_ro, blob_op_with_handle_complete, NULL);
2815 	CU_ASSERT(g_bserrno == 0);
2816 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
2817 	blob_md_ro = g_blob;
2818 
2819 	/* Change the size of blob_data_ro to check if flags are serialized
2820 	 * when blob has non zero number of extents */
2821 	spdk_blob_resize(blob_data_ro, 10, blob_op_complete, NULL);
2822 	CU_ASSERT(g_bserrno == 0);
2823 
2824 	/* Set the xattr to check if flags are serialized
2825 	 * when blob has non zero number of xattrs */
2826 	rc = spdk_blob_set_xattr(blob_md_ro, "name", "log.txt", strlen("log.txt") + 1);
2827 	CU_ASSERT(rc == 0);
2828 
2829 	blob_invalid->invalid_flags = (1ULL << 63);
2830 	blob_invalid->state = SPDK_BLOB_STATE_DIRTY;
2831 	blob_data_ro->data_ro_flags = (1ULL << 62);
2832 	blob_data_ro->state = SPDK_BLOB_STATE_DIRTY;
2833 	blob_md_ro->md_ro_flags = (1ULL << 61);
2834 	blob_md_ro->state = SPDK_BLOB_STATE_DIRTY;
2835 
2836 	g_bserrno = -1;
2837 	spdk_blob_sync_md(blob_invalid, blob_op_complete, NULL);
2838 	CU_ASSERT(g_bserrno == 0);
2839 	g_bserrno = -1;
2840 	spdk_blob_sync_md(blob_data_ro, blob_op_complete, NULL);
2841 	CU_ASSERT(g_bserrno == 0);
2842 	g_bserrno = -1;
2843 	spdk_blob_sync_md(blob_md_ro, blob_op_complete, NULL);
2844 	CU_ASSERT(g_bserrno == 0);
2845 
2846 	g_bserrno = -1;
2847 	spdk_blob_close(blob_invalid, blob_op_complete, NULL);
2848 	CU_ASSERT(g_bserrno == 0);
2849 	blob_invalid = NULL;
2850 	g_bserrno = -1;
2851 	spdk_blob_close(blob_data_ro, blob_op_complete, NULL);
2852 	CU_ASSERT(g_bserrno == 0);
2853 	blob_data_ro = NULL;
2854 	g_bserrno = -1;
2855 	spdk_blob_close(blob_md_ro, blob_op_complete, NULL);
2856 	CU_ASSERT(g_bserrno == 0);
2857 	blob_md_ro = NULL;
2858 
2859 	g_blob = NULL;
2860 	g_blobid = SPDK_BLOBID_INVALID;
2861 
2862 	/* Unload the blob store */
2863 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2864 	CU_ASSERT(g_bserrno == 0);
2865 	g_bs = NULL;
2866 
2867 	/* Load an existing blob store */
2868 	dev = init_dev();
2869 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2870 	CU_ASSERT(g_bserrno == 0);
2871 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2872 
2873 	g_blob = NULL;
2874 	g_bserrno = 0;
2875 	spdk_bs_open_blob(g_bs, blobid_invalid, blob_op_with_handle_complete, NULL);
2876 	CU_ASSERT(g_bserrno != 0);
2877 	CU_ASSERT(g_blob == NULL);
2878 
2879 	g_blob = NULL;
2880 	g_bserrno = -1;
2881 	spdk_bs_open_blob(g_bs, blobid_data_ro, blob_op_with_handle_complete, NULL);
2882 	CU_ASSERT(g_bserrno == 0);
2883 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
2884 	blob_data_ro = g_blob;
2885 	/* If an unknown data_ro flag was found, the blob should be marked both data and md read-only. */
2886 	CU_ASSERT(blob_data_ro->data_ro == true);
2887 	CU_ASSERT(blob_data_ro->md_ro == true);
2888 	CU_ASSERT(spdk_blob_get_num_clusters(blob_data_ro) == 10);
2889 
2890 	g_blob = NULL;
2891 	g_bserrno = -1;
2892 	spdk_bs_open_blob(g_bs, blobid_md_ro, blob_op_with_handle_complete, NULL);
2893 	CU_ASSERT(g_bserrno == 0);
2894 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
2895 	blob_md_ro = g_blob;
2896 	CU_ASSERT(blob_md_ro->data_ro == false);
2897 	CU_ASSERT(blob_md_ro->md_ro == true);
2898 
2899 	g_bserrno = -1;
2900 	spdk_blob_sync_md(blob_md_ro, blob_op_complete, NULL);
2901 	CU_ASSERT(g_bserrno == 0);
2902 
2903 	spdk_blob_close(blob_data_ro, blob_op_complete, NULL);
2904 	CU_ASSERT(g_bserrno == 0);
2905 	spdk_blob_close(blob_md_ro, blob_op_complete, NULL);
2906 	CU_ASSERT(g_bserrno == 0);
2907 
2908 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2909 	CU_ASSERT(g_bserrno == 0);
2910 }
2911 
2912 static void
2913 bs_version(void)
2914 {
2915 	struct spdk_bs_super_block *super;
2916 	struct spdk_bs_dev *dev;
2917 	struct spdk_bs_opts opts;
2918 	spdk_blob_id blobid;
2919 
2920 	dev = init_dev();
2921 	spdk_bs_opts_init(&opts);
2922 
2923 	/* Initialize a new blob store */
2924 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2925 	CU_ASSERT(g_bserrno == 0);
2926 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2927 
2928 	/* Unload the blob store */
2929 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2930 	CU_ASSERT(g_bserrno == 0);
2931 	g_bs = NULL;
2932 
2933 	/*
2934 	 * Change the bs version on disk.  This will allow us to
2935 	 *  test that the version does not get modified automatically
2936 	 *  when loading and unloading the blobstore.
2937 	 */
2938 	super = (struct spdk_bs_super_block *)&g_dev_buffer[0];
2939 	CU_ASSERT(super->version == SPDK_BS_VERSION);
2940 	CU_ASSERT(super->clean == 1);
2941 	super->version = 2;
2942 	/*
2943 	 * Version 2 metadata does not have a used blobid mask, so clear
2944 	 *  those fields in the super block and zero the corresponding
2945 	 *  region on "disk".  We will use this to ensure blob IDs are
2946 	 *  correctly reconstructed.
2947 	 */
2948 	memset(&g_dev_buffer[super->used_blobid_mask_start * SPDK_BS_PAGE_SIZE], 0,
2949 	       super->used_blobid_mask_len * SPDK_BS_PAGE_SIZE);
2950 	super->used_blobid_mask_start = 0;
2951 	super->used_blobid_mask_len = 0;
2952 	super->crc = _spdk_blob_md_page_calc_crc(super);
2953 
2954 	/* Load an existing blob store */
2955 	dev = init_dev();
2956 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2957 	CU_ASSERT(g_bserrno == 0);
2958 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2959 	CU_ASSERT(super->clean == 0);
2960 
2961 	/*
2962 	 * Create a blob - just to make sure that when we unload it
2963 	 *  results in writing the super block (since metadata pages
2964 	 *  were allocated.
2965 	 */
2966 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
2967 	CU_ASSERT(g_bserrno == 0);
2968 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2969 	blobid = g_blobid;
2970 
2971 	/* Unload the blob store */
2972 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2973 	CU_ASSERT(g_bserrno == 0);
2974 	g_bs = NULL;
2975 	CU_ASSERT(super->version == 2);
2976 	CU_ASSERT(super->used_blobid_mask_start == 0);
2977 	CU_ASSERT(super->used_blobid_mask_len == 0);
2978 
2979 	dev = init_dev();
2980 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2981 	CU_ASSERT(g_bserrno == 0);
2982 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2983 
2984 	g_blob = NULL;
2985 	spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
2986 	CU_ASSERT(g_bserrno == 0);
2987 	CU_ASSERT(g_blob != NULL);
2988 
2989 	spdk_blob_close(g_blob, blob_op_complete, NULL);
2990 	CU_ASSERT(g_bserrno == 0);
2991 
2992 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2993 	CU_ASSERT(g_bserrno == 0);
2994 	g_bs = NULL;
2995 	CU_ASSERT(super->version == 2);
2996 	CU_ASSERT(super->used_blobid_mask_start == 0);
2997 	CU_ASSERT(super->used_blobid_mask_len == 0);
2998 }
2999 
3000 static void
3001 blob_set_xattrs(void)
3002 {
3003 	struct spdk_blob_store *bs;
3004 	struct spdk_bs_dev *dev;
3005 	struct spdk_blob *blob;
3006 	struct spdk_blob_opts opts;
3007 	spdk_blob_id blobid;
3008 	const void *value;
3009 	size_t value_len;
3010 	int rc;
3011 
3012 	dev = init_dev();
3013 
3014 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
3015 	CU_ASSERT(g_bserrno == 0);
3016 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3017 	bs = g_bs;
3018 
3019 	/* Create blob with extra attributes */
3020 	spdk_blob_opts_init(&opts);
3021 
3022 	opts.xattrs.names = g_xattr_names;
3023 	opts.xattrs.get_value = _get_xattr_value;
3024 	opts.xattrs.count = 3;
3025 	opts.xattrs.ctx = &g_ctx;
3026 
3027 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
3028 	CU_ASSERT(g_bserrno == 0);
3029 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3030 	blobid = g_blobid;
3031 
3032 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
3033 	CU_ASSERT(g_bserrno == 0);
3034 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3035 	blob = g_blob;
3036 
3037 	/* Get the xattrs */
3038 	value = NULL;
3039 
3040 	rc = spdk_blob_get_xattr_value(blob, g_xattr_names[0], &value, &value_len);
3041 	CU_ASSERT(rc == 0);
3042 	SPDK_CU_ASSERT_FATAL(value != NULL);
3043 	CU_ASSERT(value_len == strlen(g_xattr_values[0]));
3044 	CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len);
3045 
3046 	rc = spdk_blob_get_xattr_value(blob, g_xattr_names[1], &value, &value_len);
3047 	CU_ASSERT(rc == 0);
3048 	SPDK_CU_ASSERT_FATAL(value != NULL);
3049 	CU_ASSERT(value_len == strlen(g_xattr_values[1]));
3050 	CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len);
3051 
3052 	rc = spdk_blob_get_xattr_value(blob, g_xattr_names[2], &value, &value_len);
3053 	CU_ASSERT(rc == 0);
3054 	SPDK_CU_ASSERT_FATAL(value != NULL);
3055 	CU_ASSERT(value_len == strlen(g_xattr_values[2]));
3056 	CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len);
3057 
3058 	/* Try to get non existing attribute */
3059 
3060 	rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len);
3061 	CU_ASSERT(rc == -ENOENT);
3062 
3063 	spdk_blob_close(blob, blob_op_complete, NULL);
3064 	CU_ASSERT(g_bserrno == 0);
3065 	blob = NULL;
3066 	g_blob = NULL;
3067 	g_blobid = SPDK_BLOBID_INVALID;
3068 
3069 	/* NULL callback */
3070 	spdk_blob_opts_init(&opts);
3071 	opts.xattrs.names = g_xattr_names;
3072 	opts.xattrs.get_value = NULL;
3073 	opts.xattrs.count = 1;
3074 	opts.xattrs.ctx = &g_ctx;
3075 
3076 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
3077 	CU_ASSERT(g_bserrno == -EINVAL);
3078 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3079 
3080 	/* NULL values */
3081 	spdk_blob_opts_init(&opts);
3082 	opts.xattrs.names = g_xattr_names;
3083 	opts.xattrs.get_value = _get_xattr_value_null;
3084 	opts.xattrs.count = 1;
3085 	opts.xattrs.ctx = NULL;
3086 
3087 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
3088 	CU_ASSERT(g_bserrno == -EINVAL);
3089 
3090 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3091 	CU_ASSERT(g_bserrno == 0);
3092 	g_bs = NULL;
3093 
3094 }
3095 
3096 static void
3097 blob_thin_prov_alloc(void)
3098 {
3099 	struct spdk_blob_store *bs;
3100 	struct spdk_bs_dev *dev;
3101 	struct spdk_blob *blob;
3102 	struct spdk_blob_opts opts;
3103 	spdk_blob_id blobid;
3104 	uint64_t free_clusters;
3105 
3106 	dev = init_dev();
3107 
3108 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
3109 	CU_ASSERT(g_bserrno == 0);
3110 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3111 	bs = g_bs;
3112 	free_clusters = spdk_bs_free_cluster_count(bs);
3113 
3114 	/* Set blob as thin provisioned */
3115 	spdk_blob_opts_init(&opts);
3116 	opts.thin_provision = true;
3117 
3118 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
3119 	CU_ASSERT(g_bserrno == 0);
3120 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3121 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3122 	blobid = g_blobid;
3123 
3124 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
3125 	CU_ASSERT(g_bserrno == 0);
3126 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3127 	blob = g_blob;
3128 
3129 	CU_ASSERT(blob->active.num_clusters == 0);
3130 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0);
3131 
3132 	/* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */
3133 	spdk_blob_resize(blob, 5, blob_op_complete, NULL);
3134 	CU_ASSERT(g_bserrno == 0);
3135 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3136 	CU_ASSERT(blob->active.num_clusters == 5);
3137 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5);
3138 
3139 	/* Shrink the blob to 3 clusters - still unallocated */
3140 	spdk_blob_resize(blob, 3, blob_op_complete, NULL);
3141 	CU_ASSERT(g_bserrno == 0);
3142 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3143 	CU_ASSERT(blob->active.num_clusters == 3);
3144 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 3);
3145 
3146 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
3147 	CU_ASSERT(g_bserrno == 0);
3148 	/* Sync must not change anything */
3149 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3150 	CU_ASSERT(blob->active.num_clusters == 3);
3151 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 3);
3152 
3153 	spdk_blob_close(blob, blob_op_complete, NULL);
3154 	CU_ASSERT(g_bserrno == 0);
3155 
3156 	/* Unload the blob store */
3157 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3158 	CU_ASSERT(g_bserrno == 0);
3159 	g_bs = NULL;
3160 	g_blob = NULL;
3161 	g_blobid = 0;
3162 
3163 	/* Load an existing blob store */
3164 	dev = init_dev();
3165 	spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL);
3166 	CU_ASSERT(g_bserrno == 0);
3167 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3168 
3169 	bs = g_bs;
3170 
3171 	spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
3172 	CU_ASSERT(g_bserrno == 0);
3173 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3174 	blob = g_blob;
3175 
3176 	/* Check that clusters allocation and size is still the same */
3177 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3178 	CU_ASSERT(blob->active.num_clusters == 3);
3179 
3180 	spdk_blob_close(blob, blob_op_complete, NULL);
3181 	CU_ASSERT(g_bserrno == 0);
3182 
3183 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
3184 	CU_ASSERT(g_bserrno == 0);
3185 
3186 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3187 	CU_ASSERT(g_bserrno == 0);
3188 	g_bs = NULL;
3189 }
3190 
3191 static void
3192 blob_insert_cluster_msg(void)
3193 {
3194 	struct spdk_blob_store *bs;
3195 	struct spdk_bs_dev *dev;
3196 	struct spdk_blob *blob;
3197 	struct spdk_blob_opts opts;
3198 	spdk_blob_id blobid;
3199 	uint64_t free_clusters;
3200 
3201 	dev = init_dev();
3202 
3203 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
3204 	CU_ASSERT(g_bserrno == 0);
3205 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3206 	bs = g_bs;
3207 	free_clusters = spdk_bs_free_cluster_count(bs);
3208 
3209 	/* Set blob as thin provisioned */
3210 	spdk_blob_opts_init(&opts);
3211 	opts.thin_provision = true;
3212 	opts.num_clusters = 4;
3213 
3214 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
3215 	CU_ASSERT(g_bserrno == 0);
3216 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3217 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3218 	blobid = g_blobid;
3219 
3220 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
3221 	CU_ASSERT(g_bserrno == 0);
3222 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3223 	blob = g_blob;
3224 
3225 	CU_ASSERT(blob->active.num_clusters == 4);
3226 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 4);
3227 	CU_ASSERT(blob->active.clusters[1] == 0);
3228 
3229 	_spdk_bs_claim_cluster(bs, 0xF);
3230 	_spdk_blob_insert_cluster_on_md_thread(blob, 1, 0xF, blob_op_complete, NULL);
3231 
3232 	CU_ASSERT(blob->active.clusters[1] != 0);
3233 
3234 	spdk_blob_close(blob, blob_op_complete, NULL);
3235 	CU_ASSERT(g_bserrno == 0);
3236 
3237 	/* Unload the blob store */
3238 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3239 	CU_ASSERT(g_bserrno == 0);
3240 	g_bs = NULL;
3241 	g_blob = NULL;
3242 	g_blobid = 0;
3243 
3244 	/* Load an existing blob store */
3245 	dev = init_dev();
3246 	spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL);
3247 	CU_ASSERT(g_bserrno == 0);
3248 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3249 
3250 	bs = g_bs;
3251 
3252 	spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
3253 	CU_ASSERT(g_bserrno == 0);
3254 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3255 	blob = g_blob;
3256 
3257 	CU_ASSERT(blob->active.clusters[1] != 0);
3258 
3259 	spdk_blob_close(blob, blob_op_complete, NULL);
3260 	CU_ASSERT(g_bserrno == 0);
3261 
3262 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
3263 	CU_ASSERT(g_bserrno == 0);
3264 
3265 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3266 	CU_ASSERT(g_bserrno == 0);
3267 	g_bs = NULL;
3268 }
3269 
3270 static void
3271 blob_thin_prov_rw(void)
3272 {
3273 	static const uint8_t zero[10 * 4096] = { 0 };
3274 	struct spdk_blob_store *bs;
3275 	struct spdk_bs_dev *dev;
3276 	struct spdk_blob *blob;
3277 	struct spdk_io_channel *channel;
3278 	struct spdk_blob_opts opts;
3279 	spdk_blob_id blobid;
3280 	uint64_t free_clusters;
3281 	uint8_t payload_read[10 * 4096];
3282 	uint8_t payload_write[10 * 4096];
3283 
3284 	dev = init_dev();
3285 
3286 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
3287 	CU_ASSERT(g_bserrno == 0);
3288 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3289 	bs = g_bs;
3290 	free_clusters = spdk_bs_free_cluster_count(bs);
3291 
3292 	channel = spdk_bs_alloc_io_channel(bs);
3293 	CU_ASSERT(channel != NULL);
3294 
3295 	spdk_blob_opts_init(&opts);
3296 	opts.thin_provision = true;
3297 
3298 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
3299 	CU_ASSERT(g_bserrno == 0);
3300 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3301 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3302 	blobid = g_blobid;
3303 
3304 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
3305 	CU_ASSERT(g_bserrno == 0);
3306 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3307 	blob = g_blob;
3308 
3309 	CU_ASSERT(blob->active.num_clusters == 0);
3310 
3311 	/* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */
3312 	spdk_blob_resize(blob, 5, blob_op_complete, NULL);
3313 	CU_ASSERT(g_bserrno == 0);
3314 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3315 	CU_ASSERT(blob->active.num_clusters == 5);
3316 
3317 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
3318 	CU_ASSERT(g_bserrno == 0);
3319 	/* Sync must not change anything */
3320 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3321 	CU_ASSERT(blob->active.num_clusters == 5);
3322 
3323 	/* Payload should be all zeros from unallocated clusters */
3324 	memset(payload_read, 0xFF, sizeof(payload_read));
3325 	spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL);
3326 	CU_ASSERT(g_bserrno == 0);
3327 	CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0);
3328 
3329 	memset(payload_write, 0xE5, sizeof(payload_write));
3330 	spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL);
3331 	CU_ASSERT(g_bserrno == 0);
3332 	CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs));
3333 
3334 	spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL);
3335 	CU_ASSERT(g_bserrno == 0);
3336 	CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0);
3337 
3338 	spdk_blob_close(blob, blob_op_complete, NULL);
3339 	CU_ASSERT(g_bserrno == 0);
3340 
3341 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
3342 	CU_ASSERT(g_bserrno == 0);
3343 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3344 
3345 	spdk_bs_free_io_channel(channel);
3346 
3347 	/* Unload the blob store */
3348 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3349 	CU_ASSERT(g_bserrno == 0);
3350 	g_bs = NULL;
3351 	g_blob = NULL;
3352 	g_blobid = 0;
3353 }
3354 
3355 static void
3356 blob_thin_prov_rw_iov(void)
3357 {
3358 	static const uint8_t zero[10 * 4096] = { 0 };
3359 	struct spdk_blob_store *bs;
3360 	struct spdk_bs_dev *dev;
3361 	struct spdk_blob *blob;
3362 	struct spdk_io_channel *channel;
3363 	struct spdk_blob_opts opts;
3364 	spdk_blob_id blobid;
3365 	uint64_t free_clusters;
3366 	uint8_t payload_read[10 * 4096];
3367 	uint8_t payload_write[10 * 4096];
3368 	struct iovec iov_read[3];
3369 	struct iovec iov_write[3];
3370 
3371 	dev = init_dev();
3372 
3373 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
3374 	CU_ASSERT(g_bserrno == 0);
3375 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3376 	bs = g_bs;
3377 	free_clusters = spdk_bs_free_cluster_count(bs);
3378 
3379 	channel = spdk_bs_alloc_io_channel(bs);
3380 	CU_ASSERT(channel != NULL);
3381 
3382 	spdk_blob_opts_init(&opts);
3383 	opts.thin_provision = true;
3384 
3385 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
3386 	CU_ASSERT(g_bserrno == 0);
3387 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3388 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3389 	blobid = g_blobid;
3390 
3391 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
3392 	CU_ASSERT(g_bserrno == 0);
3393 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3394 	blob = g_blob;
3395 
3396 	CU_ASSERT(blob->active.num_clusters == 0);
3397 
3398 	/* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */
3399 	spdk_blob_resize(blob, 5, blob_op_complete, NULL);
3400 	CU_ASSERT(g_bserrno == 0);
3401 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3402 	CU_ASSERT(blob->active.num_clusters == 5);
3403 
3404 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
3405 	CU_ASSERT(g_bserrno == 0);
3406 	/* Sync must not change anything */
3407 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3408 	CU_ASSERT(blob->active.num_clusters == 5);
3409 
3410 	/* Payload should be all zeros from unallocated clusters */
3411 	memset(payload_read, 0xAA, sizeof(payload_read));
3412 	iov_read[0].iov_base = payload_read;
3413 	iov_read[0].iov_len = 3 * 4096;
3414 	iov_read[1].iov_base = payload_read + 3 * 4096;
3415 	iov_read[1].iov_len = 4 * 4096;
3416 	iov_read[2].iov_base = payload_read + 7 * 4096;
3417 	iov_read[2].iov_len = 3 * 4096;
3418 	spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL);
3419 	CU_ASSERT(g_bserrno == 0);
3420 	CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0);
3421 
3422 	memset(payload_write, 0xE5, sizeof(payload_write));
3423 	iov_write[0].iov_base = payload_write;
3424 	iov_write[0].iov_len = 1 * 4096;
3425 	iov_write[1].iov_base = payload_write + 1 * 4096;
3426 	iov_write[1].iov_len = 5 * 4096;
3427 	iov_write[2].iov_base = payload_write + 6 * 4096;
3428 	iov_write[2].iov_len = 4 * 4096;
3429 
3430 	spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL);
3431 	CU_ASSERT(g_bserrno == 0);
3432 
3433 	memset(payload_read, 0xAA, sizeof(payload_read));
3434 	iov_read[0].iov_base = payload_read;
3435 	iov_read[0].iov_len = 3 * 4096;
3436 	iov_read[1].iov_base = payload_read + 3 * 4096;
3437 	iov_read[1].iov_len = 4 * 4096;
3438 	iov_read[2].iov_base = payload_read + 7 * 4096;
3439 	iov_read[2].iov_len = 3 * 4096;
3440 	spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL);
3441 	CU_ASSERT(g_bserrno == 0);
3442 	CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0);
3443 
3444 	spdk_blob_close(blob, blob_op_complete, NULL);
3445 	CU_ASSERT(g_bserrno == 0);
3446 
3447 	spdk_bs_free_io_channel(channel);
3448 
3449 	/* Unload the blob store */
3450 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3451 	CU_ASSERT(g_bserrno == 0);
3452 	g_bs = NULL;
3453 	g_blob = NULL;
3454 	g_blobid = 0;
3455 }
3456 
3457 struct iter_ctx {
3458 	int		current_iter;
3459 	spdk_blob_id	blobid[4];
3460 };
3461 
3462 static void
3463 test_iter(void *arg, struct spdk_blob *blob, int bserrno)
3464 {
3465 	struct iter_ctx *iter_ctx = arg;
3466 	spdk_blob_id blobid;
3467 
3468 	CU_ASSERT(bserrno == 0);
3469 	blobid = spdk_blob_get_id(blob);
3470 	CU_ASSERT(blobid == iter_ctx->blobid[iter_ctx->current_iter++]);
3471 }
3472 
3473 static void
3474 bs_load_iter(void)
3475 {
3476 	struct spdk_bs_dev *dev;
3477 	struct iter_ctx iter_ctx = { 0 };
3478 	struct spdk_blob *blob;
3479 	int i, rc;
3480 	struct spdk_bs_opts opts;
3481 
3482 	dev = init_dev();
3483 	spdk_bs_opts_init(&opts);
3484 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
3485 
3486 	/* Initialize a new blob store */
3487 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
3488 	CU_ASSERT(g_bserrno == 0);
3489 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3490 
3491 	for (i = 0; i < 4; i++) {
3492 		g_bserrno = -1;
3493 		g_blobid = SPDK_BLOBID_INVALID;
3494 		spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
3495 		CU_ASSERT(g_bserrno == 0);
3496 		CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3497 		iter_ctx.blobid[i] = g_blobid;
3498 
3499 		g_bserrno = -1;
3500 		g_blob = NULL;
3501 		spdk_bs_open_blob(g_bs, g_blobid, blob_op_with_handle_complete, NULL);
3502 		CU_ASSERT(g_bserrno == 0);
3503 		CU_ASSERT(g_blob != NULL);
3504 		blob = g_blob;
3505 
3506 		/* Just save the blobid as an xattr for testing purposes. */
3507 		rc = spdk_blob_set_xattr(blob, "blobid", &g_blobid, sizeof(g_blobid));
3508 		CU_ASSERT(rc == 0);
3509 
3510 		/* Resize the blob */
3511 		spdk_blob_resize(blob, i, blob_op_complete, NULL);
3512 		CU_ASSERT(g_bserrno == 0);
3513 
3514 		spdk_blob_close(blob, blob_op_complete, NULL);
3515 		CU_ASSERT(g_bserrno == 0);
3516 	}
3517 
3518 	g_bserrno = -1;
3519 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3520 	CU_ASSERT(g_bserrno == 0);
3521 
3522 	dev = init_dev();
3523 	spdk_bs_opts_init(&opts);
3524 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
3525 	opts.iter_cb_fn = test_iter;
3526 	opts.iter_cb_arg = &iter_ctx;
3527 
3528 	/* Test blob iteration during load after a clean shutdown. */
3529 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
3530 	CU_ASSERT(g_bserrno == 0);
3531 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3532 
3533 	/* Dirty shutdown */
3534 	_spdk_bs_free(g_bs);
3535 
3536 	dev = init_dev();
3537 	spdk_bs_opts_init(&opts);
3538 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
3539 	opts.iter_cb_fn = test_iter;
3540 	iter_ctx.current_iter = 0;
3541 	opts.iter_cb_arg = &iter_ctx;
3542 
3543 	/* Test blob iteration during load after a dirty shutdown. */
3544 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
3545 	CU_ASSERT(g_bserrno == 0);
3546 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3547 
3548 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3549 	CU_ASSERT(g_bserrno == 0);
3550 	g_bs = NULL;
3551 }
3552 
3553 static void
3554 blob_snapshot_rw(void)
3555 {
3556 	static const uint8_t zero[10 * 4096] = { 0 };
3557 	struct spdk_blob_store *bs;
3558 	struct spdk_bs_dev *dev;
3559 	struct spdk_blob *blob, *snapshot;
3560 	struct spdk_io_channel *channel;
3561 	struct spdk_blob_opts opts;
3562 	spdk_blob_id blobid, snapshotid;
3563 	uint64_t free_clusters;
3564 	uint8_t payload_read[10 * 4096];
3565 	uint8_t payload_write[10 * 4096];
3566 
3567 	dev = init_dev();
3568 
3569 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
3570 	CU_ASSERT(g_bserrno == 0);
3571 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3572 	bs = g_bs;
3573 	free_clusters = spdk_bs_free_cluster_count(bs);
3574 
3575 	channel = spdk_bs_alloc_io_channel(bs);
3576 	CU_ASSERT(channel != NULL);
3577 
3578 	spdk_blob_opts_init(&opts);
3579 	opts.thin_provision = true;
3580 	opts.num_clusters = 5;
3581 
3582 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
3583 	CU_ASSERT(g_bserrno == 0);
3584 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3585 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3586 	blobid = g_blobid;
3587 
3588 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
3589 	CU_ASSERT(g_bserrno == 0);
3590 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3591 	blob = g_blob;
3592 
3593 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5);
3594 
3595 	memset(payload_read, 0xFF, sizeof(payload_read));
3596 	spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL);
3597 	CU_ASSERT(g_bserrno == 0);
3598 	CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0);
3599 
3600 	memset(payload_write, 0xE5, sizeof(payload_write));
3601 	spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL);
3602 	CU_ASSERT(g_bserrno == 0);
3603 	CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs));
3604 
3605 	/* Create snapshot from blob */
3606 	spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL);
3607 	CU_ASSERT(g_bserrno == 0);
3608 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3609 	snapshotid = g_blobid;
3610 
3611 	spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL);
3612 	CU_ASSERT(g_bserrno == 0);
3613 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3614 	snapshot = g_blob;
3615 	CU_ASSERT(snapshot->data_ro == true)
3616 	CU_ASSERT(snapshot->md_ro == true)
3617 
3618 	CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 5)
3619 
3620 	memset(payload_write, 0xAA, sizeof(payload_write));
3621 	spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL);
3622 	CU_ASSERT(g_bserrno == 0);
3623 	CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs));
3624 
3625 	spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL);
3626 	CU_ASSERT(g_bserrno == 0);
3627 	CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0);
3628 
3629 	/* Data on snapshot should not change after write to clone */
3630 	memset(payload_write, 0xE5, sizeof(payload_write));
3631 	spdk_blob_io_read(snapshot, channel, payload_read, 4, 10, blob_op_complete, NULL);
3632 	CU_ASSERT(g_bserrno == 0);
3633 	CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0);
3634 
3635 	spdk_blob_close(blob, blob_op_complete, NULL);
3636 	CU_ASSERT(g_bserrno == 0);
3637 
3638 	spdk_blob_close(snapshot, blob_op_complete, NULL);
3639 	CU_ASSERT(g_bserrno == 0);
3640 
3641 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
3642 	CU_ASSERT(g_bserrno == 0);
3643 
3644 	spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL);
3645 	CU_ASSERT(g_bserrno == 0);
3646 
3647 	spdk_bs_free_io_channel(channel);
3648 
3649 	/* Unload the blob store */
3650 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3651 	CU_ASSERT(g_bserrno == 0);
3652 	g_bs = NULL;
3653 	g_blob = NULL;
3654 	g_blobid = 0;
3655 }
3656 
3657 static void
3658 blob_snapshot_rw_iov(void)
3659 {
3660 	static const uint8_t zero[10 * 4096] = { 0 };
3661 	struct spdk_blob_store *bs;
3662 	struct spdk_bs_dev *dev;
3663 	struct spdk_blob *blob, *snapshot;
3664 	struct spdk_io_channel *channel;
3665 	struct spdk_blob_opts opts;
3666 	spdk_blob_id blobid, snapshotid;
3667 	uint64_t free_clusters;
3668 	uint8_t payload_read[10 * 4096];
3669 	uint8_t payload_write[10 * 4096];
3670 	struct iovec iov_read[3];
3671 	struct iovec iov_write[3];
3672 
3673 	dev = init_dev();
3674 
3675 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
3676 	CU_ASSERT(g_bserrno == 0);
3677 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3678 	bs = g_bs;
3679 	free_clusters = spdk_bs_free_cluster_count(bs);
3680 
3681 	channel = spdk_bs_alloc_io_channel(bs);
3682 	CU_ASSERT(channel != NULL);
3683 
3684 	spdk_blob_opts_init(&opts);
3685 	opts.thin_provision = true;
3686 	opts.num_clusters = 5;
3687 
3688 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
3689 	CU_ASSERT(g_bserrno == 0);
3690 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3691 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3692 	blobid = g_blobid;
3693 
3694 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
3695 	CU_ASSERT(g_bserrno == 0);
3696 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3697 	blob = g_blob;
3698 
3699 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5);
3700 
3701 	/* Create snapshot from blob */
3702 	spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL);
3703 	CU_ASSERT(g_bserrno == 0);
3704 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3705 	snapshotid = g_blobid;
3706 
3707 	spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL);
3708 	CU_ASSERT(g_bserrno == 0);
3709 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3710 	snapshot = g_blob;
3711 	CU_ASSERT(snapshot->data_ro == true)
3712 	CU_ASSERT(snapshot->md_ro == true)
3713 	CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 5);
3714 
3715 	/* Payload should be all zeros from unallocated clusters */
3716 	memset(payload_read, 0xAA, sizeof(payload_read));
3717 	iov_read[0].iov_base = payload_read;
3718 	iov_read[0].iov_len = 3 * 4096;
3719 	iov_read[1].iov_base = payload_read + 3 * 4096;
3720 	iov_read[1].iov_len = 4 * 4096;
3721 	iov_read[2].iov_base = payload_read + 7 * 4096;
3722 	iov_read[2].iov_len = 3 * 4096;
3723 	spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL);
3724 	CU_ASSERT(g_bserrno == 0);
3725 	CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0);
3726 
3727 	memset(payload_write, 0xE5, sizeof(payload_write));
3728 	iov_write[0].iov_base = payload_write;
3729 	iov_write[0].iov_len = 1 * 4096;
3730 	iov_write[1].iov_base = payload_write + 1 * 4096;
3731 	iov_write[1].iov_len = 5 * 4096;
3732 	iov_write[2].iov_base = payload_write + 6 * 4096;
3733 	iov_write[2].iov_len = 4 * 4096;
3734 
3735 	spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL);
3736 	CU_ASSERT(g_bserrno == 0);
3737 
3738 	memset(payload_read, 0xAA, sizeof(payload_read));
3739 	iov_read[0].iov_base = payload_read;
3740 	iov_read[0].iov_len = 3 * 4096;
3741 	iov_read[1].iov_base = payload_read + 3 * 4096;
3742 	iov_read[1].iov_len = 4 * 4096;
3743 	iov_read[2].iov_base = payload_read + 7 * 4096;
3744 	iov_read[2].iov_len = 3 * 4096;
3745 	spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL);
3746 	CU_ASSERT(g_bserrno == 0);
3747 	CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0);
3748 
3749 	spdk_blob_close(blob, blob_op_complete, NULL);
3750 	CU_ASSERT(g_bserrno == 0);
3751 
3752 	spdk_blob_close(snapshot, blob_op_complete, NULL);
3753 	CU_ASSERT(g_bserrno == 0);
3754 
3755 	spdk_bs_free_io_channel(channel);
3756 
3757 	/* Unload the blob store */
3758 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3759 	CU_ASSERT(g_bserrno == 0);
3760 	g_bs = NULL;
3761 	g_blob = NULL;
3762 	g_blobid = 0;
3763 }
3764 
3765 /**
3766  * Snapshot-clones relation test
3767  *
3768  *      snapshot
3769  *          |
3770  *     +----+----+
3771  *     |         |
3772  *   blob      clone
3773  *     |
3774  *  clone2
3775  */
3776 static void
3777 blob_relations(void)
3778 {
3779 	struct spdk_blob_store *bs;
3780 	struct spdk_bs_dev *dev;
3781 	struct spdk_bs_opts bs_opts;
3782 	struct spdk_blob_opts opts;
3783 	struct spdk_blob *blob, *snapshot, *clone, *clone2;
3784 	spdk_blob_id blobid, cloneid, snapshotid, cloneid2;
3785 	int rc;
3786 	size_t count;
3787 	spdk_blob_id ids[10];
3788 
3789 	dev = init_dev();
3790 	spdk_bs_opts_init(&bs_opts);
3791 	snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE");
3792 
3793 	spdk_bs_init(dev, &bs_opts, bs_op_with_handle_complete, NULL);
3794 	CU_ASSERT(g_bserrno == 0);
3795 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3796 	bs = g_bs;
3797 
3798 	/* 1. Create blob with 10 clusters */
3799 
3800 	spdk_blob_opts_init(&opts);
3801 	opts.num_clusters = 10;
3802 
3803 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
3804 	CU_ASSERT(g_bserrno == 0);
3805 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3806 	blobid = g_blobid;
3807 
3808 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
3809 	CU_ASSERT(g_bserrno == 0);
3810 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3811 	blob = g_blob;
3812 
3813 	CU_ASSERT(!spdk_blob_is_read_only(blob));
3814 	CU_ASSERT(!spdk_blob_is_snapshot(blob));
3815 	CU_ASSERT(!spdk_blob_is_clone(blob));
3816 	CU_ASSERT(!spdk_blob_is_thin_provisioned(blob));
3817 
3818 	/* blob should not have underlying snapshot nor clones */
3819 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == SPDK_BLOBID_INVALID);
3820 	count = SPDK_COUNTOF(ids);
3821 	rc = spdk_blob_get_clones(bs, blobid, ids, &count);
3822 	CU_ASSERT(rc == 0);
3823 	CU_ASSERT(count == 0);
3824 
3825 
3826 	/* 2. Create snapshot */
3827 
3828 	spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL);
3829 	CU_ASSERT(g_bserrno == 0);
3830 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3831 	snapshotid = g_blobid;
3832 
3833 	spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL);
3834 	CU_ASSERT(g_bserrno == 0);
3835 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3836 	snapshot = g_blob;
3837 
3838 	CU_ASSERT(spdk_blob_is_read_only(snapshot));
3839 	CU_ASSERT(spdk_blob_is_snapshot(snapshot));
3840 	CU_ASSERT(!spdk_blob_is_clone(snapshot));
3841 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid) == SPDK_BLOBID_INVALID);
3842 
3843 	/* Check if original blob is converted to the clone of snapshot */
3844 	CU_ASSERT(!spdk_blob_is_read_only(blob));
3845 	CU_ASSERT(!spdk_blob_is_snapshot(blob));
3846 	CU_ASSERT(spdk_blob_is_clone(blob));
3847 	CU_ASSERT(spdk_blob_is_thin_provisioned(blob));
3848 
3849 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid);
3850 
3851 	count = SPDK_COUNTOF(ids);
3852 	rc = spdk_blob_get_clones(bs, snapshotid, ids, &count);
3853 	CU_ASSERT(rc == 0);
3854 	CU_ASSERT(count == 1);
3855 	CU_ASSERT(ids[0] == blobid);
3856 
3857 
3858 	/* 3. Create clone from snapshot */
3859 
3860 	spdk_bs_create_clone(bs, snapshotid, NULL, blob_op_with_id_complete, NULL);
3861 	CU_ASSERT(g_bserrno == 0);
3862 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3863 	cloneid = g_blobid;
3864 
3865 	spdk_bs_open_blob(bs, cloneid, blob_op_with_handle_complete, NULL);
3866 	CU_ASSERT(g_bserrno == 0);
3867 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3868 	clone = g_blob;
3869 
3870 	CU_ASSERT(!spdk_blob_is_read_only(clone));
3871 	CU_ASSERT(!spdk_blob_is_snapshot(clone));
3872 	CU_ASSERT(spdk_blob_is_clone(clone));
3873 	CU_ASSERT(spdk_blob_is_thin_provisioned(clone));
3874 
3875 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid);
3876 
3877 	count = SPDK_COUNTOF(ids);
3878 	rc = spdk_blob_get_clones(bs, cloneid, ids, &count);
3879 	CU_ASSERT(rc == 0);
3880 	CU_ASSERT(count == 0);
3881 
3882 	/* Check if clone is on the snapshot's list */
3883 	count = SPDK_COUNTOF(ids);
3884 	rc = spdk_blob_get_clones(bs, snapshotid, ids, &count);
3885 	CU_ASSERT(rc == 0);
3886 	CU_ASSERT(ids[0] == blobid || ids[1] == blobid);
3887 	CU_ASSERT(ids[0] == cloneid || ids[1] == cloneid);
3888 
3889 
3890 	/* 4. Try to create clone from read only blob */
3891 
3892 	/* Mark blob as read only */
3893 	spdk_blob_set_read_only(blob);
3894 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
3895 	CU_ASSERT(g_bserrno == 0);
3896 
3897 	/* Check if previously created blob is read only clone */
3898 	CU_ASSERT(spdk_blob_is_read_only(blob));
3899 	CU_ASSERT(!spdk_blob_is_snapshot(blob));
3900 	CU_ASSERT(spdk_blob_is_clone(blob));
3901 	CU_ASSERT(spdk_blob_is_thin_provisioned(blob));
3902 
3903 	/* Create clone from read only blob */
3904 	spdk_bs_create_clone(bs, blobid, NULL, blob_op_with_id_complete, NULL);
3905 	CU_ASSERT(g_bserrno == 0);
3906 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3907 	cloneid2 = g_blobid;
3908 
3909 	spdk_bs_open_blob(bs, cloneid2, blob_op_with_handle_complete, NULL);
3910 	CU_ASSERT(g_bserrno == 0);
3911 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3912 	clone2 = g_blob;
3913 
3914 	CU_ASSERT(!spdk_blob_is_read_only(clone2));
3915 	CU_ASSERT(!spdk_blob_is_snapshot(clone2));
3916 	CU_ASSERT(spdk_blob_is_clone(clone2));
3917 	CU_ASSERT(spdk_blob_is_thin_provisioned(clone2));
3918 
3919 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid2) == blobid);
3920 
3921 	count = SPDK_COUNTOF(ids);
3922 	rc = spdk_blob_get_clones(bs, blobid, ids, &count);
3923 	CU_ASSERT(rc == 0);
3924 
3925 	CU_ASSERT(count == 1);
3926 	CU_ASSERT(ids[0] == cloneid2);
3927 
3928 	/* Close blobs */
3929 
3930 	spdk_blob_close(clone2, blob_op_complete, NULL);
3931 	CU_ASSERT(g_bserrno == 0);
3932 
3933 	spdk_blob_close(blob, blob_op_complete, NULL);
3934 	CU_ASSERT(g_bserrno == 0);
3935 
3936 	spdk_blob_close(clone, blob_op_complete, NULL);
3937 	CU_ASSERT(g_bserrno == 0);
3938 
3939 	spdk_blob_close(snapshot, blob_op_complete, NULL);
3940 	CU_ASSERT(g_bserrno == 0);
3941 
3942 	/* Try to delete snapshot with created clones */
3943 	spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL);
3944 	CU_ASSERT(g_bserrno != 0);
3945 
3946 	spdk_bs_unload(bs, bs_op_complete, NULL);
3947 	CU_ASSERT(g_bserrno == 0);
3948 	g_bs = NULL;
3949 
3950 	/* Load an existing blob store */
3951 	dev = init_dev();
3952 	snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE");
3953 
3954 	spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL);
3955 	CU_ASSERT(g_bserrno == 0);
3956 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3957 	bs = g_bs;
3958 
3959 
3960 	/* NULL ids array should return number of clones in count */
3961 	count = SPDK_COUNTOF(ids);
3962 	rc = spdk_blob_get_clones(bs, snapshotid, NULL, &count);
3963 	CU_ASSERT(rc == -ENOMEM);
3964 	CU_ASSERT(count == 2);
3965 
3966 	/* incorrect array size */
3967 	count = 1;
3968 	rc = spdk_blob_get_clones(bs, snapshotid, ids, &count);
3969 	CU_ASSERT(rc == -ENOMEM);
3970 	CU_ASSERT(count == 2);
3971 
3972 
3973 	/* Verify structure of loaded blob store */
3974 
3975 	/* snapshot */
3976 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid) == SPDK_BLOBID_INVALID);
3977 
3978 	count = SPDK_COUNTOF(ids);
3979 	rc = spdk_blob_get_clones(bs, snapshotid, ids, &count);
3980 	CU_ASSERT(rc == 0);
3981 	CU_ASSERT(count == 2);
3982 	CU_ASSERT(ids[0] == blobid || ids[1] == blobid);
3983 	CU_ASSERT(ids[0] == cloneid || ids[1] == cloneid);
3984 
3985 	/* blob */
3986 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid);
3987 	count = SPDK_COUNTOF(ids);
3988 	rc = spdk_blob_get_clones(bs, blobid, ids, &count);
3989 	CU_ASSERT(rc == 0);
3990 	CU_ASSERT(count == 1);
3991 	CU_ASSERT(ids[0] == cloneid2);
3992 
3993 	/* clone */
3994 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid);
3995 	count = SPDK_COUNTOF(ids);
3996 	rc = spdk_blob_get_clones(bs, cloneid, ids, &count);
3997 	CU_ASSERT(rc == 0);
3998 	CU_ASSERT(count == 0);
3999 
4000 	/* clone2 */
4001 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid2) == blobid);
4002 	count = SPDK_COUNTOF(ids);
4003 	rc = spdk_blob_get_clones(bs, cloneid2, ids, &count);
4004 	CU_ASSERT(rc == 0);
4005 	CU_ASSERT(count == 0);
4006 
4007 	/* Try to delete all blobs */
4008 	spdk_bs_delete_blob(bs, cloneid, blob_op_complete, NULL);
4009 	CU_ASSERT(g_bserrno == 0);
4010 
4011 	/* Try to delete snapshot with clones */
4012 	spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL);
4013 	CU_ASSERT(g_bserrno != 0);
4014 
4015 	/* Try to delete ro blob with clones */
4016 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
4017 	CU_ASSERT(g_bserrno != 0);
4018 
4019 	spdk_bs_delete_blob(bs, cloneid2, blob_op_complete, NULL);
4020 	CU_ASSERT(g_bserrno == 0);
4021 
4022 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
4023 	CU_ASSERT(g_bserrno == 0);
4024 
4025 	spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL);
4026 	CU_ASSERT(g_bserrno == 0);
4027 
4028 	spdk_bs_unload(bs, bs_op_complete, NULL);
4029 	CU_ASSERT(g_bserrno == 0);
4030 
4031 	g_bs = NULL;
4032 }
4033 
4034 int main(int argc, char **argv)
4035 {
4036 	CU_pSuite	suite = NULL;
4037 	unsigned int	num_failures;
4038 
4039 	if (CU_initialize_registry() != CUE_SUCCESS) {
4040 		return CU_get_error();
4041 	}
4042 
4043 	suite = CU_add_suite("blob", NULL, NULL);
4044 	if (suite == NULL) {
4045 		CU_cleanup_registry();
4046 		return CU_get_error();
4047 	}
4048 
4049 	if (
4050 		CU_add_test(suite, "blob_init", blob_init) == NULL ||
4051 		CU_add_test(suite, "blob_open", blob_open) == NULL ||
4052 		CU_add_test(suite, "blob_create", blob_create) == NULL ||
4053 		CU_add_test(suite, "blob_create_internal", blob_create_internal) == NULL ||
4054 		CU_add_test(suite, "blob_thin_provision", blob_thin_provision) == NULL ||
4055 		CU_add_test(suite, "blob_snapshot", blob_snapshot) == NULL ||
4056 		CU_add_test(suite, "blob_clone", blob_clone) == NULL ||
4057 		CU_add_test(suite, "blob_delete", blob_delete) == NULL ||
4058 		CU_add_test(suite, "blob_resize", blob_resize) == NULL ||
4059 		CU_add_test(suite, "blob_read_only", blob_read_only) == NULL ||
4060 		CU_add_test(suite, "channel_ops", channel_ops) == NULL ||
4061 		CU_add_test(suite, "blob_super", blob_super) == NULL ||
4062 		CU_add_test(suite, "blob_write", blob_write) == NULL ||
4063 		CU_add_test(suite, "blob_read", blob_read) == NULL ||
4064 		CU_add_test(suite, "blob_rw_verify", blob_rw_verify) == NULL ||
4065 		CU_add_test(suite, "blob_rw_verify_iov", blob_rw_verify_iov) == NULL ||
4066 		CU_add_test(suite, "blob_rw_verify_iov_nomem", blob_rw_verify_iov_nomem) == NULL ||
4067 		CU_add_test(suite, "blob_rw_iov_read_only", blob_rw_iov_read_only) == NULL ||
4068 		CU_add_test(suite, "blob_unmap", blob_unmap) == NULL ||
4069 		CU_add_test(suite, "blob_iter", blob_iter) == NULL ||
4070 		CU_add_test(suite, "blob_xattr", blob_xattr) == NULL ||
4071 		CU_add_test(suite, "bs_load", bs_load) == NULL ||
4072 		CU_add_test(suite, "bs_unload", bs_unload) == NULL ||
4073 		CU_add_test(suite, "bs_cluster_sz", bs_cluster_sz) == NULL ||
4074 		CU_add_test(suite, "bs_usable_clusters", bs_usable_clusters) == NULL ||
4075 		CU_add_test(suite, "bs_resize_md", bs_resize_md) == NULL ||
4076 		CU_add_test(suite, "bs_destroy", bs_destroy) == NULL ||
4077 		CU_add_test(suite, "bs_type", bs_type) == NULL ||
4078 		CU_add_test(suite, "bs_super_block", bs_super_block) == NULL ||
4079 		CU_add_test(suite, "blob_serialize", blob_serialize) == NULL ||
4080 		CU_add_test(suite, "blob_crc", blob_crc) == NULL ||
4081 		CU_add_test(suite, "super_block_crc", super_block_crc) == NULL ||
4082 		CU_add_test(suite, "blob_dirty_shutdown", blob_dirty_shutdown) == NULL ||
4083 		CU_add_test(suite, "blob_flags", blob_flags) == NULL ||
4084 		CU_add_test(suite, "bs_version", bs_version) == NULL ||
4085 		CU_add_test(suite, "blob_set_xattrs", blob_set_xattrs) == NULL ||
4086 		CU_add_test(suite, "blob_thin_prov_alloc", blob_thin_prov_alloc) == NULL ||
4087 		CU_add_test(suite, "blob_insert_cluster_msg", blob_insert_cluster_msg) == NULL ||
4088 		CU_add_test(suite, "blob_thin_prov_rw", blob_thin_prov_rw) == NULL ||
4089 		CU_add_test(suite, "blob_thin_prov_rw_iov", blob_thin_prov_rw_iov) == NULL ||
4090 		CU_add_test(suite, "bs_load_iter", bs_load_iter) == NULL ||
4091 		CU_add_test(suite, "blob_snapshot_rw", blob_snapshot_rw) == NULL ||
4092 		CU_add_test(suite, "blob_snapshot_rw_iov", blob_snapshot_rw_iov) == NULL ||
4093 		CU_add_test(suite, "blob_relations", blob_relations) == NULL
4094 	) {
4095 		CU_cleanup_registry();
4096 		return CU_get_error();
4097 	}
4098 
4099 	g_dev_buffer = calloc(1, DEV_BUFFER_SIZE);
4100 	spdk_allocate_thread(_bs_send_msg, NULL, NULL, NULL, "thread0");
4101 	CU_basic_set_mode(CU_BRM_VERBOSE);
4102 	CU_basic_run_tests();
4103 	num_failures = CU_get_number_of_failures();
4104 	CU_cleanup_registry();
4105 	spdk_free_thread();
4106 	free(g_dev_buffer);
4107 	return num_failures;
4108 }
4109