[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>
This commit is contained in:
parent
bdd907bab7
commit
c962fb7902
@ -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(
|
|||||||
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(
|
|||||||
|
|
||||||
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(
|
|||||||
|
|
||||||
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(
|
|||||||
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(
|
|||||||
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(
|
|||||||
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 *);
|
|||||||
|
|
||||||
|
|
||||||
#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);
|
|||||||
|
|
||||||
#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 {
|
|||||||
{ 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(
|
|||||||
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(
|
|||||||
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,12 +210,14 @@ 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_reinit_counters(mp) do { } while (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(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)
|
||||||
#endif
|
#endif
|
||||||
@ -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);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user