From c962fb7902669a48a2c613649c1f03865c0ffd1e Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 20 May 2008 15:10:52 +1000 Subject: [PATCH] [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 Signed-off-by: David Chinner Signed-off-by: Lachlan McIlroy --- fs/xfs/linux-2.6/xfs_super.c | 37 ++++++++++++++++++++++-------------- fs/xfs/xfs_mount.c | 30 ++--------------------------- 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 d13d883d003..fe52e9276aa 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( } xfs_unmountfs(mp); + xfs_icsb_destroy_counters(mp); xfs_close_devices(mp); xfs_qmops_put(mp); xfs_dmops_put(mp); - kmem_free(mp); + kfree(mp); } STATIC void @@ -1733,14 +1734,20 @@ xfs_fs_fill_super( struct inode *root; struct xfs_mount *mp = NULL; struct xfs_mount_args *args; - int flags = 0, error; + int flags = 0, error = ENOMEM; args = xfs_args_allocate(sb, silent); if (!args) return -ENOMEM; - mp = xfs_mount_init(); + mp = kzalloc(sizeof(struct xfs_mount), GFP_KERNEL); + if (!mp) + goto out_free_args; + spin_lock_init(&mp->m_sb_lock); + mutex_init(&mp->m_ilock); + mutex_init(&mp->m_growlock); + atomic_set(&mp->m_active_trans, 0); INIT_LIST_HEAD(&mp->m_sync_list); spin_lock_init(&mp->m_sync_lock); init_waitqueue_head(&mp->m_wait_single_sync_task); @@ -1753,7 +1760,7 @@ xfs_fs_fill_super( error = xfs_parseargs(mp, (char *)data, args, 0); if (error) - goto fail_vfsop; + goto out_free_mp; sb_min_blocksize(sb, BBSIZE); sb->s_export_op = &xfs_export_operations; @@ -1762,7 +1769,7 @@ xfs_fs_fill_super( error = xfs_dmops_get(mp, args); if (error) - goto fail_vfsop; + goto out_free_mp; error = xfs_qmops_get(mp, args); if (error) goto out_put_dmops; @@ -1774,6 +1781,9 @@ xfs_fs_fill_super( if (error) goto out_put_qmops; + if (xfs_icsb_init_counters(mp)) + mp->m_flags |= XFS_MOUNT_NO_PERCPU_SB; + /* * Setup flags based on mount(2) options and then the superblock */ @@ -1849,12 +1859,18 @@ xfs_fs_fill_super( xfs_binval(mp->m_logdev_targp); if (mp->m_rtdev_targp) xfs_binval(mp->m_rtdev_targp); + out_destroy_counters: + xfs_icsb_destroy_counters(mp); xfs_close_devices(mp); out_put_qmops: xfs_qmops_put(mp); out_put_dmops: xfs_dmops_put(mp); - goto fail_vfsop; + out_free_mp: + kfree(mp); + out_free_args: + kfree(args); + return -error; fail_vnrele: if (sb->s_root) { @@ -1879,14 +1895,7 @@ xfs_fs_fill_super( IRELE(mp->m_rootip); xfs_unmountfs(mp); - xfs_close_devices(mp); - xfs_qmops_put(mp); - xfs_dmops_put(mp); - kmem_free(mp); - - fail_vfsop: - kfree(args); - return -error; + goto out_destroy_counters; } STATIC int diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index c67f8a9ae41..1bfaa204f68 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 *); #ifdef HAVE_PERCPU_SB -STATIC void xfs_icsb_destroy_counters(xfs_mount_t *); STATIC void xfs_icsb_balance_counter(xfs_mount_t *, xfs_sb_field_t, int); 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); #else -#define xfs_icsb_destroy_counters(mp) do { } while (0) #define xfs_icsb_balance_counter(mp, a, b) do { } while (0) #define xfs_icsb_balance_counter_locked(mp, a, b) do { } while (0) #define xfs_icsb_modify_counters(mp, a, b, c) do { } while (0) @@ -124,34 +122,12 @@ static const struct { { sizeof(xfs_sb_t), 0 } }; -/* - * Return a pointer to an initialized xfs_mount structure. - */ -xfs_mount_t * -xfs_mount_init(void) -{ - xfs_mount_t *mp; - - mp = kmem_zalloc(sizeof(xfs_mount_t), KM_SLEEP); - - if (xfs_icsb_init_counters(mp)) { - mp->m_flags |= XFS_MOUNT_NO_PERCPU_SB; - } - - spin_lock_init(&mp->m_sb_lock); - mutex_init(&mp->m_ilock); - mutex_init(&mp->m_growlock); - atomic_set(&mp->m_active_trans, 0); - - return mp; -} - /* * Free up the resources associated with a mount structure. Assume that * the structure was initially zeroed, so we can tell which fields got * initialized. */ -void +STATIC void xfs_mount_free( xfs_mount_t *mp) { @@ -177,8 +153,6 @@ xfs_mount_free( kmem_free(mp->m_rtname); if (mp->m_logname != NULL) kmem_free(mp->m_logname); - - xfs_icsb_destroy_counters(mp); } /* @@ -2093,7 +2067,7 @@ xfs_icsb_reinit_counters( xfs_icsb_unlock(mp); } -STATIC void +void xfs_icsb_destroy_counters( xfs_mount_t *mp) { diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 5acde7fd9c0..96d8791e9e5 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -210,12 +210,14 @@ typedef struct xfs_icsb_cnts { extern int xfs_icsb_init_counters(struct xfs_mount *); extern void xfs_icsb_reinit_counters(struct xfs_mount *); +extern void xfs_icsb_destroy_counters(struct xfs_mount *); extern void xfs_icsb_sync_counters(struct xfs_mount *, int); extern void xfs_icsb_sync_counters_locked(struct xfs_mount *, int); #else -#define xfs_icsb_init_counters(mp) (0) -#define xfs_icsb_reinit_counters(mp) do { } while (0) +#define xfs_icsb_init_counters(mp) (0) +#define xfs_icsb_destroy_counters(mp) do { } while (0) +#define xfs_icsb_reinit_counters(mp) do { } while (0) #define xfs_icsb_sync_counters(mp, flags) do { } while (0) #define xfs_icsb_sync_counters_locked(mp, flags) do { } while (0) #endif @@ -511,10 +513,8 @@ typedef struct xfs_mod_sb { #define XFS_MOUNT_ILOCK(mp) mutex_lock(&((mp)->m_ilock)) #define XFS_MOUNT_IUNLOCK(mp) mutex_unlock(&((mp)->m_ilock)) -extern xfs_mount_t *xfs_mount_init(void); extern void xfs_mod_sb(xfs_trans_t *, __int64_t); extern int xfs_log_sbcount(xfs_mount_t *, uint); -extern void xfs_mount_free(xfs_mount_t *mp); extern int xfs_mountfs(xfs_mount_t *mp, int); extern void xfs_mountfs_check_barriers(xfs_mount_t *mp); -- 2.41.0