@@ -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;
@@ -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,
This exposes fallocate(2) through io_uring. Signed-off-by: Jens Axboe <axboe@kernel.dk> --- fs/io_uring.c | 29 +++++++++++++++++++++++++++++ include/uapi/linux/io_uring.h | 1 + 2 files changed, 30 insertions(+)