diff options
author | Christoph Hellwig <hch@sgi.com> | 2005-11-01 18:15:05 -0500 |
---|---|---|
committer | Nathan Scott <nathans@sgi.com> | 2005-11-01 18:15:05 -0500 |
commit | 04d8b2841630b793919cc1ece9e77ac4de338c9e (patch) | |
tree | 89bee123d779690947eb468e2d68154000760355 | |
parent | df70b17f88a4d1d8545d3569a1f6d28c6004f9e4 (diff) |
[XFS] Make sure the threads and shaker in xfs_buf are de-initialized in
reverse startup order
SGI-PV: 942063
SGI-Modid: xfs-linux:xfs-kern:198651a
Signed-off-by: Christoph Hellwig <hch@sgi.com>
Signed-off-by: Nathan Scott <nathans@sgi.com>
-rw-r--r-- | fs/xfs/linux-2.6/xfs_buf.c | 87 |
1 files changed, 25 insertions, 62 deletions
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c index 4cd46abe8434..43128395d63b 100644 --- a/fs/xfs/linux-2.6/xfs_buf.c +++ b/fs/xfs/linux-2.6/xfs_buf.c | |||
@@ -1891,14 +1891,22 @@ xfs_flush_buftarg( | |||
1891 | return pincount; | 1891 | return pincount; |
1892 | } | 1892 | } |
1893 | 1893 | ||
1894 | STATIC int | 1894 | int __init |
1895 | xfs_buf_daemons_start(void) | 1895 | pagebuf_init(void) |
1896 | { | 1896 | { |
1897 | int error = -ENOMEM; | 1897 | int error = -ENOMEM; |
1898 | 1898 | ||
1899 | #ifdef PAGEBUF_TRACE | ||
1900 | pagebuf_trace_buf = ktrace_alloc(PAGEBUF_TRACE_SIZE, KM_SLEEP); | ||
1901 | #endif | ||
1902 | |||
1903 | pagebuf_zone = kmem_zone_init(sizeof(xfs_buf_t), "xfs_buf"); | ||
1904 | if (!pagebuf_zone) | ||
1905 | goto out_free_trace_buf; | ||
1906 | |||
1899 | xfslogd_workqueue = create_workqueue("xfslogd"); | 1907 | xfslogd_workqueue = create_workqueue("xfslogd"); |
1900 | if (!xfslogd_workqueue) | 1908 | if (!xfslogd_workqueue) |
1901 | goto out; | 1909 | goto out_free_buf_zone; |
1902 | 1910 | ||
1903 | xfsdatad_workqueue = create_workqueue("xfsdatad"); | 1911 | xfsdatad_workqueue = create_workqueue("xfsdatad"); |
1904 | if (!xfsdatad_workqueue) | 1912 | if (!xfsdatad_workqueue) |
@@ -1909,82 +1917,37 @@ xfs_buf_daemons_start(void) | |||
1909 | error = PTR_ERR(xfsbufd_task); | 1917 | error = PTR_ERR(xfsbufd_task); |
1910 | goto out_destroy_xfsdatad_workqueue; | 1918 | goto out_destroy_xfsdatad_workqueue; |
1911 | } | 1919 | } |
1920 | |||
1921 | pagebuf_shake = kmem_shake_register(xfsbufd_wakeup); | ||
1922 | if (!pagebuf_shake) | ||
1923 | goto out_stop_xfsbufd; | ||
1924 | |||
1912 | return 0; | 1925 | return 0; |
1913 | 1926 | ||
1927 | out_stop_xfsbufd: | ||
1928 | kthread_stop(xfsbufd_task); | ||
1914 | out_destroy_xfsdatad_workqueue: | 1929 | out_destroy_xfsdatad_workqueue: |
1915 | destroy_workqueue(xfsdatad_workqueue); | 1930 | destroy_workqueue(xfsdatad_workqueue); |
1916 | out_destroy_xfslogd_workqueue: | 1931 | out_destroy_xfslogd_workqueue: |
1917 | destroy_workqueue(xfslogd_workqueue); | 1932 | destroy_workqueue(xfslogd_workqueue); |
1918 | out: | ||
1919 | return error; | ||
1920 | } | ||
1921 | |||
1922 | /* | ||
1923 | * Note: do not mark as __exit, it is called from pagebuf_terminate. | ||
1924 | */ | ||
1925 | STATIC void | ||
1926 | xfs_buf_daemons_stop(void) | ||
1927 | { | ||
1928 | kthread_stop(xfsbufd_task); | ||
1929 | destroy_workqueue(xfslogd_workqueue); | ||
1930 | destroy_workqueue(xfsdatad_workqueue); | ||
1931 | } | ||
1932 | |||
1933 | /* | ||
1934 | * Initialization and Termination | ||
1935 | */ | ||
1936 | |||
1937 | int __init | ||
1938 | pagebuf_init(void) | ||
1939 | { | ||
1940 | int error = -ENOMEM; | ||
1941 | |||
1942 | pagebuf_zone = kmem_zone_init(sizeof(xfs_buf_t), "xfs_buf"); | ||
1943 | if (!pagebuf_zone) | ||
1944 | goto out; | ||
1945 | |||
1946 | #ifdef PAGEBUF_TRACE | ||
1947 | pagebuf_trace_buf = ktrace_alloc(PAGEBUF_TRACE_SIZE, KM_SLEEP); | ||
1948 | #endif | ||
1949 | |||
1950 | error = xfs_buf_daemons_start(); | ||
1951 | if (error) | ||
1952 | goto out_free_buf_zone; | ||
1953 | |||
1954 | pagebuf_shake = kmem_shake_register(xfsbufd_wakeup); | ||
1955 | if (!pagebuf_shake) { | ||
1956 | error = -ENOMEM; | ||
1957 | goto out_stop_daemons; | ||
1958 | } | ||
1959 | |||
1960 | return 0; | ||
1961 | |||
1962 | out_stop_daemons: | ||
1963 | xfs_buf_daemons_stop(); | ||
1964 | out_free_buf_zone: | 1933 | out_free_buf_zone: |
1934 | kmem_zone_destroy(pagebuf_zone); | ||
1935 | out_free_trace_buf: | ||
1965 | #ifdef PAGEBUF_TRACE | 1936 | #ifdef PAGEBUF_TRACE |
1966 | ktrace_free(pagebuf_trace_buf); | 1937 | ktrace_free(pagebuf_trace_buf); |
1967 | #endif | 1938 | #endif |
1968 | kmem_zone_destroy(pagebuf_zone); | ||
1969 | out: | ||
1970 | return error; | 1939 | return error; |
1971 | } | 1940 | } |
1972 | 1941 | ||
1973 | |||
1974 | /* | ||
1975 | * pagebuf_terminate. | ||
1976 | * | ||
1977 | * Note: do not mark as __exit, this is also called from the __init code. | ||
1978 | */ | ||
1979 | void | 1942 | void |
1980 | pagebuf_terminate(void) | 1943 | pagebuf_terminate(void) |
1981 | { | 1944 | { |
1982 | xfs_buf_daemons_stop(); | 1945 | kmem_shake_deregister(pagebuf_shake); |
1983 | 1946 | kthread_stop(xfsbufd_task); | |
1947 | destroy_workqueue(xfsdatad_workqueue); | ||
1948 | destroy_workqueue(xfslogd_workqueue); | ||
1949 | kmem_zone_destroy(pagebuf_zone); | ||
1984 | #ifdef PAGEBUF_TRACE | 1950 | #ifdef PAGEBUF_TRACE |
1985 | ktrace_free(pagebuf_trace_buf); | 1951 | ktrace_free(pagebuf_trace_buf); |
1986 | #endif | 1952 | #endif |
1987 | |||
1988 | kmem_zone_destroy(pagebuf_zone); | ||
1989 | kmem_shake_deregister(pagebuf_shake); | ||
1990 | } | 1953 | } |