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 SET_FIELD(md_page_size); 651 652 dst->opts_size = src->opts_size; 653 654 /* You should not remove this statement, but need to update the assert statement 655 * if you add a new field, and also add a corresponding SET_FIELD statement */ 656 SPDK_STATIC_ASSERT(sizeof(struct spdk_lvs_opts) == 92, "Incorrect size"); 657 658 #undef FIELD_OK 659 #undef SET_FIELD 660 661 return 0; 662 } 663 664 static void 665 setup_lvs_opts(struct spdk_bs_opts *bs_opts, struct spdk_lvs_opts *o, uint32_t total_clusters, 666 void *esnap_ctx) 667 { 668 assert(o != NULL); 669 lvs_bs_opts_init(bs_opts); 670 bs_opts->cluster_sz = o->cluster_sz; 671 bs_opts->clear_method = (enum bs_clear_method)o->clear_method; 672 bs_opts->num_md_pages = (o->num_md_pages_per_cluster_ratio * total_clusters) / 100; 673 bs_opts->md_page_size = o->md_page_size; 674 bs_opts->esnap_bs_dev_create = o->esnap_bs_dev_create; 675 bs_opts->esnap_ctx = esnap_ctx; 676 snprintf(bs_opts->bstype.bstype, sizeof(bs_opts->bstype.bstype), "LVOLSTORE"); 677 } 678 679 int 680 spdk_lvs_init(struct spdk_bs_dev *bs_dev, struct spdk_lvs_opts *o, 681 spdk_lvs_op_with_handle_complete cb_fn, void *cb_arg) 682 { 683 struct spdk_lvol_store *lvs; 684 struct spdk_lvs_with_handle_req *lvs_req; 685 struct spdk_bs_opts opts = {}; 686 struct spdk_lvs_opts lvs_opts; 687 uint32_t total_clusters; 688 int rc, len; 689 690 if (bs_dev == NULL) { 691 SPDK_ERRLOG("Blobstore device does not exist\n"); 692 return -ENODEV; 693 } 694 695 if (o == NULL) { 696 SPDK_ERRLOG("spdk_lvs_opts not specified\n"); 697 return -EINVAL; 698 } 699 700 spdk_lvs_opts_init(&lvs_opts); 701 if (lvs_opts_copy(o, &lvs_opts) != 0) { 702 SPDK_ERRLOG("spdk_lvs_opts invalid\n"); 703 return -EINVAL; 704 } 705 706 if (lvs_opts.cluster_sz < bs_dev->blocklen || (lvs_opts.cluster_sz % bs_dev->blocklen) != 0) { 707 SPDK_ERRLOG("Cluster size %" PRIu32 " is smaller than blocklen %" PRIu32 708 "Or not an integral multiple\n", lvs_opts.cluster_sz, bs_dev->blocklen); 709 return -EINVAL; 710 } 711 total_clusters = bs_dev->blockcnt / (lvs_opts.cluster_sz / bs_dev->blocklen); 712 713 lvs = lvs_alloc(); 714 if (!lvs) { 715 SPDK_ERRLOG("Cannot alloc memory for lvol store base pointer\n"); 716 return -ENOMEM; 717 } 718 719 setup_lvs_opts(&opts, o, total_clusters, lvs); 720 721 len = strnlen(lvs_opts.name, SPDK_LVS_NAME_MAX); 722 if (len == 0 || len == SPDK_LVS_NAME_MAX) { 723 SPDK_ERRLOG("Name must be between 1 and %d characters\n", SPDK_LVS_NAME_MAX - 1); 724 lvs_free(lvs); 725 return -EINVAL; 726 } 727 728 spdk_uuid_generate(&lvs->uuid); 729 snprintf(lvs->name, sizeof(lvs->name), "%s", lvs_opts.name); 730 731 rc = add_lvs_to_list(lvs); 732 if (rc) { 733 SPDK_ERRLOG("lvolstore with name %s already exists\n", lvs->name); 734 lvs_free(lvs); 735 return -EEXIST; 736 } 737 738 lvs_req = calloc(1, sizeof(*lvs_req)); 739 if (!lvs_req) { 740 lvs_free(lvs); 741 SPDK_ERRLOG("Cannot alloc memory for lvol store request pointer\n"); 742 return -ENOMEM; 743 } 744 745 assert(cb_fn != NULL); 746 lvs_req->cb_fn = cb_fn; 747 lvs_req->cb_arg = cb_arg; 748 lvs_req->lvol_store = lvs; 749 lvs->bs_dev = bs_dev; 750 751 SPDK_INFOLOG(lvol, "Initializing lvol store\n"); 752 spdk_bs_init(bs_dev, &opts, lvs_init_cb, lvs_req); 753 754 return 0; 755 } 756 757 static void 758 lvs_rename_cb(void *cb_arg, int lvolerrno) 759 { 760 struct spdk_lvs_req *req = cb_arg; 761 762 if (lvolerrno != 0) { 763 req->lvserrno = lvolerrno; 764 } 765 if (req->lvserrno != 0) { 766 SPDK_ERRLOG("Lvol store rename operation failed\n"); 767 /* Lvs renaming failed, so we should 'clear' new_name. 768 * Otherwise it could cause a failure on the next attempt to change the name to 'new_name' */ 769 snprintf(req->lvol_store->new_name, 770 sizeof(req->lvol_store->new_name), 771 "%s", req->lvol_store->name); 772 } else { 773 /* Update lvs name with new_name */ 774 snprintf(req->lvol_store->name, 775 sizeof(req->lvol_store->name), 776 "%s", req->lvol_store->new_name); 777 } 778 779 req->cb_fn(req->cb_arg, req->lvserrno); 780 free(req); 781 } 782 783 static void 784 lvs_rename_sync_cb(void *cb_arg, int lvolerrno) 785 { 786 struct spdk_lvs_req *req = cb_arg; 787 struct spdk_blob *blob = req->lvol_store->super_blob; 788 789 if (lvolerrno < 0) { 790 req->lvserrno = lvolerrno; 791 } 792 793 spdk_blob_close(blob, lvs_rename_cb, req); 794 } 795 796 static void 797 lvs_rename_open_cb(void *cb_arg, struct spdk_blob *blob, int lvolerrno) 798 { 799 struct spdk_lvs_req *req = cb_arg; 800 int rc; 801 802 if (lvolerrno < 0) { 803 lvs_rename_cb(cb_arg, lvolerrno); 804 return; 805 } 806 807 rc = spdk_blob_set_xattr(blob, "name", req->lvol_store->new_name, 808 strlen(req->lvol_store->new_name) + 1); 809 if (rc < 0) { 810 req->lvserrno = rc; 811 lvs_rename_sync_cb(req, rc); 812 return; 813 } 814 815 req->lvol_store->super_blob = blob; 816 817 spdk_blob_sync_md(blob, lvs_rename_sync_cb, req); 818 } 819 820 void 821 spdk_lvs_rename(struct spdk_lvol_store *lvs, const char *new_name, 822 spdk_lvs_op_complete cb_fn, void *cb_arg) 823 { 824 struct spdk_lvs_req *req; 825 struct spdk_lvol_store *tmp; 826 827 /* Check if new name is current lvs name. 828 * If so, return success immediately */ 829 if (strncmp(lvs->name, new_name, SPDK_LVS_NAME_MAX) == 0) { 830 cb_fn(cb_arg, 0); 831 return; 832 } 833 834 /* Check if new or new_name is already used in other lvs */ 835 pthread_mutex_lock(&g_lvol_stores_mutex); 836 TAILQ_FOREACH(tmp, &g_lvol_stores, link) { 837 if (!strncmp(new_name, tmp->name, SPDK_LVS_NAME_MAX) || 838 !strncmp(new_name, tmp->new_name, SPDK_LVS_NAME_MAX)) { 839 pthread_mutex_unlock(&g_lvol_stores_mutex); 840 cb_fn(cb_arg, -EEXIST); 841 return; 842 } 843 } 844 pthread_mutex_unlock(&g_lvol_stores_mutex); 845 846 req = calloc(1, sizeof(*req)); 847 if (!req) { 848 SPDK_ERRLOG("Cannot alloc memory for lvol request pointer\n"); 849 cb_fn(cb_arg, -ENOMEM); 850 return; 851 } 852 snprintf(lvs->new_name, sizeof(lvs->new_name), "%s", new_name); 853 req->lvol_store = lvs; 854 req->cb_fn = cb_fn; 855 req->cb_arg = cb_arg; 856 857 spdk_bs_open_blob(lvs->blobstore, lvs->super_blob_id, lvs_rename_open_cb, req); 858 } 859 860 static void 861 _lvs_unload_cb(void *cb_arg, int lvserrno) 862 { 863 struct spdk_lvs_req *lvs_req = cb_arg; 864 865 SPDK_INFOLOG(lvol, "Lvol store unloaded\n"); 866 assert(lvs_req->cb_fn != NULL); 867 lvs_req->cb_fn(lvs_req->cb_arg, lvserrno); 868 free(lvs_req); 869 } 870 871 int 872 spdk_lvs_unload(struct spdk_lvol_store *lvs, spdk_lvs_op_complete cb_fn, 873 void *cb_arg) 874 { 875 struct spdk_lvs_req *lvs_req; 876 struct spdk_lvol *lvol, *tmp; 877 878 if (lvs == NULL) { 879 SPDK_ERRLOG("Lvol store is NULL\n"); 880 return -ENODEV; 881 } 882 883 TAILQ_FOREACH_SAFE(lvol, &lvs->lvols, link, tmp) { 884 if (lvol->action_in_progress == true) { 885 SPDK_ERRLOG("Cannot unload lvol store - operations on lvols pending\n"); 886 cb_fn(cb_arg, -EBUSY); 887 return -EBUSY; 888 } else if (lvol->ref_count != 0) { 889 SPDK_ERRLOG("Lvols still open on lvol store\n"); 890 cb_fn(cb_arg, -EBUSY); 891 return -EBUSY; 892 } 893 } 894 895 TAILQ_FOREACH_SAFE(lvol, &lvs->lvols, link, tmp) { 896 spdk_lvs_esnap_missing_remove(lvol); 897 TAILQ_REMOVE(&lvs->lvols, lvol, link); 898 lvol_free(lvol); 899 } 900 901 lvs_req = calloc(1, sizeof(*lvs_req)); 902 if (!lvs_req) { 903 SPDK_ERRLOG("Cannot alloc memory for lvol store request pointer\n"); 904 return -ENOMEM; 905 } 906 907 lvs_req->cb_fn = cb_fn; 908 lvs_req->cb_arg = cb_arg; 909 910 SPDK_INFOLOG(lvol, "Unloading lvol store\n"); 911 spdk_bs_unload(lvs->blobstore, _lvs_unload_cb, lvs_req); 912 lvs_free(lvs); 913 914 return 0; 915 } 916 917 static void 918 _lvs_destroy_cb(void *cb_arg, int lvserrno) 919 { 920 struct spdk_lvs_destroy_req *lvs_req = cb_arg; 921 922 SPDK_INFOLOG(lvol, "Lvol store destroyed\n"); 923 assert(lvs_req->cb_fn != NULL); 924 lvs_req->cb_fn(lvs_req->cb_arg, lvserrno); 925 free(lvs_req); 926 } 927 928 static void 929 _lvs_destroy_super_cb(void *cb_arg, int bserrno) 930 { 931 struct spdk_lvs_destroy_req *lvs_req = cb_arg; 932 struct spdk_lvol_store *lvs = lvs_req->lvs; 933 934 assert(lvs != NULL); 935 936 SPDK_INFOLOG(lvol, "Destroying lvol store\n"); 937 spdk_bs_destroy(lvs->blobstore, _lvs_destroy_cb, lvs_req); 938 lvs_free(lvs); 939 } 940 941 int 942 spdk_lvs_destroy(struct spdk_lvol_store *lvs, spdk_lvs_op_complete cb_fn, 943 void *cb_arg) 944 { 945 struct spdk_lvs_destroy_req *lvs_req; 946 struct spdk_lvol *iter_lvol, *tmp; 947 948 if (lvs == NULL) { 949 SPDK_ERRLOG("Lvol store is NULL\n"); 950 return -ENODEV; 951 } 952 953 TAILQ_FOREACH_SAFE(iter_lvol, &lvs->lvols, link, tmp) { 954 if (iter_lvol->action_in_progress == true) { 955 SPDK_ERRLOG("Cannot destroy lvol store - operations on lvols pending\n"); 956 cb_fn(cb_arg, -EBUSY); 957 return -EBUSY; 958 } else if (iter_lvol->ref_count != 0) { 959 SPDK_ERRLOG("Lvols still open on lvol store\n"); 960 cb_fn(cb_arg, -EBUSY); 961 return -EBUSY; 962 } 963 } 964 965 TAILQ_FOREACH_SAFE(iter_lvol, &lvs->lvols, link, tmp) { 966 free(iter_lvol); 967 } 968 969 lvs_req = calloc(1, sizeof(*lvs_req)); 970 if (!lvs_req) { 971 SPDK_ERRLOG("Cannot alloc memory for lvol store request pointer\n"); 972 return -ENOMEM; 973 } 974 975 lvs_req->cb_fn = cb_fn; 976 lvs_req->cb_arg = cb_arg; 977 lvs_req->lvs = lvs; 978 979 SPDK_INFOLOG(lvol, "Deleting super blob\n"); 980 spdk_bs_delete_blob(lvs->blobstore, lvs->super_blob_id, _lvs_destroy_super_cb, lvs_req); 981 982 return 0; 983 } 984 985 static void 986 lvol_close_blob_cb(void *cb_arg, int lvolerrno) 987 { 988 struct spdk_lvol_req *req = cb_arg; 989 struct spdk_lvol *lvol = req->lvol; 990 991 if (lvolerrno < 0) { 992 SPDK_ERRLOG("Could not close blob on lvol\n"); 993 goto end; 994 } 995 996 lvol->ref_count--; 997 lvol->blob = NULL; 998 SPDK_INFOLOG(lvol, "Lvol %s closed\n", lvol->unique_id); 999 1000 end: 1001 lvol->action_in_progress = false; 1002 req->cb_fn(req->cb_arg, lvolerrno); 1003 free(req); 1004 } 1005 1006 bool 1007 spdk_lvol_deletable(struct spdk_lvol *lvol) 1008 { 1009 size_t count = 0; 1010 1011 spdk_blob_get_clones(lvol->lvol_store->blobstore, lvol->blob_id, NULL, &count); 1012 return (count == 0); 1013 } 1014 1015 static void 1016 lvol_delete_blob_cb(void *cb_arg, int lvolerrno) 1017 { 1018 struct spdk_lvol_req *req = cb_arg; 1019 struct spdk_lvol *lvol = req->lvol; 1020 struct spdk_lvol *clone_lvol = req->clone_lvol; 1021 1022 if (lvolerrno < 0) { 1023 SPDK_ERRLOG("Could not remove blob on lvol gracefully - forced removal\n"); 1024 } else { 1025 SPDK_INFOLOG(lvol, "Lvol %s deleted\n", lvol->unique_id); 1026 } 1027 1028 if (lvol->degraded_set != NULL) { 1029 if (clone_lvol != NULL) { 1030 /* 1031 * A degraded esnap clone that has a blob clone has been deleted. clone_lvol 1032 * becomes an esnap clone and needs to be associated with the 1033 * spdk_lvs_degraded_lvol_set. 1034 */ 1035 struct spdk_lvs_degraded_lvol_set *degraded_set = lvol->degraded_set; 1036 1037 lvs_degraded_lvol_set_remove(degraded_set, lvol); 1038 lvs_degraded_lvol_set_add(degraded_set, clone_lvol); 1039 } else { 1040 spdk_lvs_esnap_missing_remove(lvol); 1041 } 1042 } 1043 1044 TAILQ_REMOVE(&lvol->lvol_store->lvols, lvol, link); 1045 lvol_free(lvol); 1046 req->cb_fn(req->cb_arg, lvolerrno); 1047 free(req); 1048 } 1049 1050 static void 1051 lvol_create_open_cb(void *cb_arg, struct spdk_blob *blob, int lvolerrno) 1052 { 1053 struct spdk_lvol_with_handle_req *req = cb_arg; 1054 struct spdk_lvol *lvol = req->lvol; 1055 1056 TAILQ_REMOVE(&req->lvol->lvol_store->pending_lvols, req->lvol, link); 1057 1058 if (lvolerrno < 0) { 1059 lvol_free(lvol); 1060 req->cb_fn(req->cb_arg, NULL, lvolerrno); 1061 free(req); 1062 return; 1063 } 1064 1065 lvol->blob = blob; 1066 lvol->blob_id = spdk_blob_get_id(blob); 1067 1068 TAILQ_INSERT_TAIL(&lvol->lvol_store->lvols, lvol, link); 1069 1070 lvol->ref_count++; 1071 1072 assert(req->cb_fn != NULL); 1073 req->cb_fn(req->cb_arg, req->lvol, lvolerrno); 1074 free(req); 1075 } 1076 1077 static void 1078 lvol_create_cb(void *cb_arg, spdk_blob_id blobid, int lvolerrno) 1079 { 1080 struct spdk_lvol_with_handle_req *req = cb_arg; 1081 struct spdk_blob_store *bs; 1082 struct spdk_blob_open_opts opts; 1083 1084 if (lvolerrno < 0) { 1085 TAILQ_REMOVE(&req->lvol->lvol_store->pending_lvols, req->lvol, link); 1086 lvol_free(req->lvol); 1087 assert(req->cb_fn != NULL); 1088 req->cb_fn(req->cb_arg, NULL, lvolerrno); 1089 free(req); 1090 return; 1091 } 1092 1093 spdk_blob_open_opts_init(&opts, sizeof(opts)); 1094 opts.clear_method = req->lvol->clear_method; 1095 /* 1096 * If the lvol that is being created is an esnap clone, the blobstore needs to be able to 1097 * pass the lvol to the esnap_bs_dev_create callback. In order for that to happen, we need 1098 * to pass it here. 1099 * 1100 * This does set ensap_ctx in cases where it's not needed, but we don't know that it's not 1101 * needed until after the blob is open. When the blob is not an esnap clone, a reference to 1102 * the value stored in opts.esnap_ctx is not retained by the blobstore. 1103 */ 1104 opts.esnap_ctx = req->lvol; 1105 bs = req->lvol->lvol_store->blobstore; 1106 1107 if (req->origlvol != NULL && req->origlvol->degraded_set != NULL) { 1108 /* 1109 * A snapshot was created from a degraded esnap clone. The new snapshot is now a 1110 * degraded esnap clone. The previous clone is now a regular clone of a blob. Update 1111 * the set of directly-related clones to the missing external snapshot. 1112 */ 1113 struct spdk_lvs_degraded_lvol_set *degraded_set = req->origlvol->degraded_set; 1114 1115 lvs_degraded_lvol_set_remove(degraded_set, req->origlvol); 1116 lvs_degraded_lvol_set_add(degraded_set, req->lvol); 1117 } 1118 1119 spdk_bs_open_blob_ext(bs, blobid, &opts, lvol_create_open_cb, req); 1120 } 1121 1122 static void 1123 lvol_get_xattr_value(void *xattr_ctx, const char *name, 1124 const void **value, size_t *value_len) 1125 { 1126 struct spdk_lvol *lvol = xattr_ctx; 1127 1128 if (!strcmp(LVOL_NAME, name)) { 1129 *value = lvol->name; 1130 *value_len = SPDK_LVOL_NAME_MAX; 1131 return; 1132 } 1133 if (!strcmp("uuid", name)) { 1134 *value = lvol->uuid_str; 1135 *value_len = sizeof(lvol->uuid_str); 1136 return; 1137 } 1138 *value = NULL; 1139 *value_len = 0; 1140 } 1141 1142 static int 1143 lvs_verify_lvol_name(struct spdk_lvol_store *lvs, const char *name) 1144 { 1145 struct spdk_lvol *tmp; 1146 1147 if (name == NULL || strnlen(name, SPDK_LVOL_NAME_MAX) == 0) { 1148 SPDK_INFOLOG(lvol, "lvol name not provided.\n"); 1149 return -EINVAL; 1150 } 1151 1152 if (strnlen(name, SPDK_LVOL_NAME_MAX) == SPDK_LVOL_NAME_MAX) { 1153 SPDK_ERRLOG("Name has no null terminator.\n"); 1154 return -EINVAL; 1155 } 1156 1157 TAILQ_FOREACH(tmp, &lvs->lvols, link) { 1158 if (!strncmp(name, tmp->name, SPDK_LVOL_NAME_MAX)) { 1159 SPDK_ERRLOG("lvol with name %s already exists\n", name); 1160 return -EEXIST; 1161 } 1162 } 1163 1164 TAILQ_FOREACH(tmp, &lvs->pending_lvols, link) { 1165 if (!strncmp(name, tmp->name, SPDK_LVOL_NAME_MAX)) { 1166 SPDK_ERRLOG("lvol with name %s is being already created\n", name); 1167 return -EEXIST; 1168 } 1169 } 1170 1171 return 0; 1172 } 1173 1174 int 1175 spdk_lvol_create(struct spdk_lvol_store *lvs, const char *name, uint64_t sz, 1176 bool thin_provision, enum lvol_clear_method clear_method, spdk_lvol_op_with_handle_complete cb_fn, 1177 void *cb_arg) 1178 { 1179 struct spdk_lvol_with_handle_req *req; 1180 struct spdk_blob_store *bs; 1181 struct spdk_lvol *lvol; 1182 struct spdk_blob_opts opts; 1183 char *xattr_names[] = {LVOL_NAME, "uuid"}; 1184 int rc; 1185 1186 if (lvs == NULL) { 1187 SPDK_ERRLOG("lvol store does not exist\n"); 1188 return -EINVAL; 1189 } 1190 1191 rc = lvs_verify_lvol_name(lvs, name); 1192 if (rc < 0) { 1193 return rc; 1194 } 1195 1196 bs = lvs->blobstore; 1197 1198 req = calloc(1, sizeof(*req)); 1199 if (!req) { 1200 SPDK_ERRLOG("Cannot alloc memory for lvol request pointer\n"); 1201 return -ENOMEM; 1202 } 1203 req->cb_fn = cb_fn; 1204 req->cb_arg = cb_arg; 1205 1206 lvol = lvol_alloc(lvs, name, thin_provision, clear_method); 1207 if (!lvol) { 1208 free(req); 1209 SPDK_ERRLOG("Cannot alloc memory for lvol base pointer\n"); 1210 return -ENOMEM; 1211 } 1212 1213 req->lvol = lvol; 1214 spdk_blob_opts_init(&opts, sizeof(opts)); 1215 opts.thin_provision = thin_provision; 1216 opts.num_clusters = spdk_divide_round_up(sz, spdk_bs_get_cluster_size(bs)); 1217 opts.clear_method = lvol->clear_method; 1218 opts.xattrs.count = SPDK_COUNTOF(xattr_names); 1219 opts.xattrs.names = xattr_names; 1220 opts.xattrs.ctx = lvol; 1221 opts.xattrs.get_value = lvol_get_xattr_value; 1222 1223 spdk_bs_create_blob_ext(lvs->blobstore, &opts, lvol_create_cb, req); 1224 1225 return 0; 1226 } 1227 1228 int 1229 spdk_lvol_create_esnap_clone(const void *esnap_id, uint32_t id_len, uint64_t size_bytes, 1230 struct spdk_lvol_store *lvs, const char *clone_name, 1231 spdk_lvol_op_with_handle_complete cb_fn, void *cb_arg) 1232 { 1233 struct spdk_lvol_with_handle_req *req; 1234 struct spdk_blob_store *bs; 1235 struct spdk_lvol *lvol; 1236 struct spdk_blob_opts opts; 1237 uint64_t cluster_sz; 1238 char *xattr_names[] = {LVOL_NAME, "uuid"}; 1239 int rc; 1240 1241 if (lvs == NULL) { 1242 SPDK_ERRLOG("lvol store does not exist\n"); 1243 return -EINVAL; 1244 } 1245 1246 rc = lvs_verify_lvol_name(lvs, clone_name); 1247 if (rc < 0) { 1248 return rc; 1249 } 1250 1251 bs = lvs->blobstore; 1252 1253 cluster_sz = spdk_bs_get_cluster_size(bs); 1254 if ((size_bytes % cluster_sz) != 0) { 1255 SPDK_ERRLOG("Cannot create '%s/%s': size %" PRIu64 " is not an integer multiple of " 1256 "cluster size %" PRIu64 "\n", lvs->name, clone_name, size_bytes, 1257 cluster_sz); 1258 return -EINVAL; 1259 } 1260 1261 req = calloc(1, sizeof(*req)); 1262 if (!req) { 1263 SPDK_ERRLOG("Cannot alloc memory for lvol request pointer\n"); 1264 return -ENOMEM; 1265 } 1266 req->cb_fn = cb_fn; 1267 req->cb_arg = cb_arg; 1268 1269 lvol = lvol_alloc(lvs, clone_name, true, LVOL_CLEAR_WITH_DEFAULT); 1270 if (!lvol) { 1271 free(req); 1272 SPDK_ERRLOG("Cannot alloc memory for lvol base pointer\n"); 1273 return -ENOMEM; 1274 } 1275 req->lvol = lvol; 1276 1277 spdk_blob_opts_init(&opts, sizeof(opts)); 1278 opts.esnap_id = esnap_id; 1279 opts.esnap_id_len = id_len; 1280 opts.thin_provision = true; 1281 opts.num_clusters = spdk_divide_round_up(size_bytes, cluster_sz); 1282 opts.clear_method = lvol->clear_method; 1283 opts.xattrs.count = SPDK_COUNTOF(xattr_names); 1284 opts.xattrs.names = xattr_names; 1285 opts.xattrs.ctx = lvol; 1286 opts.xattrs.get_value = lvol_get_xattr_value; 1287 1288 spdk_bs_create_blob_ext(lvs->blobstore, &opts, lvol_create_cb, req); 1289 1290 return 0; 1291 } 1292 1293 void 1294 spdk_lvol_create_snapshot(struct spdk_lvol *origlvol, const char *snapshot_name, 1295 spdk_lvol_op_with_handle_complete cb_fn, void *cb_arg) 1296 { 1297 struct spdk_lvol_store *lvs; 1298 struct spdk_lvol *newlvol; 1299 struct spdk_blob *origblob; 1300 struct spdk_lvol_with_handle_req *req; 1301 struct spdk_blob_xattr_opts snapshot_xattrs; 1302 char *xattr_names[] = {LVOL_NAME, "uuid"}; 1303 int rc; 1304 1305 if (origlvol == NULL) { 1306 SPDK_INFOLOG(lvol, "Lvol not provided.\n"); 1307 cb_fn(cb_arg, NULL, -EINVAL); 1308 return; 1309 } 1310 1311 origblob = origlvol->blob; 1312 lvs = origlvol->lvol_store; 1313 if (lvs == NULL) { 1314 SPDK_ERRLOG("lvol store does not exist\n"); 1315 cb_fn(cb_arg, NULL, -EINVAL); 1316 return; 1317 } 1318 1319 rc = lvs_verify_lvol_name(lvs, snapshot_name); 1320 if (rc < 0) { 1321 cb_fn(cb_arg, NULL, rc); 1322 return; 1323 } 1324 1325 req = calloc(1, sizeof(*req)); 1326 if (!req) { 1327 SPDK_ERRLOG("Cannot alloc memory for lvol request pointer\n"); 1328 cb_fn(cb_arg, NULL, -ENOMEM); 1329 return; 1330 } 1331 1332 newlvol = lvol_alloc(origlvol->lvol_store, snapshot_name, true, 1333 (enum lvol_clear_method)origlvol->clear_method); 1334 if (!newlvol) { 1335 SPDK_ERRLOG("Cannot alloc memory for lvol base pointer\n"); 1336 free(req); 1337 cb_fn(cb_arg, NULL, -ENOMEM); 1338 return; 1339 } 1340 1341 snapshot_xattrs.count = SPDK_COUNTOF(xattr_names); 1342 snapshot_xattrs.ctx = newlvol; 1343 snapshot_xattrs.names = xattr_names; 1344 snapshot_xattrs.get_value = lvol_get_xattr_value; 1345 req->lvol = newlvol; 1346 req->origlvol = origlvol; 1347 req->cb_fn = cb_fn; 1348 req->cb_arg = cb_arg; 1349 1350 spdk_bs_create_snapshot(lvs->blobstore, spdk_blob_get_id(origblob), &snapshot_xattrs, 1351 lvol_create_cb, req); 1352 } 1353 1354 void 1355 spdk_lvol_create_clone(struct spdk_lvol *origlvol, const char *clone_name, 1356 spdk_lvol_op_with_handle_complete cb_fn, void *cb_arg) 1357 { 1358 struct spdk_lvol *newlvol; 1359 struct spdk_lvol_with_handle_req *req; 1360 struct spdk_lvol_store *lvs; 1361 struct spdk_blob *origblob; 1362 struct spdk_blob_xattr_opts clone_xattrs; 1363 char *xattr_names[] = {LVOL_NAME, "uuid"}; 1364 int rc; 1365 1366 if (origlvol == NULL) { 1367 SPDK_INFOLOG(lvol, "Lvol not provided.\n"); 1368 cb_fn(cb_arg, NULL, -EINVAL); 1369 return; 1370 } 1371 1372 origblob = origlvol->blob; 1373 lvs = origlvol->lvol_store; 1374 if (lvs == NULL) { 1375 SPDK_ERRLOG("lvol store does not exist\n"); 1376 cb_fn(cb_arg, NULL, -EINVAL); 1377 return; 1378 } 1379 1380 rc = lvs_verify_lvol_name(lvs, clone_name); 1381 if (rc < 0) { 1382 cb_fn(cb_arg, NULL, rc); 1383 return; 1384 } 1385 1386 req = calloc(1, sizeof(*req)); 1387 if (!req) { 1388 SPDK_ERRLOG("Cannot alloc memory for lvol request pointer\n"); 1389 cb_fn(cb_arg, NULL, -ENOMEM); 1390 return; 1391 } 1392 1393 newlvol = lvol_alloc(lvs, clone_name, true, (enum lvol_clear_method)origlvol->clear_method); 1394 if (!newlvol) { 1395 SPDK_ERRLOG("Cannot alloc memory for lvol base pointer\n"); 1396 free(req); 1397 cb_fn(cb_arg, NULL, -ENOMEM); 1398 return; 1399 } 1400 1401 clone_xattrs.count = SPDK_COUNTOF(xattr_names); 1402 clone_xattrs.ctx = newlvol; 1403 clone_xattrs.names = xattr_names; 1404 clone_xattrs.get_value = lvol_get_xattr_value; 1405 req->lvol = newlvol; 1406 req->cb_fn = cb_fn; 1407 req->cb_arg = cb_arg; 1408 1409 spdk_bs_create_clone(lvs->blobstore, spdk_blob_get_id(origblob), &clone_xattrs, 1410 lvol_create_cb, 1411 req); 1412 } 1413 1414 static void 1415 lvol_resize_done(void *cb_arg, int lvolerrno) 1416 { 1417 struct spdk_lvol_req *req = cb_arg; 1418 1419 req->cb_fn(req->cb_arg, lvolerrno); 1420 free(req); 1421 } 1422 1423 static void 1424 lvol_blob_resize_cb(void *cb_arg, int bserrno) 1425 { 1426 struct spdk_lvol_req *req = cb_arg; 1427 struct spdk_lvol *lvol = req->lvol; 1428 1429 if (bserrno != 0) { 1430 req->cb_fn(req->cb_arg, bserrno); 1431 free(req); 1432 return; 1433 } 1434 1435 spdk_blob_sync_md(lvol->blob, lvol_resize_done, req); 1436 } 1437 1438 void 1439 spdk_lvol_resize(struct spdk_lvol *lvol, uint64_t sz, 1440 spdk_lvol_op_complete cb_fn, void *cb_arg) 1441 { 1442 struct spdk_blob *blob = lvol->blob; 1443 struct spdk_lvol_store *lvs = lvol->lvol_store; 1444 struct spdk_lvol_req *req; 1445 uint64_t new_clusters = spdk_divide_round_up(sz, spdk_bs_get_cluster_size(lvs->blobstore)); 1446 1447 req = calloc(1, sizeof(*req)); 1448 if (!req) { 1449 SPDK_ERRLOG("Cannot alloc memory for lvol request pointer\n"); 1450 cb_fn(cb_arg, -ENOMEM); 1451 return; 1452 } 1453 req->cb_fn = cb_fn; 1454 req->cb_arg = cb_arg; 1455 req->lvol = lvol; 1456 1457 spdk_blob_resize(blob, new_clusters, lvol_blob_resize_cb, req); 1458 } 1459 1460 static void 1461 lvol_set_read_only_cb(void *cb_arg, int lvolerrno) 1462 { 1463 struct spdk_lvol_req *req = cb_arg; 1464 1465 req->cb_fn(req->cb_arg, lvolerrno); 1466 free(req); 1467 } 1468 1469 void 1470 spdk_lvol_set_read_only(struct spdk_lvol *lvol, spdk_lvol_op_complete cb_fn, void *cb_arg) 1471 { 1472 struct spdk_lvol_req *req; 1473 1474 req = calloc(1, sizeof(*req)); 1475 if (!req) { 1476 SPDK_ERRLOG("Cannot alloc memory for lvol request pointer\n"); 1477 cb_fn(cb_arg, -ENOMEM); 1478 return; 1479 } 1480 req->cb_fn = cb_fn; 1481 req->cb_arg = cb_arg; 1482 1483 spdk_blob_set_read_only(lvol->blob); 1484 spdk_blob_sync_md(lvol->blob, lvol_set_read_only_cb, req); 1485 } 1486 1487 static void 1488 lvol_rename_cb(void *cb_arg, int lvolerrno) 1489 { 1490 struct spdk_lvol_req *req = cb_arg; 1491 1492 if (lvolerrno != 0) { 1493 SPDK_ERRLOG("Lvol rename operation failed\n"); 1494 } else { 1495 snprintf(req->lvol->name, sizeof(req->lvol->name), "%s", req->name); 1496 } 1497 1498 req->cb_fn(req->cb_arg, lvolerrno); 1499 free(req); 1500 } 1501 1502 void 1503 spdk_lvol_rename(struct spdk_lvol *lvol, const char *new_name, 1504 spdk_lvol_op_complete cb_fn, void *cb_arg) 1505 { 1506 struct spdk_lvol *tmp; 1507 struct spdk_blob *blob = lvol->blob; 1508 struct spdk_lvol_req *req; 1509 int rc; 1510 1511 /* Check if new name is current lvol name. 1512 * If so, return success immediately */ 1513 if (strncmp(lvol->name, new_name, SPDK_LVOL_NAME_MAX) == 0) { 1514 cb_fn(cb_arg, 0); 1515 return; 1516 } 1517 1518 /* Check if lvol with 'new_name' already exists in lvolstore */ 1519 TAILQ_FOREACH(tmp, &lvol->lvol_store->lvols, link) { 1520 if (strncmp(tmp->name, new_name, SPDK_LVOL_NAME_MAX) == 0) { 1521 SPDK_ERRLOG("Lvol %s already exists in lvol store %s\n", new_name, lvol->lvol_store->name); 1522 cb_fn(cb_arg, -EEXIST); 1523 return; 1524 } 1525 } 1526 1527 req = calloc(1, sizeof(*req)); 1528 if (!req) { 1529 SPDK_ERRLOG("Cannot alloc memory for lvol request pointer\n"); 1530 cb_fn(cb_arg, -ENOMEM); 1531 return; 1532 } 1533 req->cb_fn = cb_fn; 1534 req->cb_arg = cb_arg; 1535 req->lvol = lvol; 1536 snprintf(req->name, sizeof(req->name), "%s", new_name); 1537 1538 rc = spdk_blob_set_xattr(blob, "name", new_name, strlen(new_name) + 1); 1539 if (rc < 0) { 1540 free(req); 1541 cb_fn(cb_arg, rc); 1542 return; 1543 } 1544 1545 spdk_blob_sync_md(blob, lvol_rename_cb, req); 1546 } 1547 1548 void 1549 spdk_lvol_destroy(struct spdk_lvol *lvol, spdk_lvol_op_complete cb_fn, void *cb_arg) 1550 { 1551 struct spdk_lvol_req *req; 1552 struct spdk_blob_store *bs; 1553 struct spdk_lvol_store *lvs; 1554 spdk_blob_id clone_id; 1555 size_t count = 1; 1556 int rc; 1557 1558 assert(cb_fn != NULL); 1559 1560 if (lvol == NULL) { 1561 SPDK_ERRLOG("lvol does not exist\n"); 1562 cb_fn(cb_arg, -ENODEV); 1563 return; 1564 } 1565 1566 lvs = lvol->lvol_store; 1567 1568 if (lvol->ref_count != 0) { 1569 SPDK_ERRLOG("Cannot destroy lvol %s because it is still open\n", lvol->unique_id); 1570 cb_fn(cb_arg, -EBUSY); 1571 return; 1572 } 1573 1574 req = calloc(1, sizeof(*req)); 1575 if (!req) { 1576 SPDK_ERRLOG("Cannot alloc memory for lvol request pointer\n"); 1577 cb_fn(cb_arg, -ENOMEM); 1578 return; 1579 } 1580 1581 req->cb_fn = cb_fn; 1582 req->cb_arg = cb_arg; 1583 req->lvol = lvol; 1584 bs = lvol->lvol_store->blobstore; 1585 1586 rc = spdk_blob_get_clones(lvs->blobstore, lvol->blob_id, &clone_id, &count); 1587 if (rc == 0 && count == 1) { 1588 req->clone_lvol = lvs_get_lvol_by_blob_id(lvs, clone_id); 1589 } else if (rc == -ENOMEM) { 1590 SPDK_INFOLOG(lvol, "lvol %s: cannot destroy: has %" PRIu64 " clones\n", 1591 lvol->unique_id, count); 1592 free(req); 1593 assert(count > 1); 1594 cb_fn(cb_arg, -EBUSY); 1595 return; 1596 } 1597 1598 lvol->action_in_progress = true; 1599 1600 spdk_bs_delete_blob(bs, lvol->blob_id, lvol_delete_blob_cb, req); 1601 } 1602 1603 void 1604 spdk_lvol_close(struct spdk_lvol *lvol, spdk_lvol_op_complete cb_fn, void *cb_arg) 1605 { 1606 struct spdk_lvol_req *req; 1607 1608 assert(cb_fn != NULL); 1609 1610 if (lvol == NULL) { 1611 SPDK_ERRLOG("lvol does not exist\n"); 1612 cb_fn(cb_arg, -ENODEV); 1613 return; 1614 } 1615 1616 if (lvol->ref_count > 1) { 1617 lvol->ref_count--; 1618 cb_fn(cb_arg, 0); 1619 return; 1620 } else if (lvol->ref_count == 0) { 1621 cb_fn(cb_arg, -EINVAL); 1622 return; 1623 } 1624 1625 req = calloc(1, sizeof(*req)); 1626 if (!req) { 1627 SPDK_ERRLOG("Cannot alloc memory for lvol request pointer\n"); 1628 cb_fn(cb_arg, -ENOMEM); 1629 return; 1630 } 1631 1632 req->cb_fn = cb_fn; 1633 req->cb_arg = cb_arg; 1634 req->lvol = lvol; 1635 1636 lvol->action_in_progress = true; 1637 1638 spdk_blob_close(lvol->blob, lvol_close_blob_cb, req); 1639 } 1640 1641 struct spdk_io_channel * 1642 spdk_lvol_get_io_channel(struct spdk_lvol *lvol) 1643 { 1644 return spdk_bs_alloc_io_channel(lvol->lvol_store->blobstore); 1645 } 1646 1647 static void 1648 lvol_inflate_cb(void *cb_arg, int lvolerrno) 1649 { 1650 struct spdk_lvol_req *req = cb_arg; 1651 1652 spdk_bs_free_io_channel(req->channel); 1653 1654 if (lvolerrno < 0) { 1655 SPDK_ERRLOG("Could not inflate lvol\n"); 1656 } 1657 1658 req->cb_fn(req->cb_arg, lvolerrno); 1659 free(req); 1660 } 1661 1662 void 1663 spdk_lvol_inflate(struct spdk_lvol *lvol, spdk_lvol_op_complete cb_fn, void *cb_arg) 1664 { 1665 struct spdk_lvol_req *req; 1666 spdk_blob_id blob_id; 1667 1668 assert(cb_fn != NULL); 1669 1670 if (lvol == NULL) { 1671 SPDK_ERRLOG("Lvol does not exist\n"); 1672 cb_fn(cb_arg, -ENODEV); 1673 return; 1674 } 1675 1676 req = calloc(1, sizeof(*req)); 1677 if (!req) { 1678 SPDK_ERRLOG("Cannot alloc memory for lvol request pointer\n"); 1679 cb_fn(cb_arg, -ENOMEM); 1680 return; 1681 } 1682 1683 req->cb_fn = cb_fn; 1684 req->cb_arg = cb_arg; 1685 req->channel = spdk_bs_alloc_io_channel(lvol->lvol_store->blobstore); 1686 if (req->channel == NULL) { 1687 SPDK_ERRLOG("Cannot alloc io channel for lvol inflate request\n"); 1688 free(req); 1689 cb_fn(cb_arg, -ENOMEM); 1690 return; 1691 } 1692 1693 blob_id = spdk_blob_get_id(lvol->blob); 1694 spdk_bs_inflate_blob(lvol->lvol_store->blobstore, req->channel, blob_id, lvol_inflate_cb, 1695 req); 1696 } 1697 1698 void 1699 spdk_lvol_decouple_parent(struct spdk_lvol *lvol, spdk_lvol_op_complete cb_fn, void *cb_arg) 1700 { 1701 struct spdk_lvol_req *req; 1702 spdk_blob_id blob_id; 1703 1704 assert(cb_fn != NULL); 1705 1706 if (lvol == NULL) { 1707 SPDK_ERRLOG("Lvol does not exist\n"); 1708 cb_fn(cb_arg, -ENODEV); 1709 return; 1710 } 1711 1712 req = calloc(1, sizeof(*req)); 1713 if (!req) { 1714 SPDK_ERRLOG("Cannot alloc memory for lvol request pointer\n"); 1715 cb_fn(cb_arg, -ENOMEM); 1716 return; 1717 } 1718 1719 req->cb_fn = cb_fn; 1720 req->cb_arg = cb_arg; 1721 req->channel = spdk_bs_alloc_io_channel(lvol->lvol_store->blobstore); 1722 if (req->channel == NULL) { 1723 SPDK_ERRLOG("Cannot alloc io channel for lvol inflate request\n"); 1724 free(req); 1725 cb_fn(cb_arg, -ENOMEM); 1726 return; 1727 } 1728 1729 blob_id = spdk_blob_get_id(lvol->blob); 1730 spdk_bs_blob_decouple_parent(lvol->lvol_store->blobstore, req->channel, blob_id, 1731 lvol_inflate_cb, req); 1732 } 1733 1734 static void 1735 lvs_grow_live_cb(void *cb_arg, int lvolerrno) 1736 { 1737 struct spdk_lvs_req *req = (struct spdk_lvs_req *)cb_arg; 1738 1739 if (req->cb_fn) { 1740 req->cb_fn(req->cb_arg, lvolerrno); 1741 } 1742 free(req); 1743 return; 1744 } 1745 1746 void 1747 spdk_lvs_grow_live(struct spdk_lvol_store *lvs, spdk_lvs_op_complete cb_fn, void *cb_arg) 1748 { 1749 struct spdk_lvs_req *req; 1750 1751 req = calloc(1, sizeof(*req)); 1752 if (req == NULL) { 1753 SPDK_ERRLOG("Cannot alloc memory for request structure\n"); 1754 if (cb_fn) { 1755 cb_fn(cb_arg, -ENOMEM); 1756 } 1757 return; 1758 } 1759 1760 req->cb_fn = cb_fn; 1761 req->cb_arg = cb_arg; 1762 req->lvol_store = lvs; 1763 1764 spdk_bs_grow_live(lvs->blobstore, lvs_grow_live_cb, req); 1765 } 1766 1767 void 1768 spdk_lvs_grow(struct spdk_bs_dev *bs_dev, spdk_lvs_op_with_handle_complete cb_fn, void *cb_arg) 1769 { 1770 struct spdk_lvs_with_handle_req *req; 1771 struct spdk_bs_opts opts = {}; 1772 1773 assert(cb_fn != NULL); 1774 1775 if (bs_dev == NULL) { 1776 SPDK_ERRLOG("Blobstore device does not exist\n"); 1777 cb_fn(cb_arg, NULL, -ENODEV); 1778 return; 1779 } 1780 1781 req = calloc(1, sizeof(*req)); 1782 if (req == NULL) { 1783 SPDK_ERRLOG("Cannot alloc memory for request structure\n"); 1784 cb_fn(cb_arg, NULL, -ENOMEM); 1785 return; 1786 } 1787 1788 req->lvol_store = lvs_alloc(); 1789 if (req->lvol_store == NULL) { 1790 SPDK_ERRLOG("Cannot alloc memory for lvol store\n"); 1791 free(req); 1792 cb_fn(cb_arg, NULL, -ENOMEM); 1793 return; 1794 } 1795 req->cb_fn = cb_fn; 1796 req->cb_arg = cb_arg; 1797 req->bs_dev = bs_dev; 1798 1799 lvs_bs_opts_init(&opts); 1800 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "LVOLSTORE"); 1801 1802 spdk_bs_grow(bs_dev, &opts, lvs_load_cb, req); 1803 } 1804 1805 static struct spdk_lvol * 1806 lvs_get_lvol_by_blob_id(struct spdk_lvol_store *lvs, spdk_blob_id blob_id) 1807 { 1808 struct spdk_lvol *lvol; 1809 1810 TAILQ_FOREACH(lvol, &lvs->lvols, link) { 1811 if (lvol->blob_id == blob_id) { 1812 return lvol; 1813 } 1814 } 1815 return NULL; 1816 } 1817 1818 static int 1819 lvs_esnap_bs_dev_create(void *bs_ctx, void *blob_ctx, struct spdk_blob *blob, 1820 const void *esnap_id, uint32_t id_len, 1821 struct spdk_bs_dev **bs_dev) 1822 { 1823 struct spdk_lvol_store *lvs = bs_ctx; 1824 struct spdk_lvol *lvol = blob_ctx; 1825 spdk_blob_id blob_id = spdk_blob_get_id(blob); 1826 1827 if (lvs == NULL) { 1828 if (lvol == NULL || lvol->lvol_store == NULL) { 1829 SPDK_ERRLOG("Blob 0x%" PRIx64 ": no lvs context nor lvol context\n", 1830 blob_id); 1831 return -EINVAL; 1832 } 1833 lvs = lvol->lvol_store; 1834 } 1835 1836 /* 1837 * When spdk_lvs_load() is called, it iterates through all blobs in its blobstore building 1838 * up a list of lvols (lvs->lvols). During this initial iteration, each blob is opened, 1839 * passed to load_next_lvol(), then closed. There is no need to open the external snapshot 1840 * during this phase. Once the blobstore is loaded, lvs->load_esnaps is set to true so that 1841 * future lvol opens cause the external snapshot to be loaded. 1842 */ 1843 if (!lvs->load_esnaps) { 1844 *bs_dev = NULL; 1845 return 0; 1846 } 1847 1848 if (lvol == NULL) { 1849 spdk_blob_id blob_id = spdk_blob_get_id(blob); 1850 1851 /* 1852 * If spdk_bs_blob_open() is used instead of spdk_bs_blob_open_ext() the lvol will 1853 * not have been passed in. The same is true if the open happens spontaneously due 1854 * to blobstore activity. 1855 */ 1856 lvol = lvs_get_lvol_by_blob_id(lvs, blob_id); 1857 if (lvol == NULL) { 1858 SPDK_ERRLOG("lvstore %s: no lvol for blob 0x%" PRIx64 "\n", 1859 lvs->name, blob_id); 1860 return -ENODEV; 1861 } 1862 } 1863 1864 return lvs->esnap_bs_dev_create(lvs, lvol, blob, esnap_id, id_len, bs_dev); 1865 } 1866 1867 /* 1868 * The theory of missing external snapshots 1869 * 1870 * The lvs->esnap_bs_dev_create() callback may be unable to create an external snapshot bs_dev when 1871 * it is called. This can happen, for instance, as when the device containing the lvolstore is 1872 * examined prior to spdk_bdev_register() being called on a bdev that acts as an external snapshot. 1873 * In such a case, the esnap_bs_dev_create() callback will call spdk_lvs_esnap_missing_add(). 1874 * 1875 * Missing external snapshots are tracked in a per-lvolstore tree, lvs->degraded_lvol_sets_tree. 1876 * Each tree node (struct spdk_lvs_degraded_lvol_set) contains a tailq of lvols that are missing 1877 * that particular external snapshot. 1878 * 1879 * When a potential missing snapshot becomes available, spdk_lvs_notify_hotplug() may be called to 1880 * notify this library that it is available. It will then iterate through the active lvolstores and 1881 * search each lvs->degraded_lvol_sets_tree for a set of degraded lvols that are missing an external 1882 * snapshot matching the id passed in the notification. The lvols in the tailq on each matching tree 1883 * node are then asked to create an external snapshot bs_dev using the esnap_bs_dev_create() 1884 * callback that the consumer registered with the lvolstore. If lvs->esnap_bs_dev_create() returns 1885 * 0, the lvol is removed from the spdk_lvs_degraded_lvol_set's lvol tailq. When this tailq becomes 1886 * empty, the degraded lvol set node for this missing external snapshot is removed. 1887 */ 1888 static int 1889 lvs_esnap_name_cmp(struct spdk_lvs_degraded_lvol_set *m1, struct spdk_lvs_degraded_lvol_set *m2) 1890 { 1891 if (m1->id_len == m2->id_len) { 1892 return memcmp(m1->esnap_id, m2->esnap_id, m1->id_len); 1893 } 1894 return (m1->id_len > m2->id_len) ? 1 : -1; 1895 } 1896 1897 RB_GENERATE_STATIC(degraded_lvol_sets_tree, spdk_lvs_degraded_lvol_set, node, lvs_esnap_name_cmp) 1898 1899 static void 1900 lvs_degraded_lvol_set_add(struct spdk_lvs_degraded_lvol_set *degraded_set, struct spdk_lvol *lvol) 1901 { 1902 assert(lvol->lvol_store->thread == spdk_get_thread()); 1903 1904 lvol->degraded_set = degraded_set; 1905 TAILQ_INSERT_TAIL(°raded_set->lvols, lvol, degraded_link); 1906 } 1907 1908 static void 1909 lvs_degraded_lvol_set_remove(struct spdk_lvs_degraded_lvol_set *degraded_set, 1910 struct spdk_lvol *lvol) 1911 { 1912 assert(lvol->lvol_store->thread == spdk_get_thread()); 1913 1914 lvol->degraded_set = NULL; 1915 TAILQ_REMOVE(°raded_set->lvols, lvol, degraded_link); 1916 /* degraded_set->lvols may be empty. Caller should check if not immediately adding a new 1917 * lvol. */ 1918 } 1919 1920 /* 1921 * Record in lvs->degraded_lvol_sets_tree that a bdev of the specified name is needed by the 1922 * specified lvol. 1923 */ 1924 int 1925 spdk_lvs_esnap_missing_add(struct spdk_lvol_store *lvs, struct spdk_lvol *lvol, 1926 const void *esnap_id, uint32_t id_len) 1927 { 1928 struct spdk_lvs_degraded_lvol_set find, *degraded_set; 1929 1930 assert(lvs->thread == spdk_get_thread()); 1931 1932 find.esnap_id = esnap_id; 1933 find.id_len = id_len; 1934 degraded_set = RB_FIND(degraded_lvol_sets_tree, &lvs->degraded_lvol_sets_tree, &find); 1935 if (degraded_set == NULL) { 1936 degraded_set = calloc(1, sizeof(*degraded_set)); 1937 if (degraded_set == NULL) { 1938 SPDK_ERRLOG("lvol %s: cannot create degraded_set node: out of memory\n", 1939 lvol->unique_id); 1940 return -ENOMEM; 1941 } 1942 degraded_set->esnap_id = calloc(1, id_len); 1943 if (degraded_set->esnap_id == NULL) { 1944 free(degraded_set); 1945 SPDK_ERRLOG("lvol %s: cannot create degraded_set node: out of memory\n", 1946 lvol->unique_id); 1947 return -ENOMEM; 1948 } 1949 memcpy((void *)degraded_set->esnap_id, esnap_id, id_len); 1950 degraded_set->id_len = id_len; 1951 degraded_set->lvol_store = lvs; 1952 TAILQ_INIT(°raded_set->lvols); 1953 RB_INSERT(degraded_lvol_sets_tree, &lvs->degraded_lvol_sets_tree, degraded_set); 1954 } 1955 1956 lvs_degraded_lvol_set_add(degraded_set, lvol); 1957 1958 return 0; 1959 } 1960 1961 /* 1962 * Remove the record of the specified lvol needing a degraded_set bdev. 1963 */ 1964 void 1965 spdk_lvs_esnap_missing_remove(struct spdk_lvol *lvol) 1966 { 1967 struct spdk_lvol_store *lvs = lvol->lvol_store; 1968 struct spdk_lvs_degraded_lvol_set *degraded_set = lvol->degraded_set; 1969 1970 assert(lvs->thread == spdk_get_thread()); 1971 1972 if (degraded_set == NULL) { 1973 return; 1974 } 1975 1976 lvs_degraded_lvol_set_remove(degraded_set, lvol); 1977 1978 if (!TAILQ_EMPTY(°raded_set->lvols)) { 1979 return; 1980 } 1981 1982 RB_REMOVE(degraded_lvol_sets_tree, &lvs->degraded_lvol_sets_tree, degraded_set); 1983 1984 free((char *)degraded_set->esnap_id); 1985 free(degraded_set); 1986 } 1987 1988 struct lvs_esnap_hotplug_req { 1989 struct spdk_lvol *lvol; 1990 spdk_lvol_op_with_handle_complete cb_fn; 1991 void *cb_arg; 1992 }; 1993 1994 static void 1995 lvs_esnap_hotplug_done(void *cb_arg, int bserrno) 1996 { 1997 struct lvs_esnap_hotplug_req *req = cb_arg; 1998 struct spdk_lvol *lvol = req->lvol; 1999 struct spdk_lvol_store *lvs = lvol->lvol_store; 2000 2001 if (bserrno != 0) { 2002 SPDK_ERRLOG("lvol %s/%s: failed to hotplug blob_bdev due to error %d\n", 2003 lvs->name, lvol->name, bserrno); 2004 } 2005 req->cb_fn(req->cb_arg, lvol, bserrno); 2006 free(req); 2007 } 2008 2009 static void 2010 lvs_esnap_degraded_hotplug(struct spdk_lvs_degraded_lvol_set *degraded_set, 2011 spdk_lvol_op_with_handle_complete cb_fn, void *cb_arg) 2012 { 2013 struct spdk_lvol_store *lvs = degraded_set->lvol_store; 2014 struct spdk_lvol *lvol, *tmp, *last_missing; 2015 struct spdk_bs_dev *bs_dev; 2016 const void *esnap_id = degraded_set->esnap_id; 2017 uint32_t id_len = degraded_set->id_len; 2018 struct lvs_esnap_hotplug_req *req; 2019 int rc; 2020 2021 assert(lvs->thread == spdk_get_thread()); 2022 2023 /* 2024 * When lvs->esnap_bs_bdev_create() tries to load an external snapshot, it can encounter 2025 * errors that lead it to calling spdk_lvs_esnap_missing_add(). This function needs to be 2026 * sure that such modifications do not lead to degraded_set->lvols tailqs or references 2027 * to memory that this function will free. 2028 * 2029 * While this function is running, no other thread can add items to degraded_set->lvols. If 2030 * the list is mutated, it must have been done by this function or something in its call 2031 * graph running on this thread. 2032 */ 2033 2034 /* Remember the last lvol on the list. Iteration will stop once it has been processed. */ 2035 last_missing = TAILQ_LAST(°raded_set->lvols, degraded_lvols); 2036 2037 TAILQ_FOREACH_SAFE(lvol, °raded_set->lvols, degraded_link, tmp) { 2038 req = calloc(1, sizeof(*req)); 2039 if (req == NULL) { 2040 SPDK_ERRLOG("lvol %s: failed to create esnap bs_dev: out of memory\n", 2041 lvol->unique_id); 2042 cb_fn(cb_arg, lvol, -ENOMEM); 2043 /* The next one likely won't succeed either, but keep going so that all the 2044 * failed hotplugs are logged. 2045 */ 2046 goto next; 2047 } 2048 2049 /* 2050 * Remove the lvol from the tailq so that tailq corruption is avoided if 2051 * lvs->esnap_bs_dev_create() calls spdk_lvs_esnap_missing_add(lvol). 2052 */ 2053 TAILQ_REMOVE(°raded_set->lvols, lvol, degraded_link); 2054 lvol->degraded_set = NULL; 2055 2056 bs_dev = NULL; 2057 rc = lvs->esnap_bs_dev_create(lvs, lvol, lvol->blob, esnap_id, id_len, &bs_dev); 2058 if (rc != 0) { 2059 SPDK_ERRLOG("lvol %s: failed to create esnap bs_dev: error %d\n", 2060 lvol->unique_id, rc); 2061 lvol->degraded_set = degraded_set; 2062 TAILQ_INSERT_TAIL(°raded_set->lvols, lvol, degraded_link); 2063 cb_fn(cb_arg, lvol, rc); 2064 free(req); 2065 goto next; 2066 } 2067 2068 req->lvol = lvol; 2069 req->cb_fn = cb_fn; 2070 req->cb_arg = cb_arg; 2071 spdk_blob_set_esnap_bs_dev(lvol->blob, bs_dev, lvs_esnap_hotplug_done, req); 2072 2073 next: 2074 if (lvol == last_missing) { 2075 /* 2076 * Anything after last_missing was added due to some problem encountered 2077 * while trying to create the esnap bs_dev. 2078 */ 2079 break; 2080 } 2081 } 2082 2083 if (TAILQ_EMPTY(°raded_set->lvols)) { 2084 RB_REMOVE(degraded_lvol_sets_tree, &lvs->degraded_lvol_sets_tree, degraded_set); 2085 free((void *)degraded_set->esnap_id); 2086 free(degraded_set); 2087 } 2088 } 2089 2090 /* 2091 * Notify each lvstore created on this thread that is missing a bdev by the specified name or uuid 2092 * that the bdev now exists. 2093 */ 2094 bool 2095 spdk_lvs_notify_hotplug(const void *esnap_id, uint32_t id_len, 2096 spdk_lvol_op_with_handle_complete cb_fn, void *cb_arg) 2097 { 2098 struct spdk_lvs_degraded_lvol_set *found; 2099 struct spdk_lvs_degraded_lvol_set find = { 0 }; 2100 struct spdk_lvol_store *lvs; 2101 struct spdk_thread *thread = spdk_get_thread(); 2102 bool ret = false; 2103 2104 find.esnap_id = esnap_id; 2105 find.id_len = id_len; 2106 2107 pthread_mutex_lock(&g_lvol_stores_mutex); 2108 TAILQ_FOREACH(lvs, &g_lvol_stores, link) { 2109 if (thread != lvs->thread) { 2110 /* 2111 * It is expected that this is called from vbdev_lvol's examine_config() 2112 * callback. The lvstore was likely loaded do a creation happening as a 2113 * result of an RPC call or opening of an existing lvstore via 2114 * examine_disk() callback. RPC calls, examine_disk(), and examine_config() 2115 * should all be happening only on the app thread. The "wrong thread" 2116 * condition will only happen when an application is doing something weird. 2117 */ 2118 SPDK_NOTICELOG("Discarded examine for lvstore %s: wrong thread\n", 2119 lvs->name); 2120 continue; 2121 } 2122 2123 found = RB_FIND(degraded_lvol_sets_tree, &lvs->degraded_lvol_sets_tree, &find); 2124 if (found == NULL) { 2125 continue; 2126 } 2127 2128 ret = true; 2129 lvs_esnap_degraded_hotplug(found, cb_fn, cb_arg); 2130 } 2131 pthread_mutex_unlock(&g_lvol_stores_mutex); 2132 2133 return ret; 2134 } 2135 2136 int 2137 spdk_lvol_iter_immediate_clones(struct spdk_lvol *lvol, spdk_lvol_iter_cb cb_fn, void *cb_arg) 2138 { 2139 struct spdk_lvol_store *lvs = lvol->lvol_store; 2140 struct spdk_blob_store *bs = lvs->blobstore; 2141 struct spdk_lvol *clone; 2142 spdk_blob_id *ids; 2143 size_t id_cnt = 0; 2144 size_t i; 2145 int rc; 2146 2147 rc = spdk_blob_get_clones(bs, lvol->blob_id, NULL, &id_cnt); 2148 if (rc != -ENOMEM) { 2149 /* -ENOMEM says id_cnt is valid, no other errors should be returned. */ 2150 assert(rc == 0); 2151 return rc; 2152 } 2153 2154 ids = calloc(id_cnt, sizeof(*ids)); 2155 if (ids == NULL) { 2156 SPDK_ERRLOG("lvol %s: out of memory while iterating clones\n", lvol->unique_id); 2157 return -ENOMEM; 2158 } 2159 2160 rc = spdk_blob_get_clones(bs, lvol->blob_id, ids, &id_cnt); 2161 if (rc != 0) { 2162 SPDK_ERRLOG("lvol %s: unable to get clone blob IDs: %d\n", lvol->unique_id, rc); 2163 free(ids); 2164 return rc; 2165 } 2166 2167 for (i = 0; i < id_cnt; i++) { 2168 clone = lvs_get_lvol_by_blob_id(lvs, ids[i]); 2169 if (clone == NULL) { 2170 SPDK_NOTICELOG("lvol %s: unable to find clone lvol with blob id 0x%" 2171 PRIx64 "\n", lvol->unique_id, ids[i]); 2172 continue; 2173 } 2174 rc = cb_fn(cb_arg, clone); 2175 if (rc != 0) { 2176 SPDK_DEBUGLOG(lvol, "lvol %s: iteration stopped when lvol %s (blob 0x%" 2177 PRIx64 ") returned %d\n", lvol->unique_id, clone->unique_id, 2178 ids[i], rc); 2179 break; 2180 } 2181 } 2182 2183 free(ids); 2184 return rc; 2185 } 2186 2187 struct spdk_lvol * 2188 spdk_lvol_get_by_uuid(const struct spdk_uuid *uuid) 2189 { 2190 struct spdk_lvol_store *lvs; 2191 struct spdk_lvol *lvol; 2192 2193 pthread_mutex_lock(&g_lvol_stores_mutex); 2194 2195 TAILQ_FOREACH(lvs, &g_lvol_stores, link) { 2196 TAILQ_FOREACH(lvol, &lvs->lvols, link) { 2197 if (spdk_uuid_compare(uuid, &lvol->uuid) == 0) { 2198 pthread_mutex_unlock(&g_lvol_stores_mutex); 2199 return lvol; 2200 } 2201 } 2202 } 2203 2204 pthread_mutex_unlock(&g_lvol_stores_mutex); 2205 return NULL; 2206 } 2207 2208 struct spdk_lvol * 2209 spdk_lvol_get_by_names(const char *lvs_name, const char *lvol_name) 2210 { 2211 struct spdk_lvol_store *lvs; 2212 struct spdk_lvol *lvol; 2213 2214 pthread_mutex_lock(&g_lvol_stores_mutex); 2215 2216 TAILQ_FOREACH(lvs, &g_lvol_stores, link) { 2217 if (strcmp(lvs_name, lvs->name) != 0) { 2218 continue; 2219 } 2220 TAILQ_FOREACH(lvol, &lvs->lvols, link) { 2221 if (strcmp(lvol_name, lvol->name) == 0) { 2222 pthread_mutex_unlock(&g_lvol_stores_mutex); 2223 return lvol; 2224 } 2225 } 2226 } 2227 2228 pthread_mutex_unlock(&g_lvol_stores_mutex); 2229 return NULL; 2230 } 2231 2232 bool 2233 spdk_lvol_is_degraded(const struct spdk_lvol *lvol) 2234 { 2235 struct spdk_blob *blob = lvol->blob; 2236 2237 if (blob == NULL) { 2238 return true; 2239 } 2240 return spdk_blob_is_degraded(blob); 2241 } 2242 2243 static void 2244 lvol_shallow_copy_cb(void *cb_arg, int lvolerrno) 2245 { 2246 struct spdk_lvol_copy_req *req = cb_arg; 2247 struct spdk_lvol *lvol = req->lvol; 2248 2249 spdk_bs_free_io_channel(req->channel); 2250 2251 if (lvolerrno < 0) { 2252 SPDK_ERRLOG("Could not make a shallow copy of lvol %s, error %d\n", lvol->unique_id, lvolerrno); 2253 } 2254 2255 req->cb_fn(req->cb_arg, lvolerrno); 2256 free(req); 2257 } 2258 2259 int 2260 spdk_lvol_shallow_copy(struct spdk_lvol *lvol, struct spdk_bs_dev *ext_dev, 2261 spdk_blob_shallow_copy_status status_cb_fn, void *status_cb_arg, 2262 spdk_lvol_op_complete cb_fn, void *cb_arg) 2263 { 2264 struct spdk_lvol_copy_req *req; 2265 spdk_blob_id blob_id; 2266 int rc; 2267 2268 assert(cb_fn != NULL); 2269 2270 if (lvol == NULL) { 2271 SPDK_ERRLOG("lvol must not be NULL\n"); 2272 return -EINVAL; 2273 } 2274 2275 assert(lvol->lvol_store->thread == spdk_get_thread()); 2276 2277 if (ext_dev == NULL) { 2278 SPDK_ERRLOG("lvol %s shallow copy, ext_dev must not be NULL\n", lvol->unique_id); 2279 return -EINVAL; 2280 } 2281 2282 req = calloc(1, sizeof(*req)); 2283 if (!req) { 2284 SPDK_ERRLOG("lvol %s shallow copy, cannot alloc memory for lvol request\n", lvol->unique_id); 2285 return -ENOMEM; 2286 } 2287 2288 req->lvol = lvol; 2289 req->cb_fn = cb_fn; 2290 req->cb_arg = cb_arg; 2291 req->channel = spdk_bs_alloc_io_channel(lvol->lvol_store->blobstore); 2292 if (req->channel == NULL) { 2293 SPDK_ERRLOG("lvol %s shallow copy, cannot alloc io channel for lvol request\n", lvol->unique_id); 2294 free(req); 2295 return -ENOMEM; 2296 } 2297 2298 blob_id = spdk_blob_get_id(lvol->blob); 2299 2300 rc = spdk_bs_blob_shallow_copy(lvol->lvol_store->blobstore, req->channel, blob_id, ext_dev, 2301 status_cb_fn, status_cb_arg, lvol_shallow_copy_cb, req); 2302 2303 if (rc < 0) { 2304 SPDK_ERRLOG("Could not make a shallow copy of lvol %s\n", lvol->unique_id); 2305 spdk_bs_free_io_channel(req->channel); 2306 free(req); 2307 } 2308 2309 return rc; 2310 } 2311 2312 static void 2313 lvol_set_parent_cb(void *cb_arg, int lvolerrno) 2314 { 2315 struct spdk_lvol_req *req = cb_arg; 2316 2317 if (lvolerrno < 0) { 2318 SPDK_ERRLOG("could not set parent of lvol %s, error %d\n", req->lvol->name, lvolerrno); 2319 } 2320 2321 req->cb_fn(req->cb_arg, lvolerrno); 2322 free(req); 2323 } 2324 2325 void 2326 spdk_lvol_set_parent(struct spdk_lvol *lvol, struct spdk_lvol *snapshot, 2327 spdk_lvol_op_complete cb_fn, void *cb_arg) 2328 { 2329 struct spdk_lvol_req *req; 2330 spdk_blob_id blob_id, snapshot_id; 2331 2332 assert(cb_fn != NULL); 2333 2334 if (lvol == NULL) { 2335 SPDK_ERRLOG("lvol must not be NULL\n"); 2336 cb_fn(cb_arg, -EINVAL); 2337 return; 2338 } 2339 2340 if (snapshot == NULL) { 2341 SPDK_ERRLOG("snapshot must not be NULL\n"); 2342 cb_fn(cb_arg, -EINVAL); 2343 return; 2344 } 2345 2346 req = calloc(1, sizeof(*req)); 2347 if (!req) { 2348 SPDK_ERRLOG("cannot alloc memory for lvol request pointer\n"); 2349 cb_fn(cb_arg, -ENOMEM); 2350 return; 2351 } 2352 2353 req->lvol = lvol; 2354 req->cb_fn = cb_fn; 2355 req->cb_arg = cb_arg; 2356 2357 blob_id = spdk_blob_get_id(lvol->blob); 2358 snapshot_id = spdk_blob_get_id(snapshot->blob); 2359 2360 spdk_bs_blob_set_parent(lvol->lvol_store->blobstore, blob_id, snapshot_id, 2361 lvol_set_parent_cb, req); 2362 } 2363 2364 static void 2365 lvol_set_external_parent_cb(void *cb_arg, int lvolerrno) 2366 { 2367 struct spdk_lvol_bs_dev_req *req = cb_arg; 2368 2369 if (lvolerrno < 0) { 2370 SPDK_ERRLOG("could not set external parent of lvol %s, error %d\n", req->lvol->name, lvolerrno); 2371 req->bs_dev->destroy(req->bs_dev); 2372 } 2373 2374 req->cb_fn(req->cb_arg, lvolerrno); 2375 free(req); 2376 } 2377 2378 void 2379 spdk_lvol_set_external_parent(struct spdk_lvol *lvol, const void *esnap_id, uint32_t esnap_id_len, 2380 spdk_lvol_op_complete cb_fn, void *cb_arg) 2381 { 2382 struct spdk_lvol_bs_dev_req *req; 2383 struct spdk_bs_dev *bs_dev; 2384 spdk_blob_id blob_id; 2385 int rc; 2386 2387 assert(cb_fn != NULL); 2388 2389 if (lvol == NULL) { 2390 SPDK_ERRLOG("lvol must not be NULL\n"); 2391 cb_fn(cb_arg, -EINVAL); 2392 return; 2393 } 2394 2395 if (esnap_id == NULL) { 2396 SPDK_ERRLOG("snapshot must not be NULL\n"); 2397 cb_fn(cb_arg, -EINVAL); 2398 return; 2399 } 2400 2401 if (esnap_id_len == sizeof(lvol->uuid_str) && 2402 memcmp(esnap_id, lvol->uuid_str, esnap_id_len) == 0) { 2403 SPDK_ERRLOG("lvol %s and esnap have the same UUID\n", lvol->name); 2404 cb_fn(cb_arg, -EINVAL); 2405 return; 2406 } 2407 2408 rc = lvs_esnap_bs_dev_create(lvol->lvol_store, lvol, lvol->blob, esnap_id, esnap_id_len, &bs_dev); 2409 if (rc < 0) { 2410 cb_fn(cb_arg, rc); 2411 return; 2412 } 2413 2414 req = calloc(1, sizeof(*req)); 2415 if (!req) { 2416 SPDK_ERRLOG("cannot alloc memory for lvol request pointer\n"); 2417 cb_fn(cb_arg, -ENOMEM); 2418 return; 2419 } 2420 2421 req->lvol = lvol; 2422 req->bs_dev = bs_dev; 2423 req->cb_fn = cb_fn; 2424 req->cb_arg = cb_arg; 2425 2426 blob_id = spdk_blob_get_id(lvol->blob); 2427 2428 spdk_bs_blob_set_external_parent(lvol->lvol_store->blobstore, blob_id, bs_dev, esnap_id, 2429 esnap_id_len, lvol_set_external_parent_cb, req); 2430 } 2431