Dependant links of a fixed-read/write are always cancelled. The reason is that io_complete_rw_common() uses req->result to decide whether to fail links, which is set as res=io_import_iovec(). However, io_import_fixed() doesn't return size, but error code. Signed-off-by: Pavel Begunkov <asml.silence@xxxxxxxxx> --- fs/io_uring.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/fs/io_uring.c b/fs/io_uring.c index 5ceec1a4faad..8119cbae4fb6 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -1484,9 +1484,9 @@ static void kiocb_done(struct kiocb *kiocb, ssize_t ret, struct io_kiocb **nxt, io_rw_done(kiocb, ret); } -static int io_import_fixed(struct io_ring_ctx *ctx, int rw, - const struct io_uring_sqe *sqe, - struct iov_iter *iter) +static ssize_t io_import_fixed(struct io_ring_ctx *ctx, int rw, + const struct io_uring_sqe *sqe, + struct iov_iter *iter) { size_t len = READ_ONCE(sqe->len); struct io_mapped_ubuf *imu; @@ -1555,7 +1555,7 @@ static int io_import_fixed(struct io_ring_ctx *ctx, int rw, } } - return 0; + return iter->count; } static ssize_t io_import_iovec(struct io_ring_ctx *ctx, int rw, @@ -1576,11 +1576,9 @@ static ssize_t io_import_iovec(struct io_ring_ctx *ctx, int rw, * flag. */ opcode = READ_ONCE(sqe->opcode); - if (opcode == IORING_OP_READ_FIXED || - opcode == IORING_OP_WRITE_FIXED) { - ssize_t ret = io_import_fixed(ctx, rw, sqe, iter); + if (opcode == IORING_OP_READ_FIXED || opcode == IORING_OP_WRITE_FIXED) { *iovec = NULL; - return ret; + return io_import_fixed(ctx, rw, sqe, iter); } if (!s->has_user) -- 2.24.0