Deleted Added
full compact
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 ---