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