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