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