diff options
author | Philipp Reisner <philipp.reisner@linbit.com> | 2011-02-09 04:09:07 -0500 |
---|---|---|
committer | Philipp Reisner <philipp.reisner@linbit.com> | 2011-09-28 04:33:12 -0400 |
commit | 19393e105f9702a014d3ce08bce92b3ad9cf96b5 (patch) | |
tree | 835ae14026432fe19dc9e1a054b76562351718da | |
parent | 32862ec705d4b8ecf37e41cc65aa1bd84f990c75 (diff) |
drbd: Converted drbd_worker() from mdev to tconn
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
-rw-r--r-- | drivers/block/drbd/drbd_worker.c | 97 |
1 files changed, 51 insertions, 46 deletions
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c index 6f709621ae26..c9b10d6eb88a 100644 --- a/drivers/block/drbd/drbd_worker.c +++ b/drivers/block/drbd/drbd_worker.c | |||
@@ -1624,35 +1624,53 @@ void drbd_start_resync(struct drbd_conf *mdev, enum drbd_conns side) | |||
1624 | drbd_state_unlock(mdev); | 1624 | drbd_state_unlock(mdev); |
1625 | } | 1625 | } |
1626 | 1626 | ||
1627 | static int _worker_dying(int vnr, void *p, void *data) | ||
1628 | { | ||
1629 | struct drbd_conf *mdev = (struct drbd_conf *)p; | ||
1630 | |||
1631 | D_ASSERT(mdev->state.disk == D_DISKLESS && mdev->state.conn == C_STANDALONE); | ||
1632 | /* _drbd_set_state only uses stop_nowait. | ||
1633 | * wait here for the exiting receiver. */ | ||
1634 | drbd_thread_stop(&mdev->tconn->receiver); | ||
1635 | drbd_mdev_cleanup(mdev); | ||
1636 | |||
1637 | clear_bit(DEVICE_DYING, &mdev->flags); | ||
1638 | clear_bit(CONFIG_PENDING, &mdev->flags); | ||
1639 | wake_up(&mdev->state_wait); | ||
1640 | |||
1641 | return 0; | ||
1642 | } | ||
1643 | |||
1627 | int drbd_worker(struct drbd_thread *thi) | 1644 | int drbd_worker(struct drbd_thread *thi) |
1628 | { | 1645 | { |
1629 | struct drbd_conf *mdev = thi->mdev; | 1646 | struct drbd_tconn *tconn = thi->mdev->tconn; |
1630 | struct drbd_work *w = NULL; | 1647 | struct drbd_work *w = NULL; |
1631 | LIST_HEAD(work_list); | 1648 | LIST_HEAD(work_list); |
1632 | int intr = 0, i; | 1649 | int intr = 0; |
1633 | 1650 | ||
1634 | while (get_t_state(thi) == RUNNING) { | 1651 | while (get_t_state(thi) == RUNNING) { |
1635 | drbd_thread_current_set_cpu(thi); | 1652 | drbd_thread_current_set_cpu(thi); |
1636 | 1653 | ||
1637 | if (down_trylock(&mdev->tconn->data.work.s)) { | 1654 | if (down_trylock(&tconn->data.work.s)) { |
1638 | mutex_lock(&mdev->tconn->data.mutex); | 1655 | mutex_lock(&tconn->data.mutex); |
1639 | if (mdev->tconn->data.socket && !mdev->tconn->net_conf->no_cork) | 1656 | if (tconn->data.socket && !tconn->net_conf->no_cork) |
1640 | drbd_tcp_uncork(mdev->tconn->data.socket); | 1657 | drbd_tcp_uncork(tconn->data.socket); |
1641 | mutex_unlock(&mdev->tconn->data.mutex); | 1658 | mutex_unlock(&tconn->data.mutex); |
1642 | 1659 | ||
1643 | intr = down_interruptible(&mdev->tconn->data.work.s); | 1660 | intr = down_interruptible(&tconn->data.work.s); |
1644 | 1661 | ||
1645 | mutex_lock(&mdev->tconn->data.mutex); | 1662 | mutex_lock(&tconn->data.mutex); |
1646 | if (mdev->tconn->data.socket && !mdev->tconn->net_conf->no_cork) | 1663 | if (tconn->data.socket && !tconn->net_conf->no_cork) |
1647 | drbd_tcp_cork(mdev->tconn->data.socket); | 1664 | drbd_tcp_cork(tconn->data.socket); |
1648 | mutex_unlock(&mdev->tconn->data.mutex); | 1665 | mutex_unlock(&tconn->data.mutex); |
1649 | } | 1666 | } |
1650 | 1667 | ||
1651 | if (intr) { | 1668 | if (intr) { |
1652 | D_ASSERT(intr == -EINTR); | ||
1653 | flush_signals(current); | 1669 | flush_signals(current); |
1654 | if (!expect(get_t_state(thi) != RUNNING)) | 1670 | if (get_t_state(thi) == RUNNING) { |
1671 | conn_warn(tconn, "Worker got an unexpected signal\n"); | ||
1655 | continue; | 1672 | continue; |
1673 | } | ||
1656 | break; | 1674 | break; |
1657 | } | 1675 | } |
1658 | 1676 | ||
@@ -1663,8 +1681,8 @@ int drbd_worker(struct drbd_thread *thi) | |||
1663 | this... */ | 1681 | this... */ |
1664 | 1682 | ||
1665 | w = NULL; | 1683 | w = NULL; |
1666 | spin_lock_irq(&mdev->tconn->data.work.q_lock); | 1684 | spin_lock_irq(&tconn->data.work.q_lock); |
1667 | if (!expect(!list_empty(&mdev->tconn->data.work.q))) { | 1685 | if (list_empty(&tconn->data.work.q)) { |
1668 | /* something terribly wrong in our logic. | 1686 | /* something terribly wrong in our logic. |
1669 | * we were able to down() the semaphore, | 1687 | * we were able to down() the semaphore, |
1670 | * but the list is empty... doh. | 1688 | * but the list is empty... doh. |
@@ -1676,57 +1694,44 @@ int drbd_worker(struct drbd_thread *thi) | |||
1676 | * | 1694 | * |
1677 | * I'll try to get away just starting over this loop. | 1695 | * I'll try to get away just starting over this loop. |
1678 | */ | 1696 | */ |
1679 | spin_unlock_irq(&mdev->tconn->data.work.q_lock); | 1697 | conn_warn(tconn, "Work list unexpectedly empty\n"); |
1698 | spin_unlock_irq(&tconn->data.work.q_lock); | ||
1680 | continue; | 1699 | continue; |
1681 | } | 1700 | } |
1682 | w = list_entry(mdev->tconn->data.work.q.next, struct drbd_work, list); | 1701 | w = list_entry(tconn->data.work.q.next, struct drbd_work, list); |
1683 | list_del_init(&w->list); | 1702 | list_del_init(&w->list); |
1684 | spin_unlock_irq(&mdev->tconn->data.work.q_lock); | 1703 | spin_unlock_irq(&tconn->data.work.q_lock); |
1685 | 1704 | ||
1686 | if (!w->cb(mdev, w, mdev->state.conn < C_CONNECTED)) { | 1705 | if (!w->cb(w->mdev, w, tconn->volume0->state.conn < C_CONNECTED)) { |
1687 | /* dev_warn(DEV, "worker: a callback failed! \n"); */ | 1706 | /* dev_warn(DEV, "worker: a callback failed! \n"); */ |
1688 | if (mdev->state.conn >= C_CONNECTED) | 1707 | if (tconn->volume0->state.conn >= C_CONNECTED) |
1689 | drbd_force_state(mdev, | 1708 | drbd_force_state(tconn->volume0, |
1690 | NS(conn, C_NETWORK_FAILURE)); | 1709 | NS(conn, C_NETWORK_FAILURE)); |
1691 | } | 1710 | } |
1692 | } | 1711 | } |
1693 | D_ASSERT(test_bit(DEVICE_DYING, &mdev->flags)); | ||
1694 | D_ASSERT(test_bit(CONFIG_PENDING, &mdev->flags)); | ||
1695 | 1712 | ||
1696 | spin_lock_irq(&mdev->tconn->data.work.q_lock); | 1713 | spin_lock_irq(&tconn->data.work.q_lock); |
1697 | i = 0; | 1714 | while (!list_empty(&tconn->data.work.q)) { |
1698 | while (!list_empty(&mdev->tconn->data.work.q)) { | 1715 | list_splice_init(&tconn->data.work.q, &work_list); |
1699 | list_splice_init(&mdev->tconn->data.work.q, &work_list); | 1716 | spin_unlock_irq(&tconn->data.work.q_lock); |
1700 | spin_unlock_irq(&mdev->tconn->data.work.q_lock); | ||
1701 | 1717 | ||
1702 | while (!list_empty(&work_list)) { | 1718 | while (!list_empty(&work_list)) { |
1703 | w = list_entry(work_list.next, struct drbd_work, list); | 1719 | w = list_entry(work_list.next, struct drbd_work, list); |
1704 | list_del_init(&w->list); | 1720 | list_del_init(&w->list); |
1705 | w->cb(mdev, w, 1); | 1721 | w->cb(w->mdev, w, 1); |
1706 | i++; /* dead debugging code */ | ||
1707 | } | 1722 | } |
1708 | 1723 | ||
1709 | spin_lock_irq(&mdev->tconn->data.work.q_lock); | 1724 | spin_lock_irq(&tconn->data.work.q_lock); |
1710 | } | 1725 | } |
1711 | sema_init(&mdev->tconn->data.work.s, 0); | 1726 | sema_init(&tconn->data.work.s, 0); |
1712 | /* DANGEROUS race: if someone did queue his work within the spinlock, | 1727 | /* DANGEROUS race: if someone did queue his work within the spinlock, |
1713 | * but up() ed outside the spinlock, we could get an up() on the | 1728 | * but up() ed outside the spinlock, we could get an up() on the |
1714 | * semaphore without corresponding list entry. | 1729 | * semaphore without corresponding list entry. |
1715 | * So don't do that. | 1730 | * So don't do that. |
1716 | */ | 1731 | */ |
1717 | spin_unlock_irq(&mdev->tconn->data.work.q_lock); | 1732 | spin_unlock_irq(&tconn->data.work.q_lock); |
1718 | 1733 | ||
1719 | D_ASSERT(mdev->state.disk == D_DISKLESS && mdev->state.conn == C_STANDALONE); | 1734 | idr_for_each(&tconn->volumes, _worker_dying, NULL); |
1720 | /* _drbd_set_state only uses stop_nowait. | ||
1721 | * wait here for the exiting receiver. */ | ||
1722 | drbd_thread_stop(&mdev->tconn->receiver); | ||
1723 | drbd_mdev_cleanup(mdev); | ||
1724 | |||
1725 | dev_info(DEV, "worker terminated\n"); | ||
1726 | |||
1727 | clear_bit(DEVICE_DYING, &mdev->flags); | ||
1728 | clear_bit(CONFIG_PENDING, &mdev->flags); | ||
1729 | wake_up(&mdev->state_wait); | ||
1730 | 1735 | ||
1731 | return 0; | 1736 | return 0; |
1732 | } | 1737 | } |