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>
This commit is contained in:
@@ -31,20 +31,6 @@
|
|||||||
#include "xfs_log.h"
|
#include "xfs_log.h"
|
||||||
#include "xfs_rmap.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.
|
* Lookup a record by ino in the btree given by cur.
|
||||||
*/
|
*/
|
||||||
@@ -2413,20 +2399,6 @@ out_map:
|
|||||||
return 0;
|
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
|
* 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
|
* structure over time requires that we interpret the buffer as two logical
|
||||||
@@ -2773,3 +2745,99 @@ xfs_ialloc_count_inodes(
|
|||||||
*freecount = ci.freecount;
|
*freecount = ci.freecount;
|
||||||
return 0;
|
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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -23,16 +23,6 @@ struct xfs_icluster {
|
|||||||
* sparse chunks */
|
* 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.
|
* Make an inode pointer out of the buffer/offset.
|
||||||
*/
|
*/
|
||||||
@@ -95,13 +85,6 @@ xfs_imap(
|
|||||||
struct xfs_imap *imap, /* location map structure */
|
struct xfs_imap *imap, /* location map structure */
|
||||||
uint flags); /* flags for inode btree lookup */
|
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)
|
* 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 *stat);
|
||||||
|
|
||||||
int xfs_ialloc_cluster_alignment(struct xfs_mount *mp);
|
int xfs_ialloc_cluster_alignment(struct xfs_mount *mp);
|
||||||
|
void xfs_ialloc_setup_geometry(struct xfs_mount *mp);
|
||||||
|
|
||||||
#endif /* __XFS_IALLOC_H__ */
|
#endif /* __XFS_IALLOC_H__ */
|
||||||
|
|||||||
@@ -800,22 +800,21 @@ const struct xfs_buf_ops xfs_sb_quiet_buf_ops = {
|
|||||||
*
|
*
|
||||||
* Mount initialization code establishing various mount
|
* Mount initialization code establishing various mount
|
||||||
* fields from the superblock associated with the given
|
* fields from the superblock associated with the given
|
||||||
* mount structure
|
* mount structure.
|
||||||
|
*
|
||||||
|
* Inode geometry are calculated in xfs_ialloc_setup_geometry.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
xfs_sb_mount_common(
|
xfs_sb_mount_common(
|
||||||
struct xfs_mount *mp,
|
struct xfs_mount *mp,
|
||||||
struct xfs_sb *sbp)
|
struct xfs_sb *sbp)
|
||||||
{
|
{
|
||||||
struct xfs_ino_geometry *igeo = M_IGEO(mp);
|
|
||||||
|
|
||||||
mp->m_agfrotor = mp->m_agirotor = 0;
|
mp->m_agfrotor = mp->m_agirotor = 0;
|
||||||
mp->m_maxagi = mp->m_sb.sb_agcount;
|
mp->m_maxagi = mp->m_sb.sb_agcount;
|
||||||
mp->m_blkbit_log = sbp->sb_blocklog + XFS_NBBYLOG;
|
mp->m_blkbit_log = sbp->sb_blocklog + XFS_NBBYLOG;
|
||||||
mp->m_blkbb_log = sbp->sb_blocklog - BBSHIFT;
|
mp->m_blkbb_log = sbp->sb_blocklog - BBSHIFT;
|
||||||
mp->m_sectbb_log = sbp->sb_sectlog - BBSHIFT;
|
mp->m_sectbb_log = sbp->sb_sectlog - BBSHIFT;
|
||||||
mp->m_agno_log = xfs_highbit32(sbp->sb_agcount - 1) + 1;
|
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_blockmask = sbp->sb_blocksize - 1;
|
||||||
mp->m_blockwsize = sbp->sb_blocksize >> XFS_WORDLOG;
|
mp->m_blockwsize = sbp->sb_blocksize >> XFS_WORDLOG;
|
||||||
mp->m_blockwmask = mp->m_blockwsize - 1;
|
mp->m_blockwmask = mp->m_blockwsize - 1;
|
||||||
@@ -825,11 +824,6 @@ xfs_sb_mount_common(
|
|||||||
mp->m_alloc_mnr[0] = mp->m_alloc_mxr[0] / 2;
|
mp->m_alloc_mnr[0] = mp->m_alloc_mxr[0] / 2;
|
||||||
mp->m_alloc_mnr[1] = mp->m_alloc_mxr[1] / 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[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_dmxr[1] = xfs_bmbt_maxrecs(mp, sbp->sb_blocksize, 0);
|
||||||
mp->m_bmap_dmnr[0] = mp->m_bmap_dmxr[0] / 2;
|
mp->m_bmap_dmnr[0] = mp->m_bmap_dmxr[0] / 2;
|
||||||
@@ -846,14 +840,6 @@ xfs_sb_mount_common(
|
|||||||
mp->m_refc_mnr[1] = mp->m_refc_mxr[1] / 2;
|
mp->m_refc_mnr[1] = mp->m_refc_mxr[1] / 2;
|
||||||
|
|
||||||
mp->m_bsize = XFS_FSB_TO_BB(mp, 1);
|
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_alloc_set_aside = xfs_alloc_set_aside(mp);
|
||||||
mp->m_ag_max_usable = xfs_alloc_ag_max_usable(mp);
|
mp->m_ag_max_usable = xfs_alloc_ag_max_usable(mp);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -429,32 +429,6 @@ xfs_update_alignment(xfs_mount_t *mp)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Set the maximum inode count for this filesystem
|
|
||||||
*/
|
|
||||||
STATIC void
|
|
||||||
xfs_set_maxicount(
|
|
||||||
struct xfs_mount *mp)
|
|
||||||
{
|
|
||||||
struct xfs_sb *sbp = &(mp->m_sb);
|
|
||||||
struct xfs_ino_geometry *igeo = M_IGEO(mp);
|
|
||||||
uint64_t icount;
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set the default minimum read and write sizes unless
|
* Set the default minimum read and write sizes unless
|
||||||
* already specified in a mount option.
|
* already specified in a mount option.
|
||||||
@@ -511,29 +485,6 @@ xfs_set_low_space_thresholds(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set whether we're using inode alignment.
|
|
||||||
*/
|
|
||||||
STATIC void
|
|
||||||
xfs_set_inoalignment(xfs_mount_t *mp)
|
|
||||||
{
|
|
||||||
if (xfs_sb_version_hasalign(&mp->m_sb) &&
|
|
||||||
mp->m_sb.sb_inoalignmt >= xfs_icluster_size_fsb(mp))
|
|
||||||
M_IGEO(mp)->inoalign_mask = mp->m_sb.sb_inoalignmt - 1;
|
|
||||||
else
|
|
||||||
M_IGEO(mp)->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 && M_IGEO(mp)->inoalign_mask &&
|
|
||||||
!(mp->m_dalign & M_IGEO(mp)->inoalign_mask))
|
|
||||||
M_IGEO(mp)->ialloc_align = mp->m_dalign;
|
|
||||||
else
|
|
||||||
M_IGEO(mp)->ialloc_align = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check that the data (and log if separate) is an ok size.
|
* Check that the data (and log if separate) is an ok size.
|
||||||
*/
|
*/
|
||||||
@@ -752,12 +703,10 @@ xfs_mountfs(
|
|||||||
xfs_alloc_compute_maxlevels(mp);
|
xfs_alloc_compute_maxlevels(mp);
|
||||||
xfs_bmap_compute_maxlevels(mp, XFS_DATA_FORK);
|
xfs_bmap_compute_maxlevels(mp, XFS_DATA_FORK);
|
||||||
xfs_bmap_compute_maxlevels(mp, XFS_ATTR_FORK);
|
xfs_bmap_compute_maxlevels(mp, XFS_ATTR_FORK);
|
||||||
xfs_ialloc_compute_maxlevels(mp);
|
xfs_ialloc_setup_geometry(mp);
|
||||||
xfs_rmapbt_compute_maxlevels(mp);
|
xfs_rmapbt_compute_maxlevels(mp);
|
||||||
xfs_refcountbt_compute_maxlevels(mp);
|
xfs_refcountbt_compute_maxlevels(mp);
|
||||||
|
|
||||||
xfs_set_maxicount(mp);
|
|
||||||
|
|
||||||
/* enable fail_at_unmount as default */
|
/* enable fail_at_unmount as default */
|
||||||
mp->m_fail_unmount = true;
|
mp->m_fail_unmount = true;
|
||||||
|
|
||||||
@@ -790,31 +739,6 @@ xfs_mountfs(
|
|||||||
/* set the low space thresholds for dynamic preallocation */
|
/* set the low space thresholds for dynamic preallocation */
|
||||||
xfs_set_low_space_thresholds(mp);
|
xfs_set_low_space_thresholds(mp);
|
||||||
|
|
||||||
/*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
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);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If enabled, sparse inode chunk alignment is expected to match the
|
* If enabled, sparse inode chunk alignment is expected to match the
|
||||||
* cluster size. Full inode chunk alignment must match the chunk size,
|
* cluster size. Full inode chunk alignment must match the chunk size,
|
||||||
@@ -831,11 +755,6 @@ xfs_mountfs(
|
|||||||
goto out_remove_uuid;
|
goto out_remove_uuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Set inode alignment fields
|
|
||||||
*/
|
|
||||||
xfs_set_inoalignment(mp);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check that the data (and log if separate) is an ok size.
|
* Check that the data (and log if separate) is an ok size.
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user