From: Daniel McNeil Here is the patch for AIO retry to hold an extra ref count. The patch is small, but I wanted to make sure it was safe. I spent time looking over the retry code and this patch looks ok to me. It is potentially calling put_ioctx() while holding ctx->ctx_lock, I do not think that will cause any problems. This should never be the last reference on the ioctx anyway, since the loop is checking list_empty(&ctx->run_list). The first ref is taken in sys_io_setup() and last removed in io_destroy(). It also looks like holding ctx->ctx_lock prevents any races between any retries and an io_destroy() which would try to cancel all iocbs. I've tested this on my 2-proc by coping a raw partitions and copying ext3 files using using AIO and O_DIRECT, O_SYNC, and both. 25-akpm/fs/aio.c | 9 +++++++-- 1 files changed, 7 insertions(+), 2 deletions(-) diff -puN fs/aio.c~aio-retry-elevated-refcount fs/aio.c --- 25/fs/aio.c~aio-retry-elevated-refcount Mon Oct 13 14:26:02 2003 +++ 25-akpm/fs/aio.c Mon Oct 13 14:26:02 2003 @@ -765,14 +765,19 @@ out: static void __aio_run_iocbs(struct kioctx *ctx) { struct kiocb *iocb; - ssize_t ret; int count = 0; while (!list_empty(&ctx->run_list)) { iocb = list_entry(ctx->run_list.next, struct kiocb, ki_run_list); list_del(&iocb->ki_run_list); - ret = aio_run_iocb(iocb); + /* + * Hold an extra reference while retrying i/o. + */ + iocb->ki_users++; /* grab extra reference */ + aio_run_iocb(iocb); + if (__aio_put_req(ctx, iocb)) /* drop extra ref */ + put_ioctx(ctx); count++; } aio_run++; _