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