aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/linux-2.6/xfs_buf.c143
1 files changed, 77 insertions, 66 deletions
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c
index 997963e53622..f5676ed5136d 100644
--- a/fs/xfs/linux-2.6/xfs_buf.c
+++ b/fs/xfs/linux-2.6/xfs_buf.c
@@ -61,12 +61,13 @@
61 * File wide globals 61 * File wide globals
62 */ 62 */
63 63
64STATIC kmem_cache_t *pagebuf_cache; 64STATIC kmem_cache_t *pagebuf_zone;
65STATIC kmem_shaker_t pagebuf_shake; 65STATIC kmem_shaker_t pagebuf_shake;
66STATIC int pagebuf_daemon_wakeup(int, unsigned int); 66STATIC int xfsbufd_wakeup(int, unsigned int);
67STATIC void pagebuf_delwri_queue(xfs_buf_t *, int); 67STATIC void pagebuf_delwri_queue(xfs_buf_t *, int);
68STATIC struct workqueue_struct *pagebuf_logio_workqueue; 68
69STATIC struct workqueue_struct *pagebuf_dataio_workqueue; 69STATIC struct workqueue_struct *xfslogd_workqueue;
70STATIC struct workqueue_struct *xfsdatad_workqueue;
70 71
71/* 72/*
72 * Pagebuf debugging 73 * Pagebuf debugging
@@ -123,9 +124,9 @@ ktrace_t *pagebuf_trace_buf;
123 124
124 125
125#define pagebuf_allocate(flags) \ 126#define pagebuf_allocate(flags) \
126 kmem_zone_alloc(pagebuf_cache, pb_to_km(flags)) 127 kmem_zone_alloc(pagebuf_zone, pb_to_km(flags))
127#define pagebuf_deallocate(pb) \ 128#define pagebuf_deallocate(pb) \
128 kmem_zone_free(pagebuf_cache, (pb)); 129 kmem_zone_free(pagebuf_zone, (pb));
129 130
130/* 131/*
131 * Page Region interfaces. 132 * Page Region interfaces.
@@ -425,7 +426,7 @@ _pagebuf_lookup_pages(
425 __FUNCTION__, gfp_mask); 426 __FUNCTION__, gfp_mask);
426 427
427 XFS_STATS_INC(pb_page_retries); 428 XFS_STATS_INC(pb_page_retries);
428 pagebuf_daemon_wakeup(0, gfp_mask); 429 xfsbufd_wakeup(0, gfp_mask);
429 blk_congestion_wait(WRITE, HZ/50); 430 blk_congestion_wait(WRITE, HZ/50);
430 goto retry; 431 goto retry;
431 } 432 }
@@ -1136,8 +1137,8 @@ pagebuf_iodone(
1136 if ((pb->pb_iodone) || (pb->pb_flags & PBF_ASYNC)) { 1137 if ((pb->pb_iodone) || (pb->pb_flags & PBF_ASYNC)) {
1137 if (schedule) { 1138 if (schedule) {
1138 INIT_WORK(&pb->pb_iodone_work, pagebuf_iodone_work, pb); 1139 INIT_WORK(&pb->pb_iodone_work, pagebuf_iodone_work, pb);
1139 queue_work(dataio ? pagebuf_dataio_workqueue : 1140 queue_work(dataio ? xfsdatad_workqueue :
1140 pagebuf_logio_workqueue, &pb->pb_iodone_work); 1141 xfslogd_workqueue, &pb->pb_iodone_work);
1141 } else { 1142 } else {
1142 pagebuf_iodone_work(pb); 1143 pagebuf_iodone_work(pb);
1143 } 1144 }
@@ -1742,27 +1743,27 @@ pagebuf_runall_queues(
1742} 1743}
1743 1744
1744/* Defines for pagebuf daemon */ 1745/* Defines for pagebuf daemon */
1745STATIC DECLARE_COMPLETION(pagebuf_daemon_done); 1746STATIC DECLARE_COMPLETION(xfsbufd_done);
1746STATIC struct task_struct *pagebuf_daemon_task; 1747STATIC struct task_struct *xfsbufd_task;
1747STATIC int pagebuf_daemon_active; 1748STATIC int xfsbufd_active;
1748STATIC int force_flush; 1749STATIC int xfsbufd_force_flush;
1749STATIC int force_sleep; 1750STATIC int xfsbufd_force_sleep;
1750 1751
1751STATIC int 1752STATIC int
1752pagebuf_daemon_wakeup( 1753xfsbufd_wakeup(
1753 int priority, 1754 int priority,
1754 unsigned int mask) 1755 unsigned int mask)
1755{ 1756{
1756 if (force_sleep) 1757 if (xfsbufd_force_sleep)
1757 return 0; 1758 return 0;
1758 force_flush = 1; 1759 xfsbufd_force_flush = 1;
1759 barrier(); 1760 barrier();
1760 wake_up_process(pagebuf_daemon_task); 1761 wake_up_process(xfsbufd_task);
1761 return 0; 1762 return 0;
1762} 1763}
1763 1764
1764STATIC int 1765STATIC int
1765pagebuf_daemon( 1766xfsbufd(
1766 void *data) 1767 void *data)
1767{ 1768{
1768 struct list_head tmp; 1769 struct list_head tmp;
@@ -1774,17 +1775,17 @@ pagebuf_daemon(
1774 daemonize("xfsbufd"); 1775 daemonize("xfsbufd");
1775 current->flags |= PF_MEMALLOC; 1776 current->flags |= PF_MEMALLOC;
1776 1777
1777 pagebuf_daemon_task = current; 1778 xfsbufd_task = current;
1778 pagebuf_daemon_active = 1; 1779 xfsbufd_active = 1;
1779 barrier(); 1780 barrier();
1780 1781
1781 INIT_LIST_HEAD(&tmp); 1782 INIT_LIST_HEAD(&tmp);
1782 do { 1783 do {
1783 if (unlikely(current->flags & PF_FREEZE)) { 1784 if (unlikely(current->flags & PF_FREEZE)) {
1784 force_sleep = 1; 1785 xfsbufd_force_sleep = 1;
1785 refrigerator(PF_FREEZE); 1786 refrigerator(PF_FREEZE);
1786 } else { 1787 } else {
1787 force_sleep = 0; 1788 xfsbufd_force_sleep = 0;
1788 } 1789 }
1789 1790
1790 set_current_state(TASK_INTERRUPTIBLE); 1791 set_current_state(TASK_INTERRUPTIBLE);
@@ -1797,7 +1798,7 @@ pagebuf_daemon(
1797 ASSERT(pb->pb_flags & PBF_DELWRI); 1798 ASSERT(pb->pb_flags & PBF_DELWRI);
1798 1799
1799 if (!pagebuf_ispin(pb) && !pagebuf_cond_lock(pb)) { 1800 if (!pagebuf_ispin(pb) && !pagebuf_cond_lock(pb)) {
1800 if (!force_flush && 1801 if (!xfsbufd_force_flush &&
1801 time_before(jiffies, 1802 time_before(jiffies,
1802 pb->pb_queuetime + age)) { 1803 pb->pb_queuetime + age)) {
1803 pagebuf_unlock(pb); 1804 pagebuf_unlock(pb);
@@ -1824,10 +1825,10 @@ pagebuf_daemon(
1824 if (as_list_len > 0) 1825 if (as_list_len > 0)
1825 purge_addresses(); 1826 purge_addresses();
1826 1827
1827 force_flush = 0; 1828 xfsbufd_force_flush = 0;
1828 } while (pagebuf_daemon_active); 1829 } while (xfsbufd_active);
1829 1830
1830 complete_and_exit(&pagebuf_daemon_done, 0); 1831 complete_and_exit(&xfsbufd_done, 0);
1831} 1832}
1832 1833
1833/* 1834/*
@@ -1844,8 +1845,8 @@ xfs_flush_buftarg(
1844 xfs_buf_t *pb, *n; 1845 xfs_buf_t *pb, *n;
1845 int pincount = 0; 1846 int pincount = 0;
1846 1847
1847 pagebuf_runall_queues(pagebuf_dataio_workqueue); 1848 pagebuf_runall_queues(xfsdatad_workqueue);
1848 pagebuf_runall_queues(pagebuf_logio_workqueue); 1849 pagebuf_runall_queues(xfslogd_workqueue);
1849 1850
1850 INIT_LIST_HEAD(&tmp); 1851 INIT_LIST_HEAD(&tmp);
1851 spin_lock(&pbd_delwrite_lock); 1852 spin_lock(&pbd_delwrite_lock);
@@ -1898,43 +1899,43 @@ xfs_flush_buftarg(
1898} 1899}
1899 1900
1900STATIC int 1901STATIC int
1901pagebuf_daemon_start(void) 1902xfs_buf_daemons_start(void)
1902{ 1903{
1903 int rval; 1904 int error = -ENOMEM;
1904 1905
1905 pagebuf_logio_workqueue = create_workqueue("xfslogd"); 1906 xfslogd_workqueue = create_workqueue("xfslogd");
1906 if (!pagebuf_logio_workqueue) 1907 if (!xfslogd_workqueue)
1907 return -ENOMEM; 1908 goto out;
1908 1909
1909 pagebuf_dataio_workqueue = create_workqueue("xfsdatad"); 1910 xfsdatad_workqueue = create_workqueue("xfsdatad");
1910 if (!pagebuf_dataio_workqueue) { 1911 if (!xfsdatad_workqueue)
1911 destroy_workqueue(pagebuf_logio_workqueue); 1912 goto out_destroy_xfslogd_workqueue;
1912 return -ENOMEM;
1913 }
1914 1913
1915 rval = kernel_thread(pagebuf_daemon, NULL, CLONE_FS|CLONE_FILES); 1914 error = kernel_thread(xfsbufd, NULL, CLONE_FS|CLONE_FILES);
1916 if (rval < 0) { 1915 if (error < 0)
1917 destroy_workqueue(pagebuf_logio_workqueue); 1916 goto out_destroy_xfsdatad_workqueue;
1918 destroy_workqueue(pagebuf_dataio_workqueue); 1917 return 0;
1919 }
1920 1918
1921 return rval; 1919 out_destroy_xfsdatad_workqueue:
1920 destroy_workqueue(xfsdatad_workqueue);
1921 out_destroy_xfslogd_workqueue:
1922 destroy_workqueue(xfslogd_workqueue);
1923 out:
1924 return error;
1922} 1925}
1923 1926
1924/* 1927/*
1925 * pagebuf_daemon_stop
1926 *
1927 * Note: do not mark as __exit, it is called from pagebuf_terminate. 1928 * Note: do not mark as __exit, it is called from pagebuf_terminate.
1928 */ 1929 */
1929STATIC void 1930STATIC void
1930pagebuf_daemon_stop(void) 1931xfs_buf_daemons_stop(void)
1931{ 1932{
1932 pagebuf_daemon_active = 0; 1933 xfsbufd_active = 0;
1933 barrier(); 1934 barrier();
1934 wait_for_completion(&pagebuf_daemon_done); 1935 wait_for_completion(&xfsbufd_done);
1935 1936
1936 destroy_workqueue(pagebuf_logio_workqueue); 1937 destroy_workqueue(xfslogd_workqueue);
1937 destroy_workqueue(pagebuf_dataio_workqueue); 1938 destroy_workqueue(xfsdatad_workqueue);
1938} 1939}
1939 1940
1940/* 1941/*
@@ -1944,27 +1945,37 @@ pagebuf_daemon_stop(void)
1944int __init 1945int __init
1945pagebuf_init(void) 1946pagebuf_init(void)
1946{ 1947{
1947 pagebuf_cache = kmem_cache_create("xfs_buf_t", sizeof(xfs_buf_t), 0, 1948 int error = -ENOMEM;
1948 SLAB_HWCACHE_ALIGN, NULL, NULL); 1949
1949 if (pagebuf_cache == NULL) { 1950 pagebuf_zone = kmem_zone_init(sizeof(xfs_buf_t), "xfs_buf");
1950 printk("XFS: couldn't init xfs_buf_t cache\n"); 1951 if (!pagebuf_zone)
1951 pagebuf_terminate(); 1952 goto out;
1952 return -ENOMEM;
1953 }
1954 1953
1955#ifdef PAGEBUF_TRACE 1954#ifdef PAGEBUF_TRACE
1956 pagebuf_trace_buf = ktrace_alloc(PAGEBUF_TRACE_SIZE, KM_SLEEP); 1955 pagebuf_trace_buf = ktrace_alloc(PAGEBUF_TRACE_SIZE, KM_SLEEP);
1957#endif 1956#endif
1958 1957
1959 pagebuf_daemon_start(); 1958 error = xfs_buf_daemons_start();
1959 if (!error)
1960 goto out_free_buf_zone;
1960 1961
1961 pagebuf_shake = kmem_shake_register(pagebuf_daemon_wakeup); 1962 pagebuf_shake = kmem_shake_register(xfsbufd_wakeup);
1962 if (pagebuf_shake == NULL) { 1963 if (!pagebuf_shake) {
1963 pagebuf_terminate(); 1964 error = -ENOMEM;
1964 return -ENOMEM; 1965 goto out_stop_daemons;
1965 } 1966 }
1966 1967
1967 return 0; 1968 return 0;
1969
1970 out_stop_daemons:
1971 xfs_buf_daemons_stop();
1972 out_free_buf_zone:
1973#ifdef PAGEBUF_TRACE
1974 ktrace_free(pagebuf_trace_buf);
1975#endif
1976 kmem_zone_destroy(pagebuf_zone);
1977 out:
1978 return error;
1968} 1979}
1969 1980
1970 1981
@@ -1976,12 +1987,12 @@ pagebuf_init(void)
1976void 1987void
1977pagebuf_terminate(void) 1988pagebuf_terminate(void)
1978{ 1989{
1979 pagebuf_daemon_stop(); 1990 xfs_buf_daemons_stop();
1980 1991
1981#ifdef PAGEBUF_TRACE 1992#ifdef PAGEBUF_TRACE
1982 ktrace_free(pagebuf_trace_buf); 1993 ktrace_free(pagebuf_trace_buf);
1983#endif 1994#endif
1984 1995
1985 kmem_zone_destroy(pagebuf_cache); 1996 kmem_zone_destroy(pagebuf_zone);
1986 kmem_shake_deregister(pagebuf_shake); 1997 kmem_shake_deregister(pagebuf_shake);
1987} 1998}