Commit ac9f4f30 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'io_uring-6.18-20251113' of git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux

Pull io_uring fixes from Jens Axboe:

 - Use the actual segments in a request when for bvec based buffers

 - Fix an odd case where the iovec might get leaked for a read/write
   request, if it was newly allocated, overflowed the alloc cache, and
   hit an early error

 - Minor tweak to the query API added in this release, returning the
   number of available entries

* tag 'io_uring-6.18-20251113' of git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux:
  io_uring/rsrc: don't use blk_rq_nr_phys_segments() as number of bvecs
  io_uring/query: return number of available queries
  io_uring/rw: ensure allocated iovec gets cleared for early failure
parents b86caedd 2d0e88f3
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -36,6 +36,9 @@ struct io_uring_query_opcode {
	__u64	enter_flags;
	/* Bitmask of all supported IOSQE_* flags */
	__u64	sqe_flags;
	/* The number of available query opcodes */
	__u32	nr_query_opcodes;
	__u32	__pad;
};

#endif
+2 −0
Original line number Diff line number Diff line
@@ -20,6 +20,8 @@ static ssize_t io_query_ops(void *data)
	e->ring_setup_flags = IORING_SETUP_FLAGS;
	e->enter_flags = IORING_ENTER_FLAGS;
	e->sqe_flags = SQE_VALID_FLAGS;
	e->nr_query_opcodes = __IO_URING_QUERY_MAX;
	e->__pad = 0;
	return sizeof(*e);
}

+9 −7
Original line number Diff line number Diff line
@@ -943,8 +943,8 @@ int io_buffer_register_bvec(struct io_uring_cmd *cmd, struct request *rq,
	struct req_iterator rq_iter;
	struct io_mapped_ubuf *imu;
	struct io_rsrc_node *node;
	struct bio_vec bv, *bvec;
	u16 nr_bvecs;
	struct bio_vec bv;
	unsigned int nr_bvecs = 0;
	int ret = 0;

	io_ring_submit_lock(ctx, issue_flags);
@@ -965,8 +965,11 @@ int io_buffer_register_bvec(struct io_uring_cmd *cmd, struct request *rq,
		goto unlock;
	}

	nr_bvecs = blk_rq_nr_phys_segments(rq);
	imu = io_alloc_imu(ctx, nr_bvecs);
	/*
	 * blk_rq_nr_phys_segments() may overestimate the number of bvecs
	 * but avoids needing to iterate over the bvecs
	 */
	imu = io_alloc_imu(ctx, blk_rq_nr_phys_segments(rq));
	if (!imu) {
		kfree(node);
		ret = -ENOMEM;
@@ -977,16 +980,15 @@ int io_buffer_register_bvec(struct io_uring_cmd *cmd, struct request *rq,
	imu->len = blk_rq_bytes(rq);
	imu->acct_pages = 0;
	imu->folio_shift = PAGE_SHIFT;
	imu->nr_bvecs = nr_bvecs;
	refcount_set(&imu->refs, 1);
	imu->release = release;
	imu->priv = rq;
	imu->is_kbuf = true;
	imu->dir = 1 << rq_data_dir(rq);

	bvec = imu->bvec;
	rq_for_each_bvec(bv, rq, rq_iter)
		*bvec++ = bv;
		imu->bvec[nr_bvecs++] = bv;
	imu->nr_bvecs = nr_bvecs;

	node->buf = imu;
	data->nodes[index] = node;
+3 −0
Original line number Diff line number Diff line
@@ -463,7 +463,10 @@ int io_read_mshot_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)

void io_readv_writev_cleanup(struct io_kiocb *req)
{
	struct io_async_rw *rw = req->async_data;

	lockdep_assert_held(&req->ctx->uring_lock);
	io_vec_free(&rw->vec);
	io_rw_recycle(req, 0);
}