diff --git a/mm/filemap.c b/mm/filemap.c index 89ce6fe5f8be..76bea88cbebc 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -1750,7 +1750,11 @@ static void __iov_iter_advance_iov(struct iov_iter *i, size_t bytes) const struct iovec *iov = i->iov; size_t base = i->iov_offset; - while (bytes) { + /* + * The !iov->iov_len check ensures we skip over unlikely + * zero-length segments. + */ + while (bytes || !iov->iov_len) { int copy = min(bytes, iov->iov_len - base); bytes -= copy; @@ -2268,6 +2272,7 @@ static ssize_t generic_perform_write(struct file *file, cond_resched(); + iov_iter_advance(i, copied); if (unlikely(copied == 0)) { /* * If we were unable to copy any data at all, we must @@ -2281,7 +2286,6 @@ static ssize_t generic_perform_write(struct file *file, iov_iter_single_seg_count(i)); goto again; } - iov_iter_advance(i, copied); pos += copied; written += copied;