@@ -1671,14 +1671,30 @@ static bool iomap_can_add_to_ioend(struct iomap_writepage_ctx *wpc, loff_t pos,
16711671 * At the end of a writeback pass, there will be a cached ioend remaining on the
16721672 * writepage context that the caller will need to submit.
16731673 */
1674- static int iomap_add_to_ioend (struct iomap_writepage_ctx * wpc ,
1675- struct folio * folio , loff_t pos , loff_t end_pos , unsigned len )
1674+ ssize_t iomap_add_to_ioend (struct iomap_writepage_ctx * wpc , struct folio * folio ,
1675+ loff_t pos , loff_t end_pos , unsigned int dirty_len )
16761676{
16771677 struct iomap_folio_state * ifs = folio -> private ;
16781678 size_t poff = offset_in_folio (folio , pos );
16791679 unsigned int ioend_flags = 0 ;
1680+ unsigned int map_len = min_t (u64 , dirty_len ,
1681+ wpc -> iomap .offset + wpc -> iomap .length - pos );
16801682 int error ;
16811683
1684+ trace_iomap_add_to_ioend (wpc -> inode , pos , dirty_len , & wpc -> iomap );
1685+
1686+ WARN_ON_ONCE (!folio -> private && map_len < dirty_len );
1687+
1688+ switch (wpc -> iomap .type ) {
1689+ case IOMAP_INLINE :
1690+ WARN_ON_ONCE (1 );
1691+ return - EIO ;
1692+ case IOMAP_HOLE :
1693+ return map_len ;
1694+ default :
1695+ break ;
1696+ }
1697+
16821698 if (wpc -> iomap .type == IOMAP_UNWRITTEN )
16831699 ioend_flags |= IOMAP_IOEND_UNWRITTEN ;
16841700 if (wpc -> iomap .flags & IOMAP_F_SHARED )
@@ -1696,11 +1712,11 @@ static int iomap_add_to_ioend(struct iomap_writepage_ctx *wpc,
16961712 wpc -> ioend = iomap_alloc_ioend (wpc , pos , ioend_flags );
16971713 }
16981714
1699- if (!bio_add_folio (& wpc -> ioend -> io_bio , folio , len , poff ))
1715+ if (!bio_add_folio (& wpc -> ioend -> io_bio , folio , map_len , poff ))
17001716 goto new_ioend ;
17011717
17021718 if (ifs )
1703- atomic_add (len , & ifs -> write_bytes_pending );
1719+ atomic_add (map_len , & ifs -> write_bytes_pending );
17041720
17051721 /*
17061722 * Clamp io_offset and io_size to the incore EOF so that ondisk
@@ -1743,63 +1759,39 @@ static int iomap_add_to_ioend(struct iomap_writepage_ctx *wpc,
17431759 * Note that this defeats the ability to chain the ioends of
17441760 * appending writes.
17451761 */
1746- wpc -> ioend -> io_size += len ;
1762+ wpc -> ioend -> io_size += map_len ;
17471763 if (wpc -> ioend -> io_offset + wpc -> ioend -> io_size > end_pos )
17481764 wpc -> ioend -> io_size = end_pos - wpc -> ioend -> io_offset ;
17491765
1750- wbc_account_cgroup_owner (wpc -> wbc , folio , len );
1751- return 0 ;
1766+ wbc_account_cgroup_owner (wpc -> wbc , folio , map_len );
1767+ return map_len ;
17521768}
1769+ EXPORT_SYMBOL_GPL (iomap_add_to_ioend );
17531770
1754- static int iomap_writepage_map_blocks (struct iomap_writepage_ctx * wpc ,
1755- struct folio * folio , u64 pos , u64 end_pos , unsigned dirty_len ,
1771+ static int iomap_writeback_range (struct iomap_writepage_ctx * wpc ,
1772+ struct folio * folio , u64 pos , u32 rlen , u64 end_pos ,
17561773 bool * wb_pending )
17571774{
1758- int error ;
1759-
17601775 do {
1761- unsigned map_len ;
1762-
1763- error = wpc -> ops -> map_blocks (wpc , wpc -> inode , pos , dirty_len );
1764- if (error )
1765- break ;
1766- trace_iomap_writepage_map (wpc -> inode , pos , dirty_len ,
1767- & wpc -> iomap );
1776+ ssize_t ret ;
17681777
1769- map_len = min_t (u64 , dirty_len ,
1770- wpc -> iomap .offset + wpc -> iomap .length - pos );
1771- WARN_ON_ONCE (!folio -> private && map_len < dirty_len );
1778+ ret = wpc -> ops -> writeback_range (wpc , folio , pos , rlen , end_pos );
1779+ if (WARN_ON_ONCE (ret == 0 || ret > rlen ))
1780+ return - EIO ;
1781+ if (ret < 0 )
1782+ return ret ;
1783+ rlen -= ret ;
1784+ pos += ret ;
17721785
1773- switch (wpc -> iomap .type ) {
1774- case IOMAP_INLINE :
1775- WARN_ON_ONCE (1 );
1776- error = - EIO ;
1777- break ;
1778- case IOMAP_HOLE :
1779- break ;
1780- default :
1781- error = iomap_add_to_ioend (wpc , folio , pos , end_pos ,
1782- map_len );
1783- if (!error )
1784- * wb_pending = true;
1785- break ;
1786- }
1787- dirty_len -= map_len ;
1788- pos += map_len ;
1789- } while (dirty_len && !error );
1786+ /*
1787+ * Holes are not be written back by ->writeback_range, so track
1788+ * if we did handle anything that is not a hole here.
1789+ */
1790+ if (wpc -> iomap .type != IOMAP_HOLE )
1791+ * wb_pending = true;
1792+ } while (rlen );
17901793
1791- /*
1792- * We cannot cancel the ioend directly here on error. We may have
1793- * already set other pages under writeback and hence we have to run I/O
1794- * completion to mark the error state of the pages under writeback
1795- * appropriately.
1796- *
1797- * Just let the file system know what portion of the folio failed to
1798- * map.
1799- */
1800- if (error && wpc -> ops -> discard_folio )
1801- wpc -> ops -> discard_folio (folio , pos );
1802- return error ;
1794+ return 0 ;
18031795}
18041796
18051797/*
@@ -1911,8 +1903,8 @@ static int iomap_writepage_map(struct iomap_writepage_ctx *wpc,
19111903 */
19121904 end_aligned = round_up (end_pos , i_blocksize (inode ));
19131905 while ((rlen = iomap_find_dirty_range (folio , & pos , end_aligned ))) {
1914- error = iomap_writepage_map_blocks (wpc , folio , pos , end_pos ,
1915- rlen , & wb_pending );
1906+ error = iomap_writeback_range (wpc , folio , pos , rlen , end_pos ,
1907+ & wb_pending );
19161908 if (error )
19171909 break ;
19181910 pos += rlen ;
0 commit comments