aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDarrick J. Wong <darrick.wong@oracle.com>2019-06-05 14:19:35 -0400
committerDarrick J. Wong <darrick.wong@oracle.com>2019-06-12 11:37:40 -0400
commit494dba7b276e12bc3f6ff2b9b584b6e9f693af45 (patch)
tree77b3aaafda4a18bc74fef64845c6daa4cb218a4b
parentef325959993edd53e3ce7c818b18f776ac0740a6 (diff)
xfs: refactor inode geometry setup routines
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 <darrick.wong@oracle.com> Reviewed-by: Dave Chinner <dchinner@redhat.com>
-rw-r--r--fs/xfs/libxfs/xfs_ialloc.c124
-rw-r--r--fs/xfs/libxfs/xfs_ialloc.h18
-rw-r--r--fs/xfs/libxfs/xfs_sb.c20
-rw-r--r--fs/xfs/xfs_mount.c83
4 files changed, 101 insertions, 144 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}
diff --git a/fs/xfs/libxfs/xfs_ialloc.h b/fs/xfs/libxfs/xfs_ialloc.h
index e7d935e69b11..323592d563d5 100644
--- a/fs/xfs/libxfs/xfs_ialloc.h
+++ b/fs/xfs/libxfs/xfs_ialloc.h
@@ -23,16 +23,6 @@ struct xfs_icluster {
23 * sparse chunks */ 23 * sparse chunks */
24}; 24};
25 25
26/* Calculate and return the number of filesystem blocks per inode cluster */
27static inline int
28xfs_icluster_size_fsb(
29 struct xfs_mount *mp)
30{
31 if (mp->m_sb.sb_blocksize >= M_IGEO(mp)->inode_cluster_size)
32 return 1;
33 return M_IGEO(mp)->inode_cluster_size >> mp->m_sb.sb_blocklog;
34}
35
36/* 26/*
37 * Make an inode pointer out of the buffer/offset. 27 * Make an inode pointer out of the buffer/offset.
38 */ 28 */
@@ -96,13 +86,6 @@ xfs_imap(
96 uint flags); /* flags for inode btree lookup */ 86 uint flags); /* flags for inode btree lookup */
97 87
98/* 88/*
99 * Compute and fill in value of m_ino_geo.inobt_maxlevels.
100 */
101void
102xfs_ialloc_compute_maxlevels(
103 struct xfs_mount *mp); /* file system mount structure */
104
105/*
106 * Log specified fields for the ag hdr (inode section) 89 * Log specified fields for the ag hdr (inode section)
107 */ 90 */
108void 91void
@@ -168,5 +151,6 @@ int xfs_inobt_insert_rec(struct xfs_btree_cur *cur, uint16_t holemask,
168 int *stat); 151 int *stat);
169 152
170int xfs_ialloc_cluster_alignment(struct xfs_mount *mp); 153int xfs_ialloc_cluster_alignment(struct xfs_mount *mp);
154void xfs_ialloc_setup_geometry(struct xfs_mount *mp);
171 155
172#endif /* __XFS_IALLOC_H__ */ 156#endif /* __XFS_IALLOC_H__ */
diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c
index a44eb52b861d..2490b2c9733d 100644
--- a/fs/xfs/libxfs/xfs_sb.c
+++ b/fs/xfs/libxfs/xfs_sb.c
@@ -800,22 +800,21 @@ const struct xfs_buf_ops xfs_sb_quiet_buf_ops = {
800 * 800 *
801 * Mount initialization code establishing various mount 801 * Mount initialization code establishing various mount
802 * fields from the superblock associated with the given 802 * fields from the superblock associated with the given
803 * mount structure 803 * mount structure.
804 *
805 * Inode geometry are calculated in xfs_ialloc_setup_geometry.
804 */ 806 */
805void 807void
806xfs_sb_mount_common( 808xfs_sb_mount_common(
807 struct xfs_mount *mp, 809 struct xfs_mount *mp,
808 struct xfs_sb *sbp) 810 struct xfs_sb *sbp)
809{ 811{
810 struct xfs_ino_geometry *igeo = M_IGEO(mp);
811
812 mp->m_agfrotor = mp->m_agirotor = 0; 812 mp->m_agfrotor = mp->m_agirotor = 0;
813 mp->m_maxagi = mp->m_sb.sb_agcount; 813 mp->m_maxagi = mp->m_sb.sb_agcount;
814 mp->m_blkbit_log = sbp->sb_blocklog + XFS_NBBYLOG; 814 mp->m_blkbit_log = sbp->sb_blocklog + XFS_NBBYLOG;
815 mp->m_blkbb_log = sbp->sb_blocklog - BBSHIFT; 815 mp->m_blkbb_log = sbp->sb_blocklog - BBSHIFT;
816 mp->m_sectbb_log = sbp->sb_sectlog - BBSHIFT; 816 mp->m_sectbb_log = sbp->sb_sectlog - BBSHIFT;
817 mp->m_agno_log = xfs_highbit32(sbp->sb_agcount - 1) + 1; 817 mp->m_agno_log = xfs_highbit32(sbp->sb_agcount - 1) + 1;
818 igeo->agino_log = sbp->sb_inopblog + sbp->sb_agblklog;
819 mp->m_blockmask = sbp->sb_blocksize - 1; 818 mp->m_blockmask = sbp->sb_blocksize - 1;
820 mp->m_blockwsize = sbp->sb_blocksize >> XFS_WORDLOG; 819 mp->m_blockwsize = sbp->sb_blocksize >> XFS_WORDLOG;
821 mp->m_blockwmask = mp->m_blockwsize - 1; 820 mp->m_blockwmask = mp->m_blockwsize - 1;
@@ -825,11 +824,6 @@ xfs_sb_mount_common(
825 mp->m_alloc_mnr[0] = mp->m_alloc_mxr[0] / 2; 824 mp->m_alloc_mnr[0] = mp->m_alloc_mxr[0] / 2;
826 mp->m_alloc_mnr[1] = mp->m_alloc_mxr[1] / 2; 825 mp->m_alloc_mnr[1] = mp->m_alloc_mxr[1] / 2;
827 826
828 igeo->inobt_mxr[0] = xfs_inobt_maxrecs(mp, sbp->sb_blocksize, 1);
829 igeo->inobt_mxr[1] = xfs_inobt_maxrecs(mp, sbp->sb_blocksize, 0);
830 igeo->inobt_mnr[0] = igeo->inobt_mxr[0] / 2;
831 igeo->inobt_mnr[1] = igeo->inobt_mxr[1] / 2;
832
833 mp->m_bmap_dmxr[0] = xfs_bmbt_maxrecs(mp, sbp->sb_blocksize, 1); 827 mp->m_bmap_dmxr[0] = xfs_bmbt_maxrecs(mp, sbp->sb_blocksize, 1);
834 mp->m_bmap_dmxr[1] = xfs_bmbt_maxrecs(mp, sbp->sb_blocksize, 0); 828 mp->m_bmap_dmxr[1] = xfs_bmbt_maxrecs(mp, sbp->sb_blocksize, 0);
835 mp->m_bmap_dmnr[0] = mp->m_bmap_dmxr[0] / 2; 829 mp->m_bmap_dmnr[0] = mp->m_bmap_dmxr[0] / 2;
@@ -846,14 +840,6 @@ xfs_sb_mount_common(
846 mp->m_refc_mnr[1] = mp->m_refc_mxr[1] / 2; 840 mp->m_refc_mnr[1] = mp->m_refc_mxr[1] / 2;
847 841
848 mp->m_bsize = XFS_FSB_TO_BB(mp, 1); 842 mp->m_bsize = XFS_FSB_TO_BB(mp, 1);
849 igeo->ialloc_inos = max_t(uint16_t, XFS_INODES_PER_CHUNK,
850 sbp->sb_inopblock);
851 igeo->ialloc_blks = igeo->ialloc_inos >> sbp->sb_inopblog;
852
853 if (sbp->sb_spino_align)
854 igeo->ialloc_min_blks = sbp->sb_spino_align;
855 else
856 igeo->ialloc_min_blks = igeo->ialloc_blks;
857 mp->m_alloc_set_aside = xfs_alloc_set_aside(mp); 843 mp->m_alloc_set_aside = xfs_alloc_set_aside(mp);
858 mp->m_ag_max_usable = xfs_alloc_ag_max_usable(mp); 844 mp->m_ag_max_usable = xfs_alloc_ag_max_usable(mp);
859} 845}
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index 73e5cfc4d0ec..81d6535b24b4 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -430,32 +430,6 @@ xfs_update_alignment(xfs_mount_t *mp)
430} 430}
431 431
432/* 432/*
433 * Set the maximum inode count for this filesystem
434 */
435STATIC void
436xfs_set_maxicount(
437 struct xfs_mount *mp)
438{
439 struct xfs_sb *sbp = &(mp->m_sb);
440 struct xfs_ino_geometry *igeo = M_IGEO(mp);
441 uint64_t icount;
442
443 if (sbp->sb_imax_pct) {
444 /*
445 * Make sure the maximum inode count is a multiple
446 * of the units we allocate inodes in.
447 */
448 icount = sbp->sb_dblocks * sbp->sb_imax_pct;
449 do_div(icount, 100);
450 do_div(icount, igeo->ialloc_blks);
451 igeo->maxicount = XFS_FSB_TO_INO(mp,
452 icount * igeo->ialloc_blks);
453 } else {
454 igeo->maxicount = 0;
455 }
456}
457
458/*
459 * Set the default minimum read and write sizes unless 433 * Set the default minimum read and write sizes unless
460 * already specified in a mount option. 434 * already specified in a mount option.
461 * We use smaller I/O sizes when the file system 435 * We use smaller I/O sizes when the file system
@@ -511,29 +485,6 @@ xfs_set_low_space_thresholds(
511 } 485 }
512} 486}
513 487
514
515/*
516 * Set whether we're using inode alignment.
517 */
518STATIC void
519xfs_set_inoalignment(xfs_mount_t *mp)
520{
521 if (xfs_sb_version_hasalign(&mp->m_sb) &&
522 mp->m_sb.sb_inoalignmt >= xfs_icluster_size_fsb(mp))
523 M_IGEO(mp)->inoalign_mask = mp->m_sb.sb_inoalignmt - 1;
524 else
525 M_IGEO(mp)->inoalign_mask = 0;
526 /*
527 * If we are using stripe alignment, check whether
528 * the stripe unit is a multiple of the inode alignment
529 */
530 if (mp->m_dalign && M_IGEO(mp)->inoalign_mask &&
531 !(mp->m_dalign & M_IGEO(mp)->inoalign_mask))
532 M_IGEO(mp)->ialloc_align = mp->m_dalign;
533 else
534 M_IGEO(mp)->ialloc_align = 0;
535}
536
537/* 488/*
538 * Check that the data (and log if separate) is an ok size. 489 * Check that the data (and log if separate) is an ok size.
539 */ 490 */
@@ -752,12 +703,10 @@ xfs_mountfs(
752 xfs_alloc_compute_maxlevels(mp); 703 xfs_alloc_compute_maxlevels(mp);
753 xfs_bmap_compute_maxlevels(mp, XFS_DATA_FORK); 704 xfs_bmap_compute_maxlevels(mp, XFS_DATA_FORK);
754 xfs_bmap_compute_maxlevels(mp, XFS_ATTR_FORK); 705 xfs_bmap_compute_maxlevels(mp, XFS_ATTR_FORK);
755 xfs_ialloc_compute_maxlevels(mp); 706 xfs_ialloc_setup_geometry(mp);
756 xfs_rmapbt_compute_maxlevels(mp); 707 xfs_rmapbt_compute_maxlevels(mp);
757 xfs_refcountbt_compute_maxlevels(mp); 708 xfs_refcountbt_compute_maxlevels(mp);
758 709
759 xfs_set_maxicount(mp);
760
761 /* enable fail_at_unmount as default */ 710 /* enable fail_at_unmount as default */
762 mp->m_fail_unmount = true; 711 mp->m_fail_unmount = true;
763 712
@@ -791,31 +740,6 @@ xfs_mountfs(
791 xfs_set_low_space_thresholds(mp); 740 xfs_set_low_space_thresholds(mp);
792 741
793 /* 742 /*
794 * Set the inode cluster size.
795 * This may still be overridden by the file system
796 * block size if it is larger than the chosen cluster size.
797 *
798 * For v5 filesystems, scale the cluster size with the inode size to
799 * keep a constant ratio of inode per cluster buffer, but only if mkfs
800 * has set the inode alignment value appropriately for larger cluster
801 * sizes.
802 */
803 igeo->inode_cluster_size = XFS_INODE_BIG_CLUSTER_SIZE;
804 if (xfs_sb_version_hascrc(&mp->m_sb)) {
805 int new_size = igeo->inode_cluster_size;
806
807 new_size *= mp->m_sb.sb_inodesize / XFS_DINODE_MIN_SIZE;
808 if (mp->m_sb.sb_inoalignmt >= XFS_B_TO_FSBT(mp, new_size))
809 igeo->inode_cluster_size = new_size;
810 }
811 igeo->blocks_per_cluster = xfs_icluster_size_fsb(mp);
812 igeo->inodes_per_cluster = XFS_FSB_TO_INO(mp,
813 igeo->blocks_per_cluster);
814 igeo->cluster_align = xfs_ialloc_cluster_alignment(mp);
815 igeo->cluster_align_inodes = XFS_FSB_TO_INO(mp,
816 igeo->cluster_align);
817
818 /*
819 * If enabled, sparse inode chunk alignment is expected to match the 743 * If enabled, sparse inode chunk alignment is expected to match the
820 * cluster size. Full inode chunk alignment must match the chunk size, 744 * cluster size. Full inode chunk alignment must match the chunk size,
821 * but that is checked on sb read verification... 745 * but that is checked on sb read verification...
@@ -832,11 +756,6 @@ xfs_mountfs(
832 } 756 }
833 757
834 /* 758 /*
835 * Set inode alignment fields
836 */
837 xfs_set_inoalignment(mp);
838
839 /*
840 * Check that the data (and log if separate) is an ok size. 759 * Check that the data (and log if separate) is an ok size.
841 */ 760 */
842 error = xfs_check_sizes(mp); 761 error = xfs_check_sizes(mp);