1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (C) 2017 Intel Corporation. 3 * All rights reserved. 4 * Copyright (c) 2022-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 5 */ 6 7 #include "spdk_internal/lvolstore.h" 8 #include "spdk/log.h" 9 #include "spdk/string.h" 10 #include "spdk/thread.h" 11 #include "spdk/blob_bdev.h" 12 #include "spdk/tree.h" 13 #include "spdk/util.h" 14 15 /* Default blob channel opts for lvol */ 16 #define SPDK_LVOL_BLOB_OPTS_CHANNEL_OPS 512 17 18 #define LVOL_NAME "name" 19 20 SPDK_LOG_REGISTER_COMPONENT(lvol) 21 22 struct spdk_lvs_degraded_lvol_set { 23 struct spdk_lvol_store *lvol_store; 24 const void *esnap_id; 25 uint32_t id_len; 26 TAILQ_HEAD(degraded_lvols, spdk_lvol) lvols; 27 RB_ENTRY(spdk_lvs_degraded_lvol_set) node; 28 }; 29 30 static TAILQ_HEAD(, spdk_lvol_store) g_lvol_stores = TAILQ_HEAD_INITIALIZER(g_lvol_stores); 31 static pthread_mutex_t g_lvol_stores_mutex = PTHREAD_MUTEX_INITIALIZER; 32 33 static inline int lvs_opts_copy(const struct spdk_lvs_opts *src, struct spdk_lvs_opts *dst); 34 static int lvs_esnap_bs_dev_create(void *bs_ctx, void *blob_ctx, struct spdk_blob *blob, 35 const void *esnap_id, uint32_t id_len, 36 struct spdk_bs_dev **_bs_dev); 37 static struct spdk_lvol *lvs_get_lvol_by_blob_id(struct spdk_lvol_store *lvs, spdk_blob_id blob_id); 38 static void lvs_degraded_lvol_set_add(struct spdk_lvs_degraded_lvol_set *degraded_set, 39 struct spdk_lvol *lvol); 40 static void lvs_degraded_lvol_set_remove(struct spdk_lvs_degraded_lvol_set *degraded_set, 41 struct spdk_lvol *lvol); 42 43 static int 44 add_lvs_to_list(struct spdk_lvol_store *lvs) 45 { 46 struct spdk_lvol_store *tmp; 47 bool name_conflict = false; 48 49 pthread_mutex_lock(&g_lvol_stores_mutex); 50 TAILQ_FOREACH(tmp, &g_lvol_stores, link) { 51 if (!strncmp(lvs->name, tmp->name, SPDK_LVS_NAME_MAX)) { 52 name_conflict = true; 53 break; 54 } 55 } 56 if (!name_conflict) { 57 lvs->on_list = true; 58 TAILQ_INSERT_TAIL(&g_lvol_stores, lvs, link); 59 } 60 pthread_mutex_unlock(&g_lvol_stores_mutex); 61 62 return name_conflict ? -1 : 0; 63 } 64 65 static struct spdk_lvol_store * 66 lvs_alloc(void) 67 { 68 struct spdk_lvol_store *lvs; 69 70 lvs = calloc(1, sizeof(*lvs)); 71 if (lvs == NULL) { 72 return NULL; 73 } 74 75 TAILQ_INIT(&lvs->lvols); 76 TAILQ_INIT(&lvs->pending_lvols); 77 TAILQ_INIT(&lvs->retry_open_lvols); 78 79 lvs->load_esnaps = false; 80 RB_INIT(&lvs->degraded_lvol_sets_tree); 81 lvs->thread = spdk_get_thread(); 82 83 return lvs; 84 } 85 86 static void 87 lvs_free(struct spdk_lvol_store *lvs) 88 { 89 pthread_mutex_lock(&g_lvol_stores_mutex); 90 if (lvs->on_list) { 91 TAILQ_REMOVE(&g_lvol_stores, lvs, link); 92 } 93 pthread_mutex_unlock(&g_lvol_stores_mutex); 94 95 assert(RB_EMPTY(&lvs->degraded_lvol_sets_tree)); 96 97 free(lvs); 98 } 99 100 static struct spdk_lvol * 101 lvol_alloc(struct spdk_lvol_store *lvs, const char *name, bool thin_provision, 102 enum lvol_clear_method clear_method) 103 { 104 struct spdk_lvol *lvol; 105 106 lvol = calloc(1, sizeof(*lvol)); 107 if (lvol == NULL) { 108 return NULL; 109 } 110 111 lvol->lvol_store = lvs; 112 lvol->clear_method = (enum blob_clear_method)clear_method; 113 snprintf(lvol->name, sizeof(lvol->name), "%s", name); 114 spdk_uuid_generate(&lvol->uuid); 115 spdk_uuid_fmt_lower(lvol->uuid_str, sizeof(lvol->uuid_str), &lvol->uuid); 116 spdk_uuid_fmt_lower(lvol->unique_id, sizeof(lvol->uuid_str), &lvol->uuid); 117 118 TAILQ_INSERT_TAIL(&lvs->pending_lvols, lvol, link); 119 120 return lvol; 121 } 122 123 static void 124 lvol_free(struct spdk_lvol *lvol) 125 { 126 free(lvol); 127 } 128 129 static void 130 lvol_open_cb(void *cb_arg, struct spdk_blob *blob, int lvolerrno) 131 { 132 struct spdk_lvol_with_handle_req *req = cb_arg; 133 struct spdk_lvol *lvol = req->lvol; 134 135 if (lvolerrno != 0) { 136 SPDK_INFOLOG(lvol, "Failed to open lvol %s\n", lvol->unique_id); 137 goto end; 138 } 139 140 lvol->ref_count++; 141 lvol->blob = blob; 142 end: 143 req->cb_fn(req->cb_arg, lvol, lvolerrno); 144 free(req); 145 } 146 147 void 148 spdk_lvol_open(struct spdk_lvol *lvol, spdk_lvol_op_with_handle_complete cb_fn, void *cb_arg) 149 { 150 struct spdk_lvol_with_handle_req *req; 151 struct spdk_blob_open_opts opts; 152 153 assert(cb_fn != NULL); 154 155 if (lvol == NULL) { 156 SPDK_ERRLOG("lvol does not exist\n"); 157 cb_fn(cb_arg, NULL, -ENODEV); 158 return; 159 } 160 161 if (lvol->action_in_progress == true) { 162 SPDK_ERRLOG("Cannot open lvol - operations on lvol pending\n"); 163 cb_fn(cb_arg, lvol, -EBUSY); 164 return; 165 } 166 167 if (lvol->ref_count > 0) { 168 lvol->ref_count++; 169 cb_fn(cb_arg, lvol, 0); 170 return; 171 } 172 173 req = calloc(1, sizeof(*req)); 174 if (req == NULL) { 175 SPDK_ERRLOG("Cannot alloc memory for request structure\n"); 176 cb_fn(cb_arg, NULL, -ENOMEM); 177 return; 178 } 179 180 req->cb_fn = cb_fn; 181 req->cb_arg = cb_arg; 182 req->lvol = lvol; 183 184 spdk_blob_open_opts_init(&opts, sizeof(opts)); 185 opts.clear_method = lvol->clear_method; 186 187 spdk_bs_open_blob_ext(lvol->lvol_store->blobstore, lvol->blob_id, &opts, lvol_open_cb, req); 188 } 189 190 static void 191 bs_unload_with_error_cb(void *cb_arg, int lvolerrno) 192 { 193 struct spdk_lvs_with_handle_req *req = (struct spdk_lvs_with_handle_req *)cb_arg; 194 195 req->cb_fn(req->cb_arg, NULL, req->lvserrno); 196 free(req); 197 } 198 199 static void 200 load_next_lvol(void *cb_arg, struct spdk_blob *blob, int lvolerrno) 201 { 202 struct spdk_lvs_with_handle_req *req = cb_arg; 203 struct spdk_lvol_store *lvs = req->lvol_store; 204 struct spdk_blob_store *bs = lvs->blobstore; 205 struct spdk_lvol *lvol, *tmp; 206 spdk_blob_id blob_id; 207 const char *attr; 208 size_t value_len; 209 int rc; 210 211 if (lvolerrno == -ENOENT) { 212 /* Finished iterating */ 213 if (req->lvserrno == 0) { 214 lvs->load_esnaps = true; 215 req->cb_fn(req->cb_arg, lvs, req->lvserrno); 216 free(req); 217 } else { 218 TAILQ_FOREACH_SAFE(lvol, &lvs->lvols, link, tmp) { 219 TAILQ_REMOVE(&lvs->lvols, lvol, link); 220 lvol_free(lvol); 221 } 222 lvs_free(lvs); 223 spdk_bs_unload(bs, bs_unload_with_error_cb, req); 224 } 225 return; 226 } else if (lvolerrno < 0) { 227 SPDK_ERRLOG("Failed to fetch blobs list\n"); 228 req->lvserrno = lvolerrno; 229 goto invalid; 230 } 231 232 blob_id = spdk_blob_get_id(blob); 233 234 if (blob_id == lvs->super_blob_id) { 235 SPDK_INFOLOG(lvol, "found superblob %"PRIu64"\n", (uint64_t)blob_id); 236 spdk_bs_iter_next(bs, blob, load_next_lvol, req); 237 return; 238 } 239 240 lvol = calloc(1, sizeof(*lvol)); 241 if (!lvol) { 242 SPDK_ERRLOG("Cannot alloc memory for lvol base pointer\n"); 243 req->lvserrno = -ENOMEM; 244 goto invalid; 245 } 246 247 /* 248 * Do not store a reference to blob now because spdk_bs_iter_next() will close it. 249 * Storing blob_id for future lookups is fine. 250 */ 251 lvol->blob_id = blob_id; 252 lvol->lvol_store = lvs; 253 254 rc = spdk_blob_get_xattr_value(blob, "uuid", (const void **)&attr, &value_len); 255 if (rc != 0 || value_len != SPDK_UUID_STRING_LEN || attr[SPDK_UUID_STRING_LEN - 1] != '\0' || 256 spdk_uuid_parse(&lvol->uuid, attr) != 0) { 257 SPDK_INFOLOG(lvol, "Missing or corrupt lvol uuid\n"); 258 spdk_uuid_set_null(&lvol->uuid); 259 } 260 spdk_uuid_fmt_lower(lvol->uuid_str, sizeof(lvol->uuid_str), &lvol->uuid); 261 262 if (!spdk_uuid_is_null(&lvol->uuid)) { 263 snprintf(lvol->unique_id, sizeof(lvol->unique_id), "%s", lvol->uuid_str); 264 } else { 265 spdk_uuid_fmt_lower(lvol->unique_id, sizeof(lvol->unique_id), &lvol->lvol_store->uuid); 266 value_len = strlen(lvol->unique_id); 267 snprintf(lvol->unique_id + value_len, sizeof(lvol->unique_id) - value_len, "_%"PRIu64, 268 (uint64_t)blob_id); 269 } 270 271 rc = spdk_blob_get_xattr_value(blob, "name", (const void **)&attr, &value_len); 272 if (rc != 0 || value_len > SPDK_LVOL_NAME_MAX) { 273 SPDK_ERRLOG("Cannot assign lvol name\n"); 274 lvol_free(lvol); 275 req->lvserrno = -EINVAL; 276 goto invalid; 277 } 278 279 snprintf(lvol->name, sizeof(lvol->name), "%s", attr); 280 281 TAILQ_INSERT_TAIL(&lvs->lvols, lvol, link); 282 283 lvs->lvol_count++; 284 285 SPDK_INFOLOG(lvol, "added lvol %s (%s)\n", lvol->unique_id, lvol->uuid_str); 286 287 invalid: 288 spdk_bs_iter_next(bs, blob, load_next_lvol, req); 289 } 290 291 static void 292 close_super_cb(void *cb_arg, int lvolerrno) 293 { 294 struct spdk_lvs_with_handle_req *req = (struct spdk_lvs_with_handle_req *)cb_arg; 295 struct spdk_lvol_store *lvs = req->lvol_store; 296 struct spdk_blob_store *bs = lvs->blobstore; 297 298 if (lvolerrno != 0) { 299 SPDK_INFOLOG(lvol, "Could not close super blob\n"); 300 lvs_free(lvs); 301 req->lvserrno = -ENODEV; 302 spdk_bs_unload(bs, bs_unload_with_error_cb, req); 303 return; 304 } 305 306 /* Start loading lvols */ 307 spdk_bs_iter_first(lvs->blobstore, load_next_lvol, req); 308 } 309 310 static void 311 close_super_blob_with_error_cb(void *cb_arg, int lvolerrno) 312 { 313 struct spdk_lvs_with_handle_req *req = (struct spdk_lvs_with_handle_req *)cb_arg; 314 struct spdk_lvol_store *lvs = req->lvol_store; 315 struct spdk_blob_store *bs = lvs->blobstore; 316 317 lvs_free(lvs); 318 319 spdk_bs_unload(bs, bs_unload_with_error_cb, req); 320 } 321 322 static void 323 lvs_read_uuid(void *cb_arg, struct spdk_blob *blob, int lvolerrno) 324 { 325 struct spdk_lvs_with_handle_req *req = (struct spdk_lvs_with_handle_req *)cb_arg; 326 struct spdk_lvol_store *lvs = req->lvol_store; 327 struct spdk_blob_store *bs = lvs->blobstore; 328 const char *attr; 329 size_t value_len; 330 int rc; 331 332 if (lvolerrno != 0) { 333 SPDK_INFOLOG(lvol, "Could not open super blob\n"); 334 lvs_free(lvs); 335 req->lvserrno = -ENODEV; 336 spdk_bs_unload(bs, bs_unload_with_error_cb, req); 337 return; 338 } 339 340 rc = spdk_blob_get_xattr_value(blob, "uuid", (const void **)&attr, &value_len); 341 if (rc != 0 || value_len != SPDK_UUID_STRING_LEN || attr[SPDK_UUID_STRING_LEN - 1] != '\0') { 342 SPDK_INFOLOG(lvol, "degraded_set or incorrect UUID\n"); 343 req->lvserrno = -EINVAL; 344 spdk_blob_close(blob, close_super_blob_with_error_cb, req); 345 return; 346 } 347 348 if (spdk_uuid_parse(&lvs->uuid, attr)) { 349 SPDK_INFOLOG(lvol, "incorrect UUID '%s'\n", attr); 350 req->lvserrno = -EINVAL; 351 spdk_blob_close(blob, close_super_blob_with_error_cb, req); 352 return; 353 } 354 355 rc = spdk_blob_get_xattr_value(blob, "name", (const void **)&attr, &value_len); 356 if (rc != 0 || value_len > SPDK_LVS_NAME_MAX) { 357 SPDK_INFOLOG(lvol, "degraded_set or invalid name\n"); 358 req->lvserrno = -EINVAL; 359 spdk_blob_close(blob, close_super_blob_with_error_cb, req); 360 return; 361 } 362 363 snprintf(lvs->name, sizeof(lvs->name), "%s", attr); 364 365 rc = add_lvs_to_list(lvs); 366 if (rc) { 367 SPDK_INFOLOG(lvol, "lvolstore with name %s already exists\n", lvs->name); 368 req->lvserrno = -EEXIST; 369 spdk_blob_close(blob, close_super_blob_with_error_cb, req); 370 return; 371 } 372 373 lvs->super_blob_id = spdk_blob_get_id(blob); 374 375 spdk_blob_close(blob, close_super_cb, req); 376 } 377 378 static void 379 lvs_open_super(void *cb_arg, spdk_blob_id blobid, int lvolerrno) 380 { 381 struct spdk_lvs_with_handle_req *req = (struct spdk_lvs_with_handle_req *)cb_arg; 382 struct spdk_lvol_store *lvs = req->lvol_store; 383 struct spdk_blob_store *bs = lvs->blobstore; 384 385 if (lvolerrno != 0) { 386 SPDK_INFOLOG(lvol, "Super blob not found\n"); 387 lvs_free(lvs); 388 req->lvserrno = -ENODEV; 389 spdk_bs_unload(bs, bs_unload_with_error_cb, req); 390 return; 391 } 392 393 spdk_bs_open_blob(bs, blobid, lvs_read_uuid, req); 394 } 395 396 static void 397 lvs_load_cb(void *cb_arg, struct spdk_blob_store *bs, int lvolerrno) 398 { 399 struct spdk_lvs_with_handle_req *req = (struct spdk_lvs_with_handle_req *)cb_arg; 400 struct spdk_lvol_store *lvs = req->lvol_store; 401 402 if (lvolerrno != 0) { 403 req->cb_fn(req->cb_arg, NULL, lvolerrno); 404 lvs_free(lvs); 405 free(req); 406 return; 407 } 408 409 lvs->blobstore = bs; 410 lvs->bs_dev = req->bs_dev; 411 412 spdk_bs_get_super(bs, lvs_open_super, req); 413 } 414 415 static void 416 lvs_bs_opts_init(struct spdk_bs_opts *opts) 417 { 418 spdk_bs_opts_init(opts, sizeof(*opts)); 419 opts->max_channel_ops = SPDK_LVOL_BLOB_OPTS_CHANNEL_OPS; 420 } 421 422 static void 423 lvs_load(struct spdk_bs_dev *bs_dev, const struct spdk_lvs_opts *_lvs_opts, 424 spdk_lvs_op_with_handle_complete cb_fn, void *cb_arg) 425 { 426 struct spdk_lvs_with_handle_req *req; 427 struct spdk_bs_opts bs_opts = {}; 428 struct spdk_lvs_opts lvs_opts; 429 430 assert(cb_fn != NULL); 431 432 if (bs_dev == NULL) { 433 SPDK_ERRLOG("Blobstore device does not exist\n"); 434 cb_fn(cb_arg, NULL, -ENODEV); 435 return; 436 } 437 438 spdk_lvs_opts_init(&lvs_opts); 439 if (_lvs_opts != NULL) { 440 if (lvs_opts_copy(_lvs_opts, &lvs_opts) != 0) { 441 SPDK_ERRLOG("Invalid options\n"); 442 cb_fn(cb_arg, NULL, -EINVAL); 443 return; 444 } 445 } 446 447 req = calloc(1, sizeof(*req)); 448 if (req == NULL) { 449 SPDK_ERRLOG("Cannot alloc memory for request structure\n"); 450 cb_fn(cb_arg, NULL, -ENOMEM); 451 return; 452 } 453 454 req->lvol_store = lvs_alloc(); 455 if (req->lvol_store == NULL) { 456 SPDK_ERRLOG("Cannot alloc memory for lvol store\n"); 457 free(req); 458 cb_fn(cb_arg, NULL, -ENOMEM); 459 return; 460 } 461 req->cb_fn = cb_fn; 462 req->cb_arg = cb_arg; 463 req->bs_dev = bs_dev; 464 465 lvs_bs_opts_init(&bs_opts); 466 snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "LVOLSTORE"); 467 468 if (lvs_opts.esnap_bs_dev_create != NULL) { 469 req->lvol_store->esnap_bs_dev_create = lvs_opts.esnap_bs_dev_create; 470 bs_opts.esnap_bs_dev_create = lvs_esnap_bs_dev_create; 471 bs_opts.esnap_ctx = req->lvol_store; 472 } 473 474 spdk_bs_load(bs_dev, &bs_opts, lvs_load_cb, req); 475 } 476 477 void 478 spdk_lvs_load(struct spdk_bs_dev *bs_dev, spdk_lvs_op_with_handle_complete cb_fn, void *cb_arg) 479 { 480 lvs_load(bs_dev, NULL, cb_fn, cb_arg); 481 } 482 483 void 484 spdk_lvs_load_ext(struct spdk_bs_dev *bs_dev, const struct spdk_lvs_opts *opts, 485 spdk_lvs_op_with_handle_complete cb_fn, void *cb_arg) 486 { 487 lvs_load(bs_dev, opts, cb_fn, cb_arg); 488 } 489 490 static void 491 remove_bs_on_error_cb(void *cb_arg, int bserrno) 492 { 493 } 494 495 static void 496 exit_error_lvs_req(struct spdk_lvs_with_handle_req *req, struct spdk_lvol_store *lvs, int lvolerrno) 497 { 498 req->cb_fn(req->cb_arg, NULL, lvolerrno); 499 spdk_bs_destroy(lvs->blobstore, remove_bs_on_error_cb, NULL); 500 lvs_free(lvs); 501 free(req); 502 } 503 504 static void 505 super_create_close_cb(void *cb_arg, int lvolerrno) 506 { 507 struct spdk_lvs_with_handle_req *req = cb_arg; 508 struct spdk_lvol_store *lvs = req->lvol_store; 509 510 if (lvolerrno < 0) { 511 SPDK_ERRLOG("Lvol store init failed: could not close super blob\n"); 512 exit_error_lvs_req(req, lvs, lvolerrno); 513 return; 514 } 515 516 req->cb_fn(req->cb_arg, lvs, lvolerrno); 517 free(req); 518 } 519 520 static void 521 super_blob_set_cb(void *cb_arg, int lvolerrno) 522 { 523 struct spdk_lvs_with_handle_req *req = cb_arg; 524 struct spdk_lvol_store *lvs = req->lvol_store; 525 struct spdk_blob *blob = lvs->super_blob; 526 527 if (lvolerrno < 0) { 528 SPDK_ERRLOG("Lvol store init failed: could not set uuid for super blob\n"); 529 exit_error_lvs_req(req, lvs, lvolerrno); 530 return; 531 } 532 533 spdk_blob_close(blob, super_create_close_cb, req); 534 } 535 536 static void 537 super_blob_init_cb(void *cb_arg, int lvolerrno) 538 { 539 struct spdk_lvs_with_handle_req *req = cb_arg; 540 struct spdk_lvol_store *lvs = req->lvol_store; 541 struct spdk_blob *blob = lvs->super_blob; 542 char uuid[SPDK_UUID_STRING_LEN]; 543 544 if (lvolerrno < 0) { 545 SPDK_ERRLOG("Lvol store init failed: could not set super blob\n"); 546 exit_error_lvs_req(req, lvs, lvolerrno); 547 return; 548 } 549 550 spdk_uuid_fmt_lower(uuid, sizeof(uuid), &lvs->uuid); 551 552 spdk_blob_set_xattr(blob, "uuid", uuid, sizeof(uuid)); 553 spdk_blob_set_xattr(blob, "name", lvs->name, strnlen(lvs->name, SPDK_LVS_NAME_MAX) + 1); 554 spdk_blob_sync_md(blob, super_blob_set_cb, req); 555 } 556 557 static void 558 super_blob_create_open_cb(void *cb_arg, struct spdk_blob *blob, int lvolerrno) 559 { 560 struct spdk_lvs_with_handle_req *req = cb_arg; 561 struct spdk_lvol_store *lvs = req->lvol_store; 562 563 if (lvolerrno < 0) { 564 SPDK_ERRLOG("Lvol store init failed: could not open super blob\n"); 565 exit_error_lvs_req(req, lvs, lvolerrno); 566 return; 567 } 568 569 lvs->super_blob = blob; 570 lvs->super_blob_id = spdk_blob_get_id(blob); 571 572 spdk_bs_set_super(lvs->blobstore, lvs->super_blob_id, super_blob_init_cb, req); 573 } 574 575 static void 576 super_blob_create_cb(void *cb_arg, spdk_blob_id blobid, int lvolerrno) 577 { 578 struct spdk_lvs_with_handle_req *req = cb_arg; 579 struct spdk_lvol_store *lvs = req->lvol_store; 580 struct spdk_blob_store *bs; 581 582 if (lvolerrno < 0) { 583 SPDK_ERRLOG("Lvol store init failed: could not create super blob\n"); 584 exit_error_lvs_req(req, lvs, lvolerrno); 585 return; 586 } 587 588 bs = req->lvol_store->blobstore; 589 590 spdk_bs_open_blob(bs, blobid, super_blob_create_open_cb, req); 591 } 592 593 static void 594 lvs_init_cb(void *cb_arg, struct spdk_blob_store *bs, int lvserrno) 595 { 596 struct spdk_lvs_with_handle_req *lvs_req = cb_arg; 597 struct spdk_lvol_store *lvs = lvs_req->lvol_store; 598 599 if (lvserrno != 0) { 600 assert(bs == NULL); 601 lvs_req->cb_fn(lvs_req->cb_arg, NULL, lvserrno); 602 SPDK_ERRLOG("Lvol store init failed: could not initialize blobstore\n"); 603 lvs_free(lvs); 604 free(lvs_req); 605 return; 606 } 607 608 assert(bs != NULL); 609 lvs->blobstore = bs; 610 611 SPDK_INFOLOG(lvol, "Lvol store initialized\n"); 612 613 /* create super blob */ 614 spdk_bs_create_blob(lvs->blobstore, super_blob_create_cb, lvs_req); 615 } 616 617 void 618 spdk_lvs_opts_init(struct spdk_lvs_opts *o) 619 { 620 memset(o, 0, sizeof(*o)); 621 o->cluster_sz = SPDK_LVS_OPTS_CLUSTER_SZ; 622 o->clear_method = LVS_CLEAR_WITH_UNMAP; 623 o->num_md_pages_per_cluster_ratio = 100; 624 o->opts_size = sizeof(*o); 625 } 626 627 static inline int 628 lvs_opts_copy(const struct spdk_lvs_opts *src, struct spdk_lvs_opts *dst) 629 { 630 if (src->opts_size == 0) { 631 SPDK_ERRLOG("opts_size should not be zero value\n"); 632 return -1; 633 } 634 #define FIELD_OK(field) \ 635 offsetof(struct spdk_lvs_opts, field) + sizeof(src->field) <= src->opts_size 636 637 #define SET_FIELD(field) \ 638 if (FIELD_OK(field)) { \ 639 dst->field = src->field; \ 640 } \ 641 642 SET_FIELD(cluster_sz); 643 SET_FIELD(clear_method); 644 if (FIELD_OK(name)) { 645 memcpy(&dst->name, &src->name, sizeof(dst->name)); 646 } 647 SET_FIELD(num_md_pages_per_cluster_ratio); 648 SET_FIELD(opts_size); 649 SET_FIELD(esnap_bs_dev_create); 650 651 dst->opts_size = src->opts_size; 652 653 /* You should not remove this statement, but need to update the assert statement 654 * if you add a new field, and also add a corresponding SET_FIELD statement */ 655 SPDK_STATIC_ASSERT(sizeof(struct spdk_lvs_opts) == 88, "Incorrect size"); 656 657 #undef FIELD_OK 658 #undef SET_FIELD 659 660 return 0; 661 } 662 663 static void 664 setup_lvs_opts(struct spdk_bs_opts *bs_opts, struct spdk_lvs_opts *o, uint32_t total_clusters, 665 void *esnap_ctx) 666 { 667 assert(o != NULL); 668 lvs_bs_opts_init(bs_opts); 669 bs_opts->cluster_sz = o->cluster_sz; 670 bs_opts->clear_method = (enum bs_clear_method)o->clear_method; 671 bs_opts->num_md_pages = (o->num_md_pages_per_cluster_ratio * total_clusters) / 100; 672 bs_opts->esnap_bs_dev_create = o->esnap_bs_dev_create; 673 bs_opts->esnap_ctx = esnap_ctx; 674 snprintf(bs_opts->bstype.bstype, sizeof(bs_opts->bstype.bstype), "LVOLSTORE"); 675 } 676 677 int 678 spdk_lvs_init(struct spdk_bs_dev *bs_dev, struct spdk_lvs_opts *o, 679 spdk_lvs_op_with_handle_complete cb_fn, void *cb_arg) 680 { 681 struct spdk_lvol_store *lvs; 682 struct spdk_lvs_with_handle_req *lvs_req; 683 struct spdk_bs_opts opts = {}; 684 struct spdk_lvs_opts lvs_opts; 685 uint32_t total_clusters; 686 int rc; 687 688 if (bs_dev == NULL) { 689 SPDK_ERRLOG("Blobstore device does not exist\n"); 690 return -ENODEV; 691 } 692 693 if (o == NULL) { 694 SPDK_ERRLOG("spdk_lvs_opts not specified\n"); 695 return -EINVAL; 696 } 697 698 spdk_lvs_opts_init(&lvs_opts); 699 if (lvs_opts_copy(o, &lvs_opts) != 0) { 700 SPDK_ERRLOG("spdk_lvs_opts invalid\n"); 701 return -EINVAL; 702 } 703 704 if (lvs_opts.cluster_sz < bs_dev->blocklen) { 705 SPDK_ERRLOG("Cluster size %" PRIu32 " is smaller than blocklen %" PRIu32 "\n", 706 lvs_opts.cluster_sz, bs_dev->blocklen); 707 return -EINVAL; 708 } 709 total_clusters = bs_dev->blockcnt / (lvs_opts.cluster_sz / bs_dev->blocklen); 710 711 lvs = lvs_alloc(); 712 if (!lvs) { 713 SPDK_ERRLOG("Cannot alloc memory for lvol store base pointer\n"); 714 return -ENOMEM; 715 } 716 717 setup_lvs_opts(&opts, o, total_clusters, lvs); 718 719 if (strnlen(lvs_opts.name, SPDK_LVS_NAME_MAX) == SPDK_LVS_NAME_MAX) { 720 SPDK_ERRLOG("Name has no null terminator.\n"); 721 lvs_free(lvs); 722 return -EINVAL; 723 } 724 725 if (strnlen(lvs_opts.name, SPDK_LVS_NAME_MAX) == 0) { 726 SPDK_ERRLOG("No name specified.\n"); 727 lvs_free(lvs); 728 return -EINVAL; 729 } 730 731 spdk_uuid_generate(&lvs->uuid); 732 snprintf(lvs->name, sizeof(lvs->name), "%s", lvs_opts.name); 733 734 rc = add_lvs_to_list(lvs); 735 if (rc) { 736 SPDK_ERRLOG("lvolstore with name %s already exists\n", lvs->name); 737 lvs_free(lvs); 738 return -EEXIST; 739 } 740 741 lvs_req = calloc(1, sizeof(*lvs_req)); 742 if (!lvs_req) { 743 lvs_free(lvs); 744 SPDK_ERRLOG("Cannot alloc memory for lvol store request pointer\n"); 745 return -ENOMEM; 746 } 747 748 assert(cb_fn != NULL); 749 lvs_req->cb_fn = cb_fn; 750 lvs_req->cb_arg = cb_arg; 751 lvs_req->lvol_store = lvs; 752 lvs->bs_dev = bs_dev; 753 754 SPDK_INFOLOG(lvol, "Initializing lvol store\n"); 755 spdk_bs_init(bs_dev, &opts, lvs_init_cb, lvs_req); 756 757 return 0; 758 } 759 760 static void 761 lvs_rename_cb(void *cb_arg, int lvolerrno) 762 { 763 struct spdk_lvs_req *req = cb_arg; 764 765 if (lvolerrno != 0) { 766 req->lvserrno = lvolerrno; 767 } 768 if (req->lvserrno != 0) { 769 SPDK_ERRLOG("Lvol store rename operation failed\n"); 770 /* Lvs renaming failed, so we should 'clear' new_name. 771 * Otherwise it could cause a failure on the next attempt to change the name to 'new_name' */ 772 snprintf(req->lvol_store->new_name, 773 sizeof(req->lvol_store->new_name), 774 "%s", req->lvol_store->name); 775 } else { 776 /* Update lvs name with new_name */ 777 snprintf(req->lvol_store->name, 778 sizeof(req->lvol_store->name), 779 "%s", req->lvol_store->new_name); 780 } 781 782 req->cb_fn(req->cb_arg, req->lvserrno); 783 free(req); 784 } 785 786 static void 787 lvs_rename_sync_cb(void *cb_arg, int lvolerrno) 788 { 789 struct spdk_lvs_req *req = cb_arg; 790 struct spdk_blob *blob = req->lvol_store->super_blob; 791 792 if (lvolerrno < 0) { 793 req->lvserrno = lvolerrno; 794 } 795 796 spdk_blob_close(blob, lvs_rename_cb, req); 797 } 798 799 static void 800 lvs_rename_open_cb(void *cb_arg, struct spdk_blob *blob, int lvolerrno) 801 { 802 struct spdk_lvs_req *req = cb_arg; 803 int rc; 804 805 if (lvolerrno < 0) { 806 lvs_rename_cb(cb_arg, lvolerrno); 807 return; 808 } 809 810 rc = spdk_blob_set_xattr(blob, "name", req->lvol_store->new_name, 811 strlen(req->lvol_store->new_name) + 1); 812 if (rc < 0) { 813 req->lvserrno = rc; 814 lvs_rename_sync_cb(req, rc); 815 return; 816 } 817 818 req->lvol_store->super_blob = blob; 819 820 spdk_blob_sync_md(blob, lvs_rename_sync_cb, req); 821 } 822 823 void 824 spdk_lvs_rename(struct spdk_lvol_store *lvs, const char *new_name, 825 spdk_lvs_op_complete cb_fn, void *cb_arg) 826 { 827 struct spdk_lvs_req *req; 828 struct spdk_lvol_store *tmp; 829 830 /* Check if new name is current lvs name. 831 * If so, return success immediately */ 832 if (strncmp(lvs->name, new_name, SPDK_LVS_NAME_MAX) == 0) { 833 cb_fn(cb_arg, 0); 834 return; 835 } 836 837 /* Check if new or new_name is already used in other lvs */ 838 pthread_mutex_lock(&g_lvol_stores_mutex); 839 TAILQ_FOREACH(tmp, &g_lvol_stores, link) { 840 if (!strncmp(new_name, tmp->name, SPDK_LVS_NAME_MAX) || 841 !strncmp(new_name, tmp->new_name, SPDK_LVS_NAME_MAX)) { 842 pthread_mutex_unlock(&g_lvol_stores_mutex); 843 cb_fn(cb_arg, -EEXIST); 844 return; 845 } 846 } 847 pthread_mutex_unlock(&g_lvol_stores_mutex); 848 849 req = calloc(1, sizeof(*req)); 850 if (!req) { 851 SPDK_ERRLOG("Cannot alloc memory for lvol request pointer\n"); 852 cb_fn(cb_arg, -ENOMEM); 853 return; 854 } 855 snprintf(lvs->new_name, sizeof(lvs->new_name), "%s", new_name); 856 req->lvol_store = lvs; 857 req->cb_fn = cb_fn; 858 req->cb_arg = cb_arg; 859 860 spdk_bs_open_blob(lvs->blobstore, lvs->super_blob_id, lvs_rename_open_cb, req); 861 } 862 863 static void 864 _lvs_unload_cb(void *cb_arg, int lvserrno) 865 { 866 struct spdk_lvs_req *lvs_req = cb_arg; 867 868 SPDK_INFOLOG(lvol, "Lvol store unloaded\n"); 869 assert(lvs_req->cb_fn != NULL); 870 lvs_req->cb_fn(lvs_req->cb_arg, lvserrno); 871 free(lvs_req); 872 } 873 874 int 875 spdk_lvs_unload(struct spdk_lvol_store *lvs, spdk_lvs_op_complete cb_fn, 876 void *cb_arg) 877 { 878 struct spdk_lvs_req *lvs_req; 879 struct spdk_lvol *lvol, *tmp; 880 881 if (lvs == NULL) { 882 SPDK_ERRLOG("Lvol store is NULL\n"); 883 return -ENODEV; 884 } 885 886 TAILQ_FOREACH_SAFE(lvol, &lvs->lvols, link, tmp) { 887 if (lvol->action_in_progress == true) { 888 SPDK_ERRLOG("Cannot unload lvol store - operations on lvols pending\n"); 889 cb_fn(cb_arg, -EBUSY); 890 return -EBUSY; 891 } else if (lvol->ref_count != 0) { 892 SPDK_ERRLOG("Lvols still open on lvol store\n"); 893 cb_fn(cb_arg, -EBUSY); 894 return -EBUSY; 895 } 896 } 897 898 TAILQ_FOREACH_SAFE(lvol, &lvs->lvols, link, tmp) { 899 spdk_lvs_esnap_missing_remove(lvol); 900 TAILQ_REMOVE(&lvs->lvols, lvol, link); 901 lvol_free(lvol); 902 } 903 904 lvs_req = calloc(1, sizeof(*lvs_req)); 905 if (!lvs_req) { 906 SPDK_ERRLOG("Cannot alloc memory for lvol store request pointer\n"); 907 return -ENOMEM; 908 } 909 910 lvs_req->cb_fn = cb_fn; 911 lvs_req->cb_arg = cb_arg; 912 913 SPDK_INFOLOG(lvol, "Unloading lvol store\n"); 914 spdk_bs_unload(lvs->blobstore, _lvs_unload_cb, lvs_req); 915 lvs_free(lvs); 916 917 return 0; 918 } 919 920 static void 921 _lvs_destroy_cb(void *cb_arg, int lvserrno) 922 { 923 struct spdk_lvs_destroy_req *lvs_req = cb_arg; 924 925 SPDK_INFOLOG(lvol, "Lvol store destroyed\n"); 926 assert(lvs_req->cb_fn != NULL); 927 lvs_req->cb_fn(lvs_req->cb_arg, lvserrno); 928 free(lvs_req); 929 } 930 931 static void 932 _lvs_destroy_super_cb(void *cb_arg, int bserrno) 933 { 934 struct spdk_lvs_destroy_req *lvs_req = cb_arg; 935 struct spdk_lvol_store *lvs = lvs_req->lvs; 936 937 assert(lvs != NULL); 938 939 SPDK_INFOLOG(lvol, "Destroying lvol store\n"); 940 spdk_bs_destroy(lvs->blobstore, _lvs_destroy_cb, lvs_req); 941 lvs_free(lvs); 942 } 943 944 int 945 spdk_lvs_destroy(struct spdk_lvol_store *lvs, spdk_lvs_op_complete cb_fn, 946 void *cb_arg) 947 { 948 struct spdk_lvs_destroy_req *lvs_req; 949 struct spdk_lvol *iter_lvol, *tmp; 950 951 if (lvs == NULL) { 952 SPDK_ERRLOG("Lvol store is NULL\n"); 953 return -ENODEV; 954 } 955 956 TAILQ_FOREACH_SAFE(iter_lvol, &lvs->lvols, link, tmp) { 957 if (iter_lvol->action_in_progress == true) { 958 SPDK_ERRLOG("Cannot destroy lvol store - operations on lvols pending\n"); 959 cb_fn(cb_arg, -EBUSY); 960 return -EBUSY; 961 } else if (iter_lvol->ref_count != 0) { 962 SPDK_ERRLOG("Lvols still open on lvol store\n"); 963 cb_fn(cb_arg, -EBUSY); 964 return -EBUSY; 965 } 966 } 967 968 TAILQ_FOREACH_SAFE(iter_lvol, &lvs->lvols, link, tmp) { 969 free(iter_lvol); 970 } 971 972 lvs_req = calloc(1, sizeof(*lvs_req)); 973 if (!lvs_req) { 974 SPDK_ERRLOG("Cannot alloc memory for lvol store request pointer\n"); 975 return -ENOMEM; 976 } 977 978 lvs_req->cb_fn = cb_fn; 979 lvs_req->cb_arg = cb_arg; 980 lvs_req->lvs = lvs; 981 982 SPDK_INFOLOG(lvol, "Deleting super blob\n"); 983 spdk_bs_delete_blob(lvs->blobstore, lvs->super_blob_id, _lvs_destroy_super_cb, lvs_req); 984 985 return 0; 986 } 987 988 static void 989 lvol_close_blob_cb(void *cb_arg, int lvolerrno) 990 { 991 struct spdk_lvol_req *req = cb_arg; 992 struct spdk_lvol *lvol = req->lvol; 993 994 if (lvolerrno < 0) { 995 SPDK_ERRLOG("Could not close blob on lvol\n"); 996 goto end; 997 } 998 999 lvol->ref_count--; 1000 lvol->blob = NULL; 1001 SPDK_INFOLOG(lvol, "Lvol %s closed\n", lvol->unique_id); 1002 1003 end: 1004 lvol->action_in_progress = false; 1005 req->cb_fn(req->cb_arg, lvolerrno); 1006 free(req); 1007 } 1008 1009 bool 1010 spdk_lvol_deletable(struct spdk_lvol *lvol) 1011 { 1012 size_t count = 0; 1013 1014 spdk_blob_get_clones(lvol->lvol_store->blobstore, lvol->blob_id, NULL, &count); 1015 return (count == 0); 1016 } 1017 1018 static void 1019 lvol_delete_blob_cb(void *cb_arg, int lvolerrno) 1020 { 1021 struct spdk_lvol_req *req = cb_arg; 1022 struct spdk_lvol *lvol = req->lvol; 1023 struct spdk_lvol *clone_lvol = req->clone_lvol; 1024 1025 if (lvolerrno < 0) { 1026 SPDK_ERRLOG("Could not remove blob on lvol gracefully - forced removal\n"); 1027 } else { 1028 SPDK_INFOLOG(lvol, "Lvol %s deleted\n", lvol->unique_id); 1029 } 1030 1031 if (lvol->degraded_set != NULL) { 1032 if (clone_lvol != NULL) { 1033 /* 1034 * A degraded esnap clone that has a blob clone has been deleted. clone_lvol 1035 * becomes an esnap clone and needs to be associated with the 1036 * spdk_lvs_degraded_lvol_set. 1037 */ 1038 struct spdk_lvs_degraded_lvol_set *degraded_set = lvol->degraded_set; 1039 1040 lvs_degraded_lvol_set_remove(degraded_set, lvol); 1041 lvs_degraded_lvol_set_add(degraded_set, clone_lvol); 1042 } else { 1043 spdk_lvs_esnap_missing_remove(lvol); 1044 } 1045 } 1046 1047 TAILQ_REMOVE(&lvol->lvol_store->lvols, lvol, link); 1048 lvol_free(lvol); 1049 req->cb_fn(req->cb_arg, lvolerrno); 1050 free(req); 1051 } 1052 1053 static void 1054 lvol_create_open_cb(void *cb_arg, struct spdk_blob *blob, int lvolerrno) 1055 { 1056 struct spdk_lvol_with_handle_req *req = cb_arg; 1057 struct spdk_lvol *lvol = req->lvol; 1058 1059 TAILQ_REMOVE(&req->lvol->lvol_store->pending_lvols, req->lvol, link); 1060 1061 if (lvolerrno < 0) { 1062 lvol_free(lvol); 1063 req->cb_fn(req->cb_arg, NULL, lvolerrno); 1064 free(req); 1065 return; 1066 } 1067 1068 lvol->blob = blob; 1069 lvol->blob_id = spdk_blob_get_id(blob); 1070 1071 TAILQ_INSERT_TAIL(&lvol->lvol_store->lvols, lvol, link); 1072 1073 lvol->ref_count++; 1074 1075 assert(req->cb_fn != NULL); 1076 req->cb_fn(req->cb_arg, req->lvol, lvolerrno); 1077 free(req); 1078 } 1079 1080 static void 1081 lvol_create_cb(void *cb_arg, spdk_blob_id blobid, int lvolerrno) 1082 { 1083 struct spdk_lvol_with_handle_req *req = cb_arg; 1084 struct spdk_blob_store *bs; 1085 struct spdk_blob_open_opts opts; 1086 1087 if (lvolerrno < 0) { 1088 TAILQ_REMOVE(&req->lvol->lvol_store->pending_lvols, req->lvol, link); 1089 lvol_free(req->lvol); 1090 assert(req->cb_fn != NULL); 1091 req->cb_fn(req->cb_arg, NULL, lvolerrno); 1092 free(req); 1093 return; 1094 } 1095 1096 spdk_blob_open_opts_init(&opts, sizeof(opts)); 1097 opts.clear_method = req->lvol->clear_method; 1098 /* 1099 * If the lvol that is being created is an esnap clone, the blobstore needs to be able to 1100 * pass the lvol to the esnap_bs_dev_create callback. In order for that to happen, we need 1101 * to pass it here. 1102 * 1103 * This does set ensap_ctx in cases where it's not needed, but we don't know that it's not 1104 * needed until after the blob is open. When the blob is not an esnap clone, a reference to 1105 * the value stored in opts.esnap_ctx is not retained by the blobstore. 1106 */ 1107 opts.esnap_ctx = req->lvol; 1108 bs = req->lvol->lvol_store->blobstore; 1109 1110 if (req->origlvol != NULL && req->origlvol->degraded_set != NULL) { 1111 /* 1112 * A snapshot was created from a degraded esnap clone. The new snapshot is now a 1113 * degraded esnap clone. The previous clone is now a regular clone of a blob. Update 1114 * the set of directly-related clones to the missing external snapshot. 1115 */ 1116 struct spdk_lvs_degraded_lvol_set *degraded_set = req->origlvol->degraded_set; 1117 1118 lvs_degraded_lvol_set_remove(degraded_set, req->origlvol); 1119 lvs_degraded_lvol_set_add(degraded_set, req->lvol); 1120 } 1121 1122 spdk_bs_open_blob_ext(bs, blobid, &opts, lvol_create_open_cb, req); 1123 } 1124 1125 static void 1126 lvol_get_xattr_value(void *xattr_ctx, const char *name, 1127 const void **value, size_t *value_len) 1128 { 1129 struct spdk_lvol *lvol = xattr_ctx; 1130 1131 if (!strcmp(LVOL_NAME, name)) { 1132 *value = lvol->name; 1133 *value_len = SPDK_LVOL_NAME_MAX; 1134 return; 1135 } 1136 if (!strcmp("uuid", name)) { 1137 *value = lvol->uuid_str; 1138 *value_len = sizeof(lvol->uuid_str); 1139 return; 1140 } 1141 *value = NULL; 1142 *value_len = 0; 1143 } 1144 1145 static int 1146 lvs_verify_lvol_name(struct spdk_lvol_store *lvs, const char *name) 1147 { 1148 struct spdk_lvol *tmp; 1149 1150 if (name == NULL || strnlen(name, SPDK_LVOL_NAME_MAX) == 0) { 1151 SPDK_INFOLOG(lvol, "lvol name not provided.\n"); 1152 return -EINVAL; 1153 } 1154 1155 if (strnlen(name, SPDK_LVOL_NAME_MAX) == SPDK_LVOL_NAME_MAX) { 1156 SPDK_ERRLOG("Name has no null terminator.\n"); 1157 return -EINVAL; 1158 } 1159 1160 TAILQ_FOREACH(tmp, &lvs->lvols, link) { 1161 if (!strncmp(name, tmp->name, SPDK_LVOL_NAME_MAX)) { 1162 SPDK_ERRLOG("lvol with name %s already exists\n", name); 1163 return -EEXIST; 1164 } 1165 } 1166 1167 TAILQ_FOREACH(tmp, &lvs->pending_lvols, link) { 1168 if (!strncmp(name, tmp->name, SPDK_LVOL_NAME_MAX)) { 1169 SPDK_ERRLOG("lvol with name %s is being already created\n", name); 1170 return -EEXIST; 1171 } 1172 } 1173 1174 return 0; 1175 } 1176 1177 int 1178 spdk_lvol_create(struct spdk_lvol_store *lvs, const char *name, uint64_t sz, 1179 bool thin_provision, enum lvol_clear_method clear_method, spdk_lvol_op_with_handle_complete cb_fn, 1180 void *cb_arg) 1181 { 1182 struct spdk_lvol_with_handle_req *req; 1183 struct spdk_blob_store *bs; 1184 struct spdk_lvol *lvol; 1185 struct spdk_blob_opts opts; 1186 char *xattr_names[] = {LVOL_NAME, "uuid"}; 1187 int rc; 1188 1189 if (lvs == NULL) { 1190 SPDK_ERRLOG("lvol store does not exist\n"); 1191 return -EINVAL; 1192 } 1193 1194 rc = lvs_verify_lvol_name(lvs, name); 1195 if (rc < 0) { 1196 return rc; 1197 } 1198 1199 bs = lvs->blobstore; 1200 1201 req = calloc(1, sizeof(*req)); 1202 if (!req) { 1203 SPDK_ERRLOG("Cannot alloc memory for lvol request pointer\n"); 1204 return -ENOMEM; 1205 } 1206 req->cb_fn = cb_fn; 1207 req->cb_arg = cb_arg; 1208 1209 lvol = lvol_alloc(lvs, name, thin_provision, clear_method); 1210 if (!lvol) { 1211 free(req); 1212 SPDK_ERRLOG("Cannot alloc memory for lvol base pointer\n"); 1213 return -ENOMEM; 1214 } 1215 1216 req->lvol = lvol; 1217 spdk_blob_opts_init(&opts, sizeof(opts)); 1218 opts.thin_provision = thin_provision; 1219 opts.num_clusters = spdk_divide_round_up(sz, spdk_bs_get_cluster_size(bs)); 1220 opts.clear_method = lvol->clear_method; 1221 opts.xattrs.count = SPDK_COUNTOF(xattr_names); 1222 opts.xattrs.names = xattr_names; 1223 opts.xattrs.ctx = lvol; 1224 opts.xattrs.get_value = lvol_get_xattr_value; 1225 1226 spdk_bs_create_blob_ext(lvs->blobstore, &opts, lvol_create_cb, req); 1227 1228 return 0; 1229 } 1230 1231 int 1232 spdk_lvol_create_esnap_clone(const void *esnap_id, uint32_t id_len, uint64_t size_bytes, 1233 struct spdk_lvol_store *lvs, const char *clone_name, 1234 spdk_lvol_op_with_handle_complete cb_fn, void *cb_arg) 1235 { 1236 struct spdk_lvol_with_handle_req *req; 1237 struct spdk_blob_store *bs; 1238 struct spdk_lvol *lvol; 1239 struct spdk_blob_opts opts; 1240 uint64_t cluster_sz; 1241 char *xattr_names[] = {LVOL_NAME, "uuid"}; 1242 int rc; 1243 1244 if (lvs == NULL) { 1245 SPDK_ERRLOG("lvol store does not exist\n"); 1246 return -EINVAL; 1247 } 1248 1249 rc = lvs_verify_lvol_name(lvs, clone_name); 1250 if (rc < 0) { 1251 return rc; 1252 } 1253 1254 bs = lvs->blobstore; 1255 1256 cluster_sz = spdk_bs_get_cluster_size(bs); 1257 if ((size_bytes % cluster_sz) != 0) { 1258 SPDK_ERRLOG("Cannot create '%s/%s': size %" PRIu64 " is not an integer multiple of " 1259 "cluster size %" PRIu64 "\n", lvs->name, clone_name, size_bytes, 1260 cluster_sz); 1261 return -EINVAL; 1262 } 1263 1264 req = calloc(1, sizeof(*req)); 1265 if (!req) { 1266 SPDK_ERRLOG("Cannot alloc memory for lvol request pointer\n"); 1267 return -ENOMEM; 1268 } 1269 req->cb_fn = cb_fn; 1270 req->cb_arg = cb_arg; 1271 1272 lvol = lvol_alloc(lvs, clone_name, true, LVOL_CLEAR_WITH_DEFAULT); 1273 if (!lvol) { 1274 free(req); 1275 SPDK_ERRLOG("Cannot alloc memory for lvol base pointer\n"); 1276 return -ENOMEM; 1277 } 1278 req->lvol = lvol; 1279 1280 spdk_blob_opts_init(&opts, sizeof(opts)); 1281 opts.esnap_id = esnap_id; 1282 opts.esnap_id_len = id_len; 1283 opts.thin_provision = true; 1284 opts.num_clusters = spdk_divide_round_up(size_bytes, cluster_sz); 1285 opts.clear_method = lvol->clear_method; 1286 opts.xattrs.count = SPDK_COUNTOF(xattr_names); 1287 opts.xattrs.names = xattr_names; 1288 opts.xattrs.ctx = lvol; 1289 opts.xattrs.get_value = lvol_get_xattr_value; 1290 1291 spdk_bs_create_blob_ext(lvs->blobstore, &opts, lvol_create_cb, req); 1292 1293 return 0; 1294 } 1295 1296 void 1297 spdk_lvol_create_snapshot(struct spdk_lvol *origlvol, const char *snapshot_name, 1298 spdk_lvol_op_with_handle_complete cb_fn, void *cb_arg) 1299 { 1300 struct spdk_lvol_store *lvs; 1301 struct spdk_lvol *newlvol; 1302 struct spdk_blob *origblob; 1303 struct spdk_lvol_with_handle_req *req; 1304 struct spdk_blob_xattr_opts snapshot_xattrs; 1305 char *xattr_names[] = {LVOL_NAME, "uuid"}; 1306 int rc; 1307 1308 if (origlvol == NULL) { 1309 SPDK_INFOLOG(lvol, "Lvol not provided.\n"); 1310 cb_fn(cb_arg, NULL, -EINVAL); 1311 return; 1312 } 1313 1314 origblob = origlvol->blob; 1315 lvs = origlvol->lvol_store; 1316 if (lvs == NULL) { 1317 SPDK_ERRLOG("lvol store does not exist\n"); 1318 cb_fn(cb_arg, NULL, -EINVAL); 1319 return; 1320 } 1321 1322 rc = lvs_verify_lvol_name(lvs, snapshot_name); 1323 if (rc < 0) { 1324 cb_fn(cb_arg, NULL, rc); 1325 return; 1326 } 1327 1328 req = calloc(1, sizeof(*req)); 1329 if (!req) { 1330 SPDK_ERRLOG("Cannot alloc memory for lvol request pointer\n"); 1331 cb_fn(cb_arg, NULL, -ENOMEM); 1332 return; 1333 } 1334 1335 newlvol = lvol_alloc(origlvol->lvol_store, snapshot_name, true, 1336 (enum lvol_clear_method)origlvol->clear_method); 1337 if (!newlvol) { 1338 SPDK_ERRLOG("Cannot alloc memory for lvol base pointer\n"); 1339 free(req); 1340 cb_fn(cb_arg, NULL, -ENOMEM); 1341 return; 1342 } 1343 1344 snapshot_xattrs.count = SPDK_COUNTOF(xattr_names); 1345 snapshot_xattrs.ctx = newlvol; 1346 snapshot_xattrs.names = xattr_names; 1347 snapshot_xattrs.get_value = lvol_get_xattr_value; 1348 req->lvol = newlvol; 1349 req->origlvol = origlvol; 1350 req->cb_fn = cb_fn; 1351 req->cb_arg = cb_arg; 1352 1353 spdk_bs_create_snapshot(lvs->blobstore, spdk_blob_get_id(origblob), &snapshot_xattrs, 1354 lvol_create_cb, req); 1355 } 1356 1357 void 1358 spdk_lvol_create_clone(struct spdk_lvol *origlvol, const char *clone_name, 1359 spdk_lvol_op_with_handle_complete cb_fn, void *cb_arg) 1360 { 1361 struct spdk_lvol *newlvol; 1362 struct spdk_lvol_with_handle_req *req; 1363 struct spdk_lvol_store *lvs; 1364 struct spdk_blob *origblob; 1365 struct spdk_blob_xattr_opts clone_xattrs; 1366 char *xattr_names[] = {LVOL_NAME, "uuid"}; 1367 int rc; 1368 1369 if (origlvol == NULL) { 1370 SPDK_INFOLOG(lvol, "Lvol not provided.\n"); 1371 cb_fn(cb_arg, NULL, -EINVAL); 1372 return; 1373 } 1374 1375 origblob = origlvol->blob; 1376 lvs = origlvol->lvol_store; 1377 if (lvs == NULL) { 1378 SPDK_ERRLOG("lvol store does not exist\n"); 1379 cb_fn(cb_arg, NULL, -EINVAL); 1380 return; 1381 } 1382 1383 rc = lvs_verify_lvol_name(lvs, clone_name); 1384 if (rc < 0) { 1385 cb_fn(cb_arg, NULL, rc); 1386 return; 1387 } 1388 1389 req = calloc(1, sizeof(*req)); 1390 if (!req) { 1391 SPDK_ERRLOG("Cannot alloc memory for lvol request pointer\n"); 1392 cb_fn(cb_arg, NULL, -ENOMEM); 1393 return; 1394 } 1395 1396 newlvol = lvol_alloc(lvs, clone_name, true, (enum lvol_clear_method)origlvol->clear_method); 1397 if (!newlvol) { 1398 SPDK_ERRLOG("Cannot alloc memory for lvol base pointer\n"); 1399 free(req); 1400 cb_fn(cb_arg, NULL, -ENOMEM); 1401 return; 1402 } 1403 1404 clone_xattrs.count = SPDK_COUNTOF(xattr_names); 1405 clone_xattrs.ctx = newlvol; 1406 clone_xattrs.names = xattr_names; 1407 clone_xattrs.get_value = lvol_get_xattr_value; 1408 req->lvol = newlvol; 1409 req->cb_fn = cb_fn; 1410 req->cb_arg = cb_arg; 1411 1412 spdk_bs_create_clone(lvs->blobstore, spdk_blob_get_id(origblob), &clone_xattrs, 1413 lvol_create_cb, 1414 req); 1415 } 1416 1417 static void 1418 lvol_resize_done(void *cb_arg, int lvolerrno) 1419 { 1420 struct spdk_lvol_req *req = cb_arg; 1421 1422 req->cb_fn(req->cb_arg, lvolerrno); 1423 free(req); 1424 } 1425 1426 static void 1427 lvol_blob_resize_cb(void *cb_arg, int bserrno) 1428 { 1429 struct spdk_lvol_req *req = cb_arg; 1430 struct spdk_lvol *lvol = req->lvol; 1431 1432 if (bserrno != 0) { 1433 req->cb_fn(req->cb_arg, bserrno); 1434 free(req); 1435 return; 1436 } 1437 1438 spdk_blob_sync_md(lvol->blob, lvol_resize_done, req); 1439 } 1440 1441 void 1442 spdk_lvol_resize(struct spdk_lvol *lvol, uint64_t sz, 1443 spdk_lvol_op_complete cb_fn, void *cb_arg) 1444 { 1445 struct spdk_blob *blob = lvol->blob; 1446 struct spdk_lvol_store *lvs = lvol->lvol_store; 1447 struct spdk_lvol_req *req; 1448 uint64_t new_clusters = spdk_divide_round_up(sz, spdk_bs_get_cluster_size(lvs->blobstore)); 1449 1450 req = calloc(1, sizeof(*req)); 1451 if (!req) { 1452 SPDK_ERRLOG("Cannot alloc memory for lvol request pointer\n"); 1453 cb_fn(cb_arg, -ENOMEM); 1454 return; 1455 } 1456 req->cb_fn = cb_fn; 1457 req->cb_arg = cb_arg; 1458 req->lvol = lvol; 1459 1460 spdk_blob_resize(blob, new_clusters, lvol_blob_resize_cb, req); 1461 } 1462 1463 static void 1464 lvol_set_read_only_cb(void *cb_arg, int lvolerrno) 1465 { 1466 struct spdk_lvol_req *req = cb_arg; 1467 1468 req->cb_fn(req->cb_arg, lvolerrno); 1469 free(req); 1470 } 1471 1472 void 1473 spdk_lvol_set_read_only(struct spdk_lvol *lvol, spdk_lvol_op_complete cb_fn, void *cb_arg) 1474 { 1475 struct spdk_lvol_req *req; 1476 1477 req = calloc(1, sizeof(*req)); 1478 if (!req) { 1479 SPDK_ERRLOG("Cannot alloc memory for lvol request pointer\n"); 1480 cb_fn(cb_arg, -ENOMEM); 1481 return; 1482 } 1483 req->cb_fn = cb_fn; 1484 req->cb_arg = cb_arg; 1485 1486 spdk_blob_set_read_only(lvol->blob); 1487 spdk_blob_sync_md(lvol->blob, lvol_set_read_only_cb, req); 1488 } 1489 1490 static void 1491 lvol_rename_cb(void *cb_arg, int lvolerrno) 1492 { 1493 struct spdk_lvol_req *req = cb_arg; 1494 1495 if (lvolerrno != 0) { 1496 SPDK_ERRLOG("Lvol rename operation failed\n"); 1497 } else { 1498 snprintf(req->lvol->name, sizeof(req->lvol->name), "%s", req->name); 1499 } 1500 1501 req->cb_fn(req->cb_arg, lvolerrno); 1502 free(req); 1503 } 1504 1505 void 1506 spdk_lvol_rename(struct spdk_lvol *lvol, const char *new_name, 1507 spdk_lvol_op_complete cb_fn, void *cb_arg) 1508 { 1509 struct spdk_lvol *tmp; 1510 struct spdk_blob *blob = lvol->blob; 1511 struct spdk_lvol_req *req; 1512 int rc; 1513 1514 /* Check if new name is current lvol name. 1515 * If so, return success immediately */ 1516 if (strncmp(lvol->name, new_name, SPDK_LVOL_NAME_MAX) == 0) { 1517 cb_fn(cb_arg, 0); 1518 return; 1519 } 1520 1521 /* Check if lvol with 'new_name' already exists in lvolstore */ 1522 TAILQ_FOREACH(tmp, &lvol->lvol_store->lvols, link) { 1523 if (strncmp(tmp->name, new_name, SPDK_LVOL_NAME_MAX) == 0) { 1524 SPDK_ERRLOG("Lvol %s already exists in lvol store %s\n", new_name, lvol->lvol_store->name); 1525 cb_fn(cb_arg, -EEXIST); 1526 return; 1527 } 1528 } 1529 1530 req = calloc(1, sizeof(*req)); 1531 if (!req) { 1532 SPDK_ERRLOG("Cannot alloc memory for lvol request pointer\n"); 1533 cb_fn(cb_arg, -ENOMEM); 1534 return; 1535 } 1536 req->cb_fn = cb_fn; 1537 req->cb_arg = cb_arg; 1538 req->lvol = lvol; 1539 snprintf(req->name, sizeof(req->name), "%s", new_name); 1540 1541 rc = spdk_blob_set_xattr(blob, "name", new_name, strlen(new_name) + 1); 1542 if (rc < 0) { 1543 free(req); 1544 cb_fn(cb_arg, rc); 1545 return; 1546 } 1547 1548 spdk_blob_sync_md(blob, lvol_rename_cb, req); 1549 } 1550 1551 void 1552 spdk_lvol_destroy(struct spdk_lvol *lvol, spdk_lvol_op_complete cb_fn, void *cb_arg) 1553 { 1554 struct spdk_lvol_req *req; 1555 struct spdk_blob_store *bs; 1556 struct spdk_lvol_store *lvs; 1557 spdk_blob_id clone_id; 1558 size_t count = 1; 1559 int rc; 1560 1561 assert(cb_fn != NULL); 1562 1563 if (lvol == NULL) { 1564 SPDK_ERRLOG("lvol does not exist\n"); 1565 cb_fn(cb_arg, -ENODEV); 1566 return; 1567 } 1568 1569 lvs = lvol->lvol_store; 1570 1571 if (lvol->ref_count != 0) { 1572 SPDK_ERRLOG("Cannot destroy lvol %s because it is still open\n", lvol->unique_id); 1573 cb_fn(cb_arg, -EBUSY); 1574 return; 1575 } 1576 1577 req = calloc(1, sizeof(*req)); 1578 if (!req) { 1579 SPDK_ERRLOG("Cannot alloc memory for lvol request pointer\n"); 1580 cb_fn(cb_arg, -ENOMEM); 1581 return; 1582 } 1583 1584 req->cb_fn = cb_fn; 1585 req->cb_arg = cb_arg; 1586 req->lvol = lvol; 1587 bs = lvol->lvol_store->blobstore; 1588 1589 rc = spdk_blob_get_clones(lvs->blobstore, lvol->blob_id, &clone_id, &count); 1590 if (rc == 0 && count == 1) { 1591 req->clone_lvol = lvs_get_lvol_by_blob_id(lvs, clone_id); 1592 } else if (rc == -ENOMEM) { 1593 SPDK_INFOLOG(lvol, "lvol %s: cannot destroy: has %" PRIu64 " clones\n", 1594 lvol->unique_id, count); 1595 free(req); 1596 assert(count > 1); 1597 cb_fn(cb_arg, -EBUSY); 1598 return; 1599 } 1600 1601 lvol->action_in_progress = true; 1602 1603 spdk_bs_delete_blob(bs, lvol->blob_id, lvol_delete_blob_cb, req); 1604 } 1605 1606 void 1607 spdk_lvol_close(struct spdk_lvol *lvol, spdk_lvol_op_complete cb_fn, void *cb_arg) 1608 { 1609 struct spdk_lvol_req *req; 1610 1611 assert(cb_fn != NULL); 1612 1613 if (lvol == NULL) { 1614 SPDK_ERRLOG("lvol does not exist\n"); 1615 cb_fn(cb_arg, -ENODEV); 1616 return; 1617 } 1618 1619 if (lvol->ref_count > 1) { 1620 lvol->ref_count--; 1621 cb_fn(cb_arg, 0); 1622 return; 1623 } else if (lvol->ref_count == 0) { 1624 cb_fn(cb_arg, -EINVAL); 1625 return; 1626 } 1627 1628 req = calloc(1, sizeof(*req)); 1629 if (!req) { 1630 SPDK_ERRLOG("Cannot alloc memory for lvol request pointer\n"); 1631 cb_fn(cb_arg, -ENOMEM); 1632 return; 1633 } 1634 1635 req->cb_fn = cb_fn; 1636 req->cb_arg = cb_arg; 1637 req->lvol = lvol; 1638 1639 lvol->action_in_progress = true; 1640 1641 spdk_blob_close(lvol->blob, lvol_close_blob_cb, req); 1642 } 1643 1644 struct spdk_io_channel * 1645 spdk_lvol_get_io_channel(struct spdk_lvol *lvol) 1646 { 1647 return spdk_bs_alloc_io_channel(lvol->lvol_store->blobstore); 1648 } 1649 1650 static void 1651 lvol_inflate_cb(void *cb_arg, int lvolerrno) 1652 { 1653 struct spdk_lvol_req *req = cb_arg; 1654 1655 spdk_bs_free_io_channel(req->channel); 1656 1657 if (lvolerrno < 0) { 1658 SPDK_ERRLOG("Could not inflate lvol\n"); 1659 } 1660 1661 req->cb_fn(req->cb_arg, lvolerrno); 1662 free(req); 1663 } 1664 1665 void 1666 spdk_lvol_inflate(struct spdk_lvol *lvol, spdk_lvol_op_complete cb_fn, void *cb_arg) 1667 { 1668 struct spdk_lvol_req *req; 1669 spdk_blob_id blob_id; 1670 1671 assert(cb_fn != NULL); 1672 1673 if (lvol == NULL) { 1674 SPDK_ERRLOG("Lvol does not exist\n"); 1675 cb_fn(cb_arg, -ENODEV); 1676 return; 1677 } 1678 1679 req = calloc(1, sizeof(*req)); 1680 if (!req) { 1681 SPDK_ERRLOG("Cannot alloc memory for lvol request pointer\n"); 1682 cb_fn(cb_arg, -ENOMEM); 1683 return; 1684 } 1685 1686 req->cb_fn = cb_fn; 1687 req->cb_arg = cb_arg; 1688 req->channel = spdk_bs_alloc_io_channel(lvol->lvol_store->blobstore); 1689 if (req->channel == NULL) { 1690 SPDK_ERRLOG("Cannot alloc io channel for lvol inflate request\n"); 1691 free(req); 1692 cb_fn(cb_arg, -ENOMEM); 1693 return; 1694 } 1695 1696 blob_id = spdk_blob_get_id(lvol->blob); 1697 spdk_bs_inflate_blob(lvol->lvol_store->blobstore, req->channel, blob_id, lvol_inflate_cb, 1698 req); 1699 } 1700 1701 void 1702 spdk_lvol_decouple_parent(struct spdk_lvol *lvol, spdk_lvol_op_complete cb_fn, void *cb_arg) 1703 { 1704 struct spdk_lvol_req *req; 1705 spdk_blob_id blob_id; 1706 1707 assert(cb_fn != NULL); 1708 1709 if (lvol == NULL) { 1710 SPDK_ERRLOG("Lvol does not exist\n"); 1711 cb_fn(cb_arg, -ENODEV); 1712 return; 1713 } 1714 1715 req = calloc(1, sizeof(*req)); 1716 if (!req) { 1717 SPDK_ERRLOG("Cannot alloc memory for lvol request pointer\n"); 1718 cb_fn(cb_arg, -ENOMEM); 1719 return; 1720 } 1721 1722 req->cb_fn = cb_fn; 1723 req->cb_arg = cb_arg; 1724 req->channel = spdk_bs_alloc_io_channel(lvol->lvol_store->blobstore); 1725 if (req->channel == NULL) { 1726 SPDK_ERRLOG("Cannot alloc io channel for lvol inflate request\n"); 1727 free(req); 1728 cb_fn(cb_arg, -ENOMEM); 1729 return; 1730 } 1731 1732 blob_id = spdk_blob_get_id(lvol->blob); 1733 spdk_bs_blob_decouple_parent(lvol->lvol_store->blobstore, req->channel, blob_id, 1734 lvol_inflate_cb, req); 1735 } 1736 1737 static void 1738 lvs_grow_live_cb(void *cb_arg, int lvolerrno) 1739 { 1740 struct spdk_lvs_req *req = (struct spdk_lvs_req *)cb_arg; 1741 1742 if (req->cb_fn) { 1743 req->cb_fn(req->cb_arg, lvolerrno); 1744 } 1745 free(req); 1746 return; 1747 } 1748 1749 void 1750 spdk_lvs_grow_live(struct spdk_lvol_store *lvs, spdk_lvs_op_complete cb_fn, void *cb_arg) 1751 { 1752 struct spdk_lvs_req *req; 1753 1754 req = calloc(1, sizeof(*req)); 1755 if (req == NULL) { 1756 SPDK_ERRLOG("Cannot alloc memory for request structure\n"); 1757 if (cb_fn) { 1758 cb_fn(cb_arg, -ENOMEM); 1759 } 1760 return; 1761 } 1762 1763 req->cb_fn = cb_fn; 1764 req->cb_arg = cb_arg; 1765 req->lvol_store = lvs; 1766 1767 spdk_bs_grow_live(lvs->blobstore, lvs_grow_live_cb, req); 1768 } 1769 1770 void 1771 spdk_lvs_grow(struct spdk_bs_dev *bs_dev, spdk_lvs_op_with_handle_complete cb_fn, void *cb_arg) 1772 { 1773 struct spdk_lvs_with_handle_req *req; 1774 struct spdk_bs_opts opts = {}; 1775 1776 assert(cb_fn != NULL); 1777 1778 if (bs_dev == NULL) { 1779 SPDK_ERRLOG("Blobstore device does not exist\n"); 1780 cb_fn(cb_arg, NULL, -ENODEV); 1781 return; 1782 } 1783 1784 req = calloc(1, sizeof(*req)); 1785 if (req == NULL) { 1786 SPDK_ERRLOG("Cannot alloc memory for request structure\n"); 1787 cb_fn(cb_arg, NULL, -ENOMEM); 1788 return; 1789 } 1790 1791 req->lvol_store = lvs_alloc(); 1792 if (req->lvol_store == NULL) { 1793 SPDK_ERRLOG("Cannot alloc memory for lvol store\n"); 1794 free(req); 1795 cb_fn(cb_arg, NULL, -ENOMEM); 1796 return; 1797 } 1798 req->cb_fn = cb_fn; 1799 req->cb_arg = cb_arg; 1800 req->bs_dev = bs_dev; 1801 1802 lvs_bs_opts_init(&opts); 1803 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "LVOLSTORE"); 1804 1805 spdk_bs_grow(bs_dev, &opts, lvs_load_cb, req); 1806 } 1807 1808 static struct spdk_lvol * 1809 lvs_get_lvol_by_blob_id(struct spdk_lvol_store *lvs, spdk_blob_id blob_id) 1810 { 1811 struct spdk_lvol *lvol; 1812 1813 TAILQ_FOREACH(lvol, &lvs->lvols, link) { 1814 if (lvol->blob_id == blob_id) { 1815 return lvol; 1816 } 1817 } 1818 return NULL; 1819 } 1820 1821 static int 1822 lvs_esnap_bs_dev_create(void *bs_ctx, void *blob_ctx, struct spdk_blob *blob, 1823 const void *esnap_id, uint32_t id_len, 1824 struct spdk_bs_dev **bs_dev) 1825 { 1826 struct spdk_lvol_store *lvs = bs_ctx; 1827 struct spdk_lvol *lvol = blob_ctx; 1828 spdk_blob_id blob_id = spdk_blob_get_id(blob); 1829 1830 if (lvs == NULL) { 1831 if (lvol == NULL || lvol->lvol_store == NULL) { 1832 SPDK_ERRLOG("Blob 0x%" PRIx64 ": no lvs context nor lvol context\n", 1833 blob_id); 1834 return -EINVAL; 1835 } 1836 lvs = lvol->lvol_store; 1837 } 1838 1839 /* 1840 * When spdk_lvs_load() is called, it iterates through all blobs in its blobstore building 1841 * up a list of lvols (lvs->lvols). During this initial iteration, each blob is opened, 1842 * passed to load_next_lvol(), then closed. There is no need to open the external snapshot 1843 * during this phase. Once the blobstore is loaded, lvs->load_esnaps is set to true so that 1844 * future lvol opens cause the external snapshot to be loaded. 1845 */ 1846 if (!lvs->load_esnaps) { 1847 *bs_dev = NULL; 1848 return 0; 1849 } 1850 1851 if (lvol == NULL) { 1852 spdk_blob_id blob_id = spdk_blob_get_id(blob); 1853 1854 /* 1855 * If spdk_bs_blob_open() is used instead of spdk_bs_blob_open_ext() the lvol will 1856 * not have been passed in. The same is true if the open happens spontaneously due 1857 * to blobstore activity. 1858 */ 1859 lvol = lvs_get_lvol_by_blob_id(lvs, blob_id); 1860 if (lvol == NULL) { 1861 SPDK_ERRLOG("lvstore %s: no lvol for blob 0x%" PRIx64 "\n", 1862 lvs->name, blob_id); 1863 return -ENODEV; 1864 } 1865 } 1866 1867 return lvs->esnap_bs_dev_create(lvs, lvol, blob, esnap_id, id_len, bs_dev); 1868 } 1869 1870 /* 1871 * The theory of missing external snapshots 1872 * 1873 * The lvs->esnap_bs_dev_create() callback may be unable to create an external snapshot bs_dev when 1874 * it is called. This can happen, for instance, as when the device containing the lvolstore is 1875 * examined prior to spdk_bdev_register() being called on a bdev that acts as an external snapshot. 1876 * In such a case, the esnap_bs_dev_create() callback will call spdk_lvs_esnap_missing_add(). 1877 * 1878 * Missing external snapshots are tracked in a per-lvolstore tree, lvs->degraded_lvol_sets_tree. 1879 * Each tree node (struct spdk_lvs_degraded_lvol_set) contains a tailq of lvols that are missing 1880 * that particular external snapshot. 1881 * 1882 * When a potential missing snapshot becomes available, spdk_lvs_notify_hotplug() may be called to 1883 * notify this library that it is available. It will then iterate through the active lvolstores and 1884 * search each lvs->degraded_lvol_sets_tree for a set of degraded lvols that are missing an external 1885 * snapshot matching the id passed in the notification. The lvols in the tailq on each matching tree 1886 * node are then asked to create an external snapshot bs_dev using the esnap_bs_dev_create() 1887 * callback that the consumer registered with the lvolstore. If lvs->esnap_bs_dev_create() returns 1888 * 0, the lvol is removed from the spdk_lvs_degraded_lvol_set's lvol tailq. When this tailq becomes 1889 * empty, the degraded lvol set node for this missing external snapshot is removed. 1890 */ 1891 static int 1892 lvs_esnap_name_cmp(struct spdk_lvs_degraded_lvol_set *m1, struct spdk_lvs_degraded_lvol_set *m2) 1893 { 1894 if (m1->id_len == m2->id_len) { 1895 return memcmp(m1->esnap_id, m2->esnap_id, m1->id_len); 1896 } 1897 return (m1->id_len > m2->id_len) ? 1 : -1; 1898 } 1899 1900 RB_GENERATE_STATIC(degraded_lvol_sets_tree, spdk_lvs_degraded_lvol_set, node, lvs_esnap_name_cmp) 1901 1902 static void 1903 lvs_degraded_lvol_set_add(struct spdk_lvs_degraded_lvol_set *degraded_set, struct spdk_lvol *lvol) 1904 { 1905 assert(lvol->lvol_store->thread == spdk_get_thread()); 1906 1907 lvol->degraded_set = degraded_set; 1908 TAILQ_INSERT_TAIL(°raded_set->lvols, lvol, degraded_link); 1909 } 1910 1911 static void 1912 lvs_degraded_lvol_set_remove(struct spdk_lvs_degraded_lvol_set *degraded_set, 1913 struct spdk_lvol *lvol) 1914 { 1915 assert(lvol->lvol_store->thread == spdk_get_thread()); 1916 1917 lvol->degraded_set = NULL; 1918 TAILQ_REMOVE(°raded_set->lvols, lvol, degraded_link); 1919 /* degraded_set->lvols may be empty. Caller should check if not immediately adding a new 1920 * lvol. */ 1921 } 1922 1923 /* 1924 * Record in lvs->degraded_lvol_sets_tree that a bdev of the specified name is needed by the 1925 * specified lvol. 1926 */ 1927 int 1928 spdk_lvs_esnap_missing_add(struct spdk_lvol_store *lvs, struct spdk_lvol *lvol, 1929 const void *esnap_id, uint32_t id_len) 1930 { 1931 struct spdk_lvs_degraded_lvol_set find, *degraded_set; 1932 1933 assert(lvs->thread == spdk_get_thread()); 1934 1935 find.esnap_id = esnap_id; 1936 find.id_len = id_len; 1937 degraded_set = RB_FIND(degraded_lvol_sets_tree, &lvs->degraded_lvol_sets_tree, &find); 1938 if (degraded_set == NULL) { 1939 degraded_set = calloc(1, sizeof(*degraded_set)); 1940 if (degraded_set == NULL) { 1941 SPDK_ERRLOG("lvol %s: cannot create degraded_set node: out of memory\n", 1942 lvol->unique_id); 1943 return -ENOMEM; 1944 } 1945 degraded_set->esnap_id = calloc(1, id_len); 1946 if (degraded_set->esnap_id == NULL) { 1947 free(degraded_set); 1948 SPDK_ERRLOG("lvol %s: cannot create degraded_set node: out of memory\n", 1949 lvol->unique_id); 1950 return -ENOMEM; 1951 } 1952 memcpy((void *)degraded_set->esnap_id, esnap_id, id_len); 1953 degraded_set->id_len = id_len; 1954 degraded_set->lvol_store = lvs; 1955 TAILQ_INIT(°raded_set->lvols); 1956 RB_INSERT(degraded_lvol_sets_tree, &lvs->degraded_lvol_sets_tree, degraded_set); 1957 } 1958 1959 lvs_degraded_lvol_set_add(degraded_set, lvol); 1960 1961 return 0; 1962 } 1963 1964 /* 1965 * Remove the record of the specified lvol needing a degraded_set bdev. 1966 */ 1967 void 1968 spdk_lvs_esnap_missing_remove(struct spdk_lvol *lvol) 1969 { 1970 struct spdk_lvol_store *lvs = lvol->lvol_store; 1971 struct spdk_lvs_degraded_lvol_set *degraded_set = lvol->degraded_set; 1972 1973 assert(lvs->thread == spdk_get_thread()); 1974 1975 if (degraded_set == NULL) { 1976 return; 1977 } 1978 1979 lvs_degraded_lvol_set_remove(degraded_set, lvol); 1980 1981 if (!TAILQ_EMPTY(°raded_set->lvols)) { 1982 return; 1983 } 1984 1985 RB_REMOVE(degraded_lvol_sets_tree, &lvs->degraded_lvol_sets_tree, degraded_set); 1986 1987 free((char *)degraded_set->esnap_id); 1988 free(degraded_set); 1989 } 1990 1991 struct lvs_esnap_hotplug_req { 1992 struct spdk_lvol *lvol; 1993 spdk_lvol_op_with_handle_complete cb_fn; 1994 void *cb_arg; 1995 }; 1996 1997 static void 1998 lvs_esnap_hotplug_done(void *cb_arg, int bserrno) 1999 { 2000 struct lvs_esnap_hotplug_req *req = cb_arg; 2001 struct spdk_lvol *lvol = req->lvol; 2002 struct spdk_lvol_store *lvs = lvol->lvol_store; 2003 2004 if (bserrno != 0) { 2005 SPDK_ERRLOG("lvol %s/%s: failed to hotplug blob_bdev due to error %d\n", 2006 lvs->name, lvol->name, bserrno); 2007 } 2008 req->cb_fn(req->cb_arg, lvol, bserrno); 2009 free(req); 2010 } 2011 2012 static void 2013 lvs_esnap_degraded_hotplug(struct spdk_lvs_degraded_lvol_set *degraded_set, 2014 spdk_lvol_op_with_handle_complete cb_fn, void *cb_arg) 2015 { 2016 struct spdk_lvol_store *lvs = degraded_set->lvol_store; 2017 struct spdk_lvol *lvol, *tmp, *last_missing; 2018 struct spdk_bs_dev *bs_dev; 2019 const void *esnap_id = degraded_set->esnap_id; 2020 uint32_t id_len = degraded_set->id_len; 2021 struct lvs_esnap_hotplug_req *req; 2022 int rc; 2023 2024 assert(lvs->thread == spdk_get_thread()); 2025 2026 /* 2027 * When lvs->esnap_bs_bdev_create() tries to load an external snapshot, it can encounter 2028 * errors that lead it to calling spdk_lvs_esnap_missing_add(). This function needs to be 2029 * sure that such modifications do not lead to degraded_set->lvols tailqs or references 2030 * to memory that this function will free. 2031 * 2032 * While this function is running, no other thread can add items to degraded_set->lvols. If 2033 * the list is mutated, it must have been done by this function or something in its call 2034 * graph running on this thread. 2035 */ 2036 2037 /* Remember the last lvol on the list. Iteration will stop once it has been processed. */ 2038 last_missing = TAILQ_LAST(°raded_set->lvols, degraded_lvols); 2039 2040 TAILQ_FOREACH_SAFE(lvol, °raded_set->lvols, degraded_link, tmp) { 2041 req = calloc(1, sizeof(*req)); 2042 if (req == NULL) { 2043 SPDK_ERRLOG("lvol %s: failed to create esnap bs_dev: out of memory\n", 2044 lvol->unique_id); 2045 cb_fn(cb_arg, lvol, -ENOMEM); 2046 /* The next one likely won't succeed either, but keep going so that all the 2047 * failed hotplugs are logged. 2048 */ 2049 goto next; 2050 } 2051 2052 /* 2053 * Remove the lvol from the tailq so that tailq corruption is avoided if 2054 * lvs->esnap_bs_dev_create() calls spdk_lvs_esnap_missing_add(lvol). 2055 */ 2056 TAILQ_REMOVE(°raded_set->lvols, lvol, degraded_link); 2057 lvol->degraded_set = NULL; 2058 2059 bs_dev = NULL; 2060 rc = lvs->esnap_bs_dev_create(lvs, lvol, lvol->blob, esnap_id, id_len, &bs_dev); 2061 if (rc != 0) { 2062 SPDK_ERRLOG("lvol %s: failed to create esnap bs_dev: error %d\n", 2063 lvol->unique_id, rc); 2064 lvol->degraded_set = degraded_set; 2065 TAILQ_INSERT_TAIL(°raded_set->lvols, lvol, degraded_link); 2066 cb_fn(cb_arg, lvol, rc); 2067 free(req); 2068 goto next; 2069 } 2070 2071 req->lvol = lvol; 2072 req->cb_fn = cb_fn; 2073 req->cb_arg = cb_arg; 2074 spdk_blob_set_esnap_bs_dev(lvol->blob, bs_dev, lvs_esnap_hotplug_done, req); 2075 2076 next: 2077 if (lvol == last_missing) { 2078 /* 2079 * Anything after last_missing was added due to some problem encountered 2080 * while trying to create the esnap bs_dev. 2081 */ 2082 break; 2083 } 2084 } 2085 2086 if (TAILQ_EMPTY(°raded_set->lvols)) { 2087 RB_REMOVE(degraded_lvol_sets_tree, &lvs->degraded_lvol_sets_tree, degraded_set); 2088 free((void *)degraded_set->esnap_id); 2089 free(degraded_set); 2090 } 2091 } 2092 2093 /* 2094 * Notify each lvstore created on this thread that is missing a bdev by the specified name or uuid 2095 * that the bdev now exists. 2096 */ 2097 bool 2098 spdk_lvs_notify_hotplug(const void *esnap_id, uint32_t id_len, 2099 spdk_lvol_op_with_handle_complete cb_fn, void *cb_arg) 2100 { 2101 struct spdk_lvs_degraded_lvol_set *found; 2102 struct spdk_lvs_degraded_lvol_set find = { 0 }; 2103 struct spdk_lvol_store *lvs; 2104 struct spdk_thread *thread = spdk_get_thread(); 2105 bool ret = false; 2106 2107 find.esnap_id = esnap_id; 2108 find.id_len = id_len; 2109 2110 pthread_mutex_lock(&g_lvol_stores_mutex); 2111 TAILQ_FOREACH(lvs, &g_lvol_stores, link) { 2112 if (thread != lvs->thread) { 2113 /* 2114 * It is expected that this is called from vbdev_lvol's examine_config() 2115 * callback. The lvstore was likely loaded do a creation happening as a 2116 * result of an RPC call or opening of an existing lvstore via 2117 * examine_disk() callback. RPC calls, examine_disk(), and examine_config() 2118 * should all be happening only on the app thread. The "wrong thread" 2119 * condition will only happen when an application is doing something weird. 2120 */ 2121 SPDK_NOTICELOG("Discarded examine for lvstore %s: wrong thread\n", 2122 lvs->name); 2123 continue; 2124 } 2125 2126 found = RB_FIND(degraded_lvol_sets_tree, &lvs->degraded_lvol_sets_tree, &find); 2127 if (found == NULL) { 2128 continue; 2129 } 2130 2131 ret = true; 2132 lvs_esnap_degraded_hotplug(found, cb_fn, cb_arg); 2133 } 2134 pthread_mutex_unlock(&g_lvol_stores_mutex); 2135 2136 return ret; 2137 } 2138 2139 int 2140 spdk_lvol_iter_immediate_clones(struct spdk_lvol *lvol, spdk_lvol_iter_cb cb_fn, void *cb_arg) 2141 { 2142 struct spdk_lvol_store *lvs = lvol->lvol_store; 2143 struct spdk_blob_store *bs = lvs->blobstore; 2144 struct spdk_lvol *clone; 2145 spdk_blob_id *ids; 2146 size_t id_cnt = 0; 2147 size_t i; 2148 int rc; 2149 2150 rc = spdk_blob_get_clones(bs, lvol->blob_id, NULL, &id_cnt); 2151 if (rc != -ENOMEM) { 2152 /* -ENOMEM says id_cnt is valid, no other errors should be returned. */ 2153 assert(rc == 0); 2154 return rc; 2155 } 2156 2157 ids = calloc(id_cnt, sizeof(*ids)); 2158 if (ids == NULL) { 2159 SPDK_ERRLOG("lvol %s: out of memory while iterating clones\n", lvol->unique_id); 2160 return -ENOMEM; 2161 } 2162 2163 rc = spdk_blob_get_clones(bs, lvol->blob_id, ids, &id_cnt); 2164 if (rc != 0) { 2165 SPDK_ERRLOG("lvol %s: unable to get clone blob IDs: %d\n", lvol->unique_id, rc); 2166 free(ids); 2167 return rc; 2168 } 2169 2170 for (i = 0; i < id_cnt; i++) { 2171 clone = lvs_get_lvol_by_blob_id(lvs, ids[i]); 2172 if (clone == NULL) { 2173 SPDK_NOTICELOG("lvol %s: unable to find clone lvol with blob id 0x%" 2174 PRIx64 "\n", lvol->unique_id, ids[i]); 2175 continue; 2176 } 2177 rc = cb_fn(cb_arg, clone); 2178 if (rc != 0) { 2179 SPDK_DEBUGLOG(lvol, "lvol %s: iteration stopped when lvol %s (blob 0x%" 2180 PRIx64 ") returned %d\n", lvol->unique_id, clone->unique_id, 2181 ids[i], rc); 2182 break; 2183 } 2184 } 2185 2186 free(ids); 2187 return rc; 2188 } 2189 2190 struct spdk_lvol * 2191 spdk_lvol_get_by_uuid(const struct spdk_uuid *uuid) 2192 { 2193 struct spdk_lvol_store *lvs; 2194 struct spdk_lvol *lvol; 2195 2196 pthread_mutex_lock(&g_lvol_stores_mutex); 2197 2198 TAILQ_FOREACH(lvs, &g_lvol_stores, link) { 2199 TAILQ_FOREACH(lvol, &lvs->lvols, link) { 2200 if (spdk_uuid_compare(uuid, &lvol->uuid) == 0) { 2201 pthread_mutex_unlock(&g_lvol_stores_mutex); 2202 return lvol; 2203 } 2204 } 2205 } 2206 2207 pthread_mutex_unlock(&g_lvol_stores_mutex); 2208 return NULL; 2209 } 2210 2211 struct spdk_lvol * 2212 spdk_lvol_get_by_names(const char *lvs_name, const char *lvol_name) 2213 { 2214 struct spdk_lvol_store *lvs; 2215 struct spdk_lvol *lvol; 2216 2217 pthread_mutex_lock(&g_lvol_stores_mutex); 2218 2219 TAILQ_FOREACH(lvs, &g_lvol_stores, link) { 2220 if (strcmp(lvs_name, lvs->name) != 0) { 2221 continue; 2222 } 2223 TAILQ_FOREACH(lvol, &lvs->lvols, link) { 2224 if (strcmp(lvol_name, lvol->name) == 0) { 2225 pthread_mutex_unlock(&g_lvol_stores_mutex); 2226 return lvol; 2227 } 2228 } 2229 } 2230 2231 pthread_mutex_unlock(&g_lvol_stores_mutex); 2232 return NULL; 2233 } 2234 2235 bool 2236 spdk_lvol_is_degraded(const struct spdk_lvol *lvol) 2237 { 2238 struct spdk_blob *blob = lvol->blob; 2239 2240 if (blob == NULL) { 2241 return true; 2242 } 2243 return spdk_blob_is_degraded(blob); 2244 } 2245 2246 static void 2247 lvol_shallow_copy_cb(void *cb_arg, int lvolerrno) 2248 { 2249 struct spdk_lvol_copy_req *req = cb_arg; 2250 struct spdk_lvol *lvol = req->lvol; 2251 2252 spdk_bs_free_io_channel(req->channel); 2253 2254 if (lvolerrno < 0) { 2255 SPDK_ERRLOG("Could not make a shallow copy of lvol %s, error %d\n", lvol->unique_id, lvolerrno); 2256 } 2257 2258 req->cb_fn(req->cb_arg, lvolerrno); 2259 free(req); 2260 } 2261 2262 int 2263 spdk_lvol_shallow_copy(struct spdk_lvol *lvol, struct spdk_bs_dev *ext_dev, 2264 spdk_blob_shallow_copy_status status_cb_fn, void *status_cb_arg, 2265 spdk_lvol_op_complete cb_fn, void *cb_arg) 2266 { 2267 struct spdk_lvol_copy_req *req; 2268 spdk_blob_id blob_id; 2269 int rc; 2270 2271 assert(cb_fn != NULL); 2272 2273 if (lvol == NULL) { 2274 SPDK_ERRLOG("lvol must not be NULL\n"); 2275 return -EINVAL; 2276 } 2277 2278 assert(lvol->lvol_store->thread == spdk_get_thread()); 2279 2280 if (ext_dev == NULL) { 2281 SPDK_ERRLOG("lvol %s shallow copy, ext_dev must not be NULL\n", lvol->unique_id); 2282 return -EINVAL; 2283 } 2284 2285 req = calloc(1, sizeof(*req)); 2286 if (!req) { 2287 SPDK_ERRLOG("lvol %s shallow copy, cannot alloc memory for lvol request\n", lvol->unique_id); 2288 return -ENOMEM; 2289 } 2290 2291 req->lvol = lvol; 2292 req->cb_fn = cb_fn; 2293 req->cb_arg = cb_arg; 2294 req->channel = spdk_bs_alloc_io_channel(lvol->lvol_store->blobstore); 2295 if (req->channel == NULL) { 2296 SPDK_ERRLOG("lvol %s shallow copy, cannot alloc io channel for lvol request\n", lvol->unique_id); 2297 free(req); 2298 return -ENOMEM; 2299 } 2300 2301 blob_id = spdk_blob_get_id(lvol->blob); 2302 2303 rc = spdk_bs_blob_shallow_copy(lvol->lvol_store->blobstore, req->channel, blob_id, ext_dev, 2304 status_cb_fn, status_cb_arg, lvol_shallow_copy_cb, req); 2305 2306 if (rc < 0) { 2307 SPDK_ERRLOG("Could not make a shallow copy of lvol %s\n", lvol->unique_id); 2308 spdk_bs_free_io_channel(req->channel); 2309 free(req); 2310 } 2311 2312 return rc; 2313 } 2314 2315 static void 2316 lvol_set_parent_cb(void *cb_arg, int lvolerrno) 2317 { 2318 struct spdk_lvol_req *req = cb_arg; 2319 2320 if (lvolerrno < 0) { 2321 SPDK_ERRLOG("could not set parent of lvol %s, error %d\n", req->lvol->name, lvolerrno); 2322 } 2323 2324 req->cb_fn(req->cb_arg, lvolerrno); 2325 free(req); 2326 } 2327 2328 void 2329 spdk_lvol_set_parent(struct spdk_lvol *lvol, struct spdk_lvol *snapshot, 2330 spdk_lvol_op_complete cb_fn, void *cb_arg) 2331 { 2332 struct spdk_lvol_req *req; 2333 spdk_blob_id blob_id, snapshot_id; 2334 2335 assert(cb_fn != NULL); 2336 2337 if (lvol == NULL) { 2338 SPDK_ERRLOG("lvol must not be NULL\n"); 2339 cb_fn(cb_arg, -EINVAL); 2340 return; 2341 } 2342 2343 if (snapshot == NULL) { 2344 SPDK_ERRLOG("snapshot must not be NULL\n"); 2345 cb_fn(cb_arg, -EINVAL); 2346 return; 2347 } 2348 2349 req = calloc(1, sizeof(*req)); 2350 if (!req) { 2351 SPDK_ERRLOG("cannot alloc memory for lvol request pointer\n"); 2352 cb_fn(cb_arg, -ENOMEM); 2353 return; 2354 } 2355 2356 req->lvol = lvol; 2357 req->cb_fn = cb_fn; 2358 req->cb_arg = cb_arg; 2359 2360 blob_id = spdk_blob_get_id(lvol->blob); 2361 snapshot_id = spdk_blob_get_id(snapshot->blob); 2362 2363 spdk_bs_blob_set_parent(lvol->lvol_store->blobstore, blob_id, snapshot_id, 2364 lvol_set_parent_cb, req); 2365 } 2366 2367 static void 2368 lvol_set_external_parent_cb(void *cb_arg, int lvolerrno) 2369 { 2370 struct spdk_lvol_bs_dev_req *req = cb_arg; 2371 2372 if (lvolerrno < 0) { 2373 SPDK_ERRLOG("could not set external parent of lvol %s, error %d\n", req->lvol->name, lvolerrno); 2374 req->bs_dev->destroy(req->bs_dev); 2375 } 2376 2377 req->cb_fn(req->cb_arg, lvolerrno); 2378 free(req); 2379 } 2380 2381 void 2382 spdk_lvol_set_external_parent(struct spdk_lvol *lvol, const void *esnap_id, uint32_t esnap_id_len, 2383 spdk_lvol_op_complete cb_fn, void *cb_arg) 2384 { 2385 struct spdk_lvol_bs_dev_req *req; 2386 struct spdk_bs_dev *bs_dev; 2387 spdk_blob_id blob_id; 2388 int rc; 2389 2390 assert(cb_fn != NULL); 2391 2392 if (lvol == NULL) { 2393 SPDK_ERRLOG("lvol must not be NULL\n"); 2394 cb_fn(cb_arg, -EINVAL); 2395 return; 2396 } 2397 2398 if (esnap_id == NULL) { 2399 SPDK_ERRLOG("snapshot must not be NULL\n"); 2400 cb_fn(cb_arg, -EINVAL); 2401 return; 2402 } 2403 2404 if (esnap_id_len == sizeof(lvol->uuid_str) && 2405 memcmp(esnap_id, lvol->uuid_str, esnap_id_len) == 0) { 2406 SPDK_ERRLOG("lvol %s and esnap have the same UUID\n", lvol->name); 2407 cb_fn(cb_arg, -EINVAL); 2408 return; 2409 } 2410 2411 rc = lvs_esnap_bs_dev_create(lvol->lvol_store, lvol, lvol->blob, esnap_id, esnap_id_len, &bs_dev); 2412 if (rc < 0) { 2413 cb_fn(cb_arg, rc); 2414 return; 2415 } 2416 2417 req = calloc(1, sizeof(*req)); 2418 if (!req) { 2419 SPDK_ERRLOG("cannot alloc memory for lvol request pointer\n"); 2420 cb_fn(cb_arg, -ENOMEM); 2421 return; 2422 } 2423 2424 req->lvol = lvol; 2425 req->bs_dev = bs_dev; 2426 req->cb_fn = cb_fn; 2427 req->cb_arg = cb_arg; 2428 2429 blob_id = spdk_blob_get_id(lvol->blob); 2430 2431 spdk_bs_blob_set_external_parent(lvol->lvol_store->blobstore, blob_id, bs_dev, esnap_id, 2432 esnap_id_len, lvol_set_external_parent_cb, req); 2433 } 2434