diff options
author | Christoph Hellwig <hch@infradead.org> | 2008-05-20 01:10:52 -0400 |
---|---|---|
committer | Niv Sardi <xaiki@debian.org> | 2008-07-28 02:58:29 -0400 |
commit | c962fb7902669a48a2c613649c1f03865c0ffd1e (patch) | |
tree | 370bdf7273c92a2bcb230680c6b0bfa4928b11e8 /fs | |
parent | bdd907bab78419f34113c51470192945741b839e (diff) |
[XFS] kill xfs_mount_init
xfs_mount_init is inlined into xfs_fs_fill_super and allocation switched
to kzalloc. Plug a leak of the mount structure for most early mount
failures. Move xfs_icsb_init_counters to as late as possible in the mount
path and make sure to undo it so that no stale hotplug cpu notifiers are
left around on mount failures.
SGI-PV: 981951
SGI-Modid: xfs-linux-melb:xfs-kern:31196a
Signed-off-by: Christoph Hellwig <hch@infradead.org>
Signed-off-by: David Chinner <dgc@sgi.com>
Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/xfs/linux-2.6/xfs_super.c | 37 | ||||
-rw-r--r-- | fs/xfs/xfs_mount.c | 30 | ||||
-rw-r--r-- | fs/xfs/xfs_mount.h | 8 |
3 files changed, 29 insertions, 46 deletions
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index d13d883d0039..fe52e9276aad 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c | |||
@@ -1273,10 +1273,11 @@ xfs_fs_put_super( | |||
1273 | } | 1273 | } |
1274 | 1274 | ||
1275 | xfs_unmountfs(mp); | 1275 | xfs_unmountfs(mp); |
1276 | xfs_icsb_destroy_counters(mp); | ||
1276 | xfs_close_devices(mp); | 1277 | xfs_close_devices(mp); |
1277 | xfs_qmops_put(mp); | 1278 | xfs_qmops_put(mp); |
1278 | xfs_dmops_put(mp); | 1279 | xfs_dmops_put(mp); |
1279 | kmem_free(mp); | 1280 | kfree(mp); |
1280 | } | 1281 | } |
1281 | 1282 | ||
1282 | STATIC void | 1283 | STATIC void |
@@ -1733,14 +1734,20 @@ xfs_fs_fill_super( | |||
1733 | struct inode *root; | 1734 | struct inode *root; |
1734 | struct xfs_mount *mp = NULL; | 1735 | struct xfs_mount *mp = NULL; |
1735 | struct xfs_mount_args *args; | 1736 | struct xfs_mount_args *args; |
1736 | int flags = 0, error; | 1737 | int flags = 0, error = ENOMEM; |
1737 | 1738 | ||
1738 | args = xfs_args_allocate(sb, silent); | 1739 | args = xfs_args_allocate(sb, silent); |
1739 | if (!args) | 1740 | if (!args) |
1740 | return -ENOMEM; | 1741 | return -ENOMEM; |
1741 | 1742 | ||
1742 | mp = xfs_mount_init(); | 1743 | mp = kzalloc(sizeof(struct xfs_mount), GFP_KERNEL); |
1744 | if (!mp) | ||
1745 | goto out_free_args; | ||
1743 | 1746 | ||
1747 | spin_lock_init(&mp->m_sb_lock); | ||
1748 | mutex_init(&mp->m_ilock); | ||
1749 | mutex_init(&mp->m_growlock); | ||
1750 | atomic_set(&mp->m_active_trans, 0); | ||
1744 | INIT_LIST_HEAD(&mp->m_sync_list); | 1751 | INIT_LIST_HEAD(&mp->m_sync_list); |
1745 | spin_lock_init(&mp->m_sync_lock); | 1752 | spin_lock_init(&mp->m_sync_lock); |
1746 | init_waitqueue_head(&mp->m_wait_single_sync_task); | 1753 | init_waitqueue_head(&mp->m_wait_single_sync_task); |
@@ -1753,7 +1760,7 @@ xfs_fs_fill_super( | |||
1753 | 1760 | ||
1754 | error = xfs_parseargs(mp, (char *)data, args, 0); | 1761 | error = xfs_parseargs(mp, (char *)data, args, 0); |
1755 | if (error) | 1762 | if (error) |
1756 | goto fail_vfsop; | 1763 | goto out_free_mp; |
1757 | 1764 | ||
1758 | sb_min_blocksize(sb, BBSIZE); | 1765 | sb_min_blocksize(sb, BBSIZE); |
1759 | sb->s_export_op = &xfs_export_operations; | 1766 | sb->s_export_op = &xfs_export_operations; |
@@ -1762,7 +1769,7 @@ xfs_fs_fill_super( | |||
1762 | 1769 | ||
1763 | error = xfs_dmops_get(mp, args); | 1770 | error = xfs_dmops_get(mp, args); |
1764 | if (error) | 1771 | if (error) |
1765 | goto fail_vfsop; | 1772 | goto out_free_mp; |
1766 | error = xfs_qmops_get(mp, args); | 1773 | error = xfs_qmops_get(mp, args); |
1767 | if (error) | 1774 | if (error) |
1768 | goto out_put_dmops; | 1775 | goto out_put_dmops; |
@@ -1774,6 +1781,9 @@ xfs_fs_fill_super( | |||
1774 | if (error) | 1781 | if (error) |
1775 | goto out_put_qmops; | 1782 | goto out_put_qmops; |
1776 | 1783 | ||
1784 | if (xfs_icsb_init_counters(mp)) | ||
1785 | mp->m_flags |= XFS_MOUNT_NO_PERCPU_SB; | ||
1786 | |||
1777 | /* | 1787 | /* |
1778 | * Setup flags based on mount(2) options and then the superblock | 1788 | * Setup flags based on mount(2) options and then the superblock |
1779 | */ | 1789 | */ |
@@ -1849,12 +1859,18 @@ xfs_fs_fill_super( | |||
1849 | xfs_binval(mp->m_logdev_targp); | 1859 | xfs_binval(mp->m_logdev_targp); |
1850 | if (mp->m_rtdev_targp) | 1860 | if (mp->m_rtdev_targp) |
1851 | xfs_binval(mp->m_rtdev_targp); | 1861 | xfs_binval(mp->m_rtdev_targp); |
1862 | out_destroy_counters: | ||
1863 | xfs_icsb_destroy_counters(mp); | ||
1852 | xfs_close_devices(mp); | 1864 | xfs_close_devices(mp); |
1853 | out_put_qmops: | 1865 | out_put_qmops: |
1854 | xfs_qmops_put(mp); | 1866 | xfs_qmops_put(mp); |
1855 | out_put_dmops: | 1867 | out_put_dmops: |
1856 | xfs_dmops_put(mp); | 1868 | xfs_dmops_put(mp); |
1857 | goto fail_vfsop; | 1869 | out_free_mp: |
1870 | kfree(mp); | ||
1871 | out_free_args: | ||
1872 | kfree(args); | ||
1873 | return -error; | ||
1858 | 1874 | ||
1859 | fail_vnrele: | 1875 | fail_vnrele: |
1860 | if (sb->s_root) { | 1876 | if (sb->s_root) { |
@@ -1879,14 +1895,7 @@ xfs_fs_fill_super( | |||
1879 | IRELE(mp->m_rootip); | 1895 | IRELE(mp->m_rootip); |
1880 | 1896 | ||
1881 | xfs_unmountfs(mp); | 1897 | xfs_unmountfs(mp); |
1882 | xfs_close_devices(mp); | 1898 | goto out_destroy_counters; |
1883 | xfs_qmops_put(mp); | ||
1884 | xfs_dmops_put(mp); | ||
1885 | kmem_free(mp); | ||
1886 | |||
1887 | fail_vfsop: | ||
1888 | kfree(args); | ||
1889 | return -error; | ||
1890 | } | 1899 | } |
1891 | 1900 | ||
1892 | STATIC int | 1901 | STATIC int |
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index c67f8a9ae418..1bfaa204f689 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c | |||
@@ -51,7 +51,6 @@ STATIC void xfs_unmountfs_wait(xfs_mount_t *); | |||
51 | 51 | ||
52 | 52 | ||
53 | #ifdef HAVE_PERCPU_SB | 53 | #ifdef HAVE_PERCPU_SB |
54 | STATIC void xfs_icsb_destroy_counters(xfs_mount_t *); | ||
55 | STATIC void xfs_icsb_balance_counter(xfs_mount_t *, xfs_sb_field_t, | 54 | STATIC void xfs_icsb_balance_counter(xfs_mount_t *, xfs_sb_field_t, |
56 | int); | 55 | int); |
57 | STATIC void xfs_icsb_balance_counter_locked(xfs_mount_t *, xfs_sb_field_t, | 56 | STATIC void xfs_icsb_balance_counter_locked(xfs_mount_t *, xfs_sb_field_t, |
@@ -62,7 +61,6 @@ STATIC void xfs_icsb_disable_counter(xfs_mount_t *, xfs_sb_field_t); | |||
62 | 61 | ||
63 | #else | 62 | #else |
64 | 63 | ||
65 | #define xfs_icsb_destroy_counters(mp) do { } while (0) | ||
66 | #define xfs_icsb_balance_counter(mp, a, b) do { } while (0) | 64 | #define xfs_icsb_balance_counter(mp, a, b) do { } while (0) |
67 | #define xfs_icsb_balance_counter_locked(mp, a, b) do { } while (0) | 65 | #define xfs_icsb_balance_counter_locked(mp, a, b) do { } while (0) |
68 | #define xfs_icsb_modify_counters(mp, a, b, c) do { } while (0) | 66 | #define xfs_icsb_modify_counters(mp, a, b, c) do { } while (0) |
@@ -125,33 +123,11 @@ static const struct { | |||
125 | }; | 123 | }; |
126 | 124 | ||
127 | /* | 125 | /* |
128 | * Return a pointer to an initialized xfs_mount structure. | ||
129 | */ | ||
130 | xfs_mount_t * | ||
131 | xfs_mount_init(void) | ||
132 | { | ||
133 | xfs_mount_t *mp; | ||
134 | |||
135 | mp = kmem_zalloc(sizeof(xfs_mount_t), KM_SLEEP); | ||
136 | |||
137 | if (xfs_icsb_init_counters(mp)) { | ||
138 | mp->m_flags |= XFS_MOUNT_NO_PERCPU_SB; | ||
139 | } | ||
140 | |||
141 | spin_lock_init(&mp->m_sb_lock); | ||
142 | mutex_init(&mp->m_ilock); | ||
143 | mutex_init(&mp->m_growlock); | ||
144 | atomic_set(&mp->m_active_trans, 0); | ||
145 | |||
146 | return mp; | ||
147 | } | ||
148 | |||
149 | /* | ||
150 | * Free up the resources associated with a mount structure. Assume that | 126 | * Free up the resources associated with a mount structure. Assume that |
151 | * the structure was initially zeroed, so we can tell which fields got | 127 | * the structure was initially zeroed, so we can tell which fields got |
152 | * initialized. | 128 | * initialized. |
153 | */ | 129 | */ |
154 | void | 130 | STATIC void |
155 | xfs_mount_free( | 131 | xfs_mount_free( |
156 | xfs_mount_t *mp) | 132 | xfs_mount_t *mp) |
157 | { | 133 | { |
@@ -177,8 +153,6 @@ xfs_mount_free( | |||
177 | kmem_free(mp->m_rtname); | 153 | kmem_free(mp->m_rtname); |
178 | if (mp->m_logname != NULL) | 154 | if (mp->m_logname != NULL) |
179 | kmem_free(mp->m_logname); | 155 | kmem_free(mp->m_logname); |
180 | |||
181 | xfs_icsb_destroy_counters(mp); | ||
182 | } | 156 | } |
183 | 157 | ||
184 | /* | 158 | /* |
@@ -2093,7 +2067,7 @@ xfs_icsb_reinit_counters( | |||
2093 | xfs_icsb_unlock(mp); | 2067 | xfs_icsb_unlock(mp); |
2094 | } | 2068 | } |
2095 | 2069 | ||
2096 | STATIC void | 2070 | void |
2097 | xfs_icsb_destroy_counters( | 2071 | xfs_icsb_destroy_counters( |
2098 | xfs_mount_t *mp) | 2072 | xfs_mount_t *mp) |
2099 | { | 2073 | { |
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 5acde7fd9c0a..96d8791e9e5a 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h | |||
@@ -210,12 +210,14 @@ typedef struct xfs_icsb_cnts { | |||
210 | 210 | ||
211 | extern int xfs_icsb_init_counters(struct xfs_mount *); | 211 | extern int xfs_icsb_init_counters(struct xfs_mount *); |
212 | extern void xfs_icsb_reinit_counters(struct xfs_mount *); | 212 | extern void xfs_icsb_reinit_counters(struct xfs_mount *); |
213 | extern void xfs_icsb_destroy_counters(struct xfs_mount *); | ||
213 | extern void xfs_icsb_sync_counters(struct xfs_mount *, int); | 214 | extern void xfs_icsb_sync_counters(struct xfs_mount *, int); |
214 | extern void xfs_icsb_sync_counters_locked(struct xfs_mount *, int); | 215 | extern void xfs_icsb_sync_counters_locked(struct xfs_mount *, int); |
215 | 216 | ||
216 | #else | 217 | #else |
217 | #define xfs_icsb_init_counters(mp) (0) | 218 | #define xfs_icsb_init_counters(mp) (0) |
218 | #define xfs_icsb_reinit_counters(mp) do { } while (0) | 219 | #define xfs_icsb_destroy_counters(mp) do { } while (0) |
220 | #define xfs_icsb_reinit_counters(mp) do { } while (0) | ||
219 | #define xfs_icsb_sync_counters(mp, flags) do { } while (0) | 221 | #define xfs_icsb_sync_counters(mp, flags) do { } while (0) |
220 | #define xfs_icsb_sync_counters_locked(mp, flags) do { } while (0) | 222 | #define xfs_icsb_sync_counters_locked(mp, flags) do { } while (0) |
221 | #endif | 223 | #endif |
@@ -511,10 +513,8 @@ typedef struct xfs_mod_sb { | |||
511 | #define XFS_MOUNT_ILOCK(mp) mutex_lock(&((mp)->m_ilock)) | 513 | #define XFS_MOUNT_ILOCK(mp) mutex_lock(&((mp)->m_ilock)) |
512 | #define XFS_MOUNT_IUNLOCK(mp) mutex_unlock(&((mp)->m_ilock)) | 514 | #define XFS_MOUNT_IUNLOCK(mp) mutex_unlock(&((mp)->m_ilock)) |
513 | 515 | ||
514 | extern xfs_mount_t *xfs_mount_init(void); | ||
515 | extern void xfs_mod_sb(xfs_trans_t *, __int64_t); | 516 | extern void xfs_mod_sb(xfs_trans_t *, __int64_t); |
516 | extern int xfs_log_sbcount(xfs_mount_t *, uint); | 517 | extern int xfs_log_sbcount(xfs_mount_t *, uint); |
517 | extern void xfs_mount_free(xfs_mount_t *mp); | ||
518 | extern int xfs_mountfs(xfs_mount_t *mp, int); | 518 | extern int xfs_mountfs(xfs_mount_t *mp, int); |
519 | extern void xfs_mountfs_check_barriers(xfs_mount_t *mp); | 519 | extern void xfs_mountfs_check_barriers(xfs_mount_t *mp); |
520 | 520 | ||