xfs: Introduce a helper to check if an AG is empty or not
PATCH 11/15 xfs: Introduce a helper to check if an AG is empty or not
We need to check if an affected AG is empty or not during FS shrink, this is a helper could be used for this purpose.
Maybe it's better to isolate AG related routines to a dedicated file: xfs_ag.c?
Signed-off-by Jie Liu <[email protected]>
--- fs/xfs/xfs_fsops.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 92 insertions(+), 0 deletions(-)
fs/xfs/xfs_fsops.c +92 -0
@@ -614,6 +614,98 @@ xfs_growfs_log( }/* +* Get the reserved blocks of metadatas per AG which are includes: +* Superblock (1 sector) +* AG free block info (1 sector) +* AG inode B+tree info (1 sector) +* AG internal free list (1 sector) +* Root of inode B+tree (1 block) +* Root of free space B+tree, key is block number (1 block) +* Root of free space B+tree, key is block count (1 block) +* Free list (4 blocks) +* The reserved block number of the aboves can be fetched via: +* XFS_PREALLOC_BLOCKS(mp). +* +* The left blocks are used for Primary AG only. +* - Inodes (64 inodes) +*/ +static xfs_extlen_t +xfs_ag_metadata_blocks ( +xfs_mount_t *mp, +xfs_agnumber_t agno) +{ +xfs_extlen_t mdblocks; + + mdblocks =XFS_PREALLOC_BLOCKS (mp); +/* +* For primary AG, we need to figure out how many blocks are +* reserved for those 64 inodes which are used for the root +* of inodes B+tree. +*/ +if (agno ==0 ) + mdblocks += (64 / mp->m_sb.sb_inopblock); + +return mdblocks; +} + +/* +* An empty AG means that there has no data/inodes allocated +* at it except those metadata blocks, and the agi_count should +* be ZERO. +*/ +static int +xfs_ag_is_empty ( +xfs_mount_t *mp, +xfs_agnumber_t agno, +bool *empty) +{ +xfs_extlen_t agblocks; +xfs_extlen_t agfblocks; +xfs_extlen_t agmblocks; +xfs_extlen_t agicount; +xfs_agf_t *agf; +xfs_agi_t *agi; +xfs_buf_t *bp; +int error =0 ; + + bp =xfs_buf_get (mp->m_ddev_targp, +XFS_AG_DADDR (mp, agno,XFS_AGF_DADDR (mp)), +XFS_FSS_TO_BB (mp,1 ),0 ); +if (!bp) { + error =XFS_ERROR (ENOMEM ); + goto error0; + } + agf =XFS_BUF_TO_AGF (bp); + agmblocks =xfs_ag_metadata_blocks (mp, agno); +/* +* The latest AG might has different size to others. +*/ +if (agno == mp->m_sb.sb_agcount -1 ) + agblocks = (be32_to_cpu (agf->agf_length) - agmblocks); +else + agblocks = mp->m_sb.sb_agblocks - agmblocks; + agfblocks =be32_to_cpu (agf->agf_freeblks); +xfs_buf_relse (bp); + + bp =xfs_buf_get (mp->m_ddev_targp, +XFS_AG_DADDR (mp, agno,XFS_AGI_DADDR (mp)), +XFS_FSS_TO_BB (mp,1 ),0 ); +if (!bp) { + error =XFS_ERROR (ENOMEM ); + goto error0; + } + agi =XFS_BUF_TO_AGI (bp); + agicount =be32_to_cpu (agi->agi_count); +xfs_buf_relse (bp); + + *empty = ((agblocks == agfblocks && agicount ==0 ) ? + true : false); + +error0: +return error; +} + +/* * exported through ioctl XFS_IOC_FSCOUNTS */
Signature · 6 lines
1.7.4.1 _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs