Skip to content

Commit 1a417f4

Browse files
committed
io_uring: fix sporadic double CQE entry for close
We punt close to async for the final fput(), but we log the completion even before that even in that case. We rely on the request not having a files table assigned to detect what the final async close should do. However, if we punt the async queue to __io_queue_sqe(), we'll get ->files assigned and this makes io_close_finish() think it should both close the filp again (which does no harm) AND log a new CQE event for this request. This causes duplicate CQEs. Queue the request up for async manually so we don't grab files needlessly and trigger this condition. Signed-off-by: Jens Axboe <[email protected]>
1 parent 9250f9e commit 1a417f4

File tree

1 file changed

+8
-5
lines changed

1 file changed

+8
-5
lines changed

fs/io_uring.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2843,16 +2843,13 @@ static void io_close_finish(struct io_wq_work **workptr)
28432843
int ret;
28442844

28452845
ret = filp_close(req->close.put_file, req->work.files);
2846-
if (ret < 0) {
2846+
if (ret < 0)
28472847
req_set_fail_links(req);
2848-
}
28492848
io_cqring_add_event(req, ret);
28502849
}
28512850

28522851
fput(req->close.put_file);
28532852

2854-
/* we bypassed the re-issue, drop the submission reference */
2855-
io_put_req(req);
28562853
io_put_req_find_next(req, &nxt);
28572854
if (nxt)
28582855
io_wq_assign_next(workptr, nxt);
@@ -2894,7 +2891,13 @@ static int io_close(struct io_kiocb *req, struct io_kiocb **nxt,
28942891

28952892
eagain:
28962893
req->work.func = io_close_finish;
2897-
return -EAGAIN;
2894+
/*
2895+
* Do manual async queue here to avoid grabbing files - we don't
2896+
* need the files, and it'll cause io_close_finish() to close
2897+
* the file again and cause a double CQE entry for this request
2898+
*/
2899+
io_queue_async_work(req);
2900+
return 0;
28982901
}
28992902

29002903
static int io_prep_sfr(struct io_kiocb *req, const struct io_uring_sqe *sqe)

0 commit comments

Comments
 (0)