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 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 | ||
| 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 | } |
