aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/libxfs/xfs_ialloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/libxfs/xfs_ialloc.c')
-rw-r--r--fs/xfs/libxfs/xfs_ialloc.c124
1 files changed, 96 insertions, 28 deletions
diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c
index 49f556cf244b..fdfcc03a35b9 100644
--- a/fs/xfs/libxfs/xfs_ialloc.c
+++ b/fs/xfs/libxfs/xfs_ialloc.c
@@ -31,20 +31,6 @@
31#include "xfs_log.h" 31#include "xfs_log.h"
32#include "xfs_rmap.h" 32#include "xfs_rmap.h"
33 33
34
35/*
36 * Allocation group level functions.
37 */
38int
39xfs_ialloc_cluster_alignment(
40 struct xfs_mount *mp)
41{
42 if (xfs_sb_version_hasalign(&mp->m_sb) &&
43 mp->m_sb.sb_inoalignmt >= xfs_icluster_size_fsb(mp))
44 return mp->m_sb.sb_inoalignmt;
45 return 1;
46}
47
48/* 34/*
49 * Lookup a record by ino in the btree given by cur. 35 * Lookup a record by ino in the btree given by cur.
50 */ 36 */
@@ -2414,20 +2400,6 @@ out_map:
2414} 2400}
2415 2401
2416/* 2402/*
2417 * Compute and fill in value of m_ino_geo.inobt_maxlevels.
2418 */
2419void
2420xfs_ialloc_compute_maxlevels(
2421 xfs_mount_t *mp) /* file system mount structure */
2422{
2423 uint inodes;
2424
2425 inodes = (1LL << XFS_INO_AGINO_BITS(mp)) >> XFS_INODES_PER_CHUNK_LOG;
2426 M_IGEO(mp)->inobt_maxlevels = xfs_btree_compute_maxlevels(
2427 M_IGEO(mp)->inobt_mnr, inodes);
2428}
2429
2430/*
2431 * Log specified fields for the ag hdr (inode section). The growth of the agi 2403 * Log specified fields for the ag hdr (inode section). The growth of the agi
2432 * structure over time requires that we interpret the buffer as two logical 2404 * structure over time requires that we interpret the buffer as two logical
2433 * regions delineated by the end of the unlinked list. This is due to the size 2405 * regions delineated by the end of the unlinked list. This is due to the size
@@ -2773,3 +2745,99 @@ xfs_ialloc_count_inodes(
2773 *freecount = ci.freecount; 2745 *freecount = ci.freecount;
2774 return 0; 2746 return 0;
2775} 2747}
2748
2749/*
2750 * Initialize inode-related geometry information.
2751 *
2752 * Compute the inode btree min and max levels and set maxicount.
2753 *
2754 * Set the inode cluster size. This may still be overridden by the file
2755 * system block size if it is larger than the chosen cluster size.
2756 *
2757 * For v5 filesystems, scale the cluster size with the inode size to keep a
2758 * constant ratio of inode per cluster buffer, but only if mkfs has set the
2759 * inode alignment value appropriately for larger cluster sizes.
2760 *
2761 * Then compute the inode cluster alignment information.
2762 */
2763void
2764xfs_ialloc_setup_geometry(
2765 struct xfs_mount *mp)
2766{
2767 struct xfs_sb *sbp = &mp->m_sb;
2768 struct xfs_ino_geometry *igeo = M_IGEO(mp);
2769 uint64_t icount;
2770 uint inodes;
2771
2772 /* Compute inode btree geometry. */
2773 igeo->agino_log = sbp->sb_inopblog + sbp->sb_agblklog;
2774 igeo->inobt_mxr[0] = xfs_inobt_maxrecs(mp, sbp->sb_blocksize, 1);
2775 igeo->inobt_mxr[1] = xfs_inobt_maxrecs(mp, sbp->sb_blocksize, 0);
2776 igeo->inobt_mnr[0] = igeo->inobt_mxr[0] / 2;
2777 igeo->inobt_mnr[1] = igeo->inobt_mxr[1] / 2;
2778
2779 igeo->ialloc_inos = max_t(uint16_t, XFS_INODES_PER_CHUNK,
2780 sbp->sb_inopblock);
2781 igeo->ialloc_blks = igeo->ialloc_inos >> sbp->sb_inopblog;
2782
2783 if (sbp->sb_spino_align)
2784 igeo->ialloc_min_blks = sbp->sb_spino_align;
2785 else
2786 igeo->ialloc_min_blks = igeo->ialloc_blks;
2787
2788 /* Compute and fill in value of m_ino_geo.inobt_maxlevels. */
2789 inodes = (1LL << XFS_INO_AGINO_BITS(mp)) >> XFS_INODES_PER_CHUNK_LOG;
2790 igeo->inobt_maxlevels = xfs_btree_compute_maxlevels(igeo->inobt_mnr,
2791 inodes);
2792
2793 /* Set the maximum inode count for this filesystem. */
2794 if (sbp->sb_imax_pct) {
2795 /*
2796 * Make sure the maximum inode count is a multiple
2797 * of the units we allocate inodes in.
2798 */
2799 icount = sbp->sb_dblocks * sbp->sb_imax_pct;
2800 do_div(icount, 100);
2801 do_div(icount, igeo->ialloc_blks);
2802 igeo->maxicount = XFS_FSB_TO_INO(mp,
2803 icount * igeo->ialloc_blks);
2804 } else {
2805 igeo->maxicount = 0;
2806 }
2807
2808 igeo->inode_cluster_size = XFS_INODE_BIG_CLUSTER_SIZE;
2809 if (xfs_sb_version_hascrc(&mp->m_sb)) {
2810 int new_size = igeo->inode_cluster_size;
2811
2812 new_size *= mp->m_sb.sb_inodesize / XFS_DINODE_MIN_SIZE;
2813 if (mp->m_sb.sb_inoalignmt >= XFS_B_TO_FSBT(mp, new_size))
2814 igeo->inode_cluster_size = new_size;
2815 }
2816
2817 /* Calculate inode cluster ratios. */
2818 if (igeo->inode_cluster_size > mp->m_sb.sb_blocksize)
2819 igeo->blocks_per_cluster = XFS_B_TO_FSBT(mp,
2820 igeo->inode_cluster_size);
2821 else
2822 igeo->blocks_per_cluster = 1;
2823 igeo->inodes_per_cluster = XFS_FSB_TO_INO(mp, igeo->blocks_per_cluster);
2824
2825 /* Calculate inode cluster alignment. */
2826 if (xfs_sb_version_hasalign(&mp->m_sb) &&
2827 mp->m_sb.sb_inoalignmt >= igeo->blocks_per_cluster)
2828 igeo->cluster_align = mp->m_sb.sb_inoalignmt;
2829 else
2830 igeo->cluster_align = 1;
2831 igeo->inoalign_mask = igeo->cluster_align - 1;
2832 igeo->cluster_align_inodes = XFS_FSB_TO_INO(mp, igeo->cluster_align);
2833
2834 /*
2835 * If we are using stripe alignment, check whether
2836 * the stripe unit is a multiple of the inode alignment
2837 */
2838 if (mp->m_dalign && igeo->inoalign_mask &&
2839 !(mp->m_dalign & igeo->inoalign_mask))
2840 igeo->ialloc_align = mp->m_dalign;
2841 else
2842 igeo->ialloc_align = 0;
2843}