ctl_backend_block.c (287664) | ctl_backend_block.c (287670) |
---|---|
1/*- 2 * Copyright (c) 2003 Silicon Graphics International Corp. 3 * Copyright (c) 2009-2011 Spectra Logic Corporation 4 * Copyright (c) 2012 The FreeBSD Foundation 5 * All rights reserved. 6 * 7 * Portions of this software were developed by Edward Tomasz Napierala 8 * under sponsorship from the FreeBSD Foundation. --- 26 unchanged lines hidden (view full) --- 35 * $Id: //depot/users/kenm/FreeBSD-test2/sys/cam/ctl/ctl_backend_block.c#5 $ 36 */ 37/* 38 * CAM Target Layer driver backend for block devices. 39 * 40 * Author: Ken Merry <ken@FreeBSD.org> 41 */ 42#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2003 Silicon Graphics International Corp. 3 * Copyright (c) 2009-2011 Spectra Logic Corporation 4 * Copyright (c) 2012 The FreeBSD Foundation 5 * All rights reserved. 6 * 7 * Portions of this software were developed by Edward Tomasz Napierala 8 * under sponsorship from the FreeBSD Foundation. --- 26 unchanged lines hidden (view full) --- 35 * $Id: //depot/users/kenm/FreeBSD-test2/sys/cam/ctl/ctl_backend_block.c#5 $ 36 */ 37/* 38 * CAM Target Layer driver backend for block devices. 39 * 40 * Author: Ken Merry <ken@FreeBSD.org> 41 */ 42#include <sys/cdefs.h> |
43__FBSDID("$FreeBSD: head/sys/cam/ctl/ctl_backend_block.c 287664 2015-09-11 12:50:52Z mav $"); | 43__FBSDID("$FreeBSD: head/sys/cam/ctl/ctl_backend_block.c 287670 2015-09-11 14:33:05Z mav $"); |
44 45#include <sys/param.h> 46#include <sys/systm.h> 47#include <sys/kernel.h> 48#include <sys/types.h> 49#include <sys/kthread.h> 50#include <sys/bio.h> 51#include <sys/fcntl.h> --- 1558 unchanged lines hidden (view full) --- 1610#endif 1611 ctl_datamove(io); 1612 } 1613} 1614 1615static void 1616ctl_be_block_worker(void *context, int pending) 1617{ | 44 45#include <sys/param.h> 46#include <sys/systm.h> 47#include <sys/kernel.h> 48#include <sys/types.h> 49#include <sys/kthread.h> 50#include <sys/bio.h> 51#include <sys/fcntl.h> --- 1558 unchanged lines hidden (view full) --- 1610#endif 1611 ctl_datamove(io); 1612 } 1613} 1614 1615static void 1616ctl_be_block_worker(void *context, int pending) 1617{ |
1618 struct ctl_be_block_lun *be_lun; 1619 struct ctl_be_block_softc *softc; | 1618 struct ctl_be_block_lun *be_lun = (struct ctl_be_block_lun *)context; 1619 struct ctl_be_lun *cbe_lun = &be_lun->cbe_lun; |
1620 union ctl_io *io; | 1620 union ctl_io *io; |
1621 struct ctl_be_block_io *beio; |
|
1621 | 1622 |
1622 be_lun = (struct ctl_be_block_lun *)context; 1623 softc = be_lun->softc; 1624 | |
1625 DPRINTF("entered\n"); | 1623 DPRINTF("entered\n"); |
1626 1627 mtx_lock(&be_lun->queue_lock); | 1624 /* 1625 * Fetch and process I/Os from all queues. If we detect LUN 1626 * CTL_LUN_FLAG_OFFLINE status here -- it is result of a race, 1627 * so make response maximally opaque to not confuse initiator. 1628 */ |
1628 for (;;) { | 1629 for (;;) { |
1630 mtx_lock(&be_lun->queue_lock); |
|
1629 io = (union ctl_io *)STAILQ_FIRST(&be_lun->datamove_queue); 1630 if (io != NULL) { | 1631 io = (union ctl_io *)STAILQ_FIRST(&be_lun->datamove_queue); 1632 if (io != NULL) { |
1631 struct ctl_be_block_io *beio; 1632 | |
1633 DPRINTF("datamove queue\n"); | 1633 DPRINTF("datamove queue\n"); |
1634 | |
1635 STAILQ_REMOVE(&be_lun->datamove_queue, &io->io_hdr, 1636 ctl_io_hdr, links); | 1634 STAILQ_REMOVE(&be_lun->datamove_queue, &io->io_hdr, 1635 ctl_io_hdr, links); |
1637 | |
1638 mtx_unlock(&be_lun->queue_lock); | 1636 mtx_unlock(&be_lun->queue_lock); |
1639 | |
1640 beio = (struct ctl_be_block_io *)PRIV(io)->ptr; | 1637 beio = (struct ctl_be_block_io *)PRIV(io)->ptr; |
1641 | 1638 if (cbe_lun->flags & CTL_LUN_FLAG_OFFLINE) { 1639 ctl_set_busy(&io->scsiio); 1640 ctl_complete_beio(beio); 1641 return; 1642 } |
1642 be_lun->dispatch(be_lun, beio); | 1643 be_lun->dispatch(be_lun, beio); |
1643 1644 mtx_lock(&be_lun->queue_lock); | |
1645 continue; 1646 } 1647 io = (union ctl_io *)STAILQ_FIRST(&be_lun->config_write_queue); 1648 if (io != NULL) { 1649 DPRINTF("config write queue\n"); 1650 STAILQ_REMOVE(&be_lun->config_write_queue, &io->io_hdr, 1651 ctl_io_hdr, links); 1652 mtx_unlock(&be_lun->queue_lock); | 1644 continue; 1645 } 1646 io = (union ctl_io *)STAILQ_FIRST(&be_lun->config_write_queue); 1647 if (io != NULL) { 1648 DPRINTF("config write queue\n"); 1649 STAILQ_REMOVE(&be_lun->config_write_queue, &io->io_hdr, 1650 ctl_io_hdr, links); 1651 mtx_unlock(&be_lun->queue_lock); |
1652 if (cbe_lun->flags & CTL_LUN_FLAG_OFFLINE) { 1653 ctl_set_busy(&io->scsiio); 1654 ctl_config_write_done(io); 1655 return; 1656 } |
|
1653 ctl_be_block_cw_dispatch(be_lun, io); | 1657 ctl_be_block_cw_dispatch(be_lun, io); |
1654 mtx_lock(&be_lun->queue_lock); | |
1655 continue; 1656 } 1657 io = (union ctl_io *)STAILQ_FIRST(&be_lun->config_read_queue); 1658 if (io != NULL) { 1659 DPRINTF("config read queue\n"); 1660 STAILQ_REMOVE(&be_lun->config_read_queue, &io->io_hdr, 1661 ctl_io_hdr, links); 1662 mtx_unlock(&be_lun->queue_lock); | 1658 continue; 1659 } 1660 io = (union ctl_io *)STAILQ_FIRST(&be_lun->config_read_queue); 1661 if (io != NULL) { 1662 DPRINTF("config read queue\n"); 1663 STAILQ_REMOVE(&be_lun->config_read_queue, &io->io_hdr, 1664 ctl_io_hdr, links); 1665 mtx_unlock(&be_lun->queue_lock); |
1666 if (cbe_lun->flags & CTL_LUN_FLAG_OFFLINE) { 1667 ctl_set_busy(&io->scsiio); 1668 ctl_config_read_done(io); 1669 return; 1670 } |
|
1663 ctl_be_block_cr_dispatch(be_lun, io); | 1671 ctl_be_block_cr_dispatch(be_lun, io); |
1664 mtx_lock(&be_lun->queue_lock); | |
1665 continue; 1666 } 1667 io = (union ctl_io *)STAILQ_FIRST(&be_lun->input_queue); 1668 if (io != NULL) { 1669 DPRINTF("input queue\n"); | 1672 continue; 1673 } 1674 io = (union ctl_io *)STAILQ_FIRST(&be_lun->input_queue); 1675 if (io != NULL) { 1676 DPRINTF("input queue\n"); |
1670 | |
1671 STAILQ_REMOVE(&be_lun->input_queue, &io->io_hdr, 1672 ctl_io_hdr, links); 1673 mtx_unlock(&be_lun->queue_lock); | 1677 STAILQ_REMOVE(&be_lun->input_queue, &io->io_hdr, 1678 ctl_io_hdr, links); 1679 mtx_unlock(&be_lun->queue_lock); |
1674 1675 /* 1676 * We must drop the lock, since this routine and 1677 * its children may sleep. 1678 */ | 1680 if (cbe_lun->flags & CTL_LUN_FLAG_OFFLINE) { 1681 ctl_set_busy(&io->scsiio); 1682 ctl_data_submit_done(io); 1683 return; 1684 } |
1679 ctl_be_block_dispatch(be_lun, io); | 1685 ctl_be_block_dispatch(be_lun, io); |
1680 1681 mtx_lock(&be_lun->queue_lock); | |
1682 continue; 1683 } 1684 1685 /* 1686 * If we get here, there is no work left in the queues, so 1687 * just break out and let the task queue go to sleep. 1688 */ | 1686 continue; 1687 } 1688 1689 /* 1690 * If we get here, there is no work left in the queues, so 1691 * just break out and let the task queue go to sleep. 1692 */ |
1693 mtx_unlock(&be_lun->queue_lock); |
|
1689 break; 1690 } | 1694 break; 1695 } |
1691 mtx_unlock(&be_lun->queue_lock); | |
1692} 1693 1694/* 1695 * Entry point from CTL to the backend for I/O. We queue everything to a 1696 * work thread, so this just puts the I/O on a queue and wakes up the 1697 * thread. 1698 */ 1699static int --- 738 unchanged lines hidden (view full) --- 2438 return (retval); 2439} 2440 2441static int 2442ctl_be_block_rm(struct ctl_be_block_softc *softc, struct ctl_lun_req *req) 2443{ 2444 struct ctl_lun_rm_params *params; 2445 struct ctl_be_block_lun *be_lun; | 1696} 1697 1698/* 1699 * Entry point from CTL to the backend for I/O. We queue everything to a 1700 * work thread, so this just puts the I/O on a queue and wakes up the 1701 * thread. 1702 */ 1703static int --- 738 unchanged lines hidden (view full) --- 2442 return (retval); 2443} 2444 2445static int 2446ctl_be_block_rm(struct ctl_be_block_softc *softc, struct ctl_lun_req *req) 2447{ 2448 struct ctl_lun_rm_params *params; 2449 struct ctl_be_block_lun *be_lun; |
2450 struct ctl_be_lun *cbe_lun; |
|
2446 int retval; 2447 2448 params = &req->reqdata.rm; 2449 2450 mtx_lock(&softc->lock); 2451 STAILQ_FOREACH(be_lun, &softc->lun_list, links) { 2452 if (be_lun->cbe_lun.lun_id == params->lun_id) 2453 break; 2454 } 2455 mtx_unlock(&softc->lock); 2456 2457 if (be_lun == NULL) { 2458 snprintf(req->error_str, sizeof(req->error_str), 2459 "LUN %u is not managed by the block backend", 2460 params->lun_id); 2461 goto bailout_error; 2462 } | 2451 int retval; 2452 2453 params = &req->reqdata.rm; 2454 2455 mtx_lock(&softc->lock); 2456 STAILQ_FOREACH(be_lun, &softc->lun_list, links) { 2457 if (be_lun->cbe_lun.lun_id == params->lun_id) 2458 break; 2459 } 2460 mtx_unlock(&softc->lock); 2461 2462 if (be_lun == NULL) { 2463 snprintf(req->error_str, sizeof(req->error_str), 2464 "LUN %u is not managed by the block backend", 2465 params->lun_id); 2466 goto bailout_error; 2467 } |
2468 cbe_lun = &be_lun->cbe_lun; |
|
2463 | 2469 |
2464 retval = ctl_disable_lun(&be_lun->cbe_lun); 2465 | 2470 retval = ctl_disable_lun(cbe_lun); |
2466 if (retval != 0) { 2467 snprintf(req->error_str, sizeof(req->error_str), 2468 "error %d returned from ctl_disable_lun() for " 2469 "LUN %d", retval, params->lun_id); 2470 goto bailout_error; | 2471 if (retval != 0) { 2472 snprintf(req->error_str, sizeof(req->error_str), 2473 "error %d returned from ctl_disable_lun() for " 2474 "LUN %d", retval, params->lun_id); 2475 goto bailout_error; |
2476 } |
|
2471 | 2477 |
2478 if (be_lun->vn != NULL) { 2479 cbe_lun->flags |= CTL_LUN_FLAG_OFFLINE; 2480 ctl_lun_offline(cbe_lun); 2481 taskqueue_drain_all(be_lun->io_taskqueue); 2482 ctl_be_block_close(be_lun); |
|
2472 } 2473 | 2483 } 2484 |
2474 retval = ctl_invalidate_lun(&be_lun->cbe_lun); | 2485 retval = ctl_invalidate_lun(cbe_lun); |
2475 if (retval != 0) { 2476 snprintf(req->error_str, sizeof(req->error_str), 2477 "error %d returned from ctl_invalidate_lun() for " 2478 "LUN %d", retval, params->lun_id); 2479 goto bailout_error; 2480 } 2481 2482 mtx_lock(&softc->lock); | 2486 if (retval != 0) { 2487 snprintf(req->error_str, sizeof(req->error_str), 2488 "error %d returned from ctl_invalidate_lun() for " 2489 "LUN %d", retval, params->lun_id); 2490 goto bailout_error; 2491 } 2492 2493 mtx_lock(&softc->lock); |
2483 | |
2484 be_lun->flags |= CTL_BE_BLOCK_LUN_WAITING; | 2494 be_lun->flags |= CTL_BE_BLOCK_LUN_WAITING; |
2485 | |
2486 while ((be_lun->flags & CTL_BE_BLOCK_LUN_UNCONFIGURED) == 0) { 2487 retval = msleep(be_lun, &softc->lock, PCATCH, "ctlblk", 0); 2488 if (retval == EINTR) 2489 break; 2490 } | 2495 while ((be_lun->flags & CTL_BE_BLOCK_LUN_UNCONFIGURED) == 0) { 2496 retval = msleep(be_lun, &softc->lock, PCATCH, "ctlblk", 0); 2497 if (retval == EINTR) 2498 break; 2499 } |
2491 | |
2492 be_lun->flags &= ~CTL_BE_BLOCK_LUN_WAITING; 2493 2494 if ((be_lun->flags & CTL_BE_BLOCK_LUN_UNCONFIGURED) == 0) { 2495 snprintf(req->error_str, sizeof(req->error_str), 2496 "interrupted waiting for LUN to be freed"); 2497 mtx_unlock(&softc->lock); 2498 goto bailout_error; 2499 } 2500 2501 STAILQ_REMOVE(&softc->lun_list, be_lun, ctl_be_block_lun, links); 2502 2503 softc->num_luns--; 2504 mtx_unlock(&softc->lock); 2505 | 2500 be_lun->flags &= ~CTL_BE_BLOCK_LUN_WAITING; 2501 2502 if ((be_lun->flags & CTL_BE_BLOCK_LUN_UNCONFIGURED) == 0) { 2503 snprintf(req->error_str, sizeof(req->error_str), 2504 "interrupted waiting for LUN to be freed"); 2505 mtx_unlock(&softc->lock); 2506 goto bailout_error; 2507 } 2508 2509 STAILQ_REMOVE(&softc->lun_list, be_lun, ctl_be_block_lun, links); 2510 2511 softc->num_luns--; 2512 mtx_unlock(&softc->lock); 2513 |
2506 taskqueue_drain(be_lun->io_taskqueue, &be_lun->io_task); 2507 | 2514 taskqueue_drain_all(be_lun->io_taskqueue); |
2508 taskqueue_free(be_lun->io_taskqueue); 2509 | 2515 taskqueue_free(be_lun->io_taskqueue); 2516 |
2510 ctl_be_block_close(be_lun); 2511 | |
2512 if (be_lun->disk_stats != NULL) 2513 devstat_remove_entry(be_lun->disk_stats); 2514 2515 uma_zdestroy(be_lun->lun_zone); 2516 | 2517 if (be_lun->disk_stats != NULL) 2518 devstat_remove_entry(be_lun->disk_stats); 2519 2520 uma_zdestroy(be_lun->lun_zone); 2521 |
2517 ctl_free_opts(&be_lun->cbe_lun.options); | 2522 ctl_free_opts(&cbe_lun->options); |
2518 free(be_lun->dev_path, M_CTLBLK); 2519 mtx_destroy(&be_lun->queue_lock); 2520 mtx_destroy(&be_lun->io_lock); 2521 free(be_lun, M_CTLBLK); 2522 2523 req->status = CTL_LUN_OK; 2524 2525 return (0); --- 148 unchanged lines hidden (view full) --- 2674 be_lun->vn != NULL) { 2675 cbe_lun->flags &= ~CTL_LUN_FLAG_OFFLINE; 2676 ctl_lun_online(cbe_lun); 2677 } 2678 } else { 2679 if (be_lun->vn != NULL) { 2680 cbe_lun->flags |= CTL_LUN_FLAG_OFFLINE; 2681 ctl_lun_offline(cbe_lun); | 2523 free(be_lun->dev_path, M_CTLBLK); 2524 mtx_destroy(&be_lun->queue_lock); 2525 mtx_destroy(&be_lun->io_lock); 2526 free(be_lun, M_CTLBLK); 2527 2528 req->status = CTL_LUN_OK; 2529 2530 return (0); --- 148 unchanged lines hidden (view full) --- 2679 be_lun->vn != NULL) { 2680 cbe_lun->flags &= ~CTL_LUN_FLAG_OFFLINE; 2681 ctl_lun_online(cbe_lun); 2682 } 2683 } else { 2684 if (be_lun->vn != NULL) { 2685 cbe_lun->flags |= CTL_LUN_FLAG_OFFLINE; 2686 ctl_lun_offline(cbe_lun); |
2682 pause("CTL LUN offline", hz / 8); // XXX | 2687 taskqueue_drain_all(be_lun->io_taskqueue); |
2683 error = ctl_be_block_close(be_lun); 2684 } else 2685 error = 0; 2686 } 2687 if (be_lun->size_blocks != oldsize) 2688 ctl_lun_capacity_changed(cbe_lun); 2689 2690 /* Tell the user the exact size we ended up using */ --- 244 unchanged lines hidden --- | 2688 error = ctl_be_block_close(be_lun); 2689 } else 2690 error = 0; 2691 } 2692 if (be_lun->size_blocks != oldsize) 2693 ctl_lun_capacity_changed(cbe_lun); 2694 2695 /* Tell the user the exact size we ended up using */ --- 244 unchanged lines hidden --- |