From 5ee6a39ea14e77096ca31b051ab45f6e475edd02 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Wed, 14 Aug 2019 18:03:55 -0400 Subject: [PATCH] xfs: refactor inode geometry setup routines Source kernel commit: 494dba7b276e12bc3f6ff2b9b584b6e9f693af45 Migrate all of the inode geometry setup code from xfs_mount.c into a single libxfs function that we can share with xfsprogs. Signed-off-by: Darrick J. Wong Reviewed-by: Dave Chinner Signed-off-by: Eric Sandeen --- libxfs/init.c | 57 +++----------------- libxfs/xfs_ialloc.c | 124 ++++++++++++++++++++++++++++++++++---------- libxfs/xfs_ialloc.h | 18 +------ libxfs/xfs_sb.c | 20 ++----- 4 files changed, 106 insertions(+), 113 deletions(-) diff --git a/libxfs/init.c b/libxfs/init.c index e8b4453d5..4446a62a1 100644 --- a/libxfs/init.c +++ b/libxfs/init.c @@ -637,8 +637,6 @@ libxfs_mount( xfs_buf_t *bp; xfs_sb_t *sbp; int error; - struct xfs_ino_geometry *igeo = M_IGEO(mp); - libxfs_buftarg_init(mp, dev, logdev, rtdev); @@ -650,37 +648,6 @@ libxfs_mount( xfs_sb_mount_common(mp, sb); - xfs_alloc_compute_maxlevels(mp); - xfs_bmap_compute_maxlevels(mp, XFS_DATA_FORK); - xfs_bmap_compute_maxlevels(mp, XFS_ATTR_FORK); - xfs_ialloc_compute_maxlevels(mp); - xfs_rmapbt_compute_maxlevels(mp); - xfs_refcountbt_compute_maxlevels(mp); - - if (sbp->sb_imax_pct) { - /* Make sure the maximum inode count is a multiple of the - * units we allocate inodes in. - */ - igeo->maxicount = (sbp->sb_dblocks * sbp->sb_imax_pct) / 100; - igeo->maxicount = XFS_FSB_TO_INO(mp, - (igeo->maxicount / igeo->ialloc_blks) * - igeo->ialloc_blks); - } else - igeo->maxicount = 0; - - igeo->inode_cluster_size = XFS_INODE_BIG_CLUSTER_SIZE; - if (xfs_sb_version_hascrc(&mp->m_sb)) { - int new_size = igeo->inode_cluster_size; - - new_size *= mp->m_sb.sb_inodesize / XFS_DINODE_MIN_SIZE; - if (mp->m_sb.sb_inoalignmt >= XFS_B_TO_FSBT(mp, new_size)) - igeo->inode_cluster_size = new_size; - } - igeo->blocks_per_cluster = xfs_icluster_size_fsb(mp); - igeo->inodes_per_cluster = XFS_FSB_TO_INO(mp, igeo->blocks_per_cluster); - igeo->cluster_align = xfs_ialloc_cluster_alignment(mp); - igeo->cluster_align_inodes = XFS_FSB_TO_INO(mp, igeo->cluster_align); - /* * Set whether we're using stripe alignment. */ @@ -689,24 +656,12 @@ libxfs_mount( mp->m_swidth = sbp->sb_width; } - /* - * Set whether we're using inode alignment. - */ - if (xfs_sb_version_hasalign(&mp->m_sb) && - mp->m_sb.sb_inoalignmt >= - XFS_B_TO_FSBT(mp, igeo->inode_cluster_size)) - igeo->inoalign_mask = mp->m_sb.sb_inoalignmt - 1; - else - igeo->inoalign_mask = 0; - /* - * If we are using stripe alignment, check whether - * the stripe unit is a multiple of the inode alignment - */ - if (mp->m_dalign && igeo->inoalign_mask && - !(mp->m_dalign & igeo->inoalign_mask)) - igeo->ialloc_align = mp->m_dalign; - else - igeo->ialloc_align = 0; + xfs_alloc_compute_maxlevels(mp); + xfs_bmap_compute_maxlevels(mp, XFS_DATA_FORK); + xfs_bmap_compute_maxlevels(mp, XFS_ATTR_FORK); + xfs_ialloc_setup_geometry(mp); + xfs_rmapbt_compute_maxlevels(mp); + xfs_refcountbt_compute_maxlevels(mp); /* * Check that the data (and log if separate) are an ok size. diff --git a/libxfs/xfs_ialloc.c b/libxfs/xfs_ialloc.c index 36d463a3e..acf9e55e2 100644 --- a/libxfs/xfs_ialloc.c +++ b/libxfs/xfs_ialloc.c @@ -25,20 +25,6 @@ #include "xfs_trace.h" #include "xfs_rmap.h" - -/* - * Allocation group level functions. - */ -int -xfs_ialloc_cluster_alignment( - struct xfs_mount *mp) -{ - if (xfs_sb_version_hasalign(&mp->m_sb) && - mp->m_sb.sb_inoalignmt >= xfs_icluster_size_fsb(mp)) - return mp->m_sb.sb_inoalignmt; - return 1; -} - /* * Lookup a record by ino in the btree given by cur. */ @@ -2407,20 +2393,6 @@ out_map: return 0; } -/* - * Compute and fill in value of m_ino_geo.inobt_maxlevels. - */ -void -xfs_ialloc_compute_maxlevels( - xfs_mount_t *mp) /* file system mount structure */ -{ - uint inodes; - - inodes = (1LL << XFS_INO_AGINO_BITS(mp)) >> XFS_INODES_PER_CHUNK_LOG; - M_IGEO(mp)->inobt_maxlevels = xfs_btree_compute_maxlevels( - M_IGEO(mp)->inobt_mnr, inodes); -} - /* * Log specified fields for the ag hdr (inode section). The growth of the agi * structure over time requires that we interpret the buffer as two logical @@ -2767,3 +2739,99 @@ xfs_ialloc_count_inodes( *freecount = ci.freecount; return 0; } + +/* + * Initialize inode-related geometry information. + * + * Compute the inode btree min and max levels and set maxicount. + * + * Set the inode cluster size. This may still be overridden by the file + * system block size if it is larger than the chosen cluster size. + * + * For v5 filesystems, scale the cluster size with the inode size to keep a + * constant ratio of inode per cluster buffer, but only if mkfs has set the + * inode alignment value appropriately for larger cluster sizes. + * + * Then compute the inode cluster alignment information. + */ +void +xfs_ialloc_setup_geometry( + struct xfs_mount *mp) +{ + struct xfs_sb *sbp = &mp->m_sb; + struct xfs_ino_geometry *igeo = M_IGEO(mp); + uint64_t icount; + uint inodes; + + /* Compute inode btree geometry. */ + igeo->agino_log = sbp->sb_inopblog + sbp->sb_agblklog; + igeo->inobt_mxr[0] = xfs_inobt_maxrecs(mp, sbp->sb_blocksize, 1); + igeo->inobt_mxr[1] = xfs_inobt_maxrecs(mp, sbp->sb_blocksize, 0); + igeo->inobt_mnr[0] = igeo->inobt_mxr[0] / 2; + igeo->inobt_mnr[1] = igeo->inobt_mxr[1] / 2; + + igeo->ialloc_inos = max_t(uint16_t, XFS_INODES_PER_CHUNK, + sbp->sb_inopblock); + igeo->ialloc_blks = igeo->ialloc_inos >> sbp->sb_inopblog; + + if (sbp->sb_spino_align) + igeo->ialloc_min_blks = sbp->sb_spino_align; + else + igeo->ialloc_min_blks = igeo->ialloc_blks; + + /* Compute and fill in value of m_ino_geo.inobt_maxlevels. */ + inodes = (1LL << XFS_INO_AGINO_BITS(mp)) >> XFS_INODES_PER_CHUNK_LOG; + igeo->inobt_maxlevels = xfs_btree_compute_maxlevels(igeo->inobt_mnr, + inodes); + + /* Set the maximum inode count for this filesystem. */ + if (sbp->sb_imax_pct) { + /* + * Make sure the maximum inode count is a multiple + * of the units we allocate inodes in. + */ + icount = sbp->sb_dblocks * sbp->sb_imax_pct; + do_div(icount, 100); + do_div(icount, igeo->ialloc_blks); + igeo->maxicount = XFS_FSB_TO_INO(mp, + icount * igeo->ialloc_blks); + } else { + igeo->maxicount = 0; + } + + igeo->inode_cluster_size = XFS_INODE_BIG_CLUSTER_SIZE; + if (xfs_sb_version_hascrc(&mp->m_sb)) { + int new_size = igeo->inode_cluster_size; + + new_size *= mp->m_sb.sb_inodesize / XFS_DINODE_MIN_SIZE; + if (mp->m_sb.sb_inoalignmt >= XFS_B_TO_FSBT(mp, new_size)) + igeo->inode_cluster_size = new_size; + } + + /* Calculate inode cluster ratios. */ + if (igeo->inode_cluster_size > mp->m_sb.sb_blocksize) + igeo->blocks_per_cluster = XFS_B_TO_FSBT(mp, + igeo->inode_cluster_size); + else + igeo->blocks_per_cluster = 1; + igeo->inodes_per_cluster = XFS_FSB_TO_INO(mp, igeo->blocks_per_cluster); + + /* Calculate inode cluster alignment. */ + if (xfs_sb_version_hasalign(&mp->m_sb) && + mp->m_sb.sb_inoalignmt >= igeo->blocks_per_cluster) + igeo->cluster_align = mp->m_sb.sb_inoalignmt; + else + igeo->cluster_align = 1; + igeo->inoalign_mask = igeo->cluster_align - 1; + igeo->cluster_align_inodes = XFS_FSB_TO_INO(mp, igeo->cluster_align); + + /* + * If we are using stripe alignment, check whether + * the stripe unit is a multiple of the inode alignment + */ + if (mp->m_dalign && igeo->inoalign_mask && + !(mp->m_dalign & igeo->inoalign_mask)) + igeo->ialloc_align = mp->m_dalign; + else + igeo->ialloc_align = 0; +} diff --git a/libxfs/xfs_ialloc.h b/libxfs/xfs_ialloc.h index e7d935e69..323592d56 100644 --- a/libxfs/xfs_ialloc.h +++ b/libxfs/xfs_ialloc.h @@ -23,16 +23,6 @@ struct xfs_icluster { * sparse chunks */ }; -/* Calculate and return the number of filesystem blocks per inode cluster */ -static inline int -xfs_icluster_size_fsb( - struct xfs_mount *mp) -{ - if (mp->m_sb.sb_blocksize >= M_IGEO(mp)->inode_cluster_size) - return 1; - return M_IGEO(mp)->inode_cluster_size >> mp->m_sb.sb_blocklog; -} - /* * Make an inode pointer out of the buffer/offset. */ @@ -95,13 +85,6 @@ xfs_imap( struct xfs_imap *imap, /* location map structure */ uint flags); /* flags for inode btree lookup */ -/* - * Compute and fill in value of m_ino_geo.inobt_maxlevels. - */ -void -xfs_ialloc_compute_maxlevels( - struct xfs_mount *mp); /* file system mount structure */ - /* * Log specified fields for the ag hdr (inode section) */ @@ -168,5 +151,6 @@ int xfs_inobt_insert_rec(struct xfs_btree_cur *cur, uint16_t holemask, int *stat); int xfs_ialloc_cluster_alignment(struct xfs_mount *mp); +void xfs_ialloc_setup_geometry(struct xfs_mount *mp); #endif /* __XFS_IALLOC_H__ */ diff --git a/libxfs/xfs_sb.c b/libxfs/xfs_sb.c index 3677877ae..f4bcffe19 100644 --- a/libxfs/xfs_sb.c +++ b/libxfs/xfs_sb.c @@ -777,22 +777,21 @@ const struct xfs_buf_ops xfs_sb_quiet_buf_ops = { * * Mount initialization code establishing various mount * fields from the superblock associated with the given - * mount structure + * mount structure. + * + * Inode geometry are calculated in xfs_ialloc_setup_geometry. */ void xfs_sb_mount_common( struct xfs_mount *mp, struct xfs_sb *sbp) { - struct xfs_ino_geometry *igeo = M_IGEO(mp); - mp->m_agfrotor = mp->m_agirotor = 0; 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; mp->m_sectbb_log = sbp->sb_sectlog - BBSHIFT; mp->m_agno_log = xfs_highbit32(sbp->sb_agcount - 1) + 1; - igeo->agino_log = sbp->sb_inopblog + sbp->sb_agblklog; mp->m_blockmask = sbp->sb_blocksize - 1; mp->m_blockwsize = sbp->sb_blocksize >> XFS_WORDLOG; mp->m_blockwmask = mp->m_blockwsize - 1; @@ -802,11 +801,6 @@ xfs_sb_mount_common( mp->m_alloc_mnr[0] = mp->m_alloc_mxr[0] / 2; mp->m_alloc_mnr[1] = mp->m_alloc_mxr[1] / 2; - igeo->inobt_mxr[0] = xfs_inobt_maxrecs(mp, sbp->sb_blocksize, 1); - igeo->inobt_mxr[1] = xfs_inobt_maxrecs(mp, sbp->sb_blocksize, 0); - igeo->inobt_mnr[0] = igeo->inobt_mxr[0] / 2; - igeo->inobt_mnr[1] = igeo->inobt_mxr[1] / 2; - mp->m_bmap_dmxr[0] = xfs_bmbt_maxrecs(mp, sbp->sb_blocksize, 1); mp->m_bmap_dmxr[1] = xfs_bmbt_maxrecs(mp, sbp->sb_blocksize, 0); mp->m_bmap_dmnr[0] = mp->m_bmap_dmxr[0] / 2; @@ -823,14 +817,6 @@ xfs_sb_mount_common( mp->m_refc_mnr[1] = mp->m_refc_mxr[1] / 2; mp->m_bsize = XFS_FSB_TO_BB(mp, 1); - igeo->ialloc_inos = max_t(uint16_t, XFS_INODES_PER_CHUNK, - sbp->sb_inopblock); - igeo->ialloc_blks = igeo->ialloc_inos >> sbp->sb_inopblog; - - if (sbp->sb_spino_align) - igeo->ialloc_min_blks = sbp->sb_spino_align; - else - igeo->ialloc_min_blks = igeo->ialloc_blks; mp->m_alloc_set_aside = xfs_alloc_set_aside(mp); mp->m_ag_max_usable = xfs_alloc_ag_max_usable(mp); } -- 2.47.2