aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilipp Reisner <philipp.reisner@linbit.com>2011-02-09 04:09:07 -0500
committerPhilipp Reisner <philipp.reisner@linbit.com>2011-09-28 04:33:12 -0400
commit19393e105f9702a014d3ce08bce92b3ad9cf96b5 (patch)
tree835ae14026432fe19dc9e1a054b76562351718da
parent32862ec705d4b8ecf37e41cc65aa1bd84f990c75 (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.c97
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
1627static 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
1627int drbd_worker(struct drbd_thread *thi) 1644int 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}