diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index 4906a4828d11..a43769b506f8 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c @@ -1588,6 +1588,37 @@ xfs_bmapi_reserve_delalloc( return error; } +static int +xfs_zoned_fill_srcmap( + struct xfs_inode *ip, + xfs_fileoff_t offset_fsb, + xfs_fileoff_t *end_fsb, + unsigned flags, + struct iomap *srcmap) +{ + struct xfs_bmbt_irec smap; + struct xfs_iext_cursor scur; + + if (!xfs_iext_lookup_extent(ip, &ip->i_df, offset_fsb, &scur, &smap)) + smap.br_startoff = *end_fsb; /* fake hole until EOF */ + if (smap.br_startoff > offset_fsb) { + /* + * There is a hole at @offset_fsb. Only map until the end of + * the of it. + */ + *end_fsb = min(*end_fsb, smap.br_startoff); + return 0; + } + + /* + * There is a data fork mapping, only map until the end of it. + */ + *end_fsb = min(*end_fsb, smap.br_startoff + smap.br_blockcount); + xfs_trim_extent(&smap, offset_fsb, *end_fsb - offset_fsb); + return xfs_bmbt_to_iomap(ip, srcmap, &smap, flags, 0, + xfs_iomap_inode_sequence(ip, 0)); +} + static int xfs_zoned_buffered_write_iomap_begin( struct inode *inode, @@ -1655,24 +1686,10 @@ xfs_zoned_buffered_write_iomap_begin( if (!IS_ALIGNED(offset, mp->m_sb.sb_blocksize) || !IS_ALIGNED(offset + count, mp->m_sb.sb_blocksize) || (flags & IOMAP_ZERO)) { - struct xfs_bmbt_irec smap; - struct xfs_iext_cursor scur; - - if (!xfs_iext_lookup_extent(ip, &ip->i_df, offset_fsb, &scur, - &smap)) - smap.br_startoff = end_fsb; /* fake hole until EOF */ - if (smap.br_startoff > offset_fsb) { - end_fsb = min(end_fsb, smap.br_startoff); - } else { - end_fsb = min(end_fsb, - smap.br_startoff + smap.br_blockcount); - xfs_trim_extent(&smap, offset_fsb, - end_fsb - offset_fsb); - error = xfs_bmbt_to_iomap(ip, srcmap, &smap, flags, 0, - xfs_iomap_inode_sequence(ip, 0)); - if (error) - goto out_unlock; - } + error = xfs_zoned_fill_srcmap(ip, offset_fsb, &end_fsb, flags, + srcmap); + if (error) + goto out_unlock; } if (!ip->i_cowfp)