From: Josef Bacik <jbacik@redhat.com> Date: Tue, 10 Feb 2009 13:49:32 -0500 Subject: [mm] fix infinite loop with iov_iter_advance Message-id: 1234291777-15344-20-git-send-email-jbacik@redhat.com O-Subject: [PATCH 19/24] [RHEL 5.4] mm: fix infinite loop with iov_iter_advance Bugzilla: 445433 RH-Acked-by: Jeff Layton <jlayton@redhat.com> This is a backport of upstream commit 124d3b7041f9a0ca7c43a6293e1cae4576c32fd5 and is in reference to bz 445433. This patch fixes an issue with iov_iter_advance where we don't properly handle zero length iovecs. Signed-off-by: Josef Bacik <jbacik@redhat.com> diff --git a/mm/filemap.c b/mm/filemap.c index a887f4d..53d78b5 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -1989,7 +1989,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; @@ -2513,6 +2517,7 @@ again: cond_resched(); + iov_iter_advance(i, copied); if (unlikely(copied == 0)) { /* * If we were unable to copy any data at all, we must @@ -2526,7 +2531,6 @@ again: iov_iter_single_seg_count(i)); goto again; } - iov_iter_advance(i, copied); pos += copied; written += copied;