Commit 3b87184f authored by Jens Axboe's avatar Jens Axboe
Browse files

io_uring/advise: support 64-bit lengths



The existing fadvise/madvise support only supports 32-bit lengths. Add
support for 64-bit lengths, enabled by the application setting sqe->off
rather than sqe->len for the length. If sqe->len is set, then that is
used as the 32-bit length. If sqe->len is zero, then sqe->off is read
for full 64-bit support.

Older kernels will return -EINVAL if 64-bit support isn't available.

Fixes: 4840e418 ("io_uring: add IORING_OP_FADVISE")
Fixes: c1ca757b ("io_uring: add IORING_OP_MADVISE")
Reported-by: default avatarStefan <source@s.muenzel.net>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 11d19466
Loading
Loading
Loading
Loading
+10 −6
Original line number Diff line number Diff line
@@ -17,14 +17,14 @@
struct io_fadvise {
	struct file			*file;
	u64				offset;
	u32				len;
	u64				len;
	u32				advice;
};

struct io_madvise {
	struct file			*file;
	u64				addr;
	u32				len;
	u64				len;
	u32				advice;
};

@@ -33,10 +33,12 @@ int io_madvise_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
#if defined(CONFIG_ADVISE_SYSCALLS) && defined(CONFIG_MMU)
	struct io_madvise *ma = io_kiocb_to_cmd(req, struct io_madvise);

	if (sqe->buf_index || sqe->off || sqe->splice_fd_in)
	if (sqe->buf_index || sqe->splice_fd_in)
		return -EINVAL;

	ma->addr = READ_ONCE(sqe->addr);
	ma->len = READ_ONCE(sqe->off);
	if (!ma->len)
		ma->len = READ_ONCE(sqe->len);
	ma->advice = READ_ONCE(sqe->fadvise_advice);
	req->flags |= REQ_F_FORCE_ASYNC;
@@ -78,10 +80,12 @@ int io_fadvise_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
{
	struct io_fadvise *fa = io_kiocb_to_cmd(req, struct io_fadvise);

	if (sqe->buf_index || sqe->addr || sqe->splice_fd_in)
	if (sqe->buf_index || sqe->splice_fd_in)
		return -EINVAL;

	fa->offset = READ_ONCE(sqe->off);
	fa->len = READ_ONCE(sqe->addr);
	if (!fa->len)
		fa->len = READ_ONCE(sqe->len);
	fa->advice = READ_ONCE(sqe->fadvise_advice);
	if (io_fadvise_force_async(fa))