summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2023-10-21 09:43:09 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2023-10-21 09:43:09 -0700
commit5722119f674d81eb88d51463ece8096855d94cc0 (patch)
treecddbf76e55fa69fa820398c71943e0a847afb1b1
parent9c5d00cb7b6bbc5a7965d9ab7d223b5402d1f02c (diff)
parent3ac974796e5d94509b85a403449132ea660127c2 (diff)
Merge tag 'iomap-6.6-fixes-5' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux
Pull iomap fix from Darrick Wong: - Fix a bug where a writev consisting of a bunch of sub-fsblock writes where the last buffer address is invalid could lead to an infinite loop * tag 'iomap-6.6-fixes-5' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux: iomap: fix short copy in iomap_write_iter()
-rw-r--r--fs/iomap/buffered-io.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c
index 5db54ca29a35..2bc0aa23fde3 100644
--- a/fs/iomap/buffered-io.c
+++ b/fs/iomap/buffered-io.c
@@ -881,8 +881,10 @@ static loff_t iomap_write_iter(struct iomap_iter *iter, struct iov_iter *i)
size_t bytes; /* Bytes to write to folio */
size_t copied; /* Bytes copied from user */
+ bytes = iov_iter_count(i);
+retry:
offset = pos & (chunk - 1);
- bytes = min(chunk - offset, iov_iter_count(i));
+ bytes = min(chunk - offset, bytes);
status = balance_dirty_pages_ratelimited_flags(mapping,
bdp_flags);
if (unlikely(status))
@@ -933,10 +935,12 @@ static loff_t iomap_write_iter(struct iomap_iter *iter, struct iov_iter *i)
* halfway through, might be a race with munmap,
* might be severe memory pressure.
*/
- if (copied)
- bytes = copied;
if (chunk > PAGE_SIZE)
chunk /= 2;
+ if (copied) {
+ bytes = copied;
+ goto retry;
+ }
} else {
pos += status;
written += status;