1 /*- 2 * BSD LICENSE 3 * 4 * Copyright (c) Intel Corporation. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name of Intel Corporation nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include "spdk/opal.h" 35 #include "spdk/bdev_module.h" 36 #include "vbdev_opal.h" 37 #include "spdk_internal/log.h" 38 #include "spdk/string.h" 39 40 /* OPAL locking range only supports operations on nsid=1 for now */ 41 #define NSID_SUPPORTED 1 42 43 struct spdk_vbdev_opal_config { 44 char *nvme_ctrlr_name; 45 uint8_t locking_range_id; 46 uint64_t range_start; 47 uint64_t range_length; 48 SPDK_BDEV_PART_TAILQ *part_tailq; 49 struct vbdev_opal_part_base *opal_base; 50 }; 51 52 struct opal_vbdev { 53 char *name; 54 struct nvme_bdev_ctrlr *nvme_ctrlr; 55 struct spdk_opal_dev *opal_dev; 56 struct spdk_bdev_part *bdev_part; 57 struct spdk_vbdev_opal_config cfg; 58 59 TAILQ_ENTRY(opal_vbdev) tailq; 60 }; 61 62 static TAILQ_HEAD(, opal_vbdev) g_opal_vbdev = 63 TAILQ_HEAD_INITIALIZER(g_opal_vbdev); 64 65 struct vbdev_opal_bdev_io { 66 struct spdk_io_channel *ch; 67 struct spdk_bdev_io *bdev_io; 68 struct spdk_bdev_io_wait_entry bdev_io_wait; 69 }; 70 71 struct vbdev_opal_channel { 72 struct spdk_bdev_part_channel part_ch; 73 }; 74 75 struct vbdev_opal_part_base { 76 char *nvme_ctrlr_name; 77 struct spdk_bdev_part_base *part_base; 78 int num_of_part; 79 TAILQ_ENTRY(vbdev_opal_part_base) tailq; 80 }; 81 82 static TAILQ_HEAD(, vbdev_opal_part_base) g_opal_base = TAILQ_HEAD_INITIALIZER(g_opal_base); 83 84 static void _vbdev_opal_submit_request(struct spdk_io_channel *_ch, struct spdk_bdev_io *bdev_io); 85 86 static void vbdev_opal_examine(struct spdk_bdev *bdev); 87 88 static void 89 vbdev_opal_delete(struct opal_vbdev *opal_bdev) 90 { 91 TAILQ_REMOVE(&g_opal_vbdev, opal_bdev, tailq); 92 free(opal_bdev->name); 93 free(opal_bdev->cfg.nvme_ctrlr_name); 94 free(opal_bdev); 95 opal_bdev = NULL; 96 } 97 98 static void 99 vbdev_opal_clear(void) 100 { 101 struct opal_vbdev *opal_bdev, *tmp; 102 103 TAILQ_FOREACH_SAFE(opal_bdev, &g_opal_vbdev, tailq, tmp) { 104 vbdev_opal_delete(opal_bdev); 105 } 106 } 107 108 static int 109 vbdev_opal_init(void) 110 { 111 /* TODO */ 112 return 0; 113 } 114 115 static void 116 vbdev_opal_fini(void) 117 { 118 vbdev_opal_clear(); 119 } 120 121 static int 122 vbdev_opal_get_ctx_size(void) 123 { 124 return sizeof(struct vbdev_opal_bdev_io); 125 } 126 127 /* delete all the config of the same base bdev */ 128 static void 129 vbdev_opal_delete_all_base_config(struct vbdev_opal_part_base *base) 130 { 131 char *nvme_ctrlr_name = base->nvme_ctrlr_name; 132 struct opal_vbdev *bdev, *tmp_bdev; 133 134 TAILQ_FOREACH_SAFE(bdev, &g_opal_vbdev, tailq, tmp_bdev) { 135 if (!strcmp(nvme_ctrlr_name, bdev->nvme_ctrlr->name)) { 136 vbdev_opal_delete(bdev); 137 } 138 } 139 } 140 141 static int 142 vbdev_opal_destruct(void *ctx) 143 { 144 struct spdk_bdev_part *part = ctx; 145 146 return spdk_bdev_part_free(part); 147 } 148 149 static void 150 vbdev_opal_base_free(void *ctx) 151 { 152 struct vbdev_opal_part_base *base = ctx; 153 SPDK_BDEV_PART_TAILQ *part_tailq = spdk_bdev_part_base_get_tailq(base->part_base); 154 155 free(part_tailq); 156 free(base->nvme_ctrlr_name); 157 free(base); 158 } 159 160 static void 161 vbdev_opal_resubmit_io(void *arg) 162 { 163 struct vbdev_opal_bdev_io *io_ctx = (struct vbdev_opal_bdev_io *)arg; 164 165 _vbdev_opal_submit_request(io_ctx->ch, io_ctx->bdev_io); 166 } 167 168 static void 169 vbdev_opal_queue_io(struct vbdev_opal_bdev_io *io_ctx) 170 { 171 struct vbdev_opal_channel *ch = spdk_io_channel_get_ctx(io_ctx->ch); 172 int rc; 173 174 io_ctx->bdev_io_wait.bdev = io_ctx->bdev_io->bdev; 175 io_ctx->bdev_io_wait.cb_fn = vbdev_opal_resubmit_io; 176 io_ctx->bdev_io_wait.cb_arg = io_ctx; 177 178 rc = spdk_bdev_queue_io_wait(io_ctx->bdev_io->bdev, ch->part_ch.base_ch, &io_ctx->bdev_io_wait); 179 180 if (rc != 0) { 181 SPDK_ERRLOG("Queue io failed in vbdev_opal_queue_io: %d\n", rc); 182 spdk_bdev_io_complete(io_ctx->bdev_io, SPDK_BDEV_IO_STATUS_FAILED); 183 } 184 } 185 186 static void 187 _vbdev_opal_submit_request(struct spdk_io_channel *_ch, struct spdk_bdev_io *bdev_io) 188 { 189 struct vbdev_opal_channel *ch = spdk_io_channel_get_ctx(_ch); 190 struct vbdev_opal_bdev_io *io_ctx = (struct vbdev_opal_bdev_io *)bdev_io->driver_ctx; 191 int rc; 192 193 rc = spdk_bdev_part_submit_request(&ch->part_ch, bdev_io); 194 if (rc) { 195 if (rc == -ENOMEM) { 196 SPDK_DEBUGLOG(SPDK_LOG_VBDEV_OPAL, "opal: no memory, queue io.\n"); 197 io_ctx->ch = _ch; 198 io_ctx->bdev_io = bdev_io; 199 vbdev_opal_queue_io(io_ctx); 200 } else { 201 SPDK_ERRLOG("opal: error on io submission, rc=%d.\n", rc); 202 spdk_bdev_io_complete(bdev_io, SPDK_BDEV_IO_STATUS_FAILED); 203 } 204 } 205 } 206 207 static void 208 vbdev_opal_io_get_buf_cb(struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_io, bool success) 209 { 210 if (!success) { 211 spdk_bdev_io_complete(bdev_io, SPDK_BDEV_IO_STATUS_FAILED); 212 return; 213 } 214 215 _vbdev_opal_submit_request(ch, bdev_io); 216 } 217 218 static void 219 vbdev_opal_submit_request(struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_io) 220 { 221 switch (bdev_io->type) { 222 case SPDK_BDEV_IO_TYPE_READ: 223 spdk_bdev_io_get_buf(bdev_io, vbdev_opal_io_get_buf_cb, 224 bdev_io->u.bdev.num_blocks * bdev_io->bdev->blocklen); 225 break; 226 default: 227 _vbdev_opal_submit_request(ch, bdev_io); 228 break; 229 } 230 } 231 232 struct spdk_opal_locking_range_info * 233 spdk_vbdev_opal_get_info_from_bdev(const char *opal_bdev_name, const char *password) 234 { 235 struct opal_vbdev *vbdev; 236 struct nvme_bdev_ctrlr *nvme_ctrlr; 237 int locking_range_id; 238 int rc; 239 240 TAILQ_FOREACH(vbdev, &g_opal_vbdev, tailq) { 241 if (strcmp(vbdev->name, opal_bdev_name) == 0) { 242 break; 243 } 244 } 245 246 if (vbdev == NULL) { 247 SPDK_ERRLOG("%s not found\n", opal_bdev_name); 248 return NULL; 249 } 250 251 nvme_ctrlr = vbdev->nvme_ctrlr; 252 if (nvme_ctrlr == NULL) { 253 SPDK_ERRLOG("can't find nvme_ctrlr of %s\n", vbdev->name); 254 return NULL; 255 } 256 257 if (spdk_opal_get_max_locking_ranges(nvme_ctrlr->opal_dev) == 0) { 258 rc = spdk_opal_cmd_get_max_ranges(nvme_ctrlr->opal_dev, password); 259 if (rc) { 260 SPDK_ERRLOG("Get locking range number failure: %d\n", rc); 261 return NULL; 262 } 263 } 264 265 locking_range_id = vbdev->cfg.locking_range_id; 266 rc = spdk_opal_cmd_get_locking_range_info(nvme_ctrlr->opal_dev, password, 267 OPAL_ADMIN1, locking_range_id); 268 if (rc) { 269 SPDK_ERRLOG("Get locking range info error: %d\n", rc); 270 return NULL; 271 } 272 273 return spdk_opal_get_locking_range_info(nvme_ctrlr->opal_dev, locking_range_id); 274 } 275 276 static int 277 vbdev_opal_dump_info_json(void *ctx, struct spdk_json_write_ctx *w) 278 { 279 struct spdk_bdev_part *part = ctx; 280 struct spdk_bdev *base_bdev = spdk_bdev_part_get_base_bdev(part); 281 uint64_t offset = spdk_bdev_part_get_offset_blocks(part); 282 283 spdk_json_write_named_object_begin(w, "opal"); 284 285 spdk_json_write_named_string(w, "base_bdev", spdk_bdev_get_name(base_bdev)); 286 spdk_json_write_named_uint64(w, "offset_blocks", offset); 287 288 spdk_json_write_object_end(w); 289 290 return 0; 291 } 292 293 static void 294 vbdev_opal_base_bdev_hotremove_cb(void *_part_base) 295 { 296 struct spdk_bdev_part_base *part_base = _part_base; 297 struct vbdev_opal_part_base *base = spdk_bdev_part_base_get_ctx(part_base); 298 299 spdk_bdev_part_base_hotremove(part_base, spdk_bdev_part_base_get_tailq(part_base)); 300 vbdev_opal_delete_all_base_config(base); 301 } 302 303 static bool 304 vbdev_opal_io_type_supported(void *ctx, enum spdk_bdev_io_type io_type) 305 { 306 struct spdk_bdev_part *part = ctx; 307 struct spdk_bdev *base_bdev = spdk_bdev_part_get_base_bdev(part); 308 309 return spdk_bdev_io_type_supported(base_bdev, io_type); 310 } 311 312 static struct spdk_bdev_fn_table opal_vbdev_fn_table = { 313 .destruct = vbdev_opal_destruct, 314 .submit_request = vbdev_opal_submit_request, 315 .io_type_supported = vbdev_opal_io_type_supported, 316 .dump_info_json = vbdev_opal_dump_info_json, 317 .write_config_json = NULL, 318 }; 319 320 static struct spdk_bdev_module opal_if = { 321 .name = "opal", 322 .module_init = vbdev_opal_init, 323 .module_fini = vbdev_opal_fini, 324 .get_ctx_size = vbdev_opal_get_ctx_size, 325 .examine_config = vbdev_opal_examine, 326 .config_json = NULL, 327 }; 328 329 SPDK_BDEV_MODULE_REGISTER(opal, &opal_if) 330 331 static void 332 vbdev_opal_free_bdev(struct opal_vbdev *opal_bdev) 333 { 334 free(opal_bdev->cfg.nvme_ctrlr_name); 335 free(opal_bdev); 336 } 337 338 int 339 spdk_vbdev_opal_create(const char *nvme_ctrlr_name, uint32_t nsid, uint8_t locking_range_id, 340 uint64_t range_start, uint64_t range_length, const char *password) 341 { 342 int rc; 343 char *opal_vbdev_name; 344 char *base_bdev_name; 345 struct nvme_bdev_ctrlr *nvme_ctrlr; 346 struct opal_vbdev *opal_bdev; 347 struct vbdev_opal_part_base *opal_part_base; 348 struct spdk_bdev_part *part_bdev; 349 SPDK_BDEV_PART_TAILQ *part_tailq; 350 struct spdk_vbdev_opal_config *cfg; 351 struct nvme_bdev *nvme_bdev; 352 353 if (nsid != NSID_SUPPORTED) { 354 SPDK_ERRLOG("nsid %d not supported", nsid); 355 return -EINVAL; 356 } 357 358 nvme_ctrlr = nvme_bdev_ctrlr_get_by_name(nvme_ctrlr_name); 359 if (!nvme_ctrlr) { 360 SPDK_ERRLOG("get nvme ctrlr failed\n"); 361 return -ENODEV; 362 } 363 364 if (nvme_ctrlr->opal_dev == NULL) { 365 SPDK_ERRLOG("Opal not supported\n"); 366 return -ENODEV; 367 } 368 369 opal_bdev = calloc(1, sizeof(struct opal_vbdev)); 370 if (!opal_bdev) { 371 SPDK_ERRLOG("allocation for opal_bdev failed\n"); 372 return -ENOMEM; 373 } 374 375 cfg = &opal_bdev->cfg; 376 cfg->nvme_ctrlr_name = strdup(nvme_ctrlr_name); 377 if (!cfg->nvme_ctrlr_name) { 378 SPDK_ERRLOG("allocation for nvme_ctrlr_name failed\n"); 379 free(opal_bdev); 380 return -ENOMEM; 381 } 382 383 cfg->locking_range_id = locking_range_id; 384 cfg->range_start = range_start; 385 cfg->range_length = range_length; 386 387 opal_bdev->nvme_ctrlr = nvme_ctrlr; 388 opal_bdev->opal_dev = nvme_ctrlr->opal_dev; 389 if (!spdk_opal_supported(opal_bdev->opal_dev)) { 390 SPDK_ERRLOG("Opal not supported\n"); 391 vbdev_opal_free_bdev(opal_bdev); 392 return -EINVAL; 393 } 394 395 nvme_bdev = TAILQ_FIRST(&nvme_ctrlr->namespaces[nsid - 1]->bdevs); 396 assert(nvme_bdev != NULL); 397 base_bdev_name = nvme_bdev->disk.name; 398 399 /* traverse base list to see if part_base is already create for this base bdev */ 400 TAILQ_FOREACH(opal_part_base, &g_opal_base, tailq) { 401 if (!strcmp(spdk_bdev_part_base_get_bdev_name(opal_part_base->part_base), base_bdev_name)) { 402 cfg->opal_base = opal_part_base; 403 } 404 } 405 406 /* If there is not a corresponding opal_part_base, a new opal_part_base will be created. 407 For each new part_base, there will be one tailq to store all the parts of this base */ 408 if (cfg->opal_base == NULL) { 409 part_tailq = calloc(1, sizeof(*part_tailq)); 410 if (part_tailq == NULL) { 411 SPDK_ERRLOG("Could not allocate bdev_part_tailq\n"); 412 vbdev_opal_free_bdev(opal_bdev); 413 return -ENOMEM; 414 } 415 416 TAILQ_INIT(part_tailq); 417 cfg->part_tailq = part_tailq; 418 opal_part_base = calloc(1, sizeof(*opal_part_base)); 419 if (opal_part_base == NULL) { 420 SPDK_ERRLOG("Could not allocate opal_part_base\n"); 421 vbdev_opal_free_bdev(opal_bdev); 422 free(part_tailq); 423 return -ENOMEM; 424 } 425 426 opal_part_base->part_base = spdk_bdev_part_base_construct(spdk_bdev_get_by_name(base_bdev_name), 427 vbdev_opal_base_bdev_hotremove_cb, &opal_if, 428 &opal_vbdev_fn_table, part_tailq, vbdev_opal_base_free, opal_part_base, 429 sizeof(struct vbdev_opal_channel), NULL, NULL); 430 if (opal_part_base->part_base == NULL) { 431 SPDK_ERRLOG("Could not allocate part_base\n"); 432 vbdev_opal_free_bdev(opal_bdev); 433 free(part_tailq); 434 free(opal_part_base); 435 return -ENOMEM; 436 } 437 opal_part_base->num_of_part = 0; 438 opal_part_base->nvme_ctrlr_name = strdup(cfg->nvme_ctrlr_name); 439 if (opal_part_base->nvme_ctrlr_name == NULL) { 440 vbdev_opal_free_bdev(opal_bdev); 441 spdk_bdev_part_base_free(opal_part_base->part_base); 442 return -ENOMEM; 443 } 444 445 cfg->opal_base = opal_part_base; 446 TAILQ_INSERT_TAIL(&g_opal_base, opal_part_base, tailq); 447 } 448 449 part_bdev = calloc(1, sizeof(struct spdk_bdev_part)); 450 if (!part_bdev) { 451 SPDK_ERRLOG("Could not allocate part_bdev\n"); 452 vbdev_opal_free_bdev(opal_bdev); 453 return -ENOMEM; 454 } 455 456 TAILQ_INSERT_TAIL(&g_opal_vbdev, opal_bdev, tailq); 457 opal_vbdev_name = spdk_sprintf_alloc("%sr%" PRIu8, base_bdev_name, 458 cfg->locking_range_id); /* e.g.: nvme0n1r1 */ 459 if (opal_vbdev_name == NULL) { 460 SPDK_ERRLOG("Could not allocate opal_vbdev_name\n"); 461 rc = -ENOMEM; 462 goto err; 463 } 464 465 opal_bdev->name = opal_vbdev_name; 466 rc = spdk_opal_cmd_setup_locking_range(opal_bdev->opal_dev, OPAL_ADMIN1, 467 cfg->locking_range_id, cfg->range_start, cfg->range_length, password); 468 if (rc) { 469 SPDK_ERRLOG("Error construct %s\n", opal_vbdev_name); 470 goto err; 471 } 472 473 rc = spdk_bdev_part_construct(part_bdev, cfg->opal_base->part_base, opal_vbdev_name, 474 cfg->range_start, cfg->range_length, "Opal locking range"); 475 if (rc) { 476 SPDK_ERRLOG("Could not allocate bdev part\n"); 477 goto err; 478 } 479 480 /* lock this bdev initially */ 481 rc = spdk_opal_cmd_lock_unlock(opal_bdev->opal_dev, OPAL_ADMIN1, OPAL_RWLOCK, locking_range_id, 482 password); 483 if (rc) { 484 SPDK_ERRLOG("Error lock %s\n", opal_vbdev_name); 485 goto err; 486 } 487 488 opal_bdev->bdev_part = part_bdev; 489 cfg->opal_base->num_of_part++; 490 return 0; 491 492 err: 493 vbdev_opal_delete(opal_bdev); 494 free(part_bdev); 495 return rc; 496 } 497 498 static void 499 vbdev_opal_destruct_bdev(struct opal_vbdev *opal_bdev) 500 { 501 SPDK_BDEV_PART_TAILQ *opal_part_tailq; 502 struct spdk_bdev_part *part; 503 struct spdk_vbdev_opal_config *cfg = &opal_bdev->cfg; 504 505 if (cfg->opal_base != NULL) { 506 part = opal_bdev->bdev_part; 507 opal_part_tailq = spdk_bdev_part_base_get_tailq(cfg->opal_base->part_base); 508 if (opal_part_tailq == NULL) { 509 SPDK_ERRLOG("Can't get tailq for this opal_base\n"); 510 return; 511 } 512 if (cfg->range_start == spdk_bdev_part_get_offset_blocks(part)) { 513 if (cfg->opal_base->num_of_part <= 1) { 514 /* if there is only one part for this base, we can remove the base now */ 515 spdk_bdev_part_base_hotremove(cfg->opal_base->part_base, opal_part_tailq); 516 517 /* remove from the tailq vbdev_opal_part_base */ 518 TAILQ_REMOVE(&g_opal_base, cfg->opal_base, tailq); 519 } else { 520 spdk_bdev_unregister(spdk_bdev_part_get_bdev(part), NULL, NULL); 521 cfg->opal_base->num_of_part--; 522 } 523 } 524 } 525 vbdev_opal_delete(opal_bdev); 526 } 527 528 int 529 spdk_vbdev_opal_destruct(const char *bdev_name, const char *password) 530 { 531 struct spdk_vbdev_opal_config *cfg; 532 struct nvme_bdev_ctrlr *nvme_ctrlr; 533 int locking_range_id; 534 int rc; 535 struct opal_vbdev *opal_bdev; 536 537 TAILQ_FOREACH(opal_bdev, &g_opal_vbdev, tailq) { 538 if (strcmp(opal_bdev->name, bdev_name) == 0) { 539 break; 540 } 541 } 542 543 if (opal_bdev == NULL) { 544 SPDK_ERRLOG("%s not found\n", bdev_name); 545 rc = -ENODEV; 546 goto err; 547 } 548 549 cfg = &opal_bdev->cfg; 550 locking_range_id = cfg->locking_range_id; 551 552 nvme_ctrlr = opal_bdev->nvme_ctrlr; 553 if (nvme_ctrlr == NULL) { 554 SPDK_ERRLOG("can't find nvme_ctrlr of %s\n", bdev_name); 555 return -ENODEV; 556 } 557 558 /* secure erase locking range */ 559 rc = spdk_opal_cmd_erase_locking_range(nvme_ctrlr->opal_dev, OPAL_ADMIN1, locking_range_id, 560 password); 561 if (rc) { 562 SPDK_ERRLOG("opal erase locking range failed\n"); 563 goto err; 564 } 565 566 /* reset the locking range to 0 */ 567 rc = spdk_opal_cmd_setup_locking_range(nvme_ctrlr->opal_dev, OPAL_ADMIN1, locking_range_id, 0, 568 0, password); 569 if (rc) { 570 SPDK_ERRLOG("opal reset locking range failed\n"); 571 goto err; 572 } 573 574 spdk_opal_free_locking_range_info(opal_bdev->opal_dev, locking_range_id); 575 vbdev_opal_destruct_bdev(opal_bdev); 576 return 0; 577 578 err: 579 return rc; 580 } 581 582 static void 583 vbdev_opal_examine(struct spdk_bdev *bdev) 584 { 585 /* TODO */ 586 spdk_bdev_module_examine_done(&opal_if); 587 } 588 589 static int 590 vbdev_opal_recv_poll(void *arg) 591 { 592 struct nvme_bdev_ctrlr *nvme_ctrlr = arg; 593 int rc; 594 595 rc = spdk_opal_revert_poll(nvme_ctrlr->opal_dev); 596 if (rc == -EAGAIN) { 597 return -1; 598 } 599 600 /* receive end */ 601 spdk_poller_unregister(&nvme_ctrlr->opal_poller); 602 nvme_ctrlr->opal_poller = NULL; 603 return 1; 604 } 605 606 int 607 spdk_vbdev_opal_revert_tper(struct nvme_bdev_ctrlr *nvme_ctrlr, const char *password, 608 spdk_opal_revert_cb cb_fn, void *cb_ctx) 609 { 610 int rc; 611 612 rc = spdk_opal_cmd_revert_tper_async(nvme_ctrlr->opal_dev, password, cb_fn, cb_ctx); 613 if (rc) { 614 SPDK_ERRLOG("%s revert tper failure: %d\n", nvme_ctrlr->name, rc); 615 return rc; 616 } 617 nvme_ctrlr->opal_poller = spdk_poller_register(vbdev_opal_recv_poll, nvme_ctrlr, 50); 618 return 0; 619 } 620 621 int 622 spdk_vbdev_opal_set_lock_state(const char *bdev_name, uint16_t user_id, const char *password, 623 const char *lock_state) 624 { 625 struct nvme_bdev_ctrlr *nvme_ctrlr; 626 int locking_range_id; 627 int rc; 628 enum spdk_opal_lock_state state_flag; 629 struct opal_vbdev *opal_bdev; 630 631 TAILQ_FOREACH(opal_bdev, &g_opal_vbdev, tailq) { 632 if (strcmp(opal_bdev->name, bdev_name) == 0) { 633 break; 634 } 635 } 636 637 if (opal_bdev == NULL) { 638 SPDK_ERRLOG("%s not found\n", bdev_name); 639 return -ENODEV; 640 } 641 642 nvme_ctrlr = opal_bdev->nvme_ctrlr; 643 if (nvme_ctrlr == NULL) { 644 SPDK_ERRLOG("can't find nvme_ctrlr of %s\n", opal_bdev->name); 645 return -ENODEV; 646 } 647 648 if (strcasecmp(lock_state, "READWRITE") == 0) { 649 state_flag = OPAL_READWRITE; 650 } else if (strcasecmp(lock_state, "READONLY") == 0) { 651 state_flag = OPAL_READONLY; 652 } else if (strcasecmp(lock_state, "RWLOCK") == 0) { 653 state_flag = OPAL_RWLOCK; 654 } else { 655 SPDK_ERRLOG("Invalid OPAL lock state input\n"); 656 return -EINVAL; 657 } 658 659 locking_range_id = opal_bdev->cfg.locking_range_id; 660 rc = spdk_opal_cmd_lock_unlock(nvme_ctrlr->opal_dev, user_id, state_flag, locking_range_id, 661 password); 662 if (rc) { 663 SPDK_ERRLOG("%s lock/unlock failure: %d\n", bdev_name, rc); 664 } 665 666 return rc; 667 } 668 669 int 670 spdk_vbdev_opal_enable_new_user(const char *bdev_name, const char *admin_password, uint16_t user_id, 671 const char *user_password) 672 { 673 struct nvme_bdev_ctrlr *nvme_ctrlr; 674 int locking_range_id; 675 int rc; 676 struct opal_vbdev *opal_bdev; 677 678 TAILQ_FOREACH(opal_bdev, &g_opal_vbdev, tailq) { 679 if (strcmp(opal_bdev->name, bdev_name) == 0) { 680 break; 681 } 682 } 683 684 if (opal_bdev == NULL) { 685 SPDK_ERRLOG("%s not found\n", bdev_name); 686 return -ENODEV; 687 } 688 689 nvme_ctrlr = opal_bdev->nvme_ctrlr; 690 if (nvme_ctrlr == NULL) { 691 SPDK_ERRLOG("can't find nvme_ctrlr of %s\n", opal_bdev->name); 692 return -ENODEV; 693 } 694 695 rc = spdk_opal_cmd_enable_user(nvme_ctrlr->opal_dev, user_id, admin_password); 696 if (rc) { 697 SPDK_ERRLOG("%s enable user error: %d\n", bdev_name, rc); 698 return rc; 699 } 700 701 rc = spdk_opal_cmd_set_new_passwd(nvme_ctrlr->opal_dev, user_id, user_password, admin_password, 702 true); 703 if (rc) { 704 SPDK_ERRLOG("%s set user password error: %d\n", bdev_name, rc); 705 return rc; 706 } 707 708 locking_range_id = opal_bdev->cfg.locking_range_id; 709 rc = spdk_opal_cmd_add_user_to_locking_range(nvme_ctrlr->opal_dev, user_id, locking_range_id, 710 OPAL_READONLY, admin_password); 711 if (rc) { 712 SPDK_ERRLOG("%s add user READONLY priority error: %d\n", bdev_name, rc); 713 return rc; 714 } 715 716 rc = spdk_opal_cmd_add_user_to_locking_range(nvme_ctrlr->opal_dev, user_id, locking_range_id, 717 OPAL_READWRITE, admin_password); 718 if (rc) { 719 SPDK_ERRLOG("%s add user READWRITE priority error: %d\n", bdev_name, rc); 720 return rc; 721 } 722 723 return 0; 724 } 725 726 SPDK_LOG_REGISTER_COMPONENT("vbdev_opal", SPDK_LOG_VBDEV_OPAL) 727