xref: /spdk/test/unit/lib/blob/blob.c/blob_ut.c (revision a83f91c29a4740e4bea5f9509b7036e9e7dc2788)
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 #include "spdk/string.h"
39 
40 #include "common/lib/test_env.c"
41 #include "../bs_dev_common.c"
42 #include "blob/blobstore.c"
43 #include "blob/request.c"
44 #include "blob/zeroes.c"
45 #include "blob/blob_bs_dev.c"
46 
47 struct spdk_blob_store *g_bs;
48 spdk_blob_id g_blobid;
49 struct spdk_blob *g_blob;
50 int g_bserrno;
51 struct spdk_xattr_names *g_names;
52 int g_done;
53 char *g_xattr_names[] = {"first", "second", "third"};
54 char *g_xattr_values[] = {"one", "two", "three"};
55 uint64_t g_ctx = 1729;
56 
57 struct spdk_bs_super_block_ver1 {
58 	uint8_t		signature[8];
59 	uint32_t        version;
60 	uint32_t        length;
61 	uint32_t	clean; /* If there was a clean shutdown, this is 1. */
62 	spdk_blob_id	super_blob;
63 
64 	uint32_t	cluster_size; /* In bytes */
65 
66 	uint32_t	used_page_mask_start; /* Offset from beginning of disk, in pages */
67 	uint32_t	used_page_mask_len; /* Count, in pages */
68 
69 	uint32_t	used_cluster_mask_start; /* Offset from beginning of disk, in pages */
70 	uint32_t	used_cluster_mask_len; /* Count, in pages */
71 
72 	uint32_t	md_start; /* Offset from beginning of disk, in pages */
73 	uint32_t	md_len; /* Count, in pages */
74 
75 	uint8_t		reserved[4036];
76 	uint32_t	crc;
77 } __attribute__((packed));
78 SPDK_STATIC_ASSERT(sizeof(struct spdk_bs_super_block_ver1) == 0x1000, "Invalid super block size");
79 
80 
81 static void
82 _get_xattr_value(void *arg, const char *name,
83 		 const void **value, size_t *value_len)
84 {
85 	uint64_t i;
86 
87 	SPDK_CU_ASSERT_FATAL(value_len != NULL);
88 	SPDK_CU_ASSERT_FATAL(value != NULL);
89 	CU_ASSERT(arg == &g_ctx)
90 
91 	for (i = 0; i < sizeof(g_xattr_names); i++) {
92 		if (!strcmp(name, g_xattr_names[i])) {
93 			*value_len = strlen(g_xattr_values[i]);
94 			*value = g_xattr_values[i];
95 			break;
96 		}
97 	}
98 }
99 
100 static void
101 _get_xattr_value_null(void *arg, const char *name,
102 		      const void **value, size_t *value_len)
103 {
104 	SPDK_CU_ASSERT_FATAL(value_len != NULL);
105 	SPDK_CU_ASSERT_FATAL(value != NULL);
106 	CU_ASSERT(arg == NULL)
107 
108 	*value_len = 0;
109 	*value = NULL;
110 }
111 
112 
113 
114 static void
115 bs_op_complete(void *cb_arg, int bserrno)
116 {
117 	g_bserrno = bserrno;
118 }
119 
120 static void
121 bs_op_with_handle_complete(void *cb_arg, struct spdk_blob_store *bs,
122 			   int bserrno)
123 {
124 	g_bs = bs;
125 	g_bserrno = bserrno;
126 }
127 
128 static void
129 blob_op_complete(void *cb_arg, int bserrno)
130 {
131 	g_bserrno = bserrno;
132 }
133 
134 static void
135 blob_op_with_id_complete(void *cb_arg, spdk_blob_id blobid, int bserrno)
136 {
137 	g_blobid = blobid;
138 	g_bserrno = bserrno;
139 }
140 
141 static void
142 blob_op_with_handle_complete(void *cb_arg, struct spdk_blob *blb, int bserrno)
143 {
144 	g_blob = blb;
145 	g_bserrno = bserrno;
146 }
147 
148 static void
149 blob_init(void)
150 {
151 	struct spdk_bs_dev *dev;
152 
153 	dev = init_dev();
154 
155 	/* should fail for an unsupported blocklen */
156 	dev->blocklen = 500;
157 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
158 	CU_ASSERT(g_bserrno == -EINVAL);
159 
160 	dev = init_dev();
161 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
162 	CU_ASSERT(g_bserrno == 0);
163 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
164 
165 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
166 	CU_ASSERT(g_bserrno == 0);
167 	g_bs = NULL;
168 }
169 
170 static void
171 blob_super(void)
172 {
173 	struct spdk_blob_store *bs;
174 	struct spdk_bs_dev *dev;
175 	spdk_blob_id blobid;
176 
177 	dev = init_dev();
178 
179 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
180 	CU_ASSERT(g_bserrno == 0);
181 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
182 	bs = g_bs;
183 
184 	/* Get the super blob without having set one */
185 	spdk_bs_get_super(bs, blob_op_with_id_complete, NULL);
186 	CU_ASSERT(g_bserrno == -ENOENT);
187 	CU_ASSERT(g_blobid == SPDK_BLOBID_INVALID);
188 
189 	/* Create a blob */
190 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
191 	CU_ASSERT(g_bserrno == 0);
192 	CU_ASSERT(g_blobid !=  SPDK_BLOBID_INVALID);
193 	blobid = g_blobid;
194 
195 	/* Set the blob as the super blob */
196 	spdk_bs_set_super(bs, blobid, blob_op_complete, NULL);
197 	CU_ASSERT(g_bserrno == 0);
198 
199 	/* Get the super blob */
200 	spdk_bs_get_super(bs, blob_op_with_id_complete, NULL);
201 	CU_ASSERT(g_bserrno == 0);
202 	CU_ASSERT(blobid == g_blobid);
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_open(void)
211 {
212 	struct spdk_blob_store *bs;
213 	struct spdk_bs_dev *dev;
214 	struct spdk_blob *blob;
215 	spdk_blob_id blobid, blobid2;
216 
217 	dev = init_dev();
218 
219 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
220 	CU_ASSERT(g_bserrno == 0);
221 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
222 	bs = g_bs;
223 
224 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
225 	CU_ASSERT(g_bserrno == 0);
226 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
227 	blobid = g_blobid;
228 
229 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
230 	CU_ASSERT(g_bserrno == 0);
231 	CU_ASSERT(g_blob != NULL);
232 	blob = g_blob;
233 
234 	blobid2 = spdk_blob_get_id(blob);
235 	CU_ASSERT(blobid == blobid2);
236 
237 	/* Try to open file again.  It should return success. */
238 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
239 	CU_ASSERT(g_bserrno == 0);
240 	CU_ASSERT(blob == g_blob);
241 
242 	spdk_blob_close(blob, blob_op_complete, NULL);
243 	CU_ASSERT(g_bserrno == 0);
244 
245 	/*
246 	 * Close the file a second time, releasing the second reference.  This
247 	 *  should succeed.
248 	 */
249 	blob = g_blob;
250 	spdk_blob_close(blob, blob_op_complete, NULL);
251 	CU_ASSERT(g_bserrno == 0);
252 
253 	/*
254 	 * Try to open file again.  It should succeed.  This tests the case
255 	 *  where the file is opened, closed, then re-opened again.
256 	 */
257 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
258 	CU_ASSERT(g_bserrno == 0);
259 	CU_ASSERT(g_blob != NULL);
260 	blob = g_blob;
261 
262 	spdk_blob_close(blob, blob_op_complete, NULL);
263 	CU_ASSERT(g_bserrno == 0);
264 
265 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
266 	CU_ASSERT(g_bserrno == 0);
267 	g_bs = NULL;
268 }
269 
270 static void
271 blob_create(void)
272 {
273 	struct spdk_blob_store *bs;
274 	struct spdk_bs_dev *dev;
275 	struct spdk_blob *blob;
276 	struct spdk_blob_opts opts;
277 	spdk_blob_id blobid;
278 
279 	dev = init_dev();
280 
281 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
282 	CU_ASSERT(g_bserrno == 0);
283 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
284 	bs = g_bs;
285 
286 	/* Create blob with 10 clusters */
287 
288 	spdk_blob_opts_init(&opts);
289 	opts.num_clusters = 10;
290 
291 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
292 	CU_ASSERT(g_bserrno == 0);
293 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
294 	blobid = g_blobid;
295 
296 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
297 	CU_ASSERT(g_bserrno == 0);
298 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
299 	blob = g_blob;
300 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10)
301 
302 	spdk_blob_close(blob, blob_op_complete, NULL);
303 	CU_ASSERT(g_bserrno == 0);
304 
305 	/* Create blob with 0 clusters */
306 
307 	spdk_blob_opts_init(&opts);
308 	opts.num_clusters = 0;
309 
310 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
311 	CU_ASSERT(g_bserrno == 0);
312 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
313 	blobid = g_blobid;
314 
315 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
316 	CU_ASSERT(g_bserrno == 0);
317 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
318 	blob = g_blob;
319 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0)
320 
321 	spdk_blob_close(blob, blob_op_complete, NULL);
322 	CU_ASSERT(g_bserrno == 0);
323 
324 	/* Create blob with default options (opts == NULL) */
325 
326 	spdk_bs_create_blob_ext(bs, NULL, blob_op_with_id_complete, NULL);
327 	CU_ASSERT(g_bserrno == 0);
328 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
329 	blobid = g_blobid;
330 
331 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
332 	CU_ASSERT(g_bserrno == 0);
333 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
334 	blob = g_blob;
335 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0)
336 
337 	spdk_blob_close(blob, blob_op_complete, NULL);
338 	CU_ASSERT(g_bserrno == 0);
339 
340 	/* Try to create blob with size larger than blobstore */
341 
342 	spdk_blob_opts_init(&opts);
343 	opts.num_clusters = bs->total_clusters + 1;
344 
345 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
346 	CU_ASSERT(g_bserrno == -ENOSPC);
347 
348 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
349 	CU_ASSERT(g_bserrno == 0);
350 	g_bs = NULL;
351 
352 }
353 
354 static void
355 blob_create_internal(void)
356 {
357 	struct spdk_blob_store *bs;
358 	struct spdk_bs_dev *dev;
359 	struct spdk_blob *blob;
360 	struct spdk_blob_opts opts;
361 	struct spdk_blob_xattr_opts internal_xattrs;
362 	const void *value;
363 	size_t value_len;
364 	spdk_blob_id blobid;
365 	int rc;
366 
367 	dev = init_dev();
368 
369 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
370 	CU_ASSERT(g_bserrno == 0);
371 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
372 	bs = g_bs;
373 
374 	/* Create blob with custom xattrs */
375 
376 	spdk_blob_opts_init(&opts);
377 	_spdk_blob_xattrs_init(&internal_xattrs);
378 	internal_xattrs.count = 3;
379 	internal_xattrs.names = g_xattr_names;
380 	internal_xattrs.get_value = _get_xattr_value;
381 	internal_xattrs.ctx = &g_ctx;
382 
383 	_spdk_bs_create_blob(bs, &opts, &internal_xattrs, blob_op_with_id_complete, NULL);
384 	CU_ASSERT(g_bserrno == 0);
385 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
386 	blobid = g_blobid;
387 
388 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
389 	CU_ASSERT(g_bserrno == 0);
390 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
391 	blob = g_blob;
392 
393 	rc = _spdk_blob_get_xattr_value(blob, g_xattr_names[0], &value, &value_len, true);
394 	CU_ASSERT(rc == 0);
395 	SPDK_CU_ASSERT_FATAL(value != NULL);
396 	CU_ASSERT(value_len == strlen(g_xattr_values[0]));
397 	CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len);
398 
399 	rc = _spdk_blob_get_xattr_value(blob, g_xattr_names[1], &value, &value_len, true);
400 	CU_ASSERT(rc == 0);
401 	SPDK_CU_ASSERT_FATAL(value != NULL);
402 	CU_ASSERT(value_len == strlen(g_xattr_values[1]));
403 	CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len);
404 
405 	rc = _spdk_blob_get_xattr_value(blob, g_xattr_names[2], &value, &value_len, true);
406 	CU_ASSERT(rc == 0);
407 	SPDK_CU_ASSERT_FATAL(value != NULL);
408 	CU_ASSERT(value_len == strlen(g_xattr_values[2]));
409 	CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len);
410 
411 	rc = spdk_blob_get_xattr_value(blob, g_xattr_names[0], &value, &value_len);
412 	CU_ASSERT(rc != 0);
413 
414 	rc = spdk_blob_get_xattr_value(blob, g_xattr_names[1], &value, &value_len);
415 	CU_ASSERT(rc != 0);
416 
417 	rc = spdk_blob_get_xattr_value(blob, g_xattr_names[2], &value, &value_len);
418 	CU_ASSERT(rc != 0);
419 
420 	spdk_blob_close(blob, blob_op_complete, NULL);
421 	CU_ASSERT(g_bserrno == 0);
422 
423 	/* Create blob with NULL internal options  */
424 
425 	_spdk_bs_create_blob(bs, NULL, NULL, blob_op_with_id_complete, NULL);
426 	CU_ASSERT(g_bserrno == 0);
427 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
428 	blobid = g_blobid;
429 
430 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
431 	CU_ASSERT(g_bserrno == 0);
432 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
433 	CU_ASSERT(TAILQ_FIRST(&g_blob->xattrs_internal) == NULL);
434 
435 	blob = g_blob;
436 
437 	spdk_blob_close(blob, blob_op_complete, NULL);
438 	CU_ASSERT(g_bserrno == 0);
439 
440 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
441 	CU_ASSERT(g_bserrno == 0);
442 	g_bs = NULL;
443 
444 }
445 
446 static void
447 blob_thin_provision(void)
448 {
449 	struct spdk_blob_store *bs;
450 	struct spdk_bs_dev *dev;
451 	struct spdk_blob *blob;
452 	struct spdk_blob_opts opts;
453 	struct spdk_bs_opts bs_opts;
454 	spdk_blob_id blobid;
455 
456 	dev = init_dev();
457 	spdk_bs_opts_init(&bs_opts);
458 	snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE");
459 
460 	/* Initialize a new blob store */
461 	spdk_bs_init(dev, &bs_opts, bs_op_with_handle_complete, NULL);
462 	CU_ASSERT(g_bserrno == 0);
463 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
464 
465 	bs = g_bs;
466 
467 	/* Create blob with thin provisioning enabled */
468 
469 	spdk_blob_opts_init(&opts);
470 	opts.thin_provision = true;
471 	opts.num_clusters = 10;
472 
473 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
474 	CU_ASSERT(g_bserrno == 0);
475 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
476 	blobid = g_blobid;
477 
478 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
479 	CU_ASSERT(g_bserrno == 0);
480 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
481 	blob = g_blob;
482 	CU_ASSERT(blob->invalid_flags & SPDK_BLOB_THIN_PROV);
483 
484 	spdk_blob_close(blob, blob_op_complete, NULL);
485 	CU_ASSERT(g_bserrno == 0);
486 
487 	/* Do not shut down cleanly.  This makes sure that when we load again
488 	 *  and try to recover a valid used_cluster map, that blobstore will
489 	 *  ignore clusters with index 0 since these are unallocated clusters.
490 	 */
491 
492 	/* Load an existing blob store and check if invalid_flags is set */
493 	dev = init_dev();
494 	snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE");
495 	spdk_bs_load(dev, &bs_opts, bs_op_with_handle_complete, NULL);
496 	CU_ASSERT(g_bserrno == 0);
497 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
498 
499 	bs = g_bs;
500 
501 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
502 	CU_ASSERT(g_bserrno == 0);
503 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
504 	blob = g_blob;
505 	CU_ASSERT(blob->invalid_flags & SPDK_BLOB_THIN_PROV);
506 
507 	spdk_blob_close(blob, blob_op_complete, NULL);
508 	CU_ASSERT(g_bserrno == 0);
509 
510 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
511 	CU_ASSERT(g_bserrno == 0);
512 	g_bs = NULL;
513 }
514 
515 static void
516 blob_snapshot(void)
517 {
518 	struct spdk_blob_store *bs;
519 	struct spdk_bs_dev *dev;
520 	struct spdk_blob *blob;
521 	struct spdk_blob *snapshot, *snapshot2;
522 	struct spdk_blob_bs_dev *blob_bs_dev;
523 	struct spdk_blob_opts opts;
524 	struct spdk_blob_xattr_opts xattrs;
525 	spdk_blob_id blobid;
526 	spdk_blob_id snapshotid;
527 	const void *value;
528 	size_t value_len;
529 	int rc;
530 
531 	dev = init_dev();
532 
533 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
534 	CU_ASSERT(g_bserrno == 0);
535 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
536 	bs = g_bs;
537 
538 	/* Create blob with 10 clusters */
539 	spdk_blob_opts_init(&opts);
540 	opts.num_clusters = 10;
541 
542 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
543 	CU_ASSERT(g_bserrno == 0);
544 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
545 	blobid = g_blobid;
546 
547 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
548 	CU_ASSERT(g_bserrno == 0);
549 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
550 	blob = g_blob;
551 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10)
552 
553 	/* Create snapshot from blob */
554 	spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL);
555 	CU_ASSERT(g_bserrno == 0);
556 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
557 	snapshotid = g_blobid;
558 
559 	spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL);
560 	CU_ASSERT(g_bserrno == 0);
561 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
562 	snapshot = g_blob;
563 	CU_ASSERT(snapshot->data_ro == true)
564 	CU_ASSERT(snapshot->md_ro == true)
565 	CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 10)
566 
567 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10)
568 	CU_ASSERT(blob->invalid_flags & SPDK_BLOB_THIN_PROV);
569 	CU_ASSERT(spdk_mem_all_zero(blob->active.clusters,
570 				    blob->active.num_clusters * sizeof(blob->active.clusters[0])));
571 
572 	/* Try to create snapshot from clone with xattrs */
573 	xattrs.names = g_xattr_names;
574 	xattrs.get_value = _get_xattr_value;
575 	xattrs.count = 3;
576 	xattrs.ctx = &g_ctx;
577 	spdk_bs_create_snapshot(bs, blobid, &xattrs, blob_op_with_id_complete, NULL);
578 	CU_ASSERT(g_bserrno == 0);
579 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
580 	blobid = g_blobid;
581 
582 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
583 	CU_ASSERT(g_bserrno == 0);
584 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
585 	snapshot2 = g_blob;
586 	CU_ASSERT(snapshot2->data_ro == true)
587 	CU_ASSERT(snapshot2->md_ro == true)
588 	CU_ASSERT(spdk_blob_get_num_clusters(snapshot2) == 10)
589 
590 	/* Confirm that blob is backed by snapshot2 and snapshot2 is backed by snapshot */
591 	CU_ASSERT(snapshot->back_bs_dev == NULL);
592 	SPDK_CU_ASSERT_FATAL(blob->back_bs_dev != NULL);
593 	SPDK_CU_ASSERT_FATAL(snapshot2->back_bs_dev != NULL);
594 
595 	blob_bs_dev = (struct spdk_blob_bs_dev *)blob->back_bs_dev;
596 	CU_ASSERT(blob_bs_dev->blob == snapshot2);
597 
598 	blob_bs_dev = (struct spdk_blob_bs_dev *)snapshot2->back_bs_dev;
599 	CU_ASSERT(blob_bs_dev->blob == snapshot);
600 
601 	rc = spdk_blob_get_xattr_value(snapshot2, g_xattr_names[0], &value, &value_len);
602 	CU_ASSERT(rc == 0);
603 	SPDK_CU_ASSERT_FATAL(value != NULL);
604 	CU_ASSERT(value_len == strlen(g_xattr_values[0]));
605 	CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len);
606 
607 	rc = spdk_blob_get_xattr_value(snapshot2, g_xattr_names[1], &value, &value_len);
608 	CU_ASSERT(rc == 0);
609 	SPDK_CU_ASSERT_FATAL(value != NULL);
610 	CU_ASSERT(value_len == strlen(g_xattr_values[1]));
611 	CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len);
612 
613 	rc = spdk_blob_get_xattr_value(snapshot2, g_xattr_names[2], &value, &value_len);
614 	CU_ASSERT(rc == 0);
615 	SPDK_CU_ASSERT_FATAL(value != NULL);
616 	CU_ASSERT(value_len == strlen(g_xattr_values[2]));
617 	CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len);
618 
619 	/* Try to create snapshot from snapshot */
620 	spdk_bs_create_snapshot(bs, snapshotid, NULL, blob_op_with_id_complete, NULL);
621 	CU_ASSERT(g_bserrno == -EINVAL);
622 	CU_ASSERT(g_blobid == SPDK_BLOBID_INVALID);
623 
624 	spdk_blob_close(blob, blob_op_complete, NULL);
625 	CU_ASSERT(g_bserrno == 0);
626 
627 	spdk_blob_close(snapshot, blob_op_complete, NULL);
628 	CU_ASSERT(g_bserrno == 0);
629 
630 	spdk_blob_close(snapshot2, blob_op_complete, NULL);
631 	CU_ASSERT(g_bserrno == 0);
632 
633 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
634 	CU_ASSERT(g_bserrno == 0);
635 	g_bs = NULL;
636 }
637 
638 static void
639 blob_snapshot_freeze_io(void)
640 {
641 	struct spdk_io_channel *channel;
642 	struct spdk_bs_channel *bs_channel;
643 	struct spdk_blob_store *bs;
644 	struct spdk_bs_dev *dev;
645 	struct spdk_blob *blob;
646 	struct spdk_blob_opts opts;
647 	spdk_blob_id blobid;
648 	uint32_t num_of_pages = 10;
649 	uint8_t payload_read[num_of_pages * SPDK_BS_PAGE_SIZE];
650 	uint8_t payload_write[num_of_pages * SPDK_BS_PAGE_SIZE];
651 	uint8_t payload_zero[num_of_pages * SPDK_BS_PAGE_SIZE];
652 
653 	memset(payload_write, 0xE5, sizeof(payload_write));
654 	memset(payload_read, 0x00, sizeof(payload_read));
655 	memset(payload_zero, 0x00, sizeof(payload_zero));
656 
657 	dev = init_dev();
658 	memset(g_dev_buffer, 0, DEV_BUFFER_SIZE);
659 
660 	/* Test freeze I/O during snapshot */
661 
662 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
663 	CU_ASSERT(g_bserrno == 0);
664 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
665 	bs = g_bs;
666 
667 	channel = spdk_bs_alloc_io_channel(bs);
668 	bs_channel = spdk_io_channel_get_ctx(channel);
669 
670 	/* Create blob with 10 clusters */
671 	spdk_blob_opts_init(&opts);
672 	opts.num_clusters = 10;
673 	opts.thin_provision = false;
674 
675 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
676 	CU_ASSERT(g_bserrno == 0);
677 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
678 	blobid = g_blobid;
679 
680 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
681 	CU_ASSERT(g_bserrno == 0);
682 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
683 	blob = g_blob;
684 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10);
685 
686 	/* Enable explicitly calling callbacks. On each read/write to back device
687 	 * execution will stop and wait until _bs_flush_scheduler is called */
688 	g_scheduler_delay = true;
689 
690 	spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL);
691 
692 	/* This is implementation specific.
693 	 * Flag 'frozen_io' is set in _spdk_bs_snapshot_freeze_cpl callback.
694 	 * Four async I/O operations happen before that. */
695 
696 	_bs_flush_scheduler(4);
697 
698 	CU_ASSERT(TAILQ_EMPTY(&bs_channel->queued_io));
699 
700 	/* Blob I/O should be frozen here */
701 	CU_ASSERT(blob->frozen_refcnt == 1);
702 
703 	/* Write to the blob */
704 	spdk_blob_io_write(blob, channel, payload_write, 0, num_of_pages, blob_op_complete, NULL);
705 
706 	/* Verify that I/O is queued */
707 	CU_ASSERT(!TAILQ_EMPTY(&bs_channel->queued_io));
708 	/* Verify that payload is not written to disk */
709 	CU_ASSERT(memcmp(payload_zero, &g_dev_buffer[blob->active.clusters[0]*SPDK_BS_PAGE_SIZE],
710 			 SPDK_BS_PAGE_SIZE) == 0);
711 
712 	/* Disable scheduler delay.
713 	 * Finish all operations including spdk_bs_create_snapshot */
714 	g_scheduler_delay = false;
715 	_bs_flush_scheduler(1);
716 
717 	/* Verify snapshot */
718 	CU_ASSERT(g_bserrno == 0);
719 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
720 
721 	/* Verify that blob has unset frozen_io */
722 	CU_ASSERT(blob->frozen_refcnt == 0);
723 
724 	/* Verify that postponed I/O completed successfully by comparing payload */
725 	spdk_blob_io_read(blob, channel, payload_read, 0, num_of_pages, blob_op_complete, NULL);
726 	CU_ASSERT(g_bserrno == 0);
727 	CU_ASSERT(memcmp(payload_write, payload_read, num_of_pages * SPDK_BS_PAGE_SIZE) == 0);
728 
729 	spdk_blob_close(blob, blob_op_complete, NULL);
730 	CU_ASSERT(g_bserrno == 0);
731 
732 	spdk_bs_free_io_channel(channel);
733 
734 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
735 	CU_ASSERT(g_bserrno == 0);
736 	g_bs = NULL;
737 }
738 
739 static void
740 blob_clone(void)
741 {
742 	struct spdk_blob_store *bs;
743 	struct spdk_bs_dev *dev;
744 	struct spdk_blob_opts opts;
745 	struct spdk_blob *blob, *snapshot, *clone;
746 	spdk_blob_id blobid, cloneid, snapshotid;
747 	struct spdk_blob_xattr_opts xattrs;
748 	const void *value;
749 	size_t value_len;
750 	int rc;
751 
752 	dev = init_dev();
753 
754 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
755 	CU_ASSERT(g_bserrno == 0);
756 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
757 	bs = g_bs;
758 
759 	/* Create blob with 10 clusters */
760 
761 	spdk_blob_opts_init(&opts);
762 	opts.num_clusters = 10;
763 
764 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
765 	CU_ASSERT(g_bserrno == 0);
766 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
767 	blobid = g_blobid;
768 
769 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
770 	CU_ASSERT(g_bserrno == 0);
771 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
772 	blob = g_blob;
773 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10)
774 
775 	/* Create snapshot */
776 	spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL);
777 	CU_ASSERT(g_bserrno == 0);
778 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
779 	snapshotid = g_blobid;
780 
781 	spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL);
782 	CU_ASSERT(g_bserrno == 0);
783 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
784 	snapshot = g_blob;
785 	CU_ASSERT(snapshot->data_ro == true)
786 	CU_ASSERT(snapshot->md_ro == true)
787 	CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 10);
788 
789 	spdk_blob_close(snapshot, blob_op_complete, NULL);
790 	CU_ASSERT(g_bserrno == 0);
791 
792 	/* Create clone from snapshot with xattrs */
793 	xattrs.names = g_xattr_names;
794 	xattrs.get_value = _get_xattr_value;
795 	xattrs.count = 3;
796 	xattrs.ctx = &g_ctx;
797 
798 	spdk_bs_create_clone(bs, snapshotid, &xattrs, blob_op_with_id_complete, NULL);
799 	CU_ASSERT(g_bserrno == 0);
800 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
801 	cloneid = g_blobid;
802 
803 	spdk_bs_open_blob(bs, cloneid, blob_op_with_handle_complete, NULL);
804 	CU_ASSERT(g_bserrno == 0);
805 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
806 	clone = g_blob;
807 	CU_ASSERT(clone->data_ro == false)
808 	CU_ASSERT(clone->md_ro == false)
809 	CU_ASSERT(spdk_blob_get_num_clusters(clone) == 10);
810 
811 	rc = spdk_blob_get_xattr_value(clone, g_xattr_names[0], &value, &value_len);
812 	CU_ASSERT(rc == 0);
813 	SPDK_CU_ASSERT_FATAL(value != NULL);
814 	CU_ASSERT(value_len == strlen(g_xattr_values[0]));
815 	CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len);
816 
817 	rc = spdk_blob_get_xattr_value(clone, g_xattr_names[1], &value, &value_len);
818 	CU_ASSERT(rc == 0);
819 	SPDK_CU_ASSERT_FATAL(value != NULL);
820 	CU_ASSERT(value_len == strlen(g_xattr_values[1]));
821 	CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len);
822 
823 	rc = spdk_blob_get_xattr_value(clone, g_xattr_names[2], &value, &value_len);
824 	CU_ASSERT(rc == 0);
825 	SPDK_CU_ASSERT_FATAL(value != NULL);
826 	CU_ASSERT(value_len == strlen(g_xattr_values[2]));
827 	CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len);
828 
829 
830 	spdk_blob_close(clone, blob_op_complete, NULL);
831 	CU_ASSERT(g_bserrno == 0);
832 
833 	/* Try to create clone from not read only blob */
834 	spdk_bs_create_clone(bs, blobid, NULL, blob_op_with_id_complete, NULL);
835 	CU_ASSERT(g_bserrno == -EINVAL);
836 	CU_ASSERT(g_blobid == SPDK_BLOBID_INVALID);
837 
838 	/* Mark blob as read only */
839 	spdk_blob_set_read_only(blob);
840 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
841 	CU_ASSERT(g_bserrno == 0);
842 
843 	/* Create clone from read only blob */
844 	spdk_bs_create_clone(bs, blobid, NULL, blob_op_with_id_complete, NULL);
845 	CU_ASSERT(g_bserrno == 0);
846 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
847 	cloneid = g_blobid;
848 
849 	spdk_bs_open_blob(bs, cloneid, blob_op_with_handle_complete, NULL);
850 	CU_ASSERT(g_bserrno == 0);
851 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
852 	clone = g_blob;
853 	CU_ASSERT(clone->data_ro == false)
854 	CU_ASSERT(clone->md_ro == false)
855 	CU_ASSERT(spdk_blob_get_num_clusters(clone) == 10);
856 
857 	spdk_blob_close(clone, blob_op_complete, NULL);
858 	CU_ASSERT(g_bserrno == 0);
859 
860 	spdk_blob_close(blob, blob_op_complete, NULL);
861 	CU_ASSERT(g_bserrno == 0);
862 
863 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
864 	CU_ASSERT(g_bserrno == 0);
865 	g_bs = NULL;
866 
867 }
868 
869 static void
870 blob_inflate(void)
871 {
872 	struct spdk_blob_store *bs;
873 	struct spdk_bs_dev *dev;
874 	struct spdk_blob_opts opts;
875 	struct spdk_blob *blob, *snapshot;
876 	spdk_blob_id blobid, snapshotid;
877 	struct spdk_io_channel *channel;
878 	uint64_t free_clusters;
879 
880 	dev = init_dev();
881 
882 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
883 	CU_ASSERT(g_bserrno == 0);
884 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
885 	bs = g_bs;
886 
887 	channel = spdk_bs_alloc_io_channel(bs);
888 	SPDK_CU_ASSERT_FATAL(channel != NULL);
889 
890 	/* Create blob with 10 clusters */
891 
892 	spdk_blob_opts_init(&opts);
893 	opts.num_clusters = 10;
894 
895 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
896 	CU_ASSERT(g_bserrno == 0);
897 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
898 	blobid = g_blobid;
899 
900 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
901 	CU_ASSERT(g_bserrno == 0);
902 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
903 	blob = g_blob;
904 
905 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10)
906 	CU_ASSERT(spdk_blob_is_thin_provisioned(blob) == false);
907 
908 	/* Create snapshot */
909 
910 	spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL);
911 	CU_ASSERT(g_bserrno == 0);
912 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
913 	snapshotid = g_blobid;
914 
915 	CU_ASSERT(spdk_blob_is_thin_provisioned(blob) == true);
916 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10)
917 
918 	spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL);
919 	CU_ASSERT(g_bserrno == 0);
920 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
921 	snapshot = g_blob;
922 	CU_ASSERT(snapshot->data_ro == true)
923 	CU_ASSERT(snapshot->md_ro == true)
924 	CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 10);
925 
926 	spdk_blob_close(snapshot, blob_op_complete, NULL);
927 	CU_ASSERT(g_bserrno == 0);
928 
929 	free_clusters = spdk_bs_free_cluster_count(bs);
930 
931 	/* Inflate blob */
932 	spdk_bs_inflate_blob(bs, channel, blobid, blob_op_complete, NULL);
933 	CU_ASSERT(g_bserrno == 0);
934 
935 	/* All 10 clusters should be allocated from blob store */
936 	CU_ASSERT(spdk_bs_free_cluster_count(bs) == free_clusters - 10);
937 
938 	/* Now, it should be possible to delete snapshot */
939 	spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL);
940 	CU_ASSERT(g_bserrno == 0);
941 
942 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10)
943 	CU_ASSERT(spdk_blob_is_thin_provisioned(blob) == false);
944 
945 	spdk_blob_close(blob, blob_op_complete, NULL);
946 	CU_ASSERT(g_bserrno == 0);
947 
948 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
949 	CU_ASSERT(g_bserrno == 0);
950 	g_bs = NULL;
951 
952 	spdk_bs_free_io_channel(channel);
953 }
954 
955 static void
956 blob_delete(void)
957 {
958 	struct spdk_blob_store *bs;
959 	struct spdk_bs_dev *dev;
960 	spdk_blob_id blobid;
961 
962 	dev = init_dev();
963 
964 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
965 	CU_ASSERT(g_bserrno == 0);
966 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
967 	bs = g_bs;
968 
969 	/* Create a blob and then delete it. */
970 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
971 	CU_ASSERT(g_bserrno == 0);
972 	CU_ASSERT(g_blobid > 0);
973 	blobid = g_blobid;
974 
975 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
976 	CU_ASSERT(g_bserrno == 0);
977 
978 	/* Try to open the blob */
979 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
980 	CU_ASSERT(g_bserrno == -ENOENT);
981 
982 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
983 	CU_ASSERT(g_bserrno == 0);
984 	g_bs = NULL;
985 }
986 
987 static void
988 blob_resize(void)
989 {
990 	struct spdk_blob_store *bs;
991 	struct spdk_bs_dev *dev;
992 	struct spdk_blob *blob;
993 	spdk_blob_id blobid;
994 	uint64_t free_clusters;
995 
996 	dev = init_dev();
997 
998 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
999 	CU_ASSERT(g_bserrno == 0);
1000 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1001 	bs = g_bs;
1002 	free_clusters = spdk_bs_free_cluster_count(bs);
1003 
1004 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
1005 	CU_ASSERT(g_bserrno == 0);
1006 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1007 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
1008 	blobid = g_blobid;
1009 
1010 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1011 	CU_ASSERT(g_bserrno == 0);
1012 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1013 	blob = g_blob;
1014 
1015 	/* Confirm that resize fails if blob is marked read-only. */
1016 	blob->md_ro = true;
1017 	spdk_blob_resize(blob, 5, blob_op_complete, NULL);
1018 	CU_ASSERT(g_bserrno == -EPERM);
1019 	blob->md_ro = false;
1020 
1021 	/* The blob started at 0 clusters. Resize it to be 5. */
1022 	spdk_blob_resize(blob, 5, blob_op_complete, NULL);
1023 	CU_ASSERT(g_bserrno == 0);
1024 	CU_ASSERT((free_clusters - 5) == spdk_bs_free_cluster_count(bs));
1025 
1026 	/* Shrink the blob to 3 clusters. This will not actually release
1027 	 * the old clusters until the blob is synced.
1028 	 */
1029 	spdk_blob_resize(blob, 3, blob_op_complete, NULL);
1030 	CU_ASSERT(g_bserrno == 0);
1031 	/* Verify there are still 5 clusters in use */
1032 	CU_ASSERT((free_clusters - 5) == spdk_bs_free_cluster_count(bs));
1033 
1034 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
1035 	CU_ASSERT(g_bserrno == 0);
1036 	/* Now there are only 3 clusters in use */
1037 	CU_ASSERT((free_clusters - 3) == spdk_bs_free_cluster_count(bs));
1038 
1039 	/* Resize the blob to be 10 clusters. Growth takes effect immediately. */
1040 	spdk_blob_resize(blob, 10, blob_op_complete, NULL);
1041 	CU_ASSERT(g_bserrno == 0);
1042 	CU_ASSERT((free_clusters - 10) == spdk_bs_free_cluster_count(bs));
1043 
1044 	/* Try to resize the blob to size larger than blobstore. */
1045 	spdk_blob_resize(blob, bs->total_clusters + 1, blob_op_complete, NULL);
1046 	CU_ASSERT(g_bserrno == -ENOSPC);
1047 
1048 	spdk_blob_close(blob, blob_op_complete, NULL);
1049 	CU_ASSERT(g_bserrno == 0);
1050 
1051 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
1052 	CU_ASSERT(g_bserrno == 0);
1053 
1054 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1055 	CU_ASSERT(g_bserrno == 0);
1056 	g_bs = NULL;
1057 }
1058 
1059 static void
1060 blob_read_only(void)
1061 {
1062 	struct spdk_blob_store *bs;
1063 	struct spdk_bs_dev *dev;
1064 	struct spdk_blob *blob;
1065 	struct spdk_bs_opts opts;
1066 	spdk_blob_id blobid;
1067 	int rc;
1068 
1069 	dev = init_dev();
1070 	spdk_bs_opts_init(&opts);
1071 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
1072 
1073 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
1074 	CU_ASSERT(g_bserrno == 0);
1075 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1076 	bs = g_bs;
1077 
1078 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
1079 	CU_ASSERT(g_bserrno == 0);
1080 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1081 	blobid = g_blobid;
1082 
1083 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1084 	CU_ASSERT(g_bserrno == 0);
1085 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1086 	blob = g_blob;
1087 
1088 	rc = spdk_blob_set_read_only(blob);
1089 	CU_ASSERT(rc == 0);
1090 
1091 	CU_ASSERT(blob->data_ro == false);
1092 	CU_ASSERT(blob->md_ro == false);
1093 
1094 	spdk_blob_sync_md(blob, bs_op_complete, NULL);
1095 
1096 	CU_ASSERT(blob->data_ro == true);
1097 	CU_ASSERT(blob->md_ro == true);
1098 	CU_ASSERT(blob->data_ro_flags & SPDK_BLOB_READ_ONLY);
1099 
1100 	spdk_blob_close(blob, blob_op_complete, NULL);
1101 	CU_ASSERT(g_bserrno == 0);
1102 
1103 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1104 	CU_ASSERT(g_bserrno == 0);
1105 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1106 	blob = g_blob;
1107 
1108 	CU_ASSERT(blob->data_ro == true);
1109 	CU_ASSERT(blob->md_ro == true);
1110 	CU_ASSERT(blob->data_ro_flags & SPDK_BLOB_READ_ONLY);
1111 
1112 	spdk_blob_close(blob, blob_op_complete, NULL);
1113 	CU_ASSERT(g_bserrno == 0);
1114 
1115 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1116 	CU_ASSERT(g_bserrno == 0);
1117 	g_bs = NULL;
1118 	g_blob = NULL;
1119 	g_blobid = 0;
1120 
1121 	/* Load an existing blob store */
1122 	dev = init_dev();
1123 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
1124 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1125 	CU_ASSERT(g_bserrno == 0);
1126 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1127 
1128 	spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
1129 	CU_ASSERT(g_bserrno == 0);
1130 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1131 	blob = g_blob;
1132 
1133 	CU_ASSERT(blob->data_ro == true);
1134 	CU_ASSERT(blob->md_ro == true);
1135 	CU_ASSERT(blob->data_ro_flags & SPDK_BLOB_READ_ONLY);
1136 
1137 	spdk_blob_close(blob, blob_op_complete, NULL);
1138 	CU_ASSERT(g_bserrno == 0);
1139 
1140 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1141 	CU_ASSERT(g_bserrno == 0);
1142 
1143 }
1144 
1145 static void
1146 channel_ops(void)
1147 {
1148 	struct spdk_blob_store *bs;
1149 	struct spdk_bs_dev *dev;
1150 	struct spdk_io_channel *channel;
1151 
1152 	dev = init_dev();
1153 
1154 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1155 	CU_ASSERT(g_bserrno == 0);
1156 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1157 	bs = g_bs;
1158 
1159 	channel = spdk_bs_alloc_io_channel(bs);
1160 	CU_ASSERT(channel != NULL);
1161 
1162 	spdk_bs_free_io_channel(channel);
1163 
1164 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1165 	CU_ASSERT(g_bserrno == 0);
1166 	g_bs = NULL;
1167 }
1168 
1169 static void
1170 blob_write(void)
1171 {
1172 	struct spdk_blob_store *bs;
1173 	struct spdk_bs_dev *dev;
1174 	struct spdk_blob *blob;
1175 	struct spdk_io_channel *channel;
1176 	spdk_blob_id blobid;
1177 	uint64_t pages_per_cluster;
1178 	uint8_t payload[10 * 4096];
1179 
1180 	dev = init_dev();
1181 
1182 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1183 	CU_ASSERT(g_bserrno == 0);
1184 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1185 	bs = g_bs;
1186 
1187 	pages_per_cluster = spdk_bs_get_cluster_size(bs) / spdk_bs_get_page_size(bs);
1188 
1189 	channel = spdk_bs_alloc_io_channel(bs);
1190 	CU_ASSERT(channel != NULL);
1191 
1192 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
1193 	CU_ASSERT(g_bserrno == 0);
1194 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1195 	blobid = g_blobid;
1196 
1197 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1198 	CU_ASSERT(g_bserrno == 0);
1199 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1200 	blob = g_blob;
1201 
1202 	/* Write to a blob with 0 size */
1203 	spdk_blob_io_write(blob, channel, payload, 0, 1, blob_op_complete, NULL);
1204 	CU_ASSERT(g_bserrno == -EINVAL);
1205 
1206 	/* Resize the blob */
1207 	spdk_blob_resize(blob, 5, blob_op_complete, NULL);
1208 	CU_ASSERT(g_bserrno == 0);
1209 
1210 	/* Confirm that write fails if blob is marked read-only. */
1211 	blob->data_ro = true;
1212 	spdk_blob_io_write(blob, channel, payload, 0, 1, blob_op_complete, NULL);
1213 	CU_ASSERT(g_bserrno == -EPERM);
1214 	blob->data_ro = false;
1215 
1216 	/* Write to the blob */
1217 	spdk_blob_io_write(blob, channel, payload, 0, 1, blob_op_complete, NULL);
1218 	CU_ASSERT(g_bserrno == 0);
1219 
1220 	/* Write starting beyond the end */
1221 	spdk_blob_io_write(blob, channel, payload, 5 * pages_per_cluster, 1, blob_op_complete,
1222 			   NULL);
1223 	CU_ASSERT(g_bserrno == -EINVAL);
1224 
1225 	/* Write starting at a valid location but going off the end */
1226 	spdk_blob_io_write(blob, channel, payload, 4 * pages_per_cluster, pages_per_cluster + 1,
1227 			   blob_op_complete, NULL);
1228 	CU_ASSERT(g_bserrno == -EINVAL);
1229 
1230 	spdk_blob_close(blob, blob_op_complete, NULL);
1231 	CU_ASSERT(g_bserrno == 0);
1232 
1233 	spdk_bs_free_io_channel(channel);
1234 
1235 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1236 	CU_ASSERT(g_bserrno == 0);
1237 	g_bs = NULL;
1238 }
1239 
1240 static void
1241 blob_read(void)
1242 {
1243 	struct spdk_blob_store *bs;
1244 	struct spdk_bs_dev *dev;
1245 	struct spdk_blob *blob;
1246 	struct spdk_io_channel *channel;
1247 	spdk_blob_id blobid;
1248 	uint64_t pages_per_cluster;
1249 	uint8_t payload[10 * 4096];
1250 
1251 	dev = init_dev();
1252 
1253 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1254 	CU_ASSERT(g_bserrno == 0);
1255 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1256 	bs = g_bs;
1257 
1258 	pages_per_cluster = spdk_bs_get_cluster_size(bs) / spdk_bs_get_page_size(bs);
1259 
1260 	channel = spdk_bs_alloc_io_channel(bs);
1261 	CU_ASSERT(channel != NULL);
1262 
1263 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
1264 	CU_ASSERT(g_bserrno == 0);
1265 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1266 	blobid = g_blobid;
1267 
1268 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1269 	CU_ASSERT(g_bserrno == 0);
1270 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1271 	blob = g_blob;
1272 
1273 	/* Read from a blob with 0 size */
1274 	spdk_blob_io_read(blob, channel, payload, 0, 1, blob_op_complete, NULL);
1275 	CU_ASSERT(g_bserrno == -EINVAL);
1276 
1277 	/* Resize the blob */
1278 	spdk_blob_resize(blob, 5, blob_op_complete, NULL);
1279 	CU_ASSERT(g_bserrno == 0);
1280 
1281 	/* Confirm that read passes if blob is marked read-only. */
1282 	blob->data_ro = true;
1283 	spdk_blob_io_read(blob, channel, payload, 0, 1, blob_op_complete, NULL);
1284 	CU_ASSERT(g_bserrno == 0);
1285 	blob->data_ro = false;
1286 
1287 	/* Read from the blob */
1288 	spdk_blob_io_read(blob, channel, payload, 0, 1, blob_op_complete, NULL);
1289 	CU_ASSERT(g_bserrno == 0);
1290 
1291 	/* Read starting beyond the end */
1292 	spdk_blob_io_read(blob, channel, payload, 5 * pages_per_cluster, 1, blob_op_complete,
1293 			  NULL);
1294 	CU_ASSERT(g_bserrno == -EINVAL);
1295 
1296 	/* Read starting at a valid location but going off the end */
1297 	spdk_blob_io_read(blob, channel, payload, 4 * pages_per_cluster, pages_per_cluster + 1,
1298 			  blob_op_complete, NULL);
1299 	CU_ASSERT(g_bserrno == -EINVAL);
1300 
1301 	spdk_blob_close(blob, blob_op_complete, NULL);
1302 	CU_ASSERT(g_bserrno == 0);
1303 
1304 	spdk_bs_free_io_channel(channel);
1305 
1306 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1307 	CU_ASSERT(g_bserrno == 0);
1308 	g_bs = NULL;
1309 }
1310 
1311 static void
1312 blob_rw_verify(void)
1313 {
1314 	struct spdk_blob_store *bs;
1315 	struct spdk_bs_dev *dev;
1316 	struct spdk_blob *blob;
1317 	struct spdk_io_channel *channel;
1318 	spdk_blob_id blobid;
1319 	uint8_t payload_read[10 * 4096];
1320 	uint8_t payload_write[10 * 4096];
1321 
1322 	dev = init_dev();
1323 
1324 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1325 	CU_ASSERT(g_bserrno == 0);
1326 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1327 	bs = g_bs;
1328 
1329 	channel = spdk_bs_alloc_io_channel(bs);
1330 	CU_ASSERT(channel != NULL);
1331 
1332 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
1333 	CU_ASSERT(g_bserrno == 0);
1334 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1335 	blobid = g_blobid;
1336 
1337 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1338 	CU_ASSERT(g_bserrno == 0);
1339 	CU_ASSERT(g_blob != NULL);
1340 	blob = g_blob;
1341 
1342 	spdk_blob_resize(blob, 32, blob_op_complete, NULL);
1343 	CU_ASSERT(g_bserrno == 0);
1344 
1345 	memset(payload_write, 0xE5, sizeof(payload_write));
1346 	spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL);
1347 	CU_ASSERT(g_bserrno == 0);
1348 
1349 	memset(payload_read, 0x00, sizeof(payload_read));
1350 	spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL);
1351 	CU_ASSERT(g_bserrno == 0);
1352 	CU_ASSERT(memcmp(payload_write, payload_read, 4 * 4096) == 0);
1353 
1354 	spdk_blob_close(blob, blob_op_complete, NULL);
1355 	CU_ASSERT(g_bserrno == 0);
1356 
1357 	spdk_bs_free_io_channel(channel);
1358 
1359 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1360 	CU_ASSERT(g_bserrno == 0);
1361 	g_bs = NULL;
1362 }
1363 
1364 static void
1365 blob_rw_verify_iov(void)
1366 {
1367 	struct spdk_blob_store *bs;
1368 	struct spdk_bs_dev *dev;
1369 	struct spdk_blob *blob;
1370 	struct spdk_io_channel *channel;
1371 	spdk_blob_id blobid;
1372 	uint8_t payload_read[10 * 4096];
1373 	uint8_t payload_write[10 * 4096];
1374 	struct iovec iov_read[3];
1375 	struct iovec iov_write[3];
1376 	void *buf;
1377 
1378 	dev = init_dev();
1379 	memset(g_dev_buffer, 0, DEV_BUFFER_SIZE);
1380 
1381 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1382 	CU_ASSERT(g_bserrno == 0);
1383 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1384 	bs = g_bs;
1385 
1386 	channel = spdk_bs_alloc_io_channel(bs);
1387 	CU_ASSERT(channel != NULL);
1388 
1389 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
1390 	CU_ASSERT(g_bserrno == 0);
1391 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1392 	blobid = g_blobid;
1393 
1394 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1395 	CU_ASSERT(g_bserrno == 0);
1396 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1397 	blob = g_blob;
1398 
1399 	spdk_blob_resize(blob, 2, blob_op_complete, NULL);
1400 	CU_ASSERT(g_bserrno == 0);
1401 
1402 	/*
1403 	 * Manually adjust the offset of the blob's second cluster.  This allows
1404 	 *  us to make sure that the readv/write code correctly accounts for I/O
1405 	 *  that cross cluster boundaries.  Start by asserting that the allocated
1406 	 *  clusters are where we expect before modifying the second cluster.
1407 	 */
1408 	CU_ASSERT(blob->active.clusters[0] == 1 * 256);
1409 	CU_ASSERT(blob->active.clusters[1] == 2 * 256);
1410 	blob->active.clusters[1] = 3 * 256;
1411 
1412 	memset(payload_write, 0xE5, sizeof(payload_write));
1413 	iov_write[0].iov_base = payload_write;
1414 	iov_write[0].iov_len = 1 * 4096;
1415 	iov_write[1].iov_base = payload_write + 1 * 4096;
1416 	iov_write[1].iov_len = 5 * 4096;
1417 	iov_write[2].iov_base = payload_write + 6 * 4096;
1418 	iov_write[2].iov_len = 4 * 4096;
1419 	/*
1420 	 * Choose a page offset just before the cluster boundary.  The first 6 pages of payload
1421 	 *  will get written to the first cluster, the last 4 to the second cluster.
1422 	 */
1423 	spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL);
1424 	CU_ASSERT(g_bserrno == 0);
1425 
1426 	memset(payload_read, 0xAA, sizeof(payload_read));
1427 	iov_read[0].iov_base = payload_read;
1428 	iov_read[0].iov_len = 3 * 4096;
1429 	iov_read[1].iov_base = payload_read + 3 * 4096;
1430 	iov_read[1].iov_len = 4 * 4096;
1431 	iov_read[2].iov_base = payload_read + 7 * 4096;
1432 	iov_read[2].iov_len = 3 * 4096;
1433 	spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL);
1434 	CU_ASSERT(g_bserrno == 0);
1435 	CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0);
1436 
1437 	buf = calloc(1, 256 * 4096);
1438 	SPDK_CU_ASSERT_FATAL(buf != NULL);
1439 	/* Check that cluster 2 on "disk" was not modified. */
1440 	CU_ASSERT(memcmp(buf, &g_dev_buffer[512 * 4096], 256 * 4096) == 0);
1441 	free(buf);
1442 
1443 	spdk_blob_close(blob, blob_op_complete, NULL);
1444 	CU_ASSERT(g_bserrno == 0);
1445 
1446 	spdk_bs_free_io_channel(channel);
1447 
1448 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1449 	CU_ASSERT(g_bserrno == 0);
1450 	g_bs = NULL;
1451 }
1452 
1453 static uint32_t
1454 bs_channel_get_req_count(struct spdk_io_channel *_channel)
1455 {
1456 	struct spdk_bs_channel *channel = spdk_io_channel_get_ctx(_channel);
1457 	struct spdk_bs_request_set *set;
1458 	uint32_t count = 0;
1459 
1460 	TAILQ_FOREACH(set, &channel->reqs, link) {
1461 		count++;
1462 	}
1463 
1464 	return count;
1465 }
1466 
1467 static void
1468 blob_rw_verify_iov_nomem(void)
1469 {
1470 	struct spdk_blob_store *bs;
1471 	struct spdk_bs_dev *dev;
1472 	struct spdk_blob *blob;
1473 	struct spdk_io_channel *channel;
1474 	spdk_blob_id blobid;
1475 	uint8_t payload_write[10 * 4096];
1476 	struct iovec iov_write[3];
1477 	uint32_t req_count;
1478 
1479 	dev = init_dev();
1480 	memset(g_dev_buffer, 0, DEV_BUFFER_SIZE);
1481 
1482 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1483 	CU_ASSERT(g_bserrno == 0);
1484 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1485 	bs = g_bs;
1486 
1487 	channel = spdk_bs_alloc_io_channel(bs);
1488 	CU_ASSERT(channel != NULL);
1489 
1490 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
1491 	CU_ASSERT(g_bserrno == 0);
1492 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1493 	blobid = g_blobid;
1494 
1495 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1496 	CU_ASSERT(g_bserrno == 0);
1497 	CU_ASSERT(g_blob != NULL);
1498 	blob = g_blob;
1499 
1500 	spdk_blob_resize(blob, 2, blob_op_complete, NULL);
1501 	CU_ASSERT(g_bserrno == 0);
1502 
1503 	/*
1504 	 * Choose a page offset just before the cluster boundary.  The first 6 pages of payload
1505 	 *  will get written to the first cluster, the last 4 to the second cluster.
1506 	 */
1507 	iov_write[0].iov_base = payload_write;
1508 	iov_write[0].iov_len = 1 * 4096;
1509 	iov_write[1].iov_base = payload_write + 1 * 4096;
1510 	iov_write[1].iov_len = 5 * 4096;
1511 	iov_write[2].iov_base = payload_write + 6 * 4096;
1512 	iov_write[2].iov_len = 4 * 4096;
1513 	MOCK_SET(calloc, void *, NULL);
1514 	req_count = bs_channel_get_req_count(channel);
1515 	spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL);
1516 	CU_ASSERT(g_bserrno = -ENOMEM);
1517 	CU_ASSERT(req_count == bs_channel_get_req_count(channel));
1518 	MOCK_SET(calloc, void *, (void *)MOCK_PASS_THRU);
1519 
1520 	spdk_blob_close(blob, blob_op_complete, NULL);
1521 	CU_ASSERT(g_bserrno == 0);
1522 
1523 	spdk_bs_free_io_channel(channel);
1524 
1525 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1526 	CU_ASSERT(g_bserrno == 0);
1527 	g_bs = NULL;
1528 }
1529 
1530 static void
1531 blob_rw_iov_read_only(void)
1532 {
1533 	struct spdk_blob_store *bs;
1534 	struct spdk_bs_dev *dev;
1535 	struct spdk_blob *blob;
1536 	struct spdk_io_channel *channel;
1537 	spdk_blob_id blobid;
1538 	uint8_t payload_read[4096];
1539 	uint8_t payload_write[4096];
1540 	struct iovec iov_read;
1541 	struct iovec iov_write;
1542 
1543 	dev = init_dev();
1544 	memset(g_dev_buffer, 0, DEV_BUFFER_SIZE);
1545 
1546 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1547 	CU_ASSERT(g_bserrno == 0);
1548 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1549 	bs = g_bs;
1550 
1551 	channel = spdk_bs_alloc_io_channel(bs);
1552 	CU_ASSERT(channel != NULL);
1553 
1554 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
1555 	CU_ASSERT(g_bserrno == 0);
1556 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1557 	blobid = g_blobid;
1558 
1559 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1560 	CU_ASSERT(g_bserrno == 0);
1561 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1562 	blob = g_blob;
1563 
1564 	spdk_blob_resize(blob, 2, blob_op_complete, NULL);
1565 	CU_ASSERT(g_bserrno == 0);
1566 
1567 	/* Verify that writev failed if read_only flag is set. */
1568 	blob->data_ro = true;
1569 	iov_write.iov_base = payload_write;
1570 	iov_write.iov_len = sizeof(payload_write);
1571 	spdk_blob_io_writev(blob, channel, &iov_write, 1, 0, 1, blob_op_complete, NULL);
1572 	CU_ASSERT(g_bserrno == -EPERM);
1573 
1574 	/* Verify that reads pass if data_ro flag is set. */
1575 	iov_read.iov_base = payload_read;
1576 	iov_read.iov_len = sizeof(payload_read);
1577 	spdk_blob_io_readv(blob, channel, &iov_read, 1, 0, 1, blob_op_complete, NULL);
1578 	CU_ASSERT(g_bserrno == 0);
1579 
1580 	spdk_blob_close(blob, blob_op_complete, NULL);
1581 	CU_ASSERT(g_bserrno == 0);
1582 
1583 	spdk_bs_free_io_channel(channel);
1584 
1585 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1586 	CU_ASSERT(g_bserrno == 0);
1587 	g_bs = NULL;
1588 }
1589 
1590 static void
1591 blob_unmap(void)
1592 {
1593 	struct spdk_blob_store *bs;
1594 	struct spdk_bs_dev *dev;
1595 	struct spdk_blob *blob;
1596 	struct spdk_io_channel *channel;
1597 	spdk_blob_id blobid;
1598 	struct spdk_blob_opts opts;
1599 	uint8_t payload[4096];
1600 	int i;
1601 
1602 	dev = init_dev();
1603 
1604 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1605 	CU_ASSERT(g_bserrno == 0);
1606 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1607 	bs = g_bs;
1608 
1609 	channel = spdk_bs_alloc_io_channel(bs);
1610 	CU_ASSERT(channel != NULL);
1611 
1612 	spdk_blob_opts_init(&opts);
1613 	opts.num_clusters = 10;
1614 
1615 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
1616 	CU_ASSERT(g_bserrno == 0);
1617 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1618 	blobid = g_blobid;
1619 
1620 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1621 	CU_ASSERT(g_bserrno == 0);
1622 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1623 	blob = g_blob;
1624 
1625 	spdk_blob_resize(blob, 10, blob_op_complete, NULL);
1626 	CU_ASSERT(g_bserrno == 0);
1627 
1628 	memset(payload, 0, sizeof(payload));
1629 	payload[0] = 0xFF;
1630 
1631 	/*
1632 	 * Set first byte of every cluster to 0xFF.
1633 	 * First cluster on device is reserved so let's start from cluster number 1
1634 	 */
1635 	for (i = 1; i < 11; i++) {
1636 		g_dev_buffer[i * SPDK_BLOB_OPTS_CLUSTER_SZ] = 0xFF;
1637 	}
1638 
1639 	/* Confirm writes */
1640 	for (i = 0; i < 10; i++) {
1641 		payload[0] = 0;
1642 		spdk_blob_io_read(blob, channel, &payload, i * SPDK_BLOB_OPTS_CLUSTER_SZ / 4096, 1,
1643 				  blob_op_complete, NULL);
1644 		CU_ASSERT(g_bserrno == 0);
1645 		CU_ASSERT(payload[0] == 0xFF);
1646 	}
1647 
1648 	/* Mark some clusters as unallocated */
1649 	blob->active.clusters[1] = 0;
1650 	blob->active.clusters[2] = 0;
1651 	blob->active.clusters[3] = 0;
1652 	blob->active.clusters[6] = 0;
1653 	blob->active.clusters[8] = 0;
1654 
1655 	/* Unmap clusters by resizing to 0 */
1656 	spdk_blob_resize(blob, 0, blob_op_complete, NULL);
1657 	CU_ASSERT(g_bserrno == 0);
1658 
1659 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
1660 	CU_ASSERT(g_bserrno == 0);
1661 
1662 	/* Confirm that only 'allocated' clusters were unmaped */
1663 	for (i = 1; i < 11; i++) {
1664 		switch (i) {
1665 		case 2:
1666 		case 3:
1667 		case 4:
1668 		case 7:
1669 		case 9:
1670 			CU_ASSERT(g_dev_buffer[i * SPDK_BLOB_OPTS_CLUSTER_SZ] == 0xFF);
1671 			break;
1672 		default:
1673 			CU_ASSERT(g_dev_buffer[i * SPDK_BLOB_OPTS_CLUSTER_SZ] == 0);
1674 			break;
1675 		}
1676 	}
1677 
1678 	spdk_blob_close(blob, blob_op_complete, NULL);
1679 	CU_ASSERT(g_bserrno == 0);
1680 
1681 	spdk_bs_free_io_channel(channel);
1682 
1683 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1684 	CU_ASSERT(g_bserrno == 0);
1685 	g_bs = NULL;
1686 }
1687 
1688 
1689 static void
1690 blob_iter(void)
1691 {
1692 	struct spdk_blob_store *bs;
1693 	struct spdk_bs_dev *dev;
1694 	struct spdk_blob *blob;
1695 	spdk_blob_id blobid;
1696 
1697 	dev = init_dev();
1698 
1699 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1700 	CU_ASSERT(g_bserrno == 0);
1701 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1702 	bs = g_bs;
1703 
1704 	spdk_bs_iter_first(bs, blob_op_with_handle_complete, NULL);
1705 	CU_ASSERT(g_blob == NULL);
1706 	CU_ASSERT(g_bserrno == -ENOENT);
1707 
1708 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
1709 	CU_ASSERT(g_bserrno == 0);
1710 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1711 	blobid = g_blobid;
1712 
1713 	spdk_bs_iter_first(bs, blob_op_with_handle_complete, NULL);
1714 	CU_ASSERT(g_blob != NULL);
1715 	CU_ASSERT(g_bserrno == 0);
1716 	blob = g_blob;
1717 	CU_ASSERT(spdk_blob_get_id(blob) == blobid);
1718 
1719 	spdk_bs_iter_next(bs, blob, blob_op_with_handle_complete, NULL);
1720 	CU_ASSERT(g_blob == NULL);
1721 	CU_ASSERT(g_bserrno == -ENOENT);
1722 
1723 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1724 	CU_ASSERT(g_bserrno == 0);
1725 	g_bs = NULL;
1726 }
1727 
1728 static void
1729 blob_xattr(void)
1730 {
1731 	struct spdk_blob_store *bs;
1732 	struct spdk_bs_dev *dev;
1733 	struct spdk_blob *blob;
1734 	spdk_blob_id blobid;
1735 	uint64_t length;
1736 	int rc;
1737 	const char *name1, *name2;
1738 	const void *value;
1739 	size_t value_len;
1740 	struct spdk_xattr_names *names;
1741 
1742 	dev = init_dev();
1743 
1744 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1745 	CU_ASSERT(g_bserrno == 0);
1746 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1747 	bs = g_bs;
1748 
1749 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
1750 	CU_ASSERT(g_bserrno == 0);
1751 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1752 	blobid = g_blobid;
1753 
1754 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1755 	CU_ASSERT(g_bserrno == 0);
1756 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1757 	blob = g_blob;
1758 
1759 	/* Test that set_xattr fails if md_ro flag is set. */
1760 	blob->md_ro = true;
1761 	rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1);
1762 	CU_ASSERT(rc == -EPERM);
1763 
1764 	blob->md_ro = false;
1765 	rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1);
1766 	CU_ASSERT(rc == 0);
1767 
1768 	length = 2345;
1769 	rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
1770 	CU_ASSERT(rc == 0);
1771 
1772 	/* Overwrite "length" xattr. */
1773 	length = 3456;
1774 	rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
1775 	CU_ASSERT(rc == 0);
1776 
1777 	/* get_xattr should still work even if md_ro flag is set. */
1778 	value = NULL;
1779 	blob->md_ro = true;
1780 	rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len);
1781 	CU_ASSERT(rc == 0);
1782 	SPDK_CU_ASSERT_FATAL(value != NULL);
1783 	CU_ASSERT(*(uint64_t *)value == length);
1784 	CU_ASSERT(value_len == 8);
1785 	blob->md_ro = false;
1786 
1787 	rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len);
1788 	CU_ASSERT(rc == -ENOENT);
1789 
1790 	names = NULL;
1791 	rc = spdk_blob_get_xattr_names(blob, &names);
1792 	CU_ASSERT(rc == 0);
1793 	SPDK_CU_ASSERT_FATAL(names != NULL);
1794 	CU_ASSERT(spdk_xattr_names_get_count(names) == 2);
1795 	name1 = spdk_xattr_names_get_name(names, 0);
1796 	SPDK_CU_ASSERT_FATAL(name1 != NULL);
1797 	CU_ASSERT(!strcmp(name1, "name") || !strcmp(name1, "length"));
1798 	name2 = spdk_xattr_names_get_name(names, 1);
1799 	SPDK_CU_ASSERT_FATAL(name2 != NULL);
1800 	CU_ASSERT(!strcmp(name2, "name") || !strcmp(name2, "length"));
1801 	CU_ASSERT(strcmp(name1, name2));
1802 	spdk_xattr_names_free(names);
1803 
1804 	/* Confirm that remove_xattr fails if md_ro is set to true. */
1805 	blob->md_ro = true;
1806 	rc = spdk_blob_remove_xattr(blob, "name");
1807 	CU_ASSERT(rc == -EPERM);
1808 
1809 	blob->md_ro = false;
1810 	rc = spdk_blob_remove_xattr(blob, "name");
1811 	CU_ASSERT(rc == 0);
1812 
1813 	rc = spdk_blob_remove_xattr(blob, "foobar");
1814 	CU_ASSERT(rc == -ENOENT);
1815 
1816 	/* Set internal xattr */
1817 	length = 7898;
1818 	rc = _spdk_blob_set_xattr(blob, "internal", &length, sizeof(length), true);
1819 	CU_ASSERT(rc == 0);
1820 	rc = _spdk_blob_get_xattr_value(blob, "internal", &value, &value_len, true);
1821 	CU_ASSERT(rc == 0);
1822 	CU_ASSERT(*(uint64_t *)value == length);
1823 	/* try to get public xattr with same name */
1824 	rc = spdk_blob_get_xattr_value(blob, "internal", &value, &value_len);
1825 	CU_ASSERT(rc != 0);
1826 	rc = _spdk_blob_get_xattr_value(blob, "internal", &value, &value_len, false);
1827 	CU_ASSERT(rc != 0);
1828 	/* Check if SPDK_BLOB_INTERNAL_XATTR is set */
1829 	CU_ASSERT((blob->invalid_flags & SPDK_BLOB_INTERNAL_XATTR) ==
1830 		  SPDK_BLOB_INTERNAL_XATTR)
1831 
1832 	spdk_blob_close(blob, blob_op_complete, NULL);
1833 
1834 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1835 
1836 	/* Check if xattrs are persisted */
1837 	dev = init_dev();
1838 
1839 	spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL);
1840 	CU_ASSERT(g_bserrno == 0);
1841 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1842 
1843 	bs = g_bs;
1844 
1845 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1846 	CU_ASSERT(g_bserrno == 0);
1847 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1848 	blob = g_blob;
1849 
1850 	rc = _spdk_blob_get_xattr_value(blob, "internal", &value, &value_len, true);
1851 	CU_ASSERT(rc == 0);
1852 	CU_ASSERT(*(uint64_t *)value == length);
1853 
1854 	/* try to get internal xattr trough public call */
1855 	rc = spdk_blob_get_xattr_value(blob, "internal", &value, &value_len);
1856 	CU_ASSERT(rc != 0);
1857 
1858 	rc = _spdk_blob_remove_xattr(blob, "internal", true);
1859 	CU_ASSERT(rc == 0);
1860 
1861 	CU_ASSERT((blob->invalid_flags & SPDK_BLOB_INTERNAL_XATTR) == 0);
1862 
1863 	CU_ASSERT(g_bserrno == 0);
1864 	g_bs = NULL;
1865 }
1866 
1867 static void
1868 bs_load(void)
1869 {
1870 	struct spdk_bs_dev *dev;
1871 	spdk_blob_id blobid;
1872 	struct spdk_blob *blob;
1873 	struct spdk_bs_super_block *super_block;
1874 	uint64_t length;
1875 	int rc;
1876 	const void *value;
1877 	size_t value_len;
1878 	struct spdk_bs_opts opts;
1879 
1880 	dev = init_dev();
1881 	spdk_bs_opts_init(&opts);
1882 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
1883 
1884 	/* Initialize a new blob store */
1885 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
1886 	CU_ASSERT(g_bserrno == 0);
1887 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1888 
1889 	/* Try to open a blobid that does not exist */
1890 	spdk_bs_open_blob(g_bs, 0, blob_op_with_handle_complete, NULL);
1891 	CU_ASSERT(g_bserrno == -ENOENT);
1892 	CU_ASSERT(g_blob == NULL);
1893 
1894 	/* Create a blob */
1895 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
1896 	CU_ASSERT(g_bserrno == 0);
1897 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1898 	blobid = g_blobid;
1899 
1900 	spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
1901 	CU_ASSERT(g_bserrno == 0);
1902 	CU_ASSERT(g_blob != NULL);
1903 	blob = g_blob;
1904 
1905 	/* Try again to open valid blob but without the upper bit set */
1906 	spdk_bs_open_blob(g_bs, blobid & 0xFFFFFFFF, blob_op_with_handle_complete, NULL);
1907 	CU_ASSERT(g_bserrno == -ENOENT);
1908 	CU_ASSERT(g_blob == NULL);
1909 
1910 	/* Set some xattrs */
1911 	rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1);
1912 	CU_ASSERT(rc == 0);
1913 
1914 	length = 2345;
1915 	rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
1916 	CU_ASSERT(rc == 0);
1917 
1918 	/* Resize the blob */
1919 	spdk_blob_resize(blob, 10, blob_op_complete, NULL);
1920 	CU_ASSERT(g_bserrno == 0);
1921 
1922 	spdk_blob_close(blob, blob_op_complete, NULL);
1923 	CU_ASSERT(g_bserrno == 0);
1924 	blob = NULL;
1925 	g_blob = NULL;
1926 	g_blobid = SPDK_BLOBID_INVALID;
1927 
1928 	/* Unload the blob store */
1929 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1930 	CU_ASSERT(g_bserrno == 0);
1931 	g_bs = NULL;
1932 	g_blob = NULL;
1933 	g_blobid = 0;
1934 
1935 	super_block = (struct spdk_bs_super_block *)g_dev_buffer;
1936 	CU_ASSERT(super_block->clean == 1);
1937 
1938 	/* Load should fail for device with an unsupported blocklen */
1939 	dev = init_dev();
1940 	dev->blocklen = SPDK_BS_PAGE_SIZE * 2;
1941 	spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL);
1942 	CU_ASSERT(g_bserrno == -EINVAL);
1943 
1944 	/* Load should when max_md_ops is set to zero */
1945 	dev = init_dev();
1946 	spdk_bs_opts_init(&opts);
1947 	opts.max_md_ops = 0;
1948 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1949 	CU_ASSERT(g_bserrno == -EINVAL);
1950 
1951 	/* Load should when max_channel_ops is set to zero */
1952 	dev = init_dev();
1953 	spdk_bs_opts_init(&opts);
1954 	opts.max_channel_ops = 0;
1955 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1956 	CU_ASSERT(g_bserrno == -EINVAL);
1957 
1958 	/* Load an existing blob store */
1959 	dev = init_dev();
1960 	spdk_bs_opts_init(&opts);
1961 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
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 	super_block = (struct spdk_bs_super_block *)g_dev_buffer;
1967 	CU_ASSERT(super_block->clean == 1);
1968 
1969 	spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
1970 	CU_ASSERT(g_bserrno == 0);
1971 	CU_ASSERT(g_blob != NULL);
1972 	blob = g_blob;
1973 
1974 	/* Verify that blobstore is marked dirty after first metadata sync */
1975 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
1976 	CU_ASSERT(super_block->clean == 1);
1977 
1978 	/* Get the xattrs */
1979 	value = NULL;
1980 	rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len);
1981 	CU_ASSERT(rc == 0);
1982 	SPDK_CU_ASSERT_FATAL(value != NULL);
1983 	CU_ASSERT(*(uint64_t *)value == length);
1984 	CU_ASSERT(value_len == 8);
1985 
1986 	rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len);
1987 	CU_ASSERT(rc == -ENOENT);
1988 
1989 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10);
1990 
1991 	spdk_blob_close(blob, blob_op_complete, NULL);
1992 	CU_ASSERT(g_bserrno == 0);
1993 	blob = NULL;
1994 	g_blob = NULL;
1995 	g_blobid = SPDK_BLOBID_INVALID;
1996 
1997 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1998 	CU_ASSERT(g_bserrno == 0);
1999 	g_bs = NULL;
2000 }
2001 
2002 static void
2003 bs_type(void)
2004 {
2005 	struct spdk_bs_dev *dev;
2006 	struct spdk_bs_opts opts;
2007 
2008 	dev = init_dev();
2009 	spdk_bs_opts_init(&opts);
2010 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
2011 
2012 	/* Initialize a new blob store */
2013 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2014 	CU_ASSERT(g_bserrno == 0);
2015 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2016 
2017 	/* Unload the blob store */
2018 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2019 	CU_ASSERT(g_bserrno == 0);
2020 	g_bs = NULL;
2021 	g_blob = NULL;
2022 	g_blobid = 0;
2023 
2024 	/* Load non existing blobstore type */
2025 	dev = init_dev();
2026 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "NONEXISTING");
2027 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2028 	CU_ASSERT(g_bserrno != 0);
2029 
2030 	/* Load with empty blobstore type */
2031 	dev = init_dev();
2032 	memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype));
2033 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2034 	CU_ASSERT(g_bserrno == 0);
2035 
2036 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2037 	CU_ASSERT(g_bserrno == 0);
2038 	g_bs = NULL;
2039 
2040 	/* Initialize a new blob store with empty bstype */
2041 	dev = init_dev();
2042 	memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype));
2043 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
2044 	CU_ASSERT(g_bserrno == 0);
2045 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2046 
2047 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2048 	CU_ASSERT(g_bserrno == 0);
2049 	g_bs = NULL;
2050 
2051 	/* Load non existing blobstore type */
2052 	dev = init_dev();
2053 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "NONEXISTING");
2054 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2055 	CU_ASSERT(g_bserrno != 0);
2056 
2057 	/* Load with empty blobstore type */
2058 	dev = init_dev();
2059 	memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype));
2060 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2061 	CU_ASSERT(g_bserrno == 0);
2062 
2063 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2064 	CU_ASSERT(g_bserrno == 0);
2065 	g_bs = NULL;
2066 }
2067 
2068 static void
2069 bs_super_block(void)
2070 {
2071 	struct spdk_bs_dev *dev;
2072 	struct spdk_bs_super_block *super_block;
2073 	struct spdk_bs_opts opts;
2074 	struct spdk_bs_super_block_ver1 super_block_v1;
2075 
2076 	dev = init_dev();
2077 	spdk_bs_opts_init(&opts);
2078 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
2079 
2080 	/* Initialize a new blob store */
2081 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2082 	CU_ASSERT(g_bserrno == 0);
2083 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2084 
2085 	/* Unload the blob store */
2086 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2087 	CU_ASSERT(g_bserrno == 0);
2088 	g_bs = NULL;
2089 	g_blob = NULL;
2090 	g_blobid = 0;
2091 
2092 	/* Load an existing blob store with version newer than supported */
2093 	super_block = (struct spdk_bs_super_block *)g_dev_buffer;
2094 	super_block->version++;
2095 
2096 	dev = init_dev();
2097 	memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype));
2098 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2099 	CU_ASSERT(g_bserrno != 0);
2100 
2101 	/* Create a new blob store with super block version 1 */
2102 	dev = init_dev();
2103 	super_block_v1.version = 1;
2104 	memcpy(super_block_v1.signature, "SPDKBLOB", sizeof(super_block_v1.signature));
2105 	super_block_v1.length = 0x1000;
2106 	super_block_v1.clean = 1;
2107 	super_block_v1.super_blob = 0xFFFFFFFFFFFFFFFF;
2108 	super_block_v1.cluster_size = 0x100000;
2109 	super_block_v1.used_page_mask_start = 0x01;
2110 	super_block_v1.used_page_mask_len = 0x01;
2111 	super_block_v1.used_cluster_mask_start = 0x02;
2112 	super_block_v1.used_cluster_mask_len = 0x01;
2113 	super_block_v1.md_start = 0x03;
2114 	super_block_v1.md_len = 0x40;
2115 	memset(super_block_v1.reserved, 0, 4036);
2116 	super_block_v1.crc = _spdk_blob_md_page_calc_crc(&super_block_v1);
2117 	memcpy(g_dev_buffer, &super_block_v1, sizeof(struct spdk_bs_super_block_ver1));
2118 
2119 	memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype));
2120 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2121 	CU_ASSERT(g_bserrno == 0);
2122 
2123 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2124 	CU_ASSERT(g_bserrno == 0);
2125 	g_bs = NULL;
2126 }
2127 
2128 /*
2129  * Create a blobstore and then unload it.
2130  */
2131 static void
2132 bs_unload(void)
2133 {
2134 	struct spdk_bs_dev *dev;
2135 	struct spdk_blob_store *bs;
2136 	spdk_blob_id blobid;
2137 	struct spdk_blob *blob;
2138 
2139 	dev = init_dev();
2140 
2141 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
2142 	CU_ASSERT(g_bserrno == 0);
2143 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2144 	bs = g_bs;
2145 
2146 	/* Create a blob and open it. */
2147 	g_bserrno = -1;
2148 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
2149 	CU_ASSERT(g_bserrno == 0);
2150 	CU_ASSERT(g_blobid > 0);
2151 	blobid = g_blobid;
2152 
2153 	g_bserrno = -1;
2154 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
2155 	CU_ASSERT(g_bserrno == 0);
2156 	CU_ASSERT(g_blob != NULL);
2157 	blob = g_blob;
2158 
2159 	/* Try to unload blobstore, should fail with open blob */
2160 	g_bserrno = -1;
2161 	spdk_bs_unload(bs, bs_op_complete, NULL);
2162 	CU_ASSERT(g_bserrno == -EBUSY);
2163 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2164 
2165 	/* Close the blob, then successfully unload blobstore */
2166 	g_bserrno = -1;
2167 	spdk_blob_close(blob, blob_op_complete, NULL);
2168 	CU_ASSERT(g_bserrno == 0);
2169 
2170 	g_bserrno = -1;
2171 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2172 	CU_ASSERT(g_bserrno == 0);
2173 	g_bs = NULL;
2174 }
2175 
2176 /*
2177  * Create a blobstore with a cluster size different than the default, and ensure it is
2178  *  persisted.
2179  */
2180 static void
2181 bs_cluster_sz(void)
2182 {
2183 	struct spdk_bs_dev *dev;
2184 	struct spdk_bs_opts opts;
2185 	uint32_t cluster_sz;
2186 
2187 	/* Set cluster size to zero */
2188 	dev = init_dev();
2189 	spdk_bs_opts_init(&opts);
2190 	opts.cluster_sz = 0;
2191 
2192 	/* Initialize a new blob store */
2193 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2194 	CU_ASSERT(g_bserrno == -EINVAL);
2195 	SPDK_CU_ASSERT_FATAL(g_bs == NULL);
2196 
2197 	/*
2198 	 * Set cluster size to blobstore page size,
2199 	 * to work it is required to be at least twice the blobstore page size.
2200 	 */
2201 	dev = init_dev();
2202 	spdk_bs_opts_init(&opts);
2203 	opts.cluster_sz = SPDK_BS_PAGE_SIZE;
2204 
2205 	/* Initialize a new blob store */
2206 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2207 	CU_ASSERT(g_bserrno == -ENOMEM);
2208 	SPDK_CU_ASSERT_FATAL(g_bs == NULL);
2209 
2210 	/*
2211 	 * Set cluster size to lower than page size,
2212 	 * to work it is required to be at least twice the blobstore page size.
2213 	 */
2214 	dev = init_dev();
2215 	spdk_bs_opts_init(&opts);
2216 	opts.cluster_sz = SPDK_BS_PAGE_SIZE - 1;
2217 
2218 	/* Initialize a new blob store */
2219 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2220 	CU_ASSERT(g_bserrno == -ENOMEM);
2221 	SPDK_CU_ASSERT_FATAL(g_bs == NULL);
2222 
2223 	/* Set cluster size to twice the default */
2224 	dev = init_dev();
2225 	spdk_bs_opts_init(&opts);
2226 	opts.cluster_sz *= 2;
2227 	cluster_sz = opts.cluster_sz;
2228 
2229 	/* Initialize a new blob store */
2230 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2231 	CU_ASSERT(g_bserrno == 0);
2232 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2233 
2234 	CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz);
2235 
2236 	/* Unload the blob store */
2237 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2238 	CU_ASSERT(g_bserrno == 0);
2239 	g_bs = NULL;
2240 	g_blob = NULL;
2241 	g_blobid = 0;
2242 
2243 	dev = init_dev();
2244 	/* Load an existing blob store */
2245 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2246 	CU_ASSERT(g_bserrno == 0);
2247 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2248 
2249 	CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz);
2250 
2251 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2252 	CU_ASSERT(g_bserrno == 0);
2253 	g_bs = NULL;
2254 }
2255 
2256 /*
2257  * Create a blobstore, reload it and ensure total usable cluster count
2258  *  stays the same.
2259  */
2260 static void
2261 bs_usable_clusters(void)
2262 {
2263 	struct spdk_bs_dev *dev;
2264 	struct spdk_bs_opts opts;
2265 	uint32_t clusters;
2266 	int i;
2267 
2268 	/* Init blobstore */
2269 	dev = init_dev();
2270 	spdk_bs_opts_init(&opts);
2271 
2272 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2273 	CU_ASSERT(g_bserrno == 0);
2274 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2275 
2276 	clusters = spdk_bs_total_data_cluster_count(g_bs);
2277 
2278 	/* Unload the blob store */
2279 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2280 	CU_ASSERT(g_bserrno == 0);
2281 	g_bs = NULL;
2282 
2283 	dev = init_dev();
2284 	/* Load an existing blob store */
2285 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2286 	CU_ASSERT(g_bserrno == 0);
2287 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2288 
2289 	CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters);
2290 
2291 	/* Create and resize blobs to make sure that useable cluster count won't change */
2292 	for (i = 0; i < 4; i++) {
2293 		g_bserrno = -1;
2294 		g_blobid = SPDK_BLOBID_INVALID;
2295 		spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
2296 		CU_ASSERT(g_bserrno == 0);
2297 		CU_ASSERT(g_blobid !=  SPDK_BLOBID_INVALID);
2298 
2299 		g_bserrno = -1;
2300 		g_blob = NULL;
2301 		spdk_bs_open_blob(g_bs, g_blobid, blob_op_with_handle_complete, NULL);
2302 		CU_ASSERT(g_bserrno == 0);
2303 		CU_ASSERT(g_blob !=  NULL);
2304 
2305 		spdk_blob_resize(g_blob, 10, blob_op_complete, NULL);
2306 		CU_ASSERT(g_bserrno == 0);
2307 
2308 		g_bserrno = -1;
2309 		spdk_blob_close(g_blob, blob_op_complete, NULL);
2310 		CU_ASSERT(g_bserrno == 0);
2311 
2312 		CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters);
2313 	}
2314 
2315 	/* Reload the blob store to make sure that nothing changed */
2316 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2317 	CU_ASSERT(g_bserrno == 0);
2318 	g_bs = NULL;
2319 
2320 	dev = init_dev();
2321 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2322 	CU_ASSERT(g_bserrno == 0);
2323 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2324 
2325 	CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters);
2326 
2327 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2328 	CU_ASSERT(g_bserrno == 0);
2329 	g_bs = NULL;
2330 }
2331 
2332 /*
2333  * Test resizing of the metadata blob.  This requires creating enough blobs
2334  *  so that one cluster is not enough to fit the metadata for those blobs.
2335  *  To induce this condition to happen more quickly, we reduce the cluster
2336  *  size to 16KB, which means only 4 4KB blob metadata pages can fit.
2337  */
2338 static void
2339 bs_resize_md(void)
2340 {
2341 	const int CLUSTER_PAGE_COUNT = 4;
2342 	const int NUM_BLOBS = CLUSTER_PAGE_COUNT * 4;
2343 	struct spdk_bs_dev *dev;
2344 	struct spdk_bs_opts opts;
2345 	uint32_t cluster_sz;
2346 	spdk_blob_id blobids[NUM_BLOBS];
2347 	int i;
2348 
2349 
2350 	dev = init_dev();
2351 	spdk_bs_opts_init(&opts);
2352 	opts.cluster_sz = CLUSTER_PAGE_COUNT * 4096;
2353 	cluster_sz = opts.cluster_sz;
2354 
2355 	/* Initialize a new blob store */
2356 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2357 	CU_ASSERT(g_bserrno == 0);
2358 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2359 
2360 	CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz);
2361 
2362 	for (i = 0; i < NUM_BLOBS; i++) {
2363 		g_bserrno = -1;
2364 		g_blobid = SPDK_BLOBID_INVALID;
2365 		spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
2366 		CU_ASSERT(g_bserrno == 0);
2367 		CU_ASSERT(g_blobid !=  SPDK_BLOBID_INVALID);
2368 		blobids[i] = g_blobid;
2369 	}
2370 
2371 	/* Unload the blob store */
2372 	g_bserrno = -1;
2373 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2374 	CU_ASSERT(g_bserrno == 0);
2375 
2376 	/* Load an existing blob store */
2377 	g_bserrno = -1;
2378 	g_bs = NULL;
2379 	dev = init_dev();
2380 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2381 	CU_ASSERT(g_bserrno == 0);
2382 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2383 
2384 	CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz);
2385 
2386 	for (i = 0; i < NUM_BLOBS; i++) {
2387 		g_bserrno = -1;
2388 		g_blob = NULL;
2389 		spdk_bs_open_blob(g_bs, blobids[i], blob_op_with_handle_complete, NULL);
2390 		CU_ASSERT(g_bserrno == 0);
2391 		CU_ASSERT(g_blob !=  NULL);
2392 		g_bserrno = -1;
2393 		spdk_blob_close(g_blob, blob_op_complete, NULL);
2394 		CU_ASSERT(g_bserrno == 0);
2395 	}
2396 
2397 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2398 	CU_ASSERT(g_bserrno == 0);
2399 	g_bs = NULL;
2400 }
2401 
2402 static void
2403 bs_destroy(void)
2404 {
2405 	struct spdk_bs_dev *dev;
2406 	struct spdk_bs_opts opts;
2407 
2408 	/* Initialize a new blob store */
2409 	dev = init_dev();
2410 	spdk_bs_opts_init(&opts);
2411 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2412 	CU_ASSERT(g_bserrno == 0);
2413 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2414 
2415 	/* Destroy the blob store */
2416 	g_bserrno = -1;
2417 	spdk_bs_destroy(g_bs, bs_op_complete, NULL);
2418 	CU_ASSERT(g_bserrno == 0);
2419 
2420 	/* Loading an non-existent blob store should fail. */
2421 	g_bs = NULL;
2422 	dev = init_dev();
2423 
2424 	g_bserrno = 0;
2425 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2426 	CU_ASSERT(g_bserrno != 0);
2427 }
2428 
2429 /* Try to hit all of the corner cases associated with serializing
2430  * a blob to disk
2431  */
2432 static void
2433 blob_serialize(void)
2434 {
2435 	struct spdk_bs_dev *dev;
2436 	struct spdk_bs_opts opts;
2437 	struct spdk_blob_store *bs;
2438 	spdk_blob_id blobid[2];
2439 	struct spdk_blob *blob[2];
2440 	uint64_t i;
2441 	char *value;
2442 	int rc;
2443 
2444 	dev = init_dev();
2445 
2446 	/* Initialize a new blobstore with very small clusters */
2447 	spdk_bs_opts_init(&opts);
2448 	opts.cluster_sz = dev->blocklen * 8;
2449 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2450 	CU_ASSERT(g_bserrno == 0);
2451 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2452 	bs = g_bs;
2453 
2454 	/* Create and open two blobs */
2455 	for (i = 0; i < 2; i++) {
2456 		spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
2457 		CU_ASSERT(g_bserrno == 0);
2458 		CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2459 		blobid[i] = g_blobid;
2460 
2461 		/* Open a blob */
2462 		spdk_bs_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL);
2463 		CU_ASSERT(g_bserrno == 0);
2464 		CU_ASSERT(g_blob != NULL);
2465 		blob[i] = g_blob;
2466 
2467 		/* Set a fairly large xattr on both blobs to eat up
2468 		 * metadata space
2469 		 */
2470 		value = calloc(dev->blocklen - 64, sizeof(char));
2471 		SPDK_CU_ASSERT_FATAL(value != NULL);
2472 		memset(value, i, dev->blocklen / 2);
2473 		rc = spdk_blob_set_xattr(blob[i], "name", value, dev->blocklen - 64);
2474 		CU_ASSERT(rc == 0);
2475 		free(value);
2476 	}
2477 
2478 	/* Resize the blobs, alternating 1 cluster at a time.
2479 	 * This thwarts run length encoding and will cause spill
2480 	 * over of the extents.
2481 	 */
2482 	for (i = 0; i < 6; i++) {
2483 		spdk_blob_resize(blob[i % 2], (i / 2) + 1, blob_op_complete, NULL);
2484 		CU_ASSERT(g_bserrno == 0);
2485 	}
2486 
2487 	for (i = 0; i < 2; i++) {
2488 		spdk_blob_sync_md(blob[i], blob_op_complete, NULL);
2489 		CU_ASSERT(g_bserrno == 0);
2490 	}
2491 
2492 	/* Close the blobs */
2493 	for (i = 0; i < 2; i++) {
2494 		spdk_blob_close(blob[i], blob_op_complete, NULL);
2495 		CU_ASSERT(g_bserrno == 0);
2496 	}
2497 
2498 	/* Unload the blobstore */
2499 	spdk_bs_unload(bs, bs_op_complete, NULL);
2500 	CU_ASSERT(g_bserrno == 0);
2501 	g_bs = NULL;
2502 	g_blob = NULL;
2503 	g_blobid = 0;
2504 	bs = NULL;
2505 
2506 	dev = init_dev();
2507 	/* Load an existing blob store */
2508 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2509 	CU_ASSERT(g_bserrno == 0);
2510 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2511 	bs = g_bs;
2512 
2513 	for (i = 0; i < 2; i++) {
2514 		blob[i] = NULL;
2515 
2516 		spdk_bs_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL);
2517 		CU_ASSERT(g_bserrno == 0);
2518 		CU_ASSERT(g_blob != NULL);
2519 		blob[i] = g_blob;
2520 
2521 		CU_ASSERT(spdk_blob_get_num_clusters(blob[i]) == 3);
2522 
2523 		spdk_blob_close(blob[i], blob_op_complete, NULL);
2524 		CU_ASSERT(g_bserrno == 0);
2525 	}
2526 
2527 	spdk_bs_unload(bs, bs_op_complete, NULL);
2528 	CU_ASSERT(g_bserrno == 0);
2529 	g_bs = NULL;
2530 }
2531 
2532 static void
2533 blob_crc(void)
2534 {
2535 	struct spdk_blob_store *bs;
2536 	struct spdk_bs_dev *dev;
2537 	struct spdk_blob *blob;
2538 	spdk_blob_id blobid;
2539 	uint32_t page_num;
2540 	int index;
2541 	struct spdk_blob_md_page *page;
2542 
2543 	dev = init_dev();
2544 
2545 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
2546 	CU_ASSERT(g_bserrno == 0);
2547 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2548 	bs = g_bs;
2549 
2550 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
2551 	CU_ASSERT(g_bserrno == 0);
2552 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2553 	blobid = g_blobid;
2554 
2555 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
2556 	CU_ASSERT(g_bserrno == 0);
2557 	CU_ASSERT(g_blob != NULL);
2558 	blob = g_blob;
2559 
2560 	spdk_blob_close(blob, blob_op_complete, NULL);
2561 	CU_ASSERT(g_bserrno == 0);
2562 
2563 	page_num = _spdk_bs_blobid_to_page(blobid);
2564 	index = DEV_BUFFER_BLOCKLEN * (bs->md_start + page_num);
2565 	page = (struct spdk_blob_md_page *)&g_dev_buffer[index];
2566 	page->crc = 0;
2567 
2568 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
2569 	CU_ASSERT(g_bserrno == -EINVAL);
2570 	CU_ASSERT(g_blob == NULL);
2571 	g_bserrno = 0;
2572 
2573 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
2574 	CU_ASSERT(g_bserrno == -EINVAL);
2575 
2576 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2577 	CU_ASSERT(g_bserrno == 0);
2578 	g_bs = NULL;
2579 }
2580 
2581 static void
2582 super_block_crc(void)
2583 {
2584 	struct spdk_bs_dev *dev;
2585 	struct spdk_bs_super_block *super_block;
2586 	struct spdk_bs_opts opts;
2587 
2588 	dev = init_dev();
2589 	spdk_bs_opts_init(&opts);
2590 
2591 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
2592 	CU_ASSERT(g_bserrno == 0);
2593 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2594 
2595 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2596 	CU_ASSERT(g_bserrno == 0);
2597 	g_bs = NULL;
2598 
2599 	super_block = (struct spdk_bs_super_block *)g_dev_buffer;
2600 	super_block->crc = 0;
2601 	dev = init_dev();
2602 
2603 	/* Load an existing blob store */
2604 	g_bserrno = 0;
2605 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2606 	CU_ASSERT(g_bserrno == -EILSEQ);
2607 }
2608 
2609 /* For blob dirty shutdown test case we do the following sub-test cases:
2610  * 1 Initialize new blob store and create 1 super blob with some xattrs, then we
2611  *   dirty shutdown and reload the blob store and verify the xattrs.
2612  * 2 Resize the blob from 10 clusters to 20 clusters and then dirty shutdown,
2613  *   reload the blob store and verify the clusters number.
2614  * 3 Create the second blob and then dirty shutdown, reload the blob store
2615  *   and verify the second blob.
2616  * 4 Delete the second blob and then dirty shutdown, reload the blob store
2617  *   and verify the second blob is invalid.
2618  * 5 Create the second blob again and also create the third blob, modify the
2619  *   md of second blob which makes the md invalid, and then dirty shutdown,
2620  *   reload the blob store verify the second blob, it should invalid and also
2621  *   verify the third blob, it should correct.
2622  */
2623 static void
2624 blob_dirty_shutdown(void)
2625 {
2626 	int rc;
2627 	int index;
2628 	struct spdk_bs_dev *dev;
2629 	spdk_blob_id blobid1, blobid2, blobid3;
2630 	struct spdk_blob *blob;
2631 	uint64_t length;
2632 	uint64_t free_clusters;
2633 	const void *value;
2634 	size_t value_len;
2635 	uint32_t page_num;
2636 	struct spdk_blob_md_page *page;
2637 	struct spdk_bs_opts opts;
2638 
2639 	dev = init_dev();
2640 	spdk_bs_opts_init(&opts);
2641 	/* Initialize a new blob store */
2642 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
2643 	CU_ASSERT(g_bserrno == 0);
2644 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2645 
2646 	/* Create first blob */
2647 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
2648 	CU_ASSERT(g_bserrno == 0);
2649 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2650 	blobid1 = g_blobid;
2651 
2652 	spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL);
2653 	CU_ASSERT(g_bserrno == 0);
2654 	CU_ASSERT(g_blob != NULL);
2655 	blob = g_blob;
2656 
2657 	/* Set some xattrs */
2658 	rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1);
2659 	CU_ASSERT(rc == 0);
2660 
2661 	length = 2345;
2662 	rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
2663 	CU_ASSERT(rc == 0);
2664 
2665 	/* Resize the blob */
2666 	spdk_blob_resize(blob, 10, blob_op_complete, NULL);
2667 	CU_ASSERT(g_bserrno == 0);
2668 
2669 	/* Set the blob as the super blob */
2670 	spdk_bs_set_super(g_bs, blobid1, blob_op_complete, NULL);
2671 	CU_ASSERT(g_bserrno == 0);
2672 
2673 	free_clusters = spdk_bs_free_cluster_count(g_bs);
2674 
2675 	spdk_blob_close(blob, blob_op_complete, NULL);
2676 	blob = NULL;
2677 	g_blob = NULL;
2678 	g_blobid = SPDK_BLOBID_INVALID;
2679 
2680 	/* Dirty shutdown */
2681 	_spdk_bs_free(g_bs);
2682 
2683 	/* reload blobstore */
2684 	dev = init_dev();
2685 	spdk_bs_opts_init(&opts);
2686 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2687 	CU_ASSERT(g_bserrno == 0);
2688 
2689 	/* Get the super blob */
2690 	spdk_bs_get_super(g_bs, blob_op_with_id_complete, NULL);
2691 	CU_ASSERT(g_bserrno == 0);
2692 	CU_ASSERT(blobid1 == g_blobid);
2693 
2694 	spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL);
2695 	CU_ASSERT(g_bserrno == 0);
2696 	CU_ASSERT(g_blob != NULL);
2697 	blob = g_blob;
2698 
2699 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs));
2700 
2701 	/* Get the xattrs */
2702 	value = NULL;
2703 	rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len);
2704 	CU_ASSERT(rc == 0);
2705 	SPDK_CU_ASSERT_FATAL(value != NULL);
2706 	CU_ASSERT(*(uint64_t *)value == length);
2707 	CU_ASSERT(value_len == 8);
2708 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10);
2709 
2710 	/* Resize the blob */
2711 	spdk_blob_resize(blob, 20, blob_op_complete, NULL);
2712 	CU_ASSERT(g_bserrno == 0);
2713 
2714 	free_clusters = spdk_bs_free_cluster_count(g_bs);
2715 
2716 	spdk_blob_close(blob, blob_op_complete, NULL);
2717 	CU_ASSERT(g_bserrno == 0);
2718 	blob = NULL;
2719 	g_blob = NULL;
2720 	g_blobid = SPDK_BLOBID_INVALID;
2721 
2722 	/* Dirty shutdown */
2723 	_spdk_bs_free(g_bs);
2724 
2725 	/* reload the blobstore */
2726 	dev = init_dev();
2727 	spdk_bs_opts_init(&opts);
2728 	/* Load an existing blob store */
2729 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2730 	CU_ASSERT(g_bserrno == 0);
2731 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2732 	spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL);
2733 	CU_ASSERT(g_bserrno == 0);
2734 	CU_ASSERT(g_blob != NULL);
2735 	blob = g_blob;
2736 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 20);
2737 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs));
2738 
2739 	spdk_blob_close(blob, blob_op_complete, NULL);
2740 	CU_ASSERT(g_bserrno == 0);
2741 	blob = NULL;
2742 	g_blob = NULL;
2743 	g_blobid = SPDK_BLOBID_INVALID;
2744 
2745 	/* Create second blob */
2746 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
2747 	CU_ASSERT(g_bserrno == 0);
2748 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2749 	blobid2 = g_blobid;
2750 
2751 	spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL);
2752 	CU_ASSERT(g_bserrno == 0);
2753 	CU_ASSERT(g_blob != NULL);
2754 	blob = g_blob;
2755 
2756 	/* Set some xattrs */
2757 	rc = spdk_blob_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1);
2758 	CU_ASSERT(rc == 0);
2759 
2760 	length = 5432;
2761 	rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
2762 	CU_ASSERT(rc == 0);
2763 
2764 	/* Resize the blob */
2765 	spdk_blob_resize(blob, 10, blob_op_complete, NULL);
2766 	CU_ASSERT(g_bserrno == 0);
2767 
2768 	free_clusters = spdk_bs_free_cluster_count(g_bs);
2769 
2770 	spdk_blob_close(blob, blob_op_complete, NULL);
2771 	blob = NULL;
2772 	g_blob = NULL;
2773 	g_blobid = SPDK_BLOBID_INVALID;
2774 
2775 	/* Dirty shutdown */
2776 	_spdk_bs_free(g_bs);
2777 
2778 	/* reload the blobstore */
2779 	dev = init_dev();
2780 	spdk_bs_opts_init(&opts);
2781 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2782 	CU_ASSERT(g_bserrno == 0);
2783 
2784 	spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL);
2785 	CU_ASSERT(g_bserrno == 0);
2786 	CU_ASSERT(g_blob != NULL);
2787 	blob = g_blob;
2788 
2789 	/* Get the xattrs */
2790 	value = NULL;
2791 	rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len);
2792 	CU_ASSERT(rc == 0);
2793 	SPDK_CU_ASSERT_FATAL(value != NULL);
2794 	CU_ASSERT(*(uint64_t *)value == length);
2795 	CU_ASSERT(value_len == 8);
2796 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10);
2797 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs));
2798 
2799 	spdk_blob_close(blob, blob_op_complete, NULL);
2800 	CU_ASSERT(g_bserrno == 0);
2801 	spdk_bs_delete_blob(g_bs, blobid2, blob_op_complete, NULL);
2802 	CU_ASSERT(g_bserrno == 0);
2803 
2804 	free_clusters = spdk_bs_free_cluster_count(g_bs);
2805 
2806 	/* Dirty shutdown */
2807 	_spdk_bs_free(g_bs);
2808 	/* reload the blobstore */
2809 	dev = init_dev();
2810 	spdk_bs_opts_init(&opts);
2811 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2812 	CU_ASSERT(g_bserrno == 0);
2813 
2814 	spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL);
2815 	CU_ASSERT(g_bserrno != 0);
2816 	CU_ASSERT(g_blob == NULL);
2817 
2818 	spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL);
2819 	CU_ASSERT(g_bserrno == 0);
2820 	CU_ASSERT(g_blob != NULL);
2821 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs));
2822 	spdk_blob_close(g_blob, blob_op_complete, NULL);
2823 	CU_ASSERT(g_bserrno == 0);
2824 
2825 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2826 	CU_ASSERT(g_bserrno == 0);
2827 	g_bs = NULL;
2828 
2829 	/* reload the blobstore */
2830 	dev = init_dev();
2831 	spdk_bs_opts_init(&opts);
2832 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2833 	CU_ASSERT(g_bserrno == 0);
2834 
2835 	/* Create second blob */
2836 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
2837 	CU_ASSERT(g_bserrno == 0);
2838 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2839 	blobid2 = g_blobid;
2840 
2841 	/* Create third blob */
2842 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
2843 	CU_ASSERT(g_bserrno == 0);
2844 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2845 	blobid3 = g_blobid;
2846 
2847 	spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL);
2848 	CU_ASSERT(g_bserrno == 0);
2849 	CU_ASSERT(g_blob != NULL);
2850 	blob = g_blob;
2851 
2852 	/* Set some xattrs for second blob */
2853 	rc = spdk_blob_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1);
2854 	CU_ASSERT(rc == 0);
2855 
2856 	length = 5432;
2857 	rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
2858 	CU_ASSERT(rc == 0);
2859 
2860 	spdk_blob_close(blob, blob_op_complete, NULL);
2861 	blob = NULL;
2862 	g_blob = NULL;
2863 	g_blobid = SPDK_BLOBID_INVALID;
2864 
2865 	spdk_bs_open_blob(g_bs, blobid3, blob_op_with_handle_complete, NULL);
2866 	CU_ASSERT(g_bserrno == 0);
2867 	CU_ASSERT(g_blob != NULL);
2868 	blob = g_blob;
2869 
2870 	/* Set some xattrs for third blob */
2871 	rc = spdk_blob_set_xattr(blob, "name", "log2.txt", strlen("log2.txt") + 1);
2872 	CU_ASSERT(rc == 0);
2873 
2874 	length = 5432;
2875 	rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
2876 	CU_ASSERT(rc == 0);
2877 
2878 	spdk_blob_close(blob, blob_op_complete, NULL);
2879 	blob = NULL;
2880 	g_blob = NULL;
2881 	g_blobid = SPDK_BLOBID_INVALID;
2882 
2883 	/* Mark second blob as invalid */
2884 	page_num = _spdk_bs_blobid_to_page(blobid2);
2885 
2886 	index = DEV_BUFFER_BLOCKLEN * (g_bs->md_start + page_num);
2887 	page = (struct spdk_blob_md_page *)&g_dev_buffer[index];
2888 	page->sequence_num = 1;
2889 	page->crc = _spdk_blob_md_page_calc_crc(page);
2890 
2891 	free_clusters = spdk_bs_free_cluster_count(g_bs);
2892 
2893 	/* Dirty shutdown */
2894 	_spdk_bs_free(g_bs);
2895 	/* reload the blobstore */
2896 	dev = init_dev();
2897 	spdk_bs_opts_init(&opts);
2898 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2899 	CU_ASSERT(g_bserrno == 0);
2900 
2901 	spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL);
2902 	CU_ASSERT(g_bserrno != 0);
2903 	CU_ASSERT(g_blob == NULL);
2904 
2905 	spdk_bs_open_blob(g_bs, blobid3, blob_op_with_handle_complete, NULL);
2906 	CU_ASSERT(g_bserrno == 0);
2907 	CU_ASSERT(g_blob != NULL);
2908 	blob = g_blob;
2909 
2910 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs));
2911 
2912 	spdk_blob_close(blob, blob_op_complete, NULL);
2913 	blob = NULL;
2914 	g_blob = NULL;
2915 	g_blobid = SPDK_BLOBID_INVALID;
2916 
2917 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2918 	CU_ASSERT(g_bserrno == 0);
2919 	g_bs = NULL;
2920 }
2921 
2922 static void
2923 blob_flags(void)
2924 {
2925 	struct spdk_bs_dev *dev;
2926 	spdk_blob_id blobid_invalid, blobid_data_ro, blobid_md_ro;
2927 	struct spdk_blob *blob_invalid, *blob_data_ro, *blob_md_ro;
2928 	struct spdk_bs_opts opts;
2929 	int rc;
2930 
2931 	dev = init_dev();
2932 	spdk_bs_opts_init(&opts);
2933 
2934 	/* Initialize a new blob store */
2935 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2936 	CU_ASSERT(g_bserrno == 0);
2937 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2938 
2939 	/* Create three blobs - one each for testing invalid, data_ro and md_ro flags. */
2940 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
2941 	CU_ASSERT(g_bserrno == 0);
2942 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2943 	blobid_invalid = g_blobid;
2944 
2945 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
2946 	CU_ASSERT(g_bserrno == 0);
2947 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2948 	blobid_data_ro = g_blobid;
2949 
2950 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
2951 	CU_ASSERT(g_bserrno == 0);
2952 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2953 	blobid_md_ro = g_blobid;
2954 
2955 	spdk_bs_open_blob(g_bs, blobid_invalid, blob_op_with_handle_complete, NULL);
2956 	CU_ASSERT(g_bserrno == 0);
2957 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
2958 	blob_invalid = g_blob;
2959 
2960 	spdk_bs_open_blob(g_bs, blobid_data_ro, blob_op_with_handle_complete, NULL);
2961 	CU_ASSERT(g_bserrno == 0);
2962 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
2963 	blob_data_ro = g_blob;
2964 
2965 	spdk_bs_open_blob(g_bs, blobid_md_ro, blob_op_with_handle_complete, NULL);
2966 	CU_ASSERT(g_bserrno == 0);
2967 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
2968 	blob_md_ro = g_blob;
2969 
2970 	/* Change the size of blob_data_ro to check if flags are serialized
2971 	 * when blob has non zero number of extents */
2972 	spdk_blob_resize(blob_data_ro, 10, blob_op_complete, NULL);
2973 	CU_ASSERT(g_bserrno == 0);
2974 
2975 	/* Set the xattr to check if flags are serialized
2976 	 * when blob has non zero number of xattrs */
2977 	rc = spdk_blob_set_xattr(blob_md_ro, "name", "log.txt", strlen("log.txt") + 1);
2978 	CU_ASSERT(rc == 0);
2979 
2980 	blob_invalid->invalid_flags = (1ULL << 63);
2981 	blob_invalid->state = SPDK_BLOB_STATE_DIRTY;
2982 	blob_data_ro->data_ro_flags = (1ULL << 62);
2983 	blob_data_ro->state = SPDK_BLOB_STATE_DIRTY;
2984 	blob_md_ro->md_ro_flags = (1ULL << 61);
2985 	blob_md_ro->state = SPDK_BLOB_STATE_DIRTY;
2986 
2987 	g_bserrno = -1;
2988 	spdk_blob_sync_md(blob_invalid, blob_op_complete, NULL);
2989 	CU_ASSERT(g_bserrno == 0);
2990 	g_bserrno = -1;
2991 	spdk_blob_sync_md(blob_data_ro, blob_op_complete, NULL);
2992 	CU_ASSERT(g_bserrno == 0);
2993 	g_bserrno = -1;
2994 	spdk_blob_sync_md(blob_md_ro, blob_op_complete, NULL);
2995 	CU_ASSERT(g_bserrno == 0);
2996 
2997 	g_bserrno = -1;
2998 	spdk_blob_close(blob_invalid, blob_op_complete, NULL);
2999 	CU_ASSERT(g_bserrno == 0);
3000 	blob_invalid = NULL;
3001 	g_bserrno = -1;
3002 	spdk_blob_close(blob_data_ro, blob_op_complete, NULL);
3003 	CU_ASSERT(g_bserrno == 0);
3004 	blob_data_ro = NULL;
3005 	g_bserrno = -1;
3006 	spdk_blob_close(blob_md_ro, blob_op_complete, NULL);
3007 	CU_ASSERT(g_bserrno == 0);
3008 	blob_md_ro = NULL;
3009 
3010 	g_blob = NULL;
3011 	g_blobid = SPDK_BLOBID_INVALID;
3012 
3013 	/* Unload the blob store */
3014 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3015 	CU_ASSERT(g_bserrno == 0);
3016 	g_bs = NULL;
3017 
3018 	/* Load an existing blob store */
3019 	dev = init_dev();
3020 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
3021 	CU_ASSERT(g_bserrno == 0);
3022 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3023 
3024 	g_blob = NULL;
3025 	g_bserrno = 0;
3026 	spdk_bs_open_blob(g_bs, blobid_invalid, blob_op_with_handle_complete, NULL);
3027 	CU_ASSERT(g_bserrno != 0);
3028 	CU_ASSERT(g_blob == NULL);
3029 
3030 	g_blob = NULL;
3031 	g_bserrno = -1;
3032 	spdk_bs_open_blob(g_bs, blobid_data_ro, blob_op_with_handle_complete, NULL);
3033 	CU_ASSERT(g_bserrno == 0);
3034 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3035 	blob_data_ro = g_blob;
3036 	/* If an unknown data_ro flag was found, the blob should be marked both data and md read-only. */
3037 	CU_ASSERT(blob_data_ro->data_ro == true);
3038 	CU_ASSERT(blob_data_ro->md_ro == true);
3039 	CU_ASSERT(spdk_blob_get_num_clusters(blob_data_ro) == 10);
3040 
3041 	g_blob = NULL;
3042 	g_bserrno = -1;
3043 	spdk_bs_open_blob(g_bs, blobid_md_ro, blob_op_with_handle_complete, NULL);
3044 	CU_ASSERT(g_bserrno == 0);
3045 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3046 	blob_md_ro = g_blob;
3047 	CU_ASSERT(blob_md_ro->data_ro == false);
3048 	CU_ASSERT(blob_md_ro->md_ro == true);
3049 
3050 	g_bserrno = -1;
3051 	spdk_blob_sync_md(blob_md_ro, blob_op_complete, NULL);
3052 	CU_ASSERT(g_bserrno == 0);
3053 
3054 	spdk_blob_close(blob_data_ro, blob_op_complete, NULL);
3055 	CU_ASSERT(g_bserrno == 0);
3056 	spdk_blob_close(blob_md_ro, blob_op_complete, NULL);
3057 	CU_ASSERT(g_bserrno == 0);
3058 
3059 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3060 	CU_ASSERT(g_bserrno == 0);
3061 }
3062 
3063 static void
3064 bs_version(void)
3065 {
3066 	struct spdk_bs_super_block *super;
3067 	struct spdk_bs_dev *dev;
3068 	struct spdk_bs_opts opts;
3069 	spdk_blob_id blobid;
3070 
3071 	dev = init_dev();
3072 	spdk_bs_opts_init(&opts);
3073 
3074 	/* Initialize a new blob store */
3075 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
3076 	CU_ASSERT(g_bserrno == 0);
3077 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3078 
3079 	/* Unload the blob store */
3080 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3081 	CU_ASSERT(g_bserrno == 0);
3082 	g_bs = NULL;
3083 
3084 	/*
3085 	 * Change the bs version on disk.  This will allow us to
3086 	 *  test that the version does not get modified automatically
3087 	 *  when loading and unloading the blobstore.
3088 	 */
3089 	super = (struct spdk_bs_super_block *)&g_dev_buffer[0];
3090 	CU_ASSERT(super->version == SPDK_BS_VERSION);
3091 	CU_ASSERT(super->clean == 1);
3092 	super->version = 2;
3093 	/*
3094 	 * Version 2 metadata does not have a used blobid mask, so clear
3095 	 *  those fields in the super block and zero the corresponding
3096 	 *  region on "disk".  We will use this to ensure blob IDs are
3097 	 *  correctly reconstructed.
3098 	 */
3099 	memset(&g_dev_buffer[super->used_blobid_mask_start * SPDK_BS_PAGE_SIZE], 0,
3100 	       super->used_blobid_mask_len * SPDK_BS_PAGE_SIZE);
3101 	super->used_blobid_mask_start = 0;
3102 	super->used_blobid_mask_len = 0;
3103 	super->crc = _spdk_blob_md_page_calc_crc(super);
3104 
3105 	/* Load an existing blob store */
3106 	dev = init_dev();
3107 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
3108 	CU_ASSERT(g_bserrno == 0);
3109 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3110 	CU_ASSERT(super->clean == 0);
3111 
3112 	/*
3113 	 * Create a blob - just to make sure that when we unload it
3114 	 *  results in writing the super block (since metadata pages
3115 	 *  were allocated.
3116 	 */
3117 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
3118 	CU_ASSERT(g_bserrno == 0);
3119 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3120 	blobid = g_blobid;
3121 
3122 	/* Unload the blob store */
3123 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3124 	CU_ASSERT(g_bserrno == 0);
3125 	g_bs = NULL;
3126 	CU_ASSERT(super->version == 2);
3127 	CU_ASSERT(super->used_blobid_mask_start == 0);
3128 	CU_ASSERT(super->used_blobid_mask_len == 0);
3129 
3130 	dev = init_dev();
3131 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
3132 	CU_ASSERT(g_bserrno == 0);
3133 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3134 
3135 	g_blob = NULL;
3136 	spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
3137 	CU_ASSERT(g_bserrno == 0);
3138 	CU_ASSERT(g_blob != NULL);
3139 
3140 	spdk_blob_close(g_blob, blob_op_complete, NULL);
3141 	CU_ASSERT(g_bserrno == 0);
3142 
3143 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3144 	CU_ASSERT(g_bserrno == 0);
3145 	g_bs = NULL;
3146 	CU_ASSERT(super->version == 2);
3147 	CU_ASSERT(super->used_blobid_mask_start == 0);
3148 	CU_ASSERT(super->used_blobid_mask_len == 0);
3149 }
3150 
3151 static void
3152 blob_set_xattrs(void)
3153 {
3154 	struct spdk_blob_store *bs;
3155 	struct spdk_bs_dev *dev;
3156 	struct spdk_blob *blob;
3157 	struct spdk_blob_opts opts;
3158 	spdk_blob_id blobid;
3159 	const void *value;
3160 	size_t value_len;
3161 	int rc;
3162 
3163 	dev = init_dev();
3164 
3165 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
3166 	CU_ASSERT(g_bserrno == 0);
3167 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3168 	bs = g_bs;
3169 
3170 	/* Create blob with extra attributes */
3171 	spdk_blob_opts_init(&opts);
3172 
3173 	opts.xattrs.names = g_xattr_names;
3174 	opts.xattrs.get_value = _get_xattr_value;
3175 	opts.xattrs.count = 3;
3176 	opts.xattrs.ctx = &g_ctx;
3177 
3178 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
3179 	CU_ASSERT(g_bserrno == 0);
3180 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3181 	blobid = g_blobid;
3182 
3183 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
3184 	CU_ASSERT(g_bserrno == 0);
3185 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3186 	blob = g_blob;
3187 
3188 	/* Get the xattrs */
3189 	value = NULL;
3190 
3191 	rc = spdk_blob_get_xattr_value(blob, g_xattr_names[0], &value, &value_len);
3192 	CU_ASSERT(rc == 0);
3193 	SPDK_CU_ASSERT_FATAL(value != NULL);
3194 	CU_ASSERT(value_len == strlen(g_xattr_values[0]));
3195 	CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len);
3196 
3197 	rc = spdk_blob_get_xattr_value(blob, g_xattr_names[1], &value, &value_len);
3198 	CU_ASSERT(rc == 0);
3199 	SPDK_CU_ASSERT_FATAL(value != NULL);
3200 	CU_ASSERT(value_len == strlen(g_xattr_values[1]));
3201 	CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len);
3202 
3203 	rc = spdk_blob_get_xattr_value(blob, g_xattr_names[2], &value, &value_len);
3204 	CU_ASSERT(rc == 0);
3205 	SPDK_CU_ASSERT_FATAL(value != NULL);
3206 	CU_ASSERT(value_len == strlen(g_xattr_values[2]));
3207 	CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len);
3208 
3209 	/* Try to get non existing attribute */
3210 
3211 	rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len);
3212 	CU_ASSERT(rc == -ENOENT);
3213 
3214 	spdk_blob_close(blob, blob_op_complete, NULL);
3215 	CU_ASSERT(g_bserrno == 0);
3216 	blob = NULL;
3217 	g_blob = NULL;
3218 	g_blobid = SPDK_BLOBID_INVALID;
3219 
3220 	/* NULL callback */
3221 	spdk_blob_opts_init(&opts);
3222 	opts.xattrs.names = g_xattr_names;
3223 	opts.xattrs.get_value = NULL;
3224 	opts.xattrs.count = 1;
3225 	opts.xattrs.ctx = &g_ctx;
3226 
3227 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
3228 	CU_ASSERT(g_bserrno == -EINVAL);
3229 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3230 
3231 	/* NULL values */
3232 	spdk_blob_opts_init(&opts);
3233 	opts.xattrs.names = g_xattr_names;
3234 	opts.xattrs.get_value = _get_xattr_value_null;
3235 	opts.xattrs.count = 1;
3236 	opts.xattrs.ctx = NULL;
3237 
3238 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
3239 	CU_ASSERT(g_bserrno == -EINVAL);
3240 
3241 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3242 	CU_ASSERT(g_bserrno == 0);
3243 	g_bs = NULL;
3244 
3245 }
3246 
3247 static void
3248 blob_thin_prov_alloc(void)
3249 {
3250 	struct spdk_blob_store *bs;
3251 	struct spdk_bs_dev *dev;
3252 	struct spdk_blob *blob;
3253 	struct spdk_blob_opts opts;
3254 	spdk_blob_id blobid;
3255 	uint64_t free_clusters;
3256 
3257 	dev = init_dev();
3258 
3259 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
3260 	CU_ASSERT(g_bserrno == 0);
3261 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3262 	bs = g_bs;
3263 	free_clusters = spdk_bs_free_cluster_count(bs);
3264 
3265 	/* Set blob as thin provisioned */
3266 	spdk_blob_opts_init(&opts);
3267 	opts.thin_provision = true;
3268 
3269 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
3270 	CU_ASSERT(g_bserrno == 0);
3271 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3272 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3273 	blobid = g_blobid;
3274 
3275 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
3276 	CU_ASSERT(g_bserrno == 0);
3277 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3278 	blob = g_blob;
3279 
3280 	CU_ASSERT(blob->active.num_clusters == 0);
3281 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0);
3282 
3283 	/* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */
3284 	spdk_blob_resize(blob, 5, blob_op_complete, NULL);
3285 	CU_ASSERT(g_bserrno == 0);
3286 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3287 	CU_ASSERT(blob->active.num_clusters == 5);
3288 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5);
3289 
3290 	/* Shrink the blob to 3 clusters - still unallocated */
3291 	spdk_blob_resize(blob, 3, blob_op_complete, NULL);
3292 	CU_ASSERT(g_bserrno == 0);
3293 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3294 	CU_ASSERT(blob->active.num_clusters == 3);
3295 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 3);
3296 
3297 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
3298 	CU_ASSERT(g_bserrno == 0);
3299 	/* Sync must not change anything */
3300 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3301 	CU_ASSERT(blob->active.num_clusters == 3);
3302 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 3);
3303 
3304 	spdk_blob_close(blob, blob_op_complete, NULL);
3305 	CU_ASSERT(g_bserrno == 0);
3306 
3307 	/* Unload the blob store */
3308 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3309 	CU_ASSERT(g_bserrno == 0);
3310 	g_bs = NULL;
3311 	g_blob = NULL;
3312 	g_blobid = 0;
3313 
3314 	/* Load an existing blob store */
3315 	dev = init_dev();
3316 	spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL);
3317 	CU_ASSERT(g_bserrno == 0);
3318 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3319 
3320 	bs = g_bs;
3321 
3322 	spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
3323 	CU_ASSERT(g_bserrno == 0);
3324 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3325 	blob = g_blob;
3326 
3327 	/* Check that clusters allocation and size is still the same */
3328 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3329 	CU_ASSERT(blob->active.num_clusters == 3);
3330 
3331 	spdk_blob_close(blob, blob_op_complete, NULL);
3332 	CU_ASSERT(g_bserrno == 0);
3333 
3334 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
3335 	CU_ASSERT(g_bserrno == 0);
3336 
3337 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3338 	CU_ASSERT(g_bserrno == 0);
3339 	g_bs = NULL;
3340 }
3341 
3342 static void
3343 blob_insert_cluster_msg(void)
3344 {
3345 	struct spdk_blob_store *bs;
3346 	struct spdk_bs_dev *dev;
3347 	struct spdk_blob *blob;
3348 	struct spdk_blob_opts opts;
3349 	spdk_blob_id blobid;
3350 	uint64_t free_clusters;
3351 
3352 	dev = init_dev();
3353 
3354 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
3355 	CU_ASSERT(g_bserrno == 0);
3356 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3357 	bs = g_bs;
3358 	free_clusters = spdk_bs_free_cluster_count(bs);
3359 
3360 	/* Set blob as thin provisioned */
3361 	spdk_blob_opts_init(&opts);
3362 	opts.thin_provision = true;
3363 	opts.num_clusters = 4;
3364 
3365 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
3366 	CU_ASSERT(g_bserrno == 0);
3367 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3368 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3369 	blobid = g_blobid;
3370 
3371 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
3372 	CU_ASSERT(g_bserrno == 0);
3373 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3374 	blob = g_blob;
3375 
3376 	CU_ASSERT(blob->active.num_clusters == 4);
3377 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 4);
3378 	CU_ASSERT(blob->active.clusters[1] == 0);
3379 
3380 	_spdk_bs_claim_cluster(bs, 0xF);
3381 	_spdk_blob_insert_cluster_on_md_thread(blob, 1, 0xF, blob_op_complete, NULL);
3382 
3383 	CU_ASSERT(blob->active.clusters[1] != 0);
3384 
3385 	spdk_blob_close(blob, blob_op_complete, NULL);
3386 	CU_ASSERT(g_bserrno == 0);
3387 
3388 	/* Unload the blob store */
3389 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3390 	CU_ASSERT(g_bserrno == 0);
3391 	g_bs = NULL;
3392 	g_blob = NULL;
3393 	g_blobid = 0;
3394 
3395 	/* Load an existing blob store */
3396 	dev = init_dev();
3397 	spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL);
3398 	CU_ASSERT(g_bserrno == 0);
3399 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3400 
3401 	bs = g_bs;
3402 
3403 	spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
3404 	CU_ASSERT(g_bserrno == 0);
3405 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3406 	blob = g_blob;
3407 
3408 	CU_ASSERT(blob->active.clusters[1] != 0);
3409 
3410 	spdk_blob_close(blob, blob_op_complete, NULL);
3411 	CU_ASSERT(g_bserrno == 0);
3412 
3413 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
3414 	CU_ASSERT(g_bserrno == 0);
3415 
3416 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3417 	CU_ASSERT(g_bserrno == 0);
3418 	g_bs = NULL;
3419 }
3420 
3421 static void
3422 blob_thin_prov_rw(void)
3423 {
3424 	static const uint8_t zero[10 * 4096] = { 0 };
3425 	struct spdk_blob_store *bs;
3426 	struct spdk_bs_dev *dev;
3427 	struct spdk_blob *blob;
3428 	struct spdk_io_channel *channel;
3429 	struct spdk_blob_opts opts;
3430 	spdk_blob_id blobid;
3431 	uint64_t free_clusters;
3432 	uint8_t payload_read[10 * 4096];
3433 	uint8_t payload_write[10 * 4096];
3434 
3435 	dev = init_dev();
3436 
3437 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
3438 	CU_ASSERT(g_bserrno == 0);
3439 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3440 	bs = g_bs;
3441 	free_clusters = spdk_bs_free_cluster_count(bs);
3442 
3443 	channel = spdk_bs_alloc_io_channel(bs);
3444 	CU_ASSERT(channel != NULL);
3445 
3446 	spdk_blob_opts_init(&opts);
3447 	opts.thin_provision = true;
3448 
3449 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
3450 	CU_ASSERT(g_bserrno == 0);
3451 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3452 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3453 	blobid = g_blobid;
3454 
3455 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
3456 	CU_ASSERT(g_bserrno == 0);
3457 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3458 	blob = g_blob;
3459 
3460 	CU_ASSERT(blob->active.num_clusters == 0);
3461 
3462 	/* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */
3463 	spdk_blob_resize(blob, 5, blob_op_complete, NULL);
3464 	CU_ASSERT(g_bserrno == 0);
3465 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3466 	CU_ASSERT(blob->active.num_clusters == 5);
3467 
3468 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
3469 	CU_ASSERT(g_bserrno == 0);
3470 	/* Sync must not change anything */
3471 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3472 	CU_ASSERT(blob->active.num_clusters == 5);
3473 
3474 	/* Payload should be all zeros from unallocated clusters */
3475 	memset(payload_read, 0xFF, sizeof(payload_read));
3476 	spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL);
3477 	CU_ASSERT(g_bserrno == 0);
3478 	CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0);
3479 
3480 	memset(payload_write, 0xE5, sizeof(payload_write));
3481 	spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL);
3482 	CU_ASSERT(g_bserrno == 0);
3483 	CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs));
3484 
3485 	spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL);
3486 	CU_ASSERT(g_bserrno == 0);
3487 	CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0);
3488 
3489 	spdk_blob_close(blob, blob_op_complete, NULL);
3490 	CU_ASSERT(g_bserrno == 0);
3491 
3492 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
3493 	CU_ASSERT(g_bserrno == 0);
3494 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3495 
3496 	spdk_bs_free_io_channel(channel);
3497 
3498 	/* Unload the blob store */
3499 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3500 	CU_ASSERT(g_bserrno == 0);
3501 	g_bs = NULL;
3502 	g_blob = NULL;
3503 	g_blobid = 0;
3504 }
3505 
3506 static void
3507 blob_thin_prov_rw_iov(void)
3508 {
3509 	static const uint8_t zero[10 * 4096] = { 0 };
3510 	struct spdk_blob_store *bs;
3511 	struct spdk_bs_dev *dev;
3512 	struct spdk_blob *blob;
3513 	struct spdk_io_channel *channel;
3514 	struct spdk_blob_opts opts;
3515 	spdk_blob_id blobid;
3516 	uint64_t free_clusters;
3517 	uint8_t payload_read[10 * 4096];
3518 	uint8_t payload_write[10 * 4096];
3519 	struct iovec iov_read[3];
3520 	struct iovec iov_write[3];
3521 
3522 	dev = init_dev();
3523 
3524 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
3525 	CU_ASSERT(g_bserrno == 0);
3526 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3527 	bs = g_bs;
3528 	free_clusters = spdk_bs_free_cluster_count(bs);
3529 
3530 	channel = spdk_bs_alloc_io_channel(bs);
3531 	CU_ASSERT(channel != NULL);
3532 
3533 	spdk_blob_opts_init(&opts);
3534 	opts.thin_provision = true;
3535 
3536 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
3537 	CU_ASSERT(g_bserrno == 0);
3538 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3539 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3540 	blobid = g_blobid;
3541 
3542 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
3543 	CU_ASSERT(g_bserrno == 0);
3544 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3545 	blob = g_blob;
3546 
3547 	CU_ASSERT(blob->active.num_clusters == 0);
3548 
3549 	/* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */
3550 	spdk_blob_resize(blob, 5, blob_op_complete, NULL);
3551 	CU_ASSERT(g_bserrno == 0);
3552 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3553 	CU_ASSERT(blob->active.num_clusters == 5);
3554 
3555 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
3556 	CU_ASSERT(g_bserrno == 0);
3557 	/* Sync must not change anything */
3558 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3559 	CU_ASSERT(blob->active.num_clusters == 5);
3560 
3561 	/* Payload should be all zeros from unallocated clusters */
3562 	memset(payload_read, 0xAA, sizeof(payload_read));
3563 	iov_read[0].iov_base = payload_read;
3564 	iov_read[0].iov_len = 3 * 4096;
3565 	iov_read[1].iov_base = payload_read + 3 * 4096;
3566 	iov_read[1].iov_len = 4 * 4096;
3567 	iov_read[2].iov_base = payload_read + 7 * 4096;
3568 	iov_read[2].iov_len = 3 * 4096;
3569 	spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL);
3570 	CU_ASSERT(g_bserrno == 0);
3571 	CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0);
3572 
3573 	memset(payload_write, 0xE5, sizeof(payload_write));
3574 	iov_write[0].iov_base = payload_write;
3575 	iov_write[0].iov_len = 1 * 4096;
3576 	iov_write[1].iov_base = payload_write + 1 * 4096;
3577 	iov_write[1].iov_len = 5 * 4096;
3578 	iov_write[2].iov_base = payload_write + 6 * 4096;
3579 	iov_write[2].iov_len = 4 * 4096;
3580 
3581 	spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL);
3582 	CU_ASSERT(g_bserrno == 0);
3583 
3584 	memset(payload_read, 0xAA, sizeof(payload_read));
3585 	iov_read[0].iov_base = payload_read;
3586 	iov_read[0].iov_len = 3 * 4096;
3587 	iov_read[1].iov_base = payload_read + 3 * 4096;
3588 	iov_read[1].iov_len = 4 * 4096;
3589 	iov_read[2].iov_base = payload_read + 7 * 4096;
3590 	iov_read[2].iov_len = 3 * 4096;
3591 	spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL);
3592 	CU_ASSERT(g_bserrno == 0);
3593 	CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0);
3594 
3595 	spdk_blob_close(blob, blob_op_complete, NULL);
3596 	CU_ASSERT(g_bserrno == 0);
3597 
3598 	spdk_bs_free_io_channel(channel);
3599 
3600 	/* Unload the blob store */
3601 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3602 	CU_ASSERT(g_bserrno == 0);
3603 	g_bs = NULL;
3604 	g_blob = NULL;
3605 	g_blobid = 0;
3606 }
3607 
3608 struct iter_ctx {
3609 	int		current_iter;
3610 	spdk_blob_id	blobid[4];
3611 };
3612 
3613 static void
3614 test_iter(void *arg, struct spdk_blob *blob, int bserrno)
3615 {
3616 	struct iter_ctx *iter_ctx = arg;
3617 	spdk_blob_id blobid;
3618 
3619 	CU_ASSERT(bserrno == 0);
3620 	blobid = spdk_blob_get_id(blob);
3621 	CU_ASSERT(blobid == iter_ctx->blobid[iter_ctx->current_iter++]);
3622 }
3623 
3624 static void
3625 bs_load_iter(void)
3626 {
3627 	struct spdk_bs_dev *dev;
3628 	struct iter_ctx iter_ctx = { 0 };
3629 	struct spdk_blob *blob;
3630 	int i, rc;
3631 	struct spdk_bs_opts opts;
3632 
3633 	dev = init_dev();
3634 	spdk_bs_opts_init(&opts);
3635 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
3636 
3637 	/* Initialize a new blob store */
3638 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
3639 	CU_ASSERT(g_bserrno == 0);
3640 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3641 
3642 	for (i = 0; i < 4; i++) {
3643 		g_bserrno = -1;
3644 		g_blobid = SPDK_BLOBID_INVALID;
3645 		spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
3646 		CU_ASSERT(g_bserrno == 0);
3647 		CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3648 		iter_ctx.blobid[i] = g_blobid;
3649 
3650 		g_bserrno = -1;
3651 		g_blob = NULL;
3652 		spdk_bs_open_blob(g_bs, g_blobid, blob_op_with_handle_complete, NULL);
3653 		CU_ASSERT(g_bserrno == 0);
3654 		CU_ASSERT(g_blob != NULL);
3655 		blob = g_blob;
3656 
3657 		/* Just save the blobid as an xattr for testing purposes. */
3658 		rc = spdk_blob_set_xattr(blob, "blobid", &g_blobid, sizeof(g_blobid));
3659 		CU_ASSERT(rc == 0);
3660 
3661 		/* Resize the blob */
3662 		spdk_blob_resize(blob, i, blob_op_complete, NULL);
3663 		CU_ASSERT(g_bserrno == 0);
3664 
3665 		spdk_blob_close(blob, blob_op_complete, NULL);
3666 		CU_ASSERT(g_bserrno == 0);
3667 	}
3668 
3669 	g_bserrno = -1;
3670 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3671 	CU_ASSERT(g_bserrno == 0);
3672 
3673 	dev = init_dev();
3674 	spdk_bs_opts_init(&opts);
3675 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
3676 	opts.iter_cb_fn = test_iter;
3677 	opts.iter_cb_arg = &iter_ctx;
3678 
3679 	/* Test blob iteration during load after a clean shutdown. */
3680 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
3681 	CU_ASSERT(g_bserrno == 0);
3682 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3683 
3684 	/* Dirty shutdown */
3685 	_spdk_bs_free(g_bs);
3686 
3687 	dev = init_dev();
3688 	spdk_bs_opts_init(&opts);
3689 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
3690 	opts.iter_cb_fn = test_iter;
3691 	iter_ctx.current_iter = 0;
3692 	opts.iter_cb_arg = &iter_ctx;
3693 
3694 	/* Test blob iteration during load after a dirty shutdown. */
3695 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
3696 	CU_ASSERT(g_bserrno == 0);
3697 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3698 
3699 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3700 	CU_ASSERT(g_bserrno == 0);
3701 	g_bs = NULL;
3702 }
3703 
3704 static void
3705 blob_snapshot_rw(void)
3706 {
3707 	static const uint8_t zero[10 * 4096] = { 0 };
3708 	struct spdk_blob_store *bs;
3709 	struct spdk_bs_dev *dev;
3710 	struct spdk_blob *blob, *snapshot;
3711 	struct spdk_io_channel *channel;
3712 	struct spdk_blob_opts opts;
3713 	spdk_blob_id blobid, snapshotid;
3714 	uint64_t free_clusters;
3715 	uint8_t payload_read[10 * 4096];
3716 	uint8_t payload_write[10 * 4096];
3717 
3718 	dev = init_dev();
3719 
3720 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
3721 	CU_ASSERT(g_bserrno == 0);
3722 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3723 	bs = g_bs;
3724 	free_clusters = spdk_bs_free_cluster_count(bs);
3725 
3726 	channel = spdk_bs_alloc_io_channel(bs);
3727 	CU_ASSERT(channel != NULL);
3728 
3729 	spdk_blob_opts_init(&opts);
3730 	opts.thin_provision = true;
3731 	opts.num_clusters = 5;
3732 
3733 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
3734 	CU_ASSERT(g_bserrno == 0);
3735 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3736 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3737 	blobid = g_blobid;
3738 
3739 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
3740 	CU_ASSERT(g_bserrno == 0);
3741 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3742 	blob = g_blob;
3743 
3744 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5);
3745 
3746 	memset(payload_read, 0xFF, sizeof(payload_read));
3747 	spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL);
3748 	CU_ASSERT(g_bserrno == 0);
3749 	CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0);
3750 
3751 	memset(payload_write, 0xE5, sizeof(payload_write));
3752 	spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL);
3753 	CU_ASSERT(g_bserrno == 0);
3754 	CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs));
3755 
3756 	/* Create snapshot from blob */
3757 	spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL);
3758 	CU_ASSERT(g_bserrno == 0);
3759 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3760 	snapshotid = g_blobid;
3761 
3762 	spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL);
3763 	CU_ASSERT(g_bserrno == 0);
3764 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3765 	snapshot = g_blob;
3766 	CU_ASSERT(snapshot->data_ro == true)
3767 	CU_ASSERT(snapshot->md_ro == true)
3768 
3769 	CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 5)
3770 
3771 	memset(payload_write, 0xAA, sizeof(payload_write));
3772 	spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL);
3773 	CU_ASSERT(g_bserrno == 0);
3774 	CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs));
3775 
3776 	spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL);
3777 	CU_ASSERT(g_bserrno == 0);
3778 	CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0);
3779 
3780 	/* Data on snapshot should not change after write to clone */
3781 	memset(payload_write, 0xE5, sizeof(payload_write));
3782 	spdk_blob_io_read(snapshot, channel, payload_read, 4, 10, blob_op_complete, NULL);
3783 	CU_ASSERT(g_bserrno == 0);
3784 	CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0);
3785 
3786 	spdk_blob_close(blob, blob_op_complete, NULL);
3787 	CU_ASSERT(g_bserrno == 0);
3788 
3789 	spdk_blob_close(snapshot, blob_op_complete, NULL);
3790 	CU_ASSERT(g_bserrno == 0);
3791 
3792 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
3793 	CU_ASSERT(g_bserrno == 0);
3794 
3795 	spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL);
3796 	CU_ASSERT(g_bserrno == 0);
3797 
3798 	spdk_bs_free_io_channel(channel);
3799 
3800 	/* Unload the blob store */
3801 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3802 	CU_ASSERT(g_bserrno == 0);
3803 	g_bs = NULL;
3804 	g_blob = NULL;
3805 	g_blobid = 0;
3806 }
3807 
3808 static void
3809 blob_snapshot_rw_iov(void)
3810 {
3811 	static const uint8_t zero[10 * 4096] = { 0 };
3812 	struct spdk_blob_store *bs;
3813 	struct spdk_bs_dev *dev;
3814 	struct spdk_blob *blob, *snapshot;
3815 	struct spdk_io_channel *channel;
3816 	struct spdk_blob_opts opts;
3817 	spdk_blob_id blobid, snapshotid;
3818 	uint64_t free_clusters;
3819 	uint8_t payload_read[10 * 4096];
3820 	uint8_t payload_write[10 * 4096];
3821 	struct iovec iov_read[3];
3822 	struct iovec iov_write[3];
3823 
3824 	dev = init_dev();
3825 
3826 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
3827 	CU_ASSERT(g_bserrno == 0);
3828 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3829 	bs = g_bs;
3830 	free_clusters = spdk_bs_free_cluster_count(bs);
3831 
3832 	channel = spdk_bs_alloc_io_channel(bs);
3833 	CU_ASSERT(channel != NULL);
3834 
3835 	spdk_blob_opts_init(&opts);
3836 	opts.thin_provision = true;
3837 	opts.num_clusters = 5;
3838 
3839 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
3840 	CU_ASSERT(g_bserrno == 0);
3841 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3842 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3843 	blobid = g_blobid;
3844 
3845 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
3846 	CU_ASSERT(g_bserrno == 0);
3847 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3848 	blob = g_blob;
3849 
3850 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5);
3851 
3852 	/* Create snapshot from blob */
3853 	spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL);
3854 	CU_ASSERT(g_bserrno == 0);
3855 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3856 	snapshotid = g_blobid;
3857 
3858 	spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL);
3859 	CU_ASSERT(g_bserrno == 0);
3860 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3861 	snapshot = g_blob;
3862 	CU_ASSERT(snapshot->data_ro == true)
3863 	CU_ASSERT(snapshot->md_ro == true)
3864 	CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 5);
3865 
3866 	/* Payload should be all zeros from unallocated clusters */
3867 	memset(payload_read, 0xAA, sizeof(payload_read));
3868 	iov_read[0].iov_base = payload_read;
3869 	iov_read[0].iov_len = 3 * 4096;
3870 	iov_read[1].iov_base = payload_read + 3 * 4096;
3871 	iov_read[1].iov_len = 4 * 4096;
3872 	iov_read[2].iov_base = payload_read + 7 * 4096;
3873 	iov_read[2].iov_len = 3 * 4096;
3874 	spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL);
3875 	CU_ASSERT(g_bserrno == 0);
3876 	CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0);
3877 
3878 	memset(payload_write, 0xE5, sizeof(payload_write));
3879 	iov_write[0].iov_base = payload_write;
3880 	iov_write[0].iov_len = 1 * 4096;
3881 	iov_write[1].iov_base = payload_write + 1 * 4096;
3882 	iov_write[1].iov_len = 5 * 4096;
3883 	iov_write[2].iov_base = payload_write + 6 * 4096;
3884 	iov_write[2].iov_len = 4 * 4096;
3885 
3886 	spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL);
3887 	CU_ASSERT(g_bserrno == 0);
3888 
3889 	memset(payload_read, 0xAA, sizeof(payload_read));
3890 	iov_read[0].iov_base = payload_read;
3891 	iov_read[0].iov_len = 3 * 4096;
3892 	iov_read[1].iov_base = payload_read + 3 * 4096;
3893 	iov_read[1].iov_len = 4 * 4096;
3894 	iov_read[2].iov_base = payload_read + 7 * 4096;
3895 	iov_read[2].iov_len = 3 * 4096;
3896 	spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL);
3897 	CU_ASSERT(g_bserrno == 0);
3898 	CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0);
3899 
3900 	spdk_blob_close(blob, blob_op_complete, NULL);
3901 	CU_ASSERT(g_bserrno == 0);
3902 
3903 	spdk_blob_close(snapshot, blob_op_complete, NULL);
3904 	CU_ASSERT(g_bserrno == 0);
3905 
3906 	spdk_bs_free_io_channel(channel);
3907 
3908 	/* Unload the blob store */
3909 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3910 	CU_ASSERT(g_bserrno == 0);
3911 	g_bs = NULL;
3912 	g_blob = NULL;
3913 	g_blobid = 0;
3914 }
3915 
3916 static void
3917 blob_inflate_rw(void)
3918 {
3919 	static uint8_t *zero;
3920 	struct spdk_blob_store *bs;
3921 	struct spdk_bs_dev *dev;
3922 	struct spdk_blob *blob, *snapshot;
3923 	struct spdk_io_channel *channel;
3924 	struct spdk_blob_opts opts;
3925 	spdk_blob_id blobid, snapshotid;
3926 	uint64_t free_clusters;
3927 	uint64_t cluster_size;
3928 
3929 	uint64_t payload_size;
3930 	uint8_t *payload_read;
3931 	uint8_t *payload_write;
3932 	uint8_t *payload_clone;
3933 
3934 	uint64_t pages_per_cluster;
3935 	uint64_t pages_per_payload;
3936 
3937 	int i;
3938 
3939 	dev = init_dev();
3940 
3941 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
3942 	CU_ASSERT(g_bserrno == 0);
3943 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3944 	bs = g_bs;
3945 
3946 	free_clusters = spdk_bs_free_cluster_count(bs);
3947 	cluster_size = spdk_bs_get_cluster_size(bs);
3948 	pages_per_cluster = cluster_size / spdk_bs_get_page_size(bs);
3949 	pages_per_payload = pages_per_cluster * 5;
3950 
3951 	payload_size = cluster_size * 5;
3952 
3953 	payload_read = malloc(payload_size);
3954 	SPDK_CU_ASSERT_FATAL(payload_read != NULL);
3955 
3956 	payload_write = malloc(payload_size);
3957 	SPDK_CU_ASSERT_FATAL(payload_write != NULL);
3958 
3959 	payload_clone = malloc(payload_size);
3960 	SPDK_CU_ASSERT_FATAL(payload_clone != NULL);
3961 
3962 	zero = calloc(1, payload_size);
3963 	SPDK_CU_ASSERT_FATAL(zero != NULL);
3964 
3965 	channel = spdk_bs_alloc_io_channel(bs);
3966 	SPDK_CU_ASSERT_FATAL(channel != NULL);
3967 
3968 	/* Create blob */
3969 	spdk_blob_opts_init(&opts);
3970 	opts.thin_provision = true;
3971 	opts.num_clusters = 5;
3972 
3973 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
3974 	CU_ASSERT(g_bserrno == 0);
3975 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3976 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3977 	blobid = g_blobid;
3978 
3979 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
3980 	CU_ASSERT(g_bserrno == 0);
3981 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3982 	blob = g_blob;
3983 
3984 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5);
3985 
3986 	/* Initial read should return zeroed payload */
3987 	memset(payload_read, 0xFF, payload_size);
3988 	spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, blob_op_complete, NULL);
3989 	CU_ASSERT(g_bserrno == 0);
3990 	CU_ASSERT(memcmp(zero, payload_read, payload_size) == 0);
3991 
3992 	/* Fill whole blob with a pattern */
3993 	memset(payload_write, 0xE5, payload_size);
3994 	spdk_blob_io_write(blob, channel, payload_write, 0, pages_per_payload,
3995 			   blob_op_complete, NULL);
3996 	CU_ASSERT(g_bserrno == 0);
3997 	CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs));
3998 
3999 	/* Create snapshot from blob */
4000 	spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL);
4001 	CU_ASSERT(g_bserrno == 0);
4002 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
4003 	snapshotid = g_blobid;
4004 
4005 	spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL);
4006 	CU_ASSERT(g_bserrno == 0);
4007 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4008 	snapshot = g_blob;
4009 	CU_ASSERT(snapshot->data_ro == true)
4010 	CU_ASSERT(snapshot->md_ro == true)
4011 
4012 	CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 5)
4013 
4014 	/* Write every second cluster with a pattern.
4015 	 *
4016 	 * payload_clone stores expected result on "blob" read at the time and
4017 	 * is used only to check data consistency on clone before and after
4018 	 * inflation. Initially we fill it with a backing snapshots pattern
4019 	 * used before.
4020 	 */
4021 	memset(payload_clone, 0xE5, payload_size);
4022 	memset(payload_write, 0xAA, payload_size);
4023 	for (i = 1; i < 5; i += 2) {
4024 		spdk_blob_io_write(blob, channel, payload_write, i * pages_per_cluster,
4025 				   pages_per_cluster, blob_op_complete, NULL);
4026 		CU_ASSERT(g_bserrno == 0);
4027 
4028 		/* Update expected result */
4029 		memcpy(payload_clone + (cluster_size * i), payload_write,
4030 		       cluster_size);
4031 	}
4032 	CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs));
4033 
4034 	/* Check data consistency on clone */
4035 	memset(payload_read, 0xFF, payload_size);
4036 	spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload,
4037 			  blob_op_complete, NULL);
4038 	CU_ASSERT(g_bserrno == 0);
4039 	CU_ASSERT(memcmp(payload_clone, payload_read, payload_size) == 0);
4040 
4041 	/* Close all blobs */
4042 	spdk_blob_close(blob, blob_op_complete, NULL);
4043 	CU_ASSERT(g_bserrno == 0);
4044 
4045 	spdk_blob_close(snapshot, blob_op_complete, NULL);
4046 	CU_ASSERT(g_bserrno == 0);
4047 
4048 	/* Inflate blob */
4049 	spdk_bs_inflate_blob(bs, channel, blobid, blob_op_complete, NULL);
4050 	CU_ASSERT(g_bserrno == 0);
4051 
4052 	/* Try to delete snapshot (should pass) */
4053 	spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL);
4054 	CU_ASSERT(g_bserrno == 0);
4055 
4056 	/* Reopen blob after snapshot deletion */
4057 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
4058 	CU_ASSERT(g_bserrno == 0);
4059 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4060 	blob = g_blob;
4061 
4062 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5);
4063 
4064 	/* Check data consistency on inflated blob */
4065 	memset(payload_read, 0xFF, payload_size);
4066 	spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, blob_op_complete, NULL);
4067 	CU_ASSERT(g_bserrno == 0);
4068 	CU_ASSERT(memcmp(payload_clone, payload_read, payload_size) == 0);
4069 
4070 	spdk_blob_close(blob, blob_op_complete, NULL);
4071 	CU_ASSERT(g_bserrno == 0);
4072 
4073 	spdk_bs_free_io_channel(channel);
4074 
4075 	/* Unload the blob store */
4076 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
4077 	CU_ASSERT(g_bserrno == 0);
4078 	g_bs = NULL;
4079 	g_blob = NULL;
4080 	g_blobid = 0;
4081 
4082 	free(payload_read);
4083 	free(payload_write);
4084 	free(payload_clone);
4085 	free(zero);
4086 }
4087 
4088 /**
4089  * Snapshot-clones relation test
4090  *
4091  *      snapshot
4092  *          |
4093  *     +----+----+
4094  *     |         |
4095  *   blob      clone
4096  *     |
4097  *  clone2
4098  */
4099 static void
4100 blob_relations(void)
4101 {
4102 	struct spdk_blob_store *bs;
4103 	struct spdk_bs_dev *dev;
4104 	struct spdk_bs_opts bs_opts;
4105 	struct spdk_blob_opts opts;
4106 	struct spdk_blob *blob, *snapshot, *clone, *clone2;
4107 	spdk_blob_id blobid, cloneid, snapshotid, cloneid2;
4108 	int rc;
4109 	size_t count;
4110 	spdk_blob_id ids[10];
4111 
4112 	dev = init_dev();
4113 	spdk_bs_opts_init(&bs_opts);
4114 	snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE");
4115 
4116 	spdk_bs_init(dev, &bs_opts, bs_op_with_handle_complete, NULL);
4117 	CU_ASSERT(g_bserrno == 0);
4118 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
4119 	bs = g_bs;
4120 
4121 	/* 1. Create blob with 10 clusters */
4122 
4123 	spdk_blob_opts_init(&opts);
4124 	opts.num_clusters = 10;
4125 
4126 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
4127 	CU_ASSERT(g_bserrno == 0);
4128 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
4129 	blobid = g_blobid;
4130 
4131 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
4132 	CU_ASSERT(g_bserrno == 0);
4133 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4134 	blob = g_blob;
4135 
4136 	CU_ASSERT(!spdk_blob_is_read_only(blob));
4137 	CU_ASSERT(!spdk_blob_is_snapshot(blob));
4138 	CU_ASSERT(!spdk_blob_is_clone(blob));
4139 	CU_ASSERT(!spdk_blob_is_thin_provisioned(blob));
4140 
4141 	/* blob should not have underlying snapshot nor clones */
4142 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == SPDK_BLOBID_INVALID);
4143 	count = SPDK_COUNTOF(ids);
4144 	rc = spdk_blob_get_clones(bs, blobid, ids, &count);
4145 	CU_ASSERT(rc == 0);
4146 	CU_ASSERT(count == 0);
4147 
4148 
4149 	/* 2. Create snapshot */
4150 
4151 	spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL);
4152 	CU_ASSERT(g_bserrno == 0);
4153 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
4154 	snapshotid = g_blobid;
4155 
4156 	spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL);
4157 	CU_ASSERT(g_bserrno == 0);
4158 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4159 	snapshot = g_blob;
4160 
4161 	CU_ASSERT(spdk_blob_is_read_only(snapshot));
4162 	CU_ASSERT(spdk_blob_is_snapshot(snapshot));
4163 	CU_ASSERT(!spdk_blob_is_clone(snapshot));
4164 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid) == SPDK_BLOBID_INVALID);
4165 
4166 	/* Check if original blob is converted to the clone of snapshot */
4167 	CU_ASSERT(!spdk_blob_is_read_only(blob));
4168 	CU_ASSERT(!spdk_blob_is_snapshot(blob));
4169 	CU_ASSERT(spdk_blob_is_clone(blob));
4170 	CU_ASSERT(spdk_blob_is_thin_provisioned(blob));
4171 
4172 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid);
4173 
4174 	count = SPDK_COUNTOF(ids);
4175 	rc = spdk_blob_get_clones(bs, snapshotid, ids, &count);
4176 	CU_ASSERT(rc == 0);
4177 	CU_ASSERT(count == 1);
4178 	CU_ASSERT(ids[0] == blobid);
4179 
4180 
4181 	/* 3. Create clone from snapshot */
4182 
4183 	spdk_bs_create_clone(bs, snapshotid, NULL, blob_op_with_id_complete, NULL);
4184 	CU_ASSERT(g_bserrno == 0);
4185 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
4186 	cloneid = g_blobid;
4187 
4188 	spdk_bs_open_blob(bs, cloneid, blob_op_with_handle_complete, NULL);
4189 	CU_ASSERT(g_bserrno == 0);
4190 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4191 	clone = g_blob;
4192 
4193 	CU_ASSERT(!spdk_blob_is_read_only(clone));
4194 	CU_ASSERT(!spdk_blob_is_snapshot(clone));
4195 	CU_ASSERT(spdk_blob_is_clone(clone));
4196 	CU_ASSERT(spdk_blob_is_thin_provisioned(clone));
4197 
4198 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid);
4199 
4200 	count = SPDK_COUNTOF(ids);
4201 	rc = spdk_blob_get_clones(bs, cloneid, ids, &count);
4202 	CU_ASSERT(rc == 0);
4203 	CU_ASSERT(count == 0);
4204 
4205 	/* Check if clone is on the snapshot's list */
4206 	count = SPDK_COUNTOF(ids);
4207 	rc = spdk_blob_get_clones(bs, snapshotid, ids, &count);
4208 	CU_ASSERT(rc == 0);
4209 	CU_ASSERT(ids[0] == blobid || ids[1] == blobid);
4210 	CU_ASSERT(ids[0] == cloneid || ids[1] == cloneid);
4211 
4212 
4213 	/* 4. Try to create clone from read only blob */
4214 
4215 	/* Mark blob as read only */
4216 	spdk_blob_set_read_only(blob);
4217 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
4218 	CU_ASSERT(g_bserrno == 0);
4219 
4220 	/* Check if previously created blob is read only clone */
4221 	CU_ASSERT(spdk_blob_is_read_only(blob));
4222 	CU_ASSERT(!spdk_blob_is_snapshot(blob));
4223 	CU_ASSERT(spdk_blob_is_clone(blob));
4224 	CU_ASSERT(spdk_blob_is_thin_provisioned(blob));
4225 
4226 	/* Create clone from read only blob */
4227 	spdk_bs_create_clone(bs, blobid, NULL, blob_op_with_id_complete, NULL);
4228 	CU_ASSERT(g_bserrno == 0);
4229 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
4230 	cloneid2 = g_blobid;
4231 
4232 	spdk_bs_open_blob(bs, cloneid2, blob_op_with_handle_complete, NULL);
4233 	CU_ASSERT(g_bserrno == 0);
4234 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4235 	clone2 = g_blob;
4236 
4237 	CU_ASSERT(!spdk_blob_is_read_only(clone2));
4238 	CU_ASSERT(!spdk_blob_is_snapshot(clone2));
4239 	CU_ASSERT(spdk_blob_is_clone(clone2));
4240 	CU_ASSERT(spdk_blob_is_thin_provisioned(clone2));
4241 
4242 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid2) == blobid);
4243 
4244 	count = SPDK_COUNTOF(ids);
4245 	rc = spdk_blob_get_clones(bs, blobid, ids, &count);
4246 	CU_ASSERT(rc == 0);
4247 
4248 	CU_ASSERT(count == 1);
4249 	CU_ASSERT(ids[0] == cloneid2);
4250 
4251 	/* Close blobs */
4252 
4253 	spdk_blob_close(clone2, blob_op_complete, NULL);
4254 	CU_ASSERT(g_bserrno == 0);
4255 
4256 	spdk_blob_close(blob, blob_op_complete, NULL);
4257 	CU_ASSERT(g_bserrno == 0);
4258 
4259 	spdk_blob_close(clone, blob_op_complete, NULL);
4260 	CU_ASSERT(g_bserrno == 0);
4261 
4262 	spdk_blob_close(snapshot, blob_op_complete, NULL);
4263 	CU_ASSERT(g_bserrno == 0);
4264 
4265 	/* Try to delete snapshot with created clones */
4266 	spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL);
4267 	CU_ASSERT(g_bserrno != 0);
4268 
4269 	spdk_bs_unload(bs, bs_op_complete, NULL);
4270 	CU_ASSERT(g_bserrno == 0);
4271 	g_bs = NULL;
4272 
4273 	/* Load an existing blob store */
4274 	dev = init_dev();
4275 	snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE");
4276 
4277 	spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL);
4278 	CU_ASSERT(g_bserrno == 0);
4279 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
4280 	bs = g_bs;
4281 
4282 
4283 	/* NULL ids array should return number of clones in count */
4284 	count = SPDK_COUNTOF(ids);
4285 	rc = spdk_blob_get_clones(bs, snapshotid, NULL, &count);
4286 	CU_ASSERT(rc == -ENOMEM);
4287 	CU_ASSERT(count == 2);
4288 
4289 	/* incorrect array size */
4290 	count = 1;
4291 	rc = spdk_blob_get_clones(bs, snapshotid, ids, &count);
4292 	CU_ASSERT(rc == -ENOMEM);
4293 	CU_ASSERT(count == 2);
4294 
4295 
4296 	/* Verify structure of loaded blob store */
4297 
4298 	/* snapshot */
4299 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid) == SPDK_BLOBID_INVALID);
4300 
4301 	count = SPDK_COUNTOF(ids);
4302 	rc = spdk_blob_get_clones(bs, snapshotid, ids, &count);
4303 	CU_ASSERT(rc == 0);
4304 	CU_ASSERT(count == 2);
4305 	CU_ASSERT(ids[0] == blobid || ids[1] == blobid);
4306 	CU_ASSERT(ids[0] == cloneid || ids[1] == cloneid);
4307 
4308 	/* blob */
4309 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid);
4310 	count = SPDK_COUNTOF(ids);
4311 	rc = spdk_blob_get_clones(bs, blobid, ids, &count);
4312 	CU_ASSERT(rc == 0);
4313 	CU_ASSERT(count == 1);
4314 	CU_ASSERT(ids[0] == cloneid2);
4315 
4316 	/* clone */
4317 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid);
4318 	count = SPDK_COUNTOF(ids);
4319 	rc = spdk_blob_get_clones(bs, cloneid, ids, &count);
4320 	CU_ASSERT(rc == 0);
4321 	CU_ASSERT(count == 0);
4322 
4323 	/* clone2 */
4324 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid2) == blobid);
4325 	count = SPDK_COUNTOF(ids);
4326 	rc = spdk_blob_get_clones(bs, cloneid2, ids, &count);
4327 	CU_ASSERT(rc == 0);
4328 	CU_ASSERT(count == 0);
4329 
4330 	/* Try to delete all blobs */
4331 	spdk_bs_delete_blob(bs, cloneid, blob_op_complete, NULL);
4332 	CU_ASSERT(g_bserrno == 0);
4333 
4334 	/* Try to delete snapshot with clones */
4335 	spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL);
4336 	CU_ASSERT(g_bserrno != 0);
4337 
4338 	/* Try to delete ro blob with clones */
4339 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
4340 	CU_ASSERT(g_bserrno != 0);
4341 
4342 	spdk_bs_delete_blob(bs, cloneid2, blob_op_complete, NULL);
4343 	CU_ASSERT(g_bserrno == 0);
4344 
4345 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
4346 	CU_ASSERT(g_bserrno == 0);
4347 
4348 	spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL);
4349 	CU_ASSERT(g_bserrno == 0);
4350 
4351 	spdk_bs_unload(bs, bs_op_complete, NULL);
4352 	CU_ASSERT(g_bserrno == 0);
4353 
4354 	g_bs = NULL;
4355 }
4356 
4357 int main(int argc, char **argv)
4358 {
4359 	CU_pSuite	suite = NULL;
4360 	unsigned int	num_failures;
4361 
4362 	if (CU_initialize_registry() != CUE_SUCCESS) {
4363 		return CU_get_error();
4364 	}
4365 
4366 	suite = CU_add_suite("blob", NULL, NULL);
4367 	if (suite == NULL) {
4368 		CU_cleanup_registry();
4369 		return CU_get_error();
4370 	}
4371 
4372 	if (
4373 		CU_add_test(suite, "blob_init", blob_init) == NULL ||
4374 		CU_add_test(suite, "blob_open", blob_open) == NULL ||
4375 		CU_add_test(suite, "blob_create", blob_create) == NULL ||
4376 		CU_add_test(suite, "blob_create_internal", blob_create_internal) == NULL ||
4377 		CU_add_test(suite, "blob_thin_provision", blob_thin_provision) == NULL ||
4378 		CU_add_test(suite, "blob_snapshot", blob_snapshot) == NULL ||
4379 		CU_add_test(suite, "blob_clone", blob_clone) == NULL ||
4380 		CU_add_test(suite, "blob_inflate", blob_inflate) == NULL ||
4381 		CU_add_test(suite, "blob_delete", blob_delete) == NULL ||
4382 		CU_add_test(suite, "blob_resize", blob_resize) == NULL ||
4383 		CU_add_test(suite, "blob_read_only", blob_read_only) == NULL ||
4384 		CU_add_test(suite, "channel_ops", channel_ops) == NULL ||
4385 		CU_add_test(suite, "blob_super", blob_super) == NULL ||
4386 		CU_add_test(suite, "blob_write", blob_write) == NULL ||
4387 		CU_add_test(suite, "blob_read", blob_read) == NULL ||
4388 		CU_add_test(suite, "blob_rw_verify", blob_rw_verify) == NULL ||
4389 		CU_add_test(suite, "blob_rw_verify_iov", blob_rw_verify_iov) == NULL ||
4390 		CU_add_test(suite, "blob_rw_verify_iov_nomem", blob_rw_verify_iov_nomem) == NULL ||
4391 		CU_add_test(suite, "blob_rw_iov_read_only", blob_rw_iov_read_only) == NULL ||
4392 		CU_add_test(suite, "blob_unmap", blob_unmap) == NULL ||
4393 		CU_add_test(suite, "blob_iter", blob_iter) == NULL ||
4394 		CU_add_test(suite, "blob_xattr", blob_xattr) == NULL ||
4395 		CU_add_test(suite, "bs_load", bs_load) == NULL ||
4396 		CU_add_test(suite, "bs_unload", bs_unload) == NULL ||
4397 		CU_add_test(suite, "bs_cluster_sz", bs_cluster_sz) == NULL ||
4398 		CU_add_test(suite, "bs_usable_clusters", bs_usable_clusters) == NULL ||
4399 		CU_add_test(suite, "bs_resize_md", bs_resize_md) == NULL ||
4400 		CU_add_test(suite, "bs_destroy", bs_destroy) == NULL ||
4401 		CU_add_test(suite, "bs_type", bs_type) == NULL ||
4402 		CU_add_test(suite, "bs_super_block", bs_super_block) == NULL ||
4403 		CU_add_test(suite, "blob_serialize", blob_serialize) == NULL ||
4404 		CU_add_test(suite, "blob_crc", blob_crc) == NULL ||
4405 		CU_add_test(suite, "super_block_crc", super_block_crc) == NULL ||
4406 		CU_add_test(suite, "blob_dirty_shutdown", blob_dirty_shutdown) == NULL ||
4407 		CU_add_test(suite, "blob_flags", blob_flags) == NULL ||
4408 		CU_add_test(suite, "bs_version", bs_version) == NULL ||
4409 		CU_add_test(suite, "blob_set_xattrs", blob_set_xattrs) == NULL ||
4410 		CU_add_test(suite, "blob_thin_prov_alloc", blob_thin_prov_alloc) == NULL ||
4411 		CU_add_test(suite, "blob_insert_cluster_msg", blob_insert_cluster_msg) == NULL ||
4412 		CU_add_test(suite, "blob_thin_prov_rw", blob_thin_prov_rw) == NULL ||
4413 		CU_add_test(suite, "blob_thin_prov_rw_iov", blob_thin_prov_rw_iov) == NULL ||
4414 		CU_add_test(suite, "bs_load_iter", bs_load_iter) == NULL ||
4415 		CU_add_test(suite, "blob_snapshot_rw", blob_snapshot_rw) == NULL ||
4416 		CU_add_test(suite, "blob_snapshot_rw_iov", blob_snapshot_rw_iov) == NULL ||
4417 		CU_add_test(suite, "blob_inflate_rw", blob_inflate_rw) == NULL ||
4418 		CU_add_test(suite, "blob_relations", blob_relations) == NULL ||
4419 		CU_add_test(suite, "blob_snapshot_freeze_io", blob_snapshot_freeze_io) == NULL
4420 	) {
4421 		CU_cleanup_registry();
4422 		return CU_get_error();
4423 	}
4424 
4425 	g_dev_buffer = calloc(1, DEV_BUFFER_SIZE);
4426 	spdk_allocate_thread(_bs_send_msg, NULL, NULL, NULL, "thread0");
4427 	CU_basic_set_mode(CU_BRM_VERBOSE);
4428 	CU_basic_run_tests();
4429 	num_failures = CU_get_number_of_failures();
4430 	CU_cleanup_registry();
4431 	spdk_free_thread();
4432 	free(g_dev_buffer);
4433 	return num_failures;
4434 }
4435