Skip to content

Commit a9339b7

Browse files
author
Al Viro
committed
aio: keep io_event in aio_kiocb
We want to separate forming the resulting io_event from putting it into the ring buffer. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
1 parent 833f415 commit a9339b7

File tree

1 file changed

+13
-18
lines changed

1 file changed

+13
-18
lines changed

fs/aio.c

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -204,8 +204,7 @@ struct aio_kiocb {
204204
struct kioctx *ki_ctx;
205205
kiocb_cancel_fn *ki_cancel;
206206

207-
struct iocb __user *ki_user_iocb; /* user's aiocb */
208-
__u64 ki_user_data; /* user's data for completion */
207+
struct io_event ki_res;
209208

210209
struct list_head ki_list; /* the aio core uses this
211210
* for cancellation */
@@ -1084,15 +1083,6 @@ static inline void iocb_put(struct aio_kiocb *iocb)
10841083
iocb_destroy(iocb);
10851084
}
10861085

1087-
static void aio_fill_event(struct io_event *ev, struct aio_kiocb *iocb,
1088-
long res, long res2)
1089-
{
1090-
ev->obj = (u64)(unsigned long)iocb->ki_user_iocb;
1091-
ev->data = iocb->ki_user_data;
1092-
ev->res = res;
1093-
ev->res2 = res2;
1094-
}
1095-
10961086
/* aio_complete
10971087
* Called when the io request on the given iocb is complete.
10981088
*/
@@ -1104,6 +1094,8 @@ static void aio_complete(struct aio_kiocb *iocb, long res, long res2)
11041094
unsigned tail, pos, head;
11051095
unsigned long flags;
11061096

1097+
iocb->ki_res.res = res;
1098+
iocb->ki_res.res2 = res2;
11071099
/*
11081100
* Add a completion event to the ring buffer. Must be done holding
11091101
* ctx->completion_lock to prevent other code from messing with the tail
@@ -1120,14 +1112,14 @@ static void aio_complete(struct aio_kiocb *iocb, long res, long res2)
11201112
ev_page = kmap_atomic(ctx->ring_pages[pos / AIO_EVENTS_PER_PAGE]);
11211113
event = ev_page + pos % AIO_EVENTS_PER_PAGE;
11221114

1123-
aio_fill_event(event, iocb, res, res2);
1115+
*event = iocb->ki_res;
11241116

11251117
kunmap_atomic(ev_page);
11261118
flush_dcache_page(ctx->ring_pages[pos / AIO_EVENTS_PER_PAGE]);
11271119

1128-
pr_debug("%p[%u]: %p: %p %Lx %lx %lx\n",
1129-
ctx, tail, iocb, iocb->ki_user_iocb, iocb->ki_user_data,
1130-
res, res2);
1120+
pr_debug("%p[%u]: %p: %p %Lx %Lx %Lx\n", ctx, tail, iocb,
1121+
(void __user *)(unsigned long)iocb->ki_res.obj,
1122+
iocb->ki_res.data, iocb->ki_res.res, iocb->ki_res.res2);
11311123

11321124
/* after flagging the request as done, we
11331125
* must never even look at it again
@@ -1844,8 +1836,10 @@ static int __io_submit_one(struct kioctx *ctx, const struct iocb *iocb,
18441836
goto out_put_req;
18451837
}
18461838

1847-
req->ki_user_iocb = user_iocb;
1848-
req->ki_user_data = iocb->aio_data;
1839+
req->ki_res.obj = (u64)(unsigned long)user_iocb;
1840+
req->ki_res.data = iocb->aio_data;
1841+
req->ki_res.res = 0;
1842+
req->ki_res.res2 = 0;
18491843

18501844
switch (iocb->aio_lio_opcode) {
18511845
case IOCB_CMD_PREAD:
@@ -2019,6 +2013,7 @@ SYSCALL_DEFINE3(io_cancel, aio_context_t, ctx_id, struct iocb __user *, iocb,
20192013
struct aio_kiocb *kiocb;
20202014
int ret = -EINVAL;
20212015
u32 key;
2016+
u64 obj = (u64)(unsigned long)iocb;
20222017

20232018
if (unlikely(get_user(key, &iocb->aio_key)))
20242019
return -EFAULT;
@@ -2032,7 +2027,7 @@ SYSCALL_DEFINE3(io_cancel, aio_context_t, ctx_id, struct iocb __user *, iocb,
20322027
spin_lock_irq(&ctx->ctx_lock);
20332028
/* TODO: use a hash or array, this sucks. */
20342029
list_for_each_entry(kiocb, &ctx->active_reqs, ki_list) {
2035-
if (kiocb->ki_user_iocb == iocb) {
2030+
if (kiocb->ki_res.obj == obj) {
20362031
ret = kiocb->ki_cancel(&kiocb->rw);
20372032
list_del_init(&kiocb->ki_list);
20382033
break;

0 commit comments

Comments
 (0)