diff options
Diffstat (limited to 'fs/xfs/libxfs/xfs_ialloc.c')
-rw-r--r-- | fs/xfs/libxfs/xfs_ialloc.c | 124 |
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 | */ | ||
38 | int | ||
39 | xfs_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 | */ | ||
2419 | void | ||
2420 | xfs_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 | */ | ||
2763 | void | ||
2764 | xfs_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 | } | ||