From: Daniel McNeil An AIO O_DIRECT request was extending the file so it was done synchronously. However, the request got an EFAULT and direct_io_worker() was calling aio_complete() on the iocb and returning the EFAULT. When io_submit_one() got the EFAULT return, it assume it had to call aio_complete() since the i/o never got queued. The fix is for direct_io_worker() to only call aio_complete() when the upper layer is going to return -EIOCBQUEUED and not when getting errors that are being return to the submit path. --- fs/direct-io.c | 8 ++++++-- 1 files changed, 6 insertions(+), 2 deletions(-) diff -puN fs/direct-io.c~aio-direct-io-oops-fix fs/direct-io.c --- 25/fs/direct-io.c~aio-direct-io-oops-fix 2004-03-08 23:30:43.000000000 -0800 +++ 25-akpm/fs/direct-io.c 2004-03-08 23:30:43.000000000 -0800 @@ -1076,8 +1076,12 @@ direct_io_worker(int rw, struct kiocb *i } dio_complete(dio, offset, ret); /* We could have also come here on an AIO file extend */ - if (!is_sync_kiocb(iocb) && !(rw == WRITE && ret >= 0 && - dio->result < dio->size)) + if (!is_sync_kiocb(iocb) && rw == WRITE && + ret >= 0 && dio->result == dio->size) + /* + * For AIO writes where we have completed the + * i/o, we have to mark the the aio complete. + */ aio_complete(iocb, ret, 0); kfree(dio); } _