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