xref: /spdk/test/unit/lib/blob/blob.c/blob_ut.c (revision c1174e6895ca44242d12b2e5f0742f84ccbf0b8f)
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 
39 #include "lib/test_env.c"
40 #include "../bs_dev_common.c"
41 #include "blob/blobstore.c"
42 #include "blob/request.c"
43 #include "blob/zeroes.c"
44 #include "blob/blob_bs_dev.c"
45 
46 struct spdk_blob_store *g_bs;
47 spdk_blob_id g_blobid;
48 struct spdk_blob *g_blob;
49 int g_bserrno;
50 struct spdk_xattr_names *g_names;
51 int g_done;
52 char *g_xattr_names[] = {"first", "second", "third"};
53 char *g_xattr_values[] = {"one", "two", "three"};
54 uint64_t g_ctx = 1729;
55 
56 bool g_scheduler_delay = false;
57 
58 struct scheduled_ops {
59 	spdk_thread_fn	fn;
60 	void		*ctx;
61 
62 	TAILQ_ENTRY(scheduled_ops)	ops_queue;
63 };
64 
65 static TAILQ_HEAD(, scheduled_ops) g_scheduled_ops = TAILQ_HEAD_INITIALIZER(g_scheduled_ops);
66 
67 struct spdk_bs_super_block_ver1 {
68 	uint8_t		signature[8];
69 	uint32_t        version;
70 	uint32_t        length;
71 	uint32_t	clean; /* If there was a clean shutdown, this is 1. */
72 	spdk_blob_id	super_blob;
73 
74 	uint32_t	cluster_size; /* In bytes */
75 
76 	uint32_t	used_page_mask_start; /* Offset from beginning of disk, in pages */
77 	uint32_t	used_page_mask_len; /* Count, in pages */
78 
79 	uint32_t	used_cluster_mask_start; /* Offset from beginning of disk, in pages */
80 	uint32_t	used_cluster_mask_len; /* Count, in pages */
81 
82 	uint32_t	md_start; /* Offset from beginning of disk, in pages */
83 	uint32_t	md_len; /* Count, in pages */
84 
85 	uint8_t		reserved[4036];
86 	uint32_t	crc;
87 } __attribute__((packed));
88 SPDK_STATIC_ASSERT(sizeof(struct spdk_bs_super_block_ver1) == 0x1000, "Invalid super block size");
89 
90 static void
91 _bs_send_msg(spdk_thread_fn fn, void *ctx, void *thread_ctx)
92 {
93 	if (g_scheduler_delay) {
94 		struct scheduled_ops *ops = calloc(1, sizeof(*ops));
95 
96 		SPDK_CU_ASSERT_FATAL(ops != NULL);
97 		ops->fn = fn;
98 		ops->ctx = ctx;
99 		TAILQ_INSERT_TAIL(&g_scheduled_ops, ops, ops_queue);
100 	} else {
101 		fn(ctx);
102 	}
103 }
104 
105 #if 0
106 static void
107 _bs_flush_scheduler(void)
108 {
109 	struct scheduled_ops *ops;
110 
111 	while (!TAILQ_EMPTY(&g_scheduled_ops)) {
112 		ops = TAILQ_FIRST(&g_scheduled_ops);
113 		TAILQ_REMOVE(&g_scheduled_ops, ops, ops_queue);
114 		ops->fn(ops->ctx);
115 		free(ops);
116 	}
117 }
118 #endif
119 
120 static void
121 bs_op_complete(void *cb_arg, int bserrno)
122 {
123 	g_bserrno = bserrno;
124 }
125 
126 static void
127 bs_op_with_handle_complete(void *cb_arg, struct spdk_blob_store *bs,
128 			   int bserrno)
129 {
130 	g_bs = bs;
131 	g_bserrno = bserrno;
132 }
133 
134 static void
135 blob_op_complete(void *cb_arg, int bserrno)
136 {
137 	g_bserrno = bserrno;
138 }
139 
140 static void
141 blob_op_with_id_complete(void *cb_arg, spdk_blob_id blobid, int bserrno)
142 {
143 	g_blobid = blobid;
144 	g_bserrno = bserrno;
145 }
146 
147 static void
148 blob_op_with_handle_complete(void *cb_arg, struct spdk_blob *blb, int bserrno)
149 {
150 	g_blob = blb;
151 	g_bserrno = bserrno;
152 }
153 
154 static void
155 blob_init(void)
156 {
157 	struct spdk_bs_dev *dev;
158 
159 	dev = init_dev();
160 
161 	/* should fail for an unsupported blocklen */
162 	dev->blocklen = 500;
163 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
164 	CU_ASSERT(g_bserrno == -EINVAL);
165 
166 	dev = init_dev();
167 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
168 	CU_ASSERT(g_bserrno == 0);
169 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
170 
171 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
172 	CU_ASSERT(g_bserrno == 0);
173 	g_bs = NULL;
174 }
175 
176 static void
177 blob_super(void)
178 {
179 	struct spdk_blob_store *bs;
180 	struct spdk_bs_dev *dev;
181 	spdk_blob_id blobid;
182 
183 	dev = init_dev();
184 
185 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
186 	CU_ASSERT(g_bserrno == 0);
187 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
188 	bs = g_bs;
189 
190 	/* Get the super blob without having set one */
191 	spdk_bs_get_super(bs, blob_op_with_id_complete, NULL);
192 	CU_ASSERT(g_bserrno == -ENOENT);
193 	CU_ASSERT(g_blobid == SPDK_BLOBID_INVALID);
194 
195 	/* Create a blob */
196 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
197 	CU_ASSERT(g_bserrno == 0);
198 	CU_ASSERT(g_blobid !=  SPDK_BLOBID_INVALID);
199 	blobid = g_blobid;
200 
201 	/* Set the blob as the super blob */
202 	spdk_bs_set_super(bs, blobid, blob_op_complete, NULL);
203 	CU_ASSERT(g_bserrno == 0);
204 
205 	/* Get the super blob */
206 	spdk_bs_get_super(bs, blob_op_with_id_complete, NULL);
207 	CU_ASSERT(g_bserrno == 0);
208 	CU_ASSERT(blobid == g_blobid);
209 
210 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
211 	CU_ASSERT(g_bserrno == 0);
212 	g_bs = NULL;
213 }
214 
215 static void
216 blob_open(void)
217 {
218 	struct spdk_blob_store *bs;
219 	struct spdk_bs_dev *dev;
220 	struct spdk_blob *blob;
221 	spdk_blob_id blobid, blobid2;
222 
223 	dev = init_dev();
224 
225 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
226 	CU_ASSERT(g_bserrno == 0);
227 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
228 	bs = g_bs;
229 
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 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
236 	CU_ASSERT(g_bserrno == 0);
237 	CU_ASSERT(g_blob != NULL);
238 	blob = g_blob;
239 
240 	blobid2 = spdk_blob_get_id(blob);
241 	CU_ASSERT(blobid == blobid2);
242 
243 	/* Try to open file again.  It should return success. */
244 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
245 	CU_ASSERT(g_bserrno == 0);
246 	CU_ASSERT(blob == g_blob);
247 
248 	spdk_blob_close(blob, blob_op_complete, NULL);
249 	CU_ASSERT(g_bserrno == 0);
250 
251 	/*
252 	 * Close the file a second time, releasing the second reference.  This
253 	 *  should succeed.
254 	 */
255 	blob = g_blob;
256 	spdk_blob_close(blob, blob_op_complete, NULL);
257 	CU_ASSERT(g_bserrno == 0);
258 
259 	/*
260 	 * Try to open file again.  It should succeed.  This tests the case
261 	 *  where the file is opened, closed, then re-opened again.
262 	 */
263 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
264 	CU_ASSERT(g_bserrno == 0);
265 	CU_ASSERT(g_blob != NULL);
266 	blob = g_blob;
267 
268 	spdk_blob_close(blob, blob_op_complete, NULL);
269 	CU_ASSERT(g_bserrno == 0);
270 
271 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
272 	CU_ASSERT(g_bserrno == 0);
273 	g_bs = NULL;
274 }
275 
276 static void
277 blob_create(void)
278 {
279 	struct spdk_blob_store *bs;
280 	struct spdk_bs_dev *dev;
281 	struct spdk_blob *blob;
282 	struct spdk_blob_opts opts;
283 	spdk_blob_id blobid;
284 
285 	dev = init_dev();
286 
287 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
288 	CU_ASSERT(g_bserrno == 0);
289 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
290 	bs = g_bs;
291 
292 	/* Create blob with 10 clusters */
293 
294 	spdk_blob_opts_init(&opts);
295 	opts.num_clusters = 10;
296 
297 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
298 	CU_ASSERT(g_bserrno == 0);
299 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
300 	blobid = g_blobid;
301 
302 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
303 	CU_ASSERT(g_bserrno == 0);
304 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
305 	blob = g_blob;
306 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10)
307 
308 	spdk_blob_close(blob, blob_op_complete, NULL);
309 	CU_ASSERT(g_bserrno == 0);
310 
311 	/* Create blob with 0 clusters */
312 
313 	spdk_blob_opts_init(&opts);
314 	opts.num_clusters = 0;
315 
316 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
317 	CU_ASSERT(g_bserrno == 0);
318 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
319 	blobid = g_blobid;
320 
321 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
322 	CU_ASSERT(g_bserrno == 0);
323 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
324 	blob = g_blob;
325 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0)
326 
327 	spdk_blob_close(blob, blob_op_complete, NULL);
328 	CU_ASSERT(g_bserrno == 0);
329 
330 	/* Create blob with default options (opts == NULL) */
331 
332 	spdk_bs_create_blob_ext(bs, NULL, blob_op_with_id_complete, NULL);
333 	CU_ASSERT(g_bserrno == 0);
334 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
335 	blobid = g_blobid;
336 
337 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
338 	CU_ASSERT(g_bserrno == 0);
339 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
340 	blob = g_blob;
341 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0)
342 
343 	spdk_blob_close(blob, blob_op_complete, NULL);
344 	CU_ASSERT(g_bserrno == 0);
345 
346 	/* Try to create blob with size larger than blobstore */
347 
348 	spdk_blob_opts_init(&opts);
349 	opts.num_clusters = bs->total_clusters + 1;
350 
351 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
352 	CU_ASSERT(g_bserrno == -ENOSPC);
353 
354 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
355 	CU_ASSERT(g_bserrno == 0);
356 	g_bs = NULL;
357 
358 }
359 
360 static void
361 blob_thin_provision(void)
362 {
363 	struct spdk_blob_store *bs;
364 	struct spdk_bs_dev *dev;
365 	struct spdk_blob *blob;
366 	struct spdk_blob_opts opts;
367 	struct spdk_bs_opts bs_opts;
368 	spdk_blob_id blobid;
369 
370 	dev = init_dev();
371 	spdk_bs_opts_init(&bs_opts);
372 	strncpy(bs_opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH);
373 
374 	/* Initialize a new blob store */
375 	spdk_bs_init(dev, &bs_opts, bs_op_with_handle_complete, NULL);
376 	CU_ASSERT(g_bserrno == 0);
377 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
378 
379 	bs = g_bs;
380 
381 	/* Create blob with thin provisioning enabled */
382 
383 	spdk_blob_opts_init(&opts);
384 	opts.thin_provision = true;
385 	opts.num_clusters = 10;
386 
387 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
388 	CU_ASSERT(g_bserrno == 0);
389 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
390 	blobid = g_blobid;
391 
392 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
393 	CU_ASSERT(g_bserrno == 0);
394 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
395 	blob = g_blob;
396 	CU_ASSERT(blob->invalid_flags & SPDK_BLOB_THIN_PROV);
397 
398 	spdk_blob_close(blob, blob_op_complete, NULL);
399 	CU_ASSERT(g_bserrno == 0);
400 
401 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
402 	CU_ASSERT(g_bserrno == 0);
403 	g_bs = NULL;
404 
405 	/* Load an existing blob store and check if invalid_flags is set */
406 	dev = init_dev();
407 	strncpy(bs_opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH);
408 	spdk_bs_load(dev, &bs_opts, bs_op_with_handle_complete, NULL);
409 	CU_ASSERT(g_bserrno == 0);
410 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
411 
412 	bs = g_bs;
413 
414 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
415 	CU_ASSERT(g_bserrno == 0);
416 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
417 	blob = g_blob;
418 	CU_ASSERT(blob->invalid_flags & SPDK_BLOB_THIN_PROV);
419 
420 	spdk_blob_close(blob, blob_op_complete, NULL);
421 	CU_ASSERT(g_bserrno == 0);
422 
423 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
424 	CU_ASSERT(g_bserrno == 0);
425 	g_bs = NULL;
426 }
427 
428 static void
429 blob_delete(void)
430 {
431 	struct spdk_blob_store *bs;
432 	struct spdk_bs_dev *dev;
433 	spdk_blob_id blobid;
434 
435 	dev = init_dev();
436 
437 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
438 	CU_ASSERT(g_bserrno == 0);
439 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
440 	bs = g_bs;
441 
442 	/* Create a blob and then delete it. */
443 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
444 	CU_ASSERT(g_bserrno == 0);
445 	CU_ASSERT(g_blobid > 0);
446 	blobid = g_blobid;
447 
448 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
449 	CU_ASSERT(g_bserrno == 0);
450 
451 	/* Try to open the blob */
452 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
453 	CU_ASSERT(g_bserrno == -ENOENT);
454 
455 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
456 	CU_ASSERT(g_bserrno == 0);
457 	g_bs = NULL;
458 }
459 
460 static void
461 blob_resize(void)
462 {
463 	struct spdk_blob_store *bs;
464 	struct spdk_bs_dev *dev;
465 	struct spdk_blob *blob;
466 	spdk_blob_id blobid;
467 	uint64_t free_clusters;
468 	int rc;
469 
470 	dev = init_dev();
471 
472 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
473 	CU_ASSERT(g_bserrno == 0);
474 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
475 	bs = g_bs;
476 	free_clusters = spdk_bs_free_cluster_count(bs);
477 
478 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
479 	CU_ASSERT(g_bserrno == 0);
480 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
481 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
482 	blobid = g_blobid;
483 
484 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
485 	CU_ASSERT(g_bserrno == 0);
486 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
487 	blob = g_blob;
488 
489 	/* Confirm that resize fails if blob is marked read-only. */
490 	blob->md_ro = true;
491 	rc = spdk_blob_resize(blob, 5);
492 	CU_ASSERT(rc == -EPERM);
493 	blob->md_ro = false;
494 
495 	/* The blob started at 0 clusters. Resize it to be 5. */
496 	rc = spdk_blob_resize(blob, 5);
497 	CU_ASSERT(rc == 0);
498 	CU_ASSERT((free_clusters - 5) == spdk_bs_free_cluster_count(bs));
499 
500 	/* Shrink the blob to 3 clusters. This will not actually release
501 	 * the old clusters until the blob is synced.
502 	 */
503 	rc = spdk_blob_resize(blob, 3);
504 	CU_ASSERT(rc == 0);
505 	/* Verify there are still 5 clusters in use */
506 	CU_ASSERT((free_clusters - 5) == spdk_bs_free_cluster_count(bs));
507 
508 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
509 	CU_ASSERT(g_bserrno == 0);
510 	/* Now there are only 3 clusters in use */
511 	CU_ASSERT((free_clusters - 3) == spdk_bs_free_cluster_count(bs));
512 
513 	/* Resize the blob to be 10 clusters. Growth takes effect immediately. */
514 	rc = spdk_blob_resize(blob, 10);
515 	CU_ASSERT(rc == 0);
516 	CU_ASSERT((free_clusters - 10) == spdk_bs_free_cluster_count(bs));
517 
518 	/* Try to resize the blob to size larger than blobstore. */
519 	rc = spdk_blob_resize(blob, bs->total_clusters + 1);
520 	CU_ASSERT(rc == -ENOSPC);
521 
522 	spdk_blob_close(blob, blob_op_complete, NULL);
523 	CU_ASSERT(g_bserrno == 0);
524 
525 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
526 	CU_ASSERT(g_bserrno == 0);
527 
528 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
529 	CU_ASSERT(g_bserrno == 0);
530 	g_bs = NULL;
531 }
532 
533 static void
534 blob_read_only(void)
535 {
536 	struct spdk_blob_store *bs;
537 	struct spdk_bs_dev *dev;
538 	struct spdk_blob *blob;
539 	struct spdk_bs_opts opts;
540 	spdk_blob_id blobid;
541 	int rc;
542 
543 	dev = init_dev();
544 	spdk_bs_opts_init(&opts);
545 	strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH);
546 
547 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
548 	CU_ASSERT(g_bserrno == 0);
549 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
550 	bs = g_bs;
551 
552 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
553 	CU_ASSERT(g_bserrno == 0);
554 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
555 	blobid = g_blobid;
556 
557 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
558 	CU_ASSERT(g_bserrno == 0);
559 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
560 	blob = g_blob;
561 
562 	rc = spdk_blob_set_read_only(blob);
563 	CU_ASSERT(rc == 0);
564 
565 	CU_ASSERT(blob->data_ro == false);
566 	CU_ASSERT(blob->md_ro == false);
567 
568 	spdk_blob_sync_md(blob, bs_op_complete, NULL);
569 
570 	CU_ASSERT(blob->data_ro == true);
571 	CU_ASSERT(blob->md_ro == true);
572 	CU_ASSERT(blob->data_ro_flags & SPDK_BLOB_READ_ONLY);
573 
574 	spdk_blob_close(blob, blob_op_complete, NULL);
575 	CU_ASSERT(g_bserrno == 0);
576 
577 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
578 	CU_ASSERT(g_bserrno == 0);
579 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
580 	blob = g_blob;
581 
582 	CU_ASSERT(blob->data_ro == true);
583 	CU_ASSERT(blob->md_ro == true);
584 	CU_ASSERT(blob->data_ro_flags & SPDK_BLOB_READ_ONLY);
585 
586 	spdk_blob_close(blob, blob_op_complete, NULL);
587 	CU_ASSERT(g_bserrno == 0);
588 
589 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
590 	CU_ASSERT(g_bserrno == 0);
591 	g_bs = NULL;
592 	g_blob = NULL;
593 	g_blobid = 0;
594 
595 	/* Load an existing blob store */
596 	dev = init_dev();
597 	strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH);
598 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
599 	CU_ASSERT(g_bserrno == 0);
600 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
601 
602 	spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
603 	CU_ASSERT(g_bserrno == 0);
604 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
605 	blob = g_blob;
606 
607 	CU_ASSERT(blob->data_ro == true);
608 	CU_ASSERT(blob->md_ro == true);
609 	CU_ASSERT(blob->data_ro_flags & SPDK_BLOB_READ_ONLY);
610 
611 	spdk_blob_close(blob, blob_op_complete, NULL);
612 	CU_ASSERT(g_bserrno == 0);
613 
614 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
615 	CU_ASSERT(g_bserrno == 0);
616 
617 }
618 
619 static void
620 channel_ops(void)
621 {
622 	struct spdk_blob_store *bs;
623 	struct spdk_bs_dev *dev;
624 	struct spdk_io_channel *channel;
625 
626 	dev = init_dev();
627 
628 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
629 	CU_ASSERT(g_bserrno == 0);
630 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
631 	bs = g_bs;
632 
633 	channel = spdk_bs_alloc_io_channel(bs);
634 	CU_ASSERT(channel != NULL);
635 
636 	spdk_bs_free_io_channel(channel);
637 
638 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
639 	CU_ASSERT(g_bserrno == 0);
640 	g_bs = NULL;
641 }
642 
643 static void
644 blob_write(void)
645 {
646 	struct spdk_blob_store *bs;
647 	struct spdk_bs_dev *dev;
648 	struct spdk_blob *blob;
649 	struct spdk_io_channel *channel;
650 	spdk_blob_id blobid;
651 	uint64_t pages_per_cluster;
652 	uint8_t payload[10 * 4096];
653 	int rc;
654 
655 	dev = init_dev();
656 
657 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
658 	CU_ASSERT(g_bserrno == 0);
659 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
660 	bs = g_bs;
661 
662 	pages_per_cluster = spdk_bs_get_cluster_size(bs) / spdk_bs_get_page_size(bs);
663 
664 	channel = spdk_bs_alloc_io_channel(bs);
665 	CU_ASSERT(channel != NULL);
666 
667 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
668 	CU_ASSERT(g_bserrno == 0);
669 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
670 	blobid = g_blobid;
671 
672 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
673 	CU_ASSERT(g_bserrno == 0);
674 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
675 	blob = g_blob;
676 
677 	/* Write to a blob with 0 size */
678 	spdk_blob_io_write(blob, channel, payload, 0, 1, blob_op_complete, NULL);
679 	CU_ASSERT(g_bserrno == -EINVAL);
680 
681 	/* Resize the blob */
682 	rc = spdk_blob_resize(blob, 5);
683 	CU_ASSERT(rc == 0);
684 
685 	/* Confirm that write fails if blob is marked read-only. */
686 	blob->data_ro = true;
687 	spdk_blob_io_write(blob, channel, payload, 0, 1, blob_op_complete, NULL);
688 	CU_ASSERT(g_bserrno == -EPERM);
689 	blob->data_ro = false;
690 
691 	/* Write to the blob */
692 	spdk_blob_io_write(blob, channel, payload, 0, 1, blob_op_complete, NULL);
693 	CU_ASSERT(g_bserrno == 0);
694 
695 	/* Write starting beyond the end */
696 	spdk_blob_io_write(blob, channel, payload, 5 * pages_per_cluster, 1, blob_op_complete,
697 			   NULL);
698 	CU_ASSERT(g_bserrno == -EINVAL);
699 
700 	/* Write starting at a valid location but going off the end */
701 	spdk_blob_io_write(blob, channel, payload, 4 * pages_per_cluster, pages_per_cluster + 1,
702 			   blob_op_complete, NULL);
703 	CU_ASSERT(g_bserrno == -EINVAL);
704 
705 	spdk_blob_close(blob, blob_op_complete, NULL);
706 	CU_ASSERT(g_bserrno == 0);
707 
708 	spdk_bs_free_io_channel(channel);
709 
710 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
711 	CU_ASSERT(g_bserrno == 0);
712 	g_bs = NULL;
713 }
714 
715 static void
716 blob_read(void)
717 {
718 	struct spdk_blob_store *bs;
719 	struct spdk_bs_dev *dev;
720 	struct spdk_blob *blob;
721 	struct spdk_io_channel *channel;
722 	spdk_blob_id blobid;
723 	uint64_t pages_per_cluster;
724 	uint8_t payload[10 * 4096];
725 	int rc;
726 
727 	dev = init_dev();
728 
729 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
730 	CU_ASSERT(g_bserrno == 0);
731 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
732 	bs = g_bs;
733 
734 	pages_per_cluster = spdk_bs_get_cluster_size(bs) / spdk_bs_get_page_size(bs);
735 
736 	channel = spdk_bs_alloc_io_channel(bs);
737 	CU_ASSERT(channel != NULL);
738 
739 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
740 	CU_ASSERT(g_bserrno == 0);
741 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
742 	blobid = g_blobid;
743 
744 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
745 	CU_ASSERT(g_bserrno == 0);
746 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
747 	blob = g_blob;
748 
749 	/* Read from a blob with 0 size */
750 	spdk_blob_io_read(blob, channel, payload, 0, 1, blob_op_complete, NULL);
751 	CU_ASSERT(g_bserrno == -EINVAL);
752 
753 	/* Resize the blob */
754 	rc = spdk_blob_resize(blob, 5);
755 	CU_ASSERT(rc == 0);
756 
757 	/* Confirm that read passes if blob is marked read-only. */
758 	blob->data_ro = true;
759 	spdk_blob_io_read(blob, channel, payload, 0, 1, blob_op_complete, NULL);
760 	CU_ASSERT(g_bserrno == 0);
761 	blob->data_ro = false;
762 
763 	/* Read from the blob */
764 	spdk_blob_io_read(blob, channel, payload, 0, 1, blob_op_complete, NULL);
765 	CU_ASSERT(g_bserrno == 0);
766 
767 	/* Read starting beyond the end */
768 	spdk_blob_io_read(blob, channel, payload, 5 * pages_per_cluster, 1, blob_op_complete,
769 			  NULL);
770 	CU_ASSERT(g_bserrno == -EINVAL);
771 
772 	/* Read starting at a valid location but going off the end */
773 	spdk_blob_io_read(blob, channel, payload, 4 * pages_per_cluster, pages_per_cluster + 1,
774 			  blob_op_complete, NULL);
775 	CU_ASSERT(g_bserrno == -EINVAL);
776 
777 	spdk_blob_close(blob, blob_op_complete, NULL);
778 	CU_ASSERT(g_bserrno == 0);
779 
780 	spdk_bs_free_io_channel(channel);
781 
782 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
783 	CU_ASSERT(g_bserrno == 0);
784 	g_bs = NULL;
785 }
786 
787 static void
788 blob_rw_verify(void)
789 {
790 	struct spdk_blob_store *bs;
791 	struct spdk_bs_dev *dev;
792 	struct spdk_blob *blob;
793 	struct spdk_io_channel *channel;
794 	spdk_blob_id blobid;
795 	uint8_t payload_read[10 * 4096];
796 	uint8_t payload_write[10 * 4096];
797 	int rc;
798 
799 	dev = init_dev();
800 
801 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
802 	CU_ASSERT(g_bserrno == 0);
803 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
804 	bs = g_bs;
805 
806 	channel = spdk_bs_alloc_io_channel(bs);
807 	CU_ASSERT(channel != NULL);
808 
809 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
810 	CU_ASSERT(g_bserrno == 0);
811 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
812 	blobid = g_blobid;
813 
814 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
815 	CU_ASSERT(g_bserrno == 0);
816 	CU_ASSERT(g_blob != NULL);
817 	blob = g_blob;
818 
819 	rc = spdk_blob_resize(blob, 32);
820 	CU_ASSERT(rc == 0);
821 
822 	memset(payload_write, 0xE5, sizeof(payload_write));
823 	spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL);
824 	CU_ASSERT(g_bserrno == 0);
825 
826 	memset(payload_read, 0x00, sizeof(payload_read));
827 	spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL);
828 	CU_ASSERT(g_bserrno == 0);
829 	CU_ASSERT(memcmp(payload_write, payload_read, 4 * 4096) == 0);
830 
831 	spdk_blob_close(blob, blob_op_complete, NULL);
832 	CU_ASSERT(g_bserrno == 0);
833 
834 	spdk_bs_free_io_channel(channel);
835 
836 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
837 	CU_ASSERT(g_bserrno == 0);
838 	g_bs = NULL;
839 }
840 
841 static void
842 blob_rw_verify_iov(void)
843 {
844 	struct spdk_blob_store *bs;
845 	struct spdk_bs_dev *dev;
846 	struct spdk_blob *blob;
847 	struct spdk_io_channel *channel;
848 	spdk_blob_id blobid;
849 	uint8_t payload_read[10 * 4096];
850 	uint8_t payload_write[10 * 4096];
851 	struct iovec iov_read[3];
852 	struct iovec iov_write[3];
853 	void *buf;
854 	int rc;
855 
856 	dev = init_dev();
857 	memset(g_dev_buffer, 0, DEV_BUFFER_SIZE);
858 
859 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
860 	CU_ASSERT(g_bserrno == 0);
861 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
862 	bs = g_bs;
863 
864 	channel = spdk_bs_alloc_io_channel(bs);
865 	CU_ASSERT(channel != NULL);
866 
867 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
868 	CU_ASSERT(g_bserrno == 0);
869 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
870 	blobid = g_blobid;
871 
872 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
873 	CU_ASSERT(g_bserrno == 0);
874 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
875 	blob = g_blob;
876 
877 	rc = spdk_blob_resize(blob, 2);
878 	CU_ASSERT(rc == 0);
879 
880 	/*
881 	 * Manually adjust the offset of the blob's second cluster.  This allows
882 	 *  us to make sure that the readv/write code correctly accounts for I/O
883 	 *  that cross cluster boundaries.  Start by asserting that the allocated
884 	 *  clusters are where we expect before modifying the second cluster.
885 	 */
886 	CU_ASSERT(blob->active.clusters[0] == 1 * 256);
887 	CU_ASSERT(blob->active.clusters[1] == 2 * 256);
888 	blob->active.clusters[1] = 3 * 256;
889 
890 	memset(payload_write, 0xE5, sizeof(payload_write));
891 	iov_write[0].iov_base = payload_write;
892 	iov_write[0].iov_len = 1 * 4096;
893 	iov_write[1].iov_base = payload_write + 1 * 4096;
894 	iov_write[1].iov_len = 5 * 4096;
895 	iov_write[2].iov_base = payload_write + 6 * 4096;
896 	iov_write[2].iov_len = 4 * 4096;
897 	/*
898 	 * Choose a page offset just before the cluster boundary.  The first 6 pages of payload
899 	 *  will get written to the first cluster, the last 4 to the second cluster.
900 	 */
901 	spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL);
902 	CU_ASSERT(g_bserrno == 0);
903 
904 	memset(payload_read, 0xAA, sizeof(payload_read));
905 	iov_read[0].iov_base = payload_read;
906 	iov_read[0].iov_len = 3 * 4096;
907 	iov_read[1].iov_base = payload_read + 3 * 4096;
908 	iov_read[1].iov_len = 4 * 4096;
909 	iov_read[2].iov_base = payload_read + 7 * 4096;
910 	iov_read[2].iov_len = 3 * 4096;
911 	spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL);
912 	CU_ASSERT(g_bserrno == 0);
913 	CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0);
914 
915 	buf = calloc(1, 256 * 4096);
916 	SPDK_CU_ASSERT_FATAL(buf != NULL);
917 	/* Check that cluster 2 on "disk" was not modified. */
918 	CU_ASSERT(memcmp(buf, &g_dev_buffer[512 * 4096], 256 * 4096) == 0);
919 	free(buf);
920 
921 	spdk_blob_close(blob, blob_op_complete, NULL);
922 	CU_ASSERT(g_bserrno == 0);
923 
924 	spdk_bs_free_io_channel(channel);
925 
926 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
927 	CU_ASSERT(g_bserrno == 0);
928 	g_bs = NULL;
929 }
930 
931 static uint32_t
932 bs_channel_get_req_count(struct spdk_io_channel *_channel)
933 {
934 	struct spdk_bs_channel *channel = spdk_io_channel_get_ctx(_channel);
935 	struct spdk_bs_request_set *set;
936 	uint32_t count = 0;
937 
938 	TAILQ_FOREACH(set, &channel->reqs, link) {
939 		count++;
940 	}
941 
942 	return count;
943 }
944 
945 static void
946 blob_rw_verify_iov_nomem(void)
947 {
948 	struct spdk_blob_store *bs;
949 	struct spdk_bs_dev *dev;
950 	struct spdk_blob *blob;
951 	struct spdk_io_channel *channel;
952 	spdk_blob_id blobid;
953 	uint8_t payload_write[10 * 4096];
954 	struct iovec iov_write[3];
955 	uint32_t req_count;
956 	int rc;
957 
958 	dev = init_dev();
959 	memset(g_dev_buffer, 0, DEV_BUFFER_SIZE);
960 
961 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
962 	CU_ASSERT(g_bserrno == 0);
963 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
964 	bs = g_bs;
965 
966 	channel = spdk_bs_alloc_io_channel(bs);
967 	CU_ASSERT(channel != NULL);
968 
969 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
970 	CU_ASSERT(g_bserrno == 0);
971 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
972 	blobid = g_blobid;
973 
974 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
975 	CU_ASSERT(g_bserrno == 0);
976 	CU_ASSERT(g_blob != NULL);
977 	blob = g_blob;
978 
979 	rc = spdk_blob_resize(blob, 2);
980 	CU_ASSERT(rc == 0);
981 
982 	/*
983 	 * Choose a page offset just before the cluster boundary.  The first 6 pages of payload
984 	 *  will get written to the first cluster, the last 4 to the second cluster.
985 	 */
986 	iov_write[0].iov_base = payload_write;
987 	iov_write[0].iov_len = 1 * 4096;
988 	iov_write[1].iov_base = payload_write + 1 * 4096;
989 	iov_write[1].iov_len = 5 * 4096;
990 	iov_write[2].iov_base = payload_write + 6 * 4096;
991 	iov_write[2].iov_len = 4 * 4096;
992 	MOCK_SET(calloc, void *, NULL);
993 	req_count = bs_channel_get_req_count(channel);
994 	spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL);
995 	CU_ASSERT(g_bserrno = -ENOMEM);
996 	CU_ASSERT(req_count == bs_channel_get_req_count(channel));
997 	MOCK_SET(calloc, void *, (void *)MOCK_PASS_THRU);
998 
999 	spdk_blob_close(blob, blob_op_complete, NULL);
1000 	CU_ASSERT(g_bserrno == 0);
1001 
1002 	spdk_bs_free_io_channel(channel);
1003 
1004 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1005 	CU_ASSERT(g_bserrno == 0);
1006 	g_bs = NULL;
1007 }
1008 
1009 static void
1010 blob_rw_iov_read_only(void)
1011 {
1012 	struct spdk_blob_store *bs;
1013 	struct spdk_bs_dev *dev;
1014 	struct spdk_blob *blob;
1015 	struct spdk_io_channel *channel;
1016 	spdk_blob_id blobid;
1017 	uint8_t payload_read[4096];
1018 	uint8_t payload_write[4096];
1019 	struct iovec iov_read;
1020 	struct iovec iov_write;
1021 	int rc;
1022 
1023 	dev = init_dev();
1024 	memset(g_dev_buffer, 0, DEV_BUFFER_SIZE);
1025 
1026 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1027 	CU_ASSERT(g_bserrno == 0);
1028 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1029 	bs = g_bs;
1030 
1031 	channel = spdk_bs_alloc_io_channel(bs);
1032 	CU_ASSERT(channel != NULL);
1033 
1034 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
1035 	CU_ASSERT(g_bserrno == 0);
1036 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1037 	blobid = g_blobid;
1038 
1039 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1040 	CU_ASSERT(g_bserrno == 0);
1041 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1042 	blob = g_blob;
1043 
1044 	rc = spdk_blob_resize(blob, 2);
1045 	CU_ASSERT(rc == 0);
1046 
1047 	/* Verify that writev failed if read_only flag is set. */
1048 	blob->data_ro = true;
1049 	iov_write.iov_base = payload_write;
1050 	iov_write.iov_len = sizeof(payload_write);
1051 	spdk_blob_io_writev(blob, channel, &iov_write, 1, 0, 1, blob_op_complete, NULL);
1052 	CU_ASSERT(g_bserrno == -EPERM);
1053 
1054 	/* Verify that reads pass if data_ro flag is set. */
1055 	iov_read.iov_base = payload_read;
1056 	iov_read.iov_len = sizeof(payload_read);
1057 	spdk_blob_io_readv(blob, channel, &iov_read, 1, 0, 1, blob_op_complete, NULL);
1058 	CU_ASSERT(g_bserrno == 0);
1059 
1060 	spdk_blob_close(blob, blob_op_complete, NULL);
1061 	CU_ASSERT(g_bserrno == 0);
1062 
1063 	spdk_bs_free_io_channel(channel);
1064 
1065 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1066 	CU_ASSERT(g_bserrno == 0);
1067 	g_bs = NULL;
1068 }
1069 
1070 static void
1071 blob_unmap(void)
1072 {
1073 	struct spdk_blob_store *bs;
1074 	struct spdk_bs_dev *dev;
1075 	struct spdk_blob *blob;
1076 	struct spdk_io_channel *channel;
1077 	spdk_blob_id blobid;
1078 	struct spdk_blob_opts opts;
1079 	uint8_t payload[4096];
1080 	int rc;
1081 	int i;
1082 
1083 	dev = init_dev();
1084 
1085 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1086 	CU_ASSERT(g_bserrno == 0);
1087 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1088 	bs = g_bs;
1089 
1090 	channel = spdk_bs_alloc_io_channel(bs);
1091 	CU_ASSERT(channel != NULL);
1092 
1093 	spdk_blob_opts_init(&opts);
1094 	opts.num_clusters = 10;
1095 
1096 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
1097 	CU_ASSERT(g_bserrno == 0);
1098 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1099 	blobid = g_blobid;
1100 
1101 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1102 	CU_ASSERT(g_bserrno == 0);
1103 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1104 	blob = g_blob;
1105 
1106 	rc = spdk_blob_resize(blob, 10);
1107 	CU_ASSERT(rc == 0);
1108 
1109 	memset(payload, 0, sizeof(payload));
1110 	payload[0] = 0xFF;
1111 
1112 	/*
1113 	 * Set first byte of every cluster to 0xFF.
1114 	 * First cluster on device is reserved so let's start from cluster number 1
1115 	 */
1116 	for (i = 1; i < 11; i++) {
1117 		g_dev_buffer[i * SPDK_BLOB_OPTS_CLUSTER_SZ] = 0xFF;
1118 	}
1119 
1120 	/* Confirm writes */
1121 	for (i = 0; i < 10; i++) {
1122 		payload[0] = 0;
1123 		spdk_blob_io_read(blob, channel, &payload, i * SPDK_BLOB_OPTS_CLUSTER_SZ / 4096, 1,
1124 				  blob_op_complete, NULL);
1125 		CU_ASSERT(g_bserrno == 0);
1126 		CU_ASSERT(payload[0] == 0xFF);
1127 	}
1128 
1129 	/* Mark some clusters as unallocated */
1130 	blob->active.clusters[1] = 0;
1131 	blob->active.clusters[2] = 0;
1132 	blob->active.clusters[3] = 0;
1133 	blob->active.clusters[6] = 0;
1134 	blob->active.clusters[8] = 0;
1135 
1136 	/* Unmap clusters by resizing to 0 */
1137 	rc = spdk_blob_resize(blob, 0);
1138 	CU_ASSERT(rc == 0);
1139 
1140 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
1141 	CU_ASSERT(g_bserrno == 0);
1142 
1143 	/* Confirm that only 'allocated' clusters were unmaped */
1144 	for (i = 1; i < 11; i++) {
1145 		switch (i) {
1146 		case 2:
1147 		case 3:
1148 		case 4:
1149 		case 7:
1150 		case 9:
1151 			CU_ASSERT(g_dev_buffer[i * SPDK_BLOB_OPTS_CLUSTER_SZ] == 0xFF);
1152 			break;
1153 		default:
1154 			CU_ASSERT(g_dev_buffer[i * SPDK_BLOB_OPTS_CLUSTER_SZ] == 0);
1155 			break;
1156 		}
1157 	}
1158 
1159 	spdk_blob_close(blob, blob_op_complete, NULL);
1160 	CU_ASSERT(g_bserrno == 0);
1161 
1162 	spdk_bs_free_io_channel(channel);
1163 
1164 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1165 	CU_ASSERT(g_bserrno == 0);
1166 	g_bs = NULL;
1167 }
1168 
1169 
1170 static void
1171 blob_iter(void)
1172 {
1173 	struct spdk_blob_store *bs;
1174 	struct spdk_bs_dev *dev;
1175 	struct spdk_blob *blob;
1176 	spdk_blob_id blobid;
1177 
1178 	dev = init_dev();
1179 
1180 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1181 	CU_ASSERT(g_bserrno == 0);
1182 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1183 	bs = g_bs;
1184 
1185 	spdk_bs_iter_first(bs, blob_op_with_handle_complete, NULL);
1186 	CU_ASSERT(g_blob == NULL);
1187 	CU_ASSERT(g_bserrno == -ENOENT);
1188 
1189 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
1190 	CU_ASSERT(g_bserrno == 0);
1191 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1192 	blobid = g_blobid;
1193 
1194 	spdk_bs_iter_first(bs, blob_op_with_handle_complete, NULL);
1195 	CU_ASSERT(g_blob != NULL);
1196 	CU_ASSERT(g_bserrno == 0);
1197 	blob = g_blob;
1198 	CU_ASSERT(spdk_blob_get_id(blob) == blobid);
1199 
1200 	spdk_bs_iter_next(bs, blob, blob_op_with_handle_complete, NULL);
1201 	CU_ASSERT(g_blob == NULL);
1202 	CU_ASSERT(g_bserrno == -ENOENT);
1203 
1204 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1205 	CU_ASSERT(g_bserrno == 0);
1206 	g_bs = NULL;
1207 }
1208 
1209 static void
1210 blob_xattr(void)
1211 {
1212 	struct spdk_blob_store *bs;
1213 	struct spdk_bs_dev *dev;
1214 	struct spdk_blob *blob;
1215 	spdk_blob_id blobid;
1216 	uint64_t length;
1217 	int rc;
1218 	const char *name1, *name2;
1219 	const void *value;
1220 	size_t value_len;
1221 	struct spdk_xattr_names *names;
1222 
1223 	dev = init_dev();
1224 
1225 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1226 	CU_ASSERT(g_bserrno == 0);
1227 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1228 	bs = g_bs;
1229 
1230 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
1231 	CU_ASSERT(g_bserrno == 0);
1232 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1233 	blobid = g_blobid;
1234 
1235 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1236 	CU_ASSERT(g_bserrno == 0);
1237 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1238 	blob = g_blob;
1239 
1240 	/* Test that set_xattr fails if md_ro flag is set. */
1241 	blob->md_ro = true;
1242 	rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1);
1243 	CU_ASSERT(rc == -EPERM);
1244 
1245 	blob->md_ro = false;
1246 	rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1);
1247 	CU_ASSERT(rc == 0);
1248 
1249 	length = 2345;
1250 	rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
1251 	CU_ASSERT(rc == 0);
1252 
1253 	/* Overwrite "length" xattr. */
1254 	length = 3456;
1255 	rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
1256 	CU_ASSERT(rc == 0);
1257 
1258 	/* get_xattr should still work even if md_ro flag is set. */
1259 	value = NULL;
1260 	blob->md_ro = true;
1261 	rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len);
1262 	CU_ASSERT(rc == 0);
1263 	SPDK_CU_ASSERT_FATAL(value != NULL);
1264 	CU_ASSERT(*(uint64_t *)value == length);
1265 	CU_ASSERT(value_len == 8);
1266 	blob->md_ro = false;
1267 
1268 	rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len);
1269 	CU_ASSERT(rc == -ENOENT);
1270 
1271 	names = NULL;
1272 	rc = spdk_blob_get_xattr_names(blob, &names);
1273 	CU_ASSERT(rc == 0);
1274 	SPDK_CU_ASSERT_FATAL(names != NULL);
1275 	CU_ASSERT(spdk_xattr_names_get_count(names) == 2);
1276 	name1 = spdk_xattr_names_get_name(names, 0);
1277 	SPDK_CU_ASSERT_FATAL(name1 != NULL);
1278 	CU_ASSERT(!strcmp(name1, "name") || !strcmp(name1, "length"));
1279 	name2 = spdk_xattr_names_get_name(names, 1);
1280 	SPDK_CU_ASSERT_FATAL(name2 != NULL);
1281 	CU_ASSERT(!strcmp(name2, "name") || !strcmp(name2, "length"));
1282 	CU_ASSERT(strcmp(name1, name2));
1283 	spdk_xattr_names_free(names);
1284 
1285 	/* Confirm that remove_xattr fails if md_ro is set to true. */
1286 	blob->md_ro = true;
1287 	rc = spdk_blob_remove_xattr(blob, "name");
1288 	CU_ASSERT(rc == -EPERM);
1289 
1290 	blob->md_ro = false;
1291 	rc = spdk_blob_remove_xattr(blob, "name");
1292 	CU_ASSERT(rc == 0);
1293 
1294 	rc = spdk_blob_remove_xattr(blob, "foobar");
1295 	CU_ASSERT(rc == -ENOENT);
1296 
1297 	/* Set internal xattr */
1298 	length = 7898;
1299 	rc = _spdk_blob_set_xattr(blob, "internal", &length, sizeof(length), true);
1300 	CU_ASSERT(rc == 0);
1301 	rc = _spdk_blob_get_xattr_value(blob, "internal", &value, &value_len, true);
1302 	CU_ASSERT(rc == 0);
1303 	CU_ASSERT(*(uint64_t *)value == length);
1304 	/* try to get public xattr with same name */
1305 	rc = spdk_blob_get_xattr_value(blob, "internal", &value, &value_len);
1306 	CU_ASSERT(rc != 0);
1307 	rc = _spdk_blob_get_xattr_value(blob, "internal", &value, &value_len, false);
1308 	CU_ASSERT(rc != 0);
1309 	/* Check if SPDK_BLOB_INTERNAL_XATTR is set */
1310 	CU_ASSERT((blob->invalid_flags & SPDK_BLOB_INTERNAL_XATTR) ==
1311 		  SPDK_BLOB_INTERNAL_XATTR)
1312 
1313 	spdk_blob_close(blob, blob_op_complete, NULL);
1314 
1315 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1316 
1317 	/* Check if xattrs are persisted */
1318 	dev = init_dev();
1319 
1320 	spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL);
1321 	CU_ASSERT(g_bserrno == 0);
1322 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1323 
1324 	bs = g_bs;
1325 
1326 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1327 	CU_ASSERT(g_bserrno == 0);
1328 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1329 	blob = g_blob;
1330 
1331 	rc = _spdk_blob_get_xattr_value(blob, "internal", &value, &value_len, true);
1332 	CU_ASSERT(rc == 0);
1333 	CU_ASSERT(*(uint64_t *)value == length);
1334 
1335 	/* try to get internal xattr trough public call */
1336 	rc = spdk_blob_get_xattr_value(blob, "internal", &value, &value_len);
1337 	CU_ASSERT(rc != 0);
1338 
1339 	rc = _spdk_blob_remove_xattr(blob, "internal", true);
1340 	CU_ASSERT(rc == 0);
1341 
1342 	CU_ASSERT((blob->invalid_flags & SPDK_BLOB_INTERNAL_XATTR) == 0);
1343 
1344 	CU_ASSERT(g_bserrno == 0);
1345 	g_bs = NULL;
1346 }
1347 
1348 static void
1349 bs_load(void)
1350 {
1351 	struct spdk_bs_dev *dev;
1352 	spdk_blob_id blobid;
1353 	struct spdk_blob *blob;
1354 	struct spdk_bs_super_block *super_block;
1355 	uint64_t length;
1356 	int rc;
1357 	const void *value;
1358 	size_t value_len;
1359 	struct spdk_bs_opts opts;
1360 
1361 	dev = init_dev();
1362 	spdk_bs_opts_init(&opts);
1363 	strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH);
1364 
1365 	/* Initialize a new blob store */
1366 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
1367 	CU_ASSERT(g_bserrno == 0);
1368 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1369 
1370 	/* Try to open a blobid that does not exist */
1371 	spdk_bs_open_blob(g_bs, 0, blob_op_with_handle_complete, NULL);
1372 	CU_ASSERT(g_bserrno == -ENOENT);
1373 	CU_ASSERT(g_blob == NULL);
1374 
1375 	/* Create a blob */
1376 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
1377 	CU_ASSERT(g_bserrno == 0);
1378 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1379 	blobid = g_blobid;
1380 
1381 	spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
1382 	CU_ASSERT(g_bserrno == 0);
1383 	CU_ASSERT(g_blob != NULL);
1384 	blob = g_blob;
1385 
1386 	/* Try again to open valid blob but without the upper bit set */
1387 	spdk_bs_open_blob(g_bs, blobid & 0xFFFFFFFF, blob_op_with_handle_complete, NULL);
1388 	CU_ASSERT(g_bserrno == -ENOENT);
1389 	CU_ASSERT(g_blob == NULL);
1390 
1391 	/* Set some xattrs */
1392 	rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1);
1393 	CU_ASSERT(rc == 0);
1394 
1395 	length = 2345;
1396 	rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
1397 	CU_ASSERT(rc == 0);
1398 
1399 	/* Resize the blob */
1400 	rc = spdk_blob_resize(blob, 10);
1401 	CU_ASSERT(rc == 0);
1402 
1403 	spdk_blob_close(blob, blob_op_complete, NULL);
1404 	CU_ASSERT(g_bserrno == 0);
1405 	blob = NULL;
1406 	g_blob = NULL;
1407 	g_blobid = SPDK_BLOBID_INVALID;
1408 
1409 	/* Unload the blob store */
1410 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1411 	CU_ASSERT(g_bserrno == 0);
1412 	g_bs = NULL;
1413 	g_blob = NULL;
1414 	g_blobid = 0;
1415 
1416 	super_block = (struct spdk_bs_super_block *)g_dev_buffer;
1417 	CU_ASSERT(super_block->clean == 1);
1418 
1419 
1420 	/* Load an existing blob store */
1421 	dev = init_dev();
1422 	strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH);
1423 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1424 	CU_ASSERT(g_bserrno == 0);
1425 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1426 
1427 	super_block = (struct spdk_bs_super_block *)g_dev_buffer;
1428 	CU_ASSERT(super_block->clean == 0);
1429 
1430 	spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
1431 	CU_ASSERT(g_bserrno == 0);
1432 	CU_ASSERT(g_blob != NULL);
1433 	blob = g_blob;
1434 
1435 	/* Get the xattrs */
1436 	value = NULL;
1437 	rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len);
1438 	CU_ASSERT(rc == 0);
1439 	SPDK_CU_ASSERT_FATAL(value != NULL);
1440 	CU_ASSERT(*(uint64_t *)value == length);
1441 	CU_ASSERT(value_len == 8);
1442 
1443 	rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len);
1444 	CU_ASSERT(rc == -ENOENT);
1445 
1446 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10);
1447 
1448 	spdk_blob_close(blob, blob_op_complete, NULL);
1449 	CU_ASSERT(g_bserrno == 0);
1450 	blob = NULL;
1451 	g_blob = NULL;
1452 	g_blobid = SPDK_BLOBID_INVALID;
1453 
1454 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1455 	CU_ASSERT(g_bserrno == 0);
1456 	g_bs = NULL;
1457 }
1458 
1459 static void
1460 bs_type(void)
1461 {
1462 	struct spdk_bs_dev *dev;
1463 	struct spdk_bs_opts opts;
1464 
1465 	dev = init_dev();
1466 	spdk_bs_opts_init(&opts);
1467 	strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH);
1468 
1469 	/* Initialize a new blob store */
1470 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
1471 	CU_ASSERT(g_bserrno == 0);
1472 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1473 
1474 	/* Unload the blob store */
1475 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1476 	CU_ASSERT(g_bserrno == 0);
1477 	g_bs = NULL;
1478 	g_blob = NULL;
1479 	g_blobid = 0;
1480 
1481 	/* Load non existing blobstore type */
1482 	dev = init_dev();
1483 	strncpy(opts.bstype.bstype, "NONEXISTING", SPDK_BLOBSTORE_TYPE_LENGTH);
1484 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1485 	CU_ASSERT(g_bserrno != 0);
1486 
1487 	/* Load with empty blobstore type */
1488 	dev = init_dev();
1489 	strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH);
1490 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1491 	CU_ASSERT(g_bserrno == 0);
1492 
1493 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1494 	CU_ASSERT(g_bserrno == 0);
1495 	g_bs = NULL;
1496 
1497 	/* Initialize a new blob store with empty bstype */
1498 	dev = init_dev();
1499 	strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH);
1500 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1501 	CU_ASSERT(g_bserrno == 0);
1502 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1503 
1504 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1505 	CU_ASSERT(g_bserrno == 0);
1506 	g_bs = NULL;
1507 
1508 	/* Load non existing blobstore type */
1509 	dev = init_dev();
1510 	strncpy(opts.bstype.bstype, "NONEXISTING", SPDK_BLOBSTORE_TYPE_LENGTH);
1511 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1512 	CU_ASSERT(g_bserrno != 0);
1513 
1514 	/* Load with empty blobstore type */
1515 	dev = init_dev();
1516 	strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH);
1517 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1518 	CU_ASSERT(g_bserrno == 0);
1519 
1520 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1521 	CU_ASSERT(g_bserrno == 0);
1522 	g_bs = NULL;
1523 }
1524 
1525 static void
1526 bs_super_block(void)
1527 {
1528 	struct spdk_bs_dev *dev;
1529 	struct spdk_bs_super_block *super_block;
1530 	struct spdk_bs_opts opts;
1531 	struct spdk_bs_super_block_ver1 super_block_v1;
1532 
1533 	dev = init_dev();
1534 	spdk_bs_opts_init(&opts);
1535 	strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH);
1536 
1537 	/* Initialize a new blob store */
1538 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
1539 	CU_ASSERT(g_bserrno == 0);
1540 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1541 
1542 	/* Unload the blob store */
1543 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1544 	CU_ASSERT(g_bserrno == 0);
1545 	g_bs = NULL;
1546 	g_blob = NULL;
1547 	g_blobid = 0;
1548 
1549 	/* Load an existing blob store with version newer than supported */
1550 	super_block = (struct spdk_bs_super_block *)g_dev_buffer;
1551 	super_block->version++;
1552 
1553 	dev = init_dev();
1554 	strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH);
1555 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1556 	CU_ASSERT(g_bserrno != 0);
1557 
1558 	/* Create a new blob store with super block version 1 */
1559 	dev = init_dev();
1560 	super_block_v1.version = 1;
1561 	strncpy(super_block_v1.signature, "SPDKBLOB", sizeof(super_block_v1.signature));
1562 	super_block_v1.length = 0x1000;
1563 	super_block_v1.clean = 1;
1564 	super_block_v1.super_blob = 0xFFFFFFFFFFFFFFFF;
1565 	super_block_v1.cluster_size = 0x100000;
1566 	super_block_v1.used_page_mask_start = 0x01;
1567 	super_block_v1.used_page_mask_len = 0x01;
1568 	super_block_v1.used_cluster_mask_start = 0x02;
1569 	super_block_v1.used_cluster_mask_len = 0x01;
1570 	super_block_v1.md_start = 0x03;
1571 	super_block_v1.md_len = 0x40;
1572 	memset(super_block_v1.reserved, 0, 4036);
1573 	super_block_v1.crc = _spdk_blob_md_page_calc_crc(&super_block_v1);
1574 	memcpy(g_dev_buffer, &super_block_v1, sizeof(struct spdk_bs_super_block_ver1));
1575 
1576 	strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH);
1577 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1578 	CU_ASSERT(g_bserrno == 0);
1579 
1580 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1581 	CU_ASSERT(g_bserrno == 0);
1582 	g_bs = NULL;
1583 }
1584 
1585 /*
1586  * Create a blobstore and then unload it.
1587  */
1588 static void
1589 bs_unload(void)
1590 {
1591 	struct spdk_bs_dev *dev;
1592 	struct spdk_blob_store *bs;
1593 	spdk_blob_id blobid;
1594 	struct spdk_blob *blob;
1595 
1596 	dev = init_dev();
1597 
1598 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1599 	CU_ASSERT(g_bserrno == 0);
1600 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1601 	bs = g_bs;
1602 
1603 	/* Create a blob and open it. */
1604 	g_bserrno = -1;
1605 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
1606 	CU_ASSERT(g_bserrno == 0);
1607 	CU_ASSERT(g_blobid > 0);
1608 	blobid = g_blobid;
1609 
1610 	g_bserrno = -1;
1611 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1612 	CU_ASSERT(g_bserrno == 0);
1613 	CU_ASSERT(g_blob != NULL);
1614 	blob = g_blob;
1615 
1616 	/* Try to unload blobstore, should fail with open blob */
1617 	g_bserrno = -1;
1618 	spdk_bs_unload(bs, bs_op_complete, NULL);
1619 	CU_ASSERT(g_bserrno == -EBUSY);
1620 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1621 
1622 	/* Close the blob, then successfully unload blobstore */
1623 	g_bserrno = -1;
1624 	spdk_blob_close(blob, blob_op_complete, NULL);
1625 	CU_ASSERT(g_bserrno == 0);
1626 
1627 	g_bserrno = -1;
1628 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1629 	CU_ASSERT(g_bserrno == 0);
1630 	g_bs = NULL;
1631 }
1632 
1633 /*
1634  * Create a blobstore with a cluster size different than the default, and ensure it is
1635  *  persisted.
1636  */
1637 static void
1638 bs_cluster_sz(void)
1639 {
1640 	struct spdk_bs_dev *dev;
1641 	struct spdk_bs_opts opts;
1642 	uint32_t cluster_sz;
1643 
1644 	/* Set cluster size to zero */
1645 	dev = init_dev();
1646 	spdk_bs_opts_init(&opts);
1647 	opts.cluster_sz = 0;
1648 
1649 	/* Initialize a new blob store */
1650 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
1651 	CU_ASSERT(g_bserrno == -EINVAL);
1652 	SPDK_CU_ASSERT_FATAL(g_bs == NULL);
1653 
1654 	/*
1655 	 * Set cluster size to blobstore page size,
1656 	 * to work it is required to be at least twice the blobstore page size.
1657 	 */
1658 	dev = init_dev();
1659 	spdk_bs_opts_init(&opts);
1660 	opts.cluster_sz = SPDK_BS_PAGE_SIZE;
1661 
1662 	/* Initialize a new blob store */
1663 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
1664 	CU_ASSERT(g_bserrno == -ENOMEM);
1665 	SPDK_CU_ASSERT_FATAL(g_bs == NULL);
1666 
1667 	/*
1668 	 * Set cluster size to lower than page size,
1669 	 * to work it is required to be at least twice the blobstore page size.
1670 	 */
1671 	dev = init_dev();
1672 	spdk_bs_opts_init(&opts);
1673 	opts.cluster_sz = SPDK_BS_PAGE_SIZE - 1;
1674 
1675 	/* Initialize a new blob store */
1676 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
1677 	CU_ASSERT(g_bserrno == -ENOMEM);
1678 	SPDK_CU_ASSERT_FATAL(g_bs == NULL);
1679 
1680 	/* Set cluster size to twice the default */
1681 	dev = init_dev();
1682 	spdk_bs_opts_init(&opts);
1683 	opts.cluster_sz *= 2;
1684 	cluster_sz = opts.cluster_sz;
1685 
1686 	/* Initialize a new blob store */
1687 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
1688 	CU_ASSERT(g_bserrno == 0);
1689 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1690 
1691 	CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz);
1692 
1693 	/* Unload the blob store */
1694 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1695 	CU_ASSERT(g_bserrno == 0);
1696 	g_bs = NULL;
1697 	g_blob = NULL;
1698 	g_blobid = 0;
1699 
1700 	dev = init_dev();
1701 	/* Load an existing blob store */
1702 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1703 	CU_ASSERT(g_bserrno == 0);
1704 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1705 
1706 	CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz);
1707 
1708 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1709 	CU_ASSERT(g_bserrno == 0);
1710 	g_bs = NULL;
1711 }
1712 
1713 /*
1714  * Create a blobstore, reload it and ensure total usable cluster count
1715  *  stays the same.
1716  */
1717 static void
1718 bs_usable_clusters(void)
1719 {
1720 	struct spdk_bs_dev *dev;
1721 	struct spdk_bs_opts opts;
1722 	uint32_t clusters;
1723 	int i, rc;
1724 
1725 	/* Init blobstore */
1726 	dev = init_dev();
1727 	spdk_bs_opts_init(&opts);
1728 
1729 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
1730 	CU_ASSERT(g_bserrno == 0);
1731 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1732 
1733 	clusters = spdk_bs_total_data_cluster_count(g_bs);
1734 
1735 	/* Unload the blob store */
1736 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1737 	CU_ASSERT(g_bserrno == 0);
1738 	g_bs = NULL;
1739 
1740 	dev = init_dev();
1741 	/* Load an existing blob store */
1742 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1743 	CU_ASSERT(g_bserrno == 0);
1744 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1745 
1746 	CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters);
1747 
1748 	/* Create and resize blobs to make sure that useable cluster count won't change */
1749 	for (i = 0; i < 4; i++) {
1750 		g_bserrno = -1;
1751 		g_blobid = SPDK_BLOBID_INVALID;
1752 		spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
1753 		CU_ASSERT(g_bserrno == 0);
1754 		CU_ASSERT(g_blobid !=  SPDK_BLOBID_INVALID);
1755 
1756 		g_bserrno = -1;
1757 		g_blob = NULL;
1758 		spdk_bs_open_blob(g_bs, g_blobid, blob_op_with_handle_complete, NULL);
1759 		CU_ASSERT(g_bserrno == 0);
1760 		CU_ASSERT(g_blob !=  NULL);
1761 
1762 		rc = spdk_blob_resize(g_blob, 10);
1763 		CU_ASSERT(rc == 0);
1764 
1765 		g_bserrno = -1;
1766 		spdk_blob_close(g_blob, blob_op_complete, NULL);
1767 		CU_ASSERT(g_bserrno == 0);
1768 
1769 		CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters);
1770 	}
1771 
1772 	/* Reload the blob store to make sure that nothing changed */
1773 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1774 	CU_ASSERT(g_bserrno == 0);
1775 	g_bs = NULL;
1776 
1777 	dev = init_dev();
1778 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1779 	CU_ASSERT(g_bserrno == 0);
1780 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1781 
1782 	CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters);
1783 
1784 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1785 	CU_ASSERT(g_bserrno == 0);
1786 	g_bs = NULL;
1787 }
1788 
1789 /*
1790  * Test resizing of the metadata blob.  This requires creating enough blobs
1791  *  so that one cluster is not enough to fit the metadata for those blobs.
1792  *  To induce this condition to happen more quickly, we reduce the cluster
1793  *  size to 16KB, which means only 4 4KB blob metadata pages can fit.
1794  */
1795 static void
1796 bs_resize_md(void)
1797 {
1798 	const int CLUSTER_PAGE_COUNT = 4;
1799 	const int NUM_BLOBS = CLUSTER_PAGE_COUNT * 4;
1800 	struct spdk_bs_dev *dev;
1801 	struct spdk_bs_opts opts;
1802 	uint32_t cluster_sz;
1803 	spdk_blob_id blobids[NUM_BLOBS];
1804 	int i;
1805 
1806 
1807 	dev = init_dev();
1808 	spdk_bs_opts_init(&opts);
1809 	opts.cluster_sz = CLUSTER_PAGE_COUNT * 4096;
1810 	cluster_sz = opts.cluster_sz;
1811 
1812 	/* Initialize a new blob store */
1813 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
1814 	CU_ASSERT(g_bserrno == 0);
1815 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1816 
1817 	CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz);
1818 
1819 	for (i = 0; i < NUM_BLOBS; i++) {
1820 		g_bserrno = -1;
1821 		g_blobid = SPDK_BLOBID_INVALID;
1822 		spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
1823 		CU_ASSERT(g_bserrno == 0);
1824 		CU_ASSERT(g_blobid !=  SPDK_BLOBID_INVALID);
1825 		blobids[i] = g_blobid;
1826 	}
1827 
1828 	/* Unload the blob store */
1829 	g_bserrno = -1;
1830 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1831 	CU_ASSERT(g_bserrno == 0);
1832 
1833 	/* Load an existing blob store */
1834 	g_bserrno = -1;
1835 	g_bs = NULL;
1836 	dev = init_dev();
1837 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1838 	CU_ASSERT(g_bserrno == 0);
1839 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1840 
1841 	CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz);
1842 
1843 	for (i = 0; i < NUM_BLOBS; i++) {
1844 		g_bserrno = -1;
1845 		g_blob = NULL;
1846 		spdk_bs_open_blob(g_bs, blobids[i], blob_op_with_handle_complete, NULL);
1847 		CU_ASSERT(g_bserrno == 0);
1848 		CU_ASSERT(g_blob !=  NULL);
1849 		g_bserrno = -1;
1850 		spdk_blob_close(g_blob, blob_op_complete, NULL);
1851 		CU_ASSERT(g_bserrno == 0);
1852 	}
1853 
1854 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1855 	CU_ASSERT(g_bserrno == 0);
1856 	g_bs = NULL;
1857 }
1858 
1859 static void
1860 bs_destroy(void)
1861 {
1862 	struct spdk_bs_dev *dev;
1863 	struct spdk_bs_opts opts;
1864 
1865 	/* Initialize a new blob store */
1866 	dev = init_dev();
1867 	spdk_bs_opts_init(&opts);
1868 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
1869 	CU_ASSERT(g_bserrno == 0);
1870 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1871 
1872 	/* Destroy the blob store */
1873 	g_bserrno = -1;
1874 	spdk_bs_destroy(g_bs, bs_op_complete, NULL);
1875 	CU_ASSERT(g_bserrno == 0);
1876 
1877 	/* Loading an non-existent blob store should fail. */
1878 	g_bs = NULL;
1879 	dev = init_dev();
1880 
1881 	g_bserrno = 0;
1882 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1883 	CU_ASSERT(g_bserrno != 0);
1884 }
1885 
1886 /* Try to hit all of the corner cases associated with serializing
1887  * a blob to disk
1888  */
1889 static void
1890 blob_serialize(void)
1891 {
1892 	struct spdk_bs_dev *dev;
1893 	struct spdk_bs_opts opts;
1894 	struct spdk_blob_store *bs;
1895 	spdk_blob_id blobid[2];
1896 	struct spdk_blob *blob[2];
1897 	uint64_t i;
1898 	char *value;
1899 	int rc;
1900 
1901 	dev = init_dev();
1902 
1903 	/* Initialize a new blobstore with very small clusters */
1904 	spdk_bs_opts_init(&opts);
1905 	opts.cluster_sz = dev->blocklen * 8;
1906 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
1907 	CU_ASSERT(g_bserrno == 0);
1908 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1909 	bs = g_bs;
1910 
1911 	/* Create and open two blobs */
1912 	for (i = 0; i < 2; i++) {
1913 		spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
1914 		CU_ASSERT(g_bserrno == 0);
1915 		CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1916 		blobid[i] = g_blobid;
1917 
1918 		/* Open a blob */
1919 		spdk_bs_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL);
1920 		CU_ASSERT(g_bserrno == 0);
1921 		CU_ASSERT(g_blob != NULL);
1922 		blob[i] = g_blob;
1923 
1924 		/* Set a fairly large xattr on both blobs to eat up
1925 		 * metadata space
1926 		 */
1927 		value = calloc(dev->blocklen - 64, sizeof(char));
1928 		SPDK_CU_ASSERT_FATAL(value != NULL);
1929 		memset(value, i, dev->blocklen / 2);
1930 		rc = spdk_blob_set_xattr(blob[i], "name", value, dev->blocklen - 64);
1931 		CU_ASSERT(rc == 0);
1932 		free(value);
1933 	}
1934 
1935 	/* Resize the blobs, alternating 1 cluster at a time.
1936 	 * This thwarts run length encoding and will cause spill
1937 	 * over of the extents.
1938 	 */
1939 	for (i = 0; i < 6; i++) {
1940 		rc = spdk_blob_resize(blob[i % 2], (i / 2) + 1);
1941 		CU_ASSERT(rc == 0);
1942 	}
1943 
1944 	for (i = 0; i < 2; i++) {
1945 		spdk_blob_sync_md(blob[i], blob_op_complete, NULL);
1946 		CU_ASSERT(g_bserrno == 0);
1947 	}
1948 
1949 	/* Close the blobs */
1950 	for (i = 0; i < 2; i++) {
1951 		spdk_blob_close(blob[i], blob_op_complete, NULL);
1952 		CU_ASSERT(g_bserrno == 0);
1953 	}
1954 
1955 	/* Unload the blobstore */
1956 	spdk_bs_unload(bs, bs_op_complete, NULL);
1957 	CU_ASSERT(g_bserrno == 0);
1958 	g_bs = NULL;
1959 	g_blob = NULL;
1960 	g_blobid = 0;
1961 	bs = NULL;
1962 
1963 	dev = init_dev();
1964 	/* Load an existing blob store */
1965 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1966 	CU_ASSERT(g_bserrno == 0);
1967 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1968 	bs = g_bs;
1969 
1970 	for (i = 0; i < 2; i++) {
1971 		blob[i] = NULL;
1972 
1973 		spdk_bs_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL);
1974 		CU_ASSERT(g_bserrno == 0);
1975 		CU_ASSERT(g_blob != NULL);
1976 		blob[i] = g_blob;
1977 
1978 		CU_ASSERT(spdk_blob_get_num_clusters(blob[i]) == 3);
1979 
1980 		spdk_blob_close(blob[i], blob_op_complete, NULL);
1981 		CU_ASSERT(g_bserrno == 0);
1982 	}
1983 
1984 	spdk_bs_unload(bs, bs_op_complete, NULL);
1985 	CU_ASSERT(g_bserrno == 0);
1986 	g_bs = NULL;
1987 }
1988 
1989 static void
1990 blob_crc(void)
1991 {
1992 	struct spdk_blob_store *bs;
1993 	struct spdk_bs_dev *dev;
1994 	struct spdk_blob *blob;
1995 	spdk_blob_id blobid;
1996 	uint32_t page_num;
1997 	int index;
1998 	struct spdk_blob_md_page *page;
1999 
2000 	dev = init_dev();
2001 
2002 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
2003 	CU_ASSERT(g_bserrno == 0);
2004 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2005 	bs = g_bs;
2006 
2007 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
2008 	CU_ASSERT(g_bserrno == 0);
2009 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2010 	blobid = g_blobid;
2011 
2012 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
2013 	CU_ASSERT(g_bserrno == 0);
2014 	CU_ASSERT(g_blob != NULL);
2015 	blob = g_blob;
2016 
2017 	spdk_blob_close(blob, blob_op_complete, NULL);
2018 	CU_ASSERT(g_bserrno == 0);
2019 
2020 	page_num = _spdk_bs_blobid_to_page(blobid);
2021 	index = DEV_BUFFER_BLOCKLEN * (bs->md_start + page_num);
2022 	page = (struct spdk_blob_md_page *)&g_dev_buffer[index];
2023 	page->crc = 0;
2024 
2025 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
2026 	CU_ASSERT(g_bserrno == -EINVAL);
2027 	CU_ASSERT(g_blob == NULL);
2028 	g_bserrno = 0;
2029 
2030 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
2031 	CU_ASSERT(g_bserrno == -EINVAL);
2032 
2033 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2034 	CU_ASSERT(g_bserrno == 0);
2035 	g_bs = NULL;
2036 }
2037 
2038 static void
2039 super_block_crc(void)
2040 {
2041 	struct spdk_bs_dev *dev;
2042 	struct spdk_bs_super_block *super_block;
2043 	struct spdk_bs_opts opts;
2044 
2045 	dev = init_dev();
2046 	spdk_bs_opts_init(&opts);
2047 
2048 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
2049 	CU_ASSERT(g_bserrno == 0);
2050 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2051 
2052 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2053 	CU_ASSERT(g_bserrno == 0);
2054 	g_bs = NULL;
2055 
2056 	super_block = (struct spdk_bs_super_block *)g_dev_buffer;
2057 	super_block->crc = 0;
2058 	dev = init_dev();
2059 
2060 	/* Load an existing blob store */
2061 	g_bserrno = 0;
2062 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2063 	CU_ASSERT(g_bserrno == -EILSEQ);
2064 }
2065 
2066 /* For blob dirty shutdown test case we do the following sub-test cases:
2067  * 1 Initialize new blob store and create 1 blob with some xattrs, then we
2068  *   dirty shutdown and reload the blob store and verify the xattrs.
2069  * 2 Resize the blob from 10 clusters to 20 clusters and then dirty shutdown,
2070  *   reload the blob store and verify the clusters number.
2071  * 3 Create the second blob and then dirty shutdown, reload the blob store
2072  *   and verify the second blob.
2073  * 4 Delete the second blob and then dirty shutdown, reload teh blob store
2074  *   and verify the second blob is invalid.
2075  * 5 Create the second blob again and also create the third blob, modify the
2076  *   md of second blob which makes the md invalid, and then dirty shutdown,
2077  *   reload the blob store verify the second blob, it should invalid and also
2078  *   verify the third blob, it should correct.
2079  */
2080 static void
2081 blob_dirty_shutdown(void)
2082 {
2083 	int rc;
2084 	int index;
2085 	struct spdk_bs_dev *dev;
2086 	spdk_blob_id blobid1, blobid2, blobid3;
2087 	struct spdk_blob *blob;
2088 	uint64_t length;
2089 	uint64_t free_clusters;
2090 	const void *value;
2091 	size_t value_len;
2092 	uint32_t page_num;
2093 	struct spdk_blob_md_page *page;
2094 	struct spdk_bs_opts opts;
2095 
2096 	dev = init_dev();
2097 	spdk_bs_opts_init(&opts);
2098 	/* Initialize a new blob store */
2099 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
2100 	CU_ASSERT(g_bserrno == 0);
2101 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2102 
2103 	/* Create first blob */
2104 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
2105 	CU_ASSERT(g_bserrno == 0);
2106 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2107 	blobid1 = g_blobid;
2108 
2109 	spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL);
2110 	CU_ASSERT(g_bserrno == 0);
2111 	CU_ASSERT(g_blob != NULL);
2112 	blob = g_blob;
2113 
2114 	/* Set some xattrs */
2115 	rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1);
2116 	CU_ASSERT(rc == 0);
2117 
2118 	length = 2345;
2119 	rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
2120 	CU_ASSERT(rc == 0);
2121 
2122 	/* Resize the blob */
2123 	rc = spdk_blob_resize(blob, 10);
2124 	CU_ASSERT(rc == 0);
2125 
2126 	free_clusters = spdk_bs_free_cluster_count(g_bs);
2127 
2128 	spdk_blob_close(blob, blob_op_complete, NULL);
2129 	blob = NULL;
2130 	g_blob = NULL;
2131 	g_blobid = SPDK_BLOBID_INVALID;
2132 
2133 	/* Dirty shutdown */
2134 	_spdk_bs_free(g_bs);
2135 
2136 	/* reload blobstore */
2137 	dev = init_dev();
2138 	spdk_bs_opts_init(&opts);
2139 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2140 	CU_ASSERT(g_bserrno == 0);
2141 
2142 	spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL);
2143 	CU_ASSERT(g_bserrno == 0);
2144 	CU_ASSERT(g_blob != NULL);
2145 	blob = g_blob;
2146 
2147 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs));
2148 
2149 	/* Get the xattrs */
2150 	value = NULL;
2151 	rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len);
2152 	CU_ASSERT(rc == 0);
2153 	SPDK_CU_ASSERT_FATAL(value != NULL);
2154 	CU_ASSERT(*(uint64_t *)value == length);
2155 	CU_ASSERT(value_len == 8);
2156 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10);
2157 
2158 	/* Resize the blob */
2159 	rc = spdk_blob_resize(blob, 20);
2160 	CU_ASSERT(rc == 0);
2161 
2162 	free_clusters = spdk_bs_free_cluster_count(g_bs);
2163 
2164 	spdk_blob_close(blob, blob_op_complete, NULL);
2165 	CU_ASSERT(g_bserrno == 0);
2166 	blob = NULL;
2167 	g_blob = NULL;
2168 	g_blobid = SPDK_BLOBID_INVALID;
2169 
2170 	/* Dirty shutdown */
2171 	_spdk_bs_free(g_bs);
2172 
2173 	/* reload the blobstore */
2174 	dev = init_dev();
2175 	spdk_bs_opts_init(&opts);
2176 	/* Load an existing blob store */
2177 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2178 	CU_ASSERT(g_bserrno == 0);
2179 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2180 	spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL);
2181 	CU_ASSERT(g_bserrno == 0);
2182 	CU_ASSERT(g_blob != NULL);
2183 	blob = g_blob;
2184 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 20);
2185 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs));
2186 
2187 	spdk_blob_close(blob, blob_op_complete, NULL);
2188 	CU_ASSERT(g_bserrno == 0);
2189 	blob = NULL;
2190 	g_blob = NULL;
2191 	g_blobid = SPDK_BLOBID_INVALID;
2192 
2193 	/* Create second blob */
2194 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
2195 	CU_ASSERT(g_bserrno == 0);
2196 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2197 	blobid2 = g_blobid;
2198 
2199 	spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL);
2200 	CU_ASSERT(g_bserrno == 0);
2201 	CU_ASSERT(g_blob != NULL);
2202 	blob = g_blob;
2203 
2204 	/* Set some xattrs */
2205 	rc = spdk_blob_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1);
2206 	CU_ASSERT(rc == 0);
2207 
2208 	length = 5432;
2209 	rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
2210 	CU_ASSERT(rc == 0);
2211 
2212 	/* Resize the blob */
2213 	rc = spdk_blob_resize(blob, 10);
2214 	CU_ASSERT(rc == 0);
2215 
2216 	free_clusters = spdk_bs_free_cluster_count(g_bs);
2217 
2218 	spdk_blob_close(blob, blob_op_complete, NULL);
2219 	blob = NULL;
2220 	g_blob = NULL;
2221 	g_blobid = SPDK_BLOBID_INVALID;
2222 
2223 	/* Dirty shutdown */
2224 	_spdk_bs_free(g_bs);
2225 
2226 	/* reload the blobstore */
2227 	dev = init_dev();
2228 	spdk_bs_opts_init(&opts);
2229 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2230 	CU_ASSERT(g_bserrno == 0);
2231 
2232 	spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL);
2233 	CU_ASSERT(g_bserrno == 0);
2234 	CU_ASSERT(g_blob != NULL);
2235 	blob = g_blob;
2236 
2237 	/* Get the xattrs */
2238 	value = NULL;
2239 	rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len);
2240 	CU_ASSERT(rc == 0);
2241 	SPDK_CU_ASSERT_FATAL(value != NULL);
2242 	CU_ASSERT(*(uint64_t *)value == length);
2243 	CU_ASSERT(value_len == 8);
2244 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10);
2245 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs));
2246 
2247 	spdk_blob_close(blob, blob_op_complete, NULL);
2248 	CU_ASSERT(g_bserrno == 0);
2249 	spdk_bs_delete_blob(g_bs, blobid2, blob_op_complete, NULL);
2250 	CU_ASSERT(g_bserrno == 0);
2251 
2252 	free_clusters = spdk_bs_free_cluster_count(g_bs);
2253 
2254 	/* Dirty shutdown */
2255 	_spdk_bs_free(g_bs);
2256 	/* reload the blobstore */
2257 	dev = init_dev();
2258 	spdk_bs_opts_init(&opts);
2259 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2260 	CU_ASSERT(g_bserrno == 0);
2261 
2262 	spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL);
2263 	CU_ASSERT(g_bserrno != 0);
2264 	CU_ASSERT(g_blob == NULL);
2265 
2266 	spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL);
2267 	CU_ASSERT(g_bserrno == 0);
2268 	CU_ASSERT(g_blob != NULL);
2269 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs));
2270 	spdk_blob_close(g_blob, blob_op_complete, NULL);
2271 	CU_ASSERT(g_bserrno == 0);
2272 
2273 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2274 	CU_ASSERT(g_bserrno == 0);
2275 	g_bs = NULL;
2276 
2277 	/* reload the blobstore */
2278 	dev = init_dev();
2279 	spdk_bs_opts_init(&opts);
2280 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2281 	CU_ASSERT(g_bserrno == 0);
2282 
2283 	/* Create second blob */
2284 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
2285 	CU_ASSERT(g_bserrno == 0);
2286 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2287 	blobid2 = g_blobid;
2288 
2289 	/* Create third blob */
2290 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
2291 	CU_ASSERT(g_bserrno == 0);
2292 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2293 	blobid3 = g_blobid;
2294 
2295 	spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL);
2296 	CU_ASSERT(g_bserrno == 0);
2297 	CU_ASSERT(g_blob != NULL);
2298 	blob = g_blob;
2299 
2300 	/* Set some xattrs for second blob */
2301 	rc = spdk_blob_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1);
2302 	CU_ASSERT(rc == 0);
2303 
2304 	length = 5432;
2305 	rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
2306 	CU_ASSERT(rc == 0);
2307 
2308 	spdk_blob_close(blob, blob_op_complete, NULL);
2309 	blob = NULL;
2310 	g_blob = NULL;
2311 	g_blobid = SPDK_BLOBID_INVALID;
2312 
2313 	spdk_bs_open_blob(g_bs, blobid3, blob_op_with_handle_complete, NULL);
2314 	CU_ASSERT(g_bserrno == 0);
2315 	CU_ASSERT(g_blob != NULL);
2316 	blob = g_blob;
2317 
2318 	/* Set some xattrs for third blob */
2319 	rc = spdk_blob_set_xattr(blob, "name", "log2.txt", strlen("log2.txt") + 1);
2320 	CU_ASSERT(rc == 0);
2321 
2322 	length = 5432;
2323 	rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
2324 	CU_ASSERT(rc == 0);
2325 
2326 	spdk_blob_close(blob, blob_op_complete, NULL);
2327 	blob = NULL;
2328 	g_blob = NULL;
2329 	g_blobid = SPDK_BLOBID_INVALID;
2330 
2331 	/* Mark second blob as invalid */
2332 	page_num = _spdk_bs_blobid_to_page(blobid2);
2333 
2334 	index = DEV_BUFFER_BLOCKLEN * (g_bs->md_start + page_num);
2335 	page = (struct spdk_blob_md_page *)&g_dev_buffer[index];
2336 	page->sequence_num = 1;
2337 	page->crc = _spdk_blob_md_page_calc_crc(page);
2338 
2339 	free_clusters = spdk_bs_free_cluster_count(g_bs);
2340 
2341 	/* Dirty shutdown */
2342 	_spdk_bs_free(g_bs);
2343 	/* reload the blobstore */
2344 	dev = init_dev();
2345 	spdk_bs_opts_init(&opts);
2346 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2347 	CU_ASSERT(g_bserrno == 0);
2348 
2349 	spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL);
2350 	CU_ASSERT(g_bserrno != 0);
2351 	CU_ASSERT(g_blob == NULL);
2352 
2353 	spdk_bs_open_blob(g_bs, blobid3, blob_op_with_handle_complete, NULL);
2354 	CU_ASSERT(g_bserrno == 0);
2355 	CU_ASSERT(g_blob != NULL);
2356 	blob = g_blob;
2357 
2358 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs));
2359 
2360 	spdk_blob_close(blob, blob_op_complete, NULL);
2361 	blob = NULL;
2362 	g_blob = NULL;
2363 	g_blobid = SPDK_BLOBID_INVALID;
2364 
2365 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2366 	CU_ASSERT(g_bserrno == 0);
2367 	g_bs = NULL;
2368 }
2369 
2370 static void
2371 blob_flags(void)
2372 {
2373 	struct spdk_bs_dev *dev;
2374 	spdk_blob_id blobid_invalid, blobid_data_ro, blobid_md_ro;
2375 	struct spdk_blob *blob_invalid, *blob_data_ro, *blob_md_ro;
2376 	struct spdk_bs_opts opts;
2377 	int rc;
2378 
2379 	dev = init_dev();
2380 	spdk_bs_opts_init(&opts);
2381 
2382 	/* Initialize a new blob store */
2383 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2384 	CU_ASSERT(g_bserrno == 0);
2385 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2386 
2387 	/* Create three blobs - one each for testing invalid, data_ro and md_ro flags. */
2388 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
2389 	CU_ASSERT(g_bserrno == 0);
2390 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2391 	blobid_invalid = g_blobid;
2392 
2393 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
2394 	CU_ASSERT(g_bserrno == 0);
2395 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2396 	blobid_data_ro = g_blobid;
2397 
2398 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
2399 	CU_ASSERT(g_bserrno == 0);
2400 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2401 	blobid_md_ro = g_blobid;
2402 
2403 	spdk_bs_open_blob(g_bs, blobid_invalid, blob_op_with_handle_complete, NULL);
2404 	CU_ASSERT(g_bserrno == 0);
2405 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
2406 	blob_invalid = g_blob;
2407 
2408 	spdk_bs_open_blob(g_bs, blobid_data_ro, blob_op_with_handle_complete, NULL);
2409 	CU_ASSERT(g_bserrno == 0);
2410 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
2411 	blob_data_ro = g_blob;
2412 
2413 	spdk_bs_open_blob(g_bs, blobid_md_ro, blob_op_with_handle_complete, NULL);
2414 	CU_ASSERT(g_bserrno == 0);
2415 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
2416 	blob_md_ro = g_blob;
2417 
2418 	/* Change the size of blob_data_ro to check if flags are serialized
2419 	 * when blob has non zero number of extents */
2420 	rc = spdk_blob_resize(blob_data_ro, 10);
2421 	CU_ASSERT(rc == 0);
2422 
2423 	/* Set the xattr to check if flags are serialized
2424 	 * when blob has non zero number of xattrs */
2425 	rc = spdk_blob_set_xattr(blob_md_ro, "name", "log.txt", strlen("log.txt") + 1);
2426 	CU_ASSERT(rc == 0);
2427 
2428 	blob_invalid->invalid_flags = (1ULL << 63);
2429 	blob_invalid->state = SPDK_BLOB_STATE_DIRTY;
2430 	blob_data_ro->data_ro_flags = (1ULL << 62);
2431 	blob_data_ro->state = SPDK_BLOB_STATE_DIRTY;
2432 	blob_md_ro->md_ro_flags = (1ULL << 61);
2433 	blob_md_ro->state = SPDK_BLOB_STATE_DIRTY;
2434 
2435 	g_bserrno = -1;
2436 	spdk_blob_sync_md(blob_invalid, blob_op_complete, NULL);
2437 	CU_ASSERT(g_bserrno == 0);
2438 	g_bserrno = -1;
2439 	spdk_blob_sync_md(blob_data_ro, blob_op_complete, NULL);
2440 	CU_ASSERT(g_bserrno == 0);
2441 	g_bserrno = -1;
2442 	spdk_blob_sync_md(blob_md_ro, blob_op_complete, NULL);
2443 	CU_ASSERT(g_bserrno == 0);
2444 
2445 	g_bserrno = -1;
2446 	spdk_blob_close(blob_invalid, blob_op_complete, NULL);
2447 	CU_ASSERT(g_bserrno == 0);
2448 	blob_invalid = NULL;
2449 	g_bserrno = -1;
2450 	spdk_blob_close(blob_data_ro, blob_op_complete, NULL);
2451 	CU_ASSERT(g_bserrno == 0);
2452 	blob_data_ro = NULL;
2453 	g_bserrno = -1;
2454 	spdk_blob_close(blob_md_ro, blob_op_complete, NULL);
2455 	CU_ASSERT(g_bserrno == 0);
2456 	blob_md_ro = NULL;
2457 
2458 	g_blob = NULL;
2459 	g_blobid = SPDK_BLOBID_INVALID;
2460 
2461 	/* Unload the blob store */
2462 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2463 	CU_ASSERT(g_bserrno == 0);
2464 	g_bs = NULL;
2465 
2466 	/* Load an existing blob store */
2467 	dev = init_dev();
2468 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2469 	CU_ASSERT(g_bserrno == 0);
2470 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2471 
2472 	g_blob = NULL;
2473 	g_bserrno = 0;
2474 	spdk_bs_open_blob(g_bs, blobid_invalid, blob_op_with_handle_complete, NULL);
2475 	CU_ASSERT(g_bserrno != 0);
2476 	CU_ASSERT(g_blob == NULL);
2477 
2478 	g_blob = NULL;
2479 	g_bserrno = -1;
2480 	spdk_bs_open_blob(g_bs, blobid_data_ro, blob_op_with_handle_complete, NULL);
2481 	CU_ASSERT(g_bserrno == 0);
2482 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
2483 	blob_data_ro = g_blob;
2484 	/* If an unknown data_ro flag was found, the blob should be marked both data and md read-only. */
2485 	CU_ASSERT(blob_data_ro->data_ro == true);
2486 	CU_ASSERT(blob_data_ro->md_ro == true);
2487 	CU_ASSERT(spdk_blob_get_num_clusters(blob_data_ro) == 10);
2488 
2489 	g_blob = NULL;
2490 	g_bserrno = -1;
2491 	spdk_bs_open_blob(g_bs, blobid_md_ro, blob_op_with_handle_complete, NULL);
2492 	CU_ASSERT(g_bserrno == 0);
2493 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
2494 	blob_md_ro = g_blob;
2495 	CU_ASSERT(blob_md_ro->data_ro == false);
2496 	CU_ASSERT(blob_md_ro->md_ro == true);
2497 
2498 	g_bserrno = -1;
2499 	spdk_blob_sync_md(blob_md_ro, blob_op_complete, NULL);
2500 	CU_ASSERT(g_bserrno == 0);
2501 
2502 	spdk_blob_close(blob_data_ro, blob_op_complete, NULL);
2503 	CU_ASSERT(g_bserrno == 0);
2504 	spdk_blob_close(blob_md_ro, blob_op_complete, NULL);
2505 	CU_ASSERT(g_bserrno == 0);
2506 
2507 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2508 	CU_ASSERT(g_bserrno == 0);
2509 }
2510 
2511 static void
2512 bs_version(void)
2513 {
2514 	struct spdk_bs_super_block *super;
2515 	struct spdk_bs_dev *dev;
2516 	struct spdk_bs_opts opts;
2517 	spdk_blob_id blobid;
2518 
2519 	dev = init_dev();
2520 	spdk_bs_opts_init(&opts);
2521 
2522 	/* Initialize a new blob store */
2523 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2524 	CU_ASSERT(g_bserrno == 0);
2525 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2526 
2527 	/* Unload the blob store */
2528 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2529 	CU_ASSERT(g_bserrno == 0);
2530 	g_bs = NULL;
2531 
2532 	/*
2533 	 * Change the bs version on disk.  This will allow us to
2534 	 *  test that the version does not get modified automatically
2535 	 *  when loading and unloading the blobstore.
2536 	 */
2537 	super = (struct spdk_bs_super_block *)&g_dev_buffer[0];
2538 	CU_ASSERT(super->version == SPDK_BS_VERSION);
2539 	CU_ASSERT(super->clean == 1);
2540 	super->version = 2;
2541 	/*
2542 	 * Version 2 metadata does not have a used blobid mask, so clear
2543 	 *  those fields in the super block and zero the corresponding
2544 	 *  region on "disk".  We will use this to ensure blob IDs are
2545 	 *  correctly reconstructed.
2546 	 */
2547 	memset(&g_dev_buffer[super->used_blobid_mask_start * SPDK_BS_PAGE_SIZE], 0,
2548 	       super->used_blobid_mask_len * SPDK_BS_PAGE_SIZE);
2549 	super->used_blobid_mask_start = 0;
2550 	super->used_blobid_mask_len = 0;
2551 	super->crc = _spdk_blob_md_page_calc_crc(super);
2552 
2553 	/* Load an existing blob store */
2554 	dev = init_dev();
2555 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2556 	CU_ASSERT(g_bserrno == 0);
2557 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2558 	CU_ASSERT(super->clean == 0);
2559 
2560 	/*
2561 	 * Create a blob - just to make sure that when we unload it
2562 	 *  results in writing the super block (since metadata pages
2563 	 *  were allocated.
2564 	 */
2565 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
2566 	CU_ASSERT(g_bserrno == 0);
2567 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2568 	blobid = g_blobid;
2569 
2570 	/* Unload the blob store */
2571 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2572 	CU_ASSERT(g_bserrno == 0);
2573 	g_bs = NULL;
2574 	CU_ASSERT(super->version == 2);
2575 	CU_ASSERT(super->used_blobid_mask_start == 0);
2576 	CU_ASSERT(super->used_blobid_mask_len == 0);
2577 
2578 	dev = init_dev();
2579 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2580 	CU_ASSERT(g_bserrno == 0);
2581 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2582 
2583 	g_blob = NULL;
2584 	spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
2585 	CU_ASSERT(g_bserrno == 0);
2586 	CU_ASSERT(g_blob != NULL);
2587 
2588 	spdk_blob_close(g_blob, blob_op_complete, NULL);
2589 	CU_ASSERT(g_bserrno == 0);
2590 
2591 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2592 	CU_ASSERT(g_bserrno == 0);
2593 	g_bs = NULL;
2594 	CU_ASSERT(super->version == 2);
2595 	CU_ASSERT(super->used_blobid_mask_start == 0);
2596 	CU_ASSERT(super->used_blobid_mask_len == 0);
2597 }
2598 
2599 static void
2600 _get_xattr_value(void *arg, const char *name,
2601 		 const void **value, size_t *value_len)
2602 {
2603 	uint64_t i;
2604 
2605 	SPDK_CU_ASSERT_FATAL(value_len != NULL);
2606 	SPDK_CU_ASSERT_FATAL(value != NULL);
2607 	CU_ASSERT(arg == &g_ctx)
2608 
2609 	for (i = 0; i < sizeof(g_xattr_names); i++) {
2610 		if (!strcmp(name, g_xattr_names[i])) {
2611 			*value_len = strlen(g_xattr_values[i]);
2612 			*value = g_xattr_values[i];
2613 			break;
2614 		}
2615 	}
2616 }
2617 
2618 static void
2619 _get_xattr_value_null(void *arg, const char *name,
2620 		      const void **value, size_t *value_len)
2621 {
2622 	SPDK_CU_ASSERT_FATAL(value_len != NULL);
2623 	SPDK_CU_ASSERT_FATAL(value != NULL);
2624 	CU_ASSERT(arg == NULL)
2625 
2626 	*value_len = 0;
2627 	*value = NULL;
2628 }
2629 
2630 static void
2631 blob_set_xattrs(void)
2632 {
2633 	struct spdk_blob_store *bs;
2634 	struct spdk_bs_dev *dev;
2635 	struct spdk_blob *blob;
2636 	struct spdk_blob_opts opts;
2637 	spdk_blob_id blobid;
2638 	const void *value;
2639 	size_t value_len;
2640 	int rc;
2641 
2642 	dev = init_dev();
2643 
2644 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
2645 	CU_ASSERT(g_bserrno == 0);
2646 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2647 	bs = g_bs;
2648 
2649 	/* Create blob with extra attributes */
2650 	spdk_blob_opts_init(&opts);
2651 
2652 	opts.xattrs.names = g_xattr_names;
2653 	opts.xattrs.get_value = _get_xattr_value;
2654 	opts.xattrs.count = 3;
2655 	opts.xattrs.ctx = &g_ctx;
2656 
2657 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
2658 	CU_ASSERT(g_bserrno == 0);
2659 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2660 	blobid = g_blobid;
2661 
2662 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
2663 	CU_ASSERT(g_bserrno == 0);
2664 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
2665 	blob = g_blob;
2666 
2667 	/* Get the xattrs */
2668 	value = NULL;
2669 
2670 	rc = spdk_blob_get_xattr_value(blob, g_xattr_names[0], &value, &value_len);
2671 	CU_ASSERT(rc == 0);
2672 	SPDK_CU_ASSERT_FATAL(value != NULL);
2673 	CU_ASSERT(value_len == strlen(g_xattr_values[0]));
2674 	CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len);
2675 
2676 	rc = spdk_blob_get_xattr_value(blob, g_xattr_names[1], &value, &value_len);
2677 	CU_ASSERT(rc == 0);
2678 	SPDK_CU_ASSERT_FATAL(value != NULL);
2679 	CU_ASSERT(value_len == strlen(g_xattr_values[1]));
2680 	CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len);
2681 
2682 	rc = spdk_blob_get_xattr_value(blob, g_xattr_names[2], &value, &value_len);
2683 	CU_ASSERT(rc == 0);
2684 	SPDK_CU_ASSERT_FATAL(value != NULL);
2685 	CU_ASSERT(value_len == strlen(g_xattr_values[2]));
2686 	CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len);
2687 
2688 	/* Try to get non existing attribute */
2689 
2690 	rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len);
2691 	CU_ASSERT(rc == -ENOENT);
2692 
2693 	spdk_blob_close(blob, blob_op_complete, NULL);
2694 	CU_ASSERT(g_bserrno == 0);
2695 	blob = NULL;
2696 	g_blob = NULL;
2697 	g_blobid = SPDK_BLOBID_INVALID;
2698 
2699 	/* NULL callback */
2700 	spdk_blob_opts_init(&opts);
2701 	opts.xattrs.names = g_xattr_names;
2702 	opts.xattrs.get_value = NULL;
2703 	opts.xattrs.count = 1;
2704 	opts.xattrs.ctx = &g_ctx;
2705 
2706 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
2707 	CU_ASSERT(g_bserrno == -EINVAL);
2708 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2709 
2710 	/* NULL values */
2711 	spdk_blob_opts_init(&opts);
2712 	opts.xattrs.names = g_xattr_names;
2713 	opts.xattrs.get_value = _get_xattr_value_null;
2714 	opts.xattrs.count = 1;
2715 	opts.xattrs.ctx = NULL;
2716 
2717 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
2718 	CU_ASSERT(g_bserrno == -EINVAL);
2719 
2720 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2721 	CU_ASSERT(g_bserrno == 0);
2722 	g_bs = NULL;
2723 
2724 }
2725 
2726 static void
2727 blob_thin_prov_alloc(void)
2728 {
2729 	struct spdk_blob_store *bs;
2730 	struct spdk_bs_dev *dev;
2731 	struct spdk_blob *blob;
2732 	struct spdk_blob_opts opts;
2733 	spdk_blob_id blobid;
2734 	uint64_t free_clusters;
2735 	int rc;
2736 
2737 	dev = init_dev();
2738 
2739 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
2740 	CU_ASSERT(g_bserrno == 0);
2741 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2742 	bs = g_bs;
2743 	free_clusters = spdk_bs_free_cluster_count(bs);
2744 
2745 	/* Set blob as thin provisioned */
2746 	spdk_blob_opts_init(&opts);
2747 	opts.thin_provision = true;
2748 
2749 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
2750 	CU_ASSERT(g_bserrno == 0);
2751 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2752 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
2753 	blobid = g_blobid;
2754 
2755 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
2756 	CU_ASSERT(g_bserrno == 0);
2757 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
2758 	blob = g_blob;
2759 
2760 	CU_ASSERT(blob->active.num_clusters == 0);
2761 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0);
2762 
2763 	/* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */
2764 	rc = spdk_blob_resize(blob, 5);
2765 	CU_ASSERT(rc == 0);
2766 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
2767 	CU_ASSERT(blob->active.num_clusters == 5);
2768 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5);
2769 
2770 	/* Shrink the blob to 3 clusters - still unallocated */
2771 	rc = spdk_blob_resize(blob, 3);
2772 	CU_ASSERT(rc == 0);
2773 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
2774 	CU_ASSERT(blob->active.num_clusters == 3);
2775 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 3);
2776 
2777 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
2778 	CU_ASSERT(g_bserrno == 0);
2779 	/* Sync must not change anything */
2780 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
2781 	CU_ASSERT(blob->active.num_clusters == 3);
2782 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 3);
2783 
2784 	spdk_blob_close(blob, blob_op_complete, NULL);
2785 	CU_ASSERT(g_bserrno == 0);
2786 
2787 	/* Unload the blob store */
2788 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2789 	CU_ASSERT(g_bserrno == 0);
2790 	g_bs = NULL;
2791 	g_blob = NULL;
2792 	g_blobid = 0;
2793 
2794 	/* Load an existing blob store */
2795 	dev = init_dev();
2796 	spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL);
2797 	CU_ASSERT(g_bserrno == 0);
2798 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2799 
2800 	bs = g_bs;
2801 
2802 	spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
2803 	CU_ASSERT(g_bserrno == 0);
2804 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
2805 	blob = g_blob;
2806 
2807 	/* Check that clusters allocation and size is still the same */
2808 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
2809 	CU_ASSERT(blob->active.num_clusters == 3);
2810 
2811 	spdk_blob_close(blob, blob_op_complete, NULL);
2812 	CU_ASSERT(g_bserrno == 0);
2813 
2814 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
2815 	CU_ASSERT(g_bserrno == 0);
2816 
2817 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2818 	CU_ASSERT(g_bserrno == 0);
2819 	g_bs = NULL;
2820 }
2821 
2822 static void
2823 blob_insert_cluster_msg(void)
2824 {
2825 	struct spdk_blob_store *bs;
2826 	struct spdk_bs_dev *dev;
2827 	struct spdk_blob *blob;
2828 	struct spdk_blob_opts opts;
2829 	spdk_blob_id blobid;
2830 	uint64_t free_clusters;
2831 
2832 	dev = init_dev();
2833 
2834 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
2835 	CU_ASSERT(g_bserrno == 0);
2836 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2837 	bs = g_bs;
2838 	free_clusters = spdk_bs_free_cluster_count(bs);
2839 
2840 	/* Set blob as thin provisioned */
2841 	spdk_blob_opts_init(&opts);
2842 	opts.thin_provision = true;
2843 	opts.num_clusters = 4;
2844 
2845 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
2846 	CU_ASSERT(g_bserrno == 0);
2847 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2848 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
2849 	blobid = g_blobid;
2850 
2851 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
2852 	CU_ASSERT(g_bserrno == 0);
2853 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
2854 	blob = g_blob;
2855 
2856 	CU_ASSERT(blob->active.num_clusters == 4);
2857 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 4);
2858 	CU_ASSERT(blob->active.clusters[1] == 0);
2859 
2860 	_spdk_bs_claim_cluster(bs, 0xF);
2861 	_spdk_blob_insert_cluster_on_md_thread(blob, 1, 0xF, blob_op_complete, NULL);
2862 
2863 	CU_ASSERT(blob->active.clusters[1] != 0);
2864 
2865 	spdk_blob_close(blob, blob_op_complete, NULL);
2866 	CU_ASSERT(g_bserrno == 0);
2867 
2868 	/* Unload the blob store */
2869 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2870 	CU_ASSERT(g_bserrno == 0);
2871 	g_bs = NULL;
2872 	g_blob = NULL;
2873 	g_blobid = 0;
2874 
2875 	/* Load an existing blob store */
2876 	dev = init_dev();
2877 	spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL);
2878 	CU_ASSERT(g_bserrno == 0);
2879 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2880 
2881 	bs = g_bs;
2882 
2883 	spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
2884 	CU_ASSERT(g_bserrno == 0);
2885 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
2886 	blob = g_blob;
2887 
2888 	CU_ASSERT(blob->active.clusters[1] != 0);
2889 
2890 	spdk_blob_close(blob, blob_op_complete, NULL);
2891 	CU_ASSERT(g_bserrno == 0);
2892 
2893 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
2894 	CU_ASSERT(g_bserrno == 0);
2895 
2896 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2897 	CU_ASSERT(g_bserrno == 0);
2898 	g_bs = NULL;
2899 }
2900 
2901 static void
2902 blob_thin_prov_rw(void)
2903 {
2904 	static const uint8_t zero[10 * 4096] = { 0 };
2905 	struct spdk_blob_store *bs;
2906 	struct spdk_bs_dev *dev;
2907 	struct spdk_blob *blob;
2908 	struct spdk_io_channel *channel;
2909 	struct spdk_blob_opts 	opts;
2910 	spdk_blob_id blobid;
2911 	uint64_t free_clusters;
2912 	uint8_t payload_read[10 * 4096];
2913 	uint8_t payload_write[10 * 4096];
2914 	int rc;
2915 
2916 	dev = init_dev();
2917 
2918 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
2919 	CU_ASSERT(g_bserrno == 0);
2920 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2921 	bs = g_bs;
2922 	free_clusters = spdk_bs_free_cluster_count(bs);
2923 
2924 	channel = spdk_bs_alloc_io_channel(bs);
2925 	CU_ASSERT(channel != NULL);
2926 
2927 	spdk_blob_opts_init(&opts);
2928 	opts.thin_provision = true;
2929 
2930 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
2931 	CU_ASSERT(g_bserrno == 0);
2932 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2933 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
2934 	blobid = g_blobid;
2935 
2936 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
2937 	CU_ASSERT(g_bserrno == 0);
2938 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
2939 	blob = g_blob;
2940 
2941 	CU_ASSERT(blob->active.num_clusters == 0);
2942 
2943 	/* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */
2944 	rc = spdk_blob_resize(blob, 5);
2945 	CU_ASSERT(rc == 0);
2946 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
2947 	CU_ASSERT(blob->active.num_clusters == 5);
2948 
2949 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
2950 	CU_ASSERT(g_bserrno == 0);
2951 	/* Sync must not change anything */
2952 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
2953 	CU_ASSERT(blob->active.num_clusters == 5);
2954 
2955 	/* Payload should be all zeros from unallocated clusters */
2956 	memset(payload_read, 0xFF, sizeof(payload_read));
2957 	spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL);
2958 	CU_ASSERT(g_bserrno == 0);
2959 	CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0);
2960 
2961 	memset(payload_write, 0xE5, sizeof(payload_write));
2962 	spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL);
2963 	CU_ASSERT(g_bserrno == 0);
2964 	CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs));
2965 
2966 	spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL);
2967 	CU_ASSERT(g_bserrno == 0);
2968 	CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0);
2969 
2970 	spdk_blob_close(blob, blob_op_complete, NULL);
2971 	CU_ASSERT(g_bserrno == 0);
2972 
2973 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
2974 	CU_ASSERT(g_bserrno == 0);
2975 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
2976 
2977 	spdk_bs_free_io_channel(channel);
2978 
2979 	/* Unload the blob store */
2980 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2981 	CU_ASSERT(g_bserrno == 0);
2982 	g_bs = NULL;
2983 	g_blob = NULL;
2984 	g_blobid = 0;
2985 }
2986 
2987 static void
2988 blob_thin_prov_rw_iov(void)
2989 {
2990 	static const uint8_t zero[10 * 4096] = { 0 };
2991 	struct spdk_blob_store *bs;
2992 	struct spdk_bs_dev *dev;
2993 	struct spdk_blob *blob;
2994 	struct spdk_io_channel *channel;
2995 	struct spdk_blob_opts 	opts;
2996 	spdk_blob_id blobid;
2997 	uint64_t free_clusters;
2998 	uint8_t payload_read[10 * 4096];
2999 	uint8_t payload_write[10 * 4096];
3000 	struct iovec iov_read[3];
3001 	struct iovec iov_write[3];
3002 
3003 	int rc;
3004 
3005 	dev = init_dev();
3006 
3007 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
3008 	CU_ASSERT(g_bserrno == 0);
3009 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3010 	bs = g_bs;
3011 	free_clusters = spdk_bs_free_cluster_count(bs);
3012 
3013 	channel = spdk_bs_alloc_io_channel(bs);
3014 	CU_ASSERT(channel != NULL);
3015 
3016 	spdk_blob_opts_init(&opts);
3017 	opts.thin_provision = true;
3018 
3019 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
3020 	CU_ASSERT(g_bserrno == 0);
3021 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3022 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3023 	blobid = g_blobid;
3024 
3025 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
3026 	CU_ASSERT(g_bserrno == 0);
3027 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3028 	blob = g_blob;
3029 
3030 	CU_ASSERT(blob->active.num_clusters == 0);
3031 
3032 	/* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */
3033 	rc = spdk_blob_resize(blob, 5);
3034 	CU_ASSERT(rc == 0);
3035 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3036 	CU_ASSERT(blob->active.num_clusters == 5);
3037 
3038 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
3039 	CU_ASSERT(g_bserrno == 0);
3040 	/* Sync must not change anything */
3041 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3042 	CU_ASSERT(blob->active.num_clusters == 5);
3043 
3044 	/* Payload should be all zeros from unallocated clusters */
3045 	memset(payload_read, 0xAA, sizeof(payload_read));
3046 	iov_read[0].iov_base = payload_read;
3047 	iov_read[0].iov_len = 3 * 4096;
3048 	iov_read[1].iov_base = payload_read + 3 * 4096;
3049 	iov_read[1].iov_len = 4 * 4096;
3050 	iov_read[2].iov_base = payload_read + 7 * 4096;
3051 	iov_read[2].iov_len = 3 * 4096;
3052 	spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL);
3053 	CU_ASSERT(g_bserrno == 0);
3054 	CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0);
3055 
3056 	memset(payload_write, 0xE5, sizeof(payload_write));
3057 	iov_write[0].iov_base = payload_write;
3058 	iov_write[0].iov_len = 1 * 4096;
3059 	iov_write[1].iov_base = payload_write + 1 * 4096;
3060 	iov_write[1].iov_len = 5 * 4096;
3061 	iov_write[2].iov_base = payload_write + 6 * 4096;
3062 	iov_write[2].iov_len = 4 * 4096;
3063 
3064 	spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL);
3065 	CU_ASSERT(g_bserrno == 0);
3066 
3067 	memset(payload_read, 0xAA, sizeof(payload_read));
3068 	iov_read[0].iov_base = payload_read;
3069 	iov_read[0].iov_len = 3 * 4096;
3070 	iov_read[1].iov_base = payload_read + 3 * 4096;
3071 	iov_read[1].iov_len = 4 * 4096;
3072 	iov_read[2].iov_base = payload_read + 7 * 4096;
3073 	iov_read[2].iov_len = 3 * 4096;
3074 	spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL);
3075 	CU_ASSERT(g_bserrno == 0);
3076 	CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0);
3077 
3078 	spdk_blob_close(blob, blob_op_complete, NULL);
3079 	CU_ASSERT(g_bserrno == 0);
3080 
3081 	spdk_bs_free_io_channel(channel);
3082 
3083 	/* Unload the blob store */
3084 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3085 	CU_ASSERT(g_bserrno == 0);
3086 	g_bs = NULL;
3087 	g_blob = NULL;
3088 	g_blobid = 0;
3089 }
3090 
3091 struct iter_ctx {
3092 	int		current_iter;
3093 	spdk_blob_id	blobid[4];
3094 };
3095 
3096 static void
3097 test_iter(void *arg, struct spdk_blob *blob, int bserrno)
3098 {
3099 	struct iter_ctx *iter_ctx = arg;
3100 	spdk_blob_id blobid;
3101 
3102 	CU_ASSERT(bserrno == 0);
3103 	blobid = spdk_blob_get_id(blob);
3104 	CU_ASSERT(blobid == iter_ctx->blobid[iter_ctx->current_iter++]);
3105 }
3106 
3107 static void
3108 bs_load_iter(void)
3109 {
3110 	struct spdk_bs_dev *dev;
3111 	struct iter_ctx iter_ctx = { 0 };
3112 	struct spdk_blob *blob;
3113 	int i, rc;
3114 	struct spdk_bs_opts opts;
3115 
3116 	dev = init_dev();
3117 	spdk_bs_opts_init(&opts);
3118 	strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH);
3119 
3120 	/* Initialize a new blob store */
3121 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
3122 	CU_ASSERT(g_bserrno == 0);
3123 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3124 
3125 	for (i = 0; i < 4; i++) {
3126 		g_bserrno = -1;
3127 		g_blobid = SPDK_BLOBID_INVALID;
3128 		spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
3129 		CU_ASSERT(g_bserrno == 0);
3130 		CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3131 		iter_ctx.blobid[i] = g_blobid;
3132 
3133 		g_bserrno = -1;
3134 		g_blob = NULL;
3135 		spdk_bs_open_blob(g_bs, g_blobid, blob_op_with_handle_complete, NULL);
3136 		CU_ASSERT(g_bserrno == 0);
3137 		CU_ASSERT(g_blob != NULL);
3138 		blob = g_blob;
3139 
3140 		/* Just save the blobid as an xattr for testing purposes. */
3141 		rc = spdk_blob_set_xattr(blob, "blobid", &g_blobid, sizeof(g_blobid));
3142 		CU_ASSERT(rc == 0);
3143 
3144 		/* Resize the blob */
3145 		rc = spdk_blob_resize(blob, i);
3146 		CU_ASSERT(rc == 0);
3147 
3148 		spdk_blob_close(blob, blob_op_complete, NULL);
3149 		CU_ASSERT(g_bserrno == 0);
3150 	}
3151 
3152 	g_bserrno = -1;
3153 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3154 	CU_ASSERT(g_bserrno == 0);
3155 
3156 	dev = init_dev();
3157 	spdk_bs_opts_init(&opts);
3158 	strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH);
3159 	opts.iter_cb_fn = test_iter;
3160 	opts.iter_cb_arg = &iter_ctx;
3161 
3162 	/* Test blob iteration during load after a clean shutdown. */
3163 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
3164 	CU_ASSERT(g_bserrno == 0);
3165 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3166 
3167 	/* Dirty shutdown */
3168 	_spdk_bs_free(g_bs);
3169 
3170 	dev = init_dev();
3171 	spdk_bs_opts_init(&opts);
3172 	strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH);
3173 	opts.iter_cb_fn = test_iter;
3174 	iter_ctx.current_iter = 0;
3175 	opts.iter_cb_arg = &iter_ctx;
3176 
3177 	/* Test blob iteration during load after a dirty shutdown. */
3178 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
3179 	CU_ASSERT(g_bserrno == 0);
3180 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3181 
3182 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3183 	CU_ASSERT(g_bserrno == 0);
3184 	g_bs = NULL;
3185 
3186 }
3187 
3188 int main(int argc, char **argv)
3189 {
3190 	CU_pSuite	suite = NULL;
3191 	unsigned int	num_failures;
3192 
3193 	if (CU_initialize_registry() != CUE_SUCCESS) {
3194 		return CU_get_error();
3195 	}
3196 
3197 	suite = CU_add_suite("blob", NULL, NULL);
3198 	if (suite == NULL) {
3199 		CU_cleanup_registry();
3200 		return CU_get_error();
3201 	}
3202 
3203 	if (
3204 		CU_add_test(suite, "blob_init", blob_init) == NULL ||
3205 		CU_add_test(suite, "blob_open", blob_open) == NULL ||
3206 		CU_add_test(suite, "blob_create", blob_create) == NULL ||
3207 		CU_add_test(suite, "blob_thin_provision", blob_thin_provision) == NULL ||
3208 		CU_add_test(suite, "blob_delete", blob_delete) == NULL ||
3209 		CU_add_test(suite, "blob_resize", blob_resize) == NULL ||
3210 		CU_add_test(suite, "blob_read_only", blob_read_only) == NULL ||
3211 		CU_add_test(suite, "channel_ops", channel_ops) == NULL ||
3212 		CU_add_test(suite, "blob_super", blob_super) == NULL ||
3213 		CU_add_test(suite, "blob_write", blob_write) == NULL ||
3214 		CU_add_test(suite, "blob_read", blob_read) == NULL ||
3215 		CU_add_test(suite, "blob_rw_verify", blob_rw_verify) == NULL ||
3216 		CU_add_test(suite, "blob_rw_verify_iov", blob_rw_verify_iov) == NULL ||
3217 		CU_add_test(suite, "blob_rw_verify_iov_nomem", blob_rw_verify_iov_nomem) == NULL ||
3218 		CU_add_test(suite, "blob_rw_iov_read_only", blob_rw_iov_read_only) == NULL ||
3219 		CU_add_test(suite, "blob_unmap", blob_unmap) == NULL ||
3220 		CU_add_test(suite, "blob_iter", blob_iter) == NULL ||
3221 		CU_add_test(suite, "blob_xattr", blob_xattr) == NULL ||
3222 		CU_add_test(suite, "bs_load", bs_load) == NULL ||
3223 		CU_add_test(suite, "bs_unload", bs_unload) == NULL ||
3224 		CU_add_test(suite, "bs_cluster_sz", bs_cluster_sz) == NULL ||
3225 		CU_add_test(suite, "bs_usable_clusters", bs_usable_clusters) == NULL ||
3226 		CU_add_test(suite, "bs_resize_md", bs_resize_md) == NULL ||
3227 		CU_add_test(suite, "bs_destroy", bs_destroy) == NULL ||
3228 		CU_add_test(suite, "bs_type", bs_type) == NULL ||
3229 		CU_add_test(suite, "bs_super_block", bs_super_block) == NULL ||
3230 		CU_add_test(suite, "blob_serialize", blob_serialize) == NULL ||
3231 		CU_add_test(suite, "blob_crc", blob_crc) == NULL ||
3232 		CU_add_test(suite, "super_block_crc", super_block_crc) == NULL ||
3233 		CU_add_test(suite, "blob_dirty_shutdown", blob_dirty_shutdown) == NULL ||
3234 		CU_add_test(suite, "blob_flags", blob_flags) == NULL ||
3235 		CU_add_test(suite, "bs_version", bs_version) == NULL ||
3236 		CU_add_test(suite, "blob_set_xattrs", blob_set_xattrs) == NULL ||
3237 		CU_add_test(suite, "blob_thin_prov_alloc", blob_thin_prov_alloc) == NULL ||
3238 		CU_add_test(suite, "blob_insert_cluster_msg", blob_insert_cluster_msg) == NULL ||
3239 		CU_add_test(suite, "blob_thin_prov_rw", blob_thin_prov_rw) == NULL ||
3240 		CU_add_test(suite, "blob_thin_prov_rw_iov", blob_thin_prov_rw_iov) == NULL ||
3241 		CU_add_test(suite, "bs_load_iter", bs_load_iter) == NULL
3242 	) {
3243 		CU_cleanup_registry();
3244 		return CU_get_error();
3245 	}
3246 
3247 	g_dev_buffer = calloc(1, DEV_BUFFER_SIZE);
3248 	spdk_allocate_thread(_bs_send_msg, NULL, NULL, NULL, "thread0");
3249 	CU_basic_set_mode(CU_BRM_VERBOSE);
3250 	CU_basic_run_tests();
3251 	num_failures = CU_get_number_of_failures();
3252 	CU_cleanup_registry();
3253 	spdk_free_thread();
3254 	free(g_dev_buffer);
3255 	return num_failures;
3256 }
3257