xfs: clean up xfs_mount allocation and dynamic initializers
authorBrian Foster <bfoster@redhat.com>
Sat, 24 Mar 2018 00:54:32 +0000 (17:54 -0700)
committerDarrick J. Wong <darrick.wong@oracle.com>
Mon, 26 Mar 2018 15:54:15 +0000 (08:54 -0700)
Most of the generic data structures embedded in xfs_mount are
dynamically initialized immediately after mp is allocated. A few
fields are left out and initialized during the xfs_mountfs()
sequence, after mp has been attached to the superblock.

To clean this up and help prevent premature access of associated
fields, refactor xfs_mount allocation and all dependent init calls
into a new helper. This self-documents that all low level data
structures (i.e., locks, trees, etc.) should be initialized before
xfs_mount is attached to the superblock.

Signed-off-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
fs/xfs/libxfs/xfs_sb.c
fs/xfs/xfs_mount.c
fs/xfs/xfs_super.c

index a55f7a4..53433cc 100644 (file)
@@ -731,7 +731,6 @@ xfs_sb_mount_common(
        struct xfs_sb   *sbp)
 {
        mp->m_agfrotor = mp->m_agirotor = 0;
-       spin_lock_init(&mp->m_agirotor_lock);
        mp->m_maxagi = mp->m_sb.sb_agcount;
        mp->m_blkbit_log = sbp->sb_blocklog + XFS_NBBYLOG;
        mp->m_blkbb_log = sbp->sb_blocklog - BBSHIFT;
index 6f5a5e6..a901b86 100644 (file)
@@ -817,8 +817,6 @@ xfs_mountfs(
        /*
         * Allocate and initialize the per-ag data.
         */
-       spin_lock_init(&mp->m_perag_lock);
-       INIT_RADIX_TREE(&mp->m_perag_tree, GFP_ATOMIC);
        error = xfs_initialize_perag(mp, sbp->sb_agcount, &mp->m_maxagi);
        if (error) {
                xfs_warn(mp, "Failed per-ag init: %d", error);
index 951271f..612c1d5 100644 (file)
@@ -1579,29 +1579,48 @@ xfs_destroy_percpu_counters(
        percpu_counter_destroy(&mp->m_fdblocks);
 }
 
-STATIC int
-xfs_fs_fill_super(
-       struct super_block      *sb,
-       void                    *data,
-       int                     silent)
+static struct xfs_mount *
+xfs_mount_alloc(
+       struct super_block      *sb)
 {
-       struct inode            *root;
-       struct xfs_mount        *mp = NULL;
-       int                     flags = 0, error = -ENOMEM;
+       struct xfs_mount        *mp;
 
        mp = kzalloc(sizeof(struct xfs_mount), GFP_KERNEL);
        if (!mp)
-               goto out;
+               return NULL;
 
+       mp->m_super = sb;
        spin_lock_init(&mp->m_sb_lock);
+       spin_lock_init(&mp->m_agirotor_lock);
+       INIT_RADIX_TREE(&mp->m_perag_tree, GFP_ATOMIC);
+       spin_lock_init(&mp->m_perag_lock);
        mutex_init(&mp->m_growlock);
        atomic_set(&mp->m_active_trans, 0);
        INIT_DELAYED_WORK(&mp->m_reclaim_work, xfs_reclaim_worker);
        INIT_DELAYED_WORK(&mp->m_eofblocks_work, xfs_eofblocks_worker);
        INIT_DELAYED_WORK(&mp->m_cowblocks_work, xfs_cowblocks_worker);
        mp->m_kobj.kobject.kset = xfs_kset;
+       return mp;
+}
 
-       mp->m_super = sb;
+
+STATIC int
+xfs_fs_fill_super(
+       struct super_block      *sb,
+       void                    *data,
+       int                     silent)
+{
+       struct inode            *root;
+       struct xfs_mount        *mp = NULL;
+       int                     flags = 0, error = -ENOMEM;
+
+       /*
+        * allocate mp and do all low-level struct initializations before we
+        * attach it to the super
+        */
+       mp = xfs_mount_alloc(sb);
+       if (!mp)
+               goto out;
        sb->s_fs_info = mp;
 
        error = xfs_parseargs(mp, (char *)data);