This adds support for doing fadvise through io_uring. We assume that WILLNEED doesn't block, but that DONTNEED may block.
Unified · Split
| @@ -72,6 +72,7 @@ · 71 unmodified lines | |||
| 72 | #include <linux/highmem.h> | 72 | #include <linux/highmem.h> |
| 73 | #include <linux/namei.h> | 73 | #include <linux/namei.h> |
| 74 | #include <linux/fsnotify.h> | 74 | #include <linux/fsnotify.h> |
| 75 | #include <linux/fadvise.h> | ||
| 75 | 76 | ||
| 76 | #define CREATE_TRACE_POINTS | 77 | #define CREATE_TRACE_POINTS |
| 77 | #include <trace/events/io_uring.h> | 78 | #include <trace/events/io_uring.h> |
| @@ -400,6 +401,13 @@ struct io_files_update { · 322 unmodified lines | |||
| 400 | u32 offset; | 401 | u32 offset; |
| 401 | }; | 402 | }; |
| 402 | 403 | ||
| 404 | struct io_fadvise { | ||
| 405 | struct file *file; | ||
| 406 | u64 offset; | ||
| 407 | u32 len; | ||
| 408 | u32 advice; | ||
| 409 | }; | ||
| 410 | |||
| 403 | struct io_async_connect { | 411 | struct io_async_connect { |
| 404 | struct sockaddr_storage address; | 412 | struct sockaddr_storage address; |
| 405 | }; | 413 | }; |
| @@ -452,6 +460,7 @@ struct io_kiocb { · 46 unmodified lines | |||
| 452 | struct io_open open; | 460 | struct io_open open; |
| 453 | struct io_close close; | 461 | struct io_close close; |
| 454 | struct io_files_update files_update; | 462 | struct io_files_update files_update; |
| 463 | struct io_fadvise fadvise; | ||
| 455 | }; | 464 | }; |
| 456 | 465 | ||
| 457 | struct io_async_ctx *io; | 466 | struct io_async_ctx *io; |
| @@ -667,6 +676,10 @@ static const struct io_op_def io_op_defs[] = { · 209 unmodified lines | |||
| 667 | .needs_file = 1, | 676 | .needs_file = 1, |
| 668 | .unbound_nonreg_file = 1, | 677 | .unbound_nonreg_file = 1, |
| 669 | }, | 678 | }, |
| 679 | { | ||
| 680 | /* IORING_OP_FADVISE */ | ||
| 681 | .needs_file = 1, | ||
| 682 | }, | ||
| 670 | }; | 683 | }; |
| 671 | 684 | ||
| 672 | static void io_wq_submit_work(struct io_wq_work **workptr); | 685 | static void io_wq_submit_work(struct io_wq_work **workptr); |
| @@ -2436,6 +2449,35 @@ err: · 1763 unmodified lines | |||
| 2436 | return 0; | 2449 | return 0; |
| 2437 | } | 2450 | } |
| 2438 | 2451 | ||
| 2452 | static int io_fadvise_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) | ||
| 2453 | { | ||
| 2454 | if (sqe->ioprio || sqe->buf_index || sqe->addr) | ||
| 2455 | return -EINVAL; | ||
| 2456 | |||
| 2457 | req->fadvise.offset = READ_ONCE(sqe->off); | ||
| 2458 | req->fadvise.len = READ_ONCE(sqe->len); | ||
| 2459 | req->fadvise.advice = READ_ONCE(sqe->fadvise_advice); | ||
| 2460 | return 0; | ||
| 2461 | } | ||
| 2462 | |||
| 2463 | static int io_fadvise(struct io_kiocb *req, struct io_kiocb **nxt, | ||
| 2464 | bool force_nonblock) | ||
| 2465 | { | ||
| 2466 | struct io_fadvise *fa = &req->fadvise; | ||
| 2467 | int ret; | ||
| 2468 | |||
| 2469 | /* DONTNEED may block, others _should_ not */ | ||
| 2470 | if (fa->advice == POSIX_FADV_DONTNEED && force_nonblock) | ||
| 2471 | return -EAGAIN; | ||
| 2472 | |||
| 2473 | ret = vfs_fadvise(req->file, fa->offset, fa->len, fa->advice); | ||
| 2474 | if (ret < 0) | ||
| 2475 | req_set_fail_links(req); | ||
| 2476 | io_cqring_add_event(req, ret); | ||
| 2477 | io_put_req_find_next(req, nxt); | ||
| 2478 | return 0; | ||
| 2479 | } | ||
| 2480 | |||
| 2439 | static int io_statx_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) | 2481 | static int io_statx_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) |
| 2440 | { | 2482 | { |
| 2441 | unsigned lookup_flags; | 2483 | unsigned lookup_flags; |
| @@ -3721,6 +3763,9 @@ static int io_req_defer_prep(struct io_kiocb *req, · 1279 unmodified lines | |||
| 3721 | case IORING_OP_STATX: | 3763 | case IORING_OP_STATX: |
| 3722 | ret = io_statx_prep(req, sqe); | 3764 | ret = io_statx_prep(req, sqe); |
| 3723 | break; | 3765 | break; |
| 3766 | case IORING_OP_FADVISE: | ||
| 3767 | ret = io_fadvise_prep(req, sqe); | ||
| 3768 | break; | ||
| 3724 | default: | 3769 | default: |
| 3725 | printk_once(KERN_WARNING "io_uring: unhandled opcode %d\n", | 3770 | printk_once(KERN_WARNING "io_uring: unhandled opcode %d\n", |
| 3726 | req->opcode); | 3771 | req->opcode); |
| @@ -3917,6 +3962,14 @@ static int io_issue_sqe(struct io_kiocb *req, const struct io_uring_sqe *sqe, · 190 unmodified lines | |||
| 3917 | } | 3962 | } |
| 3918 | ret = io_statx(req, nxt, force_nonblock); | 3963 | ret = io_statx(req, nxt, force_nonblock); |
| 3919 | break; | 3964 | break; |
| 3965 | case IORING_OP_FADVISE: | ||
| 3966 | if (sqe) { | ||
| 3967 | ret = io_fadvise_prep(req, sqe); | ||
| 3968 | if (ret) | ||
| 3969 | break; | ||
| 3970 | } | ||
| 3971 | ret = io_fadvise(req, nxt, force_nonblock); | ||
| 3972 | break; | ||
| 3920 | default: | 3973 | default: |
| 3921 | ret = -EINVAL; | 3974 | ret = -EINVAL; |
| 3922 | break; | 3975 | break; |
| @@ -36,6 +36,7 @@ struct io_uring_sqe { · 35 unmodified lines | |||
| 36 | __u32 cancel_flags; | 36 | __u32 cancel_flags; |
| 37 | __u32 open_flags; | 37 | __u32 open_flags; |
| 38 | __u32 statx_flags; | 38 | __u32 statx_flags; |
| 39 | __u32 fadvise_advice; | ||
| 39 | }; | 40 | }; |
| 40 | __u64 user_data; /* data to be passed back at completion time */ | 41 | __u64 user_data; /* data to be passed back at completion time */ |
| 41 | union { | 42 | union { |
| @@ -86,6 +87,7 @@ enum { · 44 unmodified lines | |||
| 86 | IORING_OP_STATX, | 87 | IORING_OP_STATX, |
| 87 | IORING_OP_READ, | 88 | IORING_OP_READ, |
| 88 | IORING_OP_WRITE, | 89 | IORING_OP_WRITE, |
| 90 | IORING_OP_FADVISE, | ||
| 89 | 91 | ||
| 90 | /* this goes last, obviously */ | 92 | /* this goes last, obviously */ |
| 91 | IORING_OP_LAST, | 93 | IORING_OP_LAST, |