while ((ret = iomap_iter(&iter, ops)) > 0) {
const struct iomap *srcmap = iomap_iter_srcmap(&iter);
- if (WARN_ON_ONCE((iter.iomap.flags & IOMAP_F_FOLIO_BATCH) &&
- srcmap->type != IOMAP_UNWRITTEN))
- return -EIO;
-
if (!(iter.iomap.flags & IOMAP_F_FOLIO_BATCH) &&
(srcmap->type == IOMAP_HOLE ||
srcmap->type == IOMAP_UNWRITTEN)) {
{
struct iomap_iter *iter = container_of(iomap, struct iomap_iter,
iomap);
- struct address_space *mapping = inode->i_mapping;
struct xfs_inode *ip = XFS_I(inode);
struct xfs_mount *mp = ip->i_mount;
xfs_fileoff_t offset_fsb = XFS_B_TO_FSBT(mp, offset);
if (error)
return error;
-restart:
error = xfs_ilock_for_iomap(ip, flags, &lockmode);
if (error)
return error;
/*
* We may need to zero over a hole in the data fork if it's fronted by
- * COW blocks and dirty pagecache. To make sure zeroing occurs, force
- * writeback to remap pending blocks and restart the lookup.
+ * COW blocks and dirty pagecache. Scan such file ranges for dirty
+ * cache and fill the iomap batch with folios that need zeroing.
*/
if ((flags & IOMAP_ZERO) && imap.br_startoff > offset_fsb) {
loff_t start, end;
xfs_trim_extent(&imap, offset_fsb,
cmap.br_startoff + cmap.br_blockcount - offset_fsb);
start = XFS_FSB_TO_B(mp, imap.br_startoff);
- end = XFS_FSB_TO_B(mp,
- imap.br_startoff + imap.br_blockcount) - 1;
- if (filemap_range_needs_writeback(mapping, start, end)) {
- xfs_iunlock(ip, lockmode);
- error = filemap_write_and_wait_range(mapping, start,
- end);
- if (error)
- return error;
- goto restart;
- }
+ end = XFS_FSB_TO_B(mp, imap.br_startoff + imap.br_blockcount);
+ iomap_fill_dirty_folios(iter, &start, end, &iomap_flags);
+ xfs_trim_extent(&imap, offset_fsb,
+ XFS_B_TO_FSB(mp, start) - offset_fsb);
goto found_imap;
}