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