[PATCH 2.6.0-test6-mm1] aio ref count in io_submit_one updated

From: Daniel McNeil
Date: Wed Oct 01 2003 - 15:52:43 EST


On Wed, 2003-10-01 at 01:46, Suparna Bhattacharya wrote:

> I haven't looked very closely, but am just wondering why you ignore
> the return value of __aio_put_req here - are you sure there is no
> potential memory leakage (could be missing a put_ioctx) as a result ?


You are right. I didn't look closely enough. I thought the only
difference between aio_put_req() and __aio_put_req() was the lock
already being help. I missed the put_ioctx(). So here is the
updated patch. This also runs on my 2-proc with CONFIG_DEBUG_PAGEALLOC
without oops'ing.

I'm still looking at the retry case and I will send out a patch for
that when I'm done.

Thanks,

Daniel


--- linux-2.6.0-test6-mm1/fs/aio.c 2003-09-30 14:47:51.000000000 -0700
+++ linux-2.6.0-test6-mm1.aio/fs/aio.c 2003-10-01 13:42:25.091744710 -0700
@@ -1431,6 +1431,7 @@ int io_submit_one(struct kioctx *ctx, st
struct kiocb *req;
struct file *file;
ssize_t ret;
+ int need_putctx;

/* enforce forwards compatibility on users */
if (unlikely(iocb->aio_reserved1 || iocb->aio_reserved2 ||
@@ -1490,16 +1491,26 @@ int io_submit_one(struct kioctx *ctx, st
goto out_put_req;

spin_lock_irq(&ctx->ctx_lock);
+ /*
+ * Hold an extra reference while submitting the i/o.
+ * This prevents races between the aio code path referencing the
+ * req (after submitting it) and aio_complete() freeing the req.
+ */
+ req->ki_users++; /* grab extra reference */
ret = aio_run_iocb(req);
+ need_putctx = __aio_put_req(ctx, req); /* drop the extra reference */
spin_unlock_irq(&ctx->ctx_lock);

if (-EIOCBRETRY == ret)
queue_work(aio_wq, &ctx->wq);

+ if (need_putctx)
+ put_ioctx(ctx);
+
return 0;

out_put_req:
- aio_put_req(req);
+ (void)aio_put_req(req);
return ret;
}