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 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 lvol_free(lvol); 997 goto end; 998 } 999 1000 lvol->ref_count--; 1001 lvol->action_in_progress = false; 1002 lvol->blob = NULL; 1003 SPDK_INFOLOG(lvol, "Lvol %s closed\n", lvol->unique_id); 1004 1005 end: 1006 req->cb_fn(req->cb_arg, lvolerrno); 1007 free(req); 1008 } 1009 1010 bool 1011 spdk_lvol_deletable(struct spdk_lvol *lvol) 1012 { 1013 size_t count = 0; 1014 1015 spdk_blob_get_clones(lvol->lvol_store->blobstore, lvol->blob_id, NULL, &count); 1016 return (count == 0); 1017 } 1018 1019 static void 1020 lvol_delete_blob_cb(void *cb_arg, int lvolerrno) 1021 { 1022 struct spdk_lvol_req *req = cb_arg; 1023 struct spdk_lvol *lvol = req->lvol; 1024 struct spdk_lvol *clone_lvol = req->clone_lvol; 1025 1026 if (lvolerrno < 0) { 1027 SPDK_ERRLOG("Could not remove blob on lvol gracefully - forced removal\n"); 1028 } else { 1029 SPDK_INFOLOG(lvol, "Lvol %s deleted\n", lvol->unique_id); 1030 } 1031 1032 if (lvol->degraded_set != NULL) { 1033 if (clone_lvol != NULL) { 1034 /* 1035 * A degraded esnap clone that has a blob clone has been deleted. clone_lvol 1036 * becomes an esnap clone and needs to be associated with the 1037 * spdk_lvs_degraded_lvol_set. 1038 */ 1039 struct spdk_lvs_degraded_lvol_set *degraded_set = lvol->degraded_set; 1040 1041 lvs_degraded_lvol_set_remove(degraded_set, lvol); 1042 lvs_degraded_lvol_set_add(degraded_set, clone_lvol); 1043 } else { 1044 spdk_lvs_esnap_missing_remove(lvol); 1045 } 1046 } 1047 1048 TAILQ_REMOVE(&lvol->lvol_store->lvols, lvol, link); 1049 lvol_free(lvol); 1050 req->cb_fn(req->cb_arg, lvolerrno); 1051 free(req); 1052 } 1053 1054 static void 1055 lvol_create_open_cb(void *cb_arg, struct spdk_blob *blob, int lvolerrno) 1056 { 1057 struct spdk_lvol_with_handle_req *req = cb_arg; 1058 struct spdk_lvol *lvol = req->lvol; 1059 1060 TAILQ_REMOVE(&req->lvol->lvol_store->pending_lvols, req->lvol, link); 1061 1062 if (lvolerrno < 0) { 1063 free(lvol); 1064 req->cb_fn(req->cb_arg, NULL, lvolerrno); 1065 free(req); 1066 return; 1067 } 1068 1069 lvol->blob = blob; 1070 lvol->blob_id = spdk_blob_get_id(blob); 1071 1072 TAILQ_INSERT_TAIL(&lvol->lvol_store->lvols, lvol, link); 1073 1074 lvol->ref_count++; 1075 1076 assert(req->cb_fn != NULL); 1077 req->cb_fn(req->cb_arg, req->lvol, lvolerrno); 1078 free(req); 1079 } 1080 1081 static void 1082 lvol_create_cb(void *cb_arg, spdk_blob_id blobid, int lvolerrno) 1083 { 1084 struct spdk_lvol_with_handle_req *req = cb_arg; 1085 struct spdk_blob_store *bs; 1086 struct spdk_blob_open_opts opts; 1087 1088 if (lvolerrno < 0) { 1089 TAILQ_REMOVE(&req->lvol->lvol_store->pending_lvols, req->lvol, link); 1090 free(req->lvol); 1091 assert(req->cb_fn != NULL); 1092 req->cb_fn(req->cb_arg, NULL, lvolerrno); 1093 free(req); 1094 return; 1095 } 1096 1097 spdk_blob_open_opts_init(&opts, sizeof(opts)); 1098 opts.clear_method = req->lvol->clear_method; 1099 /* 1100 * If the lvol that is being created is an esnap clone, the blobstore needs to be able to 1101 * pass the lvol to the esnap_bs_dev_create callback. In order for that to happen, we need 1102 * to pass it here. 1103 * 1104 * This does set ensap_ctx in cases where it's not needed, but we don't know that it's not 1105 * needed until after the blob is open. When the blob is not an esnap clone, a reference to 1106 * the value stored in opts.esnap_ctx is not retained by the blobstore. 1107 */ 1108 opts.esnap_ctx = req->lvol; 1109 bs = req->lvol->lvol_store->blobstore; 1110 1111 if (req->origlvol != NULL && req->origlvol->degraded_set != NULL) { 1112 /* 1113 * A snapshot was created from a degraded esnap clone. The new snapshot is now a 1114 * degraded esnap clone. The previous clone is now a regular clone of a blob. Update 1115 * the set of directly-related clones to the missing external snapshot. 1116 */ 1117 struct spdk_lvs_degraded_lvol_set *degraded_set = req->origlvol->degraded_set; 1118 1119 lvs_degraded_lvol_set_remove(degraded_set, req->origlvol); 1120 lvs_degraded_lvol_set_add(degraded_set, req->lvol); 1121 } 1122 1123 spdk_bs_open_blob_ext(bs, blobid, &opts, lvol_create_open_cb, req); 1124 } 1125 1126 static void 1127 lvol_get_xattr_value(void *xattr_ctx, const char *name, 1128 const void **value, size_t *value_len) 1129 { 1130 struct spdk_lvol *lvol = xattr_ctx; 1131 1132 if (!strcmp(LVOL_NAME, name)) { 1133 *value = lvol->name; 1134 *value_len = SPDK_LVOL_NAME_MAX; 1135 return; 1136 } 1137 if (!strcmp("uuid", name)) { 1138 *value = lvol->uuid_str; 1139 *value_len = sizeof(lvol->uuid_str); 1140 return; 1141 } 1142 *value = NULL; 1143 *value_len = 0; 1144 } 1145 1146 static int 1147 lvs_verify_lvol_name(struct spdk_lvol_store *lvs, const char *name) 1148 { 1149 struct spdk_lvol *tmp; 1150 1151 if (name == NULL || strnlen(name, SPDK_LVOL_NAME_MAX) == 0) { 1152 SPDK_INFOLOG(lvol, "lvol name not provided.\n"); 1153 return -EINVAL; 1154 } 1155 1156 if (strnlen(name, SPDK_LVOL_NAME_MAX) == SPDK_LVOL_NAME_MAX) { 1157 SPDK_ERRLOG("Name has no null terminator.\n"); 1158 return -EINVAL; 1159 } 1160 1161 TAILQ_FOREACH(tmp, &lvs->lvols, link) { 1162 if (!strncmp(name, tmp->name, SPDK_LVOL_NAME_MAX)) { 1163 SPDK_ERRLOG("lvol with name %s already exists\n", name); 1164 return -EEXIST; 1165 } 1166 } 1167 1168 TAILQ_FOREACH(tmp, &lvs->pending_lvols, link) { 1169 if (!strncmp(name, tmp->name, SPDK_LVOL_NAME_MAX)) { 1170 SPDK_ERRLOG("lvol with name %s is being already created\n", name); 1171 return -EEXIST; 1172 } 1173 } 1174 1175 return 0; 1176 } 1177 1178 int 1179 spdk_lvol_create(struct spdk_lvol_store *lvs, const char *name, uint64_t sz, 1180 bool thin_provision, enum lvol_clear_method clear_method, spdk_lvol_op_with_handle_complete cb_fn, 1181 void *cb_arg) 1182 { 1183 struct spdk_lvol_with_handle_req *req; 1184 struct spdk_blob_store *bs; 1185 struct spdk_lvol *lvol; 1186 struct spdk_blob_opts opts; 1187 char *xattr_names[] = {LVOL_NAME, "uuid"}; 1188 int rc; 1189 1190 if (lvs == NULL) { 1191 SPDK_ERRLOG("lvol store does not exist\n"); 1192 return -EINVAL; 1193 } 1194 1195 rc = lvs_verify_lvol_name(lvs, name); 1196 if (rc < 0) { 1197 return rc; 1198 } 1199 1200 bs = lvs->blobstore; 1201 1202 req = calloc(1, sizeof(*req)); 1203 if (!req) { 1204 SPDK_ERRLOG("Cannot alloc memory for lvol request pointer\n"); 1205 return -ENOMEM; 1206 } 1207 req->cb_fn = cb_fn; 1208 req->cb_arg = cb_arg; 1209 1210 lvol = lvol_alloc(lvs, name, thin_provision, clear_method); 1211 if (!lvol) { 1212 free(req); 1213 SPDK_ERRLOG("Cannot alloc memory for lvol base pointer\n"); 1214 return -ENOMEM; 1215 } 1216 1217 req->lvol = lvol; 1218 spdk_blob_opts_init(&opts, sizeof(opts)); 1219 opts.thin_provision = thin_provision; 1220 opts.num_clusters = spdk_divide_round_up(sz, spdk_bs_get_cluster_size(bs)); 1221 opts.clear_method = lvol->clear_method; 1222 opts.xattrs.count = SPDK_COUNTOF(xattr_names); 1223 opts.xattrs.names = xattr_names; 1224 opts.xattrs.ctx = lvol; 1225 opts.xattrs.get_value = lvol_get_xattr_value; 1226 1227 spdk_bs_create_blob_ext(lvs->blobstore, &opts, lvol_create_cb, req); 1228 1229 return 0; 1230 } 1231 1232 int 1233 spdk_lvol_create_esnap_clone(const void *esnap_id, uint32_t id_len, uint64_t size_bytes, 1234 struct spdk_lvol_store *lvs, const char *clone_name, 1235 spdk_lvol_op_with_handle_complete cb_fn, void *cb_arg) 1236 { 1237 struct spdk_lvol_with_handle_req *req; 1238 struct spdk_blob_store *bs; 1239 struct spdk_lvol *lvol; 1240 struct spdk_blob_opts opts; 1241 uint64_t cluster_sz; 1242 char *xattr_names[] = {LVOL_NAME, "uuid"}; 1243 int rc; 1244 1245 if (lvs == NULL) { 1246 SPDK_ERRLOG("lvol store does not exist\n"); 1247 return -EINVAL; 1248 } 1249 1250 rc = lvs_verify_lvol_name(lvs, clone_name); 1251 if (rc < 0) { 1252 return rc; 1253 } 1254 1255 bs = lvs->blobstore; 1256 1257 cluster_sz = spdk_bs_get_cluster_size(bs); 1258 if ((size_bytes % cluster_sz) != 0) { 1259 SPDK_ERRLOG("Cannot create '%s/%s': size %" PRIu64 " is not an integer multiple of " 1260 "cluster size %" PRIu64 "\n", lvs->name, clone_name, size_bytes, 1261 cluster_sz); 1262 return -EINVAL; 1263 } 1264 1265 req = calloc(1, sizeof(*req)); 1266 if (!req) { 1267 SPDK_ERRLOG("Cannot alloc memory for lvol request pointer\n"); 1268 return -ENOMEM; 1269 } 1270 req->cb_fn = cb_fn; 1271 req->cb_arg = cb_arg; 1272 1273 lvol = lvol_alloc(lvs, clone_name, true, LVOL_CLEAR_WITH_DEFAULT); 1274 if (!lvol) { 1275 free(req); 1276 SPDK_ERRLOG("Cannot alloc memory for lvol base pointer\n"); 1277 return -ENOMEM; 1278 } 1279 req->lvol = lvol; 1280 1281 spdk_blob_opts_init(&opts, sizeof(opts)); 1282 opts.esnap_id = esnap_id; 1283 opts.esnap_id_len = id_len; 1284 opts.thin_provision = true; 1285 opts.num_clusters = spdk_divide_round_up(size_bytes, cluster_sz); 1286 opts.clear_method = lvol->clear_method; 1287 opts.xattrs.count = SPDK_COUNTOF(xattr_names); 1288 opts.xattrs.names = xattr_names; 1289 opts.xattrs.ctx = lvol; 1290 opts.xattrs.get_value = lvol_get_xattr_value; 1291 1292 spdk_bs_create_blob_ext(lvs->blobstore, &opts, lvol_create_cb, req); 1293 1294 return 0; 1295 } 1296 1297 void 1298 spdk_lvol_create_snapshot(struct spdk_lvol *origlvol, const char *snapshot_name, 1299 spdk_lvol_op_with_handle_complete cb_fn, void *cb_arg) 1300 { 1301 struct spdk_lvol_store *lvs; 1302 struct spdk_lvol *newlvol; 1303 struct spdk_blob *origblob; 1304 struct spdk_lvol_with_handle_req *req; 1305 struct spdk_blob_xattr_opts snapshot_xattrs; 1306 char *xattr_names[] = {LVOL_NAME, "uuid"}; 1307 int rc; 1308 1309 if (origlvol == NULL) { 1310 SPDK_INFOLOG(lvol, "Lvol not provided.\n"); 1311 cb_fn(cb_arg, NULL, -EINVAL); 1312 return; 1313 } 1314 1315 origblob = origlvol->blob; 1316 lvs = origlvol->lvol_store; 1317 if (lvs == NULL) { 1318 SPDK_ERRLOG("lvol store does not exist\n"); 1319 cb_fn(cb_arg, NULL, -EINVAL); 1320 return; 1321 } 1322 1323 rc = lvs_verify_lvol_name(lvs, snapshot_name); 1324 if (rc < 0) { 1325 cb_fn(cb_arg, NULL, rc); 1326 return; 1327 } 1328 1329 req = calloc(1, sizeof(*req)); 1330 if (!req) { 1331 SPDK_ERRLOG("Cannot alloc memory for lvol request pointer\n"); 1332 cb_fn(cb_arg, NULL, -ENOMEM); 1333 return; 1334 } 1335 1336 newlvol = lvol_alloc(origlvol->lvol_store, snapshot_name, true, 1337 (enum lvol_clear_method)origlvol->clear_method); 1338 if (!newlvol) { 1339 SPDK_ERRLOG("Cannot alloc memory for lvol base pointer\n"); 1340 free(req); 1341 cb_fn(cb_arg, NULL, -ENOMEM); 1342 return; 1343 } 1344 1345 snapshot_xattrs.count = SPDK_COUNTOF(xattr_names); 1346 snapshot_xattrs.ctx = newlvol; 1347 snapshot_xattrs.names = xattr_names; 1348 snapshot_xattrs.get_value = lvol_get_xattr_value; 1349 req->lvol = newlvol; 1350 req->origlvol = origlvol; 1351 req->cb_fn = cb_fn; 1352 req->cb_arg = cb_arg; 1353 1354 spdk_bs_create_snapshot(lvs->blobstore, spdk_blob_get_id(origblob), &snapshot_xattrs, 1355 lvol_create_cb, req); 1356 } 1357 1358 void 1359 spdk_lvol_create_clone(struct spdk_lvol *origlvol, const char *clone_name, 1360 spdk_lvol_op_with_handle_complete cb_fn, void *cb_arg) 1361 { 1362 struct spdk_lvol *newlvol; 1363 struct spdk_lvol_with_handle_req *req; 1364 struct spdk_lvol_store *lvs; 1365 struct spdk_blob *origblob; 1366 struct spdk_blob_xattr_opts clone_xattrs; 1367 char *xattr_names[] = {LVOL_NAME, "uuid"}; 1368 int rc; 1369 1370 if (origlvol == NULL) { 1371 SPDK_INFOLOG(lvol, "Lvol not provided.\n"); 1372 cb_fn(cb_arg, NULL, -EINVAL); 1373 return; 1374 } 1375 1376 origblob = origlvol->blob; 1377 lvs = origlvol->lvol_store; 1378 if (lvs == NULL) { 1379 SPDK_ERRLOG("lvol store does not exist\n"); 1380 cb_fn(cb_arg, NULL, -EINVAL); 1381 return; 1382 } 1383 1384 rc = lvs_verify_lvol_name(lvs, clone_name); 1385 if (rc < 0) { 1386 cb_fn(cb_arg, NULL, rc); 1387 return; 1388 } 1389 1390 req = calloc(1, sizeof(*req)); 1391 if (!req) { 1392 SPDK_ERRLOG("Cannot alloc memory for lvol request pointer\n"); 1393 cb_fn(cb_arg, NULL, -ENOMEM); 1394 return; 1395 } 1396 1397 newlvol = lvol_alloc(lvs, clone_name, true, (enum lvol_clear_method)origlvol->clear_method); 1398 if (!newlvol) { 1399 SPDK_ERRLOG("Cannot alloc memory for lvol base pointer\n"); 1400 free(req); 1401 cb_fn(cb_arg, NULL, -ENOMEM); 1402 return; 1403 } 1404 1405 clone_xattrs.count = SPDK_COUNTOF(xattr_names); 1406 clone_xattrs.ctx = newlvol; 1407 clone_xattrs.names = xattr_names; 1408 clone_xattrs.get_value = lvol_get_xattr_value; 1409 req->lvol = newlvol; 1410 req->cb_fn = cb_fn; 1411 req->cb_arg = cb_arg; 1412 1413 spdk_bs_create_clone(lvs->blobstore, spdk_blob_get_id(origblob), &clone_xattrs, 1414 lvol_create_cb, 1415 req); 1416 } 1417 1418 static void 1419 lvol_resize_done(void *cb_arg, int lvolerrno) 1420 { 1421 struct spdk_lvol_req *req = cb_arg; 1422 1423 req->cb_fn(req->cb_arg, lvolerrno); 1424 free(req); 1425 } 1426 1427 static void 1428 lvol_blob_resize_cb(void *cb_arg, int bserrno) 1429 { 1430 struct spdk_lvol_req *req = cb_arg; 1431 struct spdk_lvol *lvol = req->lvol; 1432 1433 if (bserrno != 0) { 1434 req->cb_fn(req->cb_arg, bserrno); 1435 free(req); 1436 return; 1437 } 1438 1439 spdk_blob_sync_md(lvol->blob, lvol_resize_done, req); 1440 } 1441 1442 void 1443 spdk_lvol_resize(struct spdk_lvol *lvol, uint64_t sz, 1444 spdk_lvol_op_complete cb_fn, void *cb_arg) 1445 { 1446 struct spdk_blob *blob = lvol->blob; 1447 struct spdk_lvol_store *lvs = lvol->lvol_store; 1448 struct spdk_lvol_req *req; 1449 uint64_t new_clusters = spdk_divide_round_up(sz, spdk_bs_get_cluster_size(lvs->blobstore)); 1450 1451 req = calloc(1, sizeof(*req)); 1452 if (!req) { 1453 SPDK_ERRLOG("Cannot alloc memory for lvol request pointer\n"); 1454 cb_fn(cb_arg, -ENOMEM); 1455 return; 1456 } 1457 req->cb_fn = cb_fn; 1458 req->cb_arg = cb_arg; 1459 req->lvol = lvol; 1460 1461 spdk_blob_resize(blob, new_clusters, lvol_blob_resize_cb, req); 1462 } 1463 1464 static void 1465 lvol_set_read_only_cb(void *cb_arg, int lvolerrno) 1466 { 1467 struct spdk_lvol_req *req = cb_arg; 1468 1469 req->cb_fn(req->cb_arg, lvolerrno); 1470 free(req); 1471 } 1472 1473 void 1474 spdk_lvol_set_read_only(struct spdk_lvol *lvol, spdk_lvol_op_complete cb_fn, void *cb_arg) 1475 { 1476 struct spdk_lvol_req *req; 1477 1478 req = calloc(1, sizeof(*req)); 1479 if (!req) { 1480 SPDK_ERRLOG("Cannot alloc memory for lvol request pointer\n"); 1481 cb_fn(cb_arg, -ENOMEM); 1482 return; 1483 } 1484 req->cb_fn = cb_fn; 1485 req->cb_arg = cb_arg; 1486 1487 spdk_blob_set_read_only(lvol->blob); 1488 spdk_blob_sync_md(lvol->blob, lvol_set_read_only_cb, req); 1489 } 1490 1491 static void 1492 lvol_rename_cb(void *cb_arg, int lvolerrno) 1493 { 1494 struct spdk_lvol_req *req = cb_arg; 1495 1496 if (lvolerrno != 0) { 1497 SPDK_ERRLOG("Lvol rename operation failed\n"); 1498 } else { 1499 snprintf(req->lvol->name, sizeof(req->lvol->name), "%s", req->name); 1500 } 1501 1502 req->cb_fn(req->cb_arg, lvolerrno); 1503 free(req); 1504 } 1505 1506 void 1507 spdk_lvol_rename(struct spdk_lvol *lvol, const char *new_name, 1508 spdk_lvol_op_complete cb_fn, void *cb_arg) 1509 { 1510 struct spdk_lvol *tmp; 1511 struct spdk_blob *blob = lvol->blob; 1512 struct spdk_lvol_req *req; 1513 int rc; 1514 1515 /* Check if new name is current lvol name. 1516 * If so, return success immediately */ 1517 if (strncmp(lvol->name, new_name, SPDK_LVOL_NAME_MAX) == 0) { 1518 cb_fn(cb_arg, 0); 1519 return; 1520 } 1521 1522 /* Check if lvol with 'new_name' already exists in lvolstore */ 1523 TAILQ_FOREACH(tmp, &lvol->lvol_store->lvols, link) { 1524 if (strncmp(tmp->name, new_name, SPDK_LVOL_NAME_MAX) == 0) { 1525 SPDK_ERRLOG("Lvol %s already exists in lvol store %s\n", new_name, lvol->lvol_store->name); 1526 cb_fn(cb_arg, -EEXIST); 1527 return; 1528 } 1529 } 1530 1531 req = calloc(1, sizeof(*req)); 1532 if (!req) { 1533 SPDK_ERRLOG("Cannot alloc memory for lvol request pointer\n"); 1534 cb_fn(cb_arg, -ENOMEM); 1535 return; 1536 } 1537 req->cb_fn = cb_fn; 1538 req->cb_arg = cb_arg; 1539 req->lvol = lvol; 1540 snprintf(req->name, sizeof(req->name), "%s", new_name); 1541 1542 rc = spdk_blob_set_xattr(blob, "name", new_name, strlen(new_name) + 1); 1543 if (rc < 0) { 1544 free(req); 1545 cb_fn(cb_arg, rc); 1546 return; 1547 } 1548 1549 spdk_blob_sync_md(blob, lvol_rename_cb, req); 1550 } 1551 1552 void 1553 spdk_lvol_destroy(struct spdk_lvol *lvol, spdk_lvol_op_complete cb_fn, void *cb_arg) 1554 { 1555 struct spdk_lvol_req *req; 1556 struct spdk_blob_store *bs; 1557 struct spdk_lvol_store *lvs; 1558 spdk_blob_id clone_id; 1559 size_t count = 1; 1560 int rc; 1561 1562 assert(cb_fn != NULL); 1563 1564 if (lvol == NULL) { 1565 SPDK_ERRLOG("lvol does not exist\n"); 1566 cb_fn(cb_arg, -ENODEV); 1567 return; 1568 } 1569 1570 lvs = lvol->lvol_store; 1571 1572 if (lvol->ref_count != 0) { 1573 SPDK_ERRLOG("Cannot destroy lvol %s because it is still open\n", lvol->unique_id); 1574 cb_fn(cb_arg, -EBUSY); 1575 return; 1576 } 1577 1578 lvol->action_in_progress = true; 1579 1580 req = calloc(1, sizeof(*req)); 1581 if (!req) { 1582 SPDK_ERRLOG("Cannot alloc memory for lvol request pointer\n"); 1583 cb_fn(cb_arg, -ENOMEM); 1584 return; 1585 } 1586 1587 req->cb_fn = cb_fn; 1588 req->cb_arg = cb_arg; 1589 req->lvol = lvol; 1590 bs = lvol->lvol_store->blobstore; 1591 1592 rc = spdk_blob_get_clones(lvs->blobstore, lvol->blob_id, &clone_id, &count); 1593 if (rc == 0 && count == 1) { 1594 req->clone_lvol = lvs_get_lvol_by_blob_id(lvs, clone_id); 1595 } else if (rc == -ENOMEM) { 1596 SPDK_INFOLOG(lvol, "lvol %s: cannot destroy: has %" PRIu64 " clones\n", 1597 lvol->unique_id, count); 1598 free(req); 1599 assert(count > 1); 1600 cb_fn(cb_arg, -EBUSY); 1601 return; 1602 } 1603 1604 spdk_bs_delete_blob(bs, lvol->blob_id, lvol_delete_blob_cb, req); 1605 } 1606 1607 void 1608 spdk_lvol_close(struct spdk_lvol *lvol, spdk_lvol_op_complete cb_fn, void *cb_arg) 1609 { 1610 struct spdk_lvol_req *req; 1611 1612 assert(cb_fn != NULL); 1613 1614 if (lvol == NULL) { 1615 SPDK_ERRLOG("lvol does not exist\n"); 1616 cb_fn(cb_arg, -ENODEV); 1617 return; 1618 } 1619 1620 if (lvol->ref_count > 1) { 1621 lvol->ref_count--; 1622 cb_fn(cb_arg, 0); 1623 return; 1624 } else if (lvol->ref_count == 0) { 1625 cb_fn(cb_arg, -EINVAL); 1626 return; 1627 } 1628 1629 lvol->action_in_progress = true; 1630 1631 req = calloc(1, sizeof(*req)); 1632 if (!req) { 1633 SPDK_ERRLOG("Cannot alloc memory for lvol request pointer\n"); 1634 cb_fn(cb_arg, -ENOMEM); 1635 return; 1636 } 1637 1638 req->cb_fn = cb_fn; 1639 req->cb_arg = cb_arg; 1640 req->lvol = lvol; 1641 1642 spdk_blob_close(lvol->blob, lvol_close_blob_cb, req); 1643 } 1644 1645 struct spdk_io_channel * 1646 spdk_lvol_get_io_channel(struct spdk_lvol *lvol) 1647 { 1648 return spdk_bs_alloc_io_channel(lvol->lvol_store->blobstore); 1649 } 1650 1651 static void 1652 lvol_inflate_cb(void *cb_arg, int lvolerrno) 1653 { 1654 struct spdk_lvol_req *req = cb_arg; 1655 1656 spdk_bs_free_io_channel(req->channel); 1657 1658 if (lvolerrno < 0) { 1659 SPDK_ERRLOG("Could not inflate lvol\n"); 1660 } 1661 1662 req->cb_fn(req->cb_arg, lvolerrno); 1663 free(req); 1664 } 1665 1666 void 1667 spdk_lvol_inflate(struct spdk_lvol *lvol, spdk_lvol_op_complete cb_fn, void *cb_arg) 1668 { 1669 struct spdk_lvol_req *req; 1670 spdk_blob_id blob_id; 1671 1672 assert(cb_fn != NULL); 1673 1674 if (lvol == NULL) { 1675 SPDK_ERRLOG("Lvol does not exist\n"); 1676 cb_fn(cb_arg, -ENODEV); 1677 return; 1678 } 1679 1680 req = calloc(1, sizeof(*req)); 1681 if (!req) { 1682 SPDK_ERRLOG("Cannot alloc memory for lvol request pointer\n"); 1683 cb_fn(cb_arg, -ENOMEM); 1684 return; 1685 } 1686 1687 req->cb_fn = cb_fn; 1688 req->cb_arg = cb_arg; 1689 req->channel = spdk_bs_alloc_io_channel(lvol->lvol_store->blobstore); 1690 if (req->channel == NULL) { 1691 SPDK_ERRLOG("Cannot alloc io channel for lvol inflate request\n"); 1692 free(req); 1693 cb_fn(cb_arg, -ENOMEM); 1694 return; 1695 } 1696 1697 blob_id = spdk_blob_get_id(lvol->blob); 1698 spdk_bs_inflate_blob(lvol->lvol_store->blobstore, req->channel, blob_id, lvol_inflate_cb, 1699 req); 1700 } 1701 1702 void 1703 spdk_lvol_decouple_parent(struct spdk_lvol *lvol, spdk_lvol_op_complete cb_fn, void *cb_arg) 1704 { 1705 struct spdk_lvol_req *req; 1706 spdk_blob_id blob_id; 1707 1708 assert(cb_fn != NULL); 1709 1710 if (lvol == NULL) { 1711 SPDK_ERRLOG("Lvol does not exist\n"); 1712 cb_fn(cb_arg, -ENODEV); 1713 return; 1714 } 1715 1716 req = calloc(1, sizeof(*req)); 1717 if (!req) { 1718 SPDK_ERRLOG("Cannot alloc memory for lvol request pointer\n"); 1719 cb_fn(cb_arg, -ENOMEM); 1720 return; 1721 } 1722 1723 req->cb_fn = cb_fn; 1724 req->cb_arg = cb_arg; 1725 req->channel = spdk_bs_alloc_io_channel(lvol->lvol_store->blobstore); 1726 if (req->channel == NULL) { 1727 SPDK_ERRLOG("Cannot alloc io channel for lvol inflate request\n"); 1728 free(req); 1729 cb_fn(cb_arg, -ENOMEM); 1730 return; 1731 } 1732 1733 blob_id = spdk_blob_get_id(lvol->blob); 1734 spdk_bs_blob_decouple_parent(lvol->lvol_store->blobstore, req->channel, blob_id, 1735 lvol_inflate_cb, req); 1736 } 1737 1738 void 1739 spdk_lvs_grow(struct spdk_bs_dev *bs_dev, spdk_lvs_op_with_handle_complete cb_fn, void *cb_arg) 1740 { 1741 struct spdk_lvs_with_handle_req *req; 1742 struct spdk_bs_opts opts = {}; 1743 1744 assert(cb_fn != NULL); 1745 1746 if (bs_dev == NULL) { 1747 SPDK_ERRLOG("Blobstore device does not exist\n"); 1748 cb_fn(cb_arg, NULL, -ENODEV); 1749 return; 1750 } 1751 1752 req = calloc(1, sizeof(*req)); 1753 if (req == NULL) { 1754 SPDK_ERRLOG("Cannot alloc memory for request structure\n"); 1755 cb_fn(cb_arg, NULL, -ENOMEM); 1756 return; 1757 } 1758 1759 req->lvol_store = lvs_alloc(); 1760 if (req->lvol_store == NULL) { 1761 SPDK_ERRLOG("Cannot alloc memory for lvol store\n"); 1762 free(req); 1763 cb_fn(cb_arg, NULL, -ENOMEM); 1764 return; 1765 } 1766 req->cb_fn = cb_fn; 1767 req->cb_arg = cb_arg; 1768 req->bs_dev = bs_dev; 1769 1770 lvs_bs_opts_init(&opts); 1771 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "LVOLSTORE"); 1772 1773 spdk_bs_grow(bs_dev, &opts, lvs_load_cb, req); 1774 } 1775 1776 static struct spdk_lvol * 1777 lvs_get_lvol_by_blob_id(struct spdk_lvol_store *lvs, spdk_blob_id blob_id) 1778 { 1779 struct spdk_lvol *lvol; 1780 1781 TAILQ_FOREACH(lvol, &lvs->lvols, link) { 1782 if (lvol->blob_id == blob_id) { 1783 return lvol; 1784 } 1785 } 1786 return NULL; 1787 } 1788 1789 static int 1790 lvs_esnap_bs_dev_create(void *bs_ctx, void *blob_ctx, struct spdk_blob *blob, 1791 const void *esnap_id, uint32_t id_len, 1792 struct spdk_bs_dev **bs_dev) 1793 { 1794 struct spdk_lvol_store *lvs = bs_ctx; 1795 struct spdk_lvol *lvol = blob_ctx; 1796 spdk_blob_id blob_id = spdk_blob_get_id(blob); 1797 1798 if (lvs == NULL) { 1799 if (lvol == NULL) { 1800 SPDK_ERRLOG("Blob 0x%" PRIx64 ": no lvs context nor lvol context\n", 1801 blob_id); 1802 return -EINVAL; 1803 } 1804 lvs = lvol->lvol_store; 1805 } 1806 1807 /* 1808 * When spdk_lvs_load() is called, it iterates through all blobs in its blobstore building 1809 * up a list of lvols (lvs->lvols). During this initial iteration, each blob is opened, 1810 * passed to load_next_lvol(), then closed. There is no need to open the external snapshot 1811 * during this phase. Once the blobstore is loaded, lvs->load_esnaps is set to true so that 1812 * future lvol opens cause the external snapshot to be loaded. 1813 */ 1814 if (!lvs->load_esnaps) { 1815 *bs_dev = NULL; 1816 return 0; 1817 } 1818 1819 if (lvol == NULL) { 1820 spdk_blob_id blob_id = spdk_blob_get_id(blob); 1821 1822 /* 1823 * If spdk_bs_blob_open() is used instead of spdk_bs_blob_open_ext() the lvol will 1824 * not have been passed in. The same is true if the open happens spontaneously due 1825 * to blobstore activity. 1826 */ 1827 lvol = lvs_get_lvol_by_blob_id(lvs, blob_id); 1828 if (lvol == NULL) { 1829 SPDK_ERRLOG("lvstore %s: no lvol for blob 0x%" PRIx64 "\n", 1830 lvs->name, blob_id); 1831 return -ENODEV; 1832 } 1833 } 1834 1835 return lvs->esnap_bs_dev_create(lvs, lvol, blob, esnap_id, id_len, bs_dev); 1836 } 1837 1838 /* 1839 * The theory of missing external snapshots 1840 * 1841 * The lvs->esnap_bs_dev_create() callback may be unable to create an external snapshot bs_dev when 1842 * it is called. This can happen, for instance, as when the device containing the lvolstore is 1843 * examined prior to spdk_bdev_register() being called on a bdev that acts as an external snapshot. 1844 * In such a case, the esnap_bs_dev_create() callback will call spdk_lvs_esnap_missing_add(). 1845 * 1846 * Missing external snapshots are tracked in a per-lvolstore tree, lvs->degraded_lvol_sets_tree. 1847 * Each tree node (struct spdk_lvs_degraded_lvol_set) contains a tailq of lvols that are missing 1848 * that particular external snapshot. 1849 * 1850 * When a potential missing snapshot becomes available, spdk_lvs_notify_hotplug() may be called to 1851 * notify this library that it is available. It will then iterate through the active lvolstores and 1852 * search each lvs->degraded_lvol_sets_tree for a set of degraded lvols that are missing an external 1853 * snapshot matching the id passed in the notification. The lvols in the tailq on each matching tree 1854 * node are then asked to create an external snapshot bs_dev using the esnap_bs_dev_create() 1855 * callback that the consumer registered with the lvolstore. If lvs->esnap_bs_dev_create() returns 1856 * 0, the lvol is removed from the spdk_lvs_degraded_lvol_set's lvol tailq. When this tailq becomes 1857 * empty, the degraded lvol set node for this missing external snapshot is removed. 1858 */ 1859 static int 1860 lvs_esnap_name_cmp(struct spdk_lvs_degraded_lvol_set *m1, struct spdk_lvs_degraded_lvol_set *m2) 1861 { 1862 if (m1->id_len == m2->id_len) { 1863 return memcmp(m1->esnap_id, m2->esnap_id, m1->id_len); 1864 } 1865 return (m1->id_len > m2->id_len) ? 1 : -1; 1866 } 1867 1868 RB_GENERATE_STATIC(degraded_lvol_sets_tree, spdk_lvs_degraded_lvol_set, node, lvs_esnap_name_cmp) 1869 1870 static void 1871 lvs_degraded_lvol_set_add(struct spdk_lvs_degraded_lvol_set *degraded_set, struct spdk_lvol *lvol) 1872 { 1873 assert(lvol->lvol_store->thread == spdk_get_thread()); 1874 1875 lvol->degraded_set = degraded_set; 1876 TAILQ_INSERT_TAIL(°raded_set->lvols, lvol, degraded_link); 1877 } 1878 1879 static void 1880 lvs_degraded_lvol_set_remove(struct spdk_lvs_degraded_lvol_set *degraded_set, 1881 struct spdk_lvol *lvol) 1882 { 1883 assert(lvol->lvol_store->thread == spdk_get_thread()); 1884 1885 lvol->degraded_set = NULL; 1886 TAILQ_REMOVE(°raded_set->lvols, lvol, degraded_link); 1887 /* degraded_set->lvols may be empty. Caller should check if not immediately adding a new 1888 * lvol. */ 1889 } 1890 1891 /* 1892 * Record in lvs->degraded_lvol_sets_tree that a bdev of the specified name is needed by the 1893 * specified lvol. 1894 */ 1895 int 1896 spdk_lvs_esnap_missing_add(struct spdk_lvol_store *lvs, struct spdk_lvol *lvol, 1897 const void *esnap_id, uint32_t id_len) 1898 { 1899 struct spdk_lvs_degraded_lvol_set find, *degraded_set; 1900 1901 assert(lvs->thread == spdk_get_thread()); 1902 1903 find.esnap_id = esnap_id; 1904 find.id_len = id_len; 1905 degraded_set = RB_FIND(degraded_lvol_sets_tree, &lvs->degraded_lvol_sets_tree, &find); 1906 if (degraded_set == NULL) { 1907 degraded_set = calloc(1, sizeof(*degraded_set)); 1908 if (degraded_set == NULL) { 1909 SPDK_ERRLOG("lvol %s: cannot create degraded_set node: out of memory\n", 1910 lvol->unique_id); 1911 return -ENOMEM; 1912 } 1913 degraded_set->esnap_id = calloc(1, id_len); 1914 if (degraded_set->esnap_id == NULL) { 1915 free(degraded_set); 1916 SPDK_ERRLOG("lvol %s: cannot create degraded_set node: out of memory\n", 1917 lvol->unique_id); 1918 return -ENOMEM; 1919 } 1920 memcpy((void *)degraded_set->esnap_id, esnap_id, id_len); 1921 degraded_set->id_len = id_len; 1922 degraded_set->lvol_store = lvs; 1923 TAILQ_INIT(°raded_set->lvols); 1924 RB_INSERT(degraded_lvol_sets_tree, &lvs->degraded_lvol_sets_tree, degraded_set); 1925 } 1926 1927 lvs_degraded_lvol_set_add(degraded_set, lvol); 1928 1929 return 0; 1930 } 1931 1932 /* 1933 * Remove the record of the specified lvol needing a degraded_set bdev. 1934 */ 1935 void 1936 spdk_lvs_esnap_missing_remove(struct spdk_lvol *lvol) 1937 { 1938 struct spdk_lvol_store *lvs = lvol->lvol_store; 1939 struct spdk_lvs_degraded_lvol_set *degraded_set = lvol->degraded_set; 1940 1941 assert(lvs->thread == spdk_get_thread()); 1942 1943 if (degraded_set == NULL) { 1944 return; 1945 } 1946 1947 lvs_degraded_lvol_set_remove(degraded_set, lvol); 1948 1949 if (!TAILQ_EMPTY(°raded_set->lvols)) { 1950 return; 1951 } 1952 1953 RB_REMOVE(degraded_lvol_sets_tree, &lvs->degraded_lvol_sets_tree, degraded_set); 1954 1955 free((char *)degraded_set->esnap_id); 1956 free(degraded_set); 1957 } 1958 1959 struct lvs_esnap_hotplug_req { 1960 struct spdk_lvol *lvol; 1961 spdk_lvol_op_with_handle_complete cb_fn; 1962 void *cb_arg; 1963 }; 1964 1965 static void 1966 lvs_esnap_hotplug_done(void *cb_arg, int bserrno) 1967 { 1968 struct lvs_esnap_hotplug_req *req = cb_arg; 1969 struct spdk_lvol *lvol = req->lvol; 1970 struct spdk_lvol_store *lvs = lvol->lvol_store; 1971 1972 if (bserrno != 0) { 1973 SPDK_ERRLOG("lvol %s/%s: failed to hotplug blob_bdev due to error %d\n", 1974 lvs->name, lvol->name, bserrno); 1975 } 1976 req->cb_fn(req->cb_arg, lvol, bserrno); 1977 free(req); 1978 } 1979 1980 static void 1981 lvs_esnap_degraded_hotplug(struct spdk_lvs_degraded_lvol_set *degraded_set, 1982 spdk_lvol_op_with_handle_complete cb_fn, void *cb_arg) 1983 { 1984 struct spdk_lvol_store *lvs = degraded_set->lvol_store; 1985 struct spdk_lvol *lvol, *tmp, *last_missing; 1986 struct spdk_bs_dev *bs_dev; 1987 const void *esnap_id = degraded_set->esnap_id; 1988 uint32_t id_len = degraded_set->id_len; 1989 struct lvs_esnap_hotplug_req *req; 1990 int rc; 1991 1992 assert(lvs->thread == spdk_get_thread()); 1993 1994 /* 1995 * When lvs->esnap_bs_bdev_create() tries to load an external snapshot, it can encounter 1996 * errors that lead it to calling spdk_lvs_esnap_missing_add(). This function needs to be 1997 * sure that such modifications do not lead to degraded_set->lvols tailqs or references 1998 * to memory that this function will free. 1999 * 2000 * While this function is running, no other thread can add items to degraded_set->lvols. If 2001 * the list is mutated, it must have been done by this function or something in its call 2002 * graph running on this thread. 2003 */ 2004 2005 /* Remember the last lvol on the list. Iteration will stop once it has been processed. */ 2006 last_missing = TAILQ_LAST(°raded_set->lvols, degraded_lvols); 2007 2008 TAILQ_FOREACH_SAFE(lvol, °raded_set->lvols, degraded_link, tmp) { 2009 req = calloc(1, sizeof(*req)); 2010 if (req == NULL) { 2011 SPDK_ERRLOG("lvol %s: failed to create esnap bs_dev: out of memory\n", 2012 lvol->unique_id); 2013 cb_fn(cb_arg, lvol, -ENOMEM); 2014 /* The next one likely won't succeed either, but keep going so that all the 2015 * failed hotplugs are logged. 2016 */ 2017 goto next; 2018 } 2019 2020 /* 2021 * Remove the lvol from the tailq so that tailq corruption is avoided if 2022 * lvs->esnap_bs_dev_create() calls spdk_lvs_esnap_missing_add(lvol). 2023 */ 2024 TAILQ_REMOVE(°raded_set->lvols, lvol, degraded_link); 2025 lvol->degraded_set = NULL; 2026 2027 bs_dev = NULL; 2028 rc = lvs->esnap_bs_dev_create(lvs, lvol, lvol->blob, esnap_id, id_len, &bs_dev); 2029 if (rc != 0) { 2030 SPDK_ERRLOG("lvol %s: failed to create esnap bs_dev: error %d\n", 2031 lvol->unique_id, rc); 2032 lvol->degraded_set = degraded_set; 2033 TAILQ_INSERT_TAIL(°raded_set->lvols, lvol, degraded_link); 2034 cb_fn(cb_arg, lvol, rc); 2035 free(req); 2036 goto next; 2037 } 2038 2039 req->lvol = lvol; 2040 req->cb_fn = cb_fn; 2041 req->cb_arg = cb_arg; 2042 spdk_blob_set_esnap_bs_dev(lvol->blob, bs_dev, lvs_esnap_hotplug_done, req); 2043 2044 next: 2045 if (lvol == last_missing) { 2046 /* 2047 * Anything after last_missing was added due to some problem encountered 2048 * while trying to create the esnap bs_dev. 2049 */ 2050 break; 2051 } 2052 } 2053 2054 if (TAILQ_EMPTY(°raded_set->lvols)) { 2055 RB_REMOVE(degraded_lvol_sets_tree, &lvs->degraded_lvol_sets_tree, degraded_set); 2056 free((void *)degraded_set->esnap_id); 2057 free(degraded_set); 2058 } 2059 } 2060 2061 /* 2062 * Notify each lvstore created on this thread that is missing a bdev by the specified name or uuid 2063 * that the bdev now exists. 2064 */ 2065 bool 2066 spdk_lvs_notify_hotplug(const void *esnap_id, uint32_t id_len, 2067 spdk_lvol_op_with_handle_complete cb_fn, void *cb_arg) 2068 { 2069 struct spdk_lvs_degraded_lvol_set *found; 2070 struct spdk_lvs_degraded_lvol_set find = { 0 }; 2071 struct spdk_lvol_store *lvs; 2072 struct spdk_thread *thread = spdk_get_thread(); 2073 bool ret = false; 2074 2075 find.esnap_id = esnap_id; 2076 find.id_len = id_len; 2077 2078 pthread_mutex_lock(&g_lvol_stores_mutex); 2079 TAILQ_FOREACH(lvs, &g_lvol_stores, link) { 2080 if (thread != lvs->thread) { 2081 /* 2082 * It is expected that this is called from vbdev_lvol's examine_config() 2083 * callback. The lvstore was likely loaded do a creation happening as a 2084 * result of an RPC call or opening of an existing lvstore via 2085 * examine_disk() callback. RPC calls, examine_disk(), and examine_config() 2086 * should all be happening only on the app thread. The "wrong thread" 2087 * condition will only happen when an application is doing something weird. 2088 */ 2089 SPDK_NOTICELOG("Discarded examine for lvstore %s: wrong thread\n", 2090 lvs->name); 2091 continue; 2092 } 2093 2094 found = RB_FIND(degraded_lvol_sets_tree, &lvs->degraded_lvol_sets_tree, &find); 2095 if (found == NULL) { 2096 continue; 2097 } 2098 2099 ret = true; 2100 lvs_esnap_degraded_hotplug(found, cb_fn, cb_arg); 2101 } 2102 pthread_mutex_unlock(&g_lvol_stores_mutex); 2103 2104 return ret; 2105 } 2106 2107 int 2108 spdk_lvol_iter_immediate_clones(struct spdk_lvol *lvol, spdk_lvol_iter_cb cb_fn, void *cb_arg) 2109 { 2110 struct spdk_lvol_store *lvs = lvol->lvol_store; 2111 struct spdk_blob_store *bs = lvs->blobstore; 2112 struct spdk_lvol *clone; 2113 spdk_blob_id *ids; 2114 size_t id_cnt = 0; 2115 size_t i; 2116 int rc; 2117 2118 rc = spdk_blob_get_clones(bs, lvol->blob_id, NULL, &id_cnt); 2119 if (rc != -ENOMEM) { 2120 /* -ENOMEM says id_cnt is valid, no other errors should be returned. */ 2121 assert(rc == 0); 2122 return rc; 2123 } 2124 2125 ids = calloc(id_cnt, sizeof(*ids)); 2126 if (ids == NULL) { 2127 SPDK_ERRLOG("lvol %s: out of memory while iterating clones\n", lvol->unique_id); 2128 return -ENOMEM; 2129 } 2130 2131 rc = spdk_blob_get_clones(bs, lvol->blob_id, ids, &id_cnt); 2132 if (rc != 0) { 2133 SPDK_ERRLOG("lvol %s: unable to get clone blob IDs: %d\n", lvol->unique_id, rc); 2134 free(ids); 2135 return rc; 2136 } 2137 2138 for (i = 0; i < id_cnt; i++) { 2139 clone = lvs_get_lvol_by_blob_id(lvs, ids[i]); 2140 if (clone == NULL) { 2141 SPDK_NOTICELOG("lvol %s: unable to find clone lvol with blob id 0x%" 2142 PRIx64 "\n", lvol->unique_id, ids[i]); 2143 continue; 2144 } 2145 rc = cb_fn(cb_arg, clone); 2146 if (rc != 0) { 2147 SPDK_DEBUGLOG(lvol, "lvol %s: iteration stopped when lvol %s (blob 0x%" 2148 PRIx64 ") returned %d\n", lvol->unique_id, clone->unique_id, 2149 ids[i], rc); 2150 break; 2151 } 2152 } 2153 2154 free(ids); 2155 return rc; 2156 } 2157 2158 struct spdk_lvol * 2159 spdk_lvol_get_by_uuid(const struct spdk_uuid *uuid) 2160 { 2161 struct spdk_lvol_store *lvs; 2162 struct spdk_lvol *lvol; 2163 2164 pthread_mutex_lock(&g_lvol_stores_mutex); 2165 2166 TAILQ_FOREACH(lvs, &g_lvol_stores, link) { 2167 TAILQ_FOREACH(lvol, &lvs->lvols, link) { 2168 if (spdk_uuid_compare(uuid, &lvol->uuid) == 0) { 2169 pthread_mutex_unlock(&g_lvol_stores_mutex); 2170 return lvol; 2171 } 2172 } 2173 } 2174 2175 pthread_mutex_unlock(&g_lvol_stores_mutex); 2176 return NULL; 2177 } 2178 2179 struct spdk_lvol * 2180 spdk_lvol_get_by_names(const char *lvs_name, const char *lvol_name) 2181 { 2182 struct spdk_lvol_store *lvs; 2183 struct spdk_lvol *lvol; 2184 2185 pthread_mutex_lock(&g_lvol_stores_mutex); 2186 2187 TAILQ_FOREACH(lvs, &g_lvol_stores, link) { 2188 if (strcmp(lvs_name, lvs->name) != 0) { 2189 continue; 2190 } 2191 TAILQ_FOREACH(lvol, &lvs->lvols, link) { 2192 if (strcmp(lvol_name, lvol->name) == 0) { 2193 pthread_mutex_unlock(&g_lvol_stores_mutex); 2194 return lvol; 2195 } 2196 } 2197 } 2198 2199 pthread_mutex_unlock(&g_lvol_stores_mutex); 2200 return NULL; 2201 } 2202 2203 bool 2204 spdk_lvol_is_degraded(const struct spdk_lvol *lvol) 2205 { 2206 struct spdk_blob *blob = lvol->blob; 2207 2208 if (blob == NULL) { 2209 return true; 2210 } 2211 return spdk_blob_is_degraded(blob); 2212 } 2213