aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/linux-2.6/xfs_buf.c89
-rw-r--r--fs/xfs/linux-2.6/xfs_buf.h4
2 files changed, 27 insertions, 66 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
45static kmem_zone_t *xfs_buf_zone; 45static kmem_zone_t *xfs_buf_zone;
46STATIC int xfsbufd(void *); 46STATIC int xfsbufd(void *);
47STATIC int xfsbufd_wakeup(struct shrinker *, int, gfp_t);
48STATIC void xfs_buf_delwri_queue(xfs_buf_t *, int); 47STATIC void xfs_buf_delwri_queue(xfs_buf_t *, int);
49static struct shrinker xfs_buf_shake = {
50 .shrink = xfsbufd_wakeup,
51 .seeks = DEFAULT_SEEKS,
52};
53 48
54static struct workqueue_struct *xfslogd_workqueue; 49static struct workqueue_struct *xfslogd_workqueue;
55struct workqueue_struct *xfsdatad_workqueue; 50struct 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/* 1458int
1465 * buftarg list for delwrite queue processing 1459xfs_buftarg_shrink(
1466 */ 1460 struct shrinker *shrink,
1467static LIST_HEAD(xfs_buftarg_list); 1461 int nr_to_scan,
1468static DEFINE_SPINLOCK(xfs_buftarg_lock); 1462 gfp_t mask)
1469
1470STATIC void
1471xfs_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
1479STATIC void
1480xfs_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
1488void 1477void
@@ -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);
1612out_error:
1613 return error;
1614} 1593}
1615 1594
1616xfs_buftarg_t * 1595xfs_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
1638error: 1620error:
@@ -1737,27 +1719,6 @@ xfs_buf_runall_queues(
1737 flush_workqueue(queue); 1719 flush_workqueue(queue);
1738} 1720}
1739 1721
1740STATIC int
1741xfsbufd_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)
1968void 1928void
1969xfs_buf_terminate(void) 1929xfs_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);
diff --git a/fs/xfs/linux-2.6/xfs_buf.h b/fs/xfs/linux-2.6/xfs_buf.h
index 383a3f37cf98..9344103e77d6 100644
--- a/fs/xfs/linux-2.6/xfs_buf.h
+++ b/fs/xfs/linux-2.6/xfs_buf.h
@@ -128,10 +128,12 @@ typedef struct xfs_buftarg {
128 128
129 /* per device delwri queue */ 129 /* per device delwri queue */
130 struct task_struct *bt_task; 130 struct task_struct *bt_task;
131 struct list_head bt_list;
132 struct list_head bt_delwrite_queue; 131 struct list_head bt_delwrite_queue;
133 spinlock_t bt_delwrite_lock; 132 spinlock_t bt_delwrite_lock;
134 unsigned long bt_flags; 133 unsigned long bt_flags;
134
135 /* LRU control structures */
136 struct shrinker bt_shrinker;
135} xfs_buftarg_t; 137} xfs_buftarg_t;
136 138
137/* 139/*