]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - fs/aio.c
Merge branch 'work.vboxsf' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
[linux.git] / fs / aio.c
index 0d9a559d488c1420536d83f99bdc5099029747e6..5f3d3d8149287777d1b051215c5279cb6bb89acb 100644 (file)
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -1610,6 +1610,14 @@ static int aio_fsync(struct fsync_iocb *req, const struct iocb *iocb,
        return 0;
 }
 
+static void aio_poll_put_work(struct work_struct *work)
+{
+       struct poll_iocb *req = container_of(work, struct poll_iocb, work);
+       struct aio_kiocb *iocb = container_of(req, struct aio_kiocb, poll);
+
+       iocb_put(iocb);
+}
+
 static void aio_poll_complete_work(struct work_struct *work)
 {
        struct poll_iocb *req = container_of(work, struct poll_iocb, work);
@@ -1674,6 +1682,8 @@ static int aio_poll_wake(struct wait_queue_entry *wait, unsigned mode, int sync,
        list_del_init(&req->wait.entry);
 
        if (mask && spin_trylock_irqsave(&iocb->ki_ctx->ctx_lock, flags)) {
+               struct kioctx *ctx = iocb->ki_ctx;
+
                /*
                 * Try to complete the iocb inline if we can. Use
                 * irqsave/irqrestore because not all filesystems (e.g. fuse)
@@ -1683,8 +1693,14 @@ static int aio_poll_wake(struct wait_queue_entry *wait, unsigned mode, int sync,
                list_del(&iocb->ki_list);
                iocb->ki_res.res = mangle_poll(mask);
                req->done = true;
-               spin_unlock_irqrestore(&iocb->ki_ctx->ctx_lock, flags);
-               iocb_put(iocb);
+               if (iocb->ki_eventfd && eventfd_signal_count()) {
+                       iocb = NULL;
+                       INIT_WORK(&req->work, aio_poll_put_work);
+                       schedule_work(&req->work);
+               }
+               spin_unlock_irqrestore(&ctx->ctx_lock, flags);
+               if (iocb)
+                       iocb_put(iocb);
        } else {
                schedule_work(&req->work);
        }
@@ -2056,7 +2072,7 @@ static long do_io_getevents(aio_context_t ctx_id,
  *     specifies an infinite timeout. Note that the timeout pointed to by
  *     timeout is relative.  Will fail with -ENOSYS if not implemented.
  */
-#if !defined(CONFIG_64BIT_TIME) || defined(CONFIG_64BIT)
+#ifdef CONFIG_64BIT
 
 SYSCALL_DEFINE5(io_getevents, aio_context_t, ctx_id,
                long, min_nr,