@@ -349,6 +349,7 @@ xfs_map_blocks(
imap_valid = offset_fsb >= wpc->imap.br_startoff &&
offset_fsb < wpc->imap.br_startoff + wpc->imap.br_blockcount;
if (imap_valid &&
+ !WARN_ON_ONCE(wpc->imap.br_startblock == HOLESTARTBLOCK) &&
(!xfs_inode_has_cow_data(ip) ||
wpc->io_type == XFS_IO_COW ||
wpc->cow_seq == READ_ONCE(ip->i_cowfp->if_seq)))
@@ -454,8 +455,14 @@ xfs_map_blocks(
allocate_blocks:
error = xfs_iomap_write_allocate(ip, whichfork, offset, &imap,
&wpc->cow_seq);
- if (error)
+ if (error) {
+ if (error == -EAGAIN) {
+ /* we might have raced with truncate */
+ wpc->io_type = XFS_IO_HOLE;
+ error = 0;
+ }
return error;
+ }
ASSERT(whichfork == XFS_COW_FORK || cow_fsb == NULLFILEOFF ||
imap.br_startoff + imap.br_blockcount <= cow_fsb);
wpc->imap = imap;
-EAGAIN from xfs_iomap_write_allocate means that due to a racing truncate there is no actual mapping at this offset anymore, and we need to skip the block during writeback. Signed-off-by: Christoph Hellwig <hch@lst.de> --- fs/xfs/xfs_aops.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)