History

io_uring: add IORING_OP_FADVISE

This adds support for doing fadvise through io_uring. We assume that WILLNEED doesn't block, but that DONTNEED may block.

Jens Axboe committed 6 years ago

Commit 4840e411 parent ba042912 files · +55 −0Browse files

Unified · Split

2 files
  1. fs/io_uring.c +53 −0
  2. include/uapi/linux/io_uring.h +2 −0
fs/io_uring.c+53−0
@@ -72,6 +72,7 @@ · 71 unmodified lines
7272 #include <linux/highmem.h>
7373 #include <linux/namei.h>
7474 #include <linux/fsnotify.h>
75+#include <linux/fadvise.h>
7576
7677 #define CREATE_TRACE_POINTS
7778 #include <trace/events/io_uring.h>
@@ -400,6 +401,13 @@ struct io_files_update { · 322 unmodified lines
400401 u32 offset;
401402 };
402403
404+struct io_fadvise {
405+ struct file *file;
406+ u64 offset;
407+ u32 len;
408+ u32 advice;
409+};
410+
403411 struct io_async_connect {
404412 struct sockaddr_storage address;
405413 };
@@ -452,6 +460,7 @@ struct io_kiocb { · 46 unmodified lines
452460 struct io_open open;
453461 struct io_close close;
454462 struct io_files_update files_update;
463+ struct io_fadvise fadvise;
455464 };
456465
457466 struct io_async_ctx *io;
@@ -667,6 +676,10 @@ static const struct io_op_def io_op_defs[] = { · 209 unmodified lines
667676 .needs_file = 1,
668677 .unbound_nonreg_file = 1,
669678 },
679+ {
680+ /* IORING_OP_FADVISE */
681+ .needs_file = 1,
682+ },
670683 };
671684
672685 static void io_wq_submit_work(struct io_wq_work **workptr);
@@ -2436,6 +2449,35 @@ err: · 1763 unmodified lines
24362449 return 0;
24372450 }
24382451
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+
24392481 static int io_statx_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
24402482 {
24412483 unsigned lookup_flags;
@@ -3721,6 +3763,9 @@ static int io_req_defer_prep(struct io_kiocb *req, · 1279 unmodified lines
37213763 case IORING_OP_STATX:
37223764 ret = io_statx_prep(req, sqe);
37233765 break;
3766+ case IORING_OP_FADVISE:
3767+ ret = io_fadvise_prep(req, sqe);
3768+ break;
37243769 default:
37253770 printk_once(KERN_WARNING "io_uring: unhandled opcode %d\n",
37263771 req->opcode);
@@ -3917,6 +3962,14 @@ static int io_issue_sqe(struct io_kiocb *req, const struct io_uring_sqe *sqe, · 190 unmodified lines
39173962 }
39183963 ret = io_statx(req, nxt, force_nonblock);
39193964 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;
39203973 default:
39213974 ret = -EINVAL;
39223975 break;
include/uapi/linux/io_uring.h+2−0
@@ -36,6 +36,7 @@ struct io_uring_sqe { · 35 unmodified lines
3636 __u32 cancel_flags;
3737 __u32 open_flags;
3838 __u32 statx_flags;
39+ __u32 fadvise_advice;
3940 };
4041 __u64 user_data; /* data to be passed back at completion time */
4142 union {
@@ -86,6 +87,7 @@ enum { · 44 unmodified lines
8687 IORING_OP_STATX,
8788 IORING_OP_READ,
8889 IORING_OP_WRITE,
90+ IORING_OP_FADVISE,
8991
9092 /* this goes last, obviously */
9193 IORING_OP_LAST,