xref: /spdk/test/unit/lib/blob/blob.c/blob_ut.c (revision 4d36735401a968630e14533383f8d8b8fd610b3a)
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright (c) Intel Corporation.
5  *   All rights reserved.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 #include "spdk/stdinc.h"
35 
36 #include "spdk_cunit.h"
37 #include "spdk/blob.h"
38 
39 #include "lib/test_env.c"
40 #include "../bs_dev_common.c"
41 #include "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 
1545 	/* Load an existing blob store */
1546 	dev = init_dev();
1547 	strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH);
1548 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1549 	CU_ASSERT(g_bserrno == 0);
1550 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1551 
1552 	super_block = (struct spdk_bs_super_block *)g_dev_buffer;
1553 	CU_ASSERT(super_block->clean == 0);
1554 
1555 	spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
1556 	CU_ASSERT(g_bserrno == 0);
1557 	CU_ASSERT(g_blob != NULL);
1558 	blob = g_blob;
1559 
1560 	/* Get the xattrs */
1561 	value = NULL;
1562 	rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len);
1563 	CU_ASSERT(rc == 0);
1564 	SPDK_CU_ASSERT_FATAL(value != NULL);
1565 	CU_ASSERT(*(uint64_t *)value == length);
1566 	CU_ASSERT(value_len == 8);
1567 
1568 	rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len);
1569 	CU_ASSERT(rc == -ENOENT);
1570 
1571 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10);
1572 
1573 	spdk_blob_close(blob, blob_op_complete, NULL);
1574 	CU_ASSERT(g_bserrno == 0);
1575 	blob = NULL;
1576 	g_blob = NULL;
1577 	g_blobid = SPDK_BLOBID_INVALID;
1578 
1579 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1580 	CU_ASSERT(g_bserrno == 0);
1581 	g_bs = NULL;
1582 }
1583 
1584 static void
1585 bs_type(void)
1586 {
1587 	struct spdk_bs_dev *dev;
1588 	struct spdk_bs_opts opts;
1589 
1590 	dev = init_dev();
1591 	spdk_bs_opts_init(&opts);
1592 	strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH);
1593 
1594 	/* Initialize a new blob store */
1595 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
1596 	CU_ASSERT(g_bserrno == 0);
1597 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1598 
1599 	/* Unload the blob store */
1600 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1601 	CU_ASSERT(g_bserrno == 0);
1602 	g_bs = NULL;
1603 	g_blob = NULL;
1604 	g_blobid = 0;
1605 
1606 	/* Load non existing blobstore type */
1607 	dev = init_dev();
1608 	strncpy(opts.bstype.bstype, "NONEXISTING", SPDK_BLOBSTORE_TYPE_LENGTH);
1609 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1610 	CU_ASSERT(g_bserrno != 0);
1611 
1612 	/* Load with empty blobstore type */
1613 	dev = init_dev();
1614 	strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH);
1615 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1616 	CU_ASSERT(g_bserrno == 0);
1617 
1618 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1619 	CU_ASSERT(g_bserrno == 0);
1620 	g_bs = NULL;
1621 
1622 	/* Initialize a new blob store with empty bstype */
1623 	dev = init_dev();
1624 	strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH);
1625 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1626 	CU_ASSERT(g_bserrno == 0);
1627 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1628 
1629 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1630 	CU_ASSERT(g_bserrno == 0);
1631 	g_bs = NULL;
1632 
1633 	/* Load non existing blobstore type */
1634 	dev = init_dev();
1635 	strncpy(opts.bstype.bstype, "NONEXISTING", SPDK_BLOBSTORE_TYPE_LENGTH);
1636 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1637 	CU_ASSERT(g_bserrno != 0);
1638 
1639 	/* Load with empty blobstore type */
1640 	dev = init_dev();
1641 	strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH);
1642 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1643 	CU_ASSERT(g_bserrno == 0);
1644 
1645 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1646 	CU_ASSERT(g_bserrno == 0);
1647 	g_bs = NULL;
1648 }
1649 
1650 static void
1651 bs_super_block(void)
1652 {
1653 	struct spdk_bs_dev *dev;
1654 	struct spdk_bs_super_block *super_block;
1655 	struct spdk_bs_opts opts;
1656 	struct spdk_bs_super_block_ver1 super_block_v1;
1657 
1658 	dev = init_dev();
1659 	spdk_bs_opts_init(&opts);
1660 	strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH);
1661 
1662 	/* Initialize a new blob store */
1663 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
1664 	CU_ASSERT(g_bserrno == 0);
1665 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1666 
1667 	/* Unload the blob store */
1668 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1669 	CU_ASSERT(g_bserrno == 0);
1670 	g_bs = NULL;
1671 	g_blob = NULL;
1672 	g_blobid = 0;
1673 
1674 	/* Load an existing blob store with version newer than supported */
1675 	super_block = (struct spdk_bs_super_block *)g_dev_buffer;
1676 	super_block->version++;
1677 
1678 	dev = init_dev();
1679 	strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH);
1680 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1681 	CU_ASSERT(g_bserrno != 0);
1682 
1683 	/* Create a new blob store with super block version 1 */
1684 	dev = init_dev();
1685 	super_block_v1.version = 1;
1686 	strncpy(super_block_v1.signature, "SPDKBLOB", sizeof(super_block_v1.signature));
1687 	super_block_v1.length = 0x1000;
1688 	super_block_v1.clean = 1;
1689 	super_block_v1.super_blob = 0xFFFFFFFFFFFFFFFF;
1690 	super_block_v1.cluster_size = 0x100000;
1691 	super_block_v1.used_page_mask_start = 0x01;
1692 	super_block_v1.used_page_mask_len = 0x01;
1693 	super_block_v1.used_cluster_mask_start = 0x02;
1694 	super_block_v1.used_cluster_mask_len = 0x01;
1695 	super_block_v1.md_start = 0x03;
1696 	super_block_v1.md_len = 0x40;
1697 	memset(super_block_v1.reserved, 0, 4036);
1698 	super_block_v1.crc = _spdk_blob_md_page_calc_crc(&super_block_v1);
1699 	memcpy(g_dev_buffer, &super_block_v1, sizeof(struct spdk_bs_super_block_ver1));
1700 
1701 	strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH);
1702 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1703 	CU_ASSERT(g_bserrno == 0);
1704 
1705 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1706 	CU_ASSERT(g_bserrno == 0);
1707 	g_bs = NULL;
1708 }
1709 
1710 /*
1711  * Create a blobstore and then unload it.
1712  */
1713 static void
1714 bs_unload(void)
1715 {
1716 	struct spdk_bs_dev *dev;
1717 	struct spdk_blob_store *bs;
1718 	spdk_blob_id blobid;
1719 	struct spdk_blob *blob;
1720 
1721 	dev = init_dev();
1722 
1723 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1724 	CU_ASSERT(g_bserrno == 0);
1725 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1726 	bs = g_bs;
1727 
1728 	/* Create a blob and open it. */
1729 	g_bserrno = -1;
1730 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
1731 	CU_ASSERT(g_bserrno == 0);
1732 	CU_ASSERT(g_blobid > 0);
1733 	blobid = g_blobid;
1734 
1735 	g_bserrno = -1;
1736 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1737 	CU_ASSERT(g_bserrno == 0);
1738 	CU_ASSERT(g_blob != NULL);
1739 	blob = g_blob;
1740 
1741 	/* Try to unload blobstore, should fail with open blob */
1742 	g_bserrno = -1;
1743 	spdk_bs_unload(bs, bs_op_complete, NULL);
1744 	CU_ASSERT(g_bserrno == -EBUSY);
1745 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1746 
1747 	/* Close the blob, then successfully unload blobstore */
1748 	g_bserrno = -1;
1749 	spdk_blob_close(blob, blob_op_complete, NULL);
1750 	CU_ASSERT(g_bserrno == 0);
1751 
1752 	g_bserrno = -1;
1753 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1754 	CU_ASSERT(g_bserrno == 0);
1755 	g_bs = NULL;
1756 }
1757 
1758 /*
1759  * Create a blobstore with a cluster size different than the default, and ensure it is
1760  *  persisted.
1761  */
1762 static void
1763 bs_cluster_sz(void)
1764 {
1765 	struct spdk_bs_dev *dev;
1766 	struct spdk_bs_opts opts;
1767 	uint32_t cluster_sz;
1768 
1769 	/* Set cluster size to zero */
1770 	dev = init_dev();
1771 	spdk_bs_opts_init(&opts);
1772 	opts.cluster_sz = 0;
1773 
1774 	/* Initialize a new blob store */
1775 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
1776 	CU_ASSERT(g_bserrno == -EINVAL);
1777 	SPDK_CU_ASSERT_FATAL(g_bs == NULL);
1778 
1779 	/*
1780 	 * Set cluster size to blobstore page size,
1781 	 * to work it is required to be at least twice the blobstore page size.
1782 	 */
1783 	dev = init_dev();
1784 	spdk_bs_opts_init(&opts);
1785 	opts.cluster_sz = SPDK_BS_PAGE_SIZE;
1786 
1787 	/* Initialize a new blob store */
1788 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
1789 	CU_ASSERT(g_bserrno == -ENOMEM);
1790 	SPDK_CU_ASSERT_FATAL(g_bs == NULL);
1791 
1792 	/*
1793 	 * Set cluster size to lower than page size,
1794 	 * to work it is required to be at least twice the blobstore page size.
1795 	 */
1796 	dev = init_dev();
1797 	spdk_bs_opts_init(&opts);
1798 	opts.cluster_sz = SPDK_BS_PAGE_SIZE - 1;
1799 
1800 	/* Initialize a new blob store */
1801 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
1802 	CU_ASSERT(g_bserrno == -ENOMEM);
1803 	SPDK_CU_ASSERT_FATAL(g_bs == NULL);
1804 
1805 	/* Set cluster size to twice the default */
1806 	dev = init_dev();
1807 	spdk_bs_opts_init(&opts);
1808 	opts.cluster_sz *= 2;
1809 	cluster_sz = opts.cluster_sz;
1810 
1811 	/* Initialize a new blob store */
1812 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
1813 	CU_ASSERT(g_bserrno == 0);
1814 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1815 
1816 	CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz);
1817 
1818 	/* Unload the blob store */
1819 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1820 	CU_ASSERT(g_bserrno == 0);
1821 	g_bs = NULL;
1822 	g_blob = NULL;
1823 	g_blobid = 0;
1824 
1825 	dev = init_dev();
1826 	/* Load an existing blob store */
1827 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1828 	CU_ASSERT(g_bserrno == 0);
1829 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1830 
1831 	CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz);
1832 
1833 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1834 	CU_ASSERT(g_bserrno == 0);
1835 	g_bs = NULL;
1836 }
1837 
1838 /*
1839  * Create a blobstore, reload it and ensure total usable cluster count
1840  *  stays the same.
1841  */
1842 static void
1843 bs_usable_clusters(void)
1844 {
1845 	struct spdk_bs_dev *dev;
1846 	struct spdk_bs_opts opts;
1847 	uint32_t clusters;
1848 	int i, rc;
1849 
1850 	/* Init blobstore */
1851 	dev = init_dev();
1852 	spdk_bs_opts_init(&opts);
1853 
1854 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
1855 	CU_ASSERT(g_bserrno == 0);
1856 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1857 
1858 	clusters = spdk_bs_total_data_cluster_count(g_bs);
1859 
1860 	/* Unload the blob store */
1861 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1862 	CU_ASSERT(g_bserrno == 0);
1863 	g_bs = NULL;
1864 
1865 	dev = init_dev();
1866 	/* Load an existing blob store */
1867 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1868 	CU_ASSERT(g_bserrno == 0);
1869 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1870 
1871 	CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters);
1872 
1873 	/* Create and resize blobs to make sure that useable cluster count won't change */
1874 	for (i = 0; i < 4; i++) {
1875 		g_bserrno = -1;
1876 		g_blobid = SPDK_BLOBID_INVALID;
1877 		spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
1878 		CU_ASSERT(g_bserrno == 0);
1879 		CU_ASSERT(g_blobid !=  SPDK_BLOBID_INVALID);
1880 
1881 		g_bserrno = -1;
1882 		g_blob = NULL;
1883 		spdk_bs_open_blob(g_bs, g_blobid, blob_op_with_handle_complete, NULL);
1884 		CU_ASSERT(g_bserrno == 0);
1885 		CU_ASSERT(g_blob !=  NULL);
1886 
1887 		rc = spdk_blob_resize(g_blob, 10);
1888 		CU_ASSERT(rc == 0);
1889 
1890 		g_bserrno = -1;
1891 		spdk_blob_close(g_blob, blob_op_complete, NULL);
1892 		CU_ASSERT(g_bserrno == 0);
1893 
1894 		CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters);
1895 	}
1896 
1897 	/* Reload the blob store to make sure that nothing changed */
1898 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1899 	CU_ASSERT(g_bserrno == 0);
1900 	g_bs = NULL;
1901 
1902 	dev = init_dev();
1903 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1904 	CU_ASSERT(g_bserrno == 0);
1905 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1906 
1907 	CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters);
1908 
1909 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1910 	CU_ASSERT(g_bserrno == 0);
1911 	g_bs = NULL;
1912 }
1913 
1914 /*
1915  * Test resizing of the metadata blob.  This requires creating enough blobs
1916  *  so that one cluster is not enough to fit the metadata for those blobs.
1917  *  To induce this condition to happen more quickly, we reduce the cluster
1918  *  size to 16KB, which means only 4 4KB blob metadata pages can fit.
1919  */
1920 static void
1921 bs_resize_md(void)
1922 {
1923 	const int CLUSTER_PAGE_COUNT = 4;
1924 	const int NUM_BLOBS = CLUSTER_PAGE_COUNT * 4;
1925 	struct spdk_bs_dev *dev;
1926 	struct spdk_bs_opts opts;
1927 	uint32_t cluster_sz;
1928 	spdk_blob_id blobids[NUM_BLOBS];
1929 	int i;
1930 
1931 
1932 	dev = init_dev();
1933 	spdk_bs_opts_init(&opts);
1934 	opts.cluster_sz = CLUSTER_PAGE_COUNT * 4096;
1935 	cluster_sz = opts.cluster_sz;
1936 
1937 	/* Initialize a new blob store */
1938 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
1939 	CU_ASSERT(g_bserrno == 0);
1940 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1941 
1942 	CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz);
1943 
1944 	for (i = 0; i < NUM_BLOBS; i++) {
1945 		g_bserrno = -1;
1946 		g_blobid = SPDK_BLOBID_INVALID;
1947 		spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
1948 		CU_ASSERT(g_bserrno == 0);
1949 		CU_ASSERT(g_blobid !=  SPDK_BLOBID_INVALID);
1950 		blobids[i] = g_blobid;
1951 	}
1952 
1953 	/* Unload the blob store */
1954 	g_bserrno = -1;
1955 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1956 	CU_ASSERT(g_bserrno == 0);
1957 
1958 	/* Load an existing blob store */
1959 	g_bserrno = -1;
1960 	g_bs = NULL;
1961 	dev = init_dev();
1962 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1963 	CU_ASSERT(g_bserrno == 0);
1964 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1965 
1966 	CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz);
1967 
1968 	for (i = 0; i < NUM_BLOBS; i++) {
1969 		g_bserrno = -1;
1970 		g_blob = NULL;
1971 		spdk_bs_open_blob(g_bs, blobids[i], blob_op_with_handle_complete, NULL);
1972 		CU_ASSERT(g_bserrno == 0);
1973 		CU_ASSERT(g_blob !=  NULL);
1974 		g_bserrno = -1;
1975 		spdk_blob_close(g_blob, blob_op_complete, NULL);
1976 		CU_ASSERT(g_bserrno == 0);
1977 	}
1978 
1979 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1980 	CU_ASSERT(g_bserrno == 0);
1981 	g_bs = NULL;
1982 }
1983 
1984 static void
1985 bs_destroy(void)
1986 {
1987 	struct spdk_bs_dev *dev;
1988 	struct spdk_bs_opts opts;
1989 
1990 	/* Initialize a new blob store */
1991 	dev = init_dev();
1992 	spdk_bs_opts_init(&opts);
1993 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
1994 	CU_ASSERT(g_bserrno == 0);
1995 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1996 
1997 	/* Destroy the blob store */
1998 	g_bserrno = -1;
1999 	spdk_bs_destroy(g_bs, bs_op_complete, NULL);
2000 	CU_ASSERT(g_bserrno == 0);
2001 
2002 	/* Loading an non-existent blob store should fail. */
2003 	g_bs = NULL;
2004 	dev = init_dev();
2005 
2006 	g_bserrno = 0;
2007 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2008 	CU_ASSERT(g_bserrno != 0);
2009 }
2010 
2011 /* Try to hit all of the corner cases associated with serializing
2012  * a blob to disk
2013  */
2014 static void
2015 blob_serialize(void)
2016 {
2017 	struct spdk_bs_dev *dev;
2018 	struct spdk_bs_opts opts;
2019 	struct spdk_blob_store *bs;
2020 	spdk_blob_id blobid[2];
2021 	struct spdk_blob *blob[2];
2022 	uint64_t i;
2023 	char *value;
2024 	int rc;
2025 
2026 	dev = init_dev();
2027 
2028 	/* Initialize a new blobstore with very small clusters */
2029 	spdk_bs_opts_init(&opts);
2030 	opts.cluster_sz = dev->blocklen * 8;
2031 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2032 	CU_ASSERT(g_bserrno == 0);
2033 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2034 	bs = g_bs;
2035 
2036 	/* Create and open two blobs */
2037 	for (i = 0; i < 2; i++) {
2038 		spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
2039 		CU_ASSERT(g_bserrno == 0);
2040 		CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2041 		blobid[i] = g_blobid;
2042 
2043 		/* Open a blob */
2044 		spdk_bs_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL);
2045 		CU_ASSERT(g_bserrno == 0);
2046 		CU_ASSERT(g_blob != NULL);
2047 		blob[i] = g_blob;
2048 
2049 		/* Set a fairly large xattr on both blobs to eat up
2050 		 * metadata space
2051 		 */
2052 		value = calloc(dev->blocklen - 64, sizeof(char));
2053 		SPDK_CU_ASSERT_FATAL(value != NULL);
2054 		memset(value, i, dev->blocklen / 2);
2055 		rc = spdk_blob_set_xattr(blob[i], "name", value, dev->blocklen - 64);
2056 		CU_ASSERT(rc == 0);
2057 		free(value);
2058 	}
2059 
2060 	/* Resize the blobs, alternating 1 cluster at a time.
2061 	 * This thwarts run length encoding and will cause spill
2062 	 * over of the extents.
2063 	 */
2064 	for (i = 0; i < 6; i++) {
2065 		rc = spdk_blob_resize(blob[i % 2], (i / 2) + 1);
2066 		CU_ASSERT(rc == 0);
2067 	}
2068 
2069 	for (i = 0; i < 2; i++) {
2070 		spdk_blob_sync_md(blob[i], blob_op_complete, NULL);
2071 		CU_ASSERT(g_bserrno == 0);
2072 	}
2073 
2074 	/* Close the blobs */
2075 	for (i = 0; i < 2; i++) {
2076 		spdk_blob_close(blob[i], blob_op_complete, NULL);
2077 		CU_ASSERT(g_bserrno == 0);
2078 	}
2079 
2080 	/* Unload the blobstore */
2081 	spdk_bs_unload(bs, bs_op_complete, NULL);
2082 	CU_ASSERT(g_bserrno == 0);
2083 	g_bs = NULL;
2084 	g_blob = NULL;
2085 	g_blobid = 0;
2086 	bs = NULL;
2087 
2088 	dev = init_dev();
2089 	/* Load an existing blob store */
2090 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2091 	CU_ASSERT(g_bserrno == 0);
2092 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2093 	bs = g_bs;
2094 
2095 	for (i = 0; i < 2; i++) {
2096 		blob[i] = NULL;
2097 
2098 		spdk_bs_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL);
2099 		CU_ASSERT(g_bserrno == 0);
2100 		CU_ASSERT(g_blob != NULL);
2101 		blob[i] = g_blob;
2102 
2103 		CU_ASSERT(spdk_blob_get_num_clusters(blob[i]) == 3);
2104 
2105 		spdk_blob_close(blob[i], blob_op_complete, NULL);
2106 		CU_ASSERT(g_bserrno == 0);
2107 	}
2108 
2109 	spdk_bs_unload(bs, bs_op_complete, NULL);
2110 	CU_ASSERT(g_bserrno == 0);
2111 	g_bs = NULL;
2112 }
2113 
2114 static void
2115 blob_crc(void)
2116 {
2117 	struct spdk_blob_store *bs;
2118 	struct spdk_bs_dev *dev;
2119 	struct spdk_blob *blob;
2120 	spdk_blob_id blobid;
2121 	uint32_t page_num;
2122 	int index;
2123 	struct spdk_blob_md_page *page;
2124 
2125 	dev = init_dev();
2126 
2127 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
2128 	CU_ASSERT(g_bserrno == 0);
2129 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2130 	bs = g_bs;
2131 
2132 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
2133 	CU_ASSERT(g_bserrno == 0);
2134 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2135 	blobid = g_blobid;
2136 
2137 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
2138 	CU_ASSERT(g_bserrno == 0);
2139 	CU_ASSERT(g_blob != NULL);
2140 	blob = g_blob;
2141 
2142 	spdk_blob_close(blob, blob_op_complete, NULL);
2143 	CU_ASSERT(g_bserrno == 0);
2144 
2145 	page_num = _spdk_bs_blobid_to_page(blobid);
2146 	index = DEV_BUFFER_BLOCKLEN * (bs->md_start + page_num);
2147 	page = (struct spdk_blob_md_page *)&g_dev_buffer[index];
2148 	page->crc = 0;
2149 
2150 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
2151 	CU_ASSERT(g_bserrno == -EINVAL);
2152 	CU_ASSERT(g_blob == NULL);
2153 	g_bserrno = 0;
2154 
2155 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
2156 	CU_ASSERT(g_bserrno == -EINVAL);
2157 
2158 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2159 	CU_ASSERT(g_bserrno == 0);
2160 	g_bs = NULL;
2161 }
2162 
2163 static void
2164 super_block_crc(void)
2165 {
2166 	struct spdk_bs_dev *dev;
2167 	struct spdk_bs_super_block *super_block;
2168 	struct spdk_bs_opts opts;
2169 
2170 	dev = init_dev();
2171 	spdk_bs_opts_init(&opts);
2172 
2173 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
2174 	CU_ASSERT(g_bserrno == 0);
2175 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2176 
2177 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2178 	CU_ASSERT(g_bserrno == 0);
2179 	g_bs = NULL;
2180 
2181 	super_block = (struct spdk_bs_super_block *)g_dev_buffer;
2182 	super_block->crc = 0;
2183 	dev = init_dev();
2184 
2185 	/* Load an existing blob store */
2186 	g_bserrno = 0;
2187 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2188 	CU_ASSERT(g_bserrno == -EILSEQ);
2189 }
2190 
2191 /* For blob dirty shutdown test case we do the following sub-test cases:
2192  * 1 Initialize new blob store and create 1 super blob with some xattrs, then we
2193  *   dirty shutdown and reload the blob store and verify the xattrs.
2194  * 2 Resize the blob from 10 clusters to 20 clusters and then dirty shutdown,
2195  *   reload the blob store and verify the clusters number.
2196  * 3 Create the second blob and then dirty shutdown, reload the blob store
2197  *   and verify the second blob.
2198  * 4 Delete the second blob and then dirty shutdown, reload the blob store
2199  *   and verify the second blob is invalid.
2200  * 5 Create the second blob again and also create the third blob, modify the
2201  *   md of second blob which makes the md invalid, and then dirty shutdown,
2202  *   reload the blob store verify the second blob, it should invalid and also
2203  *   verify the third blob, it should correct.
2204  */
2205 static void
2206 blob_dirty_shutdown(void)
2207 {
2208 	int rc;
2209 	int index;
2210 	struct spdk_bs_dev *dev;
2211 	spdk_blob_id blobid1, blobid2, blobid3;
2212 	struct spdk_blob *blob;
2213 	uint64_t length;
2214 	uint64_t free_clusters;
2215 	const void *value;
2216 	size_t value_len;
2217 	uint32_t page_num;
2218 	struct spdk_blob_md_page *page;
2219 	struct spdk_bs_opts opts;
2220 
2221 	dev = init_dev();
2222 	spdk_bs_opts_init(&opts);
2223 	/* Initialize a new blob store */
2224 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
2225 	CU_ASSERT(g_bserrno == 0);
2226 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2227 
2228 	/* Create first blob */
2229 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
2230 	CU_ASSERT(g_bserrno == 0);
2231 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2232 	blobid1 = g_blobid;
2233 
2234 	spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL);
2235 	CU_ASSERT(g_bserrno == 0);
2236 	CU_ASSERT(g_blob != NULL);
2237 	blob = g_blob;
2238 
2239 	/* Set some xattrs */
2240 	rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1);
2241 	CU_ASSERT(rc == 0);
2242 
2243 	length = 2345;
2244 	rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
2245 	CU_ASSERT(rc == 0);
2246 
2247 	/* Resize the blob */
2248 	rc = spdk_blob_resize(blob, 10);
2249 	CU_ASSERT(rc == 0);
2250 
2251 	/* Set the blob as the super blob */
2252 	spdk_bs_set_super(g_bs, blobid1, blob_op_complete, NULL);
2253 	CU_ASSERT(g_bserrno == 0);
2254 
2255 	free_clusters = spdk_bs_free_cluster_count(g_bs);
2256 
2257 	spdk_blob_close(blob, blob_op_complete, NULL);
2258 	blob = NULL;
2259 	g_blob = NULL;
2260 	g_blobid = SPDK_BLOBID_INVALID;
2261 
2262 	/* Dirty shutdown */
2263 	_spdk_bs_free(g_bs);
2264 
2265 	/* reload blobstore */
2266 	dev = init_dev();
2267 	spdk_bs_opts_init(&opts);
2268 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2269 	CU_ASSERT(g_bserrno == 0);
2270 
2271 	/* Get the super blob */
2272 	spdk_bs_get_super(g_bs, blob_op_with_id_complete, NULL);
2273 	CU_ASSERT(g_bserrno == 0);
2274 	CU_ASSERT(blobid1 == g_blobid);
2275 
2276 	spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL);
2277 	CU_ASSERT(g_bserrno == 0);
2278 	CU_ASSERT(g_blob != NULL);
2279 	blob = g_blob;
2280 
2281 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs));
2282 
2283 	/* Get the xattrs */
2284 	value = NULL;
2285 	rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len);
2286 	CU_ASSERT(rc == 0);
2287 	SPDK_CU_ASSERT_FATAL(value != NULL);
2288 	CU_ASSERT(*(uint64_t *)value == length);
2289 	CU_ASSERT(value_len == 8);
2290 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10);
2291 
2292 	/* Resize the blob */
2293 	rc = spdk_blob_resize(blob, 20);
2294 	CU_ASSERT(rc == 0);
2295 
2296 	free_clusters = spdk_bs_free_cluster_count(g_bs);
2297 
2298 	spdk_blob_close(blob, blob_op_complete, NULL);
2299 	CU_ASSERT(g_bserrno == 0);
2300 	blob = NULL;
2301 	g_blob = NULL;
2302 	g_blobid = SPDK_BLOBID_INVALID;
2303 
2304 	/* Dirty shutdown */
2305 	_spdk_bs_free(g_bs);
2306 
2307 	/* reload the blobstore */
2308 	dev = init_dev();
2309 	spdk_bs_opts_init(&opts);
2310 	/* Load an existing blob store */
2311 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2312 	CU_ASSERT(g_bserrno == 0);
2313 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2314 	spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL);
2315 	CU_ASSERT(g_bserrno == 0);
2316 	CU_ASSERT(g_blob != NULL);
2317 	blob = g_blob;
2318 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 20);
2319 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs));
2320 
2321 	spdk_blob_close(blob, blob_op_complete, NULL);
2322 	CU_ASSERT(g_bserrno == 0);
2323 	blob = NULL;
2324 	g_blob = NULL;
2325 	g_blobid = SPDK_BLOBID_INVALID;
2326 
2327 	/* Create second blob */
2328 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
2329 	CU_ASSERT(g_bserrno == 0);
2330 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2331 	blobid2 = g_blobid;
2332 
2333 	spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL);
2334 	CU_ASSERT(g_bserrno == 0);
2335 	CU_ASSERT(g_blob != NULL);
2336 	blob = g_blob;
2337 
2338 	/* Set some xattrs */
2339 	rc = spdk_blob_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1);
2340 	CU_ASSERT(rc == 0);
2341 
2342 	length = 5432;
2343 	rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
2344 	CU_ASSERT(rc == 0);
2345 
2346 	/* Resize the blob */
2347 	rc = spdk_blob_resize(blob, 10);
2348 	CU_ASSERT(rc == 0);
2349 
2350 	free_clusters = spdk_bs_free_cluster_count(g_bs);
2351 
2352 	spdk_blob_close(blob, blob_op_complete, NULL);
2353 	blob = NULL;
2354 	g_blob = NULL;
2355 	g_blobid = SPDK_BLOBID_INVALID;
2356 
2357 	/* Dirty shutdown */
2358 	_spdk_bs_free(g_bs);
2359 
2360 	/* reload the blobstore */
2361 	dev = init_dev();
2362 	spdk_bs_opts_init(&opts);
2363 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2364 	CU_ASSERT(g_bserrno == 0);
2365 
2366 	spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL);
2367 	CU_ASSERT(g_bserrno == 0);
2368 	CU_ASSERT(g_blob != NULL);
2369 	blob = g_blob;
2370 
2371 	/* Get the xattrs */
2372 	value = NULL;
2373 	rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len);
2374 	CU_ASSERT(rc == 0);
2375 	SPDK_CU_ASSERT_FATAL(value != NULL);
2376 	CU_ASSERT(*(uint64_t *)value == length);
2377 	CU_ASSERT(value_len == 8);
2378 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10);
2379 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs));
2380 
2381 	spdk_blob_close(blob, blob_op_complete, NULL);
2382 	CU_ASSERT(g_bserrno == 0);
2383 	spdk_bs_delete_blob(g_bs, blobid2, blob_op_complete, NULL);
2384 	CU_ASSERT(g_bserrno == 0);
2385 
2386 	free_clusters = spdk_bs_free_cluster_count(g_bs);
2387 
2388 	/* Dirty shutdown */
2389 	_spdk_bs_free(g_bs);
2390 	/* reload the blobstore */
2391 	dev = init_dev();
2392 	spdk_bs_opts_init(&opts);
2393 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2394 	CU_ASSERT(g_bserrno == 0);
2395 
2396 	spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL);
2397 	CU_ASSERT(g_bserrno != 0);
2398 	CU_ASSERT(g_blob == NULL);
2399 
2400 	spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL);
2401 	CU_ASSERT(g_bserrno == 0);
2402 	CU_ASSERT(g_blob != NULL);
2403 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs));
2404 	spdk_blob_close(g_blob, blob_op_complete, NULL);
2405 	CU_ASSERT(g_bserrno == 0);
2406 
2407 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2408 	CU_ASSERT(g_bserrno == 0);
2409 	g_bs = NULL;
2410 
2411 	/* reload the blobstore */
2412 	dev = init_dev();
2413 	spdk_bs_opts_init(&opts);
2414 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2415 	CU_ASSERT(g_bserrno == 0);
2416 
2417 	/* Create second blob */
2418 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
2419 	CU_ASSERT(g_bserrno == 0);
2420 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2421 	blobid2 = g_blobid;
2422 
2423 	/* Create third blob */
2424 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
2425 	CU_ASSERT(g_bserrno == 0);
2426 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2427 	blobid3 = g_blobid;
2428 
2429 	spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL);
2430 	CU_ASSERT(g_bserrno == 0);
2431 	CU_ASSERT(g_blob != NULL);
2432 	blob = g_blob;
2433 
2434 	/* Set some xattrs for second blob */
2435 	rc = spdk_blob_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1);
2436 	CU_ASSERT(rc == 0);
2437 
2438 	length = 5432;
2439 	rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
2440 	CU_ASSERT(rc == 0);
2441 
2442 	spdk_blob_close(blob, blob_op_complete, NULL);
2443 	blob = NULL;
2444 	g_blob = NULL;
2445 	g_blobid = SPDK_BLOBID_INVALID;
2446 
2447 	spdk_bs_open_blob(g_bs, blobid3, blob_op_with_handle_complete, NULL);
2448 	CU_ASSERT(g_bserrno == 0);
2449 	CU_ASSERT(g_blob != NULL);
2450 	blob = g_blob;
2451 
2452 	/* Set some xattrs for third blob */
2453 	rc = spdk_blob_set_xattr(blob, "name", "log2.txt", strlen("log2.txt") + 1);
2454 	CU_ASSERT(rc == 0);
2455 
2456 	length = 5432;
2457 	rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
2458 	CU_ASSERT(rc == 0);
2459 
2460 	spdk_blob_close(blob, blob_op_complete, NULL);
2461 	blob = NULL;
2462 	g_blob = NULL;
2463 	g_blobid = SPDK_BLOBID_INVALID;
2464 
2465 	/* Mark second blob as invalid */
2466 	page_num = _spdk_bs_blobid_to_page(blobid2);
2467 
2468 	index = DEV_BUFFER_BLOCKLEN * (g_bs->md_start + page_num);
2469 	page = (struct spdk_blob_md_page *)&g_dev_buffer[index];
2470 	page->sequence_num = 1;
2471 	page->crc = _spdk_blob_md_page_calc_crc(page);
2472 
2473 	free_clusters = spdk_bs_free_cluster_count(g_bs);
2474 
2475 	/* Dirty shutdown */
2476 	_spdk_bs_free(g_bs);
2477 	/* reload the blobstore */
2478 	dev = init_dev();
2479 	spdk_bs_opts_init(&opts);
2480 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2481 	CU_ASSERT(g_bserrno == 0);
2482 
2483 	spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL);
2484 	CU_ASSERT(g_bserrno != 0);
2485 	CU_ASSERT(g_blob == NULL);
2486 
2487 	spdk_bs_open_blob(g_bs, blobid3, blob_op_with_handle_complete, NULL);
2488 	CU_ASSERT(g_bserrno == 0);
2489 	CU_ASSERT(g_blob != NULL);
2490 	blob = g_blob;
2491 
2492 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs));
2493 
2494 	spdk_blob_close(blob, blob_op_complete, NULL);
2495 	blob = NULL;
2496 	g_blob = NULL;
2497 	g_blobid = SPDK_BLOBID_INVALID;
2498 
2499 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2500 	CU_ASSERT(g_bserrno == 0);
2501 	g_bs = NULL;
2502 }
2503 
2504 static void
2505 blob_flags(void)
2506 {
2507 	struct spdk_bs_dev *dev;
2508 	spdk_blob_id blobid_invalid, blobid_data_ro, blobid_md_ro;
2509 	struct spdk_blob *blob_invalid, *blob_data_ro, *blob_md_ro;
2510 	struct spdk_bs_opts opts;
2511 	int rc;
2512 
2513 	dev = init_dev();
2514 	spdk_bs_opts_init(&opts);
2515 
2516 	/* Initialize a new blob store */
2517 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2518 	CU_ASSERT(g_bserrno == 0);
2519 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2520 
2521 	/* Create three blobs - one each for testing invalid, data_ro and md_ro flags. */
2522 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
2523 	CU_ASSERT(g_bserrno == 0);
2524 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2525 	blobid_invalid = g_blobid;
2526 
2527 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
2528 	CU_ASSERT(g_bserrno == 0);
2529 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2530 	blobid_data_ro = g_blobid;
2531 
2532 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
2533 	CU_ASSERT(g_bserrno == 0);
2534 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2535 	blobid_md_ro = g_blobid;
2536 
2537 	spdk_bs_open_blob(g_bs, blobid_invalid, blob_op_with_handle_complete, NULL);
2538 	CU_ASSERT(g_bserrno == 0);
2539 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
2540 	blob_invalid = g_blob;
2541 
2542 	spdk_bs_open_blob(g_bs, blobid_data_ro, blob_op_with_handle_complete, NULL);
2543 	CU_ASSERT(g_bserrno == 0);
2544 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
2545 	blob_data_ro = g_blob;
2546 
2547 	spdk_bs_open_blob(g_bs, blobid_md_ro, blob_op_with_handle_complete, NULL);
2548 	CU_ASSERT(g_bserrno == 0);
2549 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
2550 	blob_md_ro = g_blob;
2551 
2552 	/* Change the size of blob_data_ro to check if flags are serialized
2553 	 * when blob has non zero number of extents */
2554 	rc = spdk_blob_resize(blob_data_ro, 10);
2555 	CU_ASSERT(rc == 0);
2556 
2557 	/* Set the xattr to check if flags are serialized
2558 	 * when blob has non zero number of xattrs */
2559 	rc = spdk_blob_set_xattr(blob_md_ro, "name", "log.txt", strlen("log.txt") + 1);
2560 	CU_ASSERT(rc == 0);
2561 
2562 	blob_invalid->invalid_flags = (1ULL << 63);
2563 	blob_invalid->state = SPDK_BLOB_STATE_DIRTY;
2564 	blob_data_ro->data_ro_flags = (1ULL << 62);
2565 	blob_data_ro->state = SPDK_BLOB_STATE_DIRTY;
2566 	blob_md_ro->md_ro_flags = (1ULL << 61);
2567 	blob_md_ro->state = SPDK_BLOB_STATE_DIRTY;
2568 
2569 	g_bserrno = -1;
2570 	spdk_blob_sync_md(blob_invalid, blob_op_complete, NULL);
2571 	CU_ASSERT(g_bserrno == 0);
2572 	g_bserrno = -1;
2573 	spdk_blob_sync_md(blob_data_ro, blob_op_complete, NULL);
2574 	CU_ASSERT(g_bserrno == 0);
2575 	g_bserrno = -1;
2576 	spdk_blob_sync_md(blob_md_ro, blob_op_complete, NULL);
2577 	CU_ASSERT(g_bserrno == 0);
2578 
2579 	g_bserrno = -1;
2580 	spdk_blob_close(blob_invalid, blob_op_complete, NULL);
2581 	CU_ASSERT(g_bserrno == 0);
2582 	blob_invalid = NULL;
2583 	g_bserrno = -1;
2584 	spdk_blob_close(blob_data_ro, blob_op_complete, NULL);
2585 	CU_ASSERT(g_bserrno == 0);
2586 	blob_data_ro = NULL;
2587 	g_bserrno = -1;
2588 	spdk_blob_close(blob_md_ro, blob_op_complete, NULL);
2589 	CU_ASSERT(g_bserrno == 0);
2590 	blob_md_ro = NULL;
2591 
2592 	g_blob = NULL;
2593 	g_blobid = SPDK_BLOBID_INVALID;
2594 
2595 	/* Unload the blob store */
2596 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2597 	CU_ASSERT(g_bserrno == 0);
2598 	g_bs = NULL;
2599 
2600 	/* Load an existing blob store */
2601 	dev = init_dev();
2602 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2603 	CU_ASSERT(g_bserrno == 0);
2604 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2605 
2606 	g_blob = NULL;
2607 	g_bserrno = 0;
2608 	spdk_bs_open_blob(g_bs, blobid_invalid, blob_op_with_handle_complete, NULL);
2609 	CU_ASSERT(g_bserrno != 0);
2610 	CU_ASSERT(g_blob == NULL);
2611 
2612 	g_blob = NULL;
2613 	g_bserrno = -1;
2614 	spdk_bs_open_blob(g_bs, blobid_data_ro, blob_op_with_handle_complete, NULL);
2615 	CU_ASSERT(g_bserrno == 0);
2616 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
2617 	blob_data_ro = g_blob;
2618 	/* If an unknown data_ro flag was found, the blob should be marked both data and md read-only. */
2619 	CU_ASSERT(blob_data_ro->data_ro == true);
2620 	CU_ASSERT(blob_data_ro->md_ro == true);
2621 	CU_ASSERT(spdk_blob_get_num_clusters(blob_data_ro) == 10);
2622 
2623 	g_blob = NULL;
2624 	g_bserrno = -1;
2625 	spdk_bs_open_blob(g_bs, blobid_md_ro, blob_op_with_handle_complete, NULL);
2626 	CU_ASSERT(g_bserrno == 0);
2627 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
2628 	blob_md_ro = g_blob;
2629 	CU_ASSERT(blob_md_ro->data_ro == false);
2630 	CU_ASSERT(blob_md_ro->md_ro == true);
2631 
2632 	g_bserrno = -1;
2633 	spdk_blob_sync_md(blob_md_ro, blob_op_complete, NULL);
2634 	CU_ASSERT(g_bserrno == 0);
2635 
2636 	spdk_blob_close(blob_data_ro, blob_op_complete, NULL);
2637 	CU_ASSERT(g_bserrno == 0);
2638 	spdk_blob_close(blob_md_ro, blob_op_complete, NULL);
2639 	CU_ASSERT(g_bserrno == 0);
2640 
2641 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2642 	CU_ASSERT(g_bserrno == 0);
2643 }
2644 
2645 static void
2646 bs_version(void)
2647 {
2648 	struct spdk_bs_super_block *super;
2649 	struct spdk_bs_dev *dev;
2650 	struct spdk_bs_opts opts;
2651 	spdk_blob_id blobid;
2652 
2653 	dev = init_dev();
2654 	spdk_bs_opts_init(&opts);
2655 
2656 	/* Initialize a new blob store */
2657 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2658 	CU_ASSERT(g_bserrno == 0);
2659 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2660 
2661 	/* Unload the blob store */
2662 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2663 	CU_ASSERT(g_bserrno == 0);
2664 	g_bs = NULL;
2665 
2666 	/*
2667 	 * Change the bs version on disk.  This will allow us to
2668 	 *  test that the version does not get modified automatically
2669 	 *  when loading and unloading the blobstore.
2670 	 */
2671 	super = (struct spdk_bs_super_block *)&g_dev_buffer[0];
2672 	CU_ASSERT(super->version == SPDK_BS_VERSION);
2673 	CU_ASSERT(super->clean == 1);
2674 	super->version = 2;
2675 	/*
2676 	 * Version 2 metadata does not have a used blobid mask, so clear
2677 	 *  those fields in the super block and zero the corresponding
2678 	 *  region on "disk".  We will use this to ensure blob IDs are
2679 	 *  correctly reconstructed.
2680 	 */
2681 	memset(&g_dev_buffer[super->used_blobid_mask_start * SPDK_BS_PAGE_SIZE], 0,
2682 	       super->used_blobid_mask_len * SPDK_BS_PAGE_SIZE);
2683 	super->used_blobid_mask_start = 0;
2684 	super->used_blobid_mask_len = 0;
2685 	super->crc = _spdk_blob_md_page_calc_crc(super);
2686 
2687 	/* Load an existing blob store */
2688 	dev = init_dev();
2689 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2690 	CU_ASSERT(g_bserrno == 0);
2691 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2692 	CU_ASSERT(super->clean == 0);
2693 
2694 	/*
2695 	 * Create a blob - just to make sure that when we unload it
2696 	 *  results in writing the super block (since metadata pages
2697 	 *  were allocated.
2698 	 */
2699 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
2700 	CU_ASSERT(g_bserrno == 0);
2701 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2702 	blobid = g_blobid;
2703 
2704 	/* Unload the blob store */
2705 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2706 	CU_ASSERT(g_bserrno == 0);
2707 	g_bs = NULL;
2708 	CU_ASSERT(super->version == 2);
2709 	CU_ASSERT(super->used_blobid_mask_start == 0);
2710 	CU_ASSERT(super->used_blobid_mask_len == 0);
2711 
2712 	dev = init_dev();
2713 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2714 	CU_ASSERT(g_bserrno == 0);
2715 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2716 
2717 	g_blob = NULL;
2718 	spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
2719 	CU_ASSERT(g_bserrno == 0);
2720 	CU_ASSERT(g_blob != NULL);
2721 
2722 	spdk_blob_close(g_blob, blob_op_complete, NULL);
2723 	CU_ASSERT(g_bserrno == 0);
2724 
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 
2733 static void
2734 blob_set_xattrs(void)
2735 {
2736 	struct spdk_blob_store *bs;
2737 	struct spdk_bs_dev *dev;
2738 	struct spdk_blob *blob;
2739 	struct spdk_blob_opts opts;
2740 	spdk_blob_id blobid;
2741 	const void *value;
2742 	size_t value_len;
2743 	int rc;
2744 
2745 	dev = init_dev();
2746 
2747 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
2748 	CU_ASSERT(g_bserrno == 0);
2749 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2750 	bs = g_bs;
2751 
2752 	/* Create blob with extra attributes */
2753 	spdk_blob_opts_init(&opts);
2754 
2755 	opts.xattrs.names = g_xattr_names;
2756 	opts.xattrs.get_value = _get_xattr_value;
2757 	opts.xattrs.count = 3;
2758 	opts.xattrs.ctx = &g_ctx;
2759 
2760 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
2761 	CU_ASSERT(g_bserrno == 0);
2762 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2763 	blobid = g_blobid;
2764 
2765 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
2766 	CU_ASSERT(g_bserrno == 0);
2767 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
2768 	blob = g_blob;
2769 
2770 	/* Get the xattrs */
2771 	value = NULL;
2772 
2773 	rc = spdk_blob_get_xattr_value(blob, g_xattr_names[0], &value, &value_len);
2774 	CU_ASSERT(rc == 0);
2775 	SPDK_CU_ASSERT_FATAL(value != NULL);
2776 	CU_ASSERT(value_len == strlen(g_xattr_values[0]));
2777 	CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len);
2778 
2779 	rc = spdk_blob_get_xattr_value(blob, g_xattr_names[1], &value, &value_len);
2780 	CU_ASSERT(rc == 0);
2781 	SPDK_CU_ASSERT_FATAL(value != NULL);
2782 	CU_ASSERT(value_len == strlen(g_xattr_values[1]));
2783 	CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len);
2784 
2785 	rc = spdk_blob_get_xattr_value(blob, g_xattr_names[2], &value, &value_len);
2786 	CU_ASSERT(rc == 0);
2787 	SPDK_CU_ASSERT_FATAL(value != NULL);
2788 	CU_ASSERT(value_len == strlen(g_xattr_values[2]));
2789 	CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len);
2790 
2791 	/* Try to get non existing attribute */
2792 
2793 	rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len);
2794 	CU_ASSERT(rc == -ENOENT);
2795 
2796 	spdk_blob_close(blob, blob_op_complete, NULL);
2797 	CU_ASSERT(g_bserrno == 0);
2798 	blob = NULL;
2799 	g_blob = NULL;
2800 	g_blobid = SPDK_BLOBID_INVALID;
2801 
2802 	/* NULL callback */
2803 	spdk_blob_opts_init(&opts);
2804 	opts.xattrs.names = g_xattr_names;
2805 	opts.xattrs.get_value = NULL;
2806 	opts.xattrs.count = 1;
2807 	opts.xattrs.ctx = &g_ctx;
2808 
2809 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
2810 	CU_ASSERT(g_bserrno == -EINVAL);
2811 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2812 
2813 	/* NULL values */
2814 	spdk_blob_opts_init(&opts);
2815 	opts.xattrs.names = g_xattr_names;
2816 	opts.xattrs.get_value = _get_xattr_value_null;
2817 	opts.xattrs.count = 1;
2818 	opts.xattrs.ctx = NULL;
2819 
2820 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
2821 	CU_ASSERT(g_bserrno == -EINVAL);
2822 
2823 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2824 	CU_ASSERT(g_bserrno == 0);
2825 	g_bs = NULL;
2826 
2827 }
2828 
2829 static void
2830 blob_thin_prov_alloc(void)
2831 {
2832 	struct spdk_blob_store *bs;
2833 	struct spdk_bs_dev *dev;
2834 	struct spdk_blob *blob;
2835 	struct spdk_blob_opts opts;
2836 	spdk_blob_id blobid;
2837 	uint64_t free_clusters;
2838 	int rc;
2839 
2840 	dev = init_dev();
2841 
2842 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
2843 	CU_ASSERT(g_bserrno == 0);
2844 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2845 	bs = g_bs;
2846 	free_clusters = spdk_bs_free_cluster_count(bs);
2847 
2848 	/* Set blob as thin provisioned */
2849 	spdk_blob_opts_init(&opts);
2850 	opts.thin_provision = true;
2851 
2852 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
2853 	CU_ASSERT(g_bserrno == 0);
2854 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2855 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
2856 	blobid = g_blobid;
2857 
2858 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
2859 	CU_ASSERT(g_bserrno == 0);
2860 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
2861 	blob = g_blob;
2862 
2863 	CU_ASSERT(blob->active.num_clusters == 0);
2864 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0);
2865 
2866 	/* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */
2867 	rc = spdk_blob_resize(blob, 5);
2868 	CU_ASSERT(rc == 0);
2869 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
2870 	CU_ASSERT(blob->active.num_clusters == 5);
2871 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5);
2872 
2873 	/* Shrink the blob to 3 clusters - still unallocated */
2874 	rc = spdk_blob_resize(blob, 3);
2875 	CU_ASSERT(rc == 0);
2876 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
2877 	CU_ASSERT(blob->active.num_clusters == 3);
2878 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 3);
2879 
2880 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
2881 	CU_ASSERT(g_bserrno == 0);
2882 	/* Sync must not change anything */
2883 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
2884 	CU_ASSERT(blob->active.num_clusters == 3);
2885 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 3);
2886 
2887 	spdk_blob_close(blob, blob_op_complete, NULL);
2888 	CU_ASSERT(g_bserrno == 0);
2889 
2890 	/* Unload the blob store */
2891 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2892 	CU_ASSERT(g_bserrno == 0);
2893 	g_bs = NULL;
2894 	g_blob = NULL;
2895 	g_blobid = 0;
2896 
2897 	/* Load an existing blob store */
2898 	dev = init_dev();
2899 	spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL);
2900 	CU_ASSERT(g_bserrno == 0);
2901 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2902 
2903 	bs = g_bs;
2904 
2905 	spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
2906 	CU_ASSERT(g_bserrno == 0);
2907 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
2908 	blob = g_blob;
2909 
2910 	/* Check that clusters allocation and size is still the same */
2911 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
2912 	CU_ASSERT(blob->active.num_clusters == 3);
2913 
2914 	spdk_blob_close(blob, blob_op_complete, NULL);
2915 	CU_ASSERT(g_bserrno == 0);
2916 
2917 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
2918 	CU_ASSERT(g_bserrno == 0);
2919 
2920 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2921 	CU_ASSERT(g_bserrno == 0);
2922 	g_bs = NULL;
2923 }
2924 
2925 static void
2926 blob_insert_cluster_msg(void)
2927 {
2928 	struct spdk_blob_store *bs;
2929 	struct spdk_bs_dev *dev;
2930 	struct spdk_blob *blob;
2931 	struct spdk_blob_opts opts;
2932 	spdk_blob_id blobid;
2933 	uint64_t free_clusters;
2934 
2935 	dev = init_dev();
2936 
2937 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
2938 	CU_ASSERT(g_bserrno == 0);
2939 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2940 	bs = g_bs;
2941 	free_clusters = spdk_bs_free_cluster_count(bs);
2942 
2943 	/* Set blob as thin provisioned */
2944 	spdk_blob_opts_init(&opts);
2945 	opts.thin_provision = true;
2946 	opts.num_clusters = 4;
2947 
2948 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
2949 	CU_ASSERT(g_bserrno == 0);
2950 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2951 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
2952 	blobid = g_blobid;
2953 
2954 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
2955 	CU_ASSERT(g_bserrno == 0);
2956 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
2957 	blob = g_blob;
2958 
2959 	CU_ASSERT(blob->active.num_clusters == 4);
2960 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 4);
2961 	CU_ASSERT(blob->active.clusters[1] == 0);
2962 
2963 	_spdk_bs_claim_cluster(bs, 0xF);
2964 	_spdk_blob_insert_cluster_on_md_thread(blob, 1, 0xF, blob_op_complete, NULL);
2965 
2966 	CU_ASSERT(blob->active.clusters[1] != 0);
2967 
2968 	spdk_blob_close(blob, blob_op_complete, NULL);
2969 	CU_ASSERT(g_bserrno == 0);
2970 
2971 	/* Unload the blob store */
2972 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2973 	CU_ASSERT(g_bserrno == 0);
2974 	g_bs = NULL;
2975 	g_blob = NULL;
2976 	g_blobid = 0;
2977 
2978 	/* Load an existing blob store */
2979 	dev = init_dev();
2980 	spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL);
2981 	CU_ASSERT(g_bserrno == 0);
2982 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2983 
2984 	bs = g_bs;
2985 
2986 	spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
2987 	CU_ASSERT(g_bserrno == 0);
2988 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
2989 	blob = g_blob;
2990 
2991 	CU_ASSERT(blob->active.clusters[1] != 0);
2992 
2993 	spdk_blob_close(blob, blob_op_complete, NULL);
2994 	CU_ASSERT(g_bserrno == 0);
2995 
2996 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
2997 	CU_ASSERT(g_bserrno == 0);
2998 
2999 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3000 	CU_ASSERT(g_bserrno == 0);
3001 	g_bs = NULL;
3002 }
3003 
3004 static void
3005 blob_thin_prov_rw(void)
3006 {
3007 	static const uint8_t zero[10 * 4096] = { 0 };
3008 	struct spdk_blob_store *bs;
3009 	struct spdk_bs_dev *dev;
3010 	struct spdk_blob *blob;
3011 	struct spdk_io_channel *channel;
3012 	struct spdk_blob_opts opts;
3013 	spdk_blob_id blobid;
3014 	uint64_t free_clusters;
3015 	uint8_t payload_read[10 * 4096];
3016 	uint8_t payload_write[10 * 4096];
3017 	int rc;
3018 
3019 	dev = init_dev();
3020 
3021 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
3022 	CU_ASSERT(g_bserrno == 0);
3023 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3024 	bs = g_bs;
3025 	free_clusters = spdk_bs_free_cluster_count(bs);
3026 
3027 	channel = spdk_bs_alloc_io_channel(bs);
3028 	CU_ASSERT(channel != NULL);
3029 
3030 	spdk_blob_opts_init(&opts);
3031 	opts.thin_provision = true;
3032 
3033 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
3034 	CU_ASSERT(g_bserrno == 0);
3035 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3036 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3037 	blobid = g_blobid;
3038 
3039 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
3040 	CU_ASSERT(g_bserrno == 0);
3041 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3042 	blob = g_blob;
3043 
3044 	CU_ASSERT(blob->active.num_clusters == 0);
3045 
3046 	/* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */
3047 	rc = spdk_blob_resize(blob, 5);
3048 	CU_ASSERT(rc == 0);
3049 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3050 	CU_ASSERT(blob->active.num_clusters == 5);
3051 
3052 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
3053 	CU_ASSERT(g_bserrno == 0);
3054 	/* Sync must not change anything */
3055 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3056 	CU_ASSERT(blob->active.num_clusters == 5);
3057 
3058 	/* Payload should be all zeros from unallocated clusters */
3059 	memset(payload_read, 0xFF, sizeof(payload_read));
3060 	spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL);
3061 	CU_ASSERT(g_bserrno == 0);
3062 	CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0);
3063 
3064 	memset(payload_write, 0xE5, sizeof(payload_write));
3065 	spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL);
3066 	CU_ASSERT(g_bserrno == 0);
3067 	CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs));
3068 
3069 	spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL);
3070 	CU_ASSERT(g_bserrno == 0);
3071 	CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0);
3072 
3073 	spdk_blob_close(blob, blob_op_complete, NULL);
3074 	CU_ASSERT(g_bserrno == 0);
3075 
3076 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
3077 	CU_ASSERT(g_bserrno == 0);
3078 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3079 
3080 	spdk_bs_free_io_channel(channel);
3081 
3082 	/* Unload the blob store */
3083 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3084 	CU_ASSERT(g_bserrno == 0);
3085 	g_bs = NULL;
3086 	g_blob = NULL;
3087 	g_blobid = 0;
3088 }
3089 
3090 static void
3091 blob_thin_prov_rw_iov(void)
3092 {
3093 	static const uint8_t zero[10 * 4096] = { 0 };
3094 	struct spdk_blob_store *bs;
3095 	struct spdk_bs_dev *dev;
3096 	struct spdk_blob *blob;
3097 	struct spdk_io_channel *channel;
3098 	struct spdk_blob_opts opts;
3099 	spdk_blob_id blobid;
3100 	uint64_t free_clusters;
3101 	uint8_t payload_read[10 * 4096];
3102 	uint8_t payload_write[10 * 4096];
3103 	struct iovec iov_read[3];
3104 	struct iovec iov_write[3];
3105 
3106 	int rc;
3107 
3108 	dev = init_dev();
3109 
3110 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
3111 	CU_ASSERT(g_bserrno == 0);
3112 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3113 	bs = g_bs;
3114 	free_clusters = spdk_bs_free_cluster_count(bs);
3115 
3116 	channel = spdk_bs_alloc_io_channel(bs);
3117 	CU_ASSERT(channel != NULL);
3118 
3119 	spdk_blob_opts_init(&opts);
3120 	opts.thin_provision = true;
3121 
3122 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
3123 	CU_ASSERT(g_bserrno == 0);
3124 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3125 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3126 	blobid = g_blobid;
3127 
3128 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
3129 	CU_ASSERT(g_bserrno == 0);
3130 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3131 	blob = g_blob;
3132 
3133 	CU_ASSERT(blob->active.num_clusters == 0);
3134 
3135 	/* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */
3136 	rc = spdk_blob_resize(blob, 5);
3137 	CU_ASSERT(rc == 0);
3138 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3139 	CU_ASSERT(blob->active.num_clusters == 5);
3140 
3141 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
3142 	CU_ASSERT(g_bserrno == 0);
3143 	/* Sync must not change anything */
3144 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3145 	CU_ASSERT(blob->active.num_clusters == 5);
3146 
3147 	/* Payload should be all zeros from unallocated clusters */
3148 	memset(payload_read, 0xAA, sizeof(payload_read));
3149 	iov_read[0].iov_base = payload_read;
3150 	iov_read[0].iov_len = 3 * 4096;
3151 	iov_read[1].iov_base = payload_read + 3 * 4096;
3152 	iov_read[1].iov_len = 4 * 4096;
3153 	iov_read[2].iov_base = payload_read + 7 * 4096;
3154 	iov_read[2].iov_len = 3 * 4096;
3155 	spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL);
3156 	CU_ASSERT(g_bserrno == 0);
3157 	CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0);
3158 
3159 	memset(payload_write, 0xE5, sizeof(payload_write));
3160 	iov_write[0].iov_base = payload_write;
3161 	iov_write[0].iov_len = 1 * 4096;
3162 	iov_write[1].iov_base = payload_write + 1 * 4096;
3163 	iov_write[1].iov_len = 5 * 4096;
3164 	iov_write[2].iov_base = payload_write + 6 * 4096;
3165 	iov_write[2].iov_len = 4 * 4096;
3166 
3167 	spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL);
3168 	CU_ASSERT(g_bserrno == 0);
3169 
3170 	memset(payload_read, 0xAA, sizeof(payload_read));
3171 	iov_read[0].iov_base = payload_read;
3172 	iov_read[0].iov_len = 3 * 4096;
3173 	iov_read[1].iov_base = payload_read + 3 * 4096;
3174 	iov_read[1].iov_len = 4 * 4096;
3175 	iov_read[2].iov_base = payload_read + 7 * 4096;
3176 	iov_read[2].iov_len = 3 * 4096;
3177 	spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL);
3178 	CU_ASSERT(g_bserrno == 0);
3179 	CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0);
3180 
3181 	spdk_blob_close(blob, blob_op_complete, NULL);
3182 	CU_ASSERT(g_bserrno == 0);
3183 
3184 	spdk_bs_free_io_channel(channel);
3185 
3186 	/* Unload the blob store */
3187 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3188 	CU_ASSERT(g_bserrno == 0);
3189 	g_bs = NULL;
3190 	g_blob = NULL;
3191 	g_blobid = 0;
3192 }
3193 
3194 struct iter_ctx {
3195 	int		current_iter;
3196 	spdk_blob_id	blobid[4];
3197 };
3198 
3199 static void
3200 test_iter(void *arg, struct spdk_blob *blob, int bserrno)
3201 {
3202 	struct iter_ctx *iter_ctx = arg;
3203 	spdk_blob_id blobid;
3204 
3205 	CU_ASSERT(bserrno == 0);
3206 	blobid = spdk_blob_get_id(blob);
3207 	CU_ASSERT(blobid == iter_ctx->blobid[iter_ctx->current_iter++]);
3208 }
3209 
3210 static void
3211 bs_load_iter(void)
3212 {
3213 	struct spdk_bs_dev *dev;
3214 	struct iter_ctx iter_ctx = { 0 };
3215 	struct spdk_blob *blob;
3216 	int i, rc;
3217 	struct spdk_bs_opts opts;
3218 
3219 	dev = init_dev();
3220 	spdk_bs_opts_init(&opts);
3221 	strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH);
3222 
3223 	/* Initialize a new blob store */
3224 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
3225 	CU_ASSERT(g_bserrno == 0);
3226 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3227 
3228 	for (i = 0; i < 4; i++) {
3229 		g_bserrno = -1;
3230 		g_blobid = SPDK_BLOBID_INVALID;
3231 		spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
3232 		CU_ASSERT(g_bserrno == 0);
3233 		CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3234 		iter_ctx.blobid[i] = g_blobid;
3235 
3236 		g_bserrno = -1;
3237 		g_blob = NULL;
3238 		spdk_bs_open_blob(g_bs, g_blobid, blob_op_with_handle_complete, NULL);
3239 		CU_ASSERT(g_bserrno == 0);
3240 		CU_ASSERT(g_blob != NULL);
3241 		blob = g_blob;
3242 
3243 		/* Just save the blobid as an xattr for testing purposes. */
3244 		rc = spdk_blob_set_xattr(blob, "blobid", &g_blobid, sizeof(g_blobid));
3245 		CU_ASSERT(rc == 0);
3246 
3247 		/* Resize the blob */
3248 		rc = spdk_blob_resize(blob, i);
3249 		CU_ASSERT(rc == 0);
3250 
3251 		spdk_blob_close(blob, blob_op_complete, NULL);
3252 		CU_ASSERT(g_bserrno == 0);
3253 	}
3254 
3255 	g_bserrno = -1;
3256 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3257 	CU_ASSERT(g_bserrno == 0);
3258 
3259 	dev = init_dev();
3260 	spdk_bs_opts_init(&opts);
3261 	strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH);
3262 	opts.iter_cb_fn = test_iter;
3263 	opts.iter_cb_arg = &iter_ctx;
3264 
3265 	/* Test blob iteration during load after a clean shutdown. */
3266 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
3267 	CU_ASSERT(g_bserrno == 0);
3268 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3269 
3270 	/* Dirty shutdown */
3271 	_spdk_bs_free(g_bs);
3272 
3273 	dev = init_dev();
3274 	spdk_bs_opts_init(&opts);
3275 	strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH);
3276 	opts.iter_cb_fn = test_iter;
3277 	iter_ctx.current_iter = 0;
3278 	opts.iter_cb_arg = &iter_ctx;
3279 
3280 	/* Test blob iteration during load after a dirty shutdown. */
3281 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
3282 	CU_ASSERT(g_bserrno == 0);
3283 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3284 
3285 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3286 	CU_ASSERT(g_bserrno == 0);
3287 	g_bs = NULL;
3288 
3289 }
3290 
3291 int main(int argc, char **argv)
3292 {
3293 	CU_pSuite	suite = NULL;
3294 	unsigned int	num_failures;
3295 
3296 	if (CU_initialize_registry() != CUE_SUCCESS) {
3297 		return CU_get_error();
3298 	}
3299 
3300 	suite = CU_add_suite("blob", NULL, NULL);
3301 	if (suite == NULL) {
3302 		CU_cleanup_registry();
3303 		return CU_get_error();
3304 	}
3305 
3306 	if (
3307 		CU_add_test(suite, "blob_init", blob_init) == NULL ||
3308 		CU_add_test(suite, "blob_open", blob_open) == NULL ||
3309 		CU_add_test(suite, "blob_create", blob_create) == NULL ||
3310 		CU_add_test(suite, "blob_create_internal", blob_create_internal) == NULL ||
3311 		CU_add_test(suite, "blob_thin_provision", blob_thin_provision) == NULL ||
3312 		CU_add_test(suite, "blob_delete", blob_delete) == NULL ||
3313 		CU_add_test(suite, "blob_resize", blob_resize) == NULL ||
3314 		CU_add_test(suite, "blob_read_only", blob_read_only) == NULL ||
3315 		CU_add_test(suite, "channel_ops", channel_ops) == NULL ||
3316 		CU_add_test(suite, "blob_super", blob_super) == NULL ||
3317 		CU_add_test(suite, "blob_write", blob_write) == NULL ||
3318 		CU_add_test(suite, "blob_read", blob_read) == NULL ||
3319 		CU_add_test(suite, "blob_rw_verify", blob_rw_verify) == NULL ||
3320 		CU_add_test(suite, "blob_rw_verify_iov", blob_rw_verify_iov) == NULL ||
3321 		CU_add_test(suite, "blob_rw_verify_iov_nomem", blob_rw_verify_iov_nomem) == NULL ||
3322 		CU_add_test(suite, "blob_rw_iov_read_only", blob_rw_iov_read_only) == NULL ||
3323 		CU_add_test(suite, "blob_unmap", blob_unmap) == NULL ||
3324 		CU_add_test(suite, "blob_iter", blob_iter) == NULL ||
3325 		CU_add_test(suite, "blob_xattr", blob_xattr) == NULL ||
3326 		CU_add_test(suite, "bs_load", bs_load) == NULL ||
3327 		CU_add_test(suite, "bs_unload", bs_unload) == NULL ||
3328 		CU_add_test(suite, "bs_cluster_sz", bs_cluster_sz) == NULL ||
3329 		CU_add_test(suite, "bs_usable_clusters", bs_usable_clusters) == NULL ||
3330 		CU_add_test(suite, "bs_resize_md", bs_resize_md) == NULL ||
3331 		CU_add_test(suite, "bs_destroy", bs_destroy) == NULL ||
3332 		CU_add_test(suite, "bs_type", bs_type) == NULL ||
3333 		CU_add_test(suite, "bs_super_block", bs_super_block) == NULL ||
3334 		CU_add_test(suite, "blob_serialize", blob_serialize) == NULL ||
3335 		CU_add_test(suite, "blob_crc", blob_crc) == NULL ||
3336 		CU_add_test(suite, "super_block_crc", super_block_crc) == NULL ||
3337 		CU_add_test(suite, "blob_dirty_shutdown", blob_dirty_shutdown) == NULL ||
3338 		CU_add_test(suite, "blob_flags", blob_flags) == NULL ||
3339 		CU_add_test(suite, "bs_version", bs_version) == NULL ||
3340 		CU_add_test(suite, "blob_set_xattrs", blob_set_xattrs) == NULL ||
3341 		CU_add_test(suite, "blob_thin_prov_alloc", blob_thin_prov_alloc) == NULL ||
3342 		CU_add_test(suite, "blob_insert_cluster_msg", blob_insert_cluster_msg) == NULL ||
3343 		CU_add_test(suite, "blob_thin_prov_rw", blob_thin_prov_rw) == NULL ||
3344 		CU_add_test(suite, "blob_thin_prov_rw_iov", blob_thin_prov_rw_iov) == NULL ||
3345 		CU_add_test(suite, "bs_load_iter", bs_load_iter) == NULL
3346 	) {
3347 		CU_cleanup_registry();
3348 		return CU_get_error();
3349 	}
3350 
3351 	g_dev_buffer = calloc(1, DEV_BUFFER_SIZE);
3352 	spdk_allocate_thread(_bs_send_msg, NULL, NULL, NULL, "thread0");
3353 	CU_basic_set_mode(CU_BRM_VERBOSE);
3354 	CU_basic_run_tests();
3355 	num_failures = CU_get_number_of_failures();
3356 	CU_cleanup_registry();
3357 	spdk_free_thread();
3358 	free(g_dev_buffer);
3359 	return num_failures;
3360 }
3361