@@ -1668,14 +1668,30 @@ static bool iomap_can_add_to_ioend(struct iomap_writepage_ctx *wpc, loff_t pos,
16681668 * At the end of a writeback pass, there will be a cached ioend remaining on the
16691669 * writepage context that the caller will need to submit.
16701670 */
1671- static int iomap_add_to_ioend (struct iomap_writepage_ctx * wpc ,
1672- struct folio * folio , loff_t pos , loff_t end_pos , unsigned len )
1671+ ssize_t iomap_add_to_ioend (struct iomap_writepage_ctx * wpc , struct folio * folio ,
1672+ loff_t pos , loff_t end_pos , unsigned int dirty_len )
16731673{
16741674 struct iomap_folio_state * ifs = folio -> private ;
16751675 size_t poff = offset_in_folio (folio , pos );
16761676 unsigned int ioend_flags = 0 ;
1677+ unsigned int map_len = min_t (u64 , dirty_len ,
1678+ wpc -> iomap .offset + wpc -> iomap .length - pos );
16771679 int error ;
16781680
1681+ trace_iomap_add_to_ioend (wpc -> inode , pos , dirty_len , & wpc -> iomap );
1682+
1683+ WARN_ON_ONCE (!folio -> private && map_len < dirty_len );
1684+
1685+ switch (wpc -> iomap .type ) {
1686+ case IOMAP_INLINE :
1687+ WARN_ON_ONCE (1 );
1688+ return - EIO ;
1689+ case IOMAP_HOLE :
1690+ return map_len ;
1691+ default :
1692+ break ;
1693+ }
1694+
16791695 if (wpc -> iomap .type == IOMAP_UNWRITTEN )
16801696 ioend_flags |= IOMAP_IOEND_UNWRITTEN ;
16811697 if (wpc -> iomap .flags & IOMAP_F_SHARED )
@@ -1693,11 +1709,11 @@ static int iomap_add_to_ioend(struct iomap_writepage_ctx *wpc,
16931709 wpc -> ioend = iomap_alloc_ioend (wpc , pos , ioend_flags );
16941710 }
16951711
1696- if (!bio_add_folio (& wpc -> ioend -> io_bio , folio , len , poff ))
1712+ if (!bio_add_folio (& wpc -> ioend -> io_bio , folio , map_len , poff ))
16971713 goto new_ioend ;
16981714
16991715 if (ifs )
1700- atomic_add (len , & ifs -> write_bytes_pending );
1716+ atomic_add (map_len , & ifs -> write_bytes_pending );
17011717
17021718 /*
17031719 * Clamp io_offset and io_size to the incore EOF so that ondisk
@@ -1740,63 +1756,39 @@ static int iomap_add_to_ioend(struct iomap_writepage_ctx *wpc,
17401756 * Note that this defeats the ability to chain the ioends of
17411757 * appending writes.
17421758 */
1743- wpc -> ioend -> io_size += len ;
1759+ wpc -> ioend -> io_size += map_len ;
17441760 if (wpc -> ioend -> io_offset + wpc -> ioend -> io_size > end_pos )
17451761 wpc -> ioend -> io_size = end_pos - wpc -> ioend -> io_offset ;
17461762
1747- wbc_account_cgroup_owner (wpc -> wbc , folio , len );
1748- return 0 ;
1763+ wbc_account_cgroup_owner (wpc -> wbc , folio , map_len );
1764+ return map_len ;
17491765}
1766+ EXPORT_SYMBOL_GPL (iomap_add_to_ioend );
17501767
1751- static int iomap_writepage_map_blocks (struct iomap_writepage_ctx * wpc ,
1752- struct folio * folio , u64 pos , u64 end_pos , unsigned dirty_len ,
1768+ static int iomap_writeback_range (struct iomap_writepage_ctx * wpc ,
1769+ struct folio * folio , u64 pos , u32 rlen , u64 end_pos ,
17531770 bool * wb_pending )
17541771{
1755- int error ;
1756-
17571772 do {
1758- unsigned map_len ;
1759-
1760- error = wpc -> ops -> map_blocks (wpc , wpc -> inode , pos , dirty_len );
1761- if (error )
1762- break ;
1763- trace_iomap_writepage_map (wpc -> inode , pos , dirty_len ,
1764- & wpc -> iomap );
1773+ ssize_t ret ;
17651774
1766- map_len = min_t (u64 , dirty_len ,
1767- wpc -> iomap .offset + wpc -> iomap .length - pos );
1768- WARN_ON_ONCE (!folio -> private && map_len < dirty_len );
1775+ ret = wpc -> ops -> writeback_range (wpc , folio , pos , rlen , end_pos );
1776+ if (WARN_ON_ONCE (ret == 0 || ret > rlen ))
1777+ return - EIO ;
1778+ if (ret < 0 )
1779+ return ret ;
1780+ rlen -= ret ;
1781+ pos += ret ;
17691782
1770- switch (wpc -> iomap .type ) {
1771- case IOMAP_INLINE :
1772- WARN_ON_ONCE (1 );
1773- error = - EIO ;
1774- break ;
1775- case IOMAP_HOLE :
1776- break ;
1777- default :
1778- error = iomap_add_to_ioend (wpc , folio , pos , end_pos ,
1779- map_len );
1780- if (!error )
1781- * wb_pending = true;
1782- break ;
1783- }
1784- dirty_len -= map_len ;
1785- pos += map_len ;
1786- } while (dirty_len && !error );
1783+ /*
1784+ * Holes are not be written back by ->writeback_range, so track
1785+ * if we did handle anything that is not a hole here.
1786+ */
1787+ if (wpc -> iomap .type != IOMAP_HOLE )
1788+ * wb_pending = true;
1789+ } while (rlen );
17871790
1788- /*
1789- * We cannot cancel the ioend directly here on error. We may have
1790- * already set other pages under writeback and hence we have to run I/O
1791- * completion to mark the error state of the pages under writeback
1792- * appropriately.
1793- *
1794- * Just let the file system know what portion of the folio failed to
1795- * map.
1796- */
1797- if (error && wpc -> ops -> discard_folio )
1798- wpc -> ops -> discard_folio (folio , pos );
1799- return error ;
1791+ return 0 ;
18001792}
18011793
18021794/*
@@ -1908,8 +1900,8 @@ static int iomap_writepage_map(struct iomap_writepage_ctx *wpc,
19081900 */
19091901 end_aligned = round_up (end_pos , i_blocksize (inode ));
19101902 while ((rlen = iomap_find_dirty_range (folio , & pos , end_aligned ))) {
1911- error = iomap_writepage_map_blocks (wpc , folio , pos , end_pos ,
1912- rlen , & wb_pending );
1903+ error = iomap_writeback_range (wpc , folio , pos , rlen , end_pos ,
1904+ & wb_pending );
19131905 if (error )
19141906 break ;
19151907 pos += rlen ;
0 commit comments