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

[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
Loading
Loading
Loading
Loading
+23 −14
Original line number Diff line number Diff line
@@ -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
+2 −28
Original line number Diff line number Diff line
@@ -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)
{
+4 −4
Original line number Diff line number Diff line
@@ -210,11 +210,13 @@ 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_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)
@@ -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);