aboutsummaryrefslogtreecommitdiffstats
path: root/fs/aio.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/aio.c')
-rw-r--r--fs/aio.c28
1 files changed, 26 insertions, 2 deletions
diff --git a/fs/aio.c b/fs/aio.c
index ac1c1587aa02..dbe699e9828c 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -30,6 +30,7 @@
30#include <linux/highmem.h> 30#include <linux/highmem.h>
31#include <linux/workqueue.h> 31#include <linux/workqueue.h>
32#include <linux/security.h> 32#include <linux/security.h>
33#include <linux/eventfd.h>
33 34
34#include <asm/kmap_types.h> 35#include <asm/kmap_types.h>
35#include <asm/uaccess.h> 36#include <asm/uaccess.h>
@@ -417,6 +418,7 @@ static struct kiocb fastcall *__aio_get_req(struct kioctx *ctx)
417 req->private = NULL; 418 req->private = NULL;
418 req->ki_iovec = NULL; 419 req->ki_iovec = NULL;
419 INIT_LIST_HEAD(&req->ki_run_list); 420 INIT_LIST_HEAD(&req->ki_run_list);
421 req->ki_eventfd = ERR_PTR(-EINVAL);
420 422
421 /* Check if the completion queue has enough free space to 423 /* Check if the completion queue has enough free space to
422 * accept an event from this io. 424 * accept an event from this io.
@@ -458,6 +460,8 @@ static inline void really_put_req(struct kioctx *ctx, struct kiocb *req)
458{ 460{
459 assert_spin_locked(&ctx->ctx_lock); 461 assert_spin_locked(&ctx->ctx_lock);
460 462
463 if (!IS_ERR(req->ki_eventfd))
464 fput(req->ki_eventfd);
461 if (req->ki_dtor) 465 if (req->ki_dtor)
462 req->ki_dtor(req); 466 req->ki_dtor(req);
463 if (req->ki_iovec != &req->ki_inline_vec) 467 if (req->ki_iovec != &req->ki_inline_vec)
@@ -942,6 +946,14 @@ int fastcall aio_complete(struct kiocb *iocb, long res, long res2)
942 return 1; 946 return 1;
943 } 947 }
944 948
949 /*
950 * Check if the user asked us to deliver the result through an
951 * eventfd. The eventfd_signal() function is safe to be called
952 * from IRQ context.
953 */
954 if (!IS_ERR(iocb->ki_eventfd))
955 eventfd_signal(iocb->ki_eventfd, 1);
956
945 info = &ctx->ring_info; 957 info = &ctx->ring_info;
946 958
947 /* add a completion event to the ring buffer. 959 /* add a completion event to the ring buffer.
@@ -1526,8 +1538,7 @@ int fastcall io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb,
1526 ssize_t ret; 1538 ssize_t ret;
1527 1539
1528 /* enforce forwards compatibility on users */ 1540 /* enforce forwards compatibility on users */
1529 if (unlikely(iocb->aio_reserved1 || iocb->aio_reserved2 || 1541 if (unlikely(iocb->aio_reserved1 || iocb->aio_reserved2)) {
1530 iocb->aio_reserved3)) {
1531 pr_debug("EINVAL: io_submit: reserve field set\n"); 1542 pr_debug("EINVAL: io_submit: reserve field set\n");
1532 return -EINVAL; 1543 return -EINVAL;
1533 } 1544 }
@@ -1551,6 +1562,19 @@ int fastcall io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb,
1551 fput(file); 1562 fput(file);
1552 return -EAGAIN; 1563 return -EAGAIN;
1553 } 1564 }
1565 if (iocb->aio_flags & IOCB_FLAG_RESFD) {
1566 /*
1567 * If the IOCB_FLAG_RESFD flag of aio_flags is set, get an
1568 * instance of the file* now. The file descriptor must be
1569 * an eventfd() fd, and will be signaled for each completed
1570 * event using the eventfd_signal() function.
1571 */
1572 req->ki_eventfd = eventfd_fget((int) iocb->aio_resfd);
1573 if (unlikely(IS_ERR(req->ki_eventfd))) {
1574 ret = PTR_ERR(req->ki_eventfd);
1575 goto out_put_req;
1576 }
1577 }
1554 1578
1555 req->ki_filp = file; 1579 req->ki_filp = file;
1556 ret = put_user(req->ki_key, &user_iocb->aio_key); 1580 ret = put_user(req->ki_key, &user_iocb->aio_key);