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