xref: /spdk/test/unit/lib/blob/blob.c/blob_ut.c (revision c94020001adcc0d8fae89ff7902e2e0f2243e25d)
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(bool decouple_parent)
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 	opts.thin_provision = true;
895 
896 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
897 	CU_ASSERT(g_bserrno == 0);
898 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
899 	blobid = g_blobid;
900 
901 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
902 	CU_ASSERT(g_bserrno == 0);
903 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
904 	blob = g_blob;
905 
906 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10)
907 	CU_ASSERT(spdk_blob_is_thin_provisioned(blob) == true);
908 
909 	/* 1) Blob with no parent */
910 	if (decouple_parent) {
911 		/* Decouple parent of blob with no parent (should fail) */
912 		spdk_bs_blob_decouple_parent(bs, channel, blobid, blob_op_complete, NULL);
913 		CU_ASSERT(g_bserrno != 0);
914 	} else {
915 		/* Inflate of thin blob with no parent should made it thick */
916 		spdk_bs_inflate_blob(bs, channel, blobid, blob_op_complete, NULL);
917 		CU_ASSERT(g_bserrno == 0);
918 		CU_ASSERT(spdk_blob_is_thin_provisioned(blob) == false);
919 	}
920 
921 	spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL);
922 	CU_ASSERT(g_bserrno == 0);
923 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
924 	snapshotid = g_blobid;
925 
926 	CU_ASSERT(spdk_blob_is_thin_provisioned(blob) == true);
927 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10)
928 
929 	spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL);
930 	CU_ASSERT(g_bserrno == 0);
931 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
932 	snapshot = g_blob;
933 	CU_ASSERT(snapshot->data_ro == true)
934 	CU_ASSERT(snapshot->md_ro == true)
935 	CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 10);
936 
937 	spdk_blob_close(snapshot, blob_op_complete, NULL);
938 	CU_ASSERT(g_bserrno == 0);
939 
940 	free_clusters = spdk_bs_free_cluster_count(bs);
941 
942 	/* 2) Blob with parent */
943 	if (!decouple_parent) {
944 		/* Do full blob inflation */
945 		spdk_bs_inflate_blob(bs, channel, blobid, blob_op_complete, NULL);
946 		CU_ASSERT(g_bserrno == 0);
947 		/* all 10 clusters should be allocated */
948 		CU_ASSERT(spdk_bs_free_cluster_count(bs) == free_clusters - 10);
949 	} else {
950 		/* Decouple parent of blob */
951 		spdk_bs_blob_decouple_parent(bs, channel, blobid, blob_op_complete, NULL);
952 		CU_ASSERT(g_bserrno == 0);
953 		/* when only parent is removed, none of the clusters should be allocated */
954 		CU_ASSERT(spdk_bs_free_cluster_count(bs) == free_clusters);
955 	}
956 
957 	/* Now, it should be possible to delete snapshot */
958 	spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL);
959 	CU_ASSERT(g_bserrno == 0);
960 
961 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10)
962 	CU_ASSERT(spdk_blob_is_thin_provisioned(blob) == decouple_parent);
963 
964 	spdk_blob_close(blob, blob_op_complete, NULL);
965 	CU_ASSERT(g_bserrno == 0);
966 
967 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
968 	CU_ASSERT(g_bserrno == 0);
969 	g_bs = NULL;
970 
971 	spdk_bs_free_io_channel(channel);
972 }
973 
974 static void
975 blob_inflate(void)
976 {
977 	_blob_inflate(false);
978 	_blob_inflate(true);
979 }
980 
981 static void
982 blob_delete(void)
983 {
984 	struct spdk_blob_store *bs;
985 	struct spdk_bs_dev *dev;
986 	spdk_blob_id blobid;
987 
988 	dev = init_dev();
989 
990 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
991 	CU_ASSERT(g_bserrno == 0);
992 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
993 	bs = g_bs;
994 
995 	/* Create a blob and then delete it. */
996 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
997 	CU_ASSERT(g_bserrno == 0);
998 	CU_ASSERT(g_blobid > 0);
999 	blobid = g_blobid;
1000 
1001 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
1002 	CU_ASSERT(g_bserrno == 0);
1003 
1004 	/* Try to open the blob */
1005 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1006 	CU_ASSERT(g_bserrno == -ENOENT);
1007 
1008 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1009 	CU_ASSERT(g_bserrno == 0);
1010 	g_bs = NULL;
1011 }
1012 
1013 static void
1014 blob_resize(void)
1015 {
1016 	struct spdk_blob_store *bs;
1017 	struct spdk_bs_dev *dev;
1018 	struct spdk_blob *blob;
1019 	spdk_blob_id blobid;
1020 	uint64_t free_clusters;
1021 
1022 	dev = init_dev();
1023 
1024 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1025 	CU_ASSERT(g_bserrno == 0);
1026 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1027 	bs = g_bs;
1028 	free_clusters = spdk_bs_free_cluster_count(bs);
1029 
1030 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
1031 	CU_ASSERT(g_bserrno == 0);
1032 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1033 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
1034 	blobid = g_blobid;
1035 
1036 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1037 	CU_ASSERT(g_bserrno == 0);
1038 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1039 	blob = g_blob;
1040 
1041 	/* Confirm that resize fails if blob is marked read-only. */
1042 	blob->md_ro = true;
1043 	spdk_blob_resize(blob, 5, blob_op_complete, NULL);
1044 	CU_ASSERT(g_bserrno == -EPERM);
1045 	blob->md_ro = false;
1046 
1047 	/* The blob started at 0 clusters. Resize it to be 5. */
1048 	spdk_blob_resize(blob, 5, blob_op_complete, NULL);
1049 	CU_ASSERT(g_bserrno == 0);
1050 	CU_ASSERT((free_clusters - 5) == spdk_bs_free_cluster_count(bs));
1051 
1052 	/* Shrink the blob to 3 clusters. This will not actually release
1053 	 * the old clusters until the blob is synced.
1054 	 */
1055 	spdk_blob_resize(blob, 3, blob_op_complete, NULL);
1056 	CU_ASSERT(g_bserrno == 0);
1057 	/* Verify there are still 5 clusters in use */
1058 	CU_ASSERT((free_clusters - 5) == spdk_bs_free_cluster_count(bs));
1059 
1060 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
1061 	CU_ASSERT(g_bserrno == 0);
1062 	/* Now there are only 3 clusters in use */
1063 	CU_ASSERT((free_clusters - 3) == spdk_bs_free_cluster_count(bs));
1064 
1065 	/* Resize the blob to be 10 clusters. Growth takes effect immediately. */
1066 	spdk_blob_resize(blob, 10, blob_op_complete, NULL);
1067 	CU_ASSERT(g_bserrno == 0);
1068 	CU_ASSERT((free_clusters - 10) == spdk_bs_free_cluster_count(bs));
1069 
1070 	/* Try to resize the blob to size larger than blobstore. */
1071 	spdk_blob_resize(blob, bs->total_clusters + 1, blob_op_complete, NULL);
1072 	CU_ASSERT(g_bserrno == -ENOSPC);
1073 
1074 	spdk_blob_close(blob, blob_op_complete, NULL);
1075 	CU_ASSERT(g_bserrno == 0);
1076 
1077 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
1078 	CU_ASSERT(g_bserrno == 0);
1079 
1080 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1081 	CU_ASSERT(g_bserrno == 0);
1082 	g_bs = NULL;
1083 }
1084 
1085 static void
1086 blob_read_only(void)
1087 {
1088 	struct spdk_blob_store *bs;
1089 	struct spdk_bs_dev *dev;
1090 	struct spdk_blob *blob;
1091 	struct spdk_bs_opts opts;
1092 	spdk_blob_id blobid;
1093 	int rc;
1094 
1095 	dev = init_dev();
1096 	spdk_bs_opts_init(&opts);
1097 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
1098 
1099 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
1100 	CU_ASSERT(g_bserrno == 0);
1101 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1102 	bs = g_bs;
1103 
1104 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
1105 	CU_ASSERT(g_bserrno == 0);
1106 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1107 	blobid = g_blobid;
1108 
1109 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1110 	CU_ASSERT(g_bserrno == 0);
1111 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1112 	blob = g_blob;
1113 
1114 	rc = spdk_blob_set_read_only(blob);
1115 	CU_ASSERT(rc == 0);
1116 
1117 	CU_ASSERT(blob->data_ro == false);
1118 	CU_ASSERT(blob->md_ro == false);
1119 
1120 	spdk_blob_sync_md(blob, bs_op_complete, NULL);
1121 
1122 	CU_ASSERT(blob->data_ro == true);
1123 	CU_ASSERT(blob->md_ro == true);
1124 	CU_ASSERT(blob->data_ro_flags & SPDK_BLOB_READ_ONLY);
1125 
1126 	spdk_blob_close(blob, blob_op_complete, NULL);
1127 	CU_ASSERT(g_bserrno == 0);
1128 
1129 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1130 	CU_ASSERT(g_bserrno == 0);
1131 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1132 	blob = g_blob;
1133 
1134 	CU_ASSERT(blob->data_ro == true);
1135 	CU_ASSERT(blob->md_ro == true);
1136 	CU_ASSERT(blob->data_ro_flags & SPDK_BLOB_READ_ONLY);
1137 
1138 	spdk_blob_close(blob, blob_op_complete, NULL);
1139 	CU_ASSERT(g_bserrno == 0);
1140 
1141 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1142 	CU_ASSERT(g_bserrno == 0);
1143 	g_bs = NULL;
1144 	g_blob = NULL;
1145 	g_blobid = 0;
1146 
1147 	/* Load an existing blob store */
1148 	dev = init_dev();
1149 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
1150 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
1151 	CU_ASSERT(g_bserrno == 0);
1152 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1153 
1154 	spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
1155 	CU_ASSERT(g_bserrno == 0);
1156 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1157 	blob = g_blob;
1158 
1159 	CU_ASSERT(blob->data_ro == true);
1160 	CU_ASSERT(blob->md_ro == true);
1161 	CU_ASSERT(blob->data_ro_flags & SPDK_BLOB_READ_ONLY);
1162 
1163 	spdk_blob_close(blob, blob_op_complete, NULL);
1164 	CU_ASSERT(g_bserrno == 0);
1165 
1166 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1167 	CU_ASSERT(g_bserrno == 0);
1168 
1169 }
1170 
1171 static void
1172 channel_ops(void)
1173 {
1174 	struct spdk_blob_store *bs;
1175 	struct spdk_bs_dev *dev;
1176 	struct spdk_io_channel *channel;
1177 
1178 	dev = init_dev();
1179 
1180 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1181 	CU_ASSERT(g_bserrno == 0);
1182 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1183 	bs = g_bs;
1184 
1185 	channel = spdk_bs_alloc_io_channel(bs);
1186 	CU_ASSERT(channel != NULL);
1187 
1188 	spdk_bs_free_io_channel(channel);
1189 
1190 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1191 	CU_ASSERT(g_bserrno == 0);
1192 	g_bs = NULL;
1193 }
1194 
1195 static void
1196 blob_write(void)
1197 {
1198 	struct spdk_blob_store *bs;
1199 	struct spdk_bs_dev *dev;
1200 	struct spdk_blob *blob;
1201 	struct spdk_io_channel *channel;
1202 	spdk_blob_id blobid;
1203 	uint64_t pages_per_cluster;
1204 	uint8_t payload[10 * 4096];
1205 
1206 	dev = init_dev();
1207 
1208 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1209 	CU_ASSERT(g_bserrno == 0);
1210 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1211 	bs = g_bs;
1212 
1213 	pages_per_cluster = spdk_bs_get_cluster_size(bs) / spdk_bs_get_page_size(bs);
1214 
1215 	channel = spdk_bs_alloc_io_channel(bs);
1216 	CU_ASSERT(channel != NULL);
1217 
1218 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
1219 	CU_ASSERT(g_bserrno == 0);
1220 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1221 	blobid = g_blobid;
1222 
1223 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1224 	CU_ASSERT(g_bserrno == 0);
1225 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1226 	blob = g_blob;
1227 
1228 	/* Write to a blob with 0 size */
1229 	spdk_blob_io_write(blob, channel, payload, 0, 1, blob_op_complete, NULL);
1230 	CU_ASSERT(g_bserrno == -EINVAL);
1231 
1232 	/* Resize the blob */
1233 	spdk_blob_resize(blob, 5, blob_op_complete, NULL);
1234 	CU_ASSERT(g_bserrno == 0);
1235 
1236 	/* Confirm that write fails if blob is marked read-only. */
1237 	blob->data_ro = true;
1238 	spdk_blob_io_write(blob, channel, payload, 0, 1, blob_op_complete, NULL);
1239 	CU_ASSERT(g_bserrno == -EPERM);
1240 	blob->data_ro = false;
1241 
1242 	/* Write to the blob */
1243 	spdk_blob_io_write(blob, channel, payload, 0, 1, blob_op_complete, NULL);
1244 	CU_ASSERT(g_bserrno == 0);
1245 
1246 	/* Write starting beyond the end */
1247 	spdk_blob_io_write(blob, channel, payload, 5 * pages_per_cluster, 1, blob_op_complete,
1248 			   NULL);
1249 	CU_ASSERT(g_bserrno == -EINVAL);
1250 
1251 	/* Write starting at a valid location but going off the end */
1252 	spdk_blob_io_write(blob, channel, payload, 4 * pages_per_cluster, pages_per_cluster + 1,
1253 			   blob_op_complete, NULL);
1254 	CU_ASSERT(g_bserrno == -EINVAL);
1255 
1256 	spdk_blob_close(blob, blob_op_complete, NULL);
1257 	CU_ASSERT(g_bserrno == 0);
1258 
1259 	spdk_bs_free_io_channel(channel);
1260 
1261 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1262 	CU_ASSERT(g_bserrno == 0);
1263 	g_bs = NULL;
1264 }
1265 
1266 static void
1267 blob_read(void)
1268 {
1269 	struct spdk_blob_store *bs;
1270 	struct spdk_bs_dev *dev;
1271 	struct spdk_blob *blob;
1272 	struct spdk_io_channel *channel;
1273 	spdk_blob_id blobid;
1274 	uint64_t pages_per_cluster;
1275 	uint8_t payload[10 * 4096];
1276 
1277 	dev = init_dev();
1278 
1279 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1280 	CU_ASSERT(g_bserrno == 0);
1281 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1282 	bs = g_bs;
1283 
1284 	pages_per_cluster = spdk_bs_get_cluster_size(bs) / spdk_bs_get_page_size(bs);
1285 
1286 	channel = spdk_bs_alloc_io_channel(bs);
1287 	CU_ASSERT(channel != NULL);
1288 
1289 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
1290 	CU_ASSERT(g_bserrno == 0);
1291 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1292 	blobid = g_blobid;
1293 
1294 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1295 	CU_ASSERT(g_bserrno == 0);
1296 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1297 	blob = g_blob;
1298 
1299 	/* Read from a blob with 0 size */
1300 	spdk_blob_io_read(blob, channel, payload, 0, 1, blob_op_complete, NULL);
1301 	CU_ASSERT(g_bserrno == -EINVAL);
1302 
1303 	/* Resize the blob */
1304 	spdk_blob_resize(blob, 5, blob_op_complete, NULL);
1305 	CU_ASSERT(g_bserrno == 0);
1306 
1307 	/* Confirm that read passes if blob is marked read-only. */
1308 	blob->data_ro = true;
1309 	spdk_blob_io_read(blob, channel, payload, 0, 1, blob_op_complete, NULL);
1310 	CU_ASSERT(g_bserrno == 0);
1311 	blob->data_ro = false;
1312 
1313 	/* Read from the blob */
1314 	spdk_blob_io_read(blob, channel, payload, 0, 1, blob_op_complete, NULL);
1315 	CU_ASSERT(g_bserrno == 0);
1316 
1317 	/* Read starting beyond the end */
1318 	spdk_blob_io_read(blob, channel, payload, 5 * pages_per_cluster, 1, blob_op_complete,
1319 			  NULL);
1320 	CU_ASSERT(g_bserrno == -EINVAL);
1321 
1322 	/* Read starting at a valid location but going off the end */
1323 	spdk_blob_io_read(blob, channel, payload, 4 * pages_per_cluster, pages_per_cluster + 1,
1324 			  blob_op_complete, NULL);
1325 	CU_ASSERT(g_bserrno == -EINVAL);
1326 
1327 	spdk_blob_close(blob, blob_op_complete, NULL);
1328 	CU_ASSERT(g_bserrno == 0);
1329 
1330 	spdk_bs_free_io_channel(channel);
1331 
1332 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1333 	CU_ASSERT(g_bserrno == 0);
1334 	g_bs = NULL;
1335 }
1336 
1337 static void
1338 blob_rw_verify(void)
1339 {
1340 	struct spdk_blob_store *bs;
1341 	struct spdk_bs_dev *dev;
1342 	struct spdk_blob *blob;
1343 	struct spdk_io_channel *channel;
1344 	spdk_blob_id blobid;
1345 	uint8_t payload_read[10 * 4096];
1346 	uint8_t payload_write[10 * 4096];
1347 
1348 	dev = init_dev();
1349 
1350 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1351 	CU_ASSERT(g_bserrno == 0);
1352 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1353 	bs = g_bs;
1354 
1355 	channel = spdk_bs_alloc_io_channel(bs);
1356 	CU_ASSERT(channel != NULL);
1357 
1358 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
1359 	CU_ASSERT(g_bserrno == 0);
1360 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1361 	blobid = g_blobid;
1362 
1363 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1364 	CU_ASSERT(g_bserrno == 0);
1365 	CU_ASSERT(g_blob != NULL);
1366 	blob = g_blob;
1367 
1368 	spdk_blob_resize(blob, 32, blob_op_complete, NULL);
1369 	CU_ASSERT(g_bserrno == 0);
1370 
1371 	memset(payload_write, 0xE5, sizeof(payload_write));
1372 	spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL);
1373 	CU_ASSERT(g_bserrno == 0);
1374 
1375 	memset(payload_read, 0x00, sizeof(payload_read));
1376 	spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL);
1377 	CU_ASSERT(g_bserrno == 0);
1378 	CU_ASSERT(memcmp(payload_write, payload_read, 4 * 4096) == 0);
1379 
1380 	spdk_blob_close(blob, blob_op_complete, NULL);
1381 	CU_ASSERT(g_bserrno == 0);
1382 
1383 	spdk_bs_free_io_channel(channel);
1384 
1385 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1386 	CU_ASSERT(g_bserrno == 0);
1387 	g_bs = NULL;
1388 }
1389 
1390 static void
1391 blob_rw_verify_iov(void)
1392 {
1393 	struct spdk_blob_store *bs;
1394 	struct spdk_bs_dev *dev;
1395 	struct spdk_blob *blob;
1396 	struct spdk_io_channel *channel;
1397 	spdk_blob_id blobid;
1398 	uint8_t payload_read[10 * 4096];
1399 	uint8_t payload_write[10 * 4096];
1400 	struct iovec iov_read[3];
1401 	struct iovec iov_write[3];
1402 	void *buf;
1403 
1404 	dev = init_dev();
1405 	memset(g_dev_buffer, 0, DEV_BUFFER_SIZE);
1406 
1407 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1408 	CU_ASSERT(g_bserrno == 0);
1409 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1410 	bs = g_bs;
1411 
1412 	channel = spdk_bs_alloc_io_channel(bs);
1413 	CU_ASSERT(channel != NULL);
1414 
1415 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
1416 	CU_ASSERT(g_bserrno == 0);
1417 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1418 	blobid = g_blobid;
1419 
1420 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1421 	CU_ASSERT(g_bserrno == 0);
1422 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1423 	blob = g_blob;
1424 
1425 	spdk_blob_resize(blob, 2, blob_op_complete, NULL);
1426 	CU_ASSERT(g_bserrno == 0);
1427 
1428 	/*
1429 	 * Manually adjust the offset of the blob's second cluster.  This allows
1430 	 *  us to make sure that the readv/write code correctly accounts for I/O
1431 	 *  that cross cluster boundaries.  Start by asserting that the allocated
1432 	 *  clusters are where we expect before modifying the second cluster.
1433 	 */
1434 	CU_ASSERT(blob->active.clusters[0] == 1 * 256);
1435 	CU_ASSERT(blob->active.clusters[1] == 2 * 256);
1436 	blob->active.clusters[1] = 3 * 256;
1437 
1438 	memset(payload_write, 0xE5, sizeof(payload_write));
1439 	iov_write[0].iov_base = payload_write;
1440 	iov_write[0].iov_len = 1 * 4096;
1441 	iov_write[1].iov_base = payload_write + 1 * 4096;
1442 	iov_write[1].iov_len = 5 * 4096;
1443 	iov_write[2].iov_base = payload_write + 6 * 4096;
1444 	iov_write[2].iov_len = 4 * 4096;
1445 	/*
1446 	 * Choose a page offset just before the cluster boundary.  The first 6 pages of payload
1447 	 *  will get written to the first cluster, the last 4 to the second cluster.
1448 	 */
1449 	spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL);
1450 	CU_ASSERT(g_bserrno == 0);
1451 
1452 	memset(payload_read, 0xAA, sizeof(payload_read));
1453 	iov_read[0].iov_base = payload_read;
1454 	iov_read[0].iov_len = 3 * 4096;
1455 	iov_read[1].iov_base = payload_read + 3 * 4096;
1456 	iov_read[1].iov_len = 4 * 4096;
1457 	iov_read[2].iov_base = payload_read + 7 * 4096;
1458 	iov_read[2].iov_len = 3 * 4096;
1459 	spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL);
1460 	CU_ASSERT(g_bserrno == 0);
1461 	CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0);
1462 
1463 	buf = calloc(1, 256 * 4096);
1464 	SPDK_CU_ASSERT_FATAL(buf != NULL);
1465 	/* Check that cluster 2 on "disk" was not modified. */
1466 	CU_ASSERT(memcmp(buf, &g_dev_buffer[512 * 4096], 256 * 4096) == 0);
1467 	free(buf);
1468 
1469 	spdk_blob_close(blob, blob_op_complete, NULL);
1470 	CU_ASSERT(g_bserrno == 0);
1471 
1472 	spdk_bs_free_io_channel(channel);
1473 
1474 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1475 	CU_ASSERT(g_bserrno == 0);
1476 	g_bs = NULL;
1477 }
1478 
1479 static uint32_t
1480 bs_channel_get_req_count(struct spdk_io_channel *_channel)
1481 {
1482 	struct spdk_bs_channel *channel = spdk_io_channel_get_ctx(_channel);
1483 	struct spdk_bs_request_set *set;
1484 	uint32_t count = 0;
1485 
1486 	TAILQ_FOREACH(set, &channel->reqs, link) {
1487 		count++;
1488 	}
1489 
1490 	return count;
1491 }
1492 
1493 static void
1494 blob_rw_verify_iov_nomem(void)
1495 {
1496 	struct spdk_blob_store *bs;
1497 	struct spdk_bs_dev *dev;
1498 	struct spdk_blob *blob;
1499 	struct spdk_io_channel *channel;
1500 	spdk_blob_id blobid;
1501 	uint8_t payload_write[10 * 4096];
1502 	struct iovec iov_write[3];
1503 	uint32_t req_count;
1504 
1505 	dev = init_dev();
1506 	memset(g_dev_buffer, 0, DEV_BUFFER_SIZE);
1507 
1508 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1509 	CU_ASSERT(g_bserrno == 0);
1510 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1511 	bs = g_bs;
1512 
1513 	channel = spdk_bs_alloc_io_channel(bs);
1514 	CU_ASSERT(channel != NULL);
1515 
1516 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
1517 	CU_ASSERT(g_bserrno == 0);
1518 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1519 	blobid = g_blobid;
1520 
1521 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1522 	CU_ASSERT(g_bserrno == 0);
1523 	CU_ASSERT(g_blob != NULL);
1524 	blob = g_blob;
1525 
1526 	spdk_blob_resize(blob, 2, blob_op_complete, NULL);
1527 	CU_ASSERT(g_bserrno == 0);
1528 
1529 	/*
1530 	 * Choose a page offset just before the cluster boundary.  The first 6 pages of payload
1531 	 *  will get written to the first cluster, the last 4 to the second cluster.
1532 	 */
1533 	iov_write[0].iov_base = payload_write;
1534 	iov_write[0].iov_len = 1 * 4096;
1535 	iov_write[1].iov_base = payload_write + 1 * 4096;
1536 	iov_write[1].iov_len = 5 * 4096;
1537 	iov_write[2].iov_base = payload_write + 6 * 4096;
1538 	iov_write[2].iov_len = 4 * 4096;
1539 	MOCK_SET(calloc, NULL);
1540 	req_count = bs_channel_get_req_count(channel);
1541 	spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL);
1542 	CU_ASSERT(g_bserrno = -ENOMEM);
1543 	CU_ASSERT(req_count == bs_channel_get_req_count(channel));
1544 	MOCK_CLEAR(calloc);
1545 
1546 	spdk_blob_close(blob, blob_op_complete, NULL);
1547 	CU_ASSERT(g_bserrno == 0);
1548 
1549 	spdk_bs_free_io_channel(channel);
1550 
1551 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1552 	CU_ASSERT(g_bserrno == 0);
1553 	g_bs = NULL;
1554 }
1555 
1556 static void
1557 blob_rw_iov_read_only(void)
1558 {
1559 	struct spdk_blob_store *bs;
1560 	struct spdk_bs_dev *dev;
1561 	struct spdk_blob *blob;
1562 	struct spdk_io_channel *channel;
1563 	spdk_blob_id blobid;
1564 	uint8_t payload_read[4096];
1565 	uint8_t payload_write[4096];
1566 	struct iovec iov_read;
1567 	struct iovec iov_write;
1568 
1569 	dev = init_dev();
1570 	memset(g_dev_buffer, 0, DEV_BUFFER_SIZE);
1571 
1572 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1573 	CU_ASSERT(g_bserrno == 0);
1574 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1575 	bs = g_bs;
1576 
1577 	channel = spdk_bs_alloc_io_channel(bs);
1578 	CU_ASSERT(channel != NULL);
1579 
1580 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
1581 	CU_ASSERT(g_bserrno == 0);
1582 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1583 	blobid = g_blobid;
1584 
1585 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1586 	CU_ASSERT(g_bserrno == 0);
1587 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1588 	blob = g_blob;
1589 
1590 	spdk_blob_resize(blob, 2, blob_op_complete, NULL);
1591 	CU_ASSERT(g_bserrno == 0);
1592 
1593 	/* Verify that writev failed if read_only flag is set. */
1594 	blob->data_ro = true;
1595 	iov_write.iov_base = payload_write;
1596 	iov_write.iov_len = sizeof(payload_write);
1597 	spdk_blob_io_writev(blob, channel, &iov_write, 1, 0, 1, blob_op_complete, NULL);
1598 	CU_ASSERT(g_bserrno == -EPERM);
1599 
1600 	/* Verify that reads pass if data_ro flag is set. */
1601 	iov_read.iov_base = payload_read;
1602 	iov_read.iov_len = sizeof(payload_read);
1603 	spdk_blob_io_readv(blob, channel, &iov_read, 1, 0, 1, blob_op_complete, NULL);
1604 	CU_ASSERT(g_bserrno == 0);
1605 
1606 	spdk_blob_close(blob, blob_op_complete, NULL);
1607 	CU_ASSERT(g_bserrno == 0);
1608 
1609 	spdk_bs_free_io_channel(channel);
1610 
1611 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1612 	CU_ASSERT(g_bserrno == 0);
1613 	g_bs = NULL;
1614 }
1615 
1616 static void
1617 _blob_io_read_no_split(struct spdk_blob *blob, struct spdk_io_channel *channel,
1618 		       uint8_t *payload, uint64_t offset, uint64_t length,
1619 		       spdk_blob_op_complete cb_fn, void *cb_arg)
1620 {
1621 	uint64_t i;
1622 	uint8_t *buf;
1623 	uint64_t page_size = spdk_bs_get_page_size(blob->bs);
1624 
1625 	/* To be sure that operation is NOT splitted, read one page at the time */
1626 	buf = payload;
1627 	for (i = 0; i < length; i++) {
1628 		spdk_blob_io_read(blob, channel, buf, i + offset, 1, blob_op_complete, NULL);
1629 		if (g_bserrno != 0) {
1630 			/* Pass the error code up */
1631 			break;
1632 		}
1633 		buf += page_size;
1634 	}
1635 
1636 	cb_fn(cb_arg, g_bserrno);
1637 }
1638 
1639 static void
1640 _blob_io_write_no_split(struct spdk_blob *blob, struct spdk_io_channel *channel,
1641 			uint8_t *payload, uint64_t offset, uint64_t length,
1642 			spdk_blob_op_complete cb_fn, void *cb_arg)
1643 {
1644 	uint64_t i;
1645 	uint8_t *buf;
1646 	uint64_t page_size = spdk_bs_get_page_size(blob->bs);
1647 
1648 	/* To be sure that operation is NOT splitted, write one page at the time */
1649 	buf = payload;
1650 	for (i = 0; i < length; i++) {
1651 		spdk_blob_io_write(blob, channel, buf, i + offset, 1, blob_op_complete, NULL);
1652 		if (g_bserrno != 0) {
1653 			/* Pass the error code up */
1654 			break;
1655 		}
1656 		buf += page_size;
1657 	}
1658 
1659 	cb_fn(cb_arg, g_bserrno);
1660 }
1661 
1662 static void
1663 blob_operation_split_rw(void)
1664 {
1665 	struct spdk_blob_store *bs;
1666 	struct spdk_bs_dev *dev;
1667 	struct spdk_blob *blob;
1668 	struct spdk_io_channel *channel;
1669 	struct spdk_blob_opts opts;
1670 	spdk_blob_id blobid;
1671 	uint64_t cluster_size;
1672 
1673 	uint64_t payload_size;
1674 	uint8_t *payload_read;
1675 	uint8_t *payload_write;
1676 	uint8_t *payload_pattern;
1677 
1678 	uint64_t page_size;
1679 	uint64_t pages_per_cluster;
1680 	uint64_t pages_per_payload;
1681 
1682 	uint64_t i;
1683 
1684 	dev = init_dev();
1685 
1686 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1687 	CU_ASSERT(g_bserrno == 0);
1688 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1689 	bs = g_bs;
1690 
1691 	cluster_size = spdk_bs_get_cluster_size(bs);
1692 	page_size = spdk_bs_get_page_size(bs);
1693 	pages_per_cluster = cluster_size / page_size;
1694 	pages_per_payload = pages_per_cluster * 5;
1695 	payload_size = cluster_size * 5;
1696 
1697 	payload_read = malloc(payload_size);
1698 	SPDK_CU_ASSERT_FATAL(payload_read != NULL);
1699 
1700 	payload_write = malloc(payload_size);
1701 	SPDK_CU_ASSERT_FATAL(payload_write != NULL);
1702 
1703 	payload_pattern = malloc(payload_size);
1704 	SPDK_CU_ASSERT_FATAL(payload_pattern != NULL);
1705 
1706 	/* Prepare random pattern to write */
1707 	memset(payload_pattern, 0xFF, payload_size);
1708 	for (i = 0; i < pages_per_payload; i++) {
1709 		*((uint64_t *)(payload_pattern + page_size * i)) = (i + 1);
1710 	}
1711 
1712 	channel = spdk_bs_alloc_io_channel(bs);
1713 	SPDK_CU_ASSERT_FATAL(channel != NULL);
1714 
1715 	/* Create blob */
1716 	spdk_blob_opts_init(&opts);
1717 	opts.thin_provision = false;
1718 	opts.num_clusters = 5;
1719 
1720 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
1721 	CU_ASSERT(g_bserrno == 0);
1722 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1723 	blobid = g_blobid;
1724 
1725 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1726 	CU_ASSERT(g_bserrno == 0);
1727 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1728 	blob = g_blob;
1729 
1730 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5);
1731 
1732 	/* Initial read should return zeroed payload */
1733 	memset(payload_read, 0xFF, payload_size);
1734 	spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, blob_op_complete, NULL);
1735 	CU_ASSERT(g_bserrno == 0);
1736 	CU_ASSERT(spdk_mem_all_zero(payload_read, payload_size));
1737 
1738 	/* Fill whole blob except last page */
1739 	spdk_blob_io_write(blob, channel, payload_pattern, 0, pages_per_payload - 1,
1740 			   blob_op_complete, NULL);
1741 	CU_ASSERT(g_bserrno == 0);
1742 
1743 	/* Write last page with a pattern */
1744 	spdk_blob_io_write(blob, channel, payload_pattern, pages_per_payload - 1, 1,
1745 			   blob_op_complete, NULL);
1746 	CU_ASSERT(g_bserrno == 0);
1747 
1748 	/* Read whole blob and check consistency */
1749 	memset(payload_read, 0xFF, payload_size);
1750 	spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, blob_op_complete, NULL);
1751 	CU_ASSERT(g_bserrno == 0);
1752 	CU_ASSERT(memcmp(payload_pattern, payload_read, payload_size - page_size) == 0);
1753 	CU_ASSERT(memcmp(payload_pattern, payload_read + payload_size - page_size, page_size) == 0);
1754 
1755 	/* Fill whole blob except first page */
1756 	spdk_blob_io_write(blob, channel, payload_pattern, 1, pages_per_payload - 1,
1757 			   blob_op_complete, NULL);
1758 	CU_ASSERT(g_bserrno == 0);
1759 
1760 	/* Write first page with a pattern */
1761 	spdk_blob_io_write(blob, channel, payload_pattern, 0, 1,
1762 			   blob_op_complete, NULL);
1763 	CU_ASSERT(g_bserrno == 0);
1764 
1765 	/* Read whole blob and check consistency */
1766 	memset(payload_read, 0xFF, payload_size);
1767 	spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, blob_op_complete, NULL);
1768 	CU_ASSERT(g_bserrno == 0);
1769 	CU_ASSERT(memcmp(payload_pattern, payload_read + page_size, payload_size - page_size) == 0);
1770 	CU_ASSERT(memcmp(payload_pattern, payload_read, page_size) == 0);
1771 
1772 
1773 	/* Fill whole blob with a pattern (5 clusters) */
1774 
1775 	/* 1. Read test. */
1776 	_blob_io_write_no_split(blob, channel, payload_pattern, 0, pages_per_payload,
1777 				blob_op_complete, NULL);
1778 	CU_ASSERT(g_bserrno == 0);
1779 
1780 	memset(payload_read, 0xFF, payload_size);
1781 	spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, blob_op_complete, NULL);
1782 	CU_ASSERT(g_bserrno == 0);
1783 	CU_ASSERT(memcmp(payload_pattern, payload_read, payload_size) == 0);
1784 
1785 	/* 2. Write test. */
1786 	spdk_blob_io_write(blob, channel, payload_pattern, 0, pages_per_payload,
1787 			   blob_op_complete, NULL);
1788 	CU_ASSERT(g_bserrno == 0);
1789 
1790 	memset(payload_read, 0xFF, payload_size);
1791 	_blob_io_read_no_split(blob, channel, payload_read, 0, pages_per_payload, blob_op_complete, NULL);
1792 	CU_ASSERT(g_bserrno == 0);
1793 	CU_ASSERT(memcmp(payload_pattern, payload_read, payload_size) == 0);
1794 
1795 	spdk_blob_close(blob, blob_op_complete, NULL);
1796 	CU_ASSERT(g_bserrno == 0);
1797 
1798 	spdk_bs_free_io_channel(channel);
1799 
1800 	/* Unload the blob store */
1801 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1802 	CU_ASSERT(g_bserrno == 0);
1803 	g_bs = NULL;
1804 	g_blob = NULL;
1805 	g_blobid = 0;
1806 
1807 	free(payload_read);
1808 	free(payload_write);
1809 	free(payload_pattern);
1810 }
1811 
1812 static void
1813 blob_operation_split_rw_iov(void)
1814 {
1815 	struct spdk_blob_store *bs;
1816 	struct spdk_bs_dev *dev;
1817 	struct spdk_blob *blob;
1818 	struct spdk_io_channel *channel;
1819 	struct spdk_blob_opts opts;
1820 	spdk_blob_id blobid;
1821 	uint64_t cluster_size;
1822 
1823 	uint64_t payload_size;
1824 	uint8_t *payload_read;
1825 	uint8_t *payload_write;
1826 	uint8_t *payload_pattern;
1827 
1828 	uint64_t page_size;
1829 	uint64_t pages_per_cluster;
1830 	uint64_t pages_per_payload;
1831 
1832 	struct iovec iov_read[2];
1833 	struct iovec iov_write[2];
1834 
1835 	uint64_t i, j;
1836 
1837 	dev = init_dev();
1838 
1839 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
1840 	CU_ASSERT(g_bserrno == 0);
1841 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
1842 	bs = g_bs;
1843 
1844 	cluster_size = spdk_bs_get_cluster_size(bs);
1845 	page_size = spdk_bs_get_page_size(bs);
1846 	pages_per_cluster = cluster_size / page_size;
1847 	pages_per_payload = pages_per_cluster * 5;
1848 	payload_size = cluster_size * 5;
1849 
1850 	payload_read = malloc(payload_size);
1851 	SPDK_CU_ASSERT_FATAL(payload_read != NULL);
1852 
1853 	payload_write = malloc(payload_size);
1854 	SPDK_CU_ASSERT_FATAL(payload_write != NULL);
1855 
1856 	payload_pattern = malloc(payload_size);
1857 	SPDK_CU_ASSERT_FATAL(payload_pattern != NULL);
1858 
1859 	/* Prepare random pattern to write */
1860 	for (i = 0; i < pages_per_payload; i++) {
1861 		for (j = 0; j < page_size / sizeof(uint64_t); j++) {
1862 			uint64_t *tmp;
1863 
1864 			tmp = (uint64_t *)payload_pattern;
1865 			tmp += ((page_size * i) / sizeof(uint64_t)) + j;
1866 			*tmp = i + 1;
1867 		}
1868 	}
1869 
1870 	channel = spdk_bs_alloc_io_channel(bs);
1871 	SPDK_CU_ASSERT_FATAL(channel != NULL);
1872 
1873 	/* Create blob */
1874 	spdk_blob_opts_init(&opts);
1875 	opts.thin_provision = false;
1876 	opts.num_clusters = 5;
1877 
1878 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
1879 	CU_ASSERT(g_bserrno == 0);
1880 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
1881 	blobid = g_blobid;
1882 
1883 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
1884 	CU_ASSERT(g_bserrno == 0);
1885 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
1886 	blob = g_blob;
1887 
1888 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5);
1889 
1890 	/* Initial read should return zeroes payload */
1891 	memset(payload_read, 0xFF, payload_size);
1892 	iov_read[0].iov_base = payload_read;
1893 	iov_read[0].iov_len = cluster_size * 3;
1894 	iov_read[1].iov_base = payload_read + cluster_size * 3;
1895 	iov_read[1].iov_len = cluster_size * 2;
1896 	spdk_blob_io_readv(blob, channel, iov_read, 2, 0, pages_per_payload, blob_op_complete, NULL);
1897 	CU_ASSERT(g_bserrno == 0);
1898 	CU_ASSERT(spdk_mem_all_zero(payload_read, payload_size));
1899 
1900 	/* First of iovs fills whole blob except last page and second of iovs writes last page
1901 	 *  with a pattern. */
1902 	iov_write[0].iov_base = payload_pattern;
1903 	iov_write[0].iov_len = payload_size - page_size;
1904 	iov_write[1].iov_base = payload_pattern;
1905 	iov_write[1].iov_len = page_size;
1906 	spdk_blob_io_writev(blob, channel, iov_write, 2, 0, pages_per_payload, blob_op_complete, NULL);
1907 	CU_ASSERT(g_bserrno == 0);
1908 
1909 	/* Read whole blob and check consistency */
1910 	memset(payload_read, 0xFF, payload_size);
1911 	iov_read[0].iov_base = payload_read;
1912 	iov_read[0].iov_len = cluster_size * 2;
1913 	iov_read[1].iov_base = payload_read + cluster_size * 2;
1914 	iov_read[1].iov_len = cluster_size * 3;
1915 	spdk_blob_io_readv(blob, channel, iov_read, 2, 0, pages_per_payload, blob_op_complete, NULL);
1916 	CU_ASSERT(g_bserrno == 0);
1917 	CU_ASSERT(memcmp(payload_pattern, payload_read, payload_size - page_size) == 0);
1918 	CU_ASSERT(memcmp(payload_pattern, payload_read + payload_size - page_size, page_size) == 0);
1919 
1920 	/* First of iovs fills only first page and second of iovs writes whole blob except
1921 	 *  first page with a pattern. */
1922 	iov_write[0].iov_base = payload_pattern;
1923 	iov_write[0].iov_len = page_size;
1924 	iov_write[1].iov_base = payload_pattern;
1925 	iov_write[1].iov_len = payload_size - page_size;
1926 	spdk_blob_io_writev(blob, channel, iov_write, 2, 0, pages_per_payload, blob_op_complete, NULL);
1927 	CU_ASSERT(g_bserrno == 0);
1928 
1929 	/* Read whole blob and check consistency */
1930 	memset(payload_read, 0xFF, payload_size);
1931 	iov_read[0].iov_base = payload_read;
1932 	iov_read[0].iov_len = cluster_size * 4;
1933 	iov_read[1].iov_base = payload_read + cluster_size * 4;
1934 	iov_read[1].iov_len = cluster_size;
1935 	spdk_blob_io_readv(blob, channel, iov_read, 2, 0, pages_per_payload, blob_op_complete, NULL);
1936 	CU_ASSERT(g_bserrno == 0);
1937 	CU_ASSERT(memcmp(payload_pattern, payload_read + page_size, payload_size - page_size) == 0);
1938 	CU_ASSERT(memcmp(payload_pattern, payload_read, page_size) == 0);
1939 
1940 
1941 	/* Fill whole blob with a pattern (5 clusters) */
1942 
1943 	/* 1. Read test. */
1944 	_blob_io_write_no_split(blob, channel, payload_pattern, 0, pages_per_payload,
1945 				blob_op_complete, NULL);
1946 	CU_ASSERT(g_bserrno == 0);
1947 
1948 	memset(payload_read, 0xFF, payload_size);
1949 	iov_read[0].iov_base = payload_read;
1950 	iov_read[0].iov_len = cluster_size;
1951 	iov_read[1].iov_base = payload_read + cluster_size;
1952 	iov_read[1].iov_len = cluster_size * 4;
1953 	spdk_blob_io_readv(blob, channel, iov_read, 2, 0, pages_per_payload, blob_op_complete, NULL);
1954 	CU_ASSERT(g_bserrno == 0);
1955 	CU_ASSERT(memcmp(payload_pattern, payload_read, payload_size) == 0);
1956 
1957 	/* 2. Write test. */
1958 	iov_write[0].iov_base = payload_read;
1959 	iov_write[0].iov_len = cluster_size * 2;
1960 	iov_write[1].iov_base = payload_read + cluster_size * 2;
1961 	iov_write[1].iov_len = cluster_size * 3;
1962 	spdk_blob_io_writev(blob, channel, iov_write, 2, 0, pages_per_payload, blob_op_complete, NULL);
1963 	CU_ASSERT(g_bserrno == 0);
1964 
1965 	memset(payload_read, 0xFF, payload_size);
1966 	_blob_io_read_no_split(blob, channel, payload_read, 0, pages_per_payload, blob_op_complete, NULL);
1967 	CU_ASSERT(g_bserrno == 0);
1968 	CU_ASSERT(memcmp(payload_pattern, payload_read, payload_size) == 0);
1969 
1970 	spdk_blob_close(blob, blob_op_complete, NULL);
1971 	CU_ASSERT(g_bserrno == 0);
1972 
1973 	spdk_bs_free_io_channel(channel);
1974 
1975 	/* Unload the blob store */
1976 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
1977 	CU_ASSERT(g_bserrno == 0);
1978 	g_bs = NULL;
1979 	g_blob = NULL;
1980 	g_blobid = 0;
1981 
1982 	free(payload_read);
1983 	free(payload_write);
1984 	free(payload_pattern);
1985 }
1986 
1987 static void
1988 blob_unmap(void)
1989 {
1990 	struct spdk_blob_store *bs;
1991 	struct spdk_bs_dev *dev;
1992 	struct spdk_blob *blob;
1993 	struct spdk_io_channel *channel;
1994 	spdk_blob_id blobid;
1995 	struct spdk_blob_opts opts;
1996 	uint8_t payload[4096];
1997 	int i;
1998 
1999 	dev = init_dev();
2000 
2001 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
2002 	CU_ASSERT(g_bserrno == 0);
2003 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2004 	bs = g_bs;
2005 
2006 	channel = spdk_bs_alloc_io_channel(bs);
2007 	CU_ASSERT(channel != NULL);
2008 
2009 	spdk_blob_opts_init(&opts);
2010 	opts.num_clusters = 10;
2011 
2012 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
2013 	CU_ASSERT(g_bserrno == 0);
2014 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2015 	blobid = g_blobid;
2016 
2017 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
2018 	CU_ASSERT(g_bserrno == 0);
2019 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
2020 	blob = g_blob;
2021 
2022 	spdk_blob_resize(blob, 10, blob_op_complete, NULL);
2023 	CU_ASSERT(g_bserrno == 0);
2024 
2025 	memset(payload, 0, sizeof(payload));
2026 	payload[0] = 0xFF;
2027 
2028 	/*
2029 	 * Set first byte of every cluster to 0xFF.
2030 	 * First cluster on device is reserved so let's start from cluster number 1
2031 	 */
2032 	for (i = 1; i < 11; i++) {
2033 		g_dev_buffer[i * SPDK_BLOB_OPTS_CLUSTER_SZ] = 0xFF;
2034 	}
2035 
2036 	/* Confirm writes */
2037 	for (i = 0; i < 10; i++) {
2038 		payload[0] = 0;
2039 		spdk_blob_io_read(blob, channel, &payload, i * SPDK_BLOB_OPTS_CLUSTER_SZ / 4096, 1,
2040 				  blob_op_complete, NULL);
2041 		CU_ASSERT(g_bserrno == 0);
2042 		CU_ASSERT(payload[0] == 0xFF);
2043 	}
2044 
2045 	/* Mark some clusters as unallocated */
2046 	blob->active.clusters[1] = 0;
2047 	blob->active.clusters[2] = 0;
2048 	blob->active.clusters[3] = 0;
2049 	blob->active.clusters[6] = 0;
2050 	blob->active.clusters[8] = 0;
2051 
2052 	/* Unmap clusters by resizing to 0 */
2053 	spdk_blob_resize(blob, 0, blob_op_complete, NULL);
2054 	CU_ASSERT(g_bserrno == 0);
2055 
2056 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
2057 	CU_ASSERT(g_bserrno == 0);
2058 
2059 	/* Confirm that only 'allocated' clusters were unmapped */
2060 	for (i = 1; i < 11; i++) {
2061 		switch (i) {
2062 		case 2:
2063 		case 3:
2064 		case 4:
2065 		case 7:
2066 		case 9:
2067 			CU_ASSERT(g_dev_buffer[i * SPDK_BLOB_OPTS_CLUSTER_SZ] == 0xFF);
2068 			break;
2069 		default:
2070 			CU_ASSERT(g_dev_buffer[i * SPDK_BLOB_OPTS_CLUSTER_SZ] == 0);
2071 			break;
2072 		}
2073 	}
2074 
2075 	spdk_blob_close(blob, blob_op_complete, NULL);
2076 	CU_ASSERT(g_bserrno == 0);
2077 
2078 	spdk_bs_free_io_channel(channel);
2079 
2080 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2081 	CU_ASSERT(g_bserrno == 0);
2082 	g_bs = NULL;
2083 }
2084 
2085 
2086 static void
2087 blob_iter(void)
2088 {
2089 	struct spdk_blob_store *bs;
2090 	struct spdk_bs_dev *dev;
2091 	struct spdk_blob *blob;
2092 	spdk_blob_id blobid;
2093 
2094 	dev = init_dev();
2095 
2096 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
2097 	CU_ASSERT(g_bserrno == 0);
2098 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2099 	bs = g_bs;
2100 
2101 	spdk_bs_iter_first(bs, blob_op_with_handle_complete, NULL);
2102 	CU_ASSERT(g_blob == NULL);
2103 	CU_ASSERT(g_bserrno == -ENOENT);
2104 
2105 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
2106 	CU_ASSERT(g_bserrno == 0);
2107 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2108 	blobid = g_blobid;
2109 
2110 	spdk_bs_iter_first(bs, blob_op_with_handle_complete, NULL);
2111 	CU_ASSERT(g_blob != NULL);
2112 	CU_ASSERT(g_bserrno == 0);
2113 	blob = g_blob;
2114 	CU_ASSERT(spdk_blob_get_id(blob) == blobid);
2115 
2116 	spdk_bs_iter_next(bs, blob, blob_op_with_handle_complete, NULL);
2117 	CU_ASSERT(g_blob == NULL);
2118 	CU_ASSERT(g_bserrno == -ENOENT);
2119 
2120 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2121 	CU_ASSERT(g_bserrno == 0);
2122 	g_bs = NULL;
2123 }
2124 
2125 static void
2126 blob_xattr(void)
2127 {
2128 	struct spdk_blob_store *bs;
2129 	struct spdk_bs_dev *dev;
2130 	struct spdk_blob *blob;
2131 	spdk_blob_id blobid;
2132 	uint64_t length;
2133 	int rc;
2134 	const char *name1, *name2;
2135 	const void *value;
2136 	size_t value_len;
2137 	struct spdk_xattr_names *names;
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 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
2147 	CU_ASSERT(g_bserrno == 0);
2148 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2149 	blobid = g_blobid;
2150 
2151 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
2152 	CU_ASSERT(g_bserrno == 0);
2153 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
2154 	blob = g_blob;
2155 
2156 	/* Test that set_xattr fails if md_ro flag is set. */
2157 	blob->md_ro = true;
2158 	rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1);
2159 	CU_ASSERT(rc == -EPERM);
2160 
2161 	blob->md_ro = false;
2162 	rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1);
2163 	CU_ASSERT(rc == 0);
2164 
2165 	length = 2345;
2166 	rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
2167 	CU_ASSERT(rc == 0);
2168 
2169 	/* Overwrite "length" xattr. */
2170 	length = 3456;
2171 	rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
2172 	CU_ASSERT(rc == 0);
2173 
2174 	/* get_xattr should still work even if md_ro flag is set. */
2175 	value = NULL;
2176 	blob->md_ro = true;
2177 	rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len);
2178 	CU_ASSERT(rc == 0);
2179 	SPDK_CU_ASSERT_FATAL(value != NULL);
2180 	CU_ASSERT(*(uint64_t *)value == length);
2181 	CU_ASSERT(value_len == 8);
2182 	blob->md_ro = false;
2183 
2184 	rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len);
2185 	CU_ASSERT(rc == -ENOENT);
2186 
2187 	names = NULL;
2188 	rc = spdk_blob_get_xattr_names(blob, &names);
2189 	CU_ASSERT(rc == 0);
2190 	SPDK_CU_ASSERT_FATAL(names != NULL);
2191 	CU_ASSERT(spdk_xattr_names_get_count(names) == 2);
2192 	name1 = spdk_xattr_names_get_name(names, 0);
2193 	SPDK_CU_ASSERT_FATAL(name1 != NULL);
2194 	CU_ASSERT(!strcmp(name1, "name") || !strcmp(name1, "length"));
2195 	name2 = spdk_xattr_names_get_name(names, 1);
2196 	SPDK_CU_ASSERT_FATAL(name2 != NULL);
2197 	CU_ASSERT(!strcmp(name2, "name") || !strcmp(name2, "length"));
2198 	CU_ASSERT(strcmp(name1, name2));
2199 	spdk_xattr_names_free(names);
2200 
2201 	/* Confirm that remove_xattr fails if md_ro is set to true. */
2202 	blob->md_ro = true;
2203 	rc = spdk_blob_remove_xattr(blob, "name");
2204 	CU_ASSERT(rc == -EPERM);
2205 
2206 	blob->md_ro = false;
2207 	rc = spdk_blob_remove_xattr(blob, "name");
2208 	CU_ASSERT(rc == 0);
2209 
2210 	rc = spdk_blob_remove_xattr(blob, "foobar");
2211 	CU_ASSERT(rc == -ENOENT);
2212 
2213 	/* Set internal xattr */
2214 	length = 7898;
2215 	rc = _spdk_blob_set_xattr(blob, "internal", &length, sizeof(length), true);
2216 	CU_ASSERT(rc == 0);
2217 	rc = _spdk_blob_get_xattr_value(blob, "internal", &value, &value_len, true);
2218 	CU_ASSERT(rc == 0);
2219 	CU_ASSERT(*(uint64_t *)value == length);
2220 	/* try to get public xattr with same name */
2221 	rc = spdk_blob_get_xattr_value(blob, "internal", &value, &value_len);
2222 	CU_ASSERT(rc != 0);
2223 	rc = _spdk_blob_get_xattr_value(blob, "internal", &value, &value_len, false);
2224 	CU_ASSERT(rc != 0);
2225 	/* Check if SPDK_BLOB_INTERNAL_XATTR is set */
2226 	CU_ASSERT((blob->invalid_flags & SPDK_BLOB_INTERNAL_XATTR) ==
2227 		  SPDK_BLOB_INTERNAL_XATTR)
2228 
2229 	spdk_blob_close(blob, blob_op_complete, NULL);
2230 
2231 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2232 
2233 	/* Check if xattrs are persisted */
2234 	dev = init_dev();
2235 
2236 	spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL);
2237 	CU_ASSERT(g_bserrno == 0);
2238 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2239 
2240 	bs = g_bs;
2241 
2242 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
2243 	CU_ASSERT(g_bserrno == 0);
2244 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
2245 	blob = g_blob;
2246 
2247 	rc = _spdk_blob_get_xattr_value(blob, "internal", &value, &value_len, true);
2248 	CU_ASSERT(rc == 0);
2249 	CU_ASSERT(*(uint64_t *)value == length);
2250 
2251 	/* try to get internal xattr trough public call */
2252 	rc = spdk_blob_get_xattr_value(blob, "internal", &value, &value_len);
2253 	CU_ASSERT(rc != 0);
2254 
2255 	rc = _spdk_blob_remove_xattr(blob, "internal", true);
2256 	CU_ASSERT(rc == 0);
2257 
2258 	CU_ASSERT((blob->invalid_flags & SPDK_BLOB_INTERNAL_XATTR) == 0);
2259 
2260 	CU_ASSERT(g_bserrno == 0);
2261 	g_bs = NULL;
2262 }
2263 
2264 static void
2265 bs_load(void)
2266 {
2267 	struct spdk_bs_dev *dev;
2268 	spdk_blob_id blobid;
2269 	struct spdk_blob *blob;
2270 	struct spdk_bs_super_block *super_block;
2271 	uint64_t length;
2272 	int rc;
2273 	const void *value;
2274 	size_t value_len;
2275 	struct spdk_bs_opts opts;
2276 
2277 	dev = init_dev();
2278 	spdk_bs_opts_init(&opts);
2279 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
2280 
2281 	/* Initialize a new blob store */
2282 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2283 	CU_ASSERT(g_bserrno == 0);
2284 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2285 
2286 	/* Try to open a blobid that does not exist */
2287 	spdk_bs_open_blob(g_bs, 0, blob_op_with_handle_complete, NULL);
2288 	CU_ASSERT(g_bserrno == -ENOENT);
2289 	CU_ASSERT(g_blob == NULL);
2290 
2291 	/* Create a blob */
2292 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
2293 	CU_ASSERT(g_bserrno == 0);
2294 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2295 	blobid = g_blobid;
2296 
2297 	spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
2298 	CU_ASSERT(g_bserrno == 0);
2299 	CU_ASSERT(g_blob != NULL);
2300 	blob = g_blob;
2301 
2302 	/* Try again to open valid blob but without the upper bit set */
2303 	spdk_bs_open_blob(g_bs, blobid & 0xFFFFFFFF, blob_op_with_handle_complete, NULL);
2304 	CU_ASSERT(g_bserrno == -ENOENT);
2305 	CU_ASSERT(g_blob == NULL);
2306 
2307 	/* Set some xattrs */
2308 	rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1);
2309 	CU_ASSERT(rc == 0);
2310 
2311 	length = 2345;
2312 	rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
2313 	CU_ASSERT(rc == 0);
2314 
2315 	/* Resize the blob */
2316 	spdk_blob_resize(blob, 10, blob_op_complete, NULL);
2317 	CU_ASSERT(g_bserrno == 0);
2318 
2319 	spdk_blob_close(blob, blob_op_complete, NULL);
2320 	CU_ASSERT(g_bserrno == 0);
2321 	blob = NULL;
2322 	g_blob = NULL;
2323 	g_blobid = SPDK_BLOBID_INVALID;
2324 
2325 	/* Unload the blob store */
2326 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2327 	CU_ASSERT(g_bserrno == 0);
2328 	g_bs = NULL;
2329 	g_blob = NULL;
2330 	g_blobid = 0;
2331 
2332 	super_block = (struct spdk_bs_super_block *)g_dev_buffer;
2333 	CU_ASSERT(super_block->clean == 1);
2334 
2335 	/* Load should fail for device with an unsupported blocklen */
2336 	dev = init_dev();
2337 	dev->blocklen = SPDK_BS_PAGE_SIZE * 2;
2338 	spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL);
2339 	CU_ASSERT(g_bserrno == -EINVAL);
2340 
2341 	/* Load should when max_md_ops is set to zero */
2342 	dev = init_dev();
2343 	spdk_bs_opts_init(&opts);
2344 	opts.max_md_ops = 0;
2345 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2346 	CU_ASSERT(g_bserrno == -EINVAL);
2347 
2348 	/* Load should when max_channel_ops is set to zero */
2349 	dev = init_dev();
2350 	spdk_bs_opts_init(&opts);
2351 	opts.max_channel_ops = 0;
2352 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2353 	CU_ASSERT(g_bserrno == -EINVAL);
2354 
2355 	/* Load an existing blob store */
2356 	dev = init_dev();
2357 	spdk_bs_opts_init(&opts);
2358 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
2359 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2360 	CU_ASSERT(g_bserrno == 0);
2361 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2362 
2363 	super_block = (struct spdk_bs_super_block *)g_dev_buffer;
2364 	CU_ASSERT(super_block->clean == 1);
2365 	CU_ASSERT(super_block->size == dev->blockcnt * dev->blocklen);
2366 
2367 	spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
2368 	CU_ASSERT(g_bserrno == 0);
2369 	CU_ASSERT(g_blob != NULL);
2370 	blob = g_blob;
2371 
2372 	/* Verify that blobstore is marked dirty after first metadata sync */
2373 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
2374 	CU_ASSERT(super_block->clean == 1);
2375 
2376 	/* Get the xattrs */
2377 	value = NULL;
2378 	rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len);
2379 	CU_ASSERT(rc == 0);
2380 	SPDK_CU_ASSERT_FATAL(value != NULL);
2381 	CU_ASSERT(*(uint64_t *)value == length);
2382 	CU_ASSERT(value_len == 8);
2383 
2384 	rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len);
2385 	CU_ASSERT(rc == -ENOENT);
2386 
2387 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10);
2388 
2389 	spdk_blob_close(blob, blob_op_complete, NULL);
2390 	CU_ASSERT(g_bserrno == 0);
2391 	blob = NULL;
2392 	g_blob = NULL;
2393 
2394 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2395 	CU_ASSERT(g_bserrno == 0);
2396 	g_bs = NULL;
2397 
2398 	/* Load should fail: bdev size < saved size */
2399 	dev = init_dev();
2400 	dev->blockcnt /= 2;
2401 
2402 	spdk_bs_opts_init(&opts);
2403 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
2404 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2405 
2406 	CU_ASSERT(g_bserrno == -EILSEQ);
2407 
2408 	/* Load should succeed: bdev size > saved size */
2409 	dev = init_dev();
2410 	dev->blockcnt *= 4;
2411 
2412 	spdk_bs_opts_init(&opts);
2413 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
2414 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2415 
2416 	CU_ASSERT(g_bserrno == 0);
2417 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2418 
2419 
2420 	/* Test compatibility mode */
2421 
2422 	dev = init_dev();
2423 	super_block->size = 0;
2424 	super_block->crc = _spdk_blob_md_page_calc_crc(super_block);
2425 
2426 	spdk_bs_opts_init(&opts);
2427 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
2428 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2429 	CU_ASSERT(g_bserrno == 0);
2430 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2431 
2432 	/* Create a blob */
2433 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
2434 	CU_ASSERT(g_bserrno == 0);
2435 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2436 
2437 	/* Blobstore should update number of blocks in super_block */
2438 	CU_ASSERT(super_block->size == dev->blockcnt * dev->blocklen);
2439 	CU_ASSERT(super_block->clean == 0);
2440 
2441 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2442 	CU_ASSERT(g_bserrno == 0);
2443 	CU_ASSERT(super_block->clean == 1);
2444 	g_bs = NULL;
2445 
2446 }
2447 
2448 static void
2449 bs_load_custom_cluster_size(void)
2450 {
2451 	struct spdk_bs_dev *dev;
2452 	struct spdk_bs_super_block *super_block;
2453 	struct spdk_bs_opts opts;
2454 	uint32_t custom_cluster_size = 4194304; /* 4MiB */
2455 	uint32_t cluster_sz;
2456 	uint64_t total_clusters;
2457 
2458 	dev = init_dev();
2459 	spdk_bs_opts_init(&opts);
2460 	opts.cluster_sz = custom_cluster_size;
2461 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
2462 
2463 	/* Initialize a new blob store */
2464 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2465 	CU_ASSERT(g_bserrno == 0);
2466 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2467 	cluster_sz = g_bs->cluster_sz;
2468 	total_clusters = g_bs->total_clusters;
2469 
2470 	/* Unload the blob store */
2471 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2472 	CU_ASSERT(g_bserrno == 0);
2473 	g_bs = NULL;
2474 	g_blob = NULL;
2475 	g_blobid = 0;
2476 
2477 	super_block = (struct spdk_bs_super_block *)g_dev_buffer;
2478 	CU_ASSERT(super_block->clean == 1);
2479 
2480 	/* Load an existing blob store */
2481 	dev = init_dev();
2482 	spdk_bs_opts_init(&opts);
2483 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
2484 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2485 	CU_ASSERT(g_bserrno == 0);
2486 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2487 	/* Compare cluster size and number to one after initialization */
2488 	CU_ASSERT(cluster_sz == g_bs->cluster_sz);
2489 	CU_ASSERT(total_clusters == g_bs->total_clusters);
2490 
2491 	super_block = (struct spdk_bs_super_block *)g_dev_buffer;
2492 	CU_ASSERT(super_block->clean == 1);
2493 	CU_ASSERT(super_block->size == dev->blockcnt * dev->blocklen);
2494 
2495 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2496 	CU_ASSERT(g_bserrno == 0);
2497 	CU_ASSERT(super_block->clean == 1);
2498 	g_bs = NULL;
2499 }
2500 
2501 static void
2502 bs_type(void)
2503 {
2504 	struct spdk_bs_dev *dev;
2505 	struct spdk_bs_opts opts;
2506 
2507 	dev = init_dev();
2508 	spdk_bs_opts_init(&opts);
2509 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
2510 
2511 	/* Initialize a new blob store */
2512 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2513 	CU_ASSERT(g_bserrno == 0);
2514 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2515 
2516 	/* Unload the blob store */
2517 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2518 	CU_ASSERT(g_bserrno == 0);
2519 	g_bs = NULL;
2520 	g_blob = NULL;
2521 	g_blobid = 0;
2522 
2523 	/* Load non existing blobstore type */
2524 	dev = init_dev();
2525 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "NONEXISTING");
2526 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2527 	CU_ASSERT(g_bserrno != 0);
2528 
2529 	/* Load with empty blobstore type */
2530 	dev = init_dev();
2531 	memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype));
2532 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2533 	CU_ASSERT(g_bserrno == 0);
2534 
2535 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2536 	CU_ASSERT(g_bserrno == 0);
2537 	g_bs = NULL;
2538 
2539 	/* Initialize a new blob store with empty bstype */
2540 	dev = init_dev();
2541 	memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype));
2542 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
2543 	CU_ASSERT(g_bserrno == 0);
2544 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2545 
2546 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2547 	CU_ASSERT(g_bserrno == 0);
2548 	g_bs = NULL;
2549 
2550 	/* Load non existing blobstore type */
2551 	dev = init_dev();
2552 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "NONEXISTING");
2553 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2554 	CU_ASSERT(g_bserrno != 0);
2555 
2556 	/* Load with empty blobstore type */
2557 	dev = init_dev();
2558 	memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype));
2559 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2560 	CU_ASSERT(g_bserrno == 0);
2561 
2562 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2563 	CU_ASSERT(g_bserrno == 0);
2564 	g_bs = NULL;
2565 }
2566 
2567 static void
2568 bs_super_block(void)
2569 {
2570 	struct spdk_bs_dev *dev;
2571 	struct spdk_bs_super_block *super_block;
2572 	struct spdk_bs_opts opts;
2573 	struct spdk_bs_super_block_ver1 super_block_v1;
2574 
2575 	dev = init_dev();
2576 	spdk_bs_opts_init(&opts);
2577 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
2578 
2579 	/* Initialize a new blob store */
2580 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2581 	CU_ASSERT(g_bserrno == 0);
2582 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2583 
2584 	/* Unload the blob store */
2585 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2586 	CU_ASSERT(g_bserrno == 0);
2587 	g_bs = NULL;
2588 	g_blob = NULL;
2589 	g_blobid = 0;
2590 
2591 	/* Load an existing blob store with version newer than supported */
2592 	super_block = (struct spdk_bs_super_block *)g_dev_buffer;
2593 	super_block->version++;
2594 
2595 	dev = init_dev();
2596 	memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype));
2597 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2598 	CU_ASSERT(g_bserrno != 0);
2599 
2600 	/* Create a new blob store with super block version 1 */
2601 	dev = init_dev();
2602 	super_block_v1.version = 1;
2603 	memcpy(super_block_v1.signature, "SPDKBLOB", sizeof(super_block_v1.signature));
2604 	super_block_v1.length = 0x1000;
2605 	super_block_v1.clean = 1;
2606 	super_block_v1.super_blob = 0xFFFFFFFFFFFFFFFF;
2607 	super_block_v1.cluster_size = 0x100000;
2608 	super_block_v1.used_page_mask_start = 0x01;
2609 	super_block_v1.used_page_mask_len = 0x01;
2610 	super_block_v1.used_cluster_mask_start = 0x02;
2611 	super_block_v1.used_cluster_mask_len = 0x01;
2612 	super_block_v1.md_start = 0x03;
2613 	super_block_v1.md_len = 0x40;
2614 	memset(super_block_v1.reserved, 0, 4036);
2615 	super_block_v1.crc = _spdk_blob_md_page_calc_crc(&super_block_v1);
2616 	memcpy(g_dev_buffer, &super_block_v1, sizeof(struct spdk_bs_super_block_ver1));
2617 
2618 	memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype));
2619 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2620 	CU_ASSERT(g_bserrno == 0);
2621 
2622 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2623 	CU_ASSERT(g_bserrno == 0);
2624 	g_bs = NULL;
2625 }
2626 
2627 /*
2628  * Create a blobstore and then unload it.
2629  */
2630 static void
2631 bs_unload(void)
2632 {
2633 	struct spdk_bs_dev *dev;
2634 	struct spdk_blob_store *bs;
2635 	spdk_blob_id blobid;
2636 	struct spdk_blob *blob;
2637 
2638 	dev = init_dev();
2639 
2640 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
2641 	CU_ASSERT(g_bserrno == 0);
2642 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2643 	bs = g_bs;
2644 
2645 	/* Create a blob and open it. */
2646 	g_bserrno = -1;
2647 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
2648 	CU_ASSERT(g_bserrno == 0);
2649 	CU_ASSERT(g_blobid > 0);
2650 	blobid = g_blobid;
2651 
2652 	g_bserrno = -1;
2653 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
2654 	CU_ASSERT(g_bserrno == 0);
2655 	CU_ASSERT(g_blob != NULL);
2656 	blob = g_blob;
2657 
2658 	/* Try to unload blobstore, should fail with open blob */
2659 	g_bserrno = -1;
2660 	spdk_bs_unload(bs, bs_op_complete, NULL);
2661 	CU_ASSERT(g_bserrno == -EBUSY);
2662 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2663 
2664 	/* Close the blob, then successfully unload blobstore */
2665 	g_bserrno = -1;
2666 	spdk_blob_close(blob, blob_op_complete, NULL);
2667 	CU_ASSERT(g_bserrno == 0);
2668 
2669 	g_bserrno = -1;
2670 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2671 	CU_ASSERT(g_bserrno == 0);
2672 	g_bs = NULL;
2673 }
2674 
2675 /*
2676  * Create a blobstore with a cluster size different than the default, and ensure it is
2677  *  persisted.
2678  */
2679 static void
2680 bs_cluster_sz(void)
2681 {
2682 	struct spdk_bs_dev *dev;
2683 	struct spdk_bs_opts opts;
2684 	uint32_t cluster_sz;
2685 
2686 	/* Set cluster size to zero */
2687 	dev = init_dev();
2688 	spdk_bs_opts_init(&opts);
2689 	opts.cluster_sz = 0;
2690 
2691 	/* Initialize a new blob store */
2692 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2693 	CU_ASSERT(g_bserrno == -EINVAL);
2694 	SPDK_CU_ASSERT_FATAL(g_bs == NULL);
2695 
2696 	/*
2697 	 * Set cluster size to blobstore page size,
2698 	 * to work it is required to be at least twice the blobstore page size.
2699 	 */
2700 	dev = init_dev();
2701 	spdk_bs_opts_init(&opts);
2702 	opts.cluster_sz = SPDK_BS_PAGE_SIZE;
2703 
2704 	/* Initialize a new blob store */
2705 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2706 	CU_ASSERT(g_bserrno == -ENOMEM);
2707 	SPDK_CU_ASSERT_FATAL(g_bs == NULL);
2708 
2709 	/*
2710 	 * Set cluster size to lower than page size,
2711 	 * to work it is required to be at least twice the blobstore page size.
2712 	 */
2713 	dev = init_dev();
2714 	spdk_bs_opts_init(&opts);
2715 	opts.cluster_sz = SPDK_BS_PAGE_SIZE - 1;
2716 
2717 	/* Initialize a new blob store */
2718 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2719 	CU_ASSERT(g_bserrno == -EINVAL);
2720 	SPDK_CU_ASSERT_FATAL(g_bs == NULL);
2721 
2722 	/* Set cluster size to twice the default */
2723 	dev = init_dev();
2724 	spdk_bs_opts_init(&opts);
2725 	opts.cluster_sz *= 2;
2726 	cluster_sz = opts.cluster_sz;
2727 
2728 	/* Initialize a new blob store */
2729 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2730 	CU_ASSERT(g_bserrno == 0);
2731 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2732 
2733 	CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz);
2734 
2735 	/* Unload the blob store */
2736 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2737 	CU_ASSERT(g_bserrno == 0);
2738 	g_bs = NULL;
2739 	g_blob = NULL;
2740 	g_blobid = 0;
2741 
2742 	dev = init_dev();
2743 	/* Load an existing blob store */
2744 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2745 	CU_ASSERT(g_bserrno == 0);
2746 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2747 
2748 	CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz);
2749 
2750 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2751 	CU_ASSERT(g_bserrno == 0);
2752 	g_bs = NULL;
2753 }
2754 
2755 /*
2756  * Create a blobstore, reload it and ensure total usable cluster count
2757  *  stays the same.
2758  */
2759 static void
2760 bs_usable_clusters(void)
2761 {
2762 	struct spdk_bs_dev *dev;
2763 	struct spdk_bs_opts opts;
2764 	uint32_t clusters;
2765 	int i;
2766 
2767 	/* Init blobstore */
2768 	dev = init_dev();
2769 	spdk_bs_opts_init(&opts);
2770 
2771 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2772 	CU_ASSERT(g_bserrno == 0);
2773 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2774 
2775 	clusters = spdk_bs_total_data_cluster_count(g_bs);
2776 
2777 	/* Unload the blob store */
2778 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2779 	CU_ASSERT(g_bserrno == 0);
2780 	g_bs = NULL;
2781 
2782 	dev = init_dev();
2783 	/* Load an existing blob store */
2784 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2785 	CU_ASSERT(g_bserrno == 0);
2786 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2787 
2788 	CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters);
2789 
2790 	/* Create and resize blobs to make sure that useable cluster count won't change */
2791 	for (i = 0; i < 4; i++) {
2792 		g_bserrno = -1;
2793 		g_blobid = SPDK_BLOBID_INVALID;
2794 		spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
2795 		CU_ASSERT(g_bserrno == 0);
2796 		CU_ASSERT(g_blobid !=  SPDK_BLOBID_INVALID);
2797 
2798 		g_bserrno = -1;
2799 		g_blob = NULL;
2800 		spdk_bs_open_blob(g_bs, g_blobid, blob_op_with_handle_complete, NULL);
2801 		CU_ASSERT(g_bserrno == 0);
2802 		CU_ASSERT(g_blob !=  NULL);
2803 
2804 		spdk_blob_resize(g_blob, 10, blob_op_complete, NULL);
2805 		CU_ASSERT(g_bserrno == 0);
2806 
2807 		g_bserrno = -1;
2808 		spdk_blob_close(g_blob, blob_op_complete, NULL);
2809 		CU_ASSERT(g_bserrno == 0);
2810 
2811 		CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters);
2812 	}
2813 
2814 	/* Reload the blob store to make sure that nothing changed */
2815 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2816 	CU_ASSERT(g_bserrno == 0);
2817 	g_bs = NULL;
2818 
2819 	dev = init_dev();
2820 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2821 	CU_ASSERT(g_bserrno == 0);
2822 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2823 
2824 	CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters);
2825 
2826 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2827 	CU_ASSERT(g_bserrno == 0);
2828 	g_bs = NULL;
2829 }
2830 
2831 /*
2832  * Test resizing of the metadata blob.  This requires creating enough blobs
2833  *  so that one cluster is not enough to fit the metadata for those blobs.
2834  *  To induce this condition to happen more quickly, we reduce the cluster
2835  *  size to 16KB, which means only 4 4KB blob metadata pages can fit.
2836  */
2837 static void
2838 bs_resize_md(void)
2839 {
2840 	const int CLUSTER_PAGE_COUNT = 4;
2841 	const int NUM_BLOBS = CLUSTER_PAGE_COUNT * 4;
2842 	struct spdk_bs_dev *dev;
2843 	struct spdk_bs_opts opts;
2844 	uint32_t cluster_sz;
2845 	spdk_blob_id blobids[NUM_BLOBS];
2846 	int i;
2847 
2848 
2849 	dev = init_dev();
2850 	spdk_bs_opts_init(&opts);
2851 	opts.cluster_sz = CLUSTER_PAGE_COUNT * 4096;
2852 	cluster_sz = opts.cluster_sz;
2853 
2854 	/* Initialize a new blob store */
2855 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2856 	CU_ASSERT(g_bserrno == 0);
2857 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2858 
2859 	CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz);
2860 
2861 	for (i = 0; i < NUM_BLOBS; i++) {
2862 		g_bserrno = -1;
2863 		g_blobid = SPDK_BLOBID_INVALID;
2864 		spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
2865 		CU_ASSERT(g_bserrno == 0);
2866 		CU_ASSERT(g_blobid !=  SPDK_BLOBID_INVALID);
2867 		blobids[i] = g_blobid;
2868 	}
2869 
2870 	/* Unload the blob store */
2871 	g_bserrno = -1;
2872 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2873 	CU_ASSERT(g_bserrno == 0);
2874 
2875 	/* Load an existing blob store */
2876 	g_bserrno = -1;
2877 	g_bs = NULL;
2878 	dev = init_dev();
2879 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2880 	CU_ASSERT(g_bserrno == 0);
2881 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2882 
2883 	CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz);
2884 
2885 	for (i = 0; i < NUM_BLOBS; i++) {
2886 		g_bserrno = -1;
2887 		g_blob = NULL;
2888 		spdk_bs_open_blob(g_bs, blobids[i], blob_op_with_handle_complete, NULL);
2889 		CU_ASSERT(g_bserrno == 0);
2890 		CU_ASSERT(g_blob !=  NULL);
2891 		g_bserrno = -1;
2892 		spdk_blob_close(g_blob, blob_op_complete, NULL);
2893 		CU_ASSERT(g_bserrno == 0);
2894 	}
2895 
2896 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
2897 	CU_ASSERT(g_bserrno == 0);
2898 	g_bs = NULL;
2899 }
2900 
2901 static void
2902 bs_destroy(void)
2903 {
2904 	struct spdk_bs_dev *dev;
2905 	struct spdk_bs_opts opts;
2906 
2907 	/* Initialize a new blob store */
2908 	dev = init_dev();
2909 	spdk_bs_opts_init(&opts);
2910 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2911 	CU_ASSERT(g_bserrno == 0);
2912 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2913 
2914 	/* Destroy the blob store */
2915 	g_bserrno = -1;
2916 	spdk_bs_destroy(g_bs, bs_op_complete, NULL);
2917 	CU_ASSERT(g_bserrno == 0);
2918 
2919 	/* Loading an non-existent blob store should fail. */
2920 	g_bs = NULL;
2921 	dev = init_dev();
2922 
2923 	g_bserrno = 0;
2924 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
2925 	CU_ASSERT(g_bserrno != 0);
2926 }
2927 
2928 /* Try to hit all of the corner cases associated with serializing
2929  * a blob to disk
2930  */
2931 static void
2932 blob_serialize(void)
2933 {
2934 	struct spdk_bs_dev *dev;
2935 	struct spdk_bs_opts opts;
2936 	struct spdk_blob_store *bs;
2937 	spdk_blob_id blobid[2];
2938 	struct spdk_blob *blob[2];
2939 	uint64_t i;
2940 	char *value;
2941 	int rc;
2942 
2943 	dev = init_dev();
2944 
2945 	/* Initialize a new blobstore with very small clusters */
2946 	spdk_bs_opts_init(&opts);
2947 	opts.cluster_sz = dev->blocklen * 8;
2948 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
2949 	CU_ASSERT(g_bserrno == 0);
2950 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
2951 	bs = g_bs;
2952 
2953 	/* Create and open two blobs */
2954 	for (i = 0; i < 2; i++) {
2955 		spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
2956 		CU_ASSERT(g_bserrno == 0);
2957 		CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
2958 		blobid[i] = g_blobid;
2959 
2960 		/* Open a blob */
2961 		spdk_bs_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL);
2962 		CU_ASSERT(g_bserrno == 0);
2963 		CU_ASSERT(g_blob != NULL);
2964 		blob[i] = g_blob;
2965 
2966 		/* Set a fairly large xattr on both blobs to eat up
2967 		 * metadata space
2968 		 */
2969 		value = calloc(dev->blocklen - 64, sizeof(char));
2970 		SPDK_CU_ASSERT_FATAL(value != NULL);
2971 		memset(value, i, dev->blocklen / 2);
2972 		rc = spdk_blob_set_xattr(blob[i], "name", value, dev->blocklen - 64);
2973 		CU_ASSERT(rc == 0);
2974 		free(value);
2975 	}
2976 
2977 	/* Resize the blobs, alternating 1 cluster at a time.
2978 	 * This thwarts run length encoding and will cause spill
2979 	 * over of the extents.
2980 	 */
2981 	for (i = 0; i < 6; i++) {
2982 		spdk_blob_resize(blob[i % 2], (i / 2) + 1, blob_op_complete, NULL);
2983 		CU_ASSERT(g_bserrno == 0);
2984 	}
2985 
2986 	for (i = 0; i < 2; i++) {
2987 		spdk_blob_sync_md(blob[i], blob_op_complete, NULL);
2988 		CU_ASSERT(g_bserrno == 0);
2989 	}
2990 
2991 	/* Close the blobs */
2992 	for (i = 0; i < 2; i++) {
2993 		spdk_blob_close(blob[i], blob_op_complete, NULL);
2994 		CU_ASSERT(g_bserrno == 0);
2995 	}
2996 
2997 	/* Unload the blobstore */
2998 	spdk_bs_unload(bs, bs_op_complete, NULL);
2999 	CU_ASSERT(g_bserrno == 0);
3000 	g_bs = NULL;
3001 	g_blob = NULL;
3002 	g_blobid = 0;
3003 	bs = NULL;
3004 
3005 	dev = init_dev();
3006 	/* Load an existing blob store */
3007 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
3008 	CU_ASSERT(g_bserrno == 0);
3009 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3010 	bs = g_bs;
3011 
3012 	for (i = 0; i < 2; i++) {
3013 		blob[i] = NULL;
3014 
3015 		spdk_bs_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL);
3016 		CU_ASSERT(g_bserrno == 0);
3017 		CU_ASSERT(g_blob != NULL);
3018 		blob[i] = g_blob;
3019 
3020 		CU_ASSERT(spdk_blob_get_num_clusters(blob[i]) == 3);
3021 
3022 		spdk_blob_close(blob[i], blob_op_complete, NULL);
3023 		CU_ASSERT(g_bserrno == 0);
3024 	}
3025 
3026 	spdk_bs_unload(bs, bs_op_complete, NULL);
3027 	CU_ASSERT(g_bserrno == 0);
3028 	g_bs = NULL;
3029 }
3030 
3031 static void
3032 blob_crc(void)
3033 {
3034 	struct spdk_blob_store *bs;
3035 	struct spdk_bs_dev *dev;
3036 	struct spdk_blob *blob;
3037 	spdk_blob_id blobid;
3038 	uint32_t page_num;
3039 	int index;
3040 	struct spdk_blob_md_page *page;
3041 
3042 	dev = init_dev();
3043 
3044 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
3045 	CU_ASSERT(g_bserrno == 0);
3046 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3047 	bs = g_bs;
3048 
3049 	spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL);
3050 	CU_ASSERT(g_bserrno == 0);
3051 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3052 	blobid = g_blobid;
3053 
3054 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
3055 	CU_ASSERT(g_bserrno == 0);
3056 	CU_ASSERT(g_blob != NULL);
3057 	blob = g_blob;
3058 
3059 	spdk_blob_close(blob, blob_op_complete, NULL);
3060 	CU_ASSERT(g_bserrno == 0);
3061 
3062 	page_num = _spdk_bs_blobid_to_page(blobid);
3063 	index = DEV_BUFFER_BLOCKLEN * (bs->md_start + page_num);
3064 	page = (struct spdk_blob_md_page *)&g_dev_buffer[index];
3065 	page->crc = 0;
3066 
3067 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
3068 	CU_ASSERT(g_bserrno == -EINVAL);
3069 	CU_ASSERT(g_blob == NULL);
3070 	g_bserrno = 0;
3071 
3072 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
3073 	CU_ASSERT(g_bserrno == -EINVAL);
3074 
3075 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3076 	CU_ASSERT(g_bserrno == 0);
3077 	g_bs = NULL;
3078 }
3079 
3080 static void
3081 super_block_crc(void)
3082 {
3083 	struct spdk_bs_dev *dev;
3084 	struct spdk_bs_super_block *super_block;
3085 	struct spdk_bs_opts opts;
3086 
3087 	dev = init_dev();
3088 	spdk_bs_opts_init(&opts);
3089 
3090 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
3091 	CU_ASSERT(g_bserrno == 0);
3092 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3093 
3094 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3095 	CU_ASSERT(g_bserrno == 0);
3096 	g_bs = NULL;
3097 
3098 	super_block = (struct spdk_bs_super_block *)g_dev_buffer;
3099 	super_block->crc = 0;
3100 	dev = init_dev();
3101 
3102 	/* Load an existing blob store */
3103 	g_bserrno = 0;
3104 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
3105 	CU_ASSERT(g_bserrno == -EILSEQ);
3106 }
3107 
3108 /* For blob dirty shutdown test case we do the following sub-test cases:
3109  * 1 Initialize new blob store and create 1 super blob with some xattrs, then we
3110  *   dirty shutdown and reload the blob store and verify the xattrs.
3111  * 2 Resize the blob from 10 clusters to 20 clusters and then dirty shutdown,
3112  *   reload the blob store and verify the clusters number.
3113  * 3 Create the second blob and then dirty shutdown, reload the blob store
3114  *   and verify the second blob.
3115  * 4 Delete the second blob and then dirty shutdown, reload the blob store
3116  *   and verify the second blob is invalid.
3117  * 5 Create the second blob again and also create the third blob, modify the
3118  *   md of second blob which makes the md invalid, and then dirty shutdown,
3119  *   reload the blob store verify the second blob, it should invalid and also
3120  *   verify the third blob, it should correct.
3121  */
3122 static void
3123 blob_dirty_shutdown(void)
3124 {
3125 	int rc;
3126 	int index;
3127 	struct spdk_bs_dev *dev;
3128 	spdk_blob_id blobid1, blobid2, blobid3;
3129 	struct spdk_blob *blob;
3130 	uint64_t length;
3131 	uint64_t free_clusters;
3132 	const void *value;
3133 	size_t value_len;
3134 	uint32_t page_num;
3135 	struct spdk_blob_md_page *page;
3136 	struct spdk_bs_opts opts;
3137 
3138 	dev = init_dev();
3139 	spdk_bs_opts_init(&opts);
3140 	/* Initialize a new blob store */
3141 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
3142 	CU_ASSERT(g_bserrno == 0);
3143 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3144 
3145 	/* Create first blob */
3146 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
3147 	CU_ASSERT(g_bserrno == 0);
3148 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3149 	blobid1 = g_blobid;
3150 
3151 	spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL);
3152 	CU_ASSERT(g_bserrno == 0);
3153 	CU_ASSERT(g_blob != NULL);
3154 	blob = g_blob;
3155 
3156 	/* Set some xattrs */
3157 	rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1);
3158 	CU_ASSERT(rc == 0);
3159 
3160 	length = 2345;
3161 	rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
3162 	CU_ASSERT(rc == 0);
3163 
3164 	/* Resize the blob */
3165 	spdk_blob_resize(blob, 10, blob_op_complete, NULL);
3166 	CU_ASSERT(g_bserrno == 0);
3167 
3168 	/* Set the blob as the super blob */
3169 	spdk_bs_set_super(g_bs, blobid1, blob_op_complete, NULL);
3170 	CU_ASSERT(g_bserrno == 0);
3171 
3172 	free_clusters = spdk_bs_free_cluster_count(g_bs);
3173 
3174 	spdk_blob_close(blob, blob_op_complete, NULL);
3175 	blob = NULL;
3176 	g_blob = NULL;
3177 	g_blobid = SPDK_BLOBID_INVALID;
3178 
3179 	/* Dirty shutdown */
3180 	_spdk_bs_free(g_bs);
3181 
3182 	/* reload blobstore */
3183 	dev = init_dev();
3184 	spdk_bs_opts_init(&opts);
3185 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
3186 	CU_ASSERT(g_bserrno == 0);
3187 
3188 	/* Get the super blob */
3189 	spdk_bs_get_super(g_bs, blob_op_with_id_complete, NULL);
3190 	CU_ASSERT(g_bserrno == 0);
3191 	CU_ASSERT(blobid1 == g_blobid);
3192 
3193 	spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL);
3194 	CU_ASSERT(g_bserrno == 0);
3195 	CU_ASSERT(g_blob != NULL);
3196 	blob = g_blob;
3197 
3198 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs));
3199 
3200 	/* Get the xattrs */
3201 	value = NULL;
3202 	rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len);
3203 	CU_ASSERT(rc == 0);
3204 	SPDK_CU_ASSERT_FATAL(value != NULL);
3205 	CU_ASSERT(*(uint64_t *)value == length);
3206 	CU_ASSERT(value_len == 8);
3207 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10);
3208 
3209 	/* Resize the blob */
3210 	spdk_blob_resize(blob, 20, blob_op_complete, NULL);
3211 	CU_ASSERT(g_bserrno == 0);
3212 
3213 	free_clusters = spdk_bs_free_cluster_count(g_bs);
3214 
3215 	spdk_blob_close(blob, blob_op_complete, NULL);
3216 	CU_ASSERT(g_bserrno == 0);
3217 	blob = NULL;
3218 	g_blob = NULL;
3219 	g_blobid = SPDK_BLOBID_INVALID;
3220 
3221 	/* Dirty shutdown */
3222 	_spdk_bs_free(g_bs);
3223 
3224 	/* reload the blobstore */
3225 	dev = init_dev();
3226 	spdk_bs_opts_init(&opts);
3227 	/* Load an existing blob store */
3228 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
3229 	CU_ASSERT(g_bserrno == 0);
3230 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3231 	spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL);
3232 	CU_ASSERT(g_bserrno == 0);
3233 	CU_ASSERT(g_blob != NULL);
3234 	blob = g_blob;
3235 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 20);
3236 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs));
3237 
3238 	spdk_blob_close(blob, blob_op_complete, NULL);
3239 	CU_ASSERT(g_bserrno == 0);
3240 	blob = NULL;
3241 	g_blob = NULL;
3242 	g_blobid = SPDK_BLOBID_INVALID;
3243 
3244 	/* Create second blob */
3245 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
3246 	CU_ASSERT(g_bserrno == 0);
3247 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3248 	blobid2 = g_blobid;
3249 
3250 	spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL);
3251 	CU_ASSERT(g_bserrno == 0);
3252 	CU_ASSERT(g_blob != NULL);
3253 	blob = g_blob;
3254 
3255 	/* Set some xattrs */
3256 	rc = spdk_blob_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1);
3257 	CU_ASSERT(rc == 0);
3258 
3259 	length = 5432;
3260 	rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
3261 	CU_ASSERT(rc == 0);
3262 
3263 	/* Resize the blob */
3264 	spdk_blob_resize(blob, 10, blob_op_complete, NULL);
3265 	CU_ASSERT(g_bserrno == 0);
3266 
3267 	free_clusters = spdk_bs_free_cluster_count(g_bs);
3268 
3269 	spdk_blob_close(blob, blob_op_complete, NULL);
3270 	blob = NULL;
3271 	g_blob = NULL;
3272 	g_blobid = SPDK_BLOBID_INVALID;
3273 
3274 	/* Dirty shutdown */
3275 	_spdk_bs_free(g_bs);
3276 
3277 	/* reload the blobstore */
3278 	dev = init_dev();
3279 	spdk_bs_opts_init(&opts);
3280 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
3281 	CU_ASSERT(g_bserrno == 0);
3282 
3283 	spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL);
3284 	CU_ASSERT(g_bserrno == 0);
3285 	CU_ASSERT(g_blob != NULL);
3286 	blob = g_blob;
3287 
3288 	/* Get the xattrs */
3289 	value = NULL;
3290 	rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len);
3291 	CU_ASSERT(rc == 0);
3292 	SPDK_CU_ASSERT_FATAL(value != NULL);
3293 	CU_ASSERT(*(uint64_t *)value == length);
3294 	CU_ASSERT(value_len == 8);
3295 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10);
3296 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs));
3297 
3298 	spdk_blob_close(blob, blob_op_complete, NULL);
3299 	CU_ASSERT(g_bserrno == 0);
3300 	spdk_bs_delete_blob(g_bs, blobid2, blob_op_complete, NULL);
3301 	CU_ASSERT(g_bserrno == 0);
3302 
3303 	free_clusters = spdk_bs_free_cluster_count(g_bs);
3304 
3305 	/* Dirty shutdown */
3306 	_spdk_bs_free(g_bs);
3307 	/* reload the blobstore */
3308 	dev = init_dev();
3309 	spdk_bs_opts_init(&opts);
3310 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
3311 	CU_ASSERT(g_bserrno == 0);
3312 
3313 	spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL);
3314 	CU_ASSERT(g_bserrno != 0);
3315 	CU_ASSERT(g_blob == NULL);
3316 
3317 	spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL);
3318 	CU_ASSERT(g_bserrno == 0);
3319 	CU_ASSERT(g_blob != NULL);
3320 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs));
3321 	spdk_blob_close(g_blob, blob_op_complete, NULL);
3322 	CU_ASSERT(g_bserrno == 0);
3323 
3324 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3325 	CU_ASSERT(g_bserrno == 0);
3326 	g_bs = NULL;
3327 
3328 	/* reload the blobstore */
3329 	dev = init_dev();
3330 	spdk_bs_opts_init(&opts);
3331 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
3332 	CU_ASSERT(g_bserrno == 0);
3333 
3334 	/* Create second blob */
3335 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
3336 	CU_ASSERT(g_bserrno == 0);
3337 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3338 	blobid2 = g_blobid;
3339 
3340 	/* Create third blob */
3341 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
3342 	CU_ASSERT(g_bserrno == 0);
3343 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3344 	blobid3 = g_blobid;
3345 
3346 	spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL);
3347 	CU_ASSERT(g_bserrno == 0);
3348 	CU_ASSERT(g_blob != NULL);
3349 	blob = g_blob;
3350 
3351 	/* Set some xattrs for second blob */
3352 	rc = spdk_blob_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1);
3353 	CU_ASSERT(rc == 0);
3354 
3355 	length = 5432;
3356 	rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
3357 	CU_ASSERT(rc == 0);
3358 
3359 	spdk_blob_close(blob, blob_op_complete, NULL);
3360 	blob = NULL;
3361 	g_blob = NULL;
3362 	g_blobid = SPDK_BLOBID_INVALID;
3363 
3364 	spdk_bs_open_blob(g_bs, blobid3, blob_op_with_handle_complete, NULL);
3365 	CU_ASSERT(g_bserrno == 0);
3366 	CU_ASSERT(g_blob != NULL);
3367 	blob = g_blob;
3368 
3369 	/* Set some xattrs for third blob */
3370 	rc = spdk_blob_set_xattr(blob, "name", "log2.txt", strlen("log2.txt") + 1);
3371 	CU_ASSERT(rc == 0);
3372 
3373 	length = 5432;
3374 	rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
3375 	CU_ASSERT(rc == 0);
3376 
3377 	spdk_blob_close(blob, blob_op_complete, NULL);
3378 	blob = NULL;
3379 	g_blob = NULL;
3380 	g_blobid = SPDK_BLOBID_INVALID;
3381 
3382 	/* Mark second blob as invalid */
3383 	page_num = _spdk_bs_blobid_to_page(blobid2);
3384 
3385 	index = DEV_BUFFER_BLOCKLEN * (g_bs->md_start + page_num);
3386 	page = (struct spdk_blob_md_page *)&g_dev_buffer[index];
3387 	page->sequence_num = 1;
3388 	page->crc = _spdk_blob_md_page_calc_crc(page);
3389 
3390 	free_clusters = spdk_bs_free_cluster_count(g_bs);
3391 
3392 	/* Dirty shutdown */
3393 	_spdk_bs_free(g_bs);
3394 	/* reload the blobstore */
3395 	dev = init_dev();
3396 	spdk_bs_opts_init(&opts);
3397 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
3398 	CU_ASSERT(g_bserrno == 0);
3399 
3400 	spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL);
3401 	CU_ASSERT(g_bserrno != 0);
3402 	CU_ASSERT(g_blob == NULL);
3403 
3404 	spdk_bs_open_blob(g_bs, blobid3, blob_op_with_handle_complete, NULL);
3405 	CU_ASSERT(g_bserrno == 0);
3406 	CU_ASSERT(g_blob != NULL);
3407 	blob = g_blob;
3408 
3409 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs));
3410 
3411 	spdk_blob_close(blob, blob_op_complete, NULL);
3412 	blob = NULL;
3413 	g_blob = NULL;
3414 	g_blobid = SPDK_BLOBID_INVALID;
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_flags(void)
3423 {
3424 	struct spdk_bs_dev *dev;
3425 	spdk_blob_id blobid_invalid, blobid_data_ro, blobid_md_ro;
3426 	struct spdk_blob *blob_invalid, *blob_data_ro, *blob_md_ro;
3427 	struct spdk_bs_opts opts;
3428 	int rc;
3429 
3430 	dev = init_dev();
3431 	spdk_bs_opts_init(&opts);
3432 
3433 	/* Initialize a new blob store */
3434 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
3435 	CU_ASSERT(g_bserrno == 0);
3436 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3437 
3438 	/* Create three blobs - one each for testing invalid, data_ro and md_ro flags. */
3439 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
3440 	CU_ASSERT(g_bserrno == 0);
3441 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3442 	blobid_invalid = g_blobid;
3443 
3444 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
3445 	CU_ASSERT(g_bserrno == 0);
3446 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3447 	blobid_data_ro = g_blobid;
3448 
3449 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
3450 	CU_ASSERT(g_bserrno == 0);
3451 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3452 	blobid_md_ro = g_blobid;
3453 
3454 	spdk_bs_open_blob(g_bs, blobid_invalid, blob_op_with_handle_complete, NULL);
3455 	CU_ASSERT(g_bserrno == 0);
3456 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3457 	blob_invalid = g_blob;
3458 
3459 	spdk_bs_open_blob(g_bs, blobid_data_ro, blob_op_with_handle_complete, NULL);
3460 	CU_ASSERT(g_bserrno == 0);
3461 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3462 	blob_data_ro = g_blob;
3463 
3464 	spdk_bs_open_blob(g_bs, blobid_md_ro, blob_op_with_handle_complete, NULL);
3465 	CU_ASSERT(g_bserrno == 0);
3466 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3467 	blob_md_ro = g_blob;
3468 
3469 	/* Change the size of blob_data_ro to check if flags are serialized
3470 	 * when blob has non zero number of extents */
3471 	spdk_blob_resize(blob_data_ro, 10, blob_op_complete, NULL);
3472 	CU_ASSERT(g_bserrno == 0);
3473 
3474 	/* Set the xattr to check if flags are serialized
3475 	 * when blob has non zero number of xattrs */
3476 	rc = spdk_blob_set_xattr(blob_md_ro, "name", "log.txt", strlen("log.txt") + 1);
3477 	CU_ASSERT(rc == 0);
3478 
3479 	blob_invalid->invalid_flags = (1ULL << 63);
3480 	blob_invalid->state = SPDK_BLOB_STATE_DIRTY;
3481 	blob_data_ro->data_ro_flags = (1ULL << 62);
3482 	blob_data_ro->state = SPDK_BLOB_STATE_DIRTY;
3483 	blob_md_ro->md_ro_flags = (1ULL << 61);
3484 	blob_md_ro->state = SPDK_BLOB_STATE_DIRTY;
3485 
3486 	g_bserrno = -1;
3487 	spdk_blob_sync_md(blob_invalid, blob_op_complete, NULL);
3488 	CU_ASSERT(g_bserrno == 0);
3489 	g_bserrno = -1;
3490 	spdk_blob_sync_md(blob_data_ro, blob_op_complete, NULL);
3491 	CU_ASSERT(g_bserrno == 0);
3492 	g_bserrno = -1;
3493 	spdk_blob_sync_md(blob_md_ro, blob_op_complete, NULL);
3494 	CU_ASSERT(g_bserrno == 0);
3495 
3496 	g_bserrno = -1;
3497 	spdk_blob_close(blob_invalid, blob_op_complete, NULL);
3498 	CU_ASSERT(g_bserrno == 0);
3499 	blob_invalid = NULL;
3500 	g_bserrno = -1;
3501 	spdk_blob_close(blob_data_ro, blob_op_complete, NULL);
3502 	CU_ASSERT(g_bserrno == 0);
3503 	blob_data_ro = NULL;
3504 	g_bserrno = -1;
3505 	spdk_blob_close(blob_md_ro, blob_op_complete, NULL);
3506 	CU_ASSERT(g_bserrno == 0);
3507 	blob_md_ro = NULL;
3508 
3509 	g_blob = NULL;
3510 	g_blobid = SPDK_BLOBID_INVALID;
3511 
3512 	/* Unload the blob store */
3513 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3514 	CU_ASSERT(g_bserrno == 0);
3515 	g_bs = NULL;
3516 
3517 	/* Load an existing blob store */
3518 	dev = init_dev();
3519 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
3520 	CU_ASSERT(g_bserrno == 0);
3521 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3522 
3523 	g_blob = NULL;
3524 	g_bserrno = 0;
3525 	spdk_bs_open_blob(g_bs, blobid_invalid, blob_op_with_handle_complete, NULL);
3526 	CU_ASSERT(g_bserrno != 0);
3527 	CU_ASSERT(g_blob == NULL);
3528 
3529 	g_blob = NULL;
3530 	g_bserrno = -1;
3531 	spdk_bs_open_blob(g_bs, blobid_data_ro, blob_op_with_handle_complete, NULL);
3532 	CU_ASSERT(g_bserrno == 0);
3533 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3534 	blob_data_ro = g_blob;
3535 	/* If an unknown data_ro flag was found, the blob should be marked both data and md read-only. */
3536 	CU_ASSERT(blob_data_ro->data_ro == true);
3537 	CU_ASSERT(blob_data_ro->md_ro == true);
3538 	CU_ASSERT(spdk_blob_get_num_clusters(blob_data_ro) == 10);
3539 
3540 	g_blob = NULL;
3541 	g_bserrno = -1;
3542 	spdk_bs_open_blob(g_bs, blobid_md_ro, blob_op_with_handle_complete, NULL);
3543 	CU_ASSERT(g_bserrno == 0);
3544 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3545 	blob_md_ro = g_blob;
3546 	CU_ASSERT(blob_md_ro->data_ro == false);
3547 	CU_ASSERT(blob_md_ro->md_ro == true);
3548 
3549 	g_bserrno = -1;
3550 	spdk_blob_sync_md(blob_md_ro, blob_op_complete, NULL);
3551 	CU_ASSERT(g_bserrno == 0);
3552 
3553 	spdk_blob_close(blob_data_ro, blob_op_complete, NULL);
3554 	CU_ASSERT(g_bserrno == 0);
3555 	spdk_blob_close(blob_md_ro, blob_op_complete, NULL);
3556 	CU_ASSERT(g_bserrno == 0);
3557 
3558 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3559 	CU_ASSERT(g_bserrno == 0);
3560 }
3561 
3562 static void
3563 bs_version(void)
3564 {
3565 	struct spdk_bs_super_block *super;
3566 	struct spdk_bs_dev *dev;
3567 	struct spdk_bs_opts opts;
3568 	spdk_blob_id blobid;
3569 
3570 	dev = init_dev();
3571 	spdk_bs_opts_init(&opts);
3572 
3573 	/* Initialize a new blob store */
3574 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
3575 	CU_ASSERT(g_bserrno == 0);
3576 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3577 
3578 	/* Unload the blob store */
3579 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3580 	CU_ASSERT(g_bserrno == 0);
3581 	g_bs = NULL;
3582 
3583 	/*
3584 	 * Change the bs version on disk.  This will allow us to
3585 	 *  test that the version does not get modified automatically
3586 	 *  when loading and unloading the blobstore.
3587 	 */
3588 	super = (struct spdk_bs_super_block *)&g_dev_buffer[0];
3589 	CU_ASSERT(super->version == SPDK_BS_VERSION);
3590 	CU_ASSERT(super->clean == 1);
3591 	super->version = 2;
3592 	/*
3593 	 * Version 2 metadata does not have a used blobid mask, so clear
3594 	 *  those fields in the super block and zero the corresponding
3595 	 *  region on "disk".  We will use this to ensure blob IDs are
3596 	 *  correctly reconstructed.
3597 	 */
3598 	memset(&g_dev_buffer[super->used_blobid_mask_start * SPDK_BS_PAGE_SIZE], 0,
3599 	       super->used_blobid_mask_len * SPDK_BS_PAGE_SIZE);
3600 	super->used_blobid_mask_start = 0;
3601 	super->used_blobid_mask_len = 0;
3602 	super->crc = _spdk_blob_md_page_calc_crc(super);
3603 
3604 	/* Load an existing blob store */
3605 	dev = init_dev();
3606 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
3607 	CU_ASSERT(g_bserrno == 0);
3608 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3609 	CU_ASSERT(super->clean == 1);
3610 
3611 	/*
3612 	 * Create a blob - just to make sure that when we unload it
3613 	 *  results in writing the super block (since metadata pages
3614 	 *  were allocated.
3615 	 */
3616 	spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
3617 	CU_ASSERT(g_bserrno == 0);
3618 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3619 	blobid = g_blobid;
3620 
3621 	/* Unload the blob store */
3622 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3623 	CU_ASSERT(g_bserrno == 0);
3624 	g_bs = NULL;
3625 	CU_ASSERT(super->version == 2);
3626 	CU_ASSERT(super->used_blobid_mask_start == 0);
3627 	CU_ASSERT(super->used_blobid_mask_len == 0);
3628 
3629 	dev = init_dev();
3630 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
3631 	CU_ASSERT(g_bserrno == 0);
3632 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3633 
3634 	g_blob = NULL;
3635 	spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
3636 	CU_ASSERT(g_bserrno == 0);
3637 	CU_ASSERT(g_blob != NULL);
3638 
3639 	spdk_blob_close(g_blob, blob_op_complete, NULL);
3640 	CU_ASSERT(g_bserrno == 0);
3641 
3642 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3643 	CU_ASSERT(g_bserrno == 0);
3644 	g_bs = NULL;
3645 	CU_ASSERT(super->version == 2);
3646 	CU_ASSERT(super->used_blobid_mask_start == 0);
3647 	CU_ASSERT(super->used_blobid_mask_len == 0);
3648 }
3649 
3650 static void
3651 blob_set_xattrs(void)
3652 {
3653 	struct spdk_blob_store *bs;
3654 	struct spdk_bs_dev *dev;
3655 	struct spdk_blob *blob;
3656 	struct spdk_blob_opts opts;
3657 	spdk_blob_id blobid;
3658 	const void *value;
3659 	size_t value_len;
3660 	int rc;
3661 
3662 	dev = init_dev();
3663 
3664 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
3665 	CU_ASSERT(g_bserrno == 0);
3666 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3667 	bs = g_bs;
3668 
3669 	/* Create blob with extra attributes */
3670 	spdk_blob_opts_init(&opts);
3671 
3672 	opts.xattrs.names = g_xattr_names;
3673 	opts.xattrs.get_value = _get_xattr_value;
3674 	opts.xattrs.count = 3;
3675 	opts.xattrs.ctx = &g_ctx;
3676 
3677 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
3678 	CU_ASSERT(g_bserrno == 0);
3679 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3680 	blobid = g_blobid;
3681 
3682 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
3683 	CU_ASSERT(g_bserrno == 0);
3684 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3685 	blob = g_blob;
3686 
3687 	/* Get the xattrs */
3688 	value = NULL;
3689 
3690 	rc = spdk_blob_get_xattr_value(blob, g_xattr_names[0], &value, &value_len);
3691 	CU_ASSERT(rc == 0);
3692 	SPDK_CU_ASSERT_FATAL(value != NULL);
3693 	CU_ASSERT(value_len == strlen(g_xattr_values[0]));
3694 	CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len);
3695 
3696 	rc = spdk_blob_get_xattr_value(blob, g_xattr_names[1], &value, &value_len);
3697 	CU_ASSERT(rc == 0);
3698 	SPDK_CU_ASSERT_FATAL(value != NULL);
3699 	CU_ASSERT(value_len == strlen(g_xattr_values[1]));
3700 	CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len);
3701 
3702 	rc = spdk_blob_get_xattr_value(blob, g_xattr_names[2], &value, &value_len);
3703 	CU_ASSERT(rc == 0);
3704 	SPDK_CU_ASSERT_FATAL(value != NULL);
3705 	CU_ASSERT(value_len == strlen(g_xattr_values[2]));
3706 	CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len);
3707 
3708 	/* Try to get non existing attribute */
3709 
3710 	rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len);
3711 	CU_ASSERT(rc == -ENOENT);
3712 
3713 	spdk_blob_close(blob, blob_op_complete, NULL);
3714 	CU_ASSERT(g_bserrno == 0);
3715 	blob = NULL;
3716 	g_blob = NULL;
3717 	g_blobid = SPDK_BLOBID_INVALID;
3718 
3719 	/* NULL callback */
3720 	spdk_blob_opts_init(&opts);
3721 	opts.xattrs.names = g_xattr_names;
3722 	opts.xattrs.get_value = NULL;
3723 	opts.xattrs.count = 1;
3724 	opts.xattrs.ctx = &g_ctx;
3725 
3726 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
3727 	CU_ASSERT(g_bserrno == -EINVAL);
3728 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3729 
3730 	/* NULL values */
3731 	spdk_blob_opts_init(&opts);
3732 	opts.xattrs.names = g_xattr_names;
3733 	opts.xattrs.get_value = _get_xattr_value_null;
3734 	opts.xattrs.count = 1;
3735 	opts.xattrs.ctx = NULL;
3736 
3737 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
3738 	CU_ASSERT(g_bserrno == -EINVAL);
3739 
3740 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3741 	CU_ASSERT(g_bserrno == 0);
3742 	g_bs = NULL;
3743 
3744 }
3745 
3746 static void
3747 blob_thin_prov_alloc(void)
3748 {
3749 	struct spdk_blob_store *bs;
3750 	struct spdk_bs_dev *dev;
3751 	struct spdk_blob *blob;
3752 	struct spdk_blob_opts opts;
3753 	spdk_blob_id blobid;
3754 	uint64_t free_clusters;
3755 
3756 	dev = init_dev();
3757 
3758 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
3759 	CU_ASSERT(g_bserrno == 0);
3760 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3761 	bs = g_bs;
3762 	free_clusters = spdk_bs_free_cluster_count(bs);
3763 
3764 	/* Set blob as thin provisioned */
3765 	spdk_blob_opts_init(&opts);
3766 	opts.thin_provision = true;
3767 
3768 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
3769 	CU_ASSERT(g_bserrno == 0);
3770 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3771 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3772 	blobid = g_blobid;
3773 
3774 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
3775 	CU_ASSERT(g_bserrno == 0);
3776 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3777 	blob = g_blob;
3778 
3779 	CU_ASSERT(blob->active.num_clusters == 0);
3780 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0);
3781 
3782 	/* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */
3783 	spdk_blob_resize(blob, 5, blob_op_complete, NULL);
3784 	CU_ASSERT(g_bserrno == 0);
3785 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3786 	CU_ASSERT(blob->active.num_clusters == 5);
3787 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5);
3788 
3789 	/* Grow it to 1TB - still unallocated */
3790 	spdk_blob_resize(blob, 262144, blob_op_complete, NULL);
3791 	CU_ASSERT(g_bserrno == 0);
3792 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3793 	CU_ASSERT(blob->active.num_clusters == 262144);
3794 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 262144);
3795 
3796 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
3797 	CU_ASSERT(g_bserrno == 0);
3798 	/* Sync must not change anything */
3799 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3800 	CU_ASSERT(blob->active.num_clusters == 262144);
3801 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 262144);
3802 	/* Since clusters are not allocated,
3803 	 * number of metadata pages is expected to be minimal.
3804 	 */
3805 	CU_ASSERT(blob->active.num_pages == 1);
3806 
3807 	/* Shrink the blob to 3 clusters - still unallocated */
3808 	spdk_blob_resize(blob, 3, blob_op_complete, NULL);
3809 	CU_ASSERT(g_bserrno == 0);
3810 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3811 	CU_ASSERT(blob->active.num_clusters == 3);
3812 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 3);
3813 
3814 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
3815 	CU_ASSERT(g_bserrno == 0);
3816 	/* Sync must not change anything */
3817 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3818 	CU_ASSERT(blob->active.num_clusters == 3);
3819 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 3);
3820 
3821 	spdk_blob_close(blob, blob_op_complete, NULL);
3822 	CU_ASSERT(g_bserrno == 0);
3823 
3824 	/* Unload the blob store */
3825 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3826 	CU_ASSERT(g_bserrno == 0);
3827 	g_bs = NULL;
3828 	g_blob = NULL;
3829 	g_blobid = 0;
3830 
3831 	/* Load an existing blob store */
3832 	dev = init_dev();
3833 	spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL);
3834 	CU_ASSERT(g_bserrno == 0);
3835 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3836 
3837 	bs = g_bs;
3838 
3839 	spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
3840 	CU_ASSERT(g_bserrno == 0);
3841 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3842 	blob = g_blob;
3843 
3844 	/* Check that clusters allocation and size is still the same */
3845 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3846 	CU_ASSERT(blob->active.num_clusters == 3);
3847 
3848 	spdk_blob_close(blob, blob_op_complete, NULL);
3849 	CU_ASSERT(g_bserrno == 0);
3850 
3851 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
3852 	CU_ASSERT(g_bserrno == 0);
3853 
3854 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3855 	CU_ASSERT(g_bserrno == 0);
3856 	g_bs = NULL;
3857 }
3858 
3859 static void
3860 blob_insert_cluster_msg(void)
3861 {
3862 	struct spdk_blob_store *bs;
3863 	struct spdk_bs_dev *dev;
3864 	struct spdk_blob *blob;
3865 	struct spdk_blob_opts opts;
3866 	spdk_blob_id blobid;
3867 	uint64_t free_clusters;
3868 
3869 	dev = init_dev();
3870 
3871 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
3872 	CU_ASSERT(g_bserrno == 0);
3873 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3874 	bs = g_bs;
3875 	free_clusters = spdk_bs_free_cluster_count(bs);
3876 
3877 	/* Set blob as thin provisioned */
3878 	spdk_blob_opts_init(&opts);
3879 	opts.thin_provision = true;
3880 	opts.num_clusters = 4;
3881 
3882 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
3883 	CU_ASSERT(g_bserrno == 0);
3884 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3885 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3886 	blobid = g_blobid;
3887 
3888 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
3889 	CU_ASSERT(g_bserrno == 0);
3890 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3891 	blob = g_blob;
3892 
3893 	CU_ASSERT(blob->active.num_clusters == 4);
3894 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 4);
3895 	CU_ASSERT(blob->active.clusters[1] == 0);
3896 
3897 	_spdk_bs_claim_cluster(bs, 0xF);
3898 	_spdk_blob_insert_cluster_on_md_thread(blob, 1, 0xF, blob_op_complete, NULL);
3899 
3900 	CU_ASSERT(blob->active.clusters[1] != 0);
3901 
3902 	spdk_blob_close(blob, blob_op_complete, NULL);
3903 	CU_ASSERT(g_bserrno == 0);
3904 
3905 	/* Unload the blob store */
3906 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3907 	CU_ASSERT(g_bserrno == 0);
3908 	g_bs = NULL;
3909 	g_blob = NULL;
3910 	g_blobid = 0;
3911 
3912 	/* Load an existing blob store */
3913 	dev = init_dev();
3914 	spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL);
3915 	CU_ASSERT(g_bserrno == 0);
3916 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3917 
3918 	bs = g_bs;
3919 
3920 	spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
3921 	CU_ASSERT(g_bserrno == 0);
3922 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3923 	blob = g_blob;
3924 
3925 	CU_ASSERT(blob->active.clusters[1] != 0);
3926 
3927 	spdk_blob_close(blob, blob_op_complete, NULL);
3928 	CU_ASSERT(g_bserrno == 0);
3929 
3930 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
3931 	CU_ASSERT(g_bserrno == 0);
3932 
3933 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
3934 	CU_ASSERT(g_bserrno == 0);
3935 	g_bs = NULL;
3936 }
3937 
3938 static void
3939 blob_thin_prov_rw(void)
3940 {
3941 	static const uint8_t zero[10 * 4096] = { 0 };
3942 	struct spdk_blob_store *bs;
3943 	struct spdk_bs_dev *dev;
3944 	struct spdk_blob *blob;
3945 	struct spdk_io_channel *channel;
3946 	struct spdk_blob_opts opts;
3947 	spdk_blob_id blobid;
3948 	uint64_t free_clusters;
3949 	uint64_t page_size;
3950 	uint8_t payload_read[10 * 4096];
3951 	uint8_t payload_write[10 * 4096];
3952 	uint64_t write_bytes;
3953 	uint64_t read_bytes;
3954 
3955 	dev = init_dev();
3956 
3957 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
3958 	CU_ASSERT(g_bserrno == 0);
3959 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
3960 	bs = g_bs;
3961 	free_clusters = spdk_bs_free_cluster_count(bs);
3962 	page_size = spdk_bs_get_page_size(bs);
3963 
3964 	channel = spdk_bs_alloc_io_channel(bs);
3965 	CU_ASSERT(channel != NULL);
3966 
3967 	spdk_blob_opts_init(&opts);
3968 	opts.thin_provision = true;
3969 
3970 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
3971 	CU_ASSERT(g_bserrno == 0);
3972 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
3973 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3974 	blobid = g_blobid;
3975 
3976 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
3977 	CU_ASSERT(g_bserrno == 0);
3978 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
3979 	blob = g_blob;
3980 
3981 	CU_ASSERT(blob->active.num_clusters == 0);
3982 
3983 	/* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */
3984 	spdk_blob_resize(blob, 5, blob_op_complete, NULL);
3985 	CU_ASSERT(g_bserrno == 0);
3986 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3987 	CU_ASSERT(blob->active.num_clusters == 5);
3988 
3989 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
3990 	CU_ASSERT(g_bserrno == 0);
3991 	/* Sync must not change anything */
3992 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
3993 	CU_ASSERT(blob->active.num_clusters == 5);
3994 
3995 	/* Payload should be all zeros from unallocated clusters */
3996 	memset(payload_read, 0xFF, sizeof(payload_read));
3997 	spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL);
3998 	CU_ASSERT(g_bserrno == 0);
3999 	CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0);
4000 
4001 	write_bytes = g_dev_write_bytes;
4002 	read_bytes = g_dev_read_bytes;
4003 
4004 	memset(payload_write, 0xE5, sizeof(payload_write));
4005 	spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL);
4006 	CU_ASSERT(g_bserrno == 0);
4007 	CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs));
4008 	/* For thin-provisioned blob we need to write 10 pages plus one page metadata and
4009 	 * read 0 bytes */
4010 	CU_ASSERT(g_dev_write_bytes - write_bytes == page_size * 11);
4011 	CU_ASSERT(g_dev_read_bytes - read_bytes == 0);
4012 
4013 	spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL);
4014 	CU_ASSERT(g_bserrno == 0);
4015 	CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0);
4016 
4017 	spdk_blob_close(blob, blob_op_complete, NULL);
4018 	CU_ASSERT(g_bserrno == 0);
4019 
4020 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
4021 	CU_ASSERT(g_bserrno == 0);
4022 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
4023 
4024 	spdk_bs_free_io_channel(channel);
4025 
4026 	/* Unload the blob store */
4027 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
4028 	CU_ASSERT(g_bserrno == 0);
4029 	g_bs = NULL;
4030 	g_blob = NULL;
4031 	g_blobid = 0;
4032 }
4033 
4034 static void
4035 blob_thin_prov_rw_iov(void)
4036 {
4037 	static const uint8_t zero[10 * 4096] = { 0 };
4038 	struct spdk_blob_store *bs;
4039 	struct spdk_bs_dev *dev;
4040 	struct spdk_blob *blob;
4041 	struct spdk_io_channel *channel;
4042 	struct spdk_blob_opts opts;
4043 	spdk_blob_id blobid;
4044 	uint64_t free_clusters;
4045 	uint8_t payload_read[10 * 4096];
4046 	uint8_t payload_write[10 * 4096];
4047 	struct iovec iov_read[3];
4048 	struct iovec iov_write[3];
4049 
4050 	dev = init_dev();
4051 
4052 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
4053 	CU_ASSERT(g_bserrno == 0);
4054 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
4055 	bs = g_bs;
4056 	free_clusters = spdk_bs_free_cluster_count(bs);
4057 
4058 	channel = spdk_bs_alloc_io_channel(bs);
4059 	CU_ASSERT(channel != NULL);
4060 
4061 	spdk_blob_opts_init(&opts);
4062 	opts.thin_provision = true;
4063 
4064 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
4065 	CU_ASSERT(g_bserrno == 0);
4066 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
4067 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
4068 	blobid = g_blobid;
4069 
4070 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
4071 	CU_ASSERT(g_bserrno == 0);
4072 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4073 	blob = g_blob;
4074 
4075 	CU_ASSERT(blob->active.num_clusters == 0);
4076 
4077 	/* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */
4078 	spdk_blob_resize(blob, 5, blob_op_complete, NULL);
4079 	CU_ASSERT(g_bserrno == 0);
4080 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
4081 	CU_ASSERT(blob->active.num_clusters == 5);
4082 
4083 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
4084 	CU_ASSERT(g_bserrno == 0);
4085 	/* Sync must not change anything */
4086 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
4087 	CU_ASSERT(blob->active.num_clusters == 5);
4088 
4089 	/* Payload should be all zeros from unallocated clusters */
4090 	memset(payload_read, 0xAA, sizeof(payload_read));
4091 	iov_read[0].iov_base = payload_read;
4092 	iov_read[0].iov_len = 3 * 4096;
4093 	iov_read[1].iov_base = payload_read + 3 * 4096;
4094 	iov_read[1].iov_len = 4 * 4096;
4095 	iov_read[2].iov_base = payload_read + 7 * 4096;
4096 	iov_read[2].iov_len = 3 * 4096;
4097 	spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL);
4098 	CU_ASSERT(g_bserrno == 0);
4099 	CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0);
4100 
4101 	memset(payload_write, 0xE5, sizeof(payload_write));
4102 	iov_write[0].iov_base = payload_write;
4103 	iov_write[0].iov_len = 1 * 4096;
4104 	iov_write[1].iov_base = payload_write + 1 * 4096;
4105 	iov_write[1].iov_len = 5 * 4096;
4106 	iov_write[2].iov_base = payload_write + 6 * 4096;
4107 	iov_write[2].iov_len = 4 * 4096;
4108 
4109 	spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL);
4110 	CU_ASSERT(g_bserrno == 0);
4111 
4112 	memset(payload_read, 0xAA, sizeof(payload_read));
4113 	iov_read[0].iov_base = payload_read;
4114 	iov_read[0].iov_len = 3 * 4096;
4115 	iov_read[1].iov_base = payload_read + 3 * 4096;
4116 	iov_read[1].iov_len = 4 * 4096;
4117 	iov_read[2].iov_base = payload_read + 7 * 4096;
4118 	iov_read[2].iov_len = 3 * 4096;
4119 	spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL);
4120 	CU_ASSERT(g_bserrno == 0);
4121 	CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0);
4122 
4123 	spdk_blob_close(blob, blob_op_complete, NULL);
4124 	CU_ASSERT(g_bserrno == 0);
4125 
4126 	spdk_bs_free_io_channel(channel);
4127 
4128 	/* Unload the blob store */
4129 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
4130 	CU_ASSERT(g_bserrno == 0);
4131 	g_bs = NULL;
4132 	g_blob = NULL;
4133 	g_blobid = 0;
4134 }
4135 
4136 struct iter_ctx {
4137 	int		current_iter;
4138 	spdk_blob_id	blobid[4];
4139 };
4140 
4141 static void
4142 test_iter(void *arg, struct spdk_blob *blob, int bserrno)
4143 {
4144 	struct iter_ctx *iter_ctx = arg;
4145 	spdk_blob_id blobid;
4146 
4147 	CU_ASSERT(bserrno == 0);
4148 	blobid = spdk_blob_get_id(blob);
4149 	CU_ASSERT(blobid == iter_ctx->blobid[iter_ctx->current_iter++]);
4150 }
4151 
4152 static void
4153 bs_load_iter(void)
4154 {
4155 	struct spdk_bs_dev *dev;
4156 	struct iter_ctx iter_ctx = { 0 };
4157 	struct spdk_blob *blob;
4158 	int i, rc;
4159 	struct spdk_bs_opts opts;
4160 
4161 	dev = init_dev();
4162 	spdk_bs_opts_init(&opts);
4163 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
4164 
4165 	/* Initialize a new blob store */
4166 	spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
4167 	CU_ASSERT(g_bserrno == 0);
4168 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
4169 
4170 	for (i = 0; i < 4; i++) {
4171 		g_bserrno = -1;
4172 		g_blobid = SPDK_BLOBID_INVALID;
4173 		spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
4174 		CU_ASSERT(g_bserrno == 0);
4175 		CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
4176 		iter_ctx.blobid[i] = g_blobid;
4177 
4178 		g_bserrno = -1;
4179 		g_blob = NULL;
4180 		spdk_bs_open_blob(g_bs, g_blobid, blob_op_with_handle_complete, NULL);
4181 		CU_ASSERT(g_bserrno == 0);
4182 		CU_ASSERT(g_blob != NULL);
4183 		blob = g_blob;
4184 
4185 		/* Just save the blobid as an xattr for testing purposes. */
4186 		rc = spdk_blob_set_xattr(blob, "blobid", &g_blobid, sizeof(g_blobid));
4187 		CU_ASSERT(rc == 0);
4188 
4189 		/* Resize the blob */
4190 		spdk_blob_resize(blob, i, blob_op_complete, NULL);
4191 		CU_ASSERT(g_bserrno == 0);
4192 
4193 		spdk_blob_close(blob, blob_op_complete, NULL);
4194 		CU_ASSERT(g_bserrno == 0);
4195 	}
4196 
4197 	g_bserrno = -1;
4198 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
4199 	CU_ASSERT(g_bserrno == 0);
4200 
4201 	dev = init_dev();
4202 	spdk_bs_opts_init(&opts);
4203 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
4204 	opts.iter_cb_fn = test_iter;
4205 	opts.iter_cb_arg = &iter_ctx;
4206 
4207 	/* Test blob iteration during load after a clean shutdown. */
4208 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
4209 	CU_ASSERT(g_bserrno == 0);
4210 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
4211 
4212 	/* Dirty shutdown */
4213 	_spdk_bs_free(g_bs);
4214 
4215 	dev = init_dev();
4216 	spdk_bs_opts_init(&opts);
4217 	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
4218 	opts.iter_cb_fn = test_iter;
4219 	iter_ctx.current_iter = 0;
4220 	opts.iter_cb_arg = &iter_ctx;
4221 
4222 	/* Test blob iteration during load after a dirty shutdown. */
4223 	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
4224 	CU_ASSERT(g_bserrno == 0);
4225 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
4226 
4227 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
4228 	CU_ASSERT(g_bserrno == 0);
4229 	g_bs = NULL;
4230 }
4231 
4232 static void
4233 blob_snapshot_rw(void)
4234 {
4235 	static const uint8_t zero[10 * 4096] = { 0 };
4236 	struct spdk_blob_store *bs;
4237 	struct spdk_bs_dev *dev;
4238 	struct spdk_blob *blob, *snapshot;
4239 	struct spdk_io_channel *channel;
4240 	struct spdk_blob_opts opts;
4241 	spdk_blob_id blobid, snapshotid;
4242 	uint64_t free_clusters;
4243 	uint64_t cluster_size;
4244 	uint64_t page_size;
4245 	uint8_t payload_read[10 * 4096];
4246 	uint8_t payload_write[10 * 4096];
4247 	uint64_t write_bytes;
4248 	uint64_t read_bytes;
4249 
4250 	dev = init_dev();
4251 
4252 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
4253 	CU_ASSERT(g_bserrno == 0);
4254 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
4255 	bs = g_bs;
4256 	free_clusters = spdk_bs_free_cluster_count(bs);
4257 	cluster_size = spdk_bs_get_cluster_size(bs);
4258 	page_size = spdk_bs_get_page_size(bs);
4259 
4260 	channel = spdk_bs_alloc_io_channel(bs);
4261 	CU_ASSERT(channel != NULL);
4262 
4263 	spdk_blob_opts_init(&opts);
4264 	opts.thin_provision = true;
4265 	opts.num_clusters = 5;
4266 
4267 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
4268 	CU_ASSERT(g_bserrno == 0);
4269 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
4270 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
4271 	blobid = g_blobid;
4272 
4273 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
4274 	CU_ASSERT(g_bserrno == 0);
4275 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4276 	blob = g_blob;
4277 
4278 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5);
4279 
4280 	memset(payload_read, 0xFF, sizeof(payload_read));
4281 	spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL);
4282 	CU_ASSERT(g_bserrno == 0);
4283 	CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0);
4284 
4285 	memset(payload_write, 0xE5, sizeof(payload_write));
4286 	spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL);
4287 	CU_ASSERT(g_bserrno == 0);
4288 	CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs));
4289 
4290 	/* Create snapshot from blob */
4291 	spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL);
4292 	CU_ASSERT(g_bserrno == 0);
4293 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
4294 	snapshotid = g_blobid;
4295 
4296 	spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL);
4297 	CU_ASSERT(g_bserrno == 0);
4298 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4299 	snapshot = g_blob;
4300 	CU_ASSERT(snapshot->data_ro == true)
4301 	CU_ASSERT(snapshot->md_ro == true)
4302 
4303 	CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 5)
4304 
4305 	write_bytes = g_dev_write_bytes;
4306 	read_bytes = g_dev_read_bytes;
4307 
4308 	memset(payload_write, 0xAA, sizeof(payload_write));
4309 	spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL);
4310 	CU_ASSERT(g_bserrno == 0);
4311 	CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs));
4312 
4313 	/* For a clone we need to allocate and copy one cluster, update one page of metadata
4314 	 * and then write 10 pages of payload.
4315 	 */
4316 	CU_ASSERT(g_dev_write_bytes - write_bytes == page_size * 11 + cluster_size);
4317 	CU_ASSERT(g_dev_read_bytes - read_bytes == cluster_size);
4318 
4319 	spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL);
4320 	CU_ASSERT(g_bserrno == 0);
4321 	CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0);
4322 
4323 	/* Data on snapshot should not change after write to clone */
4324 	memset(payload_write, 0xE5, sizeof(payload_write));
4325 	spdk_blob_io_read(snapshot, channel, payload_read, 4, 10, blob_op_complete, NULL);
4326 	CU_ASSERT(g_bserrno == 0);
4327 	CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0);
4328 
4329 	spdk_blob_close(blob, blob_op_complete, NULL);
4330 	CU_ASSERT(g_bserrno == 0);
4331 
4332 	spdk_blob_close(snapshot, blob_op_complete, NULL);
4333 	CU_ASSERT(g_bserrno == 0);
4334 
4335 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
4336 	CU_ASSERT(g_bserrno == 0);
4337 
4338 	spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL);
4339 	CU_ASSERT(g_bserrno == 0);
4340 
4341 	spdk_bs_free_io_channel(channel);
4342 
4343 	/* Unload the blob store */
4344 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
4345 	CU_ASSERT(g_bserrno == 0);
4346 	g_bs = NULL;
4347 	g_blob = NULL;
4348 	g_blobid = 0;
4349 }
4350 
4351 static void
4352 blob_snapshot_rw_iov(void)
4353 {
4354 	static const uint8_t zero[10 * 4096] = { 0 };
4355 	struct spdk_blob_store *bs;
4356 	struct spdk_bs_dev *dev;
4357 	struct spdk_blob *blob, *snapshot;
4358 	struct spdk_io_channel *channel;
4359 	struct spdk_blob_opts opts;
4360 	spdk_blob_id blobid, snapshotid;
4361 	uint64_t free_clusters;
4362 	uint8_t payload_read[10 * 4096];
4363 	uint8_t payload_write[10 * 4096];
4364 	struct iovec iov_read[3];
4365 	struct iovec iov_write[3];
4366 
4367 	dev = init_dev();
4368 
4369 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
4370 	CU_ASSERT(g_bserrno == 0);
4371 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
4372 	bs = g_bs;
4373 	free_clusters = spdk_bs_free_cluster_count(bs);
4374 
4375 	channel = spdk_bs_alloc_io_channel(bs);
4376 	CU_ASSERT(channel != NULL);
4377 
4378 	spdk_blob_opts_init(&opts);
4379 	opts.thin_provision = true;
4380 	opts.num_clusters = 5;
4381 
4382 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
4383 	CU_ASSERT(g_bserrno == 0);
4384 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
4385 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
4386 	blobid = g_blobid;
4387 
4388 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
4389 	CU_ASSERT(g_bserrno == 0);
4390 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4391 	blob = g_blob;
4392 
4393 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5);
4394 
4395 	/* Create snapshot from blob */
4396 	spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL);
4397 	CU_ASSERT(g_bserrno == 0);
4398 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
4399 	snapshotid = g_blobid;
4400 
4401 	spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL);
4402 	CU_ASSERT(g_bserrno == 0);
4403 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4404 	snapshot = g_blob;
4405 	CU_ASSERT(snapshot->data_ro == true)
4406 	CU_ASSERT(snapshot->md_ro == true)
4407 	CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 5);
4408 
4409 	/* Payload should be all zeros from unallocated clusters */
4410 	memset(payload_read, 0xAA, sizeof(payload_read));
4411 	iov_read[0].iov_base = payload_read;
4412 	iov_read[0].iov_len = 3 * 4096;
4413 	iov_read[1].iov_base = payload_read + 3 * 4096;
4414 	iov_read[1].iov_len = 4 * 4096;
4415 	iov_read[2].iov_base = payload_read + 7 * 4096;
4416 	iov_read[2].iov_len = 3 * 4096;
4417 	spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL);
4418 	CU_ASSERT(g_bserrno == 0);
4419 	CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0);
4420 
4421 	memset(payload_write, 0xE5, sizeof(payload_write));
4422 	iov_write[0].iov_base = payload_write;
4423 	iov_write[0].iov_len = 1 * 4096;
4424 	iov_write[1].iov_base = payload_write + 1 * 4096;
4425 	iov_write[1].iov_len = 5 * 4096;
4426 	iov_write[2].iov_base = payload_write + 6 * 4096;
4427 	iov_write[2].iov_len = 4 * 4096;
4428 
4429 	spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL);
4430 	CU_ASSERT(g_bserrno == 0);
4431 
4432 	memset(payload_read, 0xAA, sizeof(payload_read));
4433 	iov_read[0].iov_base = payload_read;
4434 	iov_read[0].iov_len = 3 * 4096;
4435 	iov_read[1].iov_base = payload_read + 3 * 4096;
4436 	iov_read[1].iov_len = 4 * 4096;
4437 	iov_read[2].iov_base = payload_read + 7 * 4096;
4438 	iov_read[2].iov_len = 3 * 4096;
4439 	spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL);
4440 	CU_ASSERT(g_bserrno == 0);
4441 	CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0);
4442 
4443 	spdk_blob_close(blob, blob_op_complete, NULL);
4444 	CU_ASSERT(g_bserrno == 0);
4445 
4446 	spdk_blob_close(snapshot, blob_op_complete, NULL);
4447 	CU_ASSERT(g_bserrno == 0);
4448 
4449 	spdk_bs_free_io_channel(channel);
4450 
4451 	/* Unload the blob store */
4452 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
4453 	CU_ASSERT(g_bserrno == 0);
4454 	g_bs = NULL;
4455 	g_blob = NULL;
4456 	g_blobid = 0;
4457 }
4458 
4459 /**
4460  * Inflate / decouple parent rw unit tests.
4461  *
4462  * --------------
4463  * original blob:         0         1         2         3         4
4464  *                   ,---------+---------+---------+---------+---------.
4465  *         snapshot  |xxxxxxxxx|xxxxxxxxx|xxxxxxxxx|xxxxxxxxx|    -    |
4466  *                   +---------+---------+---------+---------+---------+
4467  *         snapshot2 |    -    |yyyyyyyyy|    -    |yyyyyyyyy|    -    |
4468  *                   +---------+---------+---------+---------+---------+
4469  *         blob      |    -    |zzzzzzzzz|    -    |    -    |    -    |
4470  *                   '---------+---------+---------+---------+---------'
4471  *                   .         .         .         .         .         .
4472  * --------          .         .         .         .         .         .
4473  * inflate:          .         .         .         .         .         .
4474  *                   ,---------+---------+---------+---------+---------.
4475  *         blob      |xxxxxxxxx|zzzzzzzzz|xxxxxxxxx|yyyyyyyyy|000000000|
4476  *                   '---------+---------+---------+---------+---------'
4477  *
4478  *         NOTE: needs to allocate 4 clusters, thin provisioning removed, dependency
4479  *               on snapshot2 and snapshot removed .         .         .
4480  *                   .         .         .         .         .         .
4481  * ----------------  .         .         .         .         .         .
4482  * decouple parent:  .         .         .         .         .         .
4483  *                   ,---------+---------+---------+---------+---------.
4484  *         snapshot  |xxxxxxxxx|xxxxxxxxx|xxxxxxxxx|xxxxxxxxx|    -    |
4485  *                   +---------+---------+---------+---------+---------+
4486  *         blob      |    -    |zzzzzzzzz|    -    |yyyyyyyyy|    -    |
4487  *                   '---------+---------+---------+---------+---------'
4488  *
4489  *         NOTE: needs to allocate 1 cluster, 3 clusters unallocated, dependency
4490  *               on snapshot2 removed and on snapshot still exists. Snapshot2
4491  *               should remain a clone of snapshot.
4492  */
4493 static void
4494 _blob_inflate_rw(bool decouple_parent)
4495 {
4496 	struct spdk_blob_store *bs;
4497 	struct spdk_bs_dev *dev;
4498 	struct spdk_blob *blob, *snapshot, *snapshot2;
4499 	struct spdk_io_channel *channel;
4500 	struct spdk_blob_opts opts;
4501 	spdk_blob_id blobid, snapshotid, snapshot2id;
4502 	uint64_t free_clusters;
4503 	uint64_t cluster_size;
4504 
4505 	uint64_t payload_size;
4506 	uint8_t *payload_read;
4507 	uint8_t *payload_write;
4508 	uint8_t *payload_clone;
4509 
4510 	uint64_t pages_per_cluster;
4511 	uint64_t pages_per_payload;
4512 
4513 	int i;
4514 	spdk_blob_id ids[2];
4515 	size_t count;
4516 
4517 	dev = init_dev();
4518 
4519 	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
4520 	CU_ASSERT(g_bserrno == 0);
4521 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
4522 	bs = g_bs;
4523 
4524 	free_clusters = spdk_bs_free_cluster_count(bs);
4525 	cluster_size = spdk_bs_get_cluster_size(bs);
4526 	pages_per_cluster = cluster_size / spdk_bs_get_page_size(bs);
4527 	pages_per_payload = pages_per_cluster * 5;
4528 
4529 	payload_size = cluster_size * 5;
4530 
4531 	payload_read = malloc(payload_size);
4532 	SPDK_CU_ASSERT_FATAL(payload_read != NULL);
4533 
4534 	payload_write = malloc(payload_size);
4535 	SPDK_CU_ASSERT_FATAL(payload_write != NULL);
4536 
4537 	payload_clone = malloc(payload_size);
4538 	SPDK_CU_ASSERT_FATAL(payload_clone != NULL);
4539 
4540 	channel = spdk_bs_alloc_io_channel(bs);
4541 	SPDK_CU_ASSERT_FATAL(channel != NULL);
4542 
4543 	/* Create blob */
4544 	spdk_blob_opts_init(&opts);
4545 	opts.thin_provision = true;
4546 	opts.num_clusters = 5;
4547 
4548 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
4549 	CU_ASSERT(g_bserrno == 0);
4550 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
4551 	CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
4552 	blobid = g_blobid;
4553 
4554 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
4555 	CU_ASSERT(g_bserrno == 0);
4556 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4557 	blob = g_blob;
4558 
4559 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5);
4560 
4561 	/* 1) Initial read should return zeroed payload */
4562 	memset(payload_read, 0xFF, payload_size);
4563 	spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload,
4564 			  blob_op_complete, NULL);
4565 	CU_ASSERT(g_bserrno == 0);
4566 	CU_ASSERT(spdk_mem_all_zero(payload_read, payload_size));
4567 
4568 	/* Fill whole blob with a pattern, except last cluster (to be sure it
4569 	 * isn't allocated) */
4570 	memset(payload_write, 0xE5, payload_size - cluster_size);
4571 	spdk_blob_io_write(blob, channel, payload_write, 0, pages_per_payload -
4572 			   pages_per_cluster, blob_op_complete, NULL);
4573 	CU_ASSERT(g_bserrno == 0);
4574 	CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs));
4575 
4576 	/* 2) Create snapshot from blob (first level) */
4577 	spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL);
4578 	CU_ASSERT(g_bserrno == 0);
4579 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
4580 	snapshotid = g_blobid;
4581 
4582 	spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL);
4583 	CU_ASSERT(g_bserrno == 0);
4584 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4585 	snapshot = g_blob;
4586 	CU_ASSERT(snapshot->data_ro == true)
4587 	CU_ASSERT(snapshot->md_ro == true)
4588 
4589 	CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 5)
4590 
4591 	/* Write every second cluster with a pattern.
4592 	 *
4593 	 * Last cluster shouldn't be written, to be sure that snapshot nor clone
4594 	 * doesn't allocate it.
4595 	 *
4596 	 * payload_clone stores expected result on "blob" read at the time and
4597 	 * is used only to check data consistency on clone before and after
4598 	 * inflation. Initially we fill it with a backing snapshots pattern
4599 	 * used before.
4600 	 */
4601 	memset(payload_clone, 0xE5, payload_size - cluster_size);
4602 	memset(payload_clone + payload_size - cluster_size, 0x00, cluster_size);
4603 	memset(payload_write, 0xAA, payload_size);
4604 	for (i = 1; i < 5; i += 2) {
4605 		spdk_blob_io_write(blob, channel, payload_write, i * pages_per_cluster,
4606 				   pages_per_cluster, blob_op_complete, NULL);
4607 		CU_ASSERT(g_bserrno == 0);
4608 
4609 		/* Update expected result */
4610 		memcpy(payload_clone + (cluster_size * i), payload_write,
4611 		       cluster_size);
4612 	}
4613 	CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs));
4614 
4615 	/* Check data consistency on clone */
4616 	memset(payload_read, 0xFF, payload_size);
4617 	spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload,
4618 			  blob_op_complete, NULL);
4619 	CU_ASSERT(g_bserrno == 0);
4620 	CU_ASSERT(memcmp(payload_clone, payload_read, payload_size) == 0);
4621 
4622 	/* 3) Create second levels snapshot from blob */
4623 	spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL);
4624 	CU_ASSERT(g_bserrno == 0);
4625 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
4626 	snapshot2id = g_blobid;
4627 
4628 	spdk_bs_open_blob(bs, snapshot2id, blob_op_with_handle_complete, NULL);
4629 	CU_ASSERT(g_bserrno == 0);
4630 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4631 	snapshot2 = g_blob;
4632 	CU_ASSERT(snapshot2->data_ro == true)
4633 	CU_ASSERT(snapshot2->md_ro == true)
4634 
4635 	CU_ASSERT(spdk_blob_get_num_clusters(snapshot2) == 5)
4636 
4637 	CU_ASSERT(snapshot2->parent_id == snapshotid);
4638 
4639 	/* Write one cluster on the top level blob. This cluster (1) covers
4640 	 * already allocated cluster in the snapshot2, so shouldn't be inflated
4641 	 * at all */
4642 	spdk_blob_io_write(blob, channel, payload_write, pages_per_cluster,
4643 			   pages_per_cluster, blob_op_complete, NULL);
4644 	CU_ASSERT(g_bserrno == 0);
4645 
4646 	/* Update expected result */
4647 	memcpy(payload_clone + cluster_size, payload_write, cluster_size);
4648 
4649 	/* Check data consistency on clone */
4650 	memset(payload_read, 0xFF, payload_size);
4651 	spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload,
4652 			  blob_op_complete, NULL);
4653 	CU_ASSERT(g_bserrno == 0);
4654 	CU_ASSERT(memcmp(payload_clone, payload_read, payload_size) == 0);
4655 
4656 
4657 	/* Close all blobs */
4658 	spdk_blob_close(blob, blob_op_complete, NULL);
4659 	CU_ASSERT(g_bserrno == 0);
4660 
4661 	spdk_blob_close(snapshot2, blob_op_complete, NULL);
4662 	CU_ASSERT(g_bserrno == 0);
4663 
4664 	spdk_blob_close(snapshot, blob_op_complete, NULL);
4665 	CU_ASSERT(g_bserrno == 0);
4666 
4667 	/* Check snapshot-clone relations */
4668 	count = 2;
4669 	CU_ASSERT(spdk_blob_get_clones(bs, snapshotid, ids, &count) == 0);
4670 	CU_ASSERT(count == 1);
4671 	CU_ASSERT(ids[0] == snapshot2id);
4672 
4673 	count = 2;
4674 	CU_ASSERT(spdk_blob_get_clones(bs, snapshot2id, ids, &count) == 0);
4675 	CU_ASSERT(count == 1);
4676 	CU_ASSERT(ids[0] == blobid);
4677 
4678 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshot2id);
4679 
4680 	free_clusters = spdk_bs_free_cluster_count(bs);
4681 	if (!decouple_parent) {
4682 		/* Do full blob inflation */
4683 		spdk_bs_inflate_blob(bs, channel, blobid, blob_op_complete, NULL);
4684 		CU_ASSERT(g_bserrno == 0);
4685 
4686 		/* All clusters should be inflated (except one already allocated
4687 		 * in a top level blob) */
4688 		CU_ASSERT(spdk_bs_free_cluster_count(bs) == free_clusters - 4);
4689 
4690 		/* Check if relation tree updated correctly */
4691 		count = 2;
4692 		CU_ASSERT(spdk_blob_get_clones(bs, snapshotid, ids, &count) == 0);
4693 
4694 		/* snapshotid have one clone */
4695 		CU_ASSERT(count == 1);
4696 		CU_ASSERT(ids[0] == snapshot2id);
4697 
4698 		/* snapshot2id have no clones */
4699 		count = 2;
4700 		CU_ASSERT(spdk_blob_get_clones(bs, snapshot2id, ids, &count) == 0);
4701 		CU_ASSERT(count == 0);
4702 
4703 		CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == SPDK_BLOBID_INVALID);
4704 	} else {
4705 		/* Decouple parent of blob */
4706 		spdk_bs_blob_decouple_parent(bs, channel, blobid, blob_op_complete, NULL);
4707 		CU_ASSERT(g_bserrno == 0);
4708 
4709 		/* Only one cluster from a parent should be inflated (second one
4710 		 * is covered by a cluster written on a top level blob, and
4711 		 * already allocated) */
4712 		CU_ASSERT(spdk_bs_free_cluster_count(bs) == free_clusters - 1);
4713 
4714 		/* Check if relation tree updated correctly */
4715 		count = 2;
4716 		CU_ASSERT(spdk_blob_get_clones(bs, snapshotid, ids, &count) == 0);
4717 
4718 		/* snapshotid have two clones now */
4719 		CU_ASSERT(count == 2);
4720 		CU_ASSERT(ids[0] == blobid || ids[1] == blobid);
4721 		CU_ASSERT(ids[0] == snapshot2id || ids[1] == snapshot2id);
4722 
4723 		/* snapshot2id have no clones */
4724 		count = 2;
4725 		CU_ASSERT(spdk_blob_get_clones(bs, snapshot2id, ids, &count) == 0);
4726 		CU_ASSERT(count == 0);
4727 
4728 		CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid);
4729 	}
4730 
4731 	/* Try to delete snapshot2 (should pass) */
4732 	spdk_bs_delete_blob(bs, snapshot2id, blob_op_complete, NULL);
4733 	CU_ASSERT(g_bserrno == 0);
4734 
4735 	/* Try to delete base snapshot (for decouple_parent should fail while
4736 	 * dependency still exists) */
4737 	spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL);
4738 	CU_ASSERT(decouple_parent || g_bserrno == 0);
4739 	CU_ASSERT(!decouple_parent || g_bserrno != 0);
4740 
4741 	/* Reopen blob after snapshot deletion */
4742 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
4743 	CU_ASSERT(g_bserrno == 0);
4744 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4745 	blob = g_blob;
4746 
4747 	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5);
4748 
4749 	/* Check data consistency on inflated blob */
4750 	memset(payload_read, 0xFF, payload_size);
4751 	spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload,
4752 			  blob_op_complete, NULL);
4753 	CU_ASSERT(g_bserrno == 0);
4754 	CU_ASSERT(memcmp(payload_clone, payload_read, payload_size) == 0);
4755 
4756 	spdk_blob_close(blob, blob_op_complete, NULL);
4757 	CU_ASSERT(g_bserrno == 0);
4758 
4759 	spdk_bs_free_io_channel(channel);
4760 
4761 	/* Unload the blob store */
4762 	spdk_bs_unload(g_bs, bs_op_complete, NULL);
4763 	CU_ASSERT(g_bserrno == 0);
4764 	g_bs = NULL;
4765 	g_blob = NULL;
4766 	g_blobid = 0;
4767 
4768 	free(payload_read);
4769 	free(payload_write);
4770 	free(payload_clone);
4771 }
4772 
4773 static void
4774 blob_inflate_rw(void)
4775 {
4776 	_blob_inflate_rw(false);
4777 	_blob_inflate_rw(true);
4778 }
4779 
4780 /**
4781  * Snapshot-clones relation test
4782  *
4783  *         snapshot
4784  *            |
4785  *      +-----+-----+
4786  *      |           |
4787  *   blob(ro)   snapshot2
4788  *      |           |
4789  *   clone2      clone
4790  */
4791 static void
4792 blob_relations(void)
4793 {
4794 	struct spdk_blob_store *bs;
4795 	struct spdk_bs_dev *dev;
4796 	struct spdk_bs_opts bs_opts;
4797 	struct spdk_blob_opts opts;
4798 	struct spdk_blob *blob, *snapshot, *snapshot2, *clone, *clone2;
4799 	spdk_blob_id blobid, cloneid, snapshotid, cloneid2, snapshotid2;
4800 	int rc;
4801 	size_t count;
4802 	spdk_blob_id ids[10] = {};
4803 
4804 	dev = init_dev();
4805 	spdk_bs_opts_init(&bs_opts);
4806 	snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE");
4807 
4808 	spdk_bs_init(dev, &bs_opts, bs_op_with_handle_complete, NULL);
4809 	CU_ASSERT(g_bserrno == 0);
4810 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
4811 	bs = g_bs;
4812 
4813 	/* 1. Create blob with 10 clusters */
4814 
4815 	spdk_blob_opts_init(&opts);
4816 	opts.num_clusters = 10;
4817 
4818 	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
4819 	CU_ASSERT(g_bserrno == 0);
4820 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
4821 	blobid = g_blobid;
4822 
4823 	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
4824 	CU_ASSERT(g_bserrno == 0);
4825 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4826 	blob = g_blob;
4827 
4828 	CU_ASSERT(!spdk_blob_is_read_only(blob));
4829 	CU_ASSERT(!spdk_blob_is_snapshot(blob));
4830 	CU_ASSERT(!spdk_blob_is_clone(blob));
4831 	CU_ASSERT(!spdk_blob_is_thin_provisioned(blob));
4832 
4833 	/* blob should not have underlying snapshot nor clones */
4834 	CU_ASSERT(blob->parent_id == SPDK_BLOBID_INVALID);
4835 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == SPDK_BLOBID_INVALID);
4836 	count = SPDK_COUNTOF(ids);
4837 	rc = spdk_blob_get_clones(bs, blobid, ids, &count);
4838 	CU_ASSERT(rc == 0);
4839 	CU_ASSERT(count == 0);
4840 
4841 
4842 	/* 2. Create snapshot */
4843 
4844 	spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL);
4845 	CU_ASSERT(g_bserrno == 0);
4846 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
4847 	snapshotid = g_blobid;
4848 
4849 	spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL);
4850 	CU_ASSERT(g_bserrno == 0);
4851 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4852 	snapshot = g_blob;
4853 
4854 	CU_ASSERT(spdk_blob_is_read_only(snapshot));
4855 	CU_ASSERT(spdk_blob_is_snapshot(snapshot));
4856 	CU_ASSERT(!spdk_blob_is_clone(snapshot));
4857 	CU_ASSERT(snapshot->parent_id == SPDK_BLOBID_INVALID);
4858 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid) == SPDK_BLOBID_INVALID);
4859 
4860 	/* Check if original blob is converted to the clone of snapshot */
4861 	CU_ASSERT(!spdk_blob_is_read_only(blob));
4862 	CU_ASSERT(!spdk_blob_is_snapshot(blob));
4863 	CU_ASSERT(spdk_blob_is_clone(blob));
4864 	CU_ASSERT(spdk_blob_is_thin_provisioned(blob));
4865 	CU_ASSERT(blob->parent_id == snapshotid);
4866 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid);
4867 
4868 	count = SPDK_COUNTOF(ids);
4869 	rc = spdk_blob_get_clones(bs, snapshotid, ids, &count);
4870 	CU_ASSERT(rc == 0);
4871 	CU_ASSERT(count == 1);
4872 	CU_ASSERT(ids[0] == blobid);
4873 
4874 
4875 	/* 3. Create clone from snapshot */
4876 
4877 	spdk_bs_create_clone(bs, snapshotid, NULL, blob_op_with_id_complete, NULL);
4878 	CU_ASSERT(g_bserrno == 0);
4879 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
4880 	cloneid = g_blobid;
4881 
4882 	spdk_bs_open_blob(bs, cloneid, blob_op_with_handle_complete, NULL);
4883 	CU_ASSERT(g_bserrno == 0);
4884 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4885 	clone = g_blob;
4886 
4887 	CU_ASSERT(!spdk_blob_is_read_only(clone));
4888 	CU_ASSERT(!spdk_blob_is_snapshot(clone));
4889 	CU_ASSERT(spdk_blob_is_clone(clone));
4890 	CU_ASSERT(spdk_blob_is_thin_provisioned(clone));
4891 	CU_ASSERT(clone->parent_id == snapshotid);
4892 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid);
4893 
4894 	count = SPDK_COUNTOF(ids);
4895 	rc = spdk_blob_get_clones(bs, cloneid, ids, &count);
4896 	CU_ASSERT(rc == 0);
4897 	CU_ASSERT(count == 0);
4898 
4899 	/* Check if clone is on the snapshot's list */
4900 	count = SPDK_COUNTOF(ids);
4901 	rc = spdk_blob_get_clones(bs, snapshotid, ids, &count);
4902 	CU_ASSERT(rc == 0);
4903 	CU_ASSERT(ids[0] == blobid || ids[1] == blobid);
4904 	CU_ASSERT(ids[0] == cloneid || ids[1] == cloneid);
4905 
4906 
4907 	/* 4. Create snapshot of the clone */
4908 
4909 	spdk_bs_create_snapshot(bs, cloneid, NULL, blob_op_with_id_complete, NULL);
4910 	CU_ASSERT(g_bserrno == 0);
4911 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
4912 	snapshotid2 = g_blobid;
4913 
4914 	spdk_bs_open_blob(bs, snapshotid2, blob_op_with_handle_complete, NULL);
4915 	CU_ASSERT(g_bserrno == 0);
4916 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4917 	snapshot2 = g_blob;
4918 
4919 	CU_ASSERT(spdk_blob_is_read_only(snapshot2));
4920 	CU_ASSERT(spdk_blob_is_snapshot(snapshot2));
4921 	CU_ASSERT(spdk_blob_is_clone(snapshot2));
4922 	CU_ASSERT(snapshot2->parent_id == snapshotid);
4923 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid2) == snapshotid);
4924 
4925 	/* Check if clone is converted to the clone of snapshot2 and snapshot2
4926 	 * is a child of snapshot */
4927 	CU_ASSERT(!spdk_blob_is_read_only(clone));
4928 	CU_ASSERT(!spdk_blob_is_snapshot(clone));
4929 	CU_ASSERT(spdk_blob_is_clone(clone));
4930 	CU_ASSERT(spdk_blob_is_thin_provisioned(clone));
4931 	CU_ASSERT(clone->parent_id == snapshotid2);
4932 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid2);
4933 
4934 	count = SPDK_COUNTOF(ids);
4935 	rc = spdk_blob_get_clones(bs, snapshotid2, ids, &count);
4936 	CU_ASSERT(rc == 0);
4937 	CU_ASSERT(count == 1);
4938 	CU_ASSERT(ids[0] == cloneid);
4939 
4940 
4941 	/* 5. Try to create clone from read only blob */
4942 
4943 	/* Mark blob as read only */
4944 	spdk_blob_set_read_only(blob);
4945 	spdk_blob_sync_md(blob, blob_op_complete, NULL);
4946 	CU_ASSERT(g_bserrno == 0);
4947 
4948 	/* Check if previously created blob is read only clone */
4949 	CU_ASSERT(spdk_blob_is_read_only(blob));
4950 	CU_ASSERT(!spdk_blob_is_snapshot(blob));
4951 	CU_ASSERT(spdk_blob_is_clone(blob));
4952 	CU_ASSERT(spdk_blob_is_thin_provisioned(blob));
4953 
4954 	/* Create clone from read only blob */
4955 	spdk_bs_create_clone(bs, blobid, NULL, blob_op_with_id_complete, NULL);
4956 	CU_ASSERT(g_bserrno == 0);
4957 	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
4958 	cloneid2 = g_blobid;
4959 
4960 	spdk_bs_open_blob(bs, cloneid2, blob_op_with_handle_complete, NULL);
4961 	CU_ASSERT(g_bserrno == 0);
4962 	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
4963 	clone2 = g_blob;
4964 
4965 	CU_ASSERT(!spdk_blob_is_read_only(clone2));
4966 	CU_ASSERT(!spdk_blob_is_snapshot(clone2));
4967 	CU_ASSERT(spdk_blob_is_clone(clone2));
4968 	CU_ASSERT(spdk_blob_is_thin_provisioned(clone2));
4969 
4970 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid2) == blobid);
4971 
4972 	count = SPDK_COUNTOF(ids);
4973 	rc = spdk_blob_get_clones(bs, blobid, ids, &count);
4974 	CU_ASSERT(rc == 0);
4975 
4976 	CU_ASSERT(count == 1);
4977 	CU_ASSERT(ids[0] == cloneid2);
4978 
4979 	/* Close blobs */
4980 
4981 	spdk_blob_close(clone2, blob_op_complete, NULL);
4982 	CU_ASSERT(g_bserrno == 0);
4983 
4984 	spdk_blob_close(blob, blob_op_complete, NULL);
4985 	CU_ASSERT(g_bserrno == 0);
4986 
4987 	spdk_blob_close(clone, blob_op_complete, NULL);
4988 	CU_ASSERT(g_bserrno == 0);
4989 
4990 	spdk_blob_close(snapshot, blob_op_complete, NULL);
4991 	CU_ASSERT(g_bserrno == 0);
4992 
4993 	spdk_blob_close(snapshot2, blob_op_complete, NULL);
4994 	CU_ASSERT(g_bserrno == 0);
4995 
4996 	/* Try to delete snapshot with created clones */
4997 	spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL);
4998 	CU_ASSERT(g_bserrno != 0);
4999 
5000 	spdk_bs_delete_blob(bs, snapshotid2, blob_op_complete, NULL);
5001 	CU_ASSERT(g_bserrno != 0);
5002 
5003 	spdk_bs_unload(bs, bs_op_complete, NULL);
5004 	CU_ASSERT(g_bserrno == 0);
5005 	g_bs = NULL;
5006 
5007 	/* Load an existing blob store */
5008 	dev = init_dev();
5009 	snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE");
5010 
5011 	spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL);
5012 	CU_ASSERT(g_bserrno == 0);
5013 	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
5014 	bs = g_bs;
5015 
5016 
5017 	/* NULL ids array should return number of clones in count */
5018 	count = SPDK_COUNTOF(ids);
5019 	rc = spdk_blob_get_clones(bs, snapshotid, NULL, &count);
5020 	CU_ASSERT(rc == -ENOMEM);
5021 	CU_ASSERT(count == 2);
5022 
5023 	/* incorrect array size */
5024 	count = 1;
5025 	rc = spdk_blob_get_clones(bs, snapshotid, ids, &count);
5026 	CU_ASSERT(rc == -ENOMEM);
5027 	CU_ASSERT(count == 2);
5028 
5029 
5030 	/* Verify structure of loaded blob store */
5031 
5032 	/* snapshot */
5033 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid) == SPDK_BLOBID_INVALID);
5034 
5035 	count = SPDK_COUNTOF(ids);
5036 	rc = spdk_blob_get_clones(bs, snapshotid, ids, &count);
5037 	CU_ASSERT(rc == 0);
5038 	CU_ASSERT(count == 2);
5039 	CU_ASSERT(ids[0] == blobid || ids[1] == blobid);
5040 	CU_ASSERT(ids[0] == snapshotid2 || ids[1] == snapshotid2);
5041 
5042 	/* blob */
5043 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid);
5044 	count = SPDK_COUNTOF(ids);
5045 	rc = spdk_blob_get_clones(bs, blobid, ids, &count);
5046 	CU_ASSERT(rc == 0);
5047 	CU_ASSERT(count == 1);
5048 	CU_ASSERT(ids[0] == cloneid2);
5049 
5050 	/* clone */
5051 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid2);
5052 	count = SPDK_COUNTOF(ids);
5053 	rc = spdk_blob_get_clones(bs, cloneid, ids, &count);
5054 	CU_ASSERT(rc == 0);
5055 	CU_ASSERT(count == 0);
5056 
5057 	/* snapshot2 */
5058 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid2) == snapshotid);
5059 	count = SPDK_COUNTOF(ids);
5060 	rc = spdk_blob_get_clones(bs, snapshotid2, ids, &count);
5061 	CU_ASSERT(rc == 0);
5062 	CU_ASSERT(count == 1);
5063 	CU_ASSERT(ids[0] == cloneid);
5064 
5065 	/* clone2 */
5066 	CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid2) == blobid);
5067 	count = SPDK_COUNTOF(ids);
5068 	rc = spdk_blob_get_clones(bs, cloneid2, ids, &count);
5069 	CU_ASSERT(rc == 0);
5070 	CU_ASSERT(count == 0);
5071 
5072 	/* Try to delete all blobs in the worse possible order */
5073 
5074 	spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL);
5075 	CU_ASSERT(g_bserrno != 0);
5076 
5077 	spdk_bs_delete_blob(bs, snapshotid2, blob_op_complete, NULL);
5078 	CU_ASSERT(g_bserrno != 0);
5079 
5080 	spdk_bs_delete_blob(bs, cloneid, blob_op_complete, NULL);
5081 	CU_ASSERT(g_bserrno == 0);
5082 
5083 	spdk_bs_delete_blob(bs, snapshotid2, blob_op_complete, NULL);
5084 	CU_ASSERT(g_bserrno == 0);
5085 
5086 	spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL);
5087 	CU_ASSERT(g_bserrno != 0);
5088 
5089 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
5090 	CU_ASSERT(g_bserrno != 0);
5091 
5092 	spdk_bs_delete_blob(bs, cloneid2, blob_op_complete, NULL);
5093 	CU_ASSERT(g_bserrno == 0);
5094 
5095 	spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
5096 	CU_ASSERT(g_bserrno == 0);
5097 
5098 	spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL);
5099 	CU_ASSERT(g_bserrno == 0);
5100 
5101 	spdk_bs_unload(bs, bs_op_complete, NULL);
5102 	CU_ASSERT(g_bserrno == 0);
5103 
5104 	g_bs = NULL;
5105 }
5106 
5107 int main(int argc, char **argv)
5108 {
5109 	CU_pSuite	suite = NULL;
5110 	unsigned int	num_failures;
5111 
5112 	if (CU_initialize_registry() != CUE_SUCCESS) {
5113 		return CU_get_error();
5114 	}
5115 
5116 	suite = CU_add_suite("blob", NULL, NULL);
5117 	if (suite == NULL) {
5118 		CU_cleanup_registry();
5119 		return CU_get_error();
5120 	}
5121 
5122 	if (
5123 		CU_add_test(suite, "blob_init", blob_init) == NULL ||
5124 		CU_add_test(suite, "blob_open", blob_open) == NULL ||
5125 		CU_add_test(suite, "blob_create", blob_create) == NULL ||
5126 		CU_add_test(suite, "blob_create_internal", blob_create_internal) == NULL ||
5127 		CU_add_test(suite, "blob_thin_provision", blob_thin_provision) == NULL ||
5128 		CU_add_test(suite, "blob_snapshot", blob_snapshot) == NULL ||
5129 		CU_add_test(suite, "blob_clone", blob_clone) == NULL ||
5130 		CU_add_test(suite, "blob_inflate", blob_inflate) == NULL ||
5131 		CU_add_test(suite, "blob_delete", blob_delete) == NULL ||
5132 		CU_add_test(suite, "blob_resize", blob_resize) == NULL ||
5133 		CU_add_test(suite, "blob_read_only", blob_read_only) == NULL ||
5134 		CU_add_test(suite, "channel_ops", channel_ops) == NULL ||
5135 		CU_add_test(suite, "blob_super", blob_super) == NULL ||
5136 		CU_add_test(suite, "blob_write", blob_write) == NULL ||
5137 		CU_add_test(suite, "blob_read", blob_read) == NULL ||
5138 		CU_add_test(suite, "blob_rw_verify", blob_rw_verify) == NULL ||
5139 		CU_add_test(suite, "blob_rw_verify_iov", blob_rw_verify_iov) == NULL ||
5140 		CU_add_test(suite, "blob_rw_verify_iov_nomem", blob_rw_verify_iov_nomem) == NULL ||
5141 		CU_add_test(suite, "blob_rw_iov_read_only", blob_rw_iov_read_only) == NULL ||
5142 		CU_add_test(suite, "blob_unmap", blob_unmap) == NULL ||
5143 		CU_add_test(suite, "blob_iter", blob_iter) == NULL ||
5144 		CU_add_test(suite, "blob_xattr", blob_xattr) == NULL ||
5145 		CU_add_test(suite, "bs_load", bs_load) == NULL ||
5146 		CU_add_test(suite, "bs_load_custom_cluster_size", bs_load_custom_cluster_size) == NULL ||
5147 		CU_add_test(suite, "bs_unload", bs_unload) == NULL ||
5148 		CU_add_test(suite, "bs_cluster_sz", bs_cluster_sz) == NULL ||
5149 		CU_add_test(suite, "bs_usable_clusters", bs_usable_clusters) == NULL ||
5150 		CU_add_test(suite, "bs_resize_md", bs_resize_md) == NULL ||
5151 		CU_add_test(suite, "bs_destroy", bs_destroy) == NULL ||
5152 		CU_add_test(suite, "bs_type", bs_type) == NULL ||
5153 		CU_add_test(suite, "bs_super_block", bs_super_block) == NULL ||
5154 		CU_add_test(suite, "blob_serialize", blob_serialize) == NULL ||
5155 		CU_add_test(suite, "blob_crc", blob_crc) == NULL ||
5156 		CU_add_test(suite, "super_block_crc", super_block_crc) == NULL ||
5157 		CU_add_test(suite, "blob_dirty_shutdown", blob_dirty_shutdown) == NULL ||
5158 		CU_add_test(suite, "blob_flags", blob_flags) == NULL ||
5159 		CU_add_test(suite, "bs_version", bs_version) == NULL ||
5160 		CU_add_test(suite, "blob_set_xattrs", blob_set_xattrs) == NULL ||
5161 		CU_add_test(suite, "blob_thin_prov_alloc", blob_thin_prov_alloc) == NULL ||
5162 		CU_add_test(suite, "blob_insert_cluster_msg", blob_insert_cluster_msg) == NULL ||
5163 		CU_add_test(suite, "blob_thin_prov_rw", blob_thin_prov_rw) == NULL ||
5164 		CU_add_test(suite, "blob_thin_prov_rw_iov", blob_thin_prov_rw_iov) == NULL ||
5165 		CU_add_test(suite, "bs_load_iter", bs_load_iter) == NULL ||
5166 		CU_add_test(suite, "blob_snapshot_rw", blob_snapshot_rw) == NULL ||
5167 		CU_add_test(suite, "blob_snapshot_rw_iov", blob_snapshot_rw_iov) == NULL ||
5168 		CU_add_test(suite, "blob_relations", blob_relations) == NULL ||
5169 		CU_add_test(suite, "blob_inflate_rw", blob_inflate_rw) == NULL ||
5170 		CU_add_test(suite, "blob_snapshot_freeze_io", blob_snapshot_freeze_io) == NULL ||
5171 		CU_add_test(suite, "blob_operation_split_rw", blob_operation_split_rw) == NULL ||
5172 		CU_add_test(suite, "blob_operation_split_rw_iov", blob_operation_split_rw_iov) == NULL
5173 	) {
5174 		CU_cleanup_registry();
5175 		return CU_get_error();
5176 	}
5177 
5178 	g_dev_buffer = calloc(1, DEV_BUFFER_SIZE);
5179 	spdk_allocate_thread(_bs_send_msg, NULL, NULL, NULL, "thread0");
5180 	CU_basic_set_mode(CU_BRM_VERBOSE);
5181 	CU_basic_run_tests();
5182 	num_failures = CU_get_number_of_failures();
5183 	CU_cleanup_registry();
5184 	spdk_free_thread();
5185 	free(g_dev_buffer);
5186 	return num_failures;
5187 }
5188