On Thu, Feb 13, 2020 at 05:53:59PM +0800, Zheng Bin wrote: > 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 Uh... what problem did you encounter? Did block allocation loop forever? Did errors come pouring out of dmesg? Did other strange behaviors erupt? What is the smallest number of steps needed to go from a fresh format to ... whatever went wrong here? That's what this commit message ought to capture. :) --D > 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 >