We recently used fuzz(hydra) to test XFS and automatically generate tmp.img(XFS v5 format, but some metadata is wrong) Test as follows: mount tmp.img tmpdir cp file1M tmpdir sync tmpdir/file1M size is 1M, but its data can not sync to disk. This is because tmp.img has some problems, using xfs_repair detect information as follows: agf_freeblks 0, counted 3224 in ag 0 agf_longest 536874136, counted 3224 in ag 0 sb_fdblocks 613, counted 3228 Add these agf freeblocks checks: 1. agf_longest < agf_freeblks 2. agf_freeblks < sb_fdblocks Signed-off-by: Zheng Bin <zhengbin13@xxxxxxxxxx> Signed-off-by: Ren Xudong <renxudong1@xxxxxxxxxx> --- fs/xfs/libxfs/xfs_alloc.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index d8053bc..0f4b4d1 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -2858,6 +2858,10 @@ xfs_agf_verify( be32_to_cpu(agf->agf_flcount) <= xfs_agfl_size(mp))) return __this_address; + if (be32_to_cpu(agf->agf_freeblks) < be32_to_cpu(agf->agf_longest) || + be32_to_cpu(agf->agf_freeblks) >= mp->m_sb.sb_fdblocks) + return __this_address; + if (be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]) < 1 || be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]) < 1 || be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]) > XFS_BTREE_MAXLEVELS || -- 2.7.4