|
Jiri Slaby |
2c66b1 |
From: Dave Chinner <dchinner@redhat.com>
|
|
Jiri Slaby |
2c66b1 |
Date: Thu, 27 Apr 2023 09:02:11 +1000
|
|
Jiri Slaby |
2c66b1 |
Subject: xfs: fix livelock in delayed allocation at ENOSPC
|
|
Jiri Slaby |
2c66b1 |
Git-commit: 9419092fb2630c30e4ffeb9ef61007ef0c61827a
|
|
Jiri Slaby |
2c66b1 |
Patch-mainline: 6.4-rc1
|
|
Jiri Slaby |
2c66b1 |
References: brc#2208553 xfs-issue
|
|
Jiri Slaby |
2c66b1 |
|
|
Jiri Slaby |
2c66b1 |
On a filesystem with a non-zero stripe unit and a large sequential
|
|
Jiri Slaby |
2c66b1 |
write, delayed allocation will set a minimum allocation length of
|
|
Jiri Slaby |
2c66b1 |
the stripe unit. If allocation fails because there are no extents
|
|
Jiri Slaby |
2c66b1 |
long enough for an aligned minlen allocation, it is supposed to
|
|
Jiri Slaby |
2c66b1 |
fall back to unaligned allocation which allows single block extents
|
|
Jiri Slaby |
2c66b1 |
to be allocated.
|
|
Jiri Slaby |
2c66b1 |
|
|
Jiri Slaby |
2c66b1 |
When the allocator code was rewritting in the 6.3 cycle, this
|
|
Jiri Slaby |
2c66b1 |
fallback was broken - the old code used args->fsbno as the both the
|
|
Jiri Slaby |
2c66b1 |
allocation target and the allocation result, the new code passes the
|
|
Jiri Slaby |
2c66b1 |
target as a separate parameter. The conversion didn't handle the
|
|
Jiri Slaby |
2c66b1 |
aligned->unaligned fallback path correctly - it reset args->fsbno to
|
|
Jiri Slaby |
2c66b1 |
the target fsbno on failure which broke allocation failure detection
|
|
Jiri Slaby |
2c66b1 |
in the high level code and so it never fell back to unaligned
|
|
Jiri Slaby |
2c66b1 |
allocations.
|
|
Jiri Slaby |
2c66b1 |
|
|
Jiri Slaby |
2c66b1 |
This resulted in a loop in writeback trying to allocate an aligned
|
|
Jiri Slaby |
2c66b1 |
block, getting a false positive success, trying to insert the result
|
|
Jiri Slaby |
2c66b1 |
in the BMBT. This did nothing because the extent already was in the
|
|
Jiri Slaby |
2c66b1 |
BMBT (merge results in an unchanged extent) and so it returned the
|
|
Jiri Slaby |
2c66b1 |
prior extent to the conversion code as the current iomap.
|
|
Jiri Slaby |
2c66b1 |
|
|
Jiri Slaby |
2c66b1 |
Because the iomap returned didn't cover the offset we tried to map,
|
|
Jiri Slaby |
2c66b1 |
xfs_convert_blocks() then retries the allocation, which fails in the
|
|
Jiri Slaby |
2c66b1 |
same way and now we have a livelock.
|
|
Jiri Slaby |
2c66b1 |
|
|
Jiri Slaby |
2c66b1 |
Reported-and-tested-by: Brian Foster <bfoster@redhat.com>
|
|
Jiri Slaby |
2c66b1 |
Fixes: 85843327094f ("xfs: factor xfs_bmap_btalloc()")
|
|
Jiri Slaby |
2c66b1 |
Signed-off-by: Dave Chinner <dchinner@redhat.com>
|
|
Jiri Slaby |
2c66b1 |
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
|
|
Jiri Slaby |
2c66b1 |
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
|
|
Jiri Slaby |
2c66b1 |
---
|
|
Jiri Slaby |
2c66b1 |
fs/xfs/libxfs/xfs_bmap.c | 1 -
|
|
Jiri Slaby |
2c66b1 |
1 file changed, 1 deletion(-)
|
|
Jiri Slaby |
2c66b1 |
|
|
Jiri Slaby |
2c66b1 |
--- a/fs/xfs/libxfs/xfs_bmap.c
|
|
Jiri Slaby |
2c66b1 |
+++ b/fs/xfs/libxfs/xfs_bmap.c
|
|
Jiri Slaby |
2c66b1 |
@@ -3505,7 +3505,6 @@ xfs_bmap_btalloc_at_eof(
|
|
Jiri Slaby |
2c66b1 |
* original non-aligned state so the caller can proceed on allocation
|
|
Jiri Slaby |
2c66b1 |
* failure as if this function was never called.
|
|
Jiri Slaby |
2c66b1 |
*/
|
|
Jiri Slaby |
2c66b1 |
- args->fsbno = ap->blkno;
|
|
Jiri Slaby |
2c66b1 |
args->alignment = 1;
|
|
Jiri Slaby |
2c66b1 |
return 0;
|
|
Jiri Slaby |
2c66b1 |
}
|