--- linux-2.6.10/fs/direct-io.c.orig 2005-03-03 12:41:05.541074051 +0100 +++ linux-2.6.10/fs/direct-io.c 2005-03-03 12:01:46.206210808 +0100 @@ -230,17 +230,30 @@ static void finished_one_bio(struct dio spin_lock_irqsave(&dio->bio_lock, flags); if (dio->bio_count == 1) { if (dio->is_async) { + ssize_t transferred; + ssize_t i_size; + loff_t offset; + /* * Last reference to the dio is going away. * Drop spinlock and complete the DIO. */ spin_unlock_irqrestore(&dio->bio_lock, flags); - dio_complete(dio, dio->block_in_file << dio->blkbits, - dio->result); + + /* Check for short read case */ + transferred = dio->result; + i_size = i_size_read (dio->inode); + offset = dio->iocb->ki_pos; + + if ((dio->rw == READ) && ((offset + transferred) > i_size)) + transferred = i_size - offset; + + dio_complete(dio, offset, transferred); + /* Complete AIO later if falling back to buffered i/o */ if (dio->result == dio->size || ((dio->rw == READ) && dio->result)) { - aio_complete(dio->iocb, dio->result, 0); + aio_complete(dio->iocb, transferred, 0); kfree(dio); return; } else {