On Mon, May 28, 2018 at 06:57:02PM +0100, Al Viro wrote: > From: Al Viro <viro@xxxxxxxxxxxxxxxxxx> > > We really want iocb out of io_cancel(2) reach before we start tearing > it down. A little helper would be useful, better naming for it welcome: diff --git a/fs/aio.c b/fs/aio.c index f95b167801c2..ae5977563b7e 100644 --- a/fs/aio.c +++ b/fs/aio.c @@ -1390,18 +1390,22 @@ SYSCALL_DEFINE1(io_destroy, aio_context_t, ctx) return -EINVAL; } +static void aio_remove_iocb(struct aio_kiocb *iocb) +{ + struct kioctx *ctx = iocb->ki_ctx; + unsigned long flags; + + spin_lock_irqsave(&ctx->ctx_lock, flags); + list_del(&iocb->ki_list); + spin_unlock_irqrestore(&ctx->ctx_lock, flags); +} + static void aio_complete_rw(struct kiocb *kiocb, long res, long res2) { struct aio_kiocb *iocb = container_of(kiocb, struct aio_kiocb, rw); - if (!list_empty_careful(&iocb->ki_list)) { - struct kioctx *ctx = iocb->ki_ctx; - unsigned long flags; - - spin_lock_irqsave(&ctx->ctx_lock, flags); - list_del(&iocb->ki_list); - spin_unlock_irqrestore(&ctx->ctx_lock, flags); - } + if (!list_empty_careful(&iocb->ki_list)) + aio_remove_iocb(iocb); if (kiocb->ki_flags & IOCB_WRITE) { struct inode *inode = file_inode(kiocb->ki_filp); @@ -1605,15 +1609,8 @@ static void aio_poll_work(struct work_struct *work) { struct aio_kiocb *iocb = container_of(work, struct aio_kiocb, poll.work); - if (!list_empty_careful(&iocb->ki_list)) { - struct kioctx *ctx = iocb->ki_ctx; - unsigned long flags; - - spin_lock_irqsave(&ctx->ctx_lock, flags); - list_del(&iocb->ki_list); - spin_unlock_irqrestore(&ctx->ctx_lock, flags); - } - + if (!list_empty_careful(&iocb->ki_list)) + aio_remove_iocb(iocb); __aio_poll_complete(iocb, iocb->poll.events); }