4 * Copyright (c) Intel Corporation.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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
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.
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.
34 #include "spdk_internal/lvolstore.h"
35 #include "spdk_internal/log.h"
36 #include "spdk/string.h"
37 #include "spdk/thread.h"
38 #include "spdk/blob_bdev.h"
39 #include "spdk/util.h"
41 /* Default blob channel opts for lvol */
42 #define SPDK_LVOL_BLOB_OPTS_CHANNEL_OPS 512
44 #define LVOL_NAME "name"
46 SPDK_LOG_REGISTER_COMPONENT("lvol", SPDK_LOG_LVOL
)
48 static TAILQ_HEAD(, spdk_lvol_store
) g_lvol_stores
= TAILQ_HEAD_INITIALIZER(g_lvol_stores
);
49 static pthread_mutex_t g_lvol_stores_mutex
= PTHREAD_MUTEX_INITIALIZER
;
52 add_lvs_to_list(struct spdk_lvol_store
*lvs
)
54 struct spdk_lvol_store
*tmp
;
55 bool name_conflict
= false;
57 pthread_mutex_lock(&g_lvol_stores_mutex
);
58 TAILQ_FOREACH(tmp
, &g_lvol_stores
, link
) {
59 if (!strncmp(lvs
->name
, tmp
->name
, SPDK_LVS_NAME_MAX
)) {
66 TAILQ_INSERT_TAIL(&g_lvol_stores
, lvs
, link
);
68 pthread_mutex_unlock(&g_lvol_stores_mutex
);
70 return name_conflict
? -1 : 0;
74 lvs_free(struct spdk_lvol_store
*lvs
)
76 pthread_mutex_lock(&g_lvol_stores_mutex
);
78 TAILQ_REMOVE(&g_lvol_stores
, lvs
, link
);
80 pthread_mutex_unlock(&g_lvol_stores_mutex
);
86 lvol_free(struct spdk_lvol
*lvol
)
92 lvol_open_cb(void *cb_arg
, struct spdk_blob
*blob
, int lvolerrno
)
94 struct spdk_lvol_with_handle_req
*req
= cb_arg
;
95 struct spdk_lvol
*lvol
= req
->lvol
;
98 SPDK_INFOLOG(SPDK_LOG_LVOL
, "Failed to open lvol %s\n", lvol
->unique_id
);
105 req
->cb_fn(req
->cb_arg
, lvol
, lvolerrno
);
110 spdk_lvol_open(struct spdk_lvol
*lvol
, spdk_lvol_op_with_handle_complete cb_fn
, void *cb_arg
)
112 struct spdk_lvol_with_handle_req
*req
;
113 struct spdk_blob_open_opts opts
;
115 assert(cb_fn
!= NULL
);
118 SPDK_ERRLOG("lvol does not exist\n");
119 cb_fn(cb_arg
, NULL
, -ENODEV
);
123 if (lvol
->action_in_progress
== true) {
124 SPDK_ERRLOG("Cannot open lvol - operations on lvol pending\n");
125 cb_fn(cb_arg
, lvol
, -EBUSY
);
129 if (lvol
->ref_count
> 0) {
131 cb_fn(cb_arg
, lvol
, 0);
135 req
= calloc(1, sizeof(*req
));
137 SPDK_ERRLOG("Cannot alloc memory for request structure\n");
138 cb_fn(cb_arg
, NULL
, -ENOMEM
);
143 req
->cb_arg
= cb_arg
;
146 spdk_blob_open_opts_init(&opts
);
147 opts
.clear_method
= lvol
->clear_method
;
149 spdk_bs_open_blob_ext(lvol
->lvol_store
->blobstore
, lvol
->blob_id
, &opts
, lvol_open_cb
, req
);
153 bs_unload_with_error_cb(void *cb_arg
, int lvolerrno
)
155 struct spdk_lvs_with_handle_req
*req
= (struct spdk_lvs_with_handle_req
*)cb_arg
;
157 req
->cb_fn(req
->cb_arg
, NULL
, req
->lvserrno
);
162 load_next_lvol(void *cb_arg
, struct spdk_blob
*blob
, int lvolerrno
)
164 struct spdk_lvs_with_handle_req
*req
= cb_arg
;
165 struct spdk_lvol_store
*lvs
= req
->lvol_store
;
166 struct spdk_blob_store
*bs
= lvs
->blobstore
;
167 struct spdk_lvol
*lvol
, *tmp
;
168 spdk_blob_id blob_id
;
173 if (lvolerrno
== -ENOENT
) {
174 /* Finished iterating */
175 req
->cb_fn(req
->cb_arg
, lvs
, 0);
178 } else if (lvolerrno
< 0) {
179 SPDK_ERRLOG("Failed to fetch blobs list\n");
180 req
->lvserrno
= lvolerrno
;
184 blob_id
= spdk_blob_get_id(blob
);
186 if (blob_id
== lvs
->super_blob_id
) {
187 SPDK_INFOLOG(SPDK_LOG_LVOL
, "found superblob %"PRIu64
"\n", (uint64_t)blob_id
);
188 spdk_bs_iter_next(bs
, blob
, load_next_lvol
, req
);
192 lvol
= calloc(1, sizeof(*lvol
));
194 SPDK_ERRLOG("Cannot alloc memory for lvol base pointer\n");
195 req
->lvserrno
= -ENOMEM
;
200 lvol
->blob_id
= blob_id
;
201 lvol
->lvol_store
= lvs
;
202 lvol
->thin_provision
= spdk_blob_is_thin_provisioned(blob
);
204 rc
= spdk_blob_get_xattr_value(blob
, "uuid", (const void **)&attr
, &value_len
);
205 if (rc
!= 0 || value_len
!= SPDK_UUID_STRING_LEN
|| attr
[SPDK_UUID_STRING_LEN
- 1] != '\0' ||
206 spdk_uuid_parse(&lvol
->uuid
, attr
) != 0) {
207 SPDK_INFOLOG(SPDK_LOG_LVOL
, "Missing or corrupt lvol uuid\n");
208 memset(&lvol
->uuid
, 0, sizeof(lvol
->uuid
));
210 spdk_uuid_fmt_lower(lvol
->uuid_str
, sizeof(lvol
->uuid_str
), &lvol
->uuid
);
212 if (!spdk_mem_all_zero(&lvol
->uuid
, sizeof(lvol
->uuid
))) {
213 snprintf(lvol
->unique_id
, sizeof(lvol
->unique_id
), "%s", lvol
->uuid_str
);
215 spdk_uuid_fmt_lower(lvol
->unique_id
, sizeof(lvol
->unique_id
), &lvol
->lvol_store
->uuid
);
216 value_len
= strlen(lvol
->unique_id
);
217 snprintf(lvol
->unique_id
+ value_len
, sizeof(lvol
->unique_id
) - value_len
, "_%"PRIu64
,
221 rc
= spdk_blob_get_xattr_value(blob
, "name", (const void **)&attr
, &value_len
);
222 if (rc
!= 0 || value_len
> SPDK_LVOL_NAME_MAX
) {
223 SPDK_ERRLOG("Cannot assign lvol name\n");
225 req
->lvserrno
= -EINVAL
;
229 snprintf(lvol
->name
, sizeof(lvol
->name
), "%s", attr
);
231 TAILQ_INSERT_TAIL(&lvs
->lvols
, lvol
, link
);
235 SPDK_INFOLOG(SPDK_LOG_LVOL
, "added lvol %s (%s)\n", lvol
->unique_id
, lvol
->uuid_str
);
237 spdk_bs_iter_next(bs
, blob
, load_next_lvol
, req
);
242 TAILQ_FOREACH_SAFE(lvol
, &lvs
->lvols
, link
, tmp
) {
243 TAILQ_REMOVE(&lvs
->lvols
, lvol
, link
);
248 spdk_bs_unload(bs
, bs_unload_with_error_cb
, req
);
252 close_super_cb(void *cb_arg
, int lvolerrno
)
254 struct spdk_lvs_with_handle_req
*req
= (struct spdk_lvs_with_handle_req
*)cb_arg
;
255 struct spdk_lvol_store
*lvs
= req
->lvol_store
;
256 struct spdk_blob_store
*bs
= lvs
->blobstore
;
258 if (lvolerrno
!= 0) {
259 SPDK_INFOLOG(SPDK_LOG_LVOL
, "Could not close super blob\n");
261 req
->lvserrno
= -ENODEV
;
262 spdk_bs_unload(bs
, bs_unload_with_error_cb
, req
);
266 /* Start loading lvols */
267 spdk_bs_iter_first(lvs
->blobstore
, load_next_lvol
, req
);
271 close_super_blob_with_error_cb(void *cb_arg
, int lvolerrno
)
273 struct spdk_lvs_with_handle_req
*req
= (struct spdk_lvs_with_handle_req
*)cb_arg
;
274 struct spdk_lvol_store
*lvs
= req
->lvol_store
;
275 struct spdk_blob_store
*bs
= lvs
->blobstore
;
279 spdk_bs_unload(bs
, bs_unload_with_error_cb
, req
);
283 lvs_read_uuid(void *cb_arg
, struct spdk_blob
*blob
, int lvolerrno
)
285 struct spdk_lvs_with_handle_req
*req
= (struct spdk_lvs_with_handle_req
*)cb_arg
;
286 struct spdk_lvol_store
*lvs
= req
->lvol_store
;
287 struct spdk_blob_store
*bs
= lvs
->blobstore
;
292 if (lvolerrno
!= 0) {
293 SPDK_INFOLOG(SPDK_LOG_LVOL
, "Could not open super blob\n");
295 req
->lvserrno
= -ENODEV
;
296 spdk_bs_unload(bs
, bs_unload_with_error_cb
, req
);
300 rc
= spdk_blob_get_xattr_value(blob
, "uuid", (const void **)&attr
, &value_len
);
301 if (rc
!= 0 || value_len
!= SPDK_UUID_STRING_LEN
|| attr
[SPDK_UUID_STRING_LEN
- 1] != '\0') {
302 SPDK_INFOLOG(SPDK_LOG_LVOL
, "missing or incorrect UUID\n");
303 req
->lvserrno
= -EINVAL
;
304 spdk_blob_close(blob
, close_super_blob_with_error_cb
, req
);
308 if (spdk_uuid_parse(&lvs
->uuid
, attr
)) {
309 SPDK_INFOLOG(SPDK_LOG_LVOL
, "incorrect UUID '%s'\n", attr
);
310 req
->lvserrno
= -EINVAL
;
311 spdk_blob_close(blob
, close_super_blob_with_error_cb
, req
);
315 rc
= spdk_blob_get_xattr_value(blob
, "name", (const void **)&attr
, &value_len
);
316 if (rc
!= 0 || value_len
> SPDK_LVS_NAME_MAX
) {
317 SPDK_INFOLOG(SPDK_LOG_LVOL
, "missing or invalid name\n");
318 req
->lvserrno
= -EINVAL
;
319 spdk_blob_close(blob
, close_super_blob_with_error_cb
, req
);
323 snprintf(lvs
->name
, sizeof(lvs
->name
), "%s", attr
);
325 rc
= add_lvs_to_list(lvs
);
327 SPDK_INFOLOG(SPDK_LOG_LVOL
, "lvolstore with name %s already exists\n", lvs
->name
);
328 req
->lvserrno
= -EEXIST
;
329 spdk_blob_close(blob
, close_super_blob_with_error_cb
, req
);
333 lvs
->super_blob_id
= spdk_blob_get_id(blob
);
335 spdk_blob_close(blob
, close_super_cb
, req
);
339 lvs_open_super(void *cb_arg
, spdk_blob_id blobid
, int lvolerrno
)
341 struct spdk_lvs_with_handle_req
*req
= (struct spdk_lvs_with_handle_req
*)cb_arg
;
342 struct spdk_lvol_store
*lvs
= req
->lvol_store
;
343 struct spdk_blob_store
*bs
= lvs
->blobstore
;
345 if (lvolerrno
!= 0) {
346 SPDK_INFOLOG(SPDK_LOG_LVOL
, "Super blob not found\n");
348 req
->lvserrno
= -ENODEV
;
349 spdk_bs_unload(bs
, bs_unload_with_error_cb
, req
);
353 spdk_bs_open_blob(bs
, blobid
, lvs_read_uuid
, req
);
357 lvs_load_cb(void *cb_arg
, struct spdk_blob_store
*bs
, int lvolerrno
)
359 struct spdk_lvs_with_handle_req
*req
= (struct spdk_lvs_with_handle_req
*)cb_arg
;
360 struct spdk_lvol_store
*lvs
;
362 if (lvolerrno
!= 0) {
363 req
->cb_fn(req
->cb_arg
, NULL
, lvolerrno
);
368 lvs
= calloc(1, sizeof(*lvs
));
370 SPDK_ERRLOG("Cannot alloc memory for lvol store\n");
371 spdk_bs_unload(bs
, bs_unload_with_error_cb
, req
);
376 lvs
->bs_dev
= req
->bs_dev
;
377 TAILQ_INIT(&lvs
->lvols
);
378 TAILQ_INIT(&lvs
->pending_lvols
);
380 req
->lvol_store
= lvs
;
382 spdk_bs_get_super(bs
, lvs_open_super
, req
);
386 lvs_bs_opts_init(struct spdk_bs_opts
*opts
)
388 spdk_bs_opts_init(opts
);
389 opts
->max_channel_ops
= SPDK_LVOL_BLOB_OPTS_CHANNEL_OPS
;
393 spdk_lvs_load(struct spdk_bs_dev
*bs_dev
, spdk_lvs_op_with_handle_complete cb_fn
, void *cb_arg
)
395 struct spdk_lvs_with_handle_req
*req
;
396 struct spdk_bs_opts opts
= {};
398 assert(cb_fn
!= NULL
);
400 if (bs_dev
== NULL
) {
401 SPDK_ERRLOG("Blobstore device does not exist\n");
402 cb_fn(cb_arg
, NULL
, -ENODEV
);
406 req
= calloc(1, sizeof(*req
));
408 SPDK_ERRLOG("Cannot alloc memory for request structure\n");
409 cb_fn(cb_arg
, NULL
, -ENOMEM
);
414 req
->cb_arg
= cb_arg
;
415 req
->bs_dev
= bs_dev
;
417 lvs_bs_opts_init(&opts
);
418 snprintf(opts
.bstype
.bstype
, sizeof(opts
.bstype
.bstype
), "LVOLSTORE");
420 spdk_bs_load(bs_dev
, &opts
, lvs_load_cb
, req
);
424 remove_bs_on_error_cb(void *cb_arg
, int bserrno
)
429 super_create_close_cb(void *cb_arg
, int lvolerrno
)
431 struct spdk_lvs_with_handle_req
*req
= cb_arg
;
432 struct spdk_lvol_store
*lvs
= req
->lvol_store
;
435 SPDK_ERRLOG("Lvol store init failed: could not close super blob\n");
436 req
->cb_fn(req
->cb_arg
, NULL
, lvolerrno
);
437 spdk_bs_destroy(lvs
->blobstore
, remove_bs_on_error_cb
, NULL
);
443 req
->cb_fn(req
->cb_arg
, lvs
, lvolerrno
);
448 super_blob_set_cb(void *cb_arg
, int lvolerrno
)
450 struct spdk_lvs_with_handle_req
*req
= cb_arg
;
451 struct spdk_lvol_store
*lvs
= req
->lvol_store
;
452 struct spdk_blob
*blob
= lvs
->super_blob
;
455 req
->cb_fn(req
->cb_arg
, NULL
, lvolerrno
);
456 SPDK_ERRLOG("Lvol store init failed: could not set uuid for super blob\n");
457 spdk_bs_destroy(lvs
->blobstore
, remove_bs_on_error_cb
, NULL
);
463 spdk_blob_close(blob
, super_create_close_cb
, req
);
467 super_blob_init_cb(void *cb_arg
, int lvolerrno
)
469 struct spdk_lvs_with_handle_req
*req
= cb_arg
;
470 struct spdk_lvol_store
*lvs
= req
->lvol_store
;
471 struct spdk_blob
*blob
= lvs
->super_blob
;
472 char uuid
[SPDK_UUID_STRING_LEN
];
475 req
->cb_fn(req
->cb_arg
, NULL
, lvolerrno
);
476 SPDK_ERRLOG("Lvol store init failed: could not set super blob\n");
477 spdk_bs_destroy(lvs
->blobstore
, remove_bs_on_error_cb
, NULL
);
483 spdk_uuid_fmt_lower(uuid
, sizeof(uuid
), &lvs
->uuid
);
485 spdk_blob_set_xattr(blob
, "uuid", uuid
, sizeof(uuid
));
486 spdk_blob_set_xattr(blob
, "name", lvs
->name
, strnlen(lvs
->name
, SPDK_LVS_NAME_MAX
) + 1);
487 spdk_blob_sync_md(blob
, super_blob_set_cb
, req
);
491 super_blob_create_open_cb(void *cb_arg
, struct spdk_blob
*blob
, int lvolerrno
)
493 struct spdk_lvs_with_handle_req
*req
= cb_arg
;
494 struct spdk_lvol_store
*lvs
= req
->lvol_store
;
497 req
->cb_fn(req
->cb_arg
, NULL
, lvolerrno
);
498 SPDK_ERRLOG("Lvol store init failed: could not open super blob\n");
499 spdk_bs_destroy(lvs
->blobstore
, remove_bs_on_error_cb
, NULL
);
505 lvs
->super_blob
= blob
;
506 lvs
->super_blob_id
= spdk_blob_get_id(blob
);
508 spdk_bs_set_super(lvs
->blobstore
, lvs
->super_blob_id
, super_blob_init_cb
, req
);
512 super_blob_create_cb(void *cb_arg
, spdk_blob_id blobid
, int lvolerrno
)
514 struct spdk_lvs_with_handle_req
*req
= cb_arg
;
515 struct spdk_lvol_store
*lvs
= req
->lvol_store
;
516 struct spdk_blob_store
*bs
;
519 req
->cb_fn(req
->cb_arg
, NULL
, lvolerrno
);
520 SPDK_ERRLOG("Lvol store init failed: could not create super blob\n");
521 spdk_bs_destroy(lvs
->blobstore
, remove_bs_on_error_cb
, NULL
);
527 bs
= req
->lvol_store
->blobstore
;
529 spdk_bs_open_blob(bs
, blobid
, super_blob_create_open_cb
, req
);
533 lvs_init_cb(void *cb_arg
, struct spdk_blob_store
*bs
, int lvserrno
)
535 struct spdk_lvs_with_handle_req
*lvs_req
= cb_arg
;
536 struct spdk_lvol_store
*lvs
= lvs_req
->lvol_store
;
540 lvs_req
->cb_fn(lvs_req
->cb_arg
, NULL
, lvserrno
);
541 SPDK_ERRLOG("Lvol store init failed: could not initialize blobstore\n");
549 TAILQ_INIT(&lvs
->lvols
);
550 TAILQ_INIT(&lvs
->pending_lvols
);
552 SPDK_INFOLOG(SPDK_LOG_LVOL
, "Lvol store initialized\n");
554 /* create super blob */
555 spdk_bs_create_blob(lvs
->blobstore
, super_blob_create_cb
, lvs_req
);
559 spdk_lvs_opts_init(struct spdk_lvs_opts
*o
)
561 o
->cluster_sz
= SPDK_LVS_OPTS_CLUSTER_SZ
;
562 o
->clear_method
= LVS_CLEAR_WITH_UNMAP
;
563 memset(o
->name
, 0, sizeof(o
->name
));
567 setup_lvs_opts(struct spdk_bs_opts
*bs_opts
, struct spdk_lvs_opts
*o
)
570 lvs_bs_opts_init(bs_opts
);
571 bs_opts
->cluster_sz
= o
->cluster_sz
;
572 bs_opts
->clear_method
= (enum bs_clear_method
)o
->clear_method
;
576 spdk_lvs_init(struct spdk_bs_dev
*bs_dev
, struct spdk_lvs_opts
*o
,
577 spdk_lvs_op_with_handle_complete cb_fn
, void *cb_arg
)
579 struct spdk_lvol_store
*lvs
;
580 struct spdk_lvs_with_handle_req
*lvs_req
;
581 struct spdk_bs_opts opts
= {};
584 if (bs_dev
== NULL
) {
585 SPDK_ERRLOG("Blobstore device does not exist\n");
590 SPDK_ERRLOG("spdk_lvs_opts not specified\n");
594 setup_lvs_opts(&opts
, o
);
596 if (strnlen(o
->name
, SPDK_LVS_NAME_MAX
) == SPDK_LVS_NAME_MAX
) {
597 SPDK_ERRLOG("Name has no null terminator.\n");
601 if (strnlen(o
->name
, SPDK_LVS_NAME_MAX
) == 0) {
602 SPDK_ERRLOG("No name specified.\n");
606 lvs
= calloc(1, sizeof(*lvs
));
608 SPDK_ERRLOG("Cannot alloc memory for lvol store base pointer\n");
612 spdk_uuid_generate(&lvs
->uuid
);
613 snprintf(lvs
->name
, sizeof(lvs
->name
), "%s", o
->name
);
615 rc
= add_lvs_to_list(lvs
);
617 SPDK_ERRLOG("lvolstore with name %s already exists\n", lvs
->name
);
622 lvs_req
= calloc(1, sizeof(*lvs_req
));
625 SPDK_ERRLOG("Cannot alloc memory for lvol store request pointer\n");
629 assert(cb_fn
!= NULL
);
630 lvs_req
->cb_fn
= cb_fn
;
631 lvs_req
->cb_arg
= cb_arg
;
632 lvs_req
->lvol_store
= lvs
;
633 lvs
->bs_dev
= bs_dev
;
634 lvs
->destruct
= false;
636 snprintf(opts
.bstype
.bstype
, sizeof(opts
.bstype
.bstype
), "LVOLSTORE");
638 SPDK_INFOLOG(SPDK_LOG_LVOL
, "Initializing lvol store\n");
639 spdk_bs_init(bs_dev
, &opts
, lvs_init_cb
, lvs_req
);
645 lvs_rename_cb(void *cb_arg
, int lvolerrno
)
647 struct spdk_lvs_req
*req
= cb_arg
;
649 if (lvolerrno
!= 0) {
650 req
->lvserrno
= lvolerrno
;
652 if (req
->lvserrno
!= 0) {
653 SPDK_ERRLOG("Lvol store rename operation failed\n");
654 /* Lvs renaming failed, so we should 'clear' new_name.
655 * Otherwise it could cause a failure on the next attepmt to change the name to 'new_name' */
656 snprintf(req
->lvol_store
->new_name
,
657 sizeof(req
->lvol_store
->new_name
),
658 "%s", req
->lvol_store
->name
);
660 /* Update lvs name with new_name */
661 snprintf(req
->lvol_store
->name
,
662 sizeof(req
->lvol_store
->name
),
663 "%s", req
->lvol_store
->new_name
);
666 req
->cb_fn(req
->cb_arg
, req
->lvserrno
);
671 lvs_rename_sync_cb(void *cb_arg
, int lvolerrno
)
673 struct spdk_lvs_req
*req
= cb_arg
;
674 struct spdk_blob
*blob
= req
->lvol_store
->super_blob
;
677 req
->lvserrno
= lvolerrno
;
680 spdk_blob_close(blob
, lvs_rename_cb
, req
);
684 lvs_rename_open_cb(void *cb_arg
, struct spdk_blob
*blob
, int lvolerrno
)
686 struct spdk_lvs_req
*req
= cb_arg
;
690 lvs_rename_cb(cb_arg
, lvolerrno
);
694 rc
= spdk_blob_set_xattr(blob
, "name", req
->lvol_store
->new_name
,
695 strlen(req
->lvol_store
->new_name
) + 1);
698 lvs_rename_sync_cb(req
, rc
);
702 req
->lvol_store
->super_blob
= blob
;
704 spdk_blob_sync_md(blob
, lvs_rename_sync_cb
, req
);
708 spdk_lvs_rename(struct spdk_lvol_store
*lvs
, const char *new_name
,
709 spdk_lvs_op_complete cb_fn
, void *cb_arg
)
711 struct spdk_lvs_req
*req
;
712 struct spdk_lvol_store
*tmp
;
714 /* Check if new name is current lvs name.
715 * If so, return success immediately */
716 if (strncmp(lvs
->name
, new_name
, SPDK_LVS_NAME_MAX
) == 0) {
721 /* Check if new or new_name is already used in other lvs */
722 pthread_mutex_lock(&g_lvol_stores_mutex
);
723 TAILQ_FOREACH(tmp
, &g_lvol_stores
, link
) {
724 if (!strncmp(new_name
, tmp
->name
, SPDK_LVS_NAME_MAX
) ||
725 !strncmp(new_name
, tmp
->new_name
, SPDK_LVS_NAME_MAX
)) {
726 pthread_mutex_unlock(&g_lvol_stores_mutex
);
727 cb_fn(cb_arg
, -EEXIST
);
731 pthread_mutex_unlock(&g_lvol_stores_mutex
);
733 req
= calloc(1, sizeof(*req
));
735 SPDK_ERRLOG("Cannot alloc memory for lvol request pointer\n");
736 cb_fn(cb_arg
, -ENOMEM
);
739 snprintf(lvs
->new_name
, sizeof(lvs
->new_name
), "%s", new_name
);
740 req
->lvol_store
= lvs
;
742 req
->cb_arg
= cb_arg
;
744 spdk_bs_open_blob(lvs
->blobstore
, lvs
->super_blob_id
, lvs_rename_open_cb
, req
);
748 _lvs_unload_cb(void *cb_arg
, int lvserrno
)
750 struct spdk_lvs_req
*lvs_req
= cb_arg
;
752 SPDK_INFOLOG(SPDK_LOG_LVOL
, "Lvol store unloaded\n");
753 assert(lvs_req
->cb_fn
!= NULL
);
754 lvs_req
->cb_fn(lvs_req
->cb_arg
, lvserrno
);
759 spdk_lvs_unload(struct spdk_lvol_store
*lvs
, spdk_lvs_op_complete cb_fn
,
762 struct spdk_lvs_req
*lvs_req
;
763 struct spdk_lvol
*lvol
, *tmp
;
766 SPDK_ERRLOG("Lvol store is NULL\n");
770 TAILQ_FOREACH_SAFE(lvol
, &lvs
->lvols
, link
, tmp
) {
771 if (lvol
->action_in_progress
== true) {
772 SPDK_ERRLOG("Cannot unload lvol store - operations on lvols pending\n");
773 cb_fn(cb_arg
, -EBUSY
);
775 } else if (lvol
->ref_count
!= 0) {
776 SPDK_ERRLOG("Lvols still open on lvol store\n");
777 cb_fn(cb_arg
, -EBUSY
);
782 TAILQ_FOREACH_SAFE(lvol
, &lvs
->lvols
, link
, tmp
) {
783 TAILQ_REMOVE(&lvs
->lvols
, lvol
, link
);
787 lvs_req
= calloc(1, sizeof(*lvs_req
));
789 SPDK_ERRLOG("Cannot alloc memory for lvol store request pointer\n");
793 lvs_req
->cb_fn
= cb_fn
;
794 lvs_req
->cb_arg
= cb_arg
;
796 SPDK_INFOLOG(SPDK_LOG_LVOL
, "Unloading lvol store\n");
797 spdk_bs_unload(lvs
->blobstore
, _lvs_unload_cb
, lvs_req
);
804 _lvs_destroy_cb(void *cb_arg
, int lvserrno
)
806 struct spdk_lvs_destroy_req
*lvs_req
= cb_arg
;
808 SPDK_INFOLOG(SPDK_LOG_LVOL
, "Lvol store destroyed\n");
809 assert(lvs_req
->cb_fn
!= NULL
);
810 lvs_req
->cb_fn(lvs_req
->cb_arg
, lvserrno
);
815 _lvs_destroy_super_cb(void *cb_arg
, int bserrno
)
817 struct spdk_lvs_destroy_req
*lvs_req
= cb_arg
;
818 struct spdk_lvol_store
*lvs
= lvs_req
->lvs
;
822 SPDK_INFOLOG(SPDK_LOG_LVOL
, "Destroying lvol store\n");
823 spdk_bs_destroy(lvs
->blobstore
, _lvs_destroy_cb
, lvs_req
);
828 spdk_lvs_destroy(struct spdk_lvol_store
*lvs
, spdk_lvs_op_complete cb_fn
,
831 struct spdk_lvs_destroy_req
*lvs_req
;
832 struct spdk_lvol
*iter_lvol
, *tmp
;
835 SPDK_ERRLOG("Lvol store is NULL\n");
839 TAILQ_FOREACH_SAFE(iter_lvol
, &lvs
->lvols
, link
, tmp
) {
840 if (iter_lvol
->action_in_progress
== true) {
841 SPDK_ERRLOG("Cannot destroy lvol store - operations on lvols pending\n");
842 cb_fn(cb_arg
, -EBUSY
);
844 } else if (iter_lvol
->ref_count
!= 0) {
845 SPDK_ERRLOG("Lvols still open on lvol store\n");
846 cb_fn(cb_arg
, -EBUSY
);
851 TAILQ_FOREACH_SAFE(iter_lvol
, &lvs
->lvols
, link
, tmp
) {
855 lvs_req
= calloc(1, sizeof(*lvs_req
));
857 SPDK_ERRLOG("Cannot alloc memory for lvol store request pointer\n");
861 lvs_req
->cb_fn
= cb_fn
;
862 lvs_req
->cb_arg
= cb_arg
;
865 SPDK_INFOLOG(SPDK_LOG_LVOL
, "Deleting super blob\n");
866 spdk_bs_delete_blob(lvs
->blobstore
, lvs
->super_blob_id
, _lvs_destroy_super_cb
, lvs_req
);
872 lvol_close_blob_cb(void *cb_arg
, int lvolerrno
)
874 struct spdk_lvol_req
*req
= cb_arg
;
875 struct spdk_lvol
*lvol
= req
->lvol
;
878 SPDK_ERRLOG("Could not close blob on lvol\n");
884 lvol
->action_in_progress
= false;
885 SPDK_INFOLOG(SPDK_LOG_LVOL
, "Lvol %s closed\n", lvol
->unique_id
);
888 req
->cb_fn(req
->cb_arg
, lvolerrno
);
893 spdk_lvol_deletable(struct spdk_lvol
*lvol
)
897 spdk_blob_get_clones(lvol
->lvol_store
->blobstore
, lvol
->blob_id
, NULL
, &count
);
902 lvol_delete_blob_cb(void *cb_arg
, int lvolerrno
)
904 struct spdk_lvol_req
*req
= cb_arg
;
905 struct spdk_lvol
*lvol
= req
->lvol
;
908 SPDK_ERRLOG("Could not remove blob on lvol gracefully - forced removal\n");
910 SPDK_INFOLOG(SPDK_LOG_LVOL
, "Lvol %s deleted\n", lvol
->unique_id
);
913 TAILQ_REMOVE(&lvol
->lvol_store
->lvols
, lvol
, link
);
915 req
->cb_fn(req
->cb_arg
, lvolerrno
);
920 lvol_create_open_cb(void *cb_arg
, struct spdk_blob
*blob
, int lvolerrno
)
922 struct spdk_lvol_with_handle_req
*req
= cb_arg
;
923 struct spdk_lvol
*lvol
= req
->lvol
;
925 TAILQ_REMOVE(&req
->lvol
->lvol_store
->pending_lvols
, req
->lvol
, link
);
929 req
->cb_fn(req
->cb_arg
, NULL
, lvolerrno
);
935 lvol
->blob_id
= spdk_blob_get_id(blob
);
937 TAILQ_INSERT_TAIL(&lvol
->lvol_store
->lvols
, lvol
, link
);
939 snprintf(lvol
->unique_id
, sizeof(lvol
->unique_id
), "%s", lvol
->uuid_str
);
942 assert(req
->cb_fn
!= NULL
);
943 req
->cb_fn(req
->cb_arg
, req
->lvol
, lvolerrno
);
948 lvol_create_cb(void *cb_arg
, spdk_blob_id blobid
, int lvolerrno
)
950 struct spdk_lvol_with_handle_req
*req
= cb_arg
;
951 struct spdk_blob_store
*bs
;
952 struct spdk_blob_open_opts opts
;
955 TAILQ_REMOVE(&req
->lvol
->lvol_store
->pending_lvols
, req
->lvol
, link
);
957 assert(req
->cb_fn
!= NULL
);
958 req
->cb_fn(req
->cb_arg
, NULL
, lvolerrno
);
963 spdk_blob_open_opts_init(&opts
);
964 opts
.clear_method
= req
->lvol
->clear_method
;
965 bs
= req
->lvol
->lvol_store
->blobstore
;
967 spdk_bs_open_blob_ext(bs
, blobid
, &opts
, lvol_create_open_cb
, req
);
971 lvol_get_xattr_value(void *xattr_ctx
, const char *name
,
972 const void **value
, size_t *value_len
)
974 struct spdk_lvol
*lvol
= xattr_ctx
;
976 if (!strcmp(LVOL_NAME
, name
)) {
978 *value_len
= SPDK_LVOL_NAME_MAX
;
979 } else if (!strcmp("uuid", name
)) {
980 *value
= lvol
->uuid_str
;
981 *value_len
= sizeof(lvol
->uuid_str
);
986 lvs_verify_lvol_name(struct spdk_lvol_store
*lvs
, const char *name
)
988 struct spdk_lvol
*tmp
;
990 if (name
== NULL
|| strnlen(name
, SPDK_LVOL_NAME_MAX
) == 0) {
991 SPDK_INFOLOG(SPDK_LOG_LVOL
, "lvol name not provided.\n");
995 if (strnlen(name
, SPDK_LVOL_NAME_MAX
) == SPDK_LVOL_NAME_MAX
) {
996 SPDK_ERRLOG("Name has no null terminator.\n");
1000 TAILQ_FOREACH(tmp
, &lvs
->lvols
, link
) {
1001 if (!strncmp(name
, tmp
->name
, SPDK_LVOL_NAME_MAX
)) {
1002 SPDK_ERRLOG("lvol with name %s already exists\n", name
);
1007 TAILQ_FOREACH(tmp
, &lvs
->pending_lvols
, link
) {
1008 if (!strncmp(name
, tmp
->name
, SPDK_LVOL_NAME_MAX
)) {
1009 SPDK_ERRLOG("lvol with name %s is being already created\n", name
);
1018 spdk_lvol_create(struct spdk_lvol_store
*lvs
, const char *name
, uint64_t sz
,
1019 bool thin_provision
, enum lvol_clear_method clear_method
, spdk_lvol_op_with_handle_complete cb_fn
,
1022 struct spdk_lvol_with_handle_req
*req
;
1023 struct spdk_blob_store
*bs
;
1024 struct spdk_lvol
*lvol
;
1025 struct spdk_blob_opts opts
;
1026 uint64_t num_clusters
;
1027 char *xattr_names
[] = {LVOL_NAME
, "uuid"};
1031 SPDK_ERRLOG("lvol store does not exist\n");
1035 rc
= lvs_verify_lvol_name(lvs
, name
);
1040 bs
= lvs
->blobstore
;
1042 req
= calloc(1, sizeof(*req
));
1044 SPDK_ERRLOG("Cannot alloc memory for lvol request pointer\n");
1048 req
->cb_arg
= cb_arg
;
1050 lvol
= calloc(1, sizeof(*lvol
));
1053 SPDK_ERRLOG("Cannot alloc memory for lvol base pointer\n");
1056 lvol
->lvol_store
= lvs
;
1057 num_clusters
= spdk_divide_round_up(sz
, spdk_bs_get_cluster_size(bs
));
1058 lvol
->thin_provision
= thin_provision
;
1059 lvol
->clear_method
= (enum blob_clear_method
)clear_method
;
1060 snprintf(lvol
->name
, sizeof(lvol
->name
), "%s", name
);
1061 TAILQ_INSERT_TAIL(&lvol
->lvol_store
->pending_lvols
, lvol
, link
);
1062 spdk_uuid_generate(&lvol
->uuid
);
1063 spdk_uuid_fmt_lower(lvol
->uuid_str
, sizeof(lvol
->uuid_str
), &lvol
->uuid
);
1066 spdk_blob_opts_init(&opts
);
1067 opts
.thin_provision
= thin_provision
;
1068 opts
.num_clusters
= num_clusters
;
1069 opts
.clear_method
= lvol
->clear_method
;
1070 opts
.xattrs
.count
= SPDK_COUNTOF(xattr_names
);
1071 opts
.xattrs
.names
= xattr_names
;
1072 opts
.xattrs
.ctx
= lvol
;
1073 opts
.xattrs
.get_value
= lvol_get_xattr_value
;
1075 spdk_bs_create_blob_ext(lvs
->blobstore
, &opts
, lvol_create_cb
, req
);
1081 spdk_lvol_create_snapshot(struct spdk_lvol
*origlvol
, const char *snapshot_name
,
1082 spdk_lvol_op_with_handle_complete cb_fn
, void *cb_arg
)
1084 struct spdk_lvol_store
*lvs
;
1085 struct spdk_lvol
*newlvol
;
1086 struct spdk_blob
*origblob
;
1087 struct spdk_lvol_with_handle_req
*req
;
1088 struct spdk_blob_xattr_opts snapshot_xattrs
;
1089 char *xattr_names
[] = {LVOL_NAME
, "uuid"};
1092 if (origlvol
== NULL
) {
1093 SPDK_INFOLOG(SPDK_LOG_LVOL
, "Lvol not provided.\n");
1094 cb_fn(cb_arg
, NULL
, -EINVAL
);
1098 origblob
= origlvol
->blob
;
1099 lvs
= origlvol
->lvol_store
;
1101 SPDK_ERRLOG("lvol store does not exist\n");
1102 cb_fn(cb_arg
, NULL
, -EINVAL
);
1106 rc
= lvs_verify_lvol_name(lvs
, snapshot_name
);
1108 cb_fn(cb_arg
, NULL
, rc
);
1112 req
= calloc(1, sizeof(*req
));
1114 SPDK_ERRLOG("Cannot alloc memory for lvol request pointer\n");
1115 cb_fn(cb_arg
, NULL
, -ENOMEM
);
1119 newlvol
= calloc(1, sizeof(*newlvol
));
1121 SPDK_ERRLOG("Cannot alloc memory for lvol base pointer\n");
1123 cb_fn(cb_arg
, NULL
, -ENOMEM
);
1127 newlvol
->lvol_store
= origlvol
->lvol_store
;
1128 snprintf(newlvol
->name
, sizeof(newlvol
->name
), "%s", snapshot_name
);
1129 TAILQ_INSERT_TAIL(&newlvol
->lvol_store
->pending_lvols
, newlvol
, link
);
1130 spdk_uuid_generate(&newlvol
->uuid
);
1131 spdk_uuid_fmt_lower(newlvol
->uuid_str
, sizeof(newlvol
->uuid_str
), &newlvol
->uuid
);
1132 snapshot_xattrs
.count
= SPDK_COUNTOF(xattr_names
);
1133 snapshot_xattrs
.ctx
= newlvol
;
1134 snapshot_xattrs
.names
= xattr_names
;
1135 snapshot_xattrs
.get_value
= lvol_get_xattr_value
;
1136 req
->lvol
= newlvol
;
1138 req
->cb_arg
= cb_arg
;
1140 spdk_bs_create_snapshot(lvs
->blobstore
, spdk_blob_get_id(origblob
), &snapshot_xattrs
,
1141 lvol_create_cb
, req
);
1145 spdk_lvol_create_clone(struct spdk_lvol
*origlvol
, const char *clone_name
,
1146 spdk_lvol_op_with_handle_complete cb_fn
, void *cb_arg
)
1148 struct spdk_lvol
*newlvol
;
1149 struct spdk_lvol_with_handle_req
*req
;
1150 struct spdk_lvol_store
*lvs
;
1151 struct spdk_blob
*origblob
;
1152 struct spdk_blob_xattr_opts clone_xattrs
;
1153 char *xattr_names
[] = {LVOL_NAME
, "uuid"};
1156 if (origlvol
== NULL
) {
1157 SPDK_INFOLOG(SPDK_LOG_LVOL
, "Lvol not provided.\n");
1158 cb_fn(cb_arg
, NULL
, -EINVAL
);
1162 origblob
= origlvol
->blob
;
1163 lvs
= origlvol
->lvol_store
;
1165 SPDK_ERRLOG("lvol store does not exist\n");
1166 cb_fn(cb_arg
, NULL
, -EINVAL
);
1170 rc
= lvs_verify_lvol_name(lvs
, clone_name
);
1172 cb_fn(cb_arg
, NULL
, rc
);
1176 req
= calloc(1, sizeof(*req
));
1178 SPDK_ERRLOG("Cannot alloc memory for lvol request pointer\n");
1179 cb_fn(cb_arg
, NULL
, -ENOMEM
);
1183 newlvol
= calloc(1, sizeof(*newlvol
));
1185 SPDK_ERRLOG("Cannot alloc memory for lvol base pointer\n");
1187 cb_fn(cb_arg
, NULL
, -ENOMEM
);
1191 newlvol
->lvol_store
= lvs
;
1192 snprintf(newlvol
->name
, sizeof(newlvol
->name
), "%s", clone_name
);
1193 TAILQ_INSERT_TAIL(&newlvol
->lvol_store
->pending_lvols
, newlvol
, link
);
1194 spdk_uuid_generate(&newlvol
->uuid
);
1195 spdk_uuid_fmt_lower(newlvol
->uuid_str
, sizeof(newlvol
->uuid_str
), &newlvol
->uuid
);
1196 clone_xattrs
.count
= SPDK_COUNTOF(xattr_names
);
1197 clone_xattrs
.ctx
= newlvol
;
1198 clone_xattrs
.names
= xattr_names
;
1199 clone_xattrs
.get_value
= lvol_get_xattr_value
;
1200 req
->lvol
= newlvol
;
1202 req
->cb_arg
= cb_arg
;
1204 spdk_bs_create_clone(lvs
->blobstore
, spdk_blob_get_id(origblob
), &clone_xattrs
,
1210 lvol_resize_done(void *cb_arg
, int lvolerrno
)
1212 struct spdk_lvol_req
*req
= cb_arg
;
1214 req
->cb_fn(req
->cb_arg
, lvolerrno
);
1219 lvol_blob_resize_cb(void *cb_arg
, int bserrno
)
1221 struct spdk_lvol_req
*req
= cb_arg
;
1222 struct spdk_lvol
*lvol
= req
->lvol
;
1225 req
->cb_fn(req
->cb_arg
, bserrno
);
1230 spdk_blob_sync_md(lvol
->blob
, lvol_resize_done
, req
);
1234 spdk_lvol_resize(struct spdk_lvol
*lvol
, uint64_t sz
,
1235 spdk_lvol_op_complete cb_fn
, void *cb_arg
)
1237 struct spdk_blob
*blob
= lvol
->blob
;
1238 struct spdk_lvol_store
*lvs
= lvol
->lvol_store
;
1239 struct spdk_lvol_req
*req
;
1240 uint64_t new_clusters
= spdk_divide_round_up(sz
, spdk_bs_get_cluster_size(lvs
->blobstore
));
1242 req
= calloc(1, sizeof(*req
));
1244 SPDK_ERRLOG("Cannot alloc memory for lvol request pointer\n");
1245 cb_fn(cb_arg
, -ENOMEM
);
1249 req
->cb_arg
= cb_arg
;
1252 spdk_blob_resize(blob
, new_clusters
, lvol_blob_resize_cb
, req
);
1256 lvol_set_read_only_cb(void *cb_arg
, int lvolerrno
)
1258 struct spdk_lvol_req
*req
= cb_arg
;
1260 req
->cb_fn(req
->cb_arg
, lvolerrno
);
1265 spdk_lvol_set_read_only(struct spdk_lvol
*lvol
, spdk_lvol_op_complete cb_fn
, void *cb_arg
)
1267 struct spdk_lvol_req
*req
;
1269 req
= calloc(1, sizeof(*req
));
1271 SPDK_ERRLOG("Cannot alloc memory for lvol request pointer\n");
1272 cb_fn(cb_arg
, -ENOMEM
);
1276 req
->cb_arg
= cb_arg
;
1278 spdk_blob_set_read_only(lvol
->blob
);
1279 spdk_blob_sync_md(lvol
->blob
, lvol_set_read_only_cb
, req
);
1283 lvol_rename_cb(void *cb_arg
, int lvolerrno
)
1285 struct spdk_lvol_req
*req
= cb_arg
;
1287 if (lvolerrno
!= 0) {
1288 SPDK_ERRLOG("Lvol rename operation failed\n");
1290 snprintf(req
->lvol
->name
, sizeof(req
->lvol
->name
), "%s", req
->name
);
1293 req
->cb_fn(req
->cb_arg
, lvolerrno
);
1298 spdk_lvol_rename(struct spdk_lvol
*lvol
, const char *new_name
,
1299 spdk_lvol_op_complete cb_fn
, void *cb_arg
)
1301 struct spdk_lvol
*tmp
;
1302 struct spdk_blob
*blob
= lvol
->blob
;
1303 struct spdk_lvol_req
*req
;
1306 /* Check if new name is current lvol name.
1307 * If so, return success immediately */
1308 if (strncmp(lvol
->name
, new_name
, SPDK_LVOL_NAME_MAX
) == 0) {
1313 /* Check if lvol with 'new_name' already exists in lvolstore */
1314 TAILQ_FOREACH(tmp
, &lvol
->lvol_store
->lvols
, link
) {
1315 if (strncmp(tmp
->name
, new_name
, SPDK_LVOL_NAME_MAX
) == 0) {
1316 SPDK_ERRLOG("Lvol %s already exists in lvol store %s\n", new_name
, lvol
->lvol_store
->name
);
1317 cb_fn(cb_arg
, -EEXIST
);
1322 req
= calloc(1, sizeof(*req
));
1324 SPDK_ERRLOG("Cannot alloc memory for lvol request pointer\n");
1325 cb_fn(cb_arg
, -ENOMEM
);
1329 req
->cb_arg
= cb_arg
;
1331 snprintf(req
->name
, sizeof(req
->name
), "%s", new_name
);
1333 rc
= spdk_blob_set_xattr(blob
, "name", new_name
, strlen(new_name
) + 1);
1340 spdk_blob_sync_md(blob
, lvol_rename_cb
, req
);
1344 spdk_lvol_destroy(struct spdk_lvol
*lvol
, spdk_lvol_op_complete cb_fn
, void *cb_arg
)
1346 struct spdk_lvol_req
*req
;
1347 struct spdk_blob_store
*bs
;
1349 assert(cb_fn
!= NULL
);
1352 SPDK_ERRLOG("lvol does not exist\n");
1353 cb_fn(cb_arg
, -ENODEV
);
1357 if (lvol
->ref_count
!= 0) {
1358 SPDK_ERRLOG("Cannot destroy lvol %s because it is still open\n", lvol
->unique_id
);
1359 cb_fn(cb_arg
, -EBUSY
);
1363 lvol
->action_in_progress
= true;
1365 req
= calloc(1, sizeof(*req
));
1367 SPDK_ERRLOG("Cannot alloc memory for lvol request pointer\n");
1368 cb_fn(cb_arg
, -ENOMEM
);
1373 req
->cb_arg
= cb_arg
;
1375 bs
= lvol
->lvol_store
->blobstore
;
1377 spdk_bs_delete_blob(bs
, lvol
->blob_id
, lvol_delete_blob_cb
, req
);
1381 spdk_lvol_close(struct spdk_lvol
*lvol
, spdk_lvol_op_complete cb_fn
, void *cb_arg
)
1383 struct spdk_lvol_req
*req
;
1385 assert(cb_fn
!= NULL
);
1388 SPDK_ERRLOG("lvol does not exist\n");
1389 cb_fn(cb_arg
, -ENODEV
);
1393 if (lvol
->ref_count
> 1) {
1397 } else if (lvol
->ref_count
== 0) {
1398 cb_fn(cb_arg
, -EINVAL
);
1402 lvol
->action_in_progress
= true;
1404 req
= calloc(1, sizeof(*req
));
1406 SPDK_ERRLOG("Cannot alloc memory for lvol request pointer\n");
1407 cb_fn(cb_arg
, -ENOMEM
);
1412 req
->cb_arg
= cb_arg
;
1415 spdk_blob_close(lvol
->blob
, lvol_close_blob_cb
, req
);
1418 struct spdk_io_channel
*
1419 spdk_lvol_get_io_channel(struct spdk_lvol
*lvol
)
1421 return spdk_bs_alloc_io_channel(lvol
->lvol_store
->blobstore
);
1425 lvol_inflate_cb(void *cb_arg
, int lvolerrno
)
1427 struct spdk_lvol_req
*req
= cb_arg
;
1429 spdk_bs_free_io_channel(req
->channel
);
1431 if (lvolerrno
< 0) {
1432 SPDK_ERRLOG("Could not inflate lvol\n");
1435 req
->cb_fn(req
->cb_arg
, lvolerrno
);
1440 spdk_lvol_inflate(struct spdk_lvol
*lvol
, spdk_lvol_op_complete cb_fn
, void *cb_arg
)
1442 struct spdk_lvol_req
*req
;
1443 spdk_blob_id blob_id
;
1445 assert(cb_fn
!= NULL
);
1448 SPDK_ERRLOG("Lvol does not exist\n");
1449 cb_fn(cb_arg
, -ENODEV
);
1453 req
= calloc(1, sizeof(*req
));
1455 SPDK_ERRLOG("Cannot alloc memory for lvol request pointer\n");
1456 cb_fn(cb_arg
, -ENOMEM
);
1461 req
->cb_arg
= cb_arg
;
1462 req
->channel
= spdk_bs_alloc_io_channel(lvol
->lvol_store
->blobstore
);
1463 if (req
->channel
== NULL
) {
1464 SPDK_ERRLOG("Cannot alloc io channel for lvol inflate request\n");
1466 cb_fn(cb_arg
, -ENOMEM
);
1470 blob_id
= spdk_blob_get_id(lvol
->blob
);
1471 spdk_bs_inflate_blob(lvol
->lvol_store
->blobstore
, req
->channel
, blob_id
, lvol_inflate_cb
,
1476 spdk_lvol_decouple_parent(struct spdk_lvol
*lvol
, spdk_lvol_op_complete cb_fn
, void *cb_arg
)
1478 struct spdk_lvol_req
*req
;
1479 spdk_blob_id blob_id
;
1481 assert(cb_fn
!= NULL
);
1484 SPDK_ERRLOG("Lvol does not exist\n");
1485 cb_fn(cb_arg
, -ENODEV
);
1489 req
= calloc(1, sizeof(*req
));
1491 SPDK_ERRLOG("Cannot alloc memory for lvol request pointer\n");
1492 cb_fn(cb_arg
, -ENOMEM
);
1497 req
->cb_arg
= cb_arg
;
1498 req
->channel
= spdk_bs_alloc_io_channel(lvol
->lvol_store
->blobstore
);
1499 if (req
->channel
== NULL
) {
1500 SPDK_ERRLOG("Cannot alloc io channel for lvol inflate request\n");
1502 cb_fn(cb_arg
, -ENOMEM
);
1506 blob_id
= spdk_blob_get_id(lvol
->blob
);
1507 spdk_bs_blob_decouple_parent(lvol
->lvol_store
->blobstore
, req
->channel
, blob_id
,
1508 lvol_inflate_cb
, req
);