Commit 8642174b authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'iomap-5.19-merge-2' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux

Pull iomap updates from Darrick Wong:
 "There's a couple of corrections sent in by Andreas for some accounting
  errors.

  The biggest change this time around is that writeback errors longer
  clear pageuptodate nor does XFS invalidate the page cache anymore.
  This brings XFS (and gfs2/zonefs) behavior in line with every other
  Linux filesystem driver, and fixes some UAF bugs that only cropped up
  after willy turned on multipage folios for XFS in 5.18-rc1.

  Regrettably, it took all the way to the end of the 5.18 cycle to find
  the source of these bugs and reach a consensus that XFS' writeback
  failure behavior from 20 years ago is no longer necessary.

  Summary:

   - Fix a couple of accounting errors in the buffered io code.

   - Discontinue the practice of marking folios !uptodate and
     invalidating them when writeback fails.

     This fixes some UAF bugs when multipage folios are enabled, and
     brings the behavior of XFS/gfs/zonefs into alignment with the
     behavior of all the other Linux filesystems"

* tag 'iomap-5.19-merge-2' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux:
  iomap: don't invalidate folios after writeback errors
  iomap: iomap_write_end cleanup
  iomap: iomap_write_failed fix
parents f2898112 e9c3a8e8
...@@ -531,7 +531,8 @@ iomap_write_failed(struct inode *inode, loff_t pos, unsigned len) ...@@ -531,7 +531,8 @@ iomap_write_failed(struct inode *inode, loff_t pos, unsigned len)
* write started inside the existing inode size. * write started inside the existing inode size.
*/ */
if (pos + len > i_size) if (pos + len > i_size)
truncate_pagecache_range(inode, max(pos, i_size), pos + len); truncate_pagecache_range(inode, max(pos, i_size),
pos + len - 1);
} }
static int iomap_read_folio_sync(loff_t block_start, struct folio *folio, static int iomap_read_folio_sync(loff_t block_start, struct folio *folio,
...@@ -733,7 +734,7 @@ static size_t iomap_write_end(struct iomap_iter *iter, loff_t pos, size_t len, ...@@ -733,7 +734,7 @@ static size_t iomap_write_end(struct iomap_iter *iter, loff_t pos, size_t len,
folio_put(folio); folio_put(folio);
if (ret < len) if (ret < len)
iomap_write_failed(iter->inode, pos, len); iomap_write_failed(iter->inode, pos + ret, len - ret);
return ret; return ret;
} }
...@@ -1386,7 +1387,6 @@ iomap_writepage_map(struct iomap_writepage_ctx *wpc, ...@@ -1386,7 +1387,6 @@ iomap_writepage_map(struct iomap_writepage_ctx *wpc,
if (wpc->ops->discard_folio) if (wpc->ops->discard_folio)
wpc->ops->discard_folio(folio, pos); wpc->ops->discard_folio(folio, pos);
if (!count) { if (!count) {
folio_clear_uptodate(folio);
folio_unlock(folio); folio_unlock(folio);
goto done; goto done;
} }
......
...@@ -464,7 +464,7 @@ xfs_discard_folio( ...@@ -464,7 +464,7 @@ xfs_discard_folio(
int error; int error;
if (xfs_is_shutdown(mp)) if (xfs_is_shutdown(mp))
goto out_invalidate; return;
xfs_alert_ratelimited(mp, xfs_alert_ratelimited(mp,
"page discard on page "PTR_FMT", inode 0x%llx, pos %llu.", "page discard on page "PTR_FMT", inode 0x%llx, pos %llu.",
...@@ -474,8 +474,6 @@ xfs_discard_folio( ...@@ -474,8 +474,6 @@ xfs_discard_folio(
i_blocks_per_folio(inode, folio) - pageoff_fsb); i_blocks_per_folio(inode, folio) - pageoff_fsb);
if (error && !xfs_is_shutdown(mp)) if (error && !xfs_is_shutdown(mp))
xfs_alert(mp, "page discard unable to remove delalloc mapping."); xfs_alert(mp, "page discard unable to remove delalloc mapping.");
out_invalidate:
iomap_invalidate_folio(folio, offset, folio_size(folio) - offset);
} }
static const struct iomap_writeback_ops xfs_writeback_ops = { static const struct iomap_writeback_ops xfs_writeback_ops = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment