Commit c962fb79 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Niv Sardi

[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: default avatarChristoph Hellwig <hch@infradead.org>
Signed-off-by: default avatarDavid Chinner <dgc@sgi.com>
Signed-off-by: default avatarLachlan McIlroy <lachlan@sgi.com>
parent bdd907ba
...@@ -1273,10 +1273,11 @@ xfs_fs_put_super( ...@@ -1273,10 +1273,11 @@ xfs_fs_put_super(
} }
xfs_unmountfs(mp); xfs_unmountfs(mp);
xfs_icsb_destroy_counters(mp);
xfs_close_devices(mp); xfs_close_devices(mp);
xfs_qmops_put(mp); xfs_qmops_put(mp);
xfs_dmops_put(mp); xfs_dmops_put(mp);
kmem_free(mp); kfree(mp);
} }
STATIC void STATIC void
...@@ -1733,14 +1734,20 @@ xfs_fs_fill_super( ...@@ -1733,14 +1734,20 @@ xfs_fs_fill_super(
struct inode *root; struct inode *root;
struct xfs_mount *mp = NULL; struct xfs_mount *mp = NULL;
struct xfs_mount_args *args; struct xfs_mount_args *args;
int flags = 0, error; int flags = 0, error = ENOMEM;
args = xfs_args_allocate(sb, silent); args = xfs_args_allocate(sb, silent);
if (!args) if (!args)
return -ENOMEM; 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); INIT_LIST_HEAD(&mp->m_sync_list);
spin_lock_init(&mp->m_sync_lock); spin_lock_init(&mp->m_sync_lock);
init_waitqueue_head(&mp->m_wait_single_sync_task); init_waitqueue_head(&mp->m_wait_single_sync_task);
...@@ -1753,7 +1760,7 @@ xfs_fs_fill_super( ...@@ -1753,7 +1760,7 @@ xfs_fs_fill_super(
error = xfs_parseargs(mp, (char *)data, args, 0); error = xfs_parseargs(mp, (char *)data, args, 0);
if (error) if (error)
goto fail_vfsop; goto out_free_mp;
sb_min_blocksize(sb, BBSIZE); sb_min_blocksize(sb, BBSIZE);
sb->s_export_op = &xfs_export_operations; sb->s_export_op = &xfs_export_operations;
...@@ -1762,7 +1769,7 @@ xfs_fs_fill_super( ...@@ -1762,7 +1769,7 @@ xfs_fs_fill_super(
error = xfs_dmops_get(mp, args); error = xfs_dmops_get(mp, args);
if (error) if (error)
goto fail_vfsop; goto out_free_mp;
error = xfs_qmops_get(mp, args); error = xfs_qmops_get(mp, args);
if (error) if (error)
goto out_put_dmops; goto out_put_dmops;
...@@ -1774,6 +1781,9 @@ xfs_fs_fill_super( ...@@ -1774,6 +1781,9 @@ xfs_fs_fill_super(
if (error) if (error)
goto out_put_qmops; 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 * Setup flags based on mount(2) options and then the superblock
*/ */
...@@ -1849,12 +1859,18 @@ xfs_fs_fill_super( ...@@ -1849,12 +1859,18 @@ xfs_fs_fill_super(
xfs_binval(mp->m_logdev_targp); xfs_binval(mp->m_logdev_targp);
if (mp->m_rtdev_targp) if (mp->m_rtdev_targp)
xfs_binval(mp->m_rtdev_targp); xfs_binval(mp->m_rtdev_targp);
out_destroy_counters:
xfs_icsb_destroy_counters(mp);
xfs_close_devices(mp); xfs_close_devices(mp);
out_put_qmops: out_put_qmops:
xfs_qmops_put(mp); xfs_qmops_put(mp);
out_put_dmops: out_put_dmops:
xfs_dmops_put(mp); xfs_dmops_put(mp);
goto fail_vfsop; out_free_mp:
kfree(mp);
out_free_args:
kfree(args);
return -error;
fail_vnrele: fail_vnrele:
if (sb->s_root) { if (sb->s_root) {
...@@ -1879,14 +1895,7 @@ xfs_fs_fill_super( ...@@ -1879,14 +1895,7 @@ xfs_fs_fill_super(
IRELE(mp->m_rootip); IRELE(mp->m_rootip);
xfs_unmountfs(mp); xfs_unmountfs(mp);
xfs_close_devices(mp); goto out_destroy_counters;
xfs_qmops_put(mp);
xfs_dmops_put(mp);
kmem_free(mp);
fail_vfsop:
kfree(args);
return -error;
} }
STATIC int STATIC int
......
...@@ -51,7 +51,6 @@ STATIC void xfs_unmountfs_wait(xfs_mount_t *); ...@@ -51,7 +51,6 @@ STATIC void xfs_unmountfs_wait(xfs_mount_t *);
#ifdef HAVE_PERCPU_SB #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, STATIC void xfs_icsb_balance_counter(xfs_mount_t *, xfs_sb_field_t,
int); int);
STATIC void xfs_icsb_balance_counter_locked(xfs_mount_t *, xfs_sb_field_t, 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,7 +61,6 @@ STATIC void xfs_icsb_disable_counter(xfs_mount_t *, xfs_sb_field_t);
#else #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(mp, a, b) do { } while (0)
#define xfs_icsb_balance_counter_locked(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) #define xfs_icsb_modify_counters(mp, a, b, c) do { } while (0)
...@@ -124,34 +122,12 @@ static const struct { ...@@ -124,34 +122,12 @@ static const struct {
{ sizeof(xfs_sb_t), 0 } { 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 * Free up the resources associated with a mount structure. Assume that
* the structure was initially zeroed, so we can tell which fields got * the structure was initially zeroed, so we can tell which fields got
* initialized. * initialized.
*/ */
void STATIC void
xfs_mount_free( xfs_mount_free(
xfs_mount_t *mp) xfs_mount_t *mp)
{ {
...@@ -177,8 +153,6 @@ xfs_mount_free( ...@@ -177,8 +153,6 @@ xfs_mount_free(
kmem_free(mp->m_rtname); kmem_free(mp->m_rtname);
if (mp->m_logname != NULL) if (mp->m_logname != NULL)
kmem_free(mp->m_logname); kmem_free(mp->m_logname);
xfs_icsb_destroy_counters(mp);
} }
/* /*
...@@ -2093,7 +2067,7 @@ xfs_icsb_reinit_counters( ...@@ -2093,7 +2067,7 @@ xfs_icsb_reinit_counters(
xfs_icsb_unlock(mp); xfs_icsb_unlock(mp);
} }
STATIC void void
xfs_icsb_destroy_counters( xfs_icsb_destroy_counters(
xfs_mount_t *mp) xfs_mount_t *mp)
{ {
......
...@@ -210,11 +210,13 @@ typedef struct xfs_icsb_cnts { ...@@ -210,11 +210,13 @@ typedef struct xfs_icsb_cnts {
extern int xfs_icsb_init_counters(struct xfs_mount *); extern int xfs_icsb_init_counters(struct xfs_mount *);
extern void xfs_icsb_reinit_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(struct xfs_mount *, int);
extern void xfs_icsb_sync_counters_locked(struct xfs_mount *, int); extern void xfs_icsb_sync_counters_locked(struct xfs_mount *, int);
#else #else
#define xfs_icsb_init_counters(mp) (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_reinit_counters(mp) do { } while (0)
#define xfs_icsb_sync_counters(mp, flags) do { } while (0) #define xfs_icsb_sync_counters(mp, flags) do { } while (0)
#define xfs_icsb_sync_counters_locked(mp, flags) do { } while (0) #define xfs_icsb_sync_counters_locked(mp, flags) do { } while (0)
...@@ -511,10 +513,8 @@ typedef struct xfs_mod_sb { ...@@ -511,10 +513,8 @@ typedef struct xfs_mod_sb {
#define XFS_MOUNT_ILOCK(mp) mutex_lock(&((mp)->m_ilock)) #define XFS_MOUNT_ILOCK(mp) mutex_lock(&((mp)->m_ilock))
#define XFS_MOUNT_IUNLOCK(mp) mutex_unlock(&((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 void xfs_mod_sb(xfs_trans_t *, __int64_t);
extern int xfs_log_sbcount(xfs_mount_t *, uint); 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 int xfs_mountfs(xfs_mount_t *mp, int);
extern void xfs_mountfs_check_barriers(xfs_mount_t *mp); extern void xfs_mountfs_check_barriers(xfs_mount_t *mp);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment