@@ -1758,6 +1758,64 @@ iomap_add_to_ioend(struct inode *inode, loff_t pos, struct folio *folio,
17581758 wbc_account_cgroup_owner (wbc , & folio -> page , len );
17591759}
17601760
1761+ /*
1762+ * Check interaction of the folio with the file end.
1763+ *
1764+ * If the folio is entirely beyond i_size, return false. If it straddles
1765+ * i_size, adjust end_pos and zero all data beyond i_size.
1766+ */
1767+ static bool iomap_writepage_handle_eof (struct folio * folio , struct inode * inode ,
1768+ u64 * end_pos )
1769+ {
1770+ u64 isize = i_size_read (inode );
1771+
1772+ if (* end_pos > isize ) {
1773+ size_t poff = offset_in_folio (folio , isize );
1774+ pgoff_t end_index = isize >> PAGE_SHIFT ;
1775+
1776+ /*
1777+ * If the folio is entirely ouside of i_size, skip it.
1778+ *
1779+ * This can happen due to a truncate operation that is in
1780+ * progress and in that case truncate will finish it off once
1781+ * we've dropped the folio lock.
1782+ *
1783+ * Note that the pgoff_t used for end_index is an unsigned long.
1784+ * If the given offset is greater than 16TB on a 32-bit system,
1785+ * then if we checked if the folio is fully outside i_size with
1786+ * "if (folio->index >= end_index + 1)", "end_index + 1" would
1787+ * overflow and evaluate to 0. Hence this folio would be
1788+ * redirtied and written out repeatedly, which would result in
1789+ * an infinite loop; the user program performing this operation
1790+ * would hang. Instead, we can detect this situation by
1791+ * checking if the folio is totally beyond i_size or if its
1792+ * offset is just equal to the EOF.
1793+ */
1794+ if (folio -> index > end_index ||
1795+ (folio -> index == end_index && poff == 0 ))
1796+ return false;
1797+
1798+ /*
1799+ * The folio straddles i_size.
1800+ *
1801+ * It must be zeroed out on each and every writepage invocation
1802+ * because it may be mmapped:
1803+ *
1804+ * A file is mapped in multiples of the page size. For a
1805+ * file that is not a multiple of the page size, the
1806+ * remaining memory is zeroed when mapped, and writes to that
1807+ * region are not written out to the file.
1808+ *
1809+ * Also adjust the writeback range to skip all blocks entirely
1810+ * beyond i_size.
1811+ */
1812+ folio_zero_segment (folio , poff , folio_size (folio ));
1813+ * end_pos = isize ;
1814+ }
1815+
1816+ return true;
1817+ }
1818+
17611819/*
17621820 * We implement an immediate ioend submission policy here to avoid needing to
17631821 * chain multiple ioends and hence nest mempool allocations which can violate
@@ -1898,78 +1956,16 @@ static int iomap_do_writepage(struct folio *folio,
18981956{
18991957 struct iomap_writepage_ctx * wpc = data ;
19001958 struct inode * inode = folio -> mapping -> host ;
1901- u64 end_pos , isize ;
1959+ u64 end_pos = folio_pos ( folio ) + folio_size ( folio ) ;
19021960
19031961 trace_iomap_writepage (inode , folio_pos (folio ), folio_size (folio ));
19041962
1905- /*
1906- * Is this folio beyond the end of the file?
1907- *
1908- * The folio index is less than the end_index, adjust the end_pos
1909- * to the highest offset that this folio should represent.
1910- * -----------------------------------------------------
1911- * | file mapping | <EOF> |
1912- * -----------------------------------------------------
1913- * | Page ... | Page N-2 | Page N-1 | Page N | |
1914- * ^--------------------------------^----------|--------
1915- * | desired writeback range | see else |
1916- * ---------------------------------^------------------|
1917- */
1918- isize = i_size_read (inode );
1919- end_pos = folio_pos (folio ) + folio_size (folio );
1920- if (end_pos > isize ) {
1921- /*
1922- * Check whether the page to write out is beyond or straddles
1923- * i_size or not.
1924- * -------------------------------------------------------
1925- * | file mapping | <EOF> |
1926- * -------------------------------------------------------
1927- * | Page ... | Page N-2 | Page N-1 | Page N | Beyond |
1928- * ^--------------------------------^-----------|---------
1929- * | | Straddles |
1930- * ---------------------------------^-----------|--------|
1931- */
1932- size_t poff = offset_in_folio (folio , isize );
1933- pgoff_t end_index = isize >> PAGE_SHIFT ;
1934-
1935- /*
1936- * Skip the page if it's fully outside i_size, e.g.
1937- * due to a truncate operation that's in progress. We've
1938- * cleaned this page and truncate will finish things off for
1939- * us.
1940- *
1941- * Note that the end_index is unsigned long. If the given
1942- * offset is greater than 16TB on a 32-bit system then if we
1943- * checked if the page is fully outside i_size with
1944- * "if (page->index >= end_index + 1)", "end_index + 1" would
1945- * overflow and evaluate to 0. Hence this page would be
1946- * redirtied and written out repeatedly, which would result in
1947- * an infinite loop; the user program performing this operation
1948- * would hang. Instead, we can detect this situation by
1949- * checking if the page is totally beyond i_size or if its
1950- * offset is just equal to the EOF.
1951- */
1952- if (folio -> index > end_index ||
1953- (folio -> index == end_index && poff == 0 ))
1954- goto unlock ;
1955-
1956- /*
1957- * The page straddles i_size. It must be zeroed out on each
1958- * and every writepage invocation because it may be mmapped.
1959- * "A file is mapped in multiples of the page size. For a file
1960- * that is not a multiple of the page size, the remaining
1961- * memory is zeroed when mapped, and writes to that region are
1962- * not written out to the file."
1963- */
1964- folio_zero_segment (folio , poff , folio_size (folio ));
1965- end_pos = isize ;
1963+ if (!iomap_writepage_handle_eof (folio , inode , & end_pos )) {
1964+ folio_unlock (folio );
1965+ return 0 ;
19661966 }
19671967
19681968 return iomap_writepage_map (wpc , wbc , inode , folio , end_pos );
1969-
1970- unlock :
1971- folio_unlock (folio );
1972- return 0 ;
19731969}
19741970
19751971int
0 commit comments