diff options
Diffstat (limited to 'fs/xfs/linux-2.6/xfs_buf.c')
-rw-r--r-- | fs/xfs/linux-2.6/xfs_buf.c | 89 |
1 files changed, 24 insertions, 65 deletions
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c index 4c5deb6e9e31..0a00d7a2fc23 100644 --- a/fs/xfs/linux-2.6/xfs_buf.c +++ b/fs/xfs/linux-2.6/xfs_buf.c | |||
@@ -44,12 +44,7 @@ | |||
44 | 44 | ||
45 | static kmem_zone_t *xfs_buf_zone; | 45 | static kmem_zone_t *xfs_buf_zone; |
46 | STATIC int xfsbufd(void *); | 46 | STATIC int xfsbufd(void *); |
47 | STATIC int xfsbufd_wakeup(struct shrinker *, int, gfp_t); | ||
48 | STATIC void xfs_buf_delwri_queue(xfs_buf_t *, int); | 47 | STATIC void xfs_buf_delwri_queue(xfs_buf_t *, int); |
49 | static struct shrinker xfs_buf_shake = { | ||
50 | .shrink = xfsbufd_wakeup, | ||
51 | .seeks = DEFAULT_SEEKS, | ||
52 | }; | ||
53 | 48 | ||
54 | static struct workqueue_struct *xfslogd_workqueue; | 49 | static struct workqueue_struct *xfslogd_workqueue; |
55 | struct workqueue_struct *xfsdatad_workqueue; | 50 | struct workqueue_struct *xfsdatad_workqueue; |
@@ -337,7 +332,6 @@ _xfs_buf_lookup_pages( | |||
337 | __func__, gfp_mask); | 332 | __func__, gfp_mask); |
338 | 333 | ||
339 | XFS_STATS_INC(xb_page_retries); | 334 | XFS_STATS_INC(xb_page_retries); |
340 | xfsbufd_wakeup(NULL, 0, gfp_mask); | ||
341 | congestion_wait(BLK_RW_ASYNC, HZ/50); | 335 | congestion_wait(BLK_RW_ASYNC, HZ/50); |
342 | goto retry; | 336 | goto retry; |
343 | } | 337 | } |
@@ -1461,28 +1455,23 @@ xfs_wait_buftarg( | |||
1461 | } | 1455 | } |
1462 | } | 1456 | } |
1463 | 1457 | ||
1464 | /* | 1458 | int |
1465 | * buftarg list for delwrite queue processing | 1459 | xfs_buftarg_shrink( |
1466 | */ | 1460 | struct shrinker *shrink, |
1467 | static LIST_HEAD(xfs_buftarg_list); | 1461 | int nr_to_scan, |
1468 | static DEFINE_SPINLOCK(xfs_buftarg_lock); | 1462 | gfp_t mask) |
1469 | |||
1470 | STATIC void | ||
1471 | xfs_register_buftarg( | ||
1472 | xfs_buftarg_t *btp) | ||
1473 | { | ||
1474 | spin_lock(&xfs_buftarg_lock); | ||
1475 | list_add(&btp->bt_list, &xfs_buftarg_list); | ||
1476 | spin_unlock(&xfs_buftarg_lock); | ||
1477 | } | ||
1478 | |||
1479 | STATIC void | ||
1480 | xfs_unregister_buftarg( | ||
1481 | xfs_buftarg_t *btp) | ||
1482 | { | 1463 | { |
1483 | spin_lock(&xfs_buftarg_lock); | 1464 | struct xfs_buftarg *btp = container_of(shrink, |
1484 | list_del(&btp->bt_list); | 1465 | struct xfs_buftarg, bt_shrinker); |
1485 | spin_unlock(&xfs_buftarg_lock); | 1466 | if (nr_to_scan) { |
1467 | if (test_bit(XBT_FORCE_SLEEP, &btp->bt_flags)) | ||
1468 | return -1; | ||
1469 | if (list_empty(&btp->bt_delwrite_queue)) | ||
1470 | return -1; | ||
1471 | set_bit(XBT_FORCE_FLUSH, &btp->bt_flags); | ||
1472 | wake_up_process(btp->bt_task); | ||
1473 | } | ||
1474 | return list_empty(&btp->bt_delwrite_queue) ? -1 : 1; | ||
1486 | } | 1475 | } |
1487 | 1476 | ||
1488 | void | 1477 | void |
@@ -1490,17 +1479,14 @@ xfs_free_buftarg( | |||
1490 | struct xfs_mount *mp, | 1479 | struct xfs_mount *mp, |
1491 | struct xfs_buftarg *btp) | 1480 | struct xfs_buftarg *btp) |
1492 | { | 1481 | { |
1482 | unregister_shrinker(&btp->bt_shrinker); | ||
1483 | |||
1493 | xfs_flush_buftarg(btp, 1); | 1484 | xfs_flush_buftarg(btp, 1); |
1494 | if (mp->m_flags & XFS_MOUNT_BARRIER) | 1485 | if (mp->m_flags & XFS_MOUNT_BARRIER) |
1495 | xfs_blkdev_issue_flush(btp); | 1486 | xfs_blkdev_issue_flush(btp); |
1496 | iput(btp->bt_mapping->host); | 1487 | iput(btp->bt_mapping->host); |
1497 | 1488 | ||
1498 | /* Unregister the buftarg first so that we don't get a | ||
1499 | * wakeup finding a non-existent task | ||
1500 | */ | ||
1501 | xfs_unregister_buftarg(btp); | ||
1502 | kthread_stop(btp->bt_task); | 1489 | kthread_stop(btp->bt_task); |
1503 | |||
1504 | kmem_free(btp); | 1490 | kmem_free(btp); |
1505 | } | 1491 | } |
1506 | 1492 | ||
@@ -1597,20 +1583,13 @@ xfs_alloc_delwrite_queue( | |||
1597 | xfs_buftarg_t *btp, | 1583 | xfs_buftarg_t *btp, |
1598 | const char *fsname) | 1584 | const char *fsname) |
1599 | { | 1585 | { |
1600 | int error = 0; | ||
1601 | |||
1602 | INIT_LIST_HEAD(&btp->bt_list); | ||
1603 | INIT_LIST_HEAD(&btp->bt_delwrite_queue); | 1586 | INIT_LIST_HEAD(&btp->bt_delwrite_queue); |
1604 | spin_lock_init(&btp->bt_delwrite_lock); | 1587 | spin_lock_init(&btp->bt_delwrite_lock); |
1605 | btp->bt_flags = 0; | 1588 | btp->bt_flags = 0; |
1606 | btp->bt_task = kthread_run(xfsbufd, btp, "xfsbufd/%s", fsname); | 1589 | btp->bt_task = kthread_run(xfsbufd, btp, "xfsbufd/%s", fsname); |
1607 | if (IS_ERR(btp->bt_task)) { | 1590 | if (IS_ERR(btp->bt_task)) |
1608 | error = PTR_ERR(btp->bt_task); | 1591 | return PTR_ERR(btp->bt_task); |
1609 | goto out_error; | 1592 | return 0; |
1610 | } | ||
1611 | xfs_register_buftarg(btp); | ||
1612 | out_error: | ||
1613 | return error; | ||
1614 | } | 1593 | } |
1615 | 1594 | ||
1616 | xfs_buftarg_t * | 1595 | xfs_buftarg_t * |
@@ -1633,6 +1612,9 @@ xfs_alloc_buftarg( | |||
1633 | goto error; | 1612 | goto error; |
1634 | if (xfs_alloc_delwrite_queue(btp, fsname)) | 1613 | if (xfs_alloc_delwrite_queue(btp, fsname)) |
1635 | goto error; | 1614 | goto error; |
1615 | btp->bt_shrinker.shrink = xfs_buftarg_shrink; | ||
1616 | btp->bt_shrinker.seeks = DEFAULT_SEEKS; | ||
1617 | register_shrinker(&btp->bt_shrinker); | ||
1636 | return btp; | 1618 | return btp; |
1637 | 1619 | ||
1638 | error: | 1620 | error: |
@@ -1737,27 +1719,6 @@ xfs_buf_runall_queues( | |||
1737 | flush_workqueue(queue); | 1719 | flush_workqueue(queue); |
1738 | } | 1720 | } |
1739 | 1721 | ||
1740 | STATIC int | ||
1741 | xfsbufd_wakeup( | ||
1742 | struct shrinker *shrink, | ||
1743 | int priority, | ||
1744 | gfp_t mask) | ||
1745 | { | ||
1746 | xfs_buftarg_t *btp; | ||
1747 | |||
1748 | spin_lock(&xfs_buftarg_lock); | ||
1749 | list_for_each_entry(btp, &xfs_buftarg_list, bt_list) { | ||
1750 | if (test_bit(XBT_FORCE_SLEEP, &btp->bt_flags)) | ||
1751 | continue; | ||
1752 | if (list_empty(&btp->bt_delwrite_queue)) | ||
1753 | continue; | ||
1754 | set_bit(XBT_FORCE_FLUSH, &btp->bt_flags); | ||
1755 | wake_up_process(btp->bt_task); | ||
1756 | } | ||
1757 | spin_unlock(&xfs_buftarg_lock); | ||
1758 | return 0; | ||
1759 | } | ||
1760 | |||
1761 | /* | 1722 | /* |
1762 | * Move as many buffers as specified to the supplied list | 1723 | * Move as many buffers as specified to the supplied list |
1763 | * idicating if we skipped any buffers to prevent deadlocks. | 1724 | * idicating if we skipped any buffers to prevent deadlocks. |
@@ -1952,7 +1913,6 @@ xfs_buf_init(void) | |||
1952 | if (!xfsconvertd_workqueue) | 1913 | if (!xfsconvertd_workqueue) |
1953 | goto out_destroy_xfsdatad_workqueue; | 1914 | goto out_destroy_xfsdatad_workqueue; |
1954 | 1915 | ||
1955 | register_shrinker(&xfs_buf_shake); | ||
1956 | return 0; | 1916 | return 0; |
1957 | 1917 | ||
1958 | out_destroy_xfsdatad_workqueue: | 1918 | out_destroy_xfsdatad_workqueue: |
@@ -1968,7 +1928,6 @@ xfs_buf_init(void) | |||
1968 | void | 1928 | void |
1969 | xfs_buf_terminate(void) | 1929 | xfs_buf_terminate(void) |
1970 | { | 1930 | { |
1971 | unregister_shrinker(&xfs_buf_shake); | ||
1972 | destroy_workqueue(xfsconvertd_workqueue); | 1931 | destroy_workqueue(xfsconvertd_workqueue); |
1973 | destroy_workqueue(xfsdatad_workqueue); | 1932 | destroy_workqueue(xfsdatad_workqueue); |
1974 | destroy_workqueue(xfslogd_workqueue); | 1933 | destroy_workqueue(xfslogd_workqueue); |