diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/xfs/linux-2.6/xfs_buf.c | 143 |
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 997963e5362..f5676ed5136 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 | ||
64 | STATIC kmem_cache_t *pagebuf_cache; | 64 | STATIC kmem_cache_t *pagebuf_zone; |
65 | STATIC kmem_shaker_t pagebuf_shake; | 65 | STATIC kmem_shaker_t pagebuf_shake; |
66 | STATIC int pagebuf_daemon_wakeup(int, unsigned int); | 66 | STATIC int xfsbufd_wakeup(int, unsigned int); |
67 | STATIC void pagebuf_delwri_queue(xfs_buf_t *, int); | 67 | STATIC void pagebuf_delwri_queue(xfs_buf_t *, int); |
68 | STATIC struct workqueue_struct *pagebuf_logio_workqueue; | 68 | |
69 | STATIC struct workqueue_struct *pagebuf_dataio_workqueue; | 69 | STATIC struct workqueue_struct *xfslogd_workqueue; |
70 | STATIC 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 */ |
1745 | STATIC DECLARE_COMPLETION(pagebuf_daemon_done); | 1746 | STATIC DECLARE_COMPLETION(xfsbufd_done); |
1746 | STATIC struct task_struct *pagebuf_daemon_task; | 1747 | STATIC struct task_struct *xfsbufd_task; |
1747 | STATIC int pagebuf_daemon_active; | 1748 | STATIC int xfsbufd_active; |
1748 | STATIC int force_flush; | 1749 | STATIC int xfsbufd_force_flush; |
1749 | STATIC int force_sleep; | 1750 | STATIC int xfsbufd_force_sleep; |
1750 | 1751 | ||
1751 | STATIC int | 1752 | STATIC int |
1752 | pagebuf_daemon_wakeup( | 1753 | xfsbufd_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 | ||
1764 | STATIC int | 1765 | STATIC int |
1765 | pagebuf_daemon( | 1766 | xfsbufd( |
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 | ||
1900 | STATIC int | 1901 | STATIC int |
1901 | pagebuf_daemon_start(void) | 1902 | xfs_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 | */ |
1929 | STATIC void | 1930 | STATIC void |
1930 | pagebuf_daemon_stop(void) | 1931 | xfs_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) | |||
1944 | int __init | 1945 | int __init |
1945 | pagebuf_init(void) | 1946 | pagebuf_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) | |||
1976 | void | 1987 | void |
1977 | pagebuf_terminate(void) | 1988 | pagebuf_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 | } |