Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 55934
b: refs/heads/master
c: 9c3060b
h: refs/heads/master
v: v3
  • Loading branch information
Davide Libenzi authored and Linus Torvalds committed May 11, 2007
1 parent ef7eb89 commit 40e23a5
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 4 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: fdb902b1225e1668315f38e96d2f439452c03a15
refs/heads/master: 9c3060bedd84144653a2ad7bea32389f65598d40
28 changes: 26 additions & 2 deletions trunk/fs/aio.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include <linux/highmem.h>
#include <linux/workqueue.h>
#include <linux/security.h>
#include <linux/eventfd.h>

#include <asm/kmap_types.h>
#include <asm/uaccess.h>
Expand Down Expand Up @@ -417,6 +418,7 @@ static struct kiocb fastcall *__aio_get_req(struct kioctx *ctx)
req->private = NULL;
req->ki_iovec = NULL;
INIT_LIST_HEAD(&req->ki_run_list);
req->ki_eventfd = ERR_PTR(-EINVAL);

/* Check if the completion queue has enough free space to
* accept an event from this io.
Expand Down Expand Up @@ -458,6 +460,8 @@ static inline void really_put_req(struct kioctx *ctx, struct kiocb *req)
{
assert_spin_locked(&ctx->ctx_lock);

if (!IS_ERR(req->ki_eventfd))
fput(req->ki_eventfd);
if (req->ki_dtor)
req->ki_dtor(req);
if (req->ki_iovec != &req->ki_inline_vec)
Expand Down Expand Up @@ -942,6 +946,14 @@ int fastcall aio_complete(struct kiocb *iocb, long res, long res2)
return 1;
}

/*
* Check if the user asked us to deliver the result through an
* eventfd. The eventfd_signal() function is safe to be called
* from IRQ context.
*/
if (!IS_ERR(iocb->ki_eventfd))
eventfd_signal(iocb->ki_eventfd, 1);

info = &ctx->ring_info;

/* add a completion event to the ring buffer.
Expand Down Expand Up @@ -1526,8 +1538,7 @@ int fastcall io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb,
ssize_t ret;

/* enforce forwards compatibility on users */
if (unlikely(iocb->aio_reserved1 || iocb->aio_reserved2 ||
iocb->aio_reserved3)) {
if (unlikely(iocb->aio_reserved1 || iocb->aio_reserved2)) {
pr_debug("EINVAL: io_submit: reserve field set\n");
return -EINVAL;
}
Expand All @@ -1551,6 +1562,19 @@ int fastcall io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb,
fput(file);
return -EAGAIN;
}
if (iocb->aio_flags & IOCB_FLAG_RESFD) {
/*
* If the IOCB_FLAG_RESFD flag of aio_flags is set, get an
* instance of the file* now. The file descriptor must be
* an eventfd() fd, and will be signaled for each completed
* event using the eventfd_signal() function.
*/
req->ki_eventfd = eventfd_fget((int) iocb->aio_resfd);
if (unlikely(IS_ERR(req->ki_eventfd))) {
ret = PTR_ERR(req->ki_eventfd);
goto out_put_req;
}
}

req->ki_filp = file;
ret = put_user(req->ki_key, &user_iocb->aio_key);
Expand Down
6 changes: 6 additions & 0 deletions trunk/include/linux/aio.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,12 @@ struct kiocb {

struct list_head ki_list; /* the aio core uses this
* for cancellation */

/*
* If the aio_resfd field of the userspace iocb is not zero,
* this is the underlying file* to deliver event to.
*/
struct file *ki_eventfd;
};

#define is_sync_kiocb(iocb) ((iocb)->ki_key == KIOCB_SYNC_KEY)
Expand Down
18 changes: 17 additions & 1 deletion trunk/include/linux/aio_abi.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,14 @@ enum {
IOCB_CMD_PWRITEV = 8,
};

/*
* Valid flags for the "aio_flags" member of the "struct iocb".
*
* IOCB_FLAG_RESFD - Set if the "aio_resfd" member of the "struct iocb"
* is valid.
*/
#define IOCB_FLAG_RESFD (1 << 0)

/* read() from /dev/aio returns these structures. */
struct io_event {
__u64 data; /* the data field from the iocb */
Expand Down Expand Up @@ -84,7 +92,15 @@ struct iocb {

/* extra parameters */
__u64 aio_reserved2; /* TODO: use this for a (struct sigevent *) */
__u64 aio_reserved3;

/* flags for the "struct iocb" */
__u32 aio_flags;

/*
* if the IOCB_FLAG_RESFD flag of "aio_flags" is set, this is an
* eventfd to signal AIO readiness to
*/
__u32 aio_resfd;
}; /* 64 bytes */

#undef IFBIG
Expand Down

0 comments on commit 40e23a5

Please sign in to comment.