From: Jens Axboe <axboe@suse.de>

Signed-off-by: Jens Axboe <axboe@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/fs/direct-io.c |   17 ++++++++++++-----
 1 files changed, 12 insertions(+), 5 deletions(-)

diff -puN fs/direct-io.c~o_direct-fix-again fs/direct-io.c
--- 25/fs/direct-io.c~o_direct-fix-again	Wed Nov  3 16:01:13 2004
+++ 25-akpm/fs/direct-io.c	Wed Nov  3 16:01:13 2004
@@ -987,12 +987,16 @@ direct_io_worker(int rw, struct kiocb *i
 	}
 
 	isize = i_size_read(inode);
-	if (bytes_todo > (isize - offset))
-		bytes_todo = isize - offset;
-	if (!bytes_todo)
-		return 0;
+	if (bytes_todo > (isize - offset)) {
+		if ((isize - offset))
+			bytes_todo = isize - offset;
+		else if (bytes_todo > PAGE_SIZE)
+			bytes_todo = PAGE_SIZE;
+	}
 
 	for (seg = 0; seg < nr_segs && bytes_todo; seg++) {
+		size_t bytes_done;
+
 		user_addr = (unsigned long)iov[seg].iov_base;
 		bytes = iov[seg].iov_len;
 		if (bytes > bytes_todo)
@@ -1010,16 +1014,19 @@ direct_io_worker(int rw, struct kiocb *i
 		dio->curr_page = 0;
 
 		dio->total_pages = 0;
+		bytes_done = bytes;
 		if (user_addr & (PAGE_SIZE-1)) {
 			dio->total_pages++;
+			bytes_done = bytes;
 			bytes -= PAGE_SIZE - (user_addr & (PAGE_SIZE - 1));
 		}
+
 		dio->total_pages += (bytes + PAGE_SIZE - 1) / PAGE_SIZE;
 		dio->curr_user_address = user_addr;
 	
 		ret = do_direct_IO(dio);
 
-		dio->result += bytes -
+		dio->result += bytes_done -
 			((dio->final_block_in_request - dio->block_in_file) <<
 					blkbits);
 
_