This exposes fallocate(2) through io_uring. Signed-off-by: Jens Axboe <axboe@xxxxxxxxx> --- fs/io_uring.c | 29 +++++++++++++++++++++++++++++ include/uapi/linux/io_uring.h | 1 + 2 files changed, 30 insertions(+) diff --git a/fs/io_uring.c b/fs/io_uring.c index 9b1833fedc5c..d780477b9a56 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -1974,6 +1974,32 @@ static int io_fsync(struct io_kiocb *req, const struct io_uring_sqe *sqe, return 0; } +static int io_fallocate(struct io_kiocb *req, struct io_kiocb **nxt, + bool force_nonblock) +{ + const struct io_uring_sqe *sqe = req->sqe; + loff_t offset, len; + int ret, mode; + + if (sqe->ioprio || sqe->buf_index || sqe->rw_flags) + return -EINVAL; + + /* fallocate always requiring blocking context */ + if (force_nonblock) + return -EAGAIN; + + offset = READ_ONCE(sqe->off); + len = READ_ONCE(sqe->addr); + mode = READ_ONCE(sqe->len); + + ret = vfs_fallocate(req->file, mode, offset, len); + if (ret < 0) + req_set_fail_links(req); + io_cqring_add_event(req, ret); + io_put_req_find_next(req, nxt); + return 0; +} + static int io_prep_sfr(struct io_kiocb *req, const struct io_uring_sqe *sqe) { struct io_ring_ctx *ctx = req->ctx; @@ -2983,6 +3009,9 @@ static int io_issue_sqe(struct io_kiocb *req, struct io_kiocb **nxt, case IORING_OP_ASYNC_CANCEL: ret = io_async_cancel(req, req->sqe, nxt); break; + case IORING_OP_FALLOCATE: + ret = io_fallocate(req, nxt, force_nonblock); + break; default: ret = -EINVAL; break; diff --git a/include/uapi/linux/io_uring.h b/include/uapi/linux/io_uring.h index a3300e1b9a01..bdbe2b130179 100644 --- a/include/uapi/linux/io_uring.h +++ b/include/uapi/linux/io_uring.h @@ -76,6 +76,7 @@ enum { IORING_OP_ASYNC_CANCEL, IORING_OP_LINK_TIMEOUT, IORING_OP_CONNECT, + IORING_OP_FALLOCATE, /* this goes last, obviously */ IORING_OP_LAST, -- 2.24.1