ctl_backend_ramdisk.c (288215) | ctl_backend_ramdisk.c (288220) |
---|---|
1/*- 2 * Copyright (c) 2003, 2008 Silicon Graphics International Corp. 3 * Copyright (c) 2012 The FreeBSD Foundation 4 * All rights reserved. 5 * 6 * Portions of this software were developed by Edward Tomasz Napierala 7 * under sponsorship from the FreeBSD Foundation. 8 * --- 26 unchanged lines hidden (view full) --- 35 */ 36/* 37 * CAM Target Layer backend for a "fake" ramdisk. 38 * 39 * Author: Ken Merry <ken@FreeBSD.org> 40 */ 41 42#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2003, 2008 Silicon Graphics International Corp. 3 * Copyright (c) 2012 The FreeBSD Foundation 4 * All rights reserved. 5 * 6 * Portions of this software were developed by Edward Tomasz Napierala 7 * under sponsorship from the FreeBSD Foundation. 8 * --- 26 unchanged lines hidden (view full) --- 35 */ 36/* 37 * CAM Target Layer backend for a "fake" ramdisk. 38 * 39 * Author: Ken Merry <ken@FreeBSD.org> 40 */ 41 42#include <sys/cdefs.h> |
43__FBSDID("$FreeBSD: head/sys/cam/ctl/ctl_backend_ramdisk.c 288215 2015-09-25 10:14:39Z mav $"); | 43__FBSDID("$FreeBSD: head/sys/cam/ctl/ctl_backend_ramdisk.c 288220 2015-09-25 16:34:59Z mav $"); |
44 45#include <sys/param.h> 46#include <sys/systm.h> 47#include <sys/kernel.h> 48#include <sys/condvar.h> 49#include <sys/types.h> 50#include <sys/lock.h> 51#include <sys/mutex.h> --- 88 unchanged lines hidden (view full) --- 140}; 141 142MALLOC_DEFINE(M_RAMDISK, "ramdisk", "Memory used for CTL RAMdisk"); 143CTL_BACKEND_DECLARE(cbr, ctl_be_ramdisk_driver); 144 145int 146ctl_backend_ramdisk_init(void) 147{ | 44 45#include <sys/param.h> 46#include <sys/systm.h> 47#include <sys/kernel.h> 48#include <sys/condvar.h> 49#include <sys/types.h> 50#include <sys/lock.h> 51#include <sys/mutex.h> --- 88 unchanged lines hidden (view full) --- 140}; 141 142MALLOC_DEFINE(M_RAMDISK, "ramdisk", "Memory used for CTL RAMdisk"); 143CTL_BACKEND_DECLARE(cbr, ctl_be_ramdisk_driver); 144 145int 146ctl_backend_ramdisk_init(void) 147{ |
148 struct ctl_be_ramdisk_softc *softc; | 148 struct ctl_be_ramdisk_softc *softc = &rd_softc; |
149#ifdef CTL_RAMDISK_PAGES 150 int i; 151#endif 152 | 149#ifdef CTL_RAMDISK_PAGES 150 int i; 151#endif 152 |
153 154 softc = &rd_softc; 155 | |
156 memset(softc, 0, sizeof(*softc)); | 153 memset(softc, 0, sizeof(*softc)); |
157 | |
158 mtx_init(&softc->lock, "ctlramdisk", NULL, MTX_DEF); | 154 mtx_init(&softc->lock, "ctlramdisk", NULL, MTX_DEF); |
159 | |
160 STAILQ_INIT(&softc->lun_list); 161 softc->rd_size = 1024 * 1024; 162#ifdef CTL_RAMDISK_PAGES 163 softc->num_pages = softc->rd_size / PAGE_SIZE; 164 softc->ramdisk_pages = (uint8_t **)malloc(sizeof(uint8_t *) * 165 softc->num_pages, M_RAMDISK, 166 M_WAITOK); 167 for (i = 0; i < softc->num_pages; i++) --- 4 unchanged lines hidden (view full) --- 172#endif 173 174 return (0); 175} 176 177void 178ctl_backend_ramdisk_shutdown(void) 179{ | 155 STAILQ_INIT(&softc->lun_list); 156 softc->rd_size = 1024 * 1024; 157#ifdef CTL_RAMDISK_PAGES 158 softc->num_pages = softc->rd_size / PAGE_SIZE; 159 softc->ramdisk_pages = (uint8_t **)malloc(sizeof(uint8_t *) * 160 softc->num_pages, M_RAMDISK, 161 M_WAITOK); 162 for (i = 0; i < softc->num_pages; i++) --- 4 unchanged lines hidden (view full) --- 167#endif 168 169 return (0); 170} 171 172void 173ctl_backend_ramdisk_shutdown(void) 174{ |
180 struct ctl_be_ramdisk_softc *softc; | 175 struct ctl_be_ramdisk_softc *softc = &rd_softc; |
181 struct ctl_be_ramdisk_lun *lun, *next_lun; 182#ifdef CTL_RAMDISK_PAGES 183 int i; 184#endif 185 | 176 struct ctl_be_ramdisk_lun *lun, *next_lun; 177#ifdef CTL_RAMDISK_PAGES 178 int i; 179#endif 180 |
186 softc = &rd_softc; 187 | |
188 mtx_lock(&softc->lock); 189 for (lun = STAILQ_FIRST(&softc->lun_list); lun != NULL; lun = next_lun){ 190 /* 191 * Grab the next LUN. The current LUN may get removed by 192 * ctl_invalidate_lun(), which will call our LUN shutdown 193 * routine, if there is no outstanding I/O for this LUN. 194 */ 195 next_lun = STAILQ_NEXT(lun, links); --- 159 unchanged lines hidden (view full) --- 355 softc = be_lun->softc; 356 357 mtx_lock(&be_lun->queue_lock); 358 for (;;) { 359 io = (union ctl_io *)STAILQ_FIRST(&be_lun->cont_queue); 360 if (io != NULL) { 361 STAILQ_REMOVE(&be_lun->cont_queue, &io->io_hdr, 362 ctl_io_hdr, links); | 181 mtx_lock(&softc->lock); 182 for (lun = STAILQ_FIRST(&softc->lun_list); lun != NULL; lun = next_lun){ 183 /* 184 * Grab the next LUN. The current LUN may get removed by 185 * ctl_invalidate_lun(), which will call our LUN shutdown 186 * routine, if there is no outstanding I/O for this LUN. 187 */ 188 next_lun = STAILQ_NEXT(lun, links); --- 159 unchanged lines hidden (view full) --- 348 softc = be_lun->softc; 349 350 mtx_lock(&be_lun->queue_lock); 351 for (;;) { 352 io = (union ctl_io *)STAILQ_FIRST(&be_lun->cont_queue); 353 if (io != NULL) { 354 STAILQ_REMOVE(&be_lun->cont_queue, &io->io_hdr, 355 ctl_io_hdr, links); |
363 | |
364 mtx_unlock(&be_lun->queue_lock); | 356 mtx_unlock(&be_lun->queue_lock); |
365 | |
366 ctl_backend_ramdisk_continue(io); | 357 ctl_backend_ramdisk_continue(io); |
367 | |
368 mtx_lock(&be_lun->queue_lock); 369 continue; 370 } 371 372 /* 373 * If we get here, there is no work left in the queues, so 374 * just break out and let the task queue go to sleep. 375 */ 376 break; 377 } 378 mtx_unlock(&be_lun->queue_lock); 379} 380 381static int 382ctl_backend_ramdisk_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, 383 int flag, struct thread *td) 384{ | 358 mtx_lock(&be_lun->queue_lock); 359 continue; 360 } 361 362 /* 363 * If we get here, there is no work left in the queues, so 364 * just break out and let the task queue go to sleep. 365 */ 366 break; 367 } 368 mtx_unlock(&be_lun->queue_lock); 369} 370 371static int 372ctl_backend_ramdisk_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, 373 int flag, struct thread *td) 374{ |
385 struct ctl_be_ramdisk_softc *softc; | 375 struct ctl_be_ramdisk_softc *softc = &rd_softc; 376 struct ctl_lun_req *lun_req; |
386 int retval; 387 388 retval = 0; | 377 int retval; 378 379 retval = 0; |
389 softc = &rd_softc; 390 | |
391 switch (cmd) { | 380 switch (cmd) { |
392 case CTL_LUN_REQ: { 393 struct ctl_lun_req *lun_req; 394 | 381 case CTL_LUN_REQ: |
395 lun_req = (struct ctl_lun_req *)addr; | 382 lun_req = (struct ctl_lun_req *)addr; |
396 | |
397 switch (lun_req->reqtype) { 398 case CTL_LUNREQ_CREATE: 399 retval = ctl_backend_ramdisk_create(softc, lun_req); 400 break; 401 case CTL_LUNREQ_RM: 402 retval = ctl_backend_ramdisk_rm(softc, lun_req); 403 break; 404 case CTL_LUNREQ_MODIFY: 405 retval = ctl_backend_ramdisk_modify(softc, lun_req); 406 break; 407 default: 408 lun_req->status = CTL_LUN_ERROR; 409 snprintf(lun_req->error_str, sizeof(lun_req->error_str), 410 "%s: invalid LUN request type %d", __func__, 411 lun_req->reqtype); 412 break; 413 } 414 break; | 383 switch (lun_req->reqtype) { 384 case CTL_LUNREQ_CREATE: 385 retval = ctl_backend_ramdisk_create(softc, lun_req); 386 break; 387 case CTL_LUNREQ_RM: 388 retval = ctl_backend_ramdisk_rm(softc, lun_req); 389 break; 390 case CTL_LUNREQ_MODIFY: 391 retval = ctl_backend_ramdisk_modify(softc, lun_req); 392 break; 393 default: 394 lun_req->status = CTL_LUN_ERROR; 395 snprintf(lun_req->error_str, sizeof(lun_req->error_str), 396 "%s: invalid LUN request type %d", __func__, 397 lun_req->reqtype); 398 break; 399 } 400 break; |
415 } | |
416 default: 417 retval = ENOTTY; 418 break; 419 } 420 421 return (retval); 422} 423 424static int 425ctl_backend_ramdisk_rm(struct ctl_be_ramdisk_softc *softc, 426 struct ctl_lun_req *req) 427{ 428 struct ctl_be_ramdisk_lun *be_lun; 429 struct ctl_lun_rm_params *params; 430 int retval; 431 | 401 default: 402 retval = ENOTTY; 403 break; 404 } 405 406 return (retval); 407} 408 409static int 410ctl_backend_ramdisk_rm(struct ctl_be_ramdisk_softc *softc, 411 struct ctl_lun_req *req) 412{ 413 struct ctl_be_ramdisk_lun *be_lun; 414 struct ctl_lun_rm_params *params; 415 int retval; 416 |
432 | |
433 retval = 0; 434 params = &req->reqdata.rm; | 417 retval = 0; 418 params = &req->reqdata.rm; |
435 436 be_lun = NULL; 437 | |
438 mtx_lock(&softc->lock); | 419 mtx_lock(&softc->lock); |
439 | |
440 STAILQ_FOREACH(be_lun, &softc->lun_list, links) { 441 if (be_lun->cbe_lun.lun_id == params->lun_id) 442 break; 443 } 444 mtx_unlock(&softc->lock); | 420 STAILQ_FOREACH(be_lun, &softc->lun_list, links) { 421 if (be_lun->cbe_lun.lun_id == params->lun_id) 422 break; 423 } 424 mtx_unlock(&softc->lock); |
445 | |
446 if (be_lun == NULL) { 447 snprintf(req->error_str, sizeof(req->error_str), 448 "%s: LUN %u is not managed by the ramdisk backend", 449 __func__, params->lun_id); 450 goto bailout_error; 451 } 452 453 retval = ctl_disable_lun(&be_lun->cbe_lun); | 425 if (be_lun == NULL) { 426 snprintf(req->error_str, sizeof(req->error_str), 427 "%s: LUN %u is not managed by the ramdisk backend", 428 __func__, params->lun_id); 429 goto bailout_error; 430 } 431 432 retval = ctl_disable_lun(&be_lun->cbe_lun); |
454 | |
455 if (retval != 0) { 456 snprintf(req->error_str, sizeof(req->error_str), 457 "%s: error %d returned from ctl_disable_lun() for " 458 "LUN %d", __func__, retval, params->lun_id); 459 goto bailout_error; 460 } 461 462 /* --- 15 unchanged lines hidden (view full) --- 478 "LUN %d", __func__, retval, params->lun_id); 479 mtx_lock(&softc->lock); 480 be_lun->flags &= ~CTL_BE_RAMDISK_LUN_WAITING; 481 mtx_unlock(&softc->lock); 482 goto bailout_error; 483 } 484 485 mtx_lock(&softc->lock); | 433 if (retval != 0) { 434 snprintf(req->error_str, sizeof(req->error_str), 435 "%s: error %d returned from ctl_disable_lun() for " 436 "LUN %d", __func__, retval, params->lun_id); 437 goto bailout_error; 438 } 439 440 /* --- 15 unchanged lines hidden (view full) --- 456 "LUN %d", __func__, retval, params->lun_id); 457 mtx_lock(&softc->lock); 458 be_lun->flags &= ~CTL_BE_RAMDISK_LUN_WAITING; 459 mtx_unlock(&softc->lock); 460 goto bailout_error; 461 } 462 463 mtx_lock(&softc->lock); |
486 | |
487 while ((be_lun->flags & CTL_BE_RAMDISK_LUN_UNCONFIGURED) == 0) { 488 retval = msleep(be_lun, &softc->lock, PCATCH, "ctlram", 0); | 464 while ((be_lun->flags & CTL_BE_RAMDISK_LUN_UNCONFIGURED) == 0) { 465 retval = msleep(be_lun, &softc->lock, PCATCH, "ctlram", 0); |
489 if (retval == EINTR) | 466 if (retval == EINTR) |
490 break; 491 } 492 be_lun->flags &= ~CTL_BE_RAMDISK_LUN_WAITING; 493 494 /* 495 * We only remove this LUN from the list and free it (below) if 496 * retval == 0. If the user interrupted the wait, we just bail out 497 * without actually freeing the LUN. We let the shutdown routine --- 11 unchanged lines hidden (view full) --- 509 taskqueue_drain_all(be_lun->io_taskqueue); 510 taskqueue_free(be_lun->io_taskqueue); 511 ctl_free_opts(&be_lun->cbe_lun.options); 512 mtx_destroy(&be_lun->queue_lock); 513 free(be_lun, M_RAMDISK); 514 } 515 516 req->status = CTL_LUN_OK; | 467 break; 468 } 469 be_lun->flags &= ~CTL_BE_RAMDISK_LUN_WAITING; 470 471 /* 472 * We only remove this LUN from the list and free it (below) if 473 * retval == 0. If the user interrupted the wait, we just bail out 474 * without actually freeing the LUN. We let the shutdown routine --- 11 unchanged lines hidden (view full) --- 486 taskqueue_drain_all(be_lun->io_taskqueue); 487 taskqueue_free(be_lun->io_taskqueue); 488 ctl_free_opts(&be_lun->cbe_lun.options); 489 mtx_destroy(&be_lun->queue_lock); 490 free(be_lun, M_RAMDISK); 491 } 492 493 req->status = CTL_LUN_OK; |
517 | |
518 return (retval); 519 520bailout_error: 521 req->status = CTL_LUN_ERROR; | 494 return (retval); 495 496bailout_error: 497 req->status = CTL_LUN_ERROR; |
522 | |
523 return (0); 524} 525 526static int 527ctl_backend_ramdisk_create(struct ctl_be_ramdisk_softc *softc, 528 struct ctl_lun_req *req) 529{ 530 struct ctl_be_ramdisk_lun *be_lun; --- 120 unchanged lines hidden (view full) --- 651 /*thread name*/ 652 "%s taskq", be_lun->lunname); 653 if (retval != 0) 654 goto bailout_error; 655 656 mtx_lock(&softc->lock); 657 softc->num_luns++; 658 STAILQ_INSERT_TAIL(&softc->lun_list, be_lun, links); | 498 return (0); 499} 500 501static int 502ctl_backend_ramdisk_create(struct ctl_be_ramdisk_softc *softc, 503 struct ctl_lun_req *req) 504{ 505 struct ctl_be_ramdisk_lun *be_lun; --- 120 unchanged lines hidden (view full) --- 626 /*thread name*/ 627 "%s taskq", be_lun->lunname); 628 if (retval != 0) 629 goto bailout_error; 630 631 mtx_lock(&softc->lock); 632 softc->num_luns++; 633 STAILQ_INSERT_TAIL(&softc->lun_list, be_lun, links); |
659 | |
660 mtx_unlock(&softc->lock); 661 662 retval = ctl_add_lun(&be_lun->cbe_lun); 663 if (retval != 0) { 664 mtx_lock(&softc->lock); 665 STAILQ_REMOVE(&softc->lun_list, be_lun, ctl_be_ramdisk_lun, 666 links); 667 softc->num_luns--; --- 30 unchanged lines hidden (view full) --- 698 mtx_unlock(&softc->lock); 699 goto bailout_error; 700 } else { 701 params->req_lun_id = cbe_lun->lun_id; 702 } 703 mtx_unlock(&softc->lock); 704 705 req->status = CTL_LUN_OK; | 634 mtx_unlock(&softc->lock); 635 636 retval = ctl_add_lun(&be_lun->cbe_lun); 637 if (retval != 0) { 638 mtx_lock(&softc->lock); 639 STAILQ_REMOVE(&softc->lun_list, be_lun, ctl_be_ramdisk_lun, 640 links); 641 softc->num_luns--; --- 30 unchanged lines hidden (view full) --- 672 mtx_unlock(&softc->lock); 673 goto bailout_error; 674 } else { 675 params->req_lun_id = cbe_lun->lun_id; 676 } 677 mtx_unlock(&softc->lock); 678 679 req->status = CTL_LUN_OK; |
706 | |
707 return (retval); 708 709bailout_error: 710 req->status = CTL_LUN_ERROR; 711 if (be_lun != NULL) { 712 if (be_lun->io_taskqueue != NULL) { 713 taskqueue_free(be_lun->io_taskqueue); 714 } 715 ctl_free_opts(&cbe_lun->options); 716 mtx_destroy(&be_lun->queue_lock); 717 free(be_lun, M_RAMDISK); 718 } | 680 return (retval); 681 682bailout_error: 683 req->status = CTL_LUN_ERROR; 684 if (be_lun != NULL) { 685 if (be_lun->io_taskqueue != NULL) { 686 taskqueue_free(be_lun->io_taskqueue); 687 } 688 ctl_free_opts(&cbe_lun->options); 689 mtx_destroy(&be_lun->queue_lock); 690 free(be_lun, M_RAMDISK); 691 } |
719 | |
720 return (retval); 721} 722 723static int 724ctl_backend_ramdisk_modify(struct ctl_be_ramdisk_softc *softc, 725 struct ctl_lun_req *req) 726{ 727 struct ctl_be_ramdisk_lun *be_lun; --- 6 unchanged lines hidden (view full) --- 734 params = &req->reqdata.modify; 735 736 mtx_lock(&softc->lock); 737 STAILQ_FOREACH(be_lun, &softc->lun_list, links) { 738 if (be_lun->cbe_lun.lun_id == params->lun_id) 739 break; 740 } 741 mtx_unlock(&softc->lock); | 692 return (retval); 693} 694 695static int 696ctl_backend_ramdisk_modify(struct ctl_be_ramdisk_softc *softc, 697 struct ctl_lun_req *req) 698{ 699 struct ctl_be_ramdisk_lun *be_lun; --- 6 unchanged lines hidden (view full) --- 706 params = &req->reqdata.modify; 707 708 mtx_lock(&softc->lock); 709 STAILQ_FOREACH(be_lun, &softc->lun_list, links) { 710 if (be_lun->cbe_lun.lun_id == params->lun_id) 711 break; 712 } 713 mtx_unlock(&softc->lock); |
742 | |
743 if (be_lun == NULL) { 744 snprintf(req->error_str, sizeof(req->error_str), 745 "%s: LUN %u is not managed by the ramdisk backend", 746 __func__, params->lun_id); 747 goto bailout_error; 748 } 749 cbe_lun = &be_lun->cbe_lun; 750 --- 30 unchanged lines hidden (view full) --- 781 be_lun->size_bytes = be_lun->size_blocks * blocksize; 782 be_lun->cbe_lun.maxlba = be_lun->size_blocks - 1; 783 ctl_lun_capacity_changed(&be_lun->cbe_lun); 784 785 /* Tell the user the exact size we ended up using */ 786 params->lun_size_bytes = be_lun->size_bytes; 787 788 req->status = CTL_LUN_OK; | 714 if (be_lun == NULL) { 715 snprintf(req->error_str, sizeof(req->error_str), 716 "%s: LUN %u is not managed by the ramdisk backend", 717 __func__, params->lun_id); 718 goto bailout_error; 719 } 720 cbe_lun = &be_lun->cbe_lun; 721 --- 30 unchanged lines hidden (view full) --- 752 be_lun->size_bytes = be_lun->size_blocks * blocksize; 753 be_lun->cbe_lun.maxlba = be_lun->size_blocks - 1; 754 ctl_lun_capacity_changed(&be_lun->cbe_lun); 755 756 /* Tell the user the exact size we ended up using */ 757 params->lun_size_bytes = be_lun->size_bytes; 758 759 req->status = CTL_LUN_OK; |
789 | |
790 return (0); 791 792bailout_error: 793 req->status = CTL_LUN_ERROR; | 760 return (0); 761 762bailout_error: 763 req->status = CTL_LUN_ERROR; |
794 | |
795 return (0); 796} 797 798static void 799ctl_backend_ramdisk_lun_shutdown(void *be_lun) 800{ 801 struct ctl_be_ramdisk_lun *lun; 802 struct ctl_be_ramdisk_softc *softc; 803 int do_free; 804 805 lun = (struct ctl_be_ramdisk_lun *)be_lun; 806 softc = lun->softc; 807 do_free = 0; 808 809 mtx_lock(&softc->lock); | 764 return (0); 765} 766 767static void 768ctl_backend_ramdisk_lun_shutdown(void *be_lun) 769{ 770 struct ctl_be_ramdisk_lun *lun; 771 struct ctl_be_ramdisk_softc *softc; 772 int do_free; 773 774 lun = (struct ctl_be_ramdisk_lun *)be_lun; 775 softc = lun->softc; 776 do_free = 0; 777 778 mtx_lock(&softc->lock); |
810 | |
811 lun->flags |= CTL_BE_RAMDISK_LUN_UNCONFIGURED; | 779 lun->flags |= CTL_BE_RAMDISK_LUN_UNCONFIGURED; |
812 | |
813 if (lun->flags & CTL_BE_RAMDISK_LUN_WAITING) { 814 wakeup(lun); 815 } else { 816 STAILQ_REMOVE(&softc->lun_list, lun, ctl_be_ramdisk_lun, 817 links); 818 softc->num_luns--; 819 do_free = 1; 820 } | 780 if (lun->flags & CTL_BE_RAMDISK_LUN_WAITING) { 781 wakeup(lun); 782 } else { 783 STAILQ_REMOVE(&softc->lun_list, lun, ctl_be_ramdisk_lun, 784 links); 785 softc->num_luns--; 786 do_free = 1; 787 } |
821 | |
822 mtx_unlock(&softc->lock); 823 824 if (do_free != 0) 825 free(be_lun, M_RAMDISK); 826} 827 828static void 829ctl_backend_ramdisk_lun_config_status(void *be_lun, --- 164 unchanged lines hidden --- | 788 mtx_unlock(&softc->lock); 789 790 if (do_free != 0) 791 free(be_lun, M_RAMDISK); 792} 793 794static void 795ctl_backend_ramdisk_lun_config_status(void *be_lun, --- 164 unchanged lines hidden --- |