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