Skip to content

Commit 9018ccc

Browse files
author
Christoph Hellwig
committed
aio: add a iocb refcount
This is needed to prevent races caused by the way the ->poll API works. To avoid introducing overhead for other users of the iocbs we initialize it to zero and only do refcount operations if it is non-zero in the completion path. Signed-off-by: Christoph Hellwig <[email protected]> Tested-by: Avi Kivity <[email protected]>
1 parent 7dda712 commit 9018ccc

File tree

1 file changed

+13
-4
lines changed

1 file changed

+13
-4
lines changed

fs/aio.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <linux/export.h>
1919
#include <linux/syscalls.h>
2020
#include <linux/backing-dev.h>
21+
#include <linux/refcount.h>
2122
#include <linux/uio.h>
2223

2324
#include <linux/sched/signal.h>
@@ -178,6 +179,7 @@ struct aio_kiocb {
178179

179180
struct list_head ki_list; /* the aio core uses this
180181
* for cancellation */
182+
refcount_t ki_refcnt;
181183

182184
/*
183185
* If the aio_resfd field of the userspace iocb is not zero,
@@ -1015,6 +1017,7 @@ static inline struct aio_kiocb *aio_get_req(struct kioctx *ctx)
10151017

10161018
percpu_ref_get(&ctx->reqs);
10171019
INIT_LIST_HEAD(&req->ki_list);
1020+
refcount_set(&req->ki_refcnt, 0);
10181021
req->ki_ctx = ctx;
10191022
return req;
10201023
out_put:
@@ -1049,6 +1052,15 @@ static struct kioctx *lookup_ioctx(unsigned long ctx_id)
10491052
return ret;
10501053
}
10511054

1055+
static inline void iocb_put(struct aio_kiocb *iocb)
1056+
{
1057+
if (refcount_read(&iocb->ki_refcnt) == 0 ||
1058+
refcount_dec_and_test(&iocb->ki_refcnt)) {
1059+
percpu_ref_put(&iocb->ki_ctx->reqs);
1060+
kmem_cache_free(kiocb_cachep, iocb);
1061+
}
1062+
}
1063+
10521064
/* aio_complete
10531065
* Called when the io request on the given iocb is complete.
10541066
*/
@@ -1118,8 +1130,6 @@ static void aio_complete(struct aio_kiocb *iocb, long res, long res2)
11181130
eventfd_ctx_put(iocb->ki_eventfd);
11191131
}
11201132

1121-
kmem_cache_free(kiocb_cachep, iocb);
1122-
11231133
/*
11241134
* We have to order our ring_info tail store above and test
11251135
* of the wait list below outside the wait lock. This is
@@ -1130,8 +1140,7 @@ static void aio_complete(struct aio_kiocb *iocb, long res, long res2)
11301140

11311141
if (waitqueue_active(&ctx->wait))
11321142
wake_up(&ctx->wait);
1133-
1134-
percpu_ref_put(&ctx->reqs);
1143+
iocb_put(iocb);
11351144
}
11361145

11371146
/* aio_read_events_ring

0 commit comments

Comments
 (0)