From: Jens Axboe Signed-off-by: Jens Axboe Signed-off-by: Andrew Morton --- 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); _