On Thu, Jun 16, 2016 at 06:20:32PM -0700, Darrick J. Wong wrote:
> From: Dave Chinner <dchinner@xxxxxxxxxx>
>
> XFS reserves a small amount of space in each AG for the minimum
> number of free blocks needed for operation. Adding the rmap btree
> increases the number of reserved blocks, but it also increases the
> complexity of the calculation as the free inode btree is optional
> (like the rmbt).
>
> Rather than calculate the prealloc blocks every time we need to
> check it, add a function to calculate it at mount time and store it
> in the struct xfs_mount, and convert the XFS_PREALLOC_BLOCKS macro
> just to use the xfs-mount variable directly.
>
> Signed-off-by: Dave Chinner <dchinner@xxxxxxxxxx>
> Signed-off-by: Dave Chinner <david@xxxxxxxxxxxxx>
> ---
Reviewed-by: Brian Foster <bfoster@xxxxxxxxxx>
> fs/xfs/libxfs/xfs_alloc.c | 11 +++++++++++
> fs/xfs/libxfs/xfs_alloc.h | 2 ++
> fs/xfs/libxfs/xfs_format.h | 9 +--------
> fs/xfs/xfs_fsops.c | 6 +++---
> fs/xfs/xfs_mount.c | 2 ++
> fs/xfs/xfs_mount.h | 1 +
> 6 files changed, 20 insertions(+), 11 deletions(-)
>
>
> diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c
> index b61e9c6..fb00042 100644
> --- a/fs/xfs/libxfs/xfs_alloc.c
> +++ b/fs/xfs/libxfs/xfs_alloc.c
> @@ -50,6 +50,17 @@ STATIC int xfs_alloc_ag_vextent_size(xfs_alloc_arg_t *);
> STATIC int xfs_alloc_ag_vextent_small(xfs_alloc_arg_t *,
> xfs_btree_cur_t *, xfs_agblock_t *, xfs_extlen_t *, int *);
>
> +xfs_extlen_t
> +xfs_prealloc_blocks(
> + struct xfs_mount *mp)
> +{
> + if (xfs_sb_version_hasrmapbt(&mp->m_sb))
> + return XFS_RMAP_BLOCK(mp) + 1;
> + if (xfs_sb_version_hasfinobt(&mp->m_sb))
> + return XFS_FIBT_BLOCK(mp) + 1;
> + return XFS_IBT_BLOCK(mp) + 1;
> +}
> +
> /*
> * Lookup the record equal to [bno, len] in the btree given by cur.
> */
> diff --git a/fs/xfs/libxfs/xfs_alloc.h b/fs/xfs/libxfs/xfs_alloc.h
> index cf268b2..20b54aa 100644
> --- a/fs/xfs/libxfs/xfs_alloc.h
> +++ b/fs/xfs/libxfs/xfs_alloc.h
> @@ -232,4 +232,6 @@ int xfs_alloc_fix_freelist(struct xfs_alloc_arg *args,
> int flags);
> int xfs_free_extent_fix_freelist(struct xfs_trans *tp, xfs_agnumber_t agno,
> struct xfs_buf **agbp);
>
> +xfs_extlen_t xfs_prealloc_blocks(struct xfs_mount *mp);
> +
> #endif /* __XFS_ALLOC_H__ */
> diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h
> index 8ca4a3d..b5b0901 100644
> --- a/fs/xfs/libxfs/xfs_format.h
> +++ b/fs/xfs/libxfs/xfs_format.h
> @@ -1318,18 +1318,11 @@ typedef __be32 xfs_inobt_ptr_t;
> */
> #define XFS_RMAP_CRC_MAGIC 0x524d4233 /* 'RMB3' */
>
> -/*
> - * The first data block of an AG depends on whether the filesystem was
> formatted
> - * with the finobt feature. If so, account for the finobt reserved root btree
> - * block.
> - */
> -#define XFS_PREALLOC_BLOCKS(mp) \
> +#define XFS_RMAP_BLOCK(mp) \
> (xfs_sb_version_hasfinobt(&((mp)->m_sb)) ? \
> XFS_FIBT_BLOCK(mp) + 1 : \
> XFS_IBT_BLOCK(mp) + 1)
>
> -
> -
> /*
> * BMAP Btree format definitions
> *
> diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c
> index 064fce1..62162d4 100644
> --- a/fs/xfs/xfs_fsops.c
> +++ b/fs/xfs/xfs_fsops.c
> @@ -243,7 +243,7 @@ xfs_growfs_data_private(
> agf->agf_flfirst = cpu_to_be32(1);
> agf->agf_fllast = 0;
> agf->agf_flcount = 0;
> - tmpsize = agsize - XFS_PREALLOC_BLOCKS(mp);
> + tmpsize = agsize - mp->m_ag_prealloc_blocks;
> agf->agf_freeblks = cpu_to_be32(tmpsize);
> agf->agf_longest = cpu_to_be32(tmpsize);
> if (xfs_sb_version_hascrc(&mp->m_sb))
> @@ -340,7 +340,7 @@ xfs_growfs_data_private(
> agno, 0);
>
> arec = XFS_ALLOC_REC_ADDR(mp, XFS_BUF_TO_BLOCK(bp), 1);
> - arec->ar_startblock = cpu_to_be32(XFS_PREALLOC_BLOCKS(mp));
> + arec->ar_startblock = cpu_to_be32(mp->m_ag_prealloc_blocks);
> arec->ar_blockcount = cpu_to_be32(
> agsize - be32_to_cpu(arec->ar_startblock));
>
> @@ -369,7 +369,7 @@ xfs_growfs_data_private(
> agno, 0);
>
> arec = XFS_ALLOC_REC_ADDR(mp, XFS_BUF_TO_BLOCK(bp), 1);
> - arec->ar_startblock = cpu_to_be32(XFS_PREALLOC_BLOCKS(mp));
> + arec->ar_startblock = cpu_to_be32(mp->m_ag_prealloc_blocks);
> arec->ar_blockcount = cpu_to_be32(
> agsize - be32_to_cpu(arec->ar_startblock));
> nfree += be32_to_cpu(arec->ar_blockcount);
> diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
> index bf63682..b4153f0 100644
> --- a/fs/xfs/xfs_mount.c
> +++ b/fs/xfs/xfs_mount.c
> @@ -231,6 +231,8 @@ xfs_initialize_perag(
>
> if (maxagi)
> *maxagi = index;
> +
> + mp->m_ag_prealloc_blocks = xfs_prealloc_blocks(mp);
> return 0;
>
> out_unwind:
> diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
> index c1b798c..0537b1f 100644
> --- a/fs/xfs/xfs_mount.h
> +++ b/fs/xfs/xfs_mount.h
> @@ -119,6 +119,7 @@ typedef struct xfs_mount {
> uint m_ag_maxlevels; /* XFS_AG_MAXLEVELS */
> uint m_bm_maxlevels[2]; /* XFS_BM_MAXLEVELS */
> uint m_in_maxlevels; /* max inobt btree levels. */
> + xfs_extlen_t m_ag_prealloc_blocks; /* reserved ag blocks */
> struct radix_tree_root m_perag_tree; /* per-ag accounting info */
> spinlock_t m_perag_lock; /* lock for m_perag_tree */
> struct mutex m_growlock; /* growfs mutex */
>
> _______________________________________________
> xfs mailing list
> xfs@xxxxxxxxxxx
> http://oss.sgi.com/mailman/listinfo/xfs
|