On Monday 9 November 2020 11:47:58 PM IST Darrick J. Wong wrote: > From: Darrick J. Wong <darrick.wong@xxxxxxxxxx> > > Teach the directory scrubber to check all the bestfree entries, > including the null ones. We want to be able to detect the case where > the entry is null but there actually /is/ a directory data block. > > Found by fuzzing lbests[0] = ones in xfs/391. > Looks good to me. Reviewed-by: Chandan Babu R <chandanrlinux@xxxxxxxxx> > Fixes: df481968f33b ("xfs: scrub directory freespace") > Signed-off-by: Darrick J. Wong <darrick.wong@xxxxxxxxxx> > --- > fs/xfs/scrub/dir.c | 27 ++++++++++++++++++++------- > 1 file changed, 20 insertions(+), 7 deletions(-) > > > diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c > index 7c432997edad..b045e95c2ea7 100644 > --- a/fs/xfs/scrub/dir.c > +++ b/fs/xfs/scrub/dir.c > @@ -558,14 +558,27 @@ xchk_directory_leaf1_bestfree( > /* Check all the bestfree entries. */ > for (i = 0; i < bestcount; i++, bestp++) { > best = be16_to_cpu(*bestp); > + error = xfs_dir3_data_read(sc->tp, sc->ip, > + xfs_dir2_db_to_da(args->geo, i), > + XFS_DABUF_MAP_HOLE_OK, > + &dbp); > + if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, lblk, > + &error)) > + break; > + > + if (!dbp) { > + if (best != NULLDATAOFF) { > + xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, > + lblk); > + break; > + } > + continue; > + } > + > if (best == NULLDATAOFF) > - continue; > - error = xfs_dir3_data_read(sc->tp, sc->ip, > - i * args->geo->fsbcount, 0, &dbp); > - if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, lblk, > - &error)) > - break; > - xchk_directory_check_freesp(sc, lblk, dbp, best); > + xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); > + else > + xchk_directory_check_freesp(sc, lblk, dbp, best); > xfs_trans_brelse(sc->tp, dbp); > if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) > break; > > -- chandan