Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 27922b4260f65d317aabda37e42bbbff > files > 2198

kernel-2.6.18-238.el5.src.rpm

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;