xref: /spdk/test/unit/lib/blob/blob.c/blob_ut.c (revision ea1c15791fc760e07c8e9cd4629fe17dc0ddb1a1)
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 
51 bool g_scheduler_delay = false;
52 
53 struct scheduled_ops {
54 	spdk_thread_fn	fn;
55 	void		*ctx;
56 
57 	TAILQ_ENTRY(scheduled_ops)	ops_queue;
58 };
59 
60 static TAILQ_HEAD(, scheduled_ops) g_scheduled_ops = TAILQ_HEAD_INITIALIZER(g_scheduled_ops);
61 
62 struct spdk_bs_super_block_ver1 {
63 	uint8_t		signature[8];
64 	uint32_t        version;
65 	uint32_t        length;
66 	uint32_t	clean; /* If there was a clean shutdown, this is 1. */
67 	spdk_blob_id	super_blob;
68 
69 	uint32_t	cluster_size; /* In bytes */
70 
71 	uint32_t	used_page_mask_start; /* Offset from beginning of disk, in pages */
72 	uint32_t	used_page_mask_len; /* Count, in pages */
73 
74 	uint32_t	used_cluster_mask_start; /* Offset from beginning of disk, in pages */
75 	uint32_t	used_cluster_mask_len; /* Count, in pages */
76 
77 	uint32_t	md_start; /* Offset from beginning of disk, in pages */
78 	uint32_t	md_len; /* Count, in pages */
79 
80 	uint8_t		reserved[4036];
81 	uint32_t	crc;
82 } __attribute__((packed));
83 SPDK_STATIC_ASSERT(sizeof(struct spdk_bs_super_block_ver1) == 0x1000, "Invalid super block size");
84 
85 static void
86 _bs_send_msg(spdk_thread_fn fn, void *ctx, void *thread_ctx)
87 {
88 	if (g_scheduler_delay) {
89 		struct scheduled_ops *ops = calloc(1, sizeof(*ops));
90 
91 		SPDK_CU_ASSERT_FATAL(ops != NULL);
92 		ops->fn = fn;
93 		ops->ctx = ctx;
94 		TAILQ_INSERT_TAIL(&g_scheduled_ops, ops, ops_queue);
95 	} else {
96 		fn(ctx);
97 	}
98 }
99 
100 static void
101 _bs_flush_scheduler(void)
102 {
103 	struct scheduled_ops *ops, *tmp;
104 
105 	TAILQ_FOREACH_SAFE(ops, &g_scheduled_ops, ops_queue, tmp) {
106 		ops->fn(ops->ctx);
107 		TAILQ_REMOVE(&g_scheduled_ops, ops, ops_queue);
108 		free(ops);
109 	}
110 }
111 
112 static void
113 bs_op_complete(void *cb_arg, int bserrno)
114 {
115 	g_bserrno = bserrno;
116 }
117 
118 static void
119 bs_op_with_handle_complete(void *cb_arg, struct spdk_blob_store *bs,
120 			   int bserrno)
121 {
122 	g_bs = bs;
123 	g_bserrno = bserrno;
124 }
125 
126 static void
127 blob_op_complete(void *cb_arg, int bserrno)
128 {
129 	g_bserrno = bserrno;
130 }
131 
132 static void
133 blob_op_with_id_complete(void *cb_arg, spdk_blob_id blobid, int bserrno)
134 {
135 	g_blobid = blobid;
136 	g_bserrno = bserrno;
137 }
138 
139 static void
140 blob_op_with_handle_complete(void *cb_arg, struct spdk_blob *blb, int bserrno)
141 {
142 	g_blob = blb;
143 	g_bserrno = bserrno;
144 }
145 
146 static void
147 blob_init(void)
148 {
149 	struct spdk_bs_dev *dev;
150 
151 	dev = init_dev();
152 
153 	/* should fail for an unsupported blocklen */
154 	dev->blocklen = 500;
155 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
156 	CU_ASSERT(g_bserrno == -EINVAL);
157 
158 	dev = init_dev();
159 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
160 	CU_ASSERT(g_bserrno == 0);
161 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
162 
163 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
164 	CU_ASSERT(g_bserrno == 0);
165 	g_bs = NULL;
166 }
167 
168 static void
169 blob_super(void)
170 {
171 	struct spdk_blob_store *bs;
172 	struct spdk_bs_dev *dev;
173 	spdk_blob_id blobid;
174 
175 	dev = init_dev();
176 
177 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
178 	CU_ASSERT(g_bserrno == 0);
179 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
180 	bs = g_bs;
181 
182 	/* Get the super blob without having set one */
183 	spdk_bs_get_super(bs, blob_op_with_id_complete, NULL);
184 	CU_ASSERT(g_bserrno == -ENOENT);
185 	CU_ASSERT(g_blobid == SPDK_BLOBID_INVALID);
186 
187 	/* Create a blob */
188 	spdk_bs_md_create_blob(bs,
189 			       blob_op_with_id_complete, NULL);
190 	CU_ASSERT(g_bserrno == 0);
191 	CU_ASSERT(g_blobid !=  SPDK_BLOBID_INVALID);
192 	blobid = g_blobid;
193 
194 	/* Set the blob as the super blob */
195 	spdk_bs_set_super(bs, blobid, blob_op_complete, NULL);
196 	CU_ASSERT(g_bserrno == 0);
197 
198 	/* Get the super blob */
199 	spdk_bs_get_super(bs, blob_op_with_id_complete, NULL);
200 	CU_ASSERT(g_bserrno == 0);
201 	CU_ASSERT(blobid == g_blobid);
202 
203 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
204 	CU_ASSERT(g_bserrno == 0);
205 	g_bs = NULL;
206 }
207 
208 static void
209 blob_open(void)
210 {
211 	struct spdk_blob_store *bs;
212 	struct spdk_bs_dev *dev;
213 	struct spdk_blob *blob;
214 	spdk_blob_id blobid, blobid2;
215 
216 	dev = init_dev();
217 
218 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
219 	CU_ASSERT(g_bserrno == 0);
220 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
221 	bs = g_bs;
222 
223 	spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL);
224 	CU_ASSERT(g_bserrno == 0);
225 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
226 	blobid = g_blobid;
227 
228 	spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
229 	CU_ASSERT(g_bserrno == 0);
230 	CU_ASSERT(g_blob != NULL);
231 	blob = g_blob;
232 
233 	blobid2 = spdk_blob_get_id(blob);
234 	CU_ASSERT(blobid == blobid2);
235 
236 	/* Try to open file again.  It should return success. */
237 	spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
238 	CU_ASSERT(g_bserrno == 0);
239 	CU_ASSERT(blob == g_blob);
240 
241 	spdk_bs_md_close_blob(&blob, blob_op_complete, NULL);
242 	CU_ASSERT(g_bserrno == 0);
243 	CU_ASSERT(blob == NULL);
244 
245 	/*
246 	 * Close the file a second time, releasing the second reference.  This
247 	 *  should succeed.
248 	 */
249 	blob = g_blob;
250 	spdk_bs_md_close_blob(&blob, blob_op_complete, NULL);
251 	CU_ASSERT(g_bserrno == 0);
252 
253 	/*
254 	 * Try to open file again.  It should succeed.  This tests the case
255 	 *  where the file is opened, closed, then re-opened again.
256 	 */
257 	spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
258 	CU_ASSERT(g_bserrno == 0);
259 	CU_ASSERT(g_blob != NULL);
260 	blob = g_blob;
261 
262 	spdk_bs_md_close_blob(&blob, blob_op_complete, NULL);
263 	CU_ASSERT(g_bserrno == 0);
264 
265 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
266 	CU_ASSERT(g_bserrno == 0);
267 	g_bs = NULL;
268 }
269 
270 static void
271 blob_delete(void)
272 {
273 	struct spdk_blob_store *bs;
274 	struct spdk_bs_dev *dev;
275 	spdk_blob_id blobid;
276 
277 	dev = init_dev();
278 
279 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
280 	CU_ASSERT(g_bserrno == 0);
281 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
282 	bs = g_bs;
283 
284 	/* Create a blob and then delete it. */
285 	spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL);
286 	CU_ASSERT(g_bserrno == 0);
287 	CU_ASSERT(g_blobid > 0);
288 	blobid = g_blobid;
289 
290 	spdk_bs_md_delete_blob(bs, blobid, blob_op_complete, NULL);
291 	CU_ASSERT(g_bserrno == 0);
292 
293 	/* Try to open the blob */
294 	spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
295 	CU_ASSERT(g_bserrno == -ENOENT);
296 
297 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
298 	CU_ASSERT(g_bserrno == 0);
299 	g_bs = NULL;
300 }
301 
302 static void
303 blob_resize(void)
304 {
305 	struct spdk_blob_store *bs;
306 	struct spdk_bs_dev *dev;
307 	struct spdk_blob *blob;
308 	spdk_blob_id blobid;
309 	uint64_t free_clusters;
310 	int rc;
311 
312 	dev = init_dev();
313 
314 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
315 	CU_ASSERT(g_bserrno == 0);
316 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
317 	bs = g_bs;
318 	free_clusters = spdk_bs_free_cluster_count(bs);
319 
320 	spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL);
321 	CU_ASSERT(g_bserrno == 0);
322 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
323 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
324 	blobid = g_blobid;
325 
326 	spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
327 	CU_ASSERT(g_bserrno == 0);
328 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
329 	blob = g_blob;
330 
331 	/* Confirm that resize fails if blob is marked read-only. */
332 	blob->md_ro = true;
333 	rc = spdk_bs_md_resize_blob(blob, 5);
334 	CU_ASSERT(rc == -EPERM);
335 	blob->md_ro = false;
336 
337 	/* The blob started at 0 clusters. Resize it to be 5. */
338 	rc = spdk_bs_md_resize_blob(blob, 5);
339 	CU_ASSERT(rc == 0);
340 	CU_ASSERT((free_clusters - 5) == spdk_bs_free_cluster_count(bs));
341 
342 	/* Shrink the blob to 3 clusters. This will not actually release
343 	 * the old clusters until the blob is synced.
344 	 */
345 	rc = spdk_bs_md_resize_blob(blob, 3);
346 	CU_ASSERT(rc == 0);
347 	/* Verify there are still 5 clusters in use */
348 	CU_ASSERT((free_clusters - 5) == spdk_bs_free_cluster_count(bs));
349 
350 	spdk_bs_md_sync_blob(blob, blob_op_complete, NULL);
351 	CU_ASSERT(g_bserrno == 0);
352 	/* Now there are only 3 clusters in use */
353 	CU_ASSERT((free_clusters - 3) == spdk_bs_free_cluster_count(bs));
354 
355 	/* Resize the blob to be 10 clusters. Growth takes effect immediately. */
356 	rc = spdk_bs_md_resize_blob(blob, 10);
357 	CU_ASSERT(rc == 0);
358 	CU_ASSERT((free_clusters - 10) == spdk_bs_free_cluster_count(bs));
359 
360 	spdk_bs_md_close_blob(&blob, blob_op_complete, NULL);
361 	CU_ASSERT(g_bserrno == 0);
362 
363 	spdk_bs_md_delete_blob(bs, blobid, blob_op_complete, NULL);
364 	CU_ASSERT(g_bserrno == 0);
365 
366 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
367 	CU_ASSERT(g_bserrno == 0);
368 	g_bs = NULL;
369 }
370 
371 static void
372 channel_ops(void)
373 {
374 	struct spdk_blob_store *bs;
375 	struct spdk_bs_dev *dev;
376 	struct spdk_io_channel *channel;
377 
378 	dev = init_dev();
379 
380 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
381 	CU_ASSERT(g_bserrno == 0);
382 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
383 	bs = g_bs;
384 
385 	channel = spdk_bs_alloc_io_channel(bs);
386 	CU_ASSERT(channel != NULL);
387 
388 	spdk_bs_free_io_channel(channel);
389 
390 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
391 	CU_ASSERT(g_bserrno == 0);
392 	g_bs = NULL;
393 }
394 
395 static void
396 blob_write(void)
397 {
398 	struct spdk_blob_store *bs;
399 	struct spdk_bs_dev *dev;
400 	struct spdk_blob *blob;
401 	struct spdk_io_channel *channel;
402 	spdk_blob_id blobid;
403 	uint64_t pages_per_cluster;
404 	uint8_t payload[10 * 4096];
405 	int rc;
406 
407 	dev = init_dev();
408 
409 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
410 	CU_ASSERT(g_bserrno == 0);
411 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
412 	bs = g_bs;
413 
414 	pages_per_cluster = spdk_bs_get_cluster_size(bs) / spdk_bs_get_page_size(bs);
415 
416 	channel = spdk_bs_alloc_io_channel(bs);
417 	CU_ASSERT(channel != NULL);
418 
419 	spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL);
420 	CU_ASSERT(g_bserrno == 0);
421 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
422 	blobid = g_blobid;
423 
424 	spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
425 	CU_ASSERT(g_bserrno == 0);
426 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
427 	blob = g_blob;
428 
429 	/* Write to a blob with 0 size */
430 	spdk_bs_io_write_blob(blob, channel, payload, 0, 1, blob_op_complete, NULL);
431 	CU_ASSERT(g_bserrno == -EINVAL);
432 
433 	/* Resize the blob */
434 	rc = spdk_bs_md_resize_blob(blob, 5);
435 	CU_ASSERT(rc == 0);
436 
437 	/* Confirm that write fails if blob is marked read-only. */
438 	blob->data_ro = true;
439 	spdk_bs_io_write_blob(blob, channel, payload, 0, 1, blob_op_complete, NULL);
440 	CU_ASSERT(g_bserrno == -EPERM);
441 	blob->data_ro = false;
442 
443 	/* Write to the blob */
444 	spdk_bs_io_write_blob(blob, channel, payload, 0, 1, blob_op_complete, NULL);
445 	CU_ASSERT(g_bserrno == 0);
446 
447 	/* Write starting beyond the end */
448 	spdk_bs_io_write_blob(blob, channel, payload, 5 * pages_per_cluster, 1, blob_op_complete,
449 			      NULL);
450 	CU_ASSERT(g_bserrno == -EINVAL);
451 
452 	/* Write starting at a valid location but going off the end */
453 	spdk_bs_io_write_blob(blob, channel, payload, 4 * pages_per_cluster, pages_per_cluster + 1,
454 			      blob_op_complete, NULL);
455 	CU_ASSERT(g_bserrno == -EINVAL);
456 
457 	spdk_bs_md_close_blob(&blob, blob_op_complete, NULL);
458 	CU_ASSERT(g_bserrno == 0);
459 
460 	spdk_bs_free_io_channel(channel);
461 
462 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
463 	CU_ASSERT(g_bserrno == 0);
464 	g_bs = NULL;
465 }
466 
467 static void
468 blob_read(void)
469 {
470 	struct spdk_blob_store *bs;
471 	struct spdk_bs_dev *dev;
472 	struct spdk_blob *blob;
473 	struct spdk_io_channel *channel;
474 	spdk_blob_id blobid;
475 	uint64_t pages_per_cluster;
476 	uint8_t payload[10 * 4096];
477 	int rc;
478 
479 	dev = init_dev();
480 
481 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
482 	CU_ASSERT(g_bserrno == 0);
483 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
484 	bs = g_bs;
485 
486 	pages_per_cluster = spdk_bs_get_cluster_size(bs) / spdk_bs_get_page_size(bs);
487 
488 	channel = spdk_bs_alloc_io_channel(bs);
489 	CU_ASSERT(channel != NULL);
490 
491 	spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL);
492 	CU_ASSERT(g_bserrno == 0);
493 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
494 	blobid = g_blobid;
495 
496 	spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
497 	CU_ASSERT(g_bserrno == 0);
498 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
499 	blob = g_blob;
500 
501 	/* Read from a blob with 0 size */
502 	spdk_bs_io_read_blob(blob, channel, payload, 0, 1, blob_op_complete, NULL);
503 	CU_ASSERT(g_bserrno == -EINVAL);
504 
505 	/* Resize the blob */
506 	rc = spdk_bs_md_resize_blob(blob, 5);
507 	CU_ASSERT(rc == 0);
508 
509 	/* Confirm that read passes if blob is marked read-only. */
510 	blob->data_ro = true;
511 	spdk_bs_io_read_blob(blob, channel, payload, 0, 1, blob_op_complete, NULL);
512 	CU_ASSERT(g_bserrno == 0);
513 	blob->data_ro = false;
514 
515 	/* Read from the blob */
516 	spdk_bs_io_read_blob(blob, channel, payload, 0, 1, blob_op_complete, NULL);
517 	CU_ASSERT(g_bserrno == 0);
518 
519 	/* Read starting beyond the end */
520 	spdk_bs_io_read_blob(blob, channel, payload, 5 * pages_per_cluster, 1, blob_op_complete,
521 			     NULL);
522 	CU_ASSERT(g_bserrno == -EINVAL);
523 
524 	/* Read starting at a valid location but going off the end */
525 	spdk_bs_io_read_blob(blob, channel, payload, 4 * pages_per_cluster, pages_per_cluster + 1,
526 			     blob_op_complete, NULL);
527 	CU_ASSERT(g_bserrno == -EINVAL);
528 
529 	spdk_bs_md_close_blob(&blob, blob_op_complete, NULL);
530 	CU_ASSERT(g_bserrno == 0);
531 
532 	spdk_bs_free_io_channel(channel);
533 
534 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
535 	CU_ASSERT(g_bserrno == 0);
536 	g_bs = NULL;
537 }
538 
539 static void
540 blob_rw_verify(void)
541 {
542 	struct spdk_blob_store *bs;
543 	struct spdk_bs_dev *dev;
544 	struct spdk_blob *blob;
545 	struct spdk_io_channel *channel;
546 	spdk_blob_id blobid;
547 	uint8_t payload_read[10 * 4096];
548 	uint8_t payload_write[10 * 4096];
549 	int rc;
550 
551 	dev = init_dev();
552 
553 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
554 	CU_ASSERT(g_bserrno == 0);
555 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
556 	bs = g_bs;
557 
558 	channel = spdk_bs_alloc_io_channel(bs);
559 	CU_ASSERT(channel != NULL);
560 
561 	spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL);
562 	CU_ASSERT(g_bserrno == 0);
563 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
564 	blobid = g_blobid;
565 
566 	spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
567 	CU_ASSERT(g_bserrno == 0);
568 	CU_ASSERT(g_blob != NULL);
569 	blob = g_blob;
570 
571 	rc = spdk_bs_md_resize_blob(blob, 32);
572 	CU_ASSERT(rc == 0);
573 
574 	memset(payload_write, 0xE5, sizeof(payload_write));
575 	spdk_bs_io_write_blob(blob, channel, payload_write, 4, 10, blob_op_complete, NULL);
576 	CU_ASSERT(g_bserrno == 0);
577 
578 	memset(payload_read, 0x00, sizeof(payload_read));
579 	spdk_bs_io_read_blob(blob, channel, payload_read, 4, 10, blob_op_complete, NULL);
580 	CU_ASSERT(g_bserrno == 0);
581 	CU_ASSERT(memcmp(payload_write, payload_read, 4 * 4096) == 0);
582 
583 	spdk_bs_md_close_blob(&blob, blob_op_complete, NULL);
584 	CU_ASSERT(g_bserrno == 0);
585 
586 	spdk_bs_free_io_channel(channel);
587 
588 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
589 	CU_ASSERT(g_bserrno == 0);
590 	g_bs = NULL;
591 }
592 
593 static void
594 blob_rw_verify_iov(void)
595 {
596 	struct spdk_blob_store *bs;
597 	struct spdk_bs_dev *dev;
598 	struct spdk_blob *blob;
599 	struct spdk_io_channel *channel;
600 	spdk_blob_id blobid;
601 	uint8_t payload_read[10 * 4096];
602 	uint8_t payload_write[10 * 4096];
603 	struct iovec iov_read[3];
604 	struct iovec iov_write[3];
605 	void *buf;
606 	int rc;
607 
608 	dev = init_dev();
609 	memset(g_dev_buffer, 0, DEV_BUFFER_SIZE);
610 
611 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
612 	CU_ASSERT(g_bserrno == 0);
613 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
614 	bs = g_bs;
615 
616 	channel = spdk_bs_alloc_io_channel(bs);
617 	CU_ASSERT(channel != NULL);
618 
619 	spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL);
620 	CU_ASSERT(g_bserrno == 0);
621 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
622 	blobid = g_blobid;
623 
624 	spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
625 	CU_ASSERT(g_bserrno == 0);
626 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
627 	blob = g_blob;
628 
629 	rc = spdk_bs_md_resize_blob(blob, 2);
630 	CU_ASSERT(rc == 0);
631 
632 	/*
633 	 * Manually adjust the offset of the blob's second cluster.  This allows
634 	 *  us to make sure that the readv/write code correctly accounts for I/O
635 	 *  that cross cluster boundaries.  Start by asserting that the allocated
636 	 *  clusters are where we expect before modifying the second cluster.
637 	 */
638 	CU_ASSERT(blob->active.clusters[0] == 1 * 256);
639 	CU_ASSERT(blob->active.clusters[1] == 2 * 256);
640 	blob->active.clusters[1] = 3 * 256;
641 
642 	memset(payload_write, 0xE5, sizeof(payload_write));
643 	iov_write[0].iov_base = payload_write;
644 	iov_write[0].iov_len = 1 * 4096;
645 	iov_write[1].iov_base = payload_write + 1 * 4096;
646 	iov_write[1].iov_len = 5 * 4096;
647 	iov_write[2].iov_base = payload_write + 6 * 4096;
648 	iov_write[2].iov_len = 4 * 4096;
649 	/*
650 	 * Choose a page offset just before the cluster boundary.  The first 6 pages of payload
651 	 *  will get written to the first cluster, the last 4 to the second cluster.
652 	 */
653 	spdk_bs_io_writev_blob(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL);
654 	CU_ASSERT(g_bserrno == 0);
655 
656 	memset(payload_read, 0xAA, sizeof(payload_read));
657 	iov_read[0].iov_base = payload_read;
658 	iov_read[0].iov_len = 3 * 4096;
659 	iov_read[1].iov_base = payload_read + 3 * 4096;
660 	iov_read[1].iov_len = 4 * 4096;
661 	iov_read[2].iov_base = payload_read + 7 * 4096;
662 	iov_read[2].iov_len = 3 * 4096;
663 	spdk_bs_io_readv_blob(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL);
664 	CU_ASSERT(g_bserrno == 0);
665 	CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0);
666 
667 	buf = calloc(1, 256 * 4096);
668 	SPDK_CU_ASSERT_FATAL(buf != NULL);
669 	/* Check that cluster 2 on "disk" was not modified. */
670 	CU_ASSERT(memcmp(buf, &g_dev_buffer[512 * 4096], 256 * 4096) == 0);
671 	free(buf);
672 
673 	spdk_bs_md_close_blob(&blob, blob_op_complete, NULL);
674 	CU_ASSERT(g_bserrno == 0);
675 
676 	spdk_bs_free_io_channel(channel);
677 
678 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
679 	CU_ASSERT(g_bserrno == 0);
680 	g_bs = NULL;
681 }
682 
683 static uint32_t
684 bs_channel_get_req_count(struct spdk_io_channel *_channel)
685 {
686 	struct spdk_bs_channel *channel = spdk_io_channel_get_ctx(_channel);
687 	struct spdk_bs_request_set *set;
688 	uint32_t count = 0;
689 
690 	TAILQ_FOREACH(set, &channel->reqs, link) {
691 		count++;
692 	}
693 
694 	return count;
695 }
696 
697 static void
698 blob_rw_verify_iov_nomem(void)
699 {
700 	struct spdk_blob_store *bs;
701 	struct spdk_bs_dev *dev;
702 	struct spdk_blob *blob;
703 	struct spdk_io_channel *channel;
704 	spdk_blob_id blobid;
705 	uint8_t payload_write[10 * 4096];
706 	struct iovec iov_write[3];
707 	uint32_t req_count;
708 	int rc;
709 
710 	dev = init_dev();
711 	memset(g_dev_buffer, 0, DEV_BUFFER_SIZE);
712 
713 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
714 	CU_ASSERT(g_bserrno == 0);
715 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
716 	bs = g_bs;
717 
718 	channel = spdk_bs_alloc_io_channel(bs);
719 	CU_ASSERT(channel != NULL);
720 
721 	spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL);
722 	CU_ASSERT(g_bserrno == 0);
723 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
724 	blobid = g_blobid;
725 
726 	spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
727 	CU_ASSERT(g_bserrno == 0);
728 	CU_ASSERT(g_blob != NULL);
729 	blob = g_blob;
730 
731 	rc = spdk_bs_md_resize_blob(blob, 2);
732 	CU_ASSERT(rc == 0);
733 
734 	/*
735 	 * Choose a page offset just before the cluster boundary.  The first 6 pages of payload
736 	 *  will get written to the first cluster, the last 4 to the second cluster.
737 	 */
738 	iov_write[0].iov_base = payload_write;
739 	iov_write[0].iov_len = 1 * 4096;
740 	iov_write[1].iov_base = payload_write + 1 * 4096;
741 	iov_write[1].iov_len = 5 * 4096;
742 	iov_write[2].iov_base = payload_write + 6 * 4096;
743 	iov_write[2].iov_len = 4 * 4096;
744 	MOCK_SET(calloc, void *, NULL);
745 	req_count = bs_channel_get_req_count(channel);
746 	spdk_bs_io_writev_blob(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL);
747 	CU_ASSERT(g_bserrno = -ENOMEM);
748 	CU_ASSERT(req_count == bs_channel_get_req_count(channel));
749 	MOCK_SET(calloc, void *, (void *)MOCK_PASS_THRU);
750 
751 	spdk_bs_md_close_blob(&blob, blob_op_complete, NULL);
752 	CU_ASSERT(g_bserrno == 0);
753 
754 	spdk_bs_free_io_channel(channel);
755 
756 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
757 	CU_ASSERT(g_bserrno == 0);
758 	g_bs = NULL;
759 }
760 
761 static void
762 blob_rw_iov_read_only(void)
763 {
764 	struct spdk_blob_store *bs;
765 	struct spdk_bs_dev *dev;
766 	struct spdk_blob *blob;
767 	struct spdk_io_channel *channel;
768 	spdk_blob_id blobid;
769 	uint8_t payload_read[4096];
770 	uint8_t payload_write[4096];
771 	struct iovec iov_read;
772 	struct iovec iov_write;
773 	int rc;
774 
775 	dev = init_dev();
776 	memset(g_dev_buffer, 0, DEV_BUFFER_SIZE);
777 
778 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
779 	CU_ASSERT(g_bserrno == 0);
780 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
781 	bs = g_bs;
782 
783 	channel = spdk_bs_alloc_io_channel(bs);
784 	CU_ASSERT(channel != NULL);
785 
786 	spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL);
787 	CU_ASSERT(g_bserrno == 0);
788 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
789 	blobid = g_blobid;
790 
791 	spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
792 	CU_ASSERT(g_bserrno == 0);
793 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
794 	blob = g_blob;
795 
796 	rc = spdk_bs_md_resize_blob(blob, 2);
797 	CU_ASSERT(rc == 0);
798 
799 	/* Verify that writev failed if read_only flag is set. */
800 	blob->data_ro = true;
801 	iov_write.iov_base = payload_write;
802 	iov_write.iov_len = sizeof(payload_write);
803 	spdk_bs_io_writev_blob(blob, channel, &iov_write, 1, 0, 1, blob_op_complete, NULL);
804 	CU_ASSERT(g_bserrno == -EPERM);
805 
806 	/* Verify that reads pass if data_ro flag is set. */
807 	iov_read.iov_base = payload_read;
808 	iov_read.iov_len = sizeof(payload_read);
809 	spdk_bs_io_readv_blob(blob, channel, &iov_read, 1, 0, 1, blob_op_complete, NULL);
810 	CU_ASSERT(g_bserrno == 0);
811 
812 	spdk_bs_md_close_blob(&blob, blob_op_complete, NULL);
813 	CU_ASSERT(g_bserrno == 0);
814 
815 	spdk_bs_free_io_channel(channel);
816 
817 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
818 	CU_ASSERT(g_bserrno == 0);
819 	g_bs = NULL;
820 }
821 
822 static void
823 blob_iter(void)
824 {
825 	struct spdk_blob_store *bs;
826 	struct spdk_bs_dev *dev;
827 	struct spdk_blob *blob;
828 	spdk_blob_id blobid;
829 
830 	dev = init_dev();
831 
832 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
833 	CU_ASSERT(g_bserrno == 0);
834 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
835 	bs = g_bs;
836 
837 	spdk_bs_md_iter_first(bs, blob_op_with_handle_complete, NULL);
838 	CU_ASSERT(g_blob == NULL);
839 	CU_ASSERT(g_bserrno == -ENOENT);
840 
841 	spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL);
842 	CU_ASSERT(g_bserrno == 0);
843 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
844 	blobid = g_blobid;
845 
846 	spdk_bs_md_iter_first(bs, blob_op_with_handle_complete, NULL);
847 	CU_ASSERT(g_blob != NULL);
848 	CU_ASSERT(g_bserrno == 0);
849 	blob = g_blob;
850 	CU_ASSERT(spdk_blob_get_id(blob) == blobid);
851 
852 	spdk_bs_md_iter_next(bs, &blob, blob_op_with_handle_complete, NULL);
853 	CU_ASSERT(g_blob == NULL);
854 	CU_ASSERT(g_bserrno == -ENOENT);
855 
856 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
857 	CU_ASSERT(g_bserrno == 0);
858 	g_bs = NULL;
859 }
860 
861 static void
862 blob_xattr(void)
863 {
864 	struct spdk_blob_store *bs;
865 	struct spdk_bs_dev *dev;
866 	struct spdk_blob *blob;
867 	spdk_blob_id blobid;
868 	uint64_t length;
869 	int rc;
870 	const char *name1, *name2;
871 	const void *value;
872 	size_t value_len;
873 	struct spdk_xattr_names *names;
874 
875 	dev = init_dev();
876 
877 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
878 	CU_ASSERT(g_bserrno == 0);
879 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
880 	bs = g_bs;
881 
882 	spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL);
883 	CU_ASSERT(g_bserrno == 0);
884 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
885 	blobid = g_blobid;
886 
887 	spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
888 	CU_ASSERT(g_bserrno == 0);
889 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
890 	blob = g_blob;
891 
892 	/* Test that set_xattr fails if md_ro flag is set. */
893 	blob->md_ro = true;
894 	rc = spdk_blob_md_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1);
895 	CU_ASSERT(rc == -EPERM);
896 
897 	blob->md_ro = false;
898 	rc = spdk_blob_md_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1);
899 	CU_ASSERT(rc == 0);
900 
901 	length = 2345;
902 	rc = spdk_blob_md_set_xattr(blob, "length", &length, sizeof(length));
903 	CU_ASSERT(rc == 0);
904 
905 	/* Overwrite "length" xattr. */
906 	length = 3456;
907 	rc = spdk_blob_md_set_xattr(blob, "length", &length, sizeof(length));
908 	CU_ASSERT(rc == 0);
909 
910 	/* get_xattr should still work even if md_ro flag is set. */
911 	value = NULL;
912 	blob->md_ro = true;
913 	rc = spdk_bs_md_get_xattr_value(blob, "length", &value, &value_len);
914 	CU_ASSERT(rc == 0);
915 	SPDK_CU_ASSERT_FATAL(value != NULL);
916 	CU_ASSERT(*(uint64_t *)value == length);
917 	CU_ASSERT(value_len == 8);
918 	blob->md_ro = false;
919 
920 	rc = spdk_bs_md_get_xattr_value(blob, "foobar", &value, &value_len);
921 	CU_ASSERT(rc == -ENOENT);
922 
923 	names = NULL;
924 	rc = spdk_bs_md_get_xattr_names(blob, &names);
925 	CU_ASSERT(rc == 0);
926 	SPDK_CU_ASSERT_FATAL(names != NULL);
927 	CU_ASSERT(spdk_xattr_names_get_count(names) == 2);
928 	name1 = spdk_xattr_names_get_name(names, 0);
929 	SPDK_CU_ASSERT_FATAL(name1 != NULL);
930 	CU_ASSERT(!strcmp(name1, "name") || !strcmp(name1, "length"));
931 	name2 = spdk_xattr_names_get_name(names, 1);
932 	SPDK_CU_ASSERT_FATAL(name2 != NULL);
933 	CU_ASSERT(!strcmp(name2, "name") || !strcmp(name2, "length"));
934 	CU_ASSERT(strcmp(name1, name2));
935 	spdk_xattr_names_free(names);
936 
937 	/* Confirm that remove_xattr fails if md_ro is set to true. */
938 	blob->md_ro = true;
939 	rc = spdk_blob_md_remove_xattr(blob, "name");
940 	CU_ASSERT(rc == -EPERM);
941 
942 	blob->md_ro = false;
943 	rc = spdk_blob_md_remove_xattr(blob, "name");
944 	CU_ASSERT(rc == 0);
945 
946 	rc = spdk_blob_md_remove_xattr(blob, "foobar");
947 	CU_ASSERT(rc == -ENOENT);
948 
949 	spdk_bs_md_close_blob(&blob, blob_op_complete, NULL);
950 
951 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
952 	CU_ASSERT(g_bserrno == 0);
953 	g_bs = NULL;
954 }
955 
956 static void
957 bs_load(void)
958 {
959 	struct spdk_bs_dev *dev;
960 	spdk_blob_id blobid;
961 	struct spdk_blob *blob;
962 	struct spdk_bs_super_block *super_block;
963 	uint64_t length;
964 	int rc;
965 	const void *value;
966 	size_t value_len;
967 	struct spdk_bs_opts opts;
968 
969 	g_scheduler_delay = true;
970 
971 	dev = init_dev();
972 	spdk_bs_opts_init(&opts);
973 	strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH);
974 
975 	/* Initialize a new blob store */
976 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
977 	CU_ASSERT(g_bserrno == 0);
978 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
979 
980 	/* Try to open a blobid that does not exist */
981 	spdk_bs_md_open_blob(g_bs, 0, blob_op_with_handle_complete, NULL);
982 	CU_ASSERT(g_bserrno == -ENOENT);
983 	CU_ASSERT(g_blob == NULL);
984 
985 	/* Create a blob */
986 	spdk_bs_md_create_blob(g_bs, blob_op_with_id_complete, NULL);
987 	CU_ASSERT(g_bserrno == 0);
988 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
989 	blobid = g_blobid;
990 
991 	spdk_bs_md_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
992 	CU_ASSERT(g_bserrno == 0);
993 	CU_ASSERT(g_blob != NULL);
994 	blob = g_blob;
995 
996 	/* Try again to open valid blob but without the upper bit set */
997 	spdk_bs_md_open_blob(g_bs, blobid & 0xFFFFFFFF, blob_op_with_handle_complete, NULL);
998 	CU_ASSERT(g_bserrno == -ENOENT);
999 	CU_ASSERT(g_blob == NULL);
1000 
1001 	/* Set some xattrs */
1002 	rc = spdk_blob_md_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1);
1003 	CU_ASSERT(rc == 0);
1004 
1005 	length = 2345;
1006 	rc = spdk_blob_md_set_xattr(blob, "length", &length, sizeof(length));
1007 	CU_ASSERT(rc == 0);
1008 
1009 	/* Resize the blob */
1010 	rc = spdk_bs_md_resize_blob(blob, 10);
1011 	CU_ASSERT(rc == 0);
1012 
1013 	spdk_bs_md_close_blob(&blob, blob_op_complete, NULL);
1014 	CU_ASSERT(g_bserrno == 0);
1015 	blob = NULL;
1016 	g_blob = NULL;
1017 	g_blobid = SPDK_BLOBID_INVALID;
1018 
1019 	/* Unload the blob store */
1020 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1021 	CU_ASSERT(g_bserrno == 0);
1022 	g_bs = NULL;
1023 	g_blob = NULL;
1024 	g_blobid = 0;
1025 
1026 	super_block = (struct spdk_bs_super_block *)g_dev_buffer;
1027 	CU_ASSERT(super_block->clean == 1);
1028 
1029 
1030 	/* Load an existing blob store */
1031 	dev = init_dev();
1032 	strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH);
1033 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1034 	CU_ASSERT(g_bserrno == 0);
1035 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1036 
1037 	super_block = (struct spdk_bs_super_block *)g_dev_buffer;
1038 	CU_ASSERT(super_block->clean == 0);
1039 
1040 	spdk_bs_md_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
1041 	CU_ASSERT(g_bserrno == 0);
1042 	CU_ASSERT(g_blob != NULL);
1043 	blob = g_blob;
1044 
1045 	/* Get the xattrs */
1046 	value = NULL;
1047 	rc = spdk_bs_md_get_xattr_value(blob, "length", &value, &value_len);
1048 	CU_ASSERT(rc == 0);
1049 	SPDK_CU_ASSERT_FATAL(value != NULL);
1050 	CU_ASSERT(*(uint64_t *)value == length);
1051 	CU_ASSERT(value_len == 8);
1052 
1053 	rc = spdk_bs_md_get_xattr_value(blob, "foobar", &value, &value_len);
1054 	CU_ASSERT(rc == -ENOENT);
1055 
1056 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10);
1057 
1058 	spdk_bs_md_close_blob(&blob, blob_op_complete, NULL);
1059 	CU_ASSERT(g_bserrno == 0);
1060 	blob = NULL;
1061 	g_blob = NULL;
1062 	g_blobid = SPDK_BLOBID_INVALID;
1063 
1064 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1065 	CU_ASSERT(g_bserrno == 0);
1066 	g_bs = NULL;
1067 	g_scheduler_delay = false;
1068 }
1069 
1070 static void
1071 bs_type(void)
1072 {
1073 	struct spdk_bs_dev *dev;
1074 	struct spdk_bs_opts opts;
1075 
1076 	g_scheduler_delay = true;
1077 
1078 	dev = init_dev();
1079 	spdk_bs_opts_init(&opts);
1080 	strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH);
1081 
1082 	/* Initialize a new blob store */
1083 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
1084 	CU_ASSERT(g_bserrno == 0);
1085 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1086 
1087 	/* Unload the blob store */
1088 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1089 	CU_ASSERT(g_bserrno == 0);
1090 	g_bs = NULL;
1091 	g_blob = NULL;
1092 	g_blobid = 0;
1093 
1094 	/* Load non existing blobstore type */
1095 	dev = init_dev();
1096 	strncpy(opts.bstype.bstype, "NONEXISTING", SPDK_BLOBSTORE_TYPE_LENGTH);
1097 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1098 	CU_ASSERT(g_bserrno != 0);
1099 
1100 	/* Load with empty blobstore type */
1101 	dev = init_dev();
1102 	strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH);
1103 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1104 	CU_ASSERT(g_bserrno == 0);
1105 
1106 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1107 	CU_ASSERT(g_bserrno == 0);
1108 	g_bs = NULL;
1109 
1110 	/* Initialize a new blob store with empty bstype */
1111 	dev = init_dev();
1112 	strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH);
1113 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1114 	CU_ASSERT(g_bserrno == 0);
1115 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1116 
1117 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1118 	CU_ASSERT(g_bserrno == 0);
1119 	g_bs = NULL;
1120 
1121 	/* Load non existing blobstore type */
1122 	dev = init_dev();
1123 	strncpy(opts.bstype.bstype, "NONEXISTING", SPDK_BLOBSTORE_TYPE_LENGTH);
1124 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1125 	CU_ASSERT(g_bserrno != 0);
1126 
1127 	/* Load with empty blobstore type */
1128 	dev = init_dev();
1129 	strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH);
1130 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1131 	CU_ASSERT(g_bserrno == 0);
1132 
1133 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1134 	CU_ASSERT(g_bserrno == 0);
1135 	g_bs = NULL;
1136 	g_scheduler_delay = false;
1137 }
1138 
1139 static void
1140 bs_super_block(void)
1141 {
1142 	struct spdk_bs_dev *dev;
1143 	struct spdk_bs_super_block *super_block;
1144 	struct spdk_bs_opts opts;
1145 	struct spdk_bs_super_block_ver1 super_block_v1;
1146 
1147 	g_scheduler_delay = true;
1148 
1149 	dev = init_dev();
1150 	spdk_bs_opts_init(&opts);
1151 	strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH);
1152 
1153 	/* Initialize a new blob store */
1154 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
1155 	CU_ASSERT(g_bserrno == 0);
1156 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1157 
1158 	/* Unload the blob store */
1159 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1160 	CU_ASSERT(g_bserrno == 0);
1161 	g_bs = NULL;
1162 	g_blob = NULL;
1163 	g_blobid = 0;
1164 
1165 	/* Load an existing blob store with version newer than supported */
1166 	super_block = (struct spdk_bs_super_block *)g_dev_buffer;
1167 	super_block->version++;
1168 
1169 	dev = init_dev();
1170 	strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH);
1171 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1172 	CU_ASSERT(g_bserrno != 0);
1173 
1174 	/* Create a new blob store with super block version 1 */
1175 	dev = init_dev();
1176 	super_block_v1.version = 1;
1177 	strncpy(super_block_v1.signature, "SPDKBLOB", sizeof(super_block_v1.signature));
1178 	super_block_v1.length = 0x1000;
1179 	super_block_v1.clean = 1;
1180 	super_block_v1.super_blob = 0xFFFFFFFFFFFFFFFF;
1181 	super_block_v1.cluster_size = 0x100000;
1182 	super_block_v1.used_page_mask_start = 0x01;
1183 	super_block_v1.used_page_mask_len = 0x01;
1184 	super_block_v1.used_cluster_mask_start = 0x02;
1185 	super_block_v1.used_cluster_mask_len = 0x01;
1186 	super_block_v1.md_start = 0x03;
1187 	super_block_v1.md_len = 0x40;
1188 	memset(super_block_v1.reserved, 0, 4036);
1189 	super_block_v1.crc = _spdk_blob_md_page_calc_crc(&super_block_v1);
1190 	memcpy(g_dev_buffer, &super_block_v1, sizeof(struct spdk_bs_super_block_ver1));
1191 
1192 	strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH);
1193 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1194 	CU_ASSERT(g_bserrno == 0);
1195 
1196 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1197 	CU_ASSERT(g_bserrno == 0);
1198 	g_bs = NULL;
1199 	g_scheduler_delay = false;
1200 }
1201 
1202 /*
1203  * Create a blobstore and then unload it.
1204  */
1205 static void
1206 bs_unload(void)
1207 {
1208 	struct spdk_bs_dev *dev;
1209 	struct spdk_blob_store *bs;
1210 	spdk_blob_id blobid;
1211 	struct spdk_blob *blob;
1212 
1213 	dev = init_dev();
1214 
1215 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1216 	CU_ASSERT(g_bserrno == 0);
1217 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1218 	bs = g_bs;
1219 
1220 	/* Create a blob and open it. */
1221 	g_bserrno = -1;
1222 	spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL);
1223 	CU_ASSERT(g_bserrno == 0);
1224 	CU_ASSERT(g_blobid > 0);
1225 	blobid = g_blobid;
1226 
1227 	g_bserrno = -1;
1228 	spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1229 	CU_ASSERT(g_bserrno == 0);
1230 	CU_ASSERT(g_blob != NULL);
1231 	blob = g_blob;
1232 
1233 	/* Try to unload blobstore, should fail with open blob */
1234 	g_bserrno = -1;
1235 	spdk_bs_unload(bs, bs_op_complete, NULL);
1236 	CU_ASSERT(g_bserrno == -EBUSY);
1237 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1238 
1239 	/* Close the blob, then successfully unload blobstore */
1240 	g_bserrno = -1;
1241 	spdk_bs_md_close_blob(&blob, blob_op_complete, NULL);
1242 	CU_ASSERT(g_bserrno == 0);
1243 	CU_ASSERT(blob == NULL);
1244 
1245 	g_bserrno = -1;
1246 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1247 	CU_ASSERT(g_bserrno == 0);
1248 	g_bs = NULL;
1249 }
1250 
1251 /*
1252  * Create a blobstore with a cluster size different than the default, and ensure it is
1253  *  persisted.
1254  */
1255 static void
1256 bs_cluster_sz(void)
1257 {
1258 	struct spdk_bs_dev *dev;
1259 	struct spdk_bs_opts opts;
1260 	uint32_t cluster_sz;
1261 
1262 	/* Set cluster size to zero */
1263 	dev = init_dev();
1264 	spdk_bs_opts_init(&opts);
1265 	opts.cluster_sz = 0;
1266 
1267 	/* Initialize a new blob store */
1268 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
1269 	CU_ASSERT(g_bserrno == -EINVAL);
1270 	SPDK_CU_ASSERT_FATAL(g_bs == NULL);
1271 
1272 	/*
1273 	 * Set cluster size to blobstore page size,
1274 	 * to work it is required to be at least twice the blobstore page size.
1275 	 */
1276 	dev = init_dev();
1277 	spdk_bs_opts_init(&opts);
1278 	opts.cluster_sz = SPDK_BS_PAGE_SIZE;
1279 
1280 	/* Initialize a new blob store */
1281 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
1282 	CU_ASSERT(g_bserrno == -ENOMEM);
1283 	SPDK_CU_ASSERT_FATAL(g_bs == NULL);
1284 
1285 	/*
1286 	 * Set cluster size to lower than page size,
1287 	 * to work it is required to be at least twice the blobstore page size.
1288 	 */
1289 	dev = init_dev();
1290 	spdk_bs_opts_init(&opts);
1291 	opts.cluster_sz = SPDK_BS_PAGE_SIZE - 1;
1292 
1293 	/* Initialize a new blob store */
1294 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
1295 	CU_ASSERT(g_bserrno == -ENOMEM);
1296 	SPDK_CU_ASSERT_FATAL(g_bs == NULL);
1297 
1298 	/* Set cluster size to twice the default */
1299 	dev = init_dev();
1300 	spdk_bs_opts_init(&opts);
1301 	opts.cluster_sz *= 2;
1302 	cluster_sz = opts.cluster_sz;
1303 
1304 	/* Initialize a new blob store */
1305 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
1306 	CU_ASSERT(g_bserrno == 0);
1307 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1308 
1309 	CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz);
1310 
1311 	/* Unload the blob store */
1312 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1313 	CU_ASSERT(g_bserrno == 0);
1314 	g_bs = NULL;
1315 	g_blob = NULL;
1316 	g_blobid = 0;
1317 
1318 	dev = init_dev();
1319 	/* Load an existing blob store */
1320 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1321 	CU_ASSERT(g_bserrno == 0);
1322 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1323 
1324 	CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz);
1325 
1326 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1327 	CU_ASSERT(g_bserrno == 0);
1328 	g_bs = NULL;
1329 }
1330 
1331 /*
1332  * Create a blobstore, reload it and ensure total usable cluster count
1333  *  stays the same.
1334  */
1335 static void
1336 bs_usable_clusters(void)
1337 {
1338 	struct spdk_bs_dev *dev;
1339 	struct spdk_bs_opts opts;
1340 	uint32_t clusters;
1341 	int i, rc;
1342 
1343 	/* Init blobstore */
1344 	dev = init_dev();
1345 	spdk_bs_opts_init(&opts);
1346 
1347 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
1348 	CU_ASSERT(g_bserrno == 0);
1349 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1350 
1351 	clusters = spdk_bs_total_data_cluster_count(g_bs);
1352 
1353 	/* Unload the blob store */
1354 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1355 	CU_ASSERT(g_bserrno == 0);
1356 	g_bs = NULL;
1357 
1358 	dev = init_dev();
1359 	/* Load an existing blob store */
1360 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1361 	CU_ASSERT(g_bserrno == 0);
1362 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1363 
1364 	CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters);
1365 
1366 	/* Create and resize blobs to make sure that useable cluster count won't change */
1367 	for (i = 0; i < 4; i++) {
1368 		g_bserrno = -1;
1369 		g_blobid = SPDK_BLOBID_INVALID;
1370 		spdk_bs_md_create_blob(g_bs, blob_op_with_id_complete, NULL);
1371 		CU_ASSERT(g_bserrno == 0);
1372 		CU_ASSERT(g_blobid !=  SPDK_BLOBID_INVALID);
1373 
1374 		g_bserrno = -1;
1375 		g_blob = NULL;
1376 		spdk_bs_md_open_blob(g_bs, g_blobid, blob_op_with_handle_complete, NULL);
1377 		CU_ASSERT(g_bserrno == 0);
1378 		CU_ASSERT(g_blob !=  NULL);
1379 
1380 		rc = spdk_bs_md_resize_blob(g_blob, 10);
1381 		CU_ASSERT(rc == 0);
1382 
1383 		g_bserrno = -1;
1384 		spdk_bs_md_close_blob(&g_blob, blob_op_complete, NULL);
1385 		CU_ASSERT(g_bserrno == 0);
1386 
1387 		CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters);
1388 	}
1389 
1390 	/* Reload the blob store to make sure that nothing changed */
1391 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1392 	CU_ASSERT(g_bserrno == 0);
1393 	g_bs = NULL;
1394 
1395 	dev = init_dev();
1396 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1397 	CU_ASSERT(g_bserrno == 0);
1398 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1399 
1400 	CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters);
1401 
1402 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1403 	CU_ASSERT(g_bserrno == 0);
1404 	g_bs = NULL;
1405 }
1406 
1407 /*
1408  * Test resizing of the metadata blob.  This requires creating enough blobs
1409  *  so that one cluster is not enough to fit the metadata for those blobs.
1410  *  To induce this condition to happen more quickly, we reduce the cluster
1411  *  size to 16KB, which means only 4 4KB blob metadata pages can fit.
1412  */
1413 static void
1414 bs_resize_md(void)
1415 {
1416 	const int CLUSTER_PAGE_COUNT = 4;
1417 	const int NUM_BLOBS = CLUSTER_PAGE_COUNT * 4;
1418 	struct spdk_bs_dev *dev;
1419 	struct spdk_bs_opts opts;
1420 	uint32_t cluster_sz;
1421 	spdk_blob_id blobids[NUM_BLOBS];
1422 	int i;
1423 
1424 
1425 	dev = init_dev();
1426 	spdk_bs_opts_init(&opts);
1427 	opts.cluster_sz = CLUSTER_PAGE_COUNT * 4096;
1428 	cluster_sz = opts.cluster_sz;
1429 
1430 	/* Initialize a new blob store */
1431 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
1432 	CU_ASSERT(g_bserrno == 0);
1433 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1434 
1435 	CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz);
1436 
1437 	for (i = 0; i < NUM_BLOBS; i++) {
1438 		g_bserrno = -1;
1439 		g_blobid = SPDK_BLOBID_INVALID;
1440 		spdk_bs_md_create_blob(g_bs,
1441 				       blob_op_with_id_complete, NULL);
1442 		CU_ASSERT(g_bserrno == 0);
1443 		CU_ASSERT(g_blobid !=  SPDK_BLOBID_INVALID);
1444 		blobids[i] = g_blobid;
1445 	}
1446 
1447 	/* Unload the blob store */
1448 	g_bserrno = -1;
1449 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1450 	CU_ASSERT(g_bserrno == 0);
1451 
1452 	/* Load an existing blob store */
1453 	g_bserrno = -1;
1454 	g_bs = NULL;
1455 	dev = init_dev();
1456 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1457 	CU_ASSERT(g_bserrno == 0);
1458 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1459 
1460 	CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz);
1461 
1462 	for (i = 0; i < NUM_BLOBS; i++) {
1463 		g_bserrno = -1;
1464 		g_blob = NULL;
1465 		spdk_bs_md_open_blob(g_bs, blobids[i], blob_op_with_handle_complete, NULL);
1466 		CU_ASSERT(g_bserrno == 0);
1467 		CU_ASSERT(g_blob !=  NULL);
1468 		g_bserrno = -1;
1469 		spdk_bs_md_close_blob(&g_blob, blob_op_complete, NULL);
1470 		CU_ASSERT(g_bserrno == 0);
1471 	}
1472 
1473 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1474 	CU_ASSERT(g_bserrno == 0);
1475 	g_bs = NULL;
1476 }
1477 
1478 static void
1479 bs_destroy(void)
1480 {
1481 	struct spdk_bs_dev *dev;
1482 	struct spdk_bs_opts opts;
1483 
1484 	g_scheduler_delay = true;
1485 
1486 	_bs_flush_scheduler();
1487 	CU_ASSERT(TAILQ_EMPTY(&g_scheduled_ops));
1488 
1489 	/* Initialize a new blob store */
1490 	dev = init_dev();
1491 	spdk_bs_opts_init(&opts);
1492 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
1493 	CU_ASSERT(g_bserrno == 0);
1494 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1495 
1496 	/* Destroy the blob store */
1497 	g_bserrno = -1;
1498 	spdk_bs_destroy(g_bs, bs_op_complete, NULL);
1499 	/* Callback is called after device is destroyed in next scheduler run. */
1500 	_bs_flush_scheduler();
1501 	CU_ASSERT(TAILQ_EMPTY(&g_scheduled_ops));
1502 	CU_ASSERT(g_bserrno == 0);
1503 
1504 	/* Loading an non-existent blob store should fail. */
1505 	g_bserrno = -1;
1506 	g_bs = NULL;
1507 	dev = init_dev();
1508 
1509 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1510 	CU_ASSERT(g_bserrno != 0);
1511 	g_scheduler_delay = false;
1512 }
1513 
1514 /* Try to hit all of the corner cases associated with serializing
1515  * a blob to disk
1516  */
1517 static void
1518 blob_serialize(void)
1519 {
1520 	struct spdk_bs_dev *dev;
1521 	struct spdk_bs_opts opts;
1522 	struct spdk_blob_store *bs;
1523 	spdk_blob_id blobid[2];
1524 	struct spdk_blob *blob[2];
1525 	uint64_t i;
1526 	char *value;
1527 	int rc;
1528 
1529 	dev = init_dev();
1530 
1531 	/* Initialize a new blobstore with very small clusters */
1532 	spdk_bs_opts_init(&opts);
1533 	opts.cluster_sz = dev->blocklen * 8;
1534 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
1535 	CU_ASSERT(g_bserrno == 0);
1536 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1537 	bs = g_bs;
1538 
1539 	/* Create and open two blobs */
1540 	for (i = 0; i < 2; i++) {
1541 		spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL);
1542 		CU_ASSERT(g_bserrno == 0);
1543 		CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1544 		blobid[i] = g_blobid;
1545 
1546 		/* Open a blob */
1547 		spdk_bs_md_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL);
1548 		CU_ASSERT(g_bserrno == 0);
1549 		CU_ASSERT(g_blob != NULL);
1550 		blob[i] = g_blob;
1551 
1552 		/* Set a fairly large xattr on both blobs to eat up
1553 		 * metadata space
1554 		 */
1555 		value = calloc(dev->blocklen - 64, sizeof(char));
1556 		SPDK_CU_ASSERT_FATAL(value != NULL);
1557 		memset(value, i, dev->blocklen / 2);
1558 		rc = spdk_blob_md_set_xattr(blob[i], "name", value, dev->blocklen - 64);
1559 		CU_ASSERT(rc == 0);
1560 		free(value);
1561 	}
1562 
1563 	/* Resize the blobs, alternating 1 cluster at a time.
1564 	 * This thwarts run length encoding and will cause spill
1565 	 * over of the extents.
1566 	 */
1567 	for (i = 0; i < 6; i++) {
1568 		rc = spdk_bs_md_resize_blob(blob[i % 2], (i / 2) + 1);
1569 		CU_ASSERT(rc == 0);
1570 	}
1571 
1572 	for (i = 0; i < 2; i++) {
1573 		spdk_bs_md_sync_blob(blob[i], blob_op_complete, NULL);
1574 		CU_ASSERT(g_bserrno == 0);
1575 	}
1576 
1577 	/* Close the blobs */
1578 	for (i = 0; i < 2; i++) {
1579 		spdk_bs_md_close_blob(&blob[i], blob_op_complete, NULL);
1580 		CU_ASSERT(g_bserrno == 0);
1581 	}
1582 
1583 	/* Unload the blobstore */
1584 	spdk_bs_unload(bs, bs_op_complete, NULL);
1585 	CU_ASSERT(g_bserrno == 0);
1586 	g_bs = NULL;
1587 	g_blob = NULL;
1588 	g_blobid = 0;
1589 	bs = NULL;
1590 
1591 	dev = init_dev();
1592 	/* Load an existing blob store */
1593 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1594 	CU_ASSERT(g_bserrno == 0);
1595 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1596 	bs = g_bs;
1597 
1598 	for (i = 0; i < 2; i++) {
1599 		blob[i] = NULL;
1600 
1601 		spdk_bs_md_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL);
1602 		CU_ASSERT(g_bserrno == 0);
1603 		CU_ASSERT(g_blob != NULL);
1604 		blob[i] = g_blob;
1605 
1606 		CU_ASSERT(spdk_blob_get_num_clusters(blob[i]) == 3);
1607 
1608 		spdk_bs_md_close_blob(&blob[i], blob_op_complete, NULL);
1609 		CU_ASSERT(g_bserrno == 0);
1610 	}
1611 
1612 	spdk_bs_unload(bs, bs_op_complete, NULL);
1613 	CU_ASSERT(g_bserrno == 0);
1614 	g_bs = NULL;
1615 }
1616 
1617 static void
1618 blob_crc(void)
1619 {
1620 	struct spdk_blob_store *bs;
1621 	struct spdk_bs_dev *dev;
1622 	struct spdk_blob *blob;
1623 	spdk_blob_id blobid;
1624 	uint32_t page_num;
1625 	int index;
1626 	struct spdk_blob_md_page *page;
1627 
1628 	dev = init_dev();
1629 
1630 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1631 	CU_ASSERT(g_bserrno == 0);
1632 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1633 	bs = g_bs;
1634 
1635 	spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL);
1636 	CU_ASSERT(g_bserrno == 0);
1637 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1638 	blobid = g_blobid;
1639 
1640 	spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1641 	CU_ASSERT(g_bserrno == 0);
1642 	CU_ASSERT(g_blob != NULL);
1643 	blob = g_blob;
1644 
1645 	spdk_bs_md_close_blob(&blob, blob_op_complete, NULL);
1646 	CU_ASSERT(g_bserrno == 0);
1647 	CU_ASSERT(blob == NULL);
1648 
1649 	page_num = _spdk_bs_blobid_to_page(blobid);
1650 	index = DEV_BUFFER_BLOCKLEN * (bs->md_start + page_num);
1651 	page = (struct spdk_blob_md_page *)&g_dev_buffer[index];
1652 	page->crc = 0;
1653 
1654 	spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1655 	CU_ASSERT(g_bserrno == -EINVAL);
1656 	CU_ASSERT(g_blob == NULL);
1657 	g_bserrno = 0;
1658 
1659 	spdk_bs_md_delete_blob(bs, blobid, blob_op_complete, NULL);
1660 	CU_ASSERT(g_bserrno == -EINVAL);
1661 
1662 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1663 	CU_ASSERT(g_bserrno == 0);
1664 	g_bs = NULL;
1665 }
1666 
1667 static void
1668 super_block_crc(void)
1669 {
1670 	struct spdk_bs_dev *dev;
1671 	struct spdk_bs_super_block *super_block;
1672 	struct spdk_bs_opts opts;
1673 
1674 	dev = init_dev();
1675 	spdk_bs_opts_init(&opts);
1676 
1677 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1678 	CU_ASSERT(g_bserrno == 0);
1679 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1680 
1681 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1682 	CU_ASSERT(g_bserrno == 0);
1683 	g_bs = NULL;
1684 
1685 	super_block = (struct spdk_bs_super_block *)g_dev_buffer;
1686 	super_block->crc = 0;
1687 	dev = init_dev();
1688 
1689 	g_scheduler_delay = true;
1690 	/* Load an existing blob store */
1691 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1692 
1693 	CU_ASSERT(g_bserrno == -EILSEQ);
1694 	_bs_flush_scheduler();
1695 	CU_ASSERT(TAILQ_EMPTY(&g_scheduled_ops));
1696 
1697 	g_scheduler_delay = false;
1698 }
1699 
1700 /* For blob dirty shutdown test case we do the following sub-test cases:
1701  * 1 Initialize new blob store and create 1 blob with some xattrs, then we
1702  *   dirty shutdown and reload the blob store and verify the xattrs.
1703  * 2 Resize the blob from 10 clusters to 20 clusters and then dirty shutdown,
1704  *   reload the blob store and verify the clusters number.
1705  * 3 Create the second blob and then dirty shutdown, reload the blob store
1706  *   and verify the second blob.
1707  * 4 Delete the second blob and then dirty shutdown, reload teh blob store
1708  *   and verify the second blob is invalid.
1709  * 5 Create the second blob again and also create the third blob, modify the
1710  *   md of second blob which makes the md invalid, and then dirty shutdown,
1711  *   reload the blob store verify the second blob, it should invalid and also
1712  *   verify the third blob, it should correct.
1713  */
1714 static void
1715 blob_dirty_shutdown(void)
1716 {
1717 	int rc;
1718 	int index;
1719 	struct spdk_bs_dev *dev;
1720 	spdk_blob_id blobid1, blobid2, blobid3;
1721 	struct spdk_blob *blob;
1722 	uint64_t length;
1723 	const void *value;
1724 	size_t value_len;
1725 	uint32_t page_num;
1726 	struct spdk_blob_md_page *page;
1727 	struct spdk_bs_opts opts;
1728 
1729 	dev = init_dev();
1730 	spdk_bs_opts_init(&opts);
1731 	/* Initialize a new blob store */
1732 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1733 	CU_ASSERT(g_bserrno == 0);
1734 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1735 
1736 	/* Create first blob */
1737 	spdk_bs_md_create_blob(g_bs, blob_op_with_id_complete, NULL);
1738 	CU_ASSERT(g_bserrno == 0);
1739 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1740 	blobid1 = g_blobid;
1741 
1742 	spdk_bs_md_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL);
1743 	CU_ASSERT(g_bserrno == 0);
1744 	CU_ASSERT(g_blob != NULL);
1745 	blob = g_blob;
1746 
1747 	/* Set some xattrs */
1748 	rc = spdk_blob_md_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1);
1749 	CU_ASSERT(rc == 0);
1750 
1751 	length = 2345;
1752 	rc = spdk_blob_md_set_xattr(blob, "length", &length, sizeof(length));
1753 	CU_ASSERT(rc == 0);
1754 
1755 	/* Resize the blob */
1756 	rc = spdk_bs_md_resize_blob(blob, 10);
1757 	CU_ASSERT(rc == 0);
1758 
1759 	spdk_bs_md_close_blob(&blob, blob_op_complete, NULL);
1760 	blob = NULL;
1761 	g_blob = NULL;
1762 	g_blobid = SPDK_BLOBID_INVALID;
1763 
1764 	/* Dirty shutdown */
1765 	_spdk_bs_free(g_bs);
1766 
1767 	/* reload blobstore */
1768 	dev = init_dev();
1769 	spdk_bs_opts_init(&opts);
1770 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1771 	CU_ASSERT(g_bserrno == 0);
1772 
1773 	spdk_bs_md_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL);
1774 	CU_ASSERT(g_bserrno == 0);
1775 	CU_ASSERT(g_blob != NULL);
1776 	blob = g_blob;
1777 
1778 	/* Get the xattrs */
1779 	value = NULL;
1780 	rc = spdk_bs_md_get_xattr_value(blob, "length", &value, &value_len);
1781 	CU_ASSERT(rc == 0);
1782 	SPDK_CU_ASSERT_FATAL(value != NULL);
1783 	CU_ASSERT(*(uint64_t *)value == length);
1784 	CU_ASSERT(value_len == 8);
1785 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10);
1786 
1787 	/* Resize the blob */
1788 	rc = spdk_bs_md_resize_blob(blob, 20);
1789 	CU_ASSERT(rc == 0);
1790 
1791 	spdk_bs_md_close_blob(&blob, blob_op_complete, NULL);
1792 	CU_ASSERT(g_bserrno == 0);
1793 	blob = NULL;
1794 	g_blob = NULL;
1795 	g_blobid = SPDK_BLOBID_INVALID;
1796 
1797 	/* Dirty shutdown */
1798 	_spdk_bs_free(g_bs);
1799 
1800 	/* reload the blobstore */
1801 	dev = init_dev();
1802 	spdk_bs_opts_init(&opts);
1803 	/* Load an existing blob store */
1804 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1805 	CU_ASSERT(g_bserrno == 0);
1806 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1807 	spdk_bs_md_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL);
1808 	CU_ASSERT(g_bserrno == 0);
1809 	CU_ASSERT(g_blob != NULL);
1810 	blob = g_blob;
1811 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 20);
1812 
1813 	spdk_bs_md_close_blob(&blob, blob_op_complete, NULL);
1814 	CU_ASSERT(g_bserrno == 0);
1815 	blob = NULL;
1816 	g_blob = NULL;
1817 	g_blobid = SPDK_BLOBID_INVALID;
1818 
1819 	/* Create second blob */
1820 	spdk_bs_md_create_blob(g_bs, blob_op_with_id_complete, NULL);
1821 	CU_ASSERT(g_bserrno == 0);
1822 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1823 	blobid2 = g_blobid;
1824 
1825 	spdk_bs_md_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL);
1826 	CU_ASSERT(g_bserrno == 0);
1827 	CU_ASSERT(g_blob != NULL);
1828 	blob = g_blob;
1829 
1830 	/* Set some xattrs */
1831 	rc = spdk_blob_md_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1);
1832 	CU_ASSERT(rc == 0);
1833 
1834 	length = 5432;
1835 	rc = spdk_blob_md_set_xattr(blob, "length", &length, sizeof(length));
1836 	CU_ASSERT(rc == 0);
1837 
1838 	/* Resize the blob */
1839 	rc = spdk_bs_md_resize_blob(blob, 10);
1840 	CU_ASSERT(rc == 0);
1841 
1842 	spdk_bs_md_close_blob(&blob, blob_op_complete, NULL);
1843 	blob = NULL;
1844 	g_blob = NULL;
1845 	g_blobid = SPDK_BLOBID_INVALID;
1846 
1847 	/* Dirty shutdown */
1848 	_spdk_bs_free(g_bs);
1849 
1850 	/* reload the blobstore */
1851 	dev = init_dev();
1852 	spdk_bs_opts_init(&opts);
1853 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1854 	CU_ASSERT(g_bserrno == 0);
1855 
1856 	spdk_bs_md_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL);
1857 	CU_ASSERT(g_bserrno == 0);
1858 	CU_ASSERT(g_blob != NULL);
1859 	blob = g_blob;
1860 
1861 	/* Get the xattrs */
1862 	value = NULL;
1863 	rc = spdk_bs_md_get_xattr_value(blob, "length", &value, &value_len);
1864 	CU_ASSERT(rc == 0);
1865 	SPDK_CU_ASSERT_FATAL(value != NULL);
1866 	CU_ASSERT(*(uint64_t *)value == length);
1867 	CU_ASSERT(value_len == 8);
1868 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10);
1869 
1870 	spdk_bs_md_close_blob(&blob, blob_op_complete, NULL);
1871 	CU_ASSERT(g_bserrno == 0);
1872 	spdk_bs_md_delete_blob(g_bs, blobid2, blob_op_complete, NULL);
1873 	CU_ASSERT(g_bserrno == 0);
1874 
1875 	/* Dirty shutdown */
1876 	_spdk_bs_free(g_bs);
1877 	/* reload the blobstore */
1878 	dev = init_dev();
1879 	spdk_bs_opts_init(&opts);
1880 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1881 	CU_ASSERT(g_bserrno == 0);
1882 
1883 	spdk_bs_md_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL);
1884 	CU_ASSERT(g_bserrno != 0);
1885 	CU_ASSERT(g_blob == NULL);
1886 
1887 	spdk_bs_md_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL);
1888 	CU_ASSERT(g_bserrno == 0);
1889 	CU_ASSERT(g_blob != NULL);
1890 	spdk_bs_md_close_blob(&g_blob, blob_op_complete, NULL);
1891 	CU_ASSERT(g_bserrno == 0);
1892 
1893 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1894 	CU_ASSERT(g_bserrno == 0);
1895 	g_bs = NULL;
1896 
1897 	/* reload the blobstore */
1898 	dev = init_dev();
1899 	spdk_bs_opts_init(&opts);
1900 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1901 	CU_ASSERT(g_bserrno == 0);
1902 
1903 	/* Create second blob */
1904 	spdk_bs_md_create_blob(g_bs, blob_op_with_id_complete, NULL);
1905 	CU_ASSERT(g_bserrno == 0);
1906 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1907 	blobid2 = g_blobid;
1908 
1909 	/* Create third blob */
1910 	spdk_bs_md_create_blob(g_bs, blob_op_with_id_complete, NULL);
1911 	CU_ASSERT(g_bserrno == 0);
1912 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1913 	blobid3 = g_blobid;
1914 
1915 	spdk_bs_md_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL);
1916 	CU_ASSERT(g_bserrno == 0);
1917 	CU_ASSERT(g_blob != NULL);
1918 	blob = g_blob;
1919 
1920 	/* Set some xattrs for second blob */
1921 	rc = spdk_blob_md_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1);
1922 	CU_ASSERT(rc == 0);
1923 
1924 	length = 5432;
1925 	rc = spdk_blob_md_set_xattr(blob, "length", &length, sizeof(length));
1926 	CU_ASSERT(rc == 0);
1927 
1928 	spdk_bs_md_close_blob(&blob, blob_op_complete, NULL);
1929 	blob = NULL;
1930 	g_blob = NULL;
1931 	g_blobid = SPDK_BLOBID_INVALID;
1932 
1933 	spdk_bs_md_open_blob(g_bs, blobid3, blob_op_with_handle_complete, NULL);
1934 	CU_ASSERT(g_bserrno == 0);
1935 	CU_ASSERT(g_blob != NULL);
1936 	blob = g_blob;
1937 
1938 	/* Set some xattrs for third blob */
1939 	rc = spdk_blob_md_set_xattr(blob, "name", "log2.txt", strlen("log2.txt") + 1);
1940 	CU_ASSERT(rc == 0);
1941 
1942 	length = 5432;
1943 	rc = spdk_blob_md_set_xattr(blob, "length", &length, sizeof(length));
1944 	CU_ASSERT(rc == 0);
1945 
1946 	spdk_bs_md_close_blob(&blob, blob_op_complete, NULL);
1947 	blob = NULL;
1948 	g_blob = NULL;
1949 	g_blobid = SPDK_BLOBID_INVALID;
1950 
1951 	/* Mark second blob as invalid */
1952 	page_num = _spdk_bs_blobid_to_page(blobid2);
1953 
1954 	index = DEV_BUFFER_BLOCKLEN * (g_bs->md_start + page_num);
1955 	page = (struct spdk_blob_md_page *)&g_dev_buffer[index];
1956 	page->sequence_num = 1;
1957 	page->crc = _spdk_blob_md_page_calc_crc(page);
1958 
1959 	/* Dirty shutdown */
1960 	_spdk_bs_free(g_bs);
1961 	/* reload the blobstore */
1962 	dev = init_dev();
1963 	spdk_bs_opts_init(&opts);
1964 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1965 	CU_ASSERT(g_bserrno == 0);
1966 
1967 	spdk_bs_md_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL);
1968 	CU_ASSERT(g_bserrno != 0);
1969 	CU_ASSERT(g_blob == NULL);
1970 
1971 	spdk_bs_md_open_blob(g_bs, blobid3, blob_op_with_handle_complete, NULL);
1972 	CU_ASSERT(g_bserrno == 0);
1973 	CU_ASSERT(g_blob != NULL);
1974 	blob = g_blob;
1975 
1976 	spdk_bs_md_close_blob(&blob, blob_op_complete, NULL);
1977 	blob = NULL;
1978 	g_blob = NULL;
1979 	g_blobid = SPDK_BLOBID_INVALID;
1980 
1981 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1982 	CU_ASSERT(g_bserrno == 0);
1983 	g_bs = NULL;
1984 }
1985 
1986 static void
1987 blob_flags(void)
1988 {
1989 	struct spdk_bs_dev *dev;
1990 	spdk_blob_id blobid_invalid, blobid_data_ro, blobid_md_ro;
1991 	struct spdk_blob *blob_invalid, *blob_data_ro, *blob_md_ro;
1992 	struct spdk_bs_opts opts;
1993 
1994 	dev = init_dev();
1995 	spdk_bs_opts_init(&opts);
1996 
1997 	/* Initialize a new blob store */
1998 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
1999 	CU_ASSERT(g_bserrno == 0);
2000 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2001 
2002 	/* Create three blobs - one each for testing invalid, data_ro and md_ro flags. */
2003 	spdk_bs_md_create_blob(g_bs, blob_op_with_id_complete, NULL);
2004 	CU_ASSERT(g_bserrno == 0);
2005 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2006 	blobid_invalid = g_blobid;
2007 
2008 	spdk_bs_md_create_blob(g_bs, blob_op_with_id_complete, NULL);
2009 	CU_ASSERT(g_bserrno == 0);
2010 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2011 	blobid_data_ro = g_blobid;
2012 
2013 	spdk_bs_md_create_blob(g_bs, blob_op_with_id_complete, NULL);
2014 	CU_ASSERT(g_bserrno == 0);
2015 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2016 	blobid_md_ro = g_blobid;
2017 
2018 	spdk_bs_md_open_blob(g_bs, blobid_invalid, blob_op_with_handle_complete, NULL);
2019 	CU_ASSERT(g_bserrno == 0);
2020 	CU_ASSERT(g_blob != NULL);
2021 	blob_invalid = g_blob;
2022 
2023 	spdk_bs_md_open_blob(g_bs, blobid_data_ro, blob_op_with_handle_complete, NULL);
2024 	CU_ASSERT(g_bserrno == 0);
2025 	CU_ASSERT(g_blob != NULL);
2026 	blob_data_ro = g_blob;
2027 
2028 	spdk_bs_md_open_blob(g_bs, blobid_md_ro, blob_op_with_handle_complete, NULL);
2029 	CU_ASSERT(g_bserrno == 0);
2030 	CU_ASSERT(g_blob != NULL);
2031 	blob_md_ro = g_blob;
2032 
2033 	blob_invalid->invalid_flags = (1ULL << 63);
2034 	blob_invalid->state = SPDK_BLOB_STATE_DIRTY;
2035 	blob_data_ro->data_ro_flags = (1ULL << 62);
2036 	blob_data_ro->state = SPDK_BLOB_STATE_DIRTY;
2037 	blob_md_ro->md_ro_flags = (1ULL << 61);
2038 	blob_md_ro->state = SPDK_BLOB_STATE_DIRTY;
2039 
2040 	g_bserrno = -1;
2041 	spdk_bs_md_sync_blob(blob_invalid, blob_op_complete, NULL);
2042 	CU_ASSERT(g_bserrno == 0);
2043 	g_bserrno = -1;
2044 	spdk_bs_md_sync_blob(blob_data_ro, blob_op_complete, NULL);
2045 	CU_ASSERT(g_bserrno == 0);
2046 	g_bserrno = -1;
2047 	spdk_bs_md_sync_blob(blob_md_ro, blob_op_complete, NULL);
2048 	CU_ASSERT(g_bserrno == 0);
2049 
2050 	g_bserrno = -1;
2051 	spdk_bs_md_close_blob(&blob_invalid, blob_op_complete, NULL);
2052 	CU_ASSERT(g_bserrno == 0);
2053 	blob_invalid = NULL;
2054 	g_bserrno = -1;
2055 	spdk_bs_md_close_blob(&blob_data_ro, blob_op_complete, NULL);
2056 	CU_ASSERT(g_bserrno == 0);
2057 	blob_data_ro = NULL;
2058 	g_bserrno = -1;
2059 	spdk_bs_md_close_blob(&blob_md_ro, blob_op_complete, NULL);
2060 	CU_ASSERT(g_bserrno == 0);
2061 	blob_md_ro = NULL;
2062 
2063 	g_blob = NULL;
2064 	g_blobid = SPDK_BLOBID_INVALID;
2065 
2066 	/* Unload the blob store */
2067 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2068 	CU_ASSERT(g_bserrno == 0);
2069 	g_bs = NULL;
2070 
2071 	/* Load an existing blob store */
2072 	dev = init_dev();
2073 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2074 	CU_ASSERT(g_bserrno == 0);
2075 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2076 
2077 	g_blob = NULL;
2078 	g_bserrno = 0;
2079 	spdk_bs_md_open_blob(g_bs, blobid_invalid, blob_op_with_handle_complete, NULL);
2080 	CU_ASSERT(g_bserrno != 0);
2081 	CU_ASSERT(g_blob == NULL);
2082 
2083 	g_blob = NULL;
2084 	g_bserrno = -1;
2085 	spdk_bs_md_open_blob(g_bs, blobid_data_ro, blob_op_with_handle_complete, NULL);
2086 	CU_ASSERT(g_bserrno == 0);
2087 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
2088 	blob_data_ro = g_blob;
2089 	/* If an unknown data_ro flag was found, the blob should be marked both data and md read-only. */
2090 	CU_ASSERT(blob_data_ro->data_ro == true);
2091 	CU_ASSERT(blob_data_ro->md_ro == true);
2092 
2093 	g_blob = NULL;
2094 	g_bserrno = -1;
2095 	spdk_bs_md_open_blob(g_bs, blobid_md_ro, blob_op_with_handle_complete, NULL);
2096 	CU_ASSERT(g_bserrno == 0);
2097 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
2098 	blob_md_ro = g_blob;
2099 	CU_ASSERT(blob_md_ro->data_ro == false);
2100 	CU_ASSERT(blob_md_ro->md_ro == true);
2101 
2102 	spdk_bs_md_close_blob(&blob_data_ro, blob_op_complete, NULL);
2103 	CU_ASSERT(g_bserrno == 0);
2104 	spdk_bs_md_close_blob(&blob_md_ro, blob_op_complete, NULL);
2105 	CU_ASSERT(g_bserrno == 0);
2106 
2107 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2108 	CU_ASSERT(g_bserrno == 0);
2109 }
2110 
2111 int main(int argc, char **argv)
2112 {
2113 	CU_pSuite	suite = NULL;
2114 	unsigned int	num_failures;
2115 
2116 	if (CU_initialize_registry() != CUE_SUCCESS) {
2117 		return CU_get_error();
2118 	}
2119 
2120 	suite = CU_add_suite("blob", NULL, NULL);
2121 	if (suite == NULL) {
2122 		CU_cleanup_registry();
2123 		return CU_get_error();
2124 	}
2125 
2126 	if (
2127 		CU_add_test(suite, "blob_init", blob_init) == NULL ||
2128 		CU_add_test(suite, "blob_open", blob_open) == NULL ||
2129 		CU_add_test(suite, "blob_delete", blob_delete) == NULL ||
2130 		CU_add_test(suite, "blob_resize", blob_resize) == NULL ||
2131 		CU_add_test(suite, "channel_ops", channel_ops) == NULL ||
2132 		CU_add_test(suite, "blob_super", blob_super) == NULL ||
2133 		CU_add_test(suite, "blob_write", blob_write) == NULL ||
2134 		CU_add_test(suite, "blob_read", blob_read) == NULL ||
2135 		CU_add_test(suite, "blob_rw_verify", blob_rw_verify) == NULL ||
2136 		CU_add_test(suite, "blob_rw_verify_iov", blob_rw_verify_iov) == NULL ||
2137 		CU_add_test(suite, "blob_rw_verify_iov_nomem", blob_rw_verify_iov_nomem) == NULL ||
2138 		CU_add_test(suite, "blob_rw_iov_read_only", blob_rw_iov_read_only) == NULL ||
2139 		CU_add_test(suite, "blob_iter", blob_iter) == NULL ||
2140 		CU_add_test(suite, "blob_xattr", blob_xattr) == NULL ||
2141 		CU_add_test(suite, "bs_load", bs_load) == NULL ||
2142 		CU_add_test(suite, "bs_unload", bs_unload) == NULL ||
2143 		CU_add_test(suite, "bs_cluster_sz", bs_cluster_sz) == NULL ||
2144 		CU_add_test(suite, "bs_usable_clusters", bs_usable_clusters) == NULL ||
2145 		CU_add_test(suite, "bs_resize_md", bs_resize_md) == NULL ||
2146 		CU_add_test(suite, "bs_destroy", bs_destroy) == NULL ||
2147 		CU_add_test(suite, "bs_type", bs_type) == NULL ||
2148 		CU_add_test(suite, "bs_super_block", bs_super_block) == NULL ||
2149 		CU_add_test(suite, "blob_serialize", blob_serialize) == NULL ||
2150 		CU_add_test(suite, "blob_crc", blob_crc) == NULL ||
2151 		CU_add_test(suite, "super_block_crc", super_block_crc) == NULL ||
2152 		CU_add_test(suite, "blob_dirty_shutdown", blob_dirty_shutdown) == NULL ||
2153 		CU_add_test(suite, "blob_flags", blob_flags) == NULL
2154 	) {
2155 		CU_cleanup_registry();
2156 		return CU_get_error();
2157 	}
2158 
2159 	g_dev_buffer = calloc(1, DEV_BUFFER_SIZE);
2160 	spdk_allocate_thread(_bs_send_msg, NULL, NULL, NULL, "thread0");
2161 	CU_basic_set_mode(CU_BRM_VERBOSE);
2162 	CU_basic_run_tests();
2163 	num_failures = CU_get_number_of_failures();
2164 	CU_cleanup_registry();
2165 	spdk_free_thread();
2166 	free(g_dev_buffer);
2167 	return num_failures;
2168 }
2169