aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/linux-2.6
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2008-07-18 03:11:46 -0400
committerNiv Sardi <xaiki@debian.org>2008-07-28 02:59:25 -0400
commit9f8868ffb39c2f80ba69df4552cb530b6634f646 (patch)
treefba09366faf55ee039cdbd91dff78b7d87a86d0b /fs/xfs/linux-2.6
parent136f8f21b6d564f553abe6130127d16fb50432d3 (diff)
[XFS] streamline init/exit path
Currently the xfs module init/exit code is a mess. It's farmed out over a lot of function with very little error checking. This patch makes sure we propagate all initialization failures properly and clean up after them. Various runtime initializations are replaced with compile-time initializations where possible to make this easier. The exit path is similarly consolidated. There's now split out function to create/destroy the kmem zones and alloc/free the trace buffers. I've also changed the ktrace allocations to KM_MAYFAIL and handled errors resulting from that. And yes, we really should replace the XFS_*_TRACE ifdefs with a single XFS_TRACE.. SGI-PV: 976035 SGI-Modid: xfs-linux-melb:xfs-kern:31354a Signed-off-by: Christoph Hellwig <hch@infradead.org> Signed-off-by: Niv Sardi <xaiki@sgi.com> Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
Diffstat (limited to 'fs/xfs/linux-2.6')
-rw-r--r--fs/xfs/linux-2.6/xfs_stats.c15
-rw-r--r--fs/xfs/linux-2.6/xfs_stats.h11
-rw-r--r--fs/xfs/linux-2.6/xfs_super.c330
-rw-r--r--fs/xfs/linux-2.6/xfs_sysctl.c8
-rw-r--r--fs/xfs/linux-2.6/xfs_sysctl.h4
5 files changed, 305 insertions, 63 deletions
diff --git a/fs/xfs/linux-2.6/xfs_stats.c b/fs/xfs/linux-2.6/xfs_stats.c
index e480b6102051..3d5b67c075c7 100644
--- a/fs/xfs/linux-2.6/xfs_stats.c
+++ b/fs/xfs/linux-2.6/xfs_stats.c
@@ -98,12 +98,21 @@ xfs_read_xfsstats(
98 return len; 98 return len;
99} 99}
100 100
101void 101int
102xfs_init_procfs(void) 102xfs_init_procfs(void)
103{ 103{
104 if (!proc_mkdir("fs/xfs", NULL)) 104 if (!proc_mkdir("fs/xfs", NULL))
105 return; 105 goto out;
106 create_proc_read_entry("fs/xfs/stat", 0, NULL, xfs_read_xfsstats, NULL); 106
107 if (!create_proc_read_entry("fs/xfs/stat", 0, NULL,
108 xfs_read_xfsstats, NULL))
109 goto out_remove_entry;
110 return 0;
111
112 out_remove_entry:
113 remove_proc_entry("fs/xfs", NULL);
114 out:
115 return -ENOMEM;
107} 116}
108 117
109void 118void
diff --git a/fs/xfs/linux-2.6/xfs_stats.h b/fs/xfs/linux-2.6/xfs_stats.h
index afd0b0d5fdb2..3fa753d7b700 100644
--- a/fs/xfs/linux-2.6/xfs_stats.h
+++ b/fs/xfs/linux-2.6/xfs_stats.h
@@ -134,7 +134,7 @@ DECLARE_PER_CPU(struct xfsstats, xfsstats);
134#define XFS_STATS_DEC(v) (per_cpu(xfsstats, current_cpu()).v--) 134#define XFS_STATS_DEC(v) (per_cpu(xfsstats, current_cpu()).v--)
135#define XFS_STATS_ADD(v, inc) (per_cpu(xfsstats, current_cpu()).v += (inc)) 135#define XFS_STATS_ADD(v, inc) (per_cpu(xfsstats, current_cpu()).v += (inc))
136 136
137extern void xfs_init_procfs(void); 137extern int xfs_init_procfs(void);
138extern void xfs_cleanup_procfs(void); 138extern void xfs_cleanup_procfs(void);
139 139
140 140
@@ -144,8 +144,13 @@ extern void xfs_cleanup_procfs(void);
144# define XFS_STATS_DEC(count) 144# define XFS_STATS_DEC(count)
145# define XFS_STATS_ADD(count, inc) 145# define XFS_STATS_ADD(count, inc)
146 146
147static inline void xfs_init_procfs(void) { }; 147static inline int xfs_init_procfs(void)
148static inline void xfs_cleanup_procfs(void) { }; 148{
149 return 0
150};
151static inline void xfs_cleanup_procfs(void)
152{
153};
149 154
150#endif /* !CONFIG_PROC_FS */ 155#endif /* !CONFIG_PROC_FS */
151 156
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c
index 967603c46998..7c621dfee73d 100644
--- a/fs/xfs/linux-2.6/xfs_super.c
+++ b/fs/xfs/linux-2.6/xfs_super.c
@@ -53,6 +53,11 @@
53#include "xfs_log_priv.h" 53#include "xfs_log_priv.h"
54#include "xfs_trans_priv.h" 54#include "xfs_trans_priv.h"
55#include "xfs_filestream.h" 55#include "xfs_filestream.h"
56#include "xfs_da_btree.h"
57#include "xfs_dir2_trace.h"
58#include "xfs_extfree_item.h"
59#include "xfs_mru_cache.h"
60#include "xfs_inode_item.h"
56 61
57#include <linux/namei.h> 62#include <linux/namei.h>
58#include <linux/init.h> 63#include <linux/init.h>
@@ -987,42 +992,6 @@ xfs_fs_inode_init_once(
987 inode_init_once(vn_to_inode((bhv_vnode_t *)vnode)); 992 inode_init_once(vn_to_inode((bhv_vnode_t *)vnode));
988} 993}
989 994
990STATIC int __init
991xfs_init_zones(void)
992{
993 xfs_vnode_zone = kmem_zone_init_flags(sizeof(bhv_vnode_t), "xfs_vnode",
994 KM_ZONE_HWALIGN | KM_ZONE_RECLAIM |
995 KM_ZONE_SPREAD,
996 xfs_fs_inode_init_once);
997 if (!xfs_vnode_zone)
998 goto out;
999
1000 xfs_ioend_zone = kmem_zone_init(sizeof(xfs_ioend_t), "xfs_ioend");
1001 if (!xfs_ioend_zone)
1002 goto out_destroy_vnode_zone;
1003
1004 xfs_ioend_pool = mempool_create_slab_pool(4 * MAX_BUF_PER_PAGE,
1005 xfs_ioend_zone);
1006 if (!xfs_ioend_pool)
1007 goto out_free_ioend_zone;
1008 return 0;
1009
1010 out_free_ioend_zone:
1011 kmem_zone_destroy(xfs_ioend_zone);
1012 out_destroy_vnode_zone:
1013 kmem_zone_destroy(xfs_vnode_zone);
1014 out:
1015 return -ENOMEM;
1016}
1017
1018STATIC void
1019xfs_destroy_zones(void)
1020{
1021 mempool_destroy(xfs_ioend_pool);
1022 kmem_zone_destroy(xfs_vnode_zone);
1023 kmem_zone_destroy(xfs_ioend_zone);
1024}
1025
1026/* 995/*
1027 * Attempt to flush the inode, this will actually fail 996 * Attempt to flush the inode, this will actually fail
1028 * if the inode is pinned, but we dirty the inode again 997 * if the inode is pinned, but we dirty the inode again
@@ -1939,9 +1908,235 @@ static struct file_system_type xfs_fs_type = {
1939 .fs_flags = FS_REQUIRES_DEV, 1908 .fs_flags = FS_REQUIRES_DEV,
1940}; 1909};
1941 1910
1911STATIC int __init
1912xfs_alloc_trace_bufs(void)
1913{
1914#ifdef XFS_ALLOC_TRACE
1915 xfs_alloc_trace_buf = ktrace_alloc(XFS_ALLOC_TRACE_SIZE, KM_MAYFAIL);
1916 if (!xfs_alloc_trace_buf)
1917 goto out;
1918#endif
1919#ifdef XFS_BMAP_TRACE
1920 xfs_bmap_trace_buf = ktrace_alloc(XFS_BMAP_TRACE_SIZE, KM_MAYFAIL);
1921 if (!xfs_bmap_trace_buf)
1922 goto out_free_alloc_trace;
1923#endif
1924#ifdef XFS_BMBT_TRACE
1925 xfs_bmbt_trace_buf = ktrace_alloc(XFS_BMBT_TRACE_SIZE, KM_MAYFAIL);
1926 if (!xfs_bmbt_trace_buf)
1927 goto out_free_bmap_trace;
1928#endif
1929#ifdef XFS_ATTR_TRACE
1930 xfs_attr_trace_buf = ktrace_alloc(XFS_ATTR_TRACE_SIZE, KM_MAYFAIL);
1931 if (!xfs_attr_trace_buf)
1932 goto out_free_bmbt_trace;
1933#endif
1934#ifdef XFS_DIR2_TRACE
1935 xfs_dir2_trace_buf = ktrace_alloc(XFS_DIR2_GTRACE_SIZE, KM_MAYFAIL);
1936 if (!xfs_dir2_trace_buf)
1937 goto out_free_attr_trace;
1938#endif
1939
1940 return 0;
1941
1942#ifdef XFS_DIR2_TRACE
1943 out_free_attr_trace:
1944#endif
1945#ifdef XFS_ATTR_TRACE
1946 ktrace_free(xfs_attr_trace_buf);
1947 out_free_bmbt_trace:
1948#endif
1949#ifdef XFS_BMBT_TRACE
1950 ktrace_free(xfs_bmbt_trace_buf);
1951 out_free_bmap_trace:
1952#endif
1953#ifdef XFS_BMAP_TRACE
1954 ktrace_free(xfs_bmap_trace_buf);
1955 out_free_alloc_trace:
1956#endif
1957#ifdef XFS_ALLOC_TRACE
1958 ktrace_free(xfs_alloc_trace_buf);
1959 out:
1960#endif
1961 return -ENOMEM;
1962}
1963
1964STATIC void
1965xfs_free_trace_bufs(void)
1966{
1967#ifdef XFS_DIR2_TRACE
1968 ktrace_free(xfs_dir2_trace_buf);
1969#endif
1970#ifdef XFS_ATTR_TRACE
1971 ktrace_free(xfs_attr_trace_buf);
1972#endif
1973#ifdef XFS_BMBT_TRACE
1974 ktrace_free(xfs_bmbt_trace_buf);
1975#endif
1976#ifdef XFS_BMAP_TRACE
1977 ktrace_free(xfs_bmap_trace_buf);
1978#endif
1979#ifdef XFS_ALLOC_TRACE
1980 ktrace_free(xfs_alloc_trace_buf);
1981#endif
1982}
1983
1984STATIC int __init
1985xfs_init_zones(void)
1986{
1987 xfs_vnode_zone = kmem_zone_init_flags(sizeof(bhv_vnode_t), "xfs_vnode",
1988 KM_ZONE_HWALIGN | KM_ZONE_RECLAIM |
1989 KM_ZONE_SPREAD,
1990 xfs_fs_inode_init_once);
1991 if (!xfs_vnode_zone)
1992 goto out;
1993
1994 xfs_ioend_zone = kmem_zone_init(sizeof(xfs_ioend_t), "xfs_ioend");
1995 if (!xfs_ioend_zone)
1996 goto out_destroy_vnode_zone;
1997
1998 xfs_ioend_pool = mempool_create_slab_pool(4 * MAX_BUF_PER_PAGE,
1999 xfs_ioend_zone);
2000 if (!xfs_ioend_pool)
2001 goto out_destroy_ioend_zone;
2002
2003 xfs_log_ticket_zone = kmem_zone_init(sizeof(xlog_ticket_t),
2004 "xfs_log_ticket");
2005 if (!xfs_log_ticket_zone)
2006 goto out_destroy_ioend_pool;
2007
2008 xfs_bmap_free_item_zone = kmem_zone_init(sizeof(xfs_bmap_free_item_t),
2009 "xfs_bmap_free_item");
2010 if (!xfs_bmap_free_item_zone)
2011 goto out_destroy_log_ticket_zone;
2012 xfs_btree_cur_zone = kmem_zone_init(sizeof(xfs_btree_cur_t),
2013 "xfs_btree_cur");
2014 if (!xfs_btree_cur_zone)
2015 goto out_destroy_bmap_free_item_zone;
2016
2017 xfs_da_state_zone = kmem_zone_init(sizeof(xfs_da_state_t),
2018 "xfs_da_state");
2019 if (!xfs_da_state_zone)
2020 goto out_destroy_btree_cur_zone;
2021
2022 xfs_dabuf_zone = kmem_zone_init(sizeof(xfs_dabuf_t), "xfs_dabuf");
2023 if (!xfs_dabuf_zone)
2024 goto out_destroy_da_state_zone;
2025
2026 xfs_ifork_zone = kmem_zone_init(sizeof(xfs_ifork_t), "xfs_ifork");
2027 if (!xfs_ifork_zone)
2028 goto out_destroy_dabuf_zone;
2029
2030 xfs_trans_zone = kmem_zone_init(sizeof(xfs_trans_t), "xfs_trans");
2031 if (!xfs_trans_zone)
2032 goto out_destroy_ifork_zone;
2033
2034 /*
2035 * The size of the zone allocated buf log item is the maximum
2036 * size possible under XFS. This wastes a little bit of memory,
2037 * but it is much faster.
2038 */
2039 xfs_buf_item_zone = kmem_zone_init((sizeof(xfs_buf_log_item_t) +
2040 (((XFS_MAX_BLOCKSIZE / XFS_BLI_CHUNK) /
2041 NBWORD) * sizeof(int))), "xfs_buf_item");
2042 if (!xfs_buf_item_zone)
2043 goto out_destroy_trans_zone;
2044
2045 xfs_efd_zone = kmem_zone_init((sizeof(xfs_efd_log_item_t) +
2046 ((XFS_EFD_MAX_FAST_EXTENTS - 1) *
2047 sizeof(xfs_extent_t))), "xfs_efd_item");
2048 if (!xfs_efd_zone)
2049 goto out_destroy_buf_item_zone;
2050
2051 xfs_efi_zone = kmem_zone_init((sizeof(xfs_efi_log_item_t) +
2052 ((XFS_EFI_MAX_FAST_EXTENTS - 1) *
2053 sizeof(xfs_extent_t))), "xfs_efi_item");
2054 if (!xfs_efi_zone)
2055 goto out_destroy_efd_zone;
2056
2057 xfs_inode_zone =
2058 kmem_zone_init_flags(sizeof(xfs_inode_t), "xfs_inode",
2059 KM_ZONE_HWALIGN | KM_ZONE_RECLAIM |
2060 KM_ZONE_SPREAD, NULL);
2061 if (!xfs_inode_zone)
2062 goto out_destroy_efi_zone;
2063
2064 xfs_ili_zone =
2065 kmem_zone_init_flags(sizeof(xfs_inode_log_item_t), "xfs_ili",
2066 KM_ZONE_SPREAD, NULL);
2067 if (!xfs_ili_zone)
2068 goto out_destroy_inode_zone;
2069
2070#ifdef CONFIG_XFS_POSIX_ACL
2071 xfs_acl_zone = kmem_zone_init(sizeof(xfs_acl_t), "xfs_acl");
2072 if (!xfs_acl_zone)
2073 goto out_destroy_ili_zone;
2074#endif
2075
2076 return 0;
2077
2078#ifdef CONFIG_XFS_POSIX_ACL
2079 out_destroy_ili_zone:
2080#endif
2081 kmem_zone_destroy(xfs_ili_zone);
2082 out_destroy_inode_zone:
2083 kmem_zone_destroy(xfs_inode_zone);
2084 out_destroy_efi_zone:
2085 kmem_zone_destroy(xfs_efi_zone);
2086 out_destroy_efd_zone:
2087 kmem_zone_destroy(xfs_efd_zone);
2088 out_destroy_buf_item_zone:
2089 kmem_zone_destroy(xfs_buf_item_zone);
2090 out_destroy_trans_zone:
2091 kmem_zone_destroy(xfs_trans_zone);
2092 out_destroy_ifork_zone:
2093 kmem_zone_destroy(xfs_ifork_zone);
2094 out_destroy_dabuf_zone:
2095 kmem_zone_destroy(xfs_dabuf_zone);
2096 out_destroy_da_state_zone:
2097 kmem_zone_destroy(xfs_da_state_zone);
2098 out_destroy_btree_cur_zone:
2099 kmem_zone_destroy(xfs_btree_cur_zone);
2100 out_destroy_bmap_free_item_zone:
2101 kmem_zone_destroy(xfs_bmap_free_item_zone);
2102 out_destroy_log_ticket_zone:
2103 kmem_zone_destroy(xfs_log_ticket_zone);
2104 out_destroy_ioend_pool:
2105 mempool_destroy(xfs_ioend_pool);
2106 out_destroy_ioend_zone:
2107 kmem_zone_destroy(xfs_ioend_zone);
2108 out_destroy_vnode_zone:
2109 kmem_zone_destroy(xfs_vnode_zone);
2110 out:
2111 return -ENOMEM;
2112}
2113
2114STATIC void
2115xfs_destroy_zones(void)
2116{
2117#ifdef CONFIG_XFS_POSIX_ACL
2118 kmem_zone_destroy(xfs_acl_zone);
2119#endif
2120 kmem_zone_destroy(xfs_ili_zone);
2121 kmem_zone_destroy(xfs_inode_zone);
2122 kmem_zone_destroy(xfs_efi_zone);
2123 kmem_zone_destroy(xfs_efd_zone);
2124 kmem_zone_destroy(xfs_buf_item_zone);
2125 kmem_zone_destroy(xfs_trans_zone);
2126 kmem_zone_destroy(xfs_ifork_zone);
2127 kmem_zone_destroy(xfs_dabuf_zone);
2128 kmem_zone_destroy(xfs_da_state_zone);
2129 kmem_zone_destroy(xfs_btree_cur_zone);
2130 kmem_zone_destroy(xfs_bmap_free_item_zone);
2131 kmem_zone_destroy(xfs_log_ticket_zone);
2132 mempool_destroy(xfs_ioend_pool);
2133 kmem_zone_destroy(xfs_ioend_zone);
2134 kmem_zone_destroy(xfs_vnode_zone);
2135
2136}
1942 2137
1943STATIC int __init 2138STATIC int __init
1944init_xfs_fs( void ) 2139init_xfs_fs(void)
1945{ 2140{
1946 int error; 2141 int error;
1947 static char message[] __initdata = KERN_INFO \ 2142 static char message[] __initdata = KERN_INFO \
@@ -1950,42 +2145,73 @@ init_xfs_fs( void )
1950 printk(message); 2145 printk(message);
1951 2146
1952 ktrace_init(64); 2147 ktrace_init(64);
2148 vn_init();
2149 xfs_dir_startup();
1953 2150
1954 error = xfs_init_zones(); 2151 error = xfs_init_zones();
1955 if (error < 0) 2152 if (error)
1956 goto undo_zones; 2153 goto out;
2154
2155 error = xfs_alloc_trace_bufs();
2156 if (error)
2157 goto out_destroy_zones;
2158
2159 error = xfs_mru_cache_init();
2160 if (error)
2161 goto out_free_trace_buffers;
2162
2163 error = xfs_filestream_init();
2164 if (error)
2165 goto out_mru_cache_uninit;
1957 2166
1958 error = xfs_buf_init(); 2167 error = xfs_buf_init();
1959 if (error < 0) 2168 if (error)
1960 goto undo_buffers; 2169 goto out_filestream_uninit;
2170
2171 error = xfs_init_procfs();
2172 if (error)
2173 goto out_buf_terminate;
2174
2175 error = xfs_sysctl_register();
2176 if (error)
2177 goto out_cleanup_procfs;
1961 2178
1962 vn_init();
1963 xfs_init();
1964 uuid_init();
1965 vfs_initquota(); 2179 vfs_initquota();
1966 2180
1967 error = register_filesystem(&xfs_fs_type); 2181 error = register_filesystem(&xfs_fs_type);
1968 if (error) 2182 if (error)
1969 goto undo_register; 2183 goto out_sysctl_unregister;
1970 return 0; 2184 return 0;
1971 2185
1972undo_register: 2186 out_sysctl_unregister:
2187 xfs_sysctl_unregister();
2188 out_cleanup_procfs:
2189 xfs_cleanup_procfs();
2190 out_buf_terminate:
1973 xfs_buf_terminate(); 2191 xfs_buf_terminate();
1974 2192 out_filestream_uninit:
1975undo_buffers: 2193 xfs_filestream_uninit();
2194 out_mru_cache_uninit:
2195 xfs_mru_cache_uninit();
2196 out_free_trace_buffers:
2197 xfs_free_trace_bufs();
2198 out_destroy_zones:
1976 xfs_destroy_zones(); 2199 xfs_destroy_zones();
1977 2200 out:
1978undo_zones:
1979 return error; 2201 return error;
1980} 2202}
1981 2203
1982STATIC void __exit 2204STATIC void __exit
1983exit_xfs_fs( void ) 2205exit_xfs_fs(void)
1984{ 2206{
1985 vfs_exitquota(); 2207 vfs_exitquota();
1986 unregister_filesystem(&xfs_fs_type); 2208 unregister_filesystem(&xfs_fs_type);
1987 xfs_cleanup(); 2209 xfs_sysctl_unregister();
2210 xfs_cleanup_procfs();
1988 xfs_buf_terminate(); 2211 xfs_buf_terminate();
2212 xfs_filestream_uninit();
2213 xfs_mru_cache_uninit();
2214 xfs_free_trace_bufs();
1989 xfs_destroy_zones(); 2215 xfs_destroy_zones();
1990 ktrace_uninit(); 2216 ktrace_uninit();
1991} 2217}
diff --git a/fs/xfs/linux-2.6/xfs_sysctl.c b/fs/xfs/linux-2.6/xfs_sysctl.c
index bb997d75c05c..7dacb5bbde3f 100644
--- a/fs/xfs/linux-2.6/xfs_sysctl.c
+++ b/fs/xfs/linux-2.6/xfs_sysctl.c
@@ -259,15 +259,17 @@ static ctl_table xfs_root_table[] = {
259 {} 259 {}
260}; 260};
261 261
262void 262int
263xfs_sysctl_register(void) 263xfs_sysctl_register(void)
264{ 264{
265 xfs_table_header = register_sysctl_table(xfs_root_table); 265 xfs_table_header = register_sysctl_table(xfs_root_table);
266 if (!xfs_table_header)
267 return -ENOMEM;
268 return 0;
266} 269}
267 270
268void 271void
269xfs_sysctl_unregister(void) 272xfs_sysctl_unregister(void)
270{ 273{
271 if (xfs_table_header) 274 unregister_sysctl_table(xfs_table_header);
272 unregister_sysctl_table(xfs_table_header);
273} 275}
diff --git a/fs/xfs/linux-2.6/xfs_sysctl.h b/fs/xfs/linux-2.6/xfs_sysctl.h
index 98b97e399d6f..4aadb8056c37 100644
--- a/fs/xfs/linux-2.6/xfs_sysctl.h
+++ b/fs/xfs/linux-2.6/xfs_sysctl.h
@@ -93,10 +93,10 @@ enum {
93extern xfs_param_t xfs_params; 93extern xfs_param_t xfs_params;
94 94
95#ifdef CONFIG_SYSCTL 95#ifdef CONFIG_SYSCTL
96extern void xfs_sysctl_register(void); 96extern int xfs_sysctl_register(void);
97extern void xfs_sysctl_unregister(void); 97extern void xfs_sysctl_unregister(void);
98#else 98#else
99# define xfs_sysctl_register() do { } while (0) 99# define xfs_sysctl_register() (0)
100# define xfs_sysctl_unregister() do { } while (0) 100# define xfs_sysctl_unregister() do { } while (0)
101#endif /* CONFIG_SYSCTL */ 101#endif /* CONFIG_SYSCTL */
102 102