On Sat, Apr 22, 2023 at 08:24:40AM +1000, Dave Chinner wrote: > From: Dave Chinner <dchinner@xxxxxxxxxx> > > On a filesystem with a non-zero stripe unit and a large sequential > write, delayed allocation will set a minimum allocation length of > the stripe unit. If allocation fails because there are no extents > long enough for an aligned minlen allocation, it is supposed to > fall back to unaligned allocation which allows single block extents > to be allocated. > > When the allocator code was rewritting in the 6.3 cycle, this > fallback was broken - the old code used args->fsbno as the both the > allocation target and the allocation result, the new code passes the > target as a separate parameter. The conversion didn't handle the > aligned->unaligned fallback path correctly - it reset args->fsbno to > the target fsbno on failure which broke allocation failure detection > in the high level code and so it never fell back to unaligned > allocations. > > This resulted in a loop in writeback trying to allocate an aligned > block, getting a false positive success, trying to insert the result > in the BMBT. This did nothing because the extent already was in the > BMBT (merge results in an unchanged extent) and so it returned the > prior extent to the conversion code as the current iomap. > > Because the iomap returned didn't cover the offset we tried to map, > xfs_convert_blocks() then retries the allocation, which fails in the > same way and now we have a livelock. > > Reported-by: Brian Foster <bfoster@xxxxxxxxxx> > Fixes: 85843327094f ("xfs: factor xfs_bmap_btalloc()") > Signed-off-by: Dave Chinner <dchinner@xxxxxxxxxx> > --- Problem solved, thanks. FWIW: Tested-by: Brian Foster <bfoster@xxxxxxxxxx> > fs/xfs/libxfs/xfs_bmap.c | 1 - > 1 file changed, 1 deletion(-) > > diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c > index 1a4e446194dd..b512de0540d5 100644 > --- a/fs/xfs/libxfs/xfs_bmap.c > +++ b/fs/xfs/libxfs/xfs_bmap.c > @@ -3540,7 +3540,6 @@ xfs_bmap_btalloc_at_eof( > * original non-aligned state so the caller can proceed on allocation > * failure as if this function was never called. > */ > - args->fsbno = ap->blkno; > args->alignment = 1; > return 0; > } > -- > 2.39.2 >