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