From nobody Fri Sep 25 17:45:13 2026 Received: from mail-qk1-f226.google.com (mail-qk1-f226.google.com [209.85.222.226]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0252A4825AD for ; Wed, 9 Sep 2026 22:29:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.222.226 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788992962; cv=none; b=Fv0dLrsun2nkQwB1HoupFJx6B73GnnX68GOlgXovo8EQPiEX9oP4aau4cZ4mN3UogfwAaKxgCL25EN1nwnpjwSYXZL7Hu9ghg8/0JMC2e5hEKBAXm8YYUMzMvrSw3FVP9n0s8ljcGNqu8GpG/XT7jVTff/YetL2Cukto+UdOE0I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788992962; c=relaxed/simple; bh=WlsOlqUvKm0Axyc+Vr7Lx6IQyXMjzH3K2ebSlJNCLAM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=EQkW600eV7z3t/nTw6hDNv2MUnBSMFRzbULtAihnVRiJFOKOUK7qBDrcVoRg+gftJlMkz2MUfcdbbvfJKXSUgFRIc+dtTtFmk/DQ73QS+deCJ5f/rms+oT40PJio1aFltvzp1eXq4vmK/vqcfFE1lNYg3sOPKXaTqvIhg6m46/4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=purestorage.com; spf=pass smtp.mailfrom=purestorage.com; dkim=pass (2048-bit key) header.d=purestorage.com header.i=@purestorage.com header.b=YlaDTKAO; arc=none smtp.client-ip=209.85.222.226 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=purestorage.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=purestorage.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=purestorage.com header.i=@purestorage.com header.b="YlaDTKAO" Received: by mail-qk1-f226.google.com with SMTP id af79cd13be357-939a5f8d16aso884285a.3 for ; Wed, 09 Sep 2026 15:29:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=purestorage.com; s=google2022; t=1788992944; x=1789597744; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=UMfVAOprw3d03YbEriUlDSnVZxTmhvnPgihN27iwNZ0=; b=YlaDTKAOPD8G9f6lPOdiST5HYvAvKoSvlH1Q0SKuFaO04MjE6GXwrFoaECtfMuWseT i6JIP9OpSkWmJrK+hCs5zwirb9PTaYOFEIjPhwYDxXlx0M3W4slMSObihwDMwEK+8Sly JKNS3jSK+MBICrCm6z/UfNqdlcUPH6zO3SXSeob9nWcjF0qeSNpwwm4wk5vSfzAjMpae tI94U6R6t6K8/p5ch9nWGNj4sr5i2Bpp44VbJYIGDBxW/SUzU0dK+fb3ptJmA18VTkta 1aQWLCsngoLenxXlVpKPtsi8mzs2edAo/XdAkknk6Nnwomtk7366JjmabSnqOYnZa5ch K6Dw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788992944; x=1789597744; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=UMfVAOprw3d03YbEriUlDSnVZxTmhvnPgihN27iwNZ0=; b=BmWDflUnMMnTAVo0NJm8MU95/9akfNGI838oKFIJojv+aEE82RrIxORvYd3w30eE9y kcuYHwWs54oFzvJPPdvJeuwafqmtgI38Nns4jOasJt4F9vlhIf1yvIZmXFj0VdRUAg2a 8gBu/JHGQa6KgPX5L9Y+CV/koZGD42vzIp7cvRQyVr6G3IbeEUqiuydeEpQouFlFNQ+8 NrSUXWpLAZQKmAaN8w8ShTKuw01tHobCf+O5QS4k1MR/DH5jirWzydw32scvutGimhKK xuY3gyIqSbhnllUOlZDU1TN+Ko5WJE0z8nuawBdF7tz4uyuSNUMA2YbU2Usn6bL2zAcv cYvw== X-Forwarded-Encrypted: i=1; AKwUvBxHUL9pt00wA9/77KLArLj9rZc8bf94KxzR/Z6nDUhCTP9x8ZqyXJQ/BaZAXQpwKk6AJw9hCHEdAX/RsLw=@vger.kernel.org X-Gm-Message-State: AFuF++nvN11f+hjuuphag5UYcAPWYbPX5YUcDmYnfxQgyMXAYQjF/GJJ gDGilbrKwg3542J3mpYxl8VyXpyYgYBIu69TyAIK2PDehSm1cjMpeQGzJFt4Uldosgnk6Z4Lnpf URc1t2coXZrGlMrwUGPvfN8acwmunpwxHF3SmXqzxUT8Y3hfdk7w+ X-Gm-Gg: AYBFou3csJiEjHJPAOcSM7MvdAypkOVUTcY4dlD+EgCFdJh4+kWssE+o4NXQSryjAxG aOBccqvM3RWkyT+Q0TMi28loAgOmUzWEdpAxFNh9xXuGNl/1SRf/N3917bgXu1ER7DY7iWnW0KU CddUy7r/pfgczEEZZnl/2qSBk91BtbLum5nhMxhw8hIhyKwAa36NThW1ms2DhKKjfabCU5KLLdk JZmWzkcyWHPJBtJYPEQx4Ec5M8l44T1d/zGDVIkcHrXlJSDhpOKuygdEHj9jClK153t0KCicqwI MQ96sOb+25nlg8Y26bHIglIwyiFYd2TqnmBf0F2HxwEja0D5I4dfs3S0JuaXDy64ueV3Prrj7Rk DqXCAD+Ud2bAgnnrW X-Received: by 2002:a05:620a:46a0:b0:939:8a2e:68bc with SMTP id af79cd13be357-939916a0e37mr2963766485a.1.1788992943812; Wed, 09 Sep 2026 15:29:03 -0700 (PDT) Received: from c7-smtp-2026.dev.purestorage.com ([2620:125:9017:12:36:3:6:0]) by smtp-relay.gmail.com with ESMTPS id 6a1803df08f44-91040757b20sm1488646d6.24.2026.09.09.15.29.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 09 Sep 2026 15:29:03 -0700 (PDT) X-Relaying-Domain: purestorage.com Received: from dev-csander.dev.purestorage.com (bond0.slc5-n17m28-k8s.dev.purestorage.com [IPv6:2620:125:9025:20::a31:41f]) by c7-smtp-2026.dev.purestorage.com (Postfix) with ESMTP id 096AD402B2; Wed, 9 Sep 2026 16:29:03 -0600 (MDT) Received: by dev-csander.dev.purestorage.com (Postfix, from userid 1557716354) id 07299E40322; Wed, 9 Sep 2026 16:29:03 -0600 (MDT) From: Caleb Sander Mateos To: Jens Axboe , Keith Busch , Christoph Hellwig , Sagi Grimberg Cc: io-uring@vger.kernel.org, linux-nvme@lists.infradead.org, linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, Caleb Sander Mateos Subject: [PATCH 1/6] bio-integrity: remove dead bio_integrity_copy_user() error path Date: Wed, 9 Sep 2026 16:28:31 -0600 Message-ID: <20260909222836.2475352-2-csander@purestorage.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260909222836.2475352-1-csander@purestorage.com> References: <20260909222836.2475352-1-csander@purestorage.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" If bio_integrity_add_page() in bio_integrity_copy_user() fails in the write case, bio_integrity_copy_user() will return an error after having already unpinned the user pages. The release_pages label in bio_integrity_map_user() would then unpin the pages a second time. Thankfully, bio_integrity_add_page() can't fail here because the bio_integrity_payload is freshly allocated, so bip_vcnt is 0. Replace the unreachable error path with a WARN_ON_ONCE(). Signed-off-by: Caleb Sander Mateos --- block/bio-integrity.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/block/bio-integrity.c b/block/bio-integrity.c index b23e2434d80c..8ba8bfa41f8a 100644 --- a/block/bio-integrity.c +++ b/block/bio-integrity.c @@ -299,19 +299,13 @@ static int bio_integrity_copy_user(struct bio *bio, s= truct bio_vec *bvec, else memcpy(&bip->bip_vec[1], bvec, nr_vecs * sizeof(*bvec)); =20 ret =3D bio_integrity_add_page(bio, virt_to_page(buf), len, offset_in_page(buf)); - if (ret !=3D len) { - ret =3D -ENOMEM; - goto free_bip; - } - + WARN_ON_ONCE(ret !=3D len); bip->bip_flags |=3D BIP_COPY_USER; return 0; -free_bip: - bio_integrity_free(bio); free_buf: kfree(buf); return ret; } =20 --=20 2.55.0 From nobody Fri Sep 25 17:45:13 2026 Received: from mail-pl1-f227.google.com (mail-pl1-f227.google.com [209.85.214.227]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E4F2248EC9E for ; Wed, 9 Sep 2026 22:29:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.227 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788992959; cv=none; b=DJsb2cWN5TNnd3P9dgb4rJ9MNOWvU75yWLZ9quI5xesEAb6wpq98kVP5cdl20PrPaTXI4BcvVNwpfOi77VINt1HMfnm3pRKaQA1TsZRWrQJNGyjYrL6UvwuGHjt9T02xQ2wIRBiDyJkl3ZmfI3fpmGFF2JkYdo1S/vEln5xUmA4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788992959; c=relaxed/simple; bh=OdVOZ5O8bsyIlL1MZXztJGFmGTxDsLLSFGFWiYbuuh4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=f6TuYMVeu/Q7iu6uhFkWgELwL/LPhZENYEIWNdrNRY9n+2O4fDy1HPYKUIQPybd3pZ2AAozU91IXX529nrCofCz672tTETs9rF31+PA73fzsRIwoTX0kMXfZmGP3+B/28vYp8cb+ot7cmBdYo5dmNQ3U4Ea8jsRqLadvTDMt2Iw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=purestorage.com; spf=pass smtp.mailfrom=purestorage.com; dkim=pass (2048-bit key) header.d=purestorage.com header.i=@purestorage.com header.b=US7gi+ib; arc=none smtp.client-ip=209.85.214.227 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=purestorage.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=purestorage.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=purestorage.com header.i=@purestorage.com header.b="US7gi+ib" Received: by mail-pl1-f227.google.com with SMTP id d9443c01a7336-2db63ec5ac6so265925ad.3 for ; Wed, 09 Sep 2026 15:29:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=purestorage.com; s=google2022; t=1788992944; x=1789597744; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=tubVMf7ZqCGq+soHl3bfDL6vCCu/4h0yxEEMGvUD99M=; b=US7gi+ib679tUwmyt5JgXnZ8F5gwTnEUKsksikAtRJxhWl5jgigBZ269pc+7Ut8i0g pKmb8pp7tyIG7P8ci/9dtwX1T0O6m5MSp2Ujg3MVuvwdlIIhagbU0c/eLkt2flXk8Z26 iad9EmMoJ4ijNW+3r3BEKQn6pqv/9GnfS1V5xBr/hI+UMIfUcc4It9nENG5iSz7S8iHn rEzAhtOxzAUPSsopeYNytUTxvQNiByCLNePEknkjRJAtmmdR344Ei7R58gxIWlStwUEB CEeSezQivzHAenRG2D/jTcJWuhawqs5MAl/PFFn/Ng6SJn9/ikBYTaA22eoRu3JJATre jnOQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788992944; x=1789597744; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=tubVMf7ZqCGq+soHl3bfDL6vCCu/4h0yxEEMGvUD99M=; b=ihlr7WQB/Y4X+xJeJNu1W3vAi4wnzBVkHMcioH+xieIJUoZn9+y5vSvsEclBprwMfs QWZBBAu8pGD/4xMl+fhGYk6BOiiHSTRy6nY754sk8QQ/SuB/xvT49hABZokXiRm2ut1M glYE0DdS1C8hMup7HzhmWmEL/aGYDbhYC2go3c5YbqML2Hq5PIxSa10xYqUMhu29MnX2 7M44ryxSCMSb88EwlC8E0eEvhQAm7ExjlQLbWony9LXNwJA8RtDJR4Xiy59YP08Qqeq7 cL9mfO2xD6H6oqz/cQgtqxAVyFJor0VuOSsIcyfRsIONQNtgtVhodIf3aK60OKudn6KR kzeg== X-Forwarded-Encrypted: i=1; AKwUvByxegFAxVI1exj5WP4DTBDEkx5NyDyq6Exdo7WX4bPip/r3Wp31doVNAuRSKvkARr92xkhGwUyB8tlkYtk=@vger.kernel.org X-Gm-Message-State: AFuF++lfjWbOAbdVdGiED5vm+fJ5txdy7XLBSxPDd7E4990z1k5Fw053 V2zCWdnnYBIraKV09bf1vOjcwsWWogorbvt3sjnyveZLO6SPjwQB9h8xsrrj7+qDEsLNYEo5ifr F4x/Nq80CRfCZaq5+FkvId8wNs59tQcwPRuEqBkYw0b2RKyZW9Hsk X-Gm-Gg: AYBFou1frSYkLZI4CYHPkTsahelQfbzGr5GO4qLSsBQiaErNGuZElt9Di7XBu6OPazp nAlEJKLc3DSAftWP+n6Q9NiKhTSLSk+PK0DRTsAExwYtJuFIgCQPoExz4v2RqYWMGaST8372HWe t8NNIXh20ySM5qiRBRT2RCs6As/X+5tUXVT9ASbX4jtHu6Vdeqiobz63YbabmmWmanOEtH7nMNR ysbc7AZwiXwFaS/R7G4qpUQLSwp1pVBMQ/wC+KirDonvOBryft9ZomEQF81fY/kekbKwMzA9Edk 5G6jcqmGE7bGdQ0h5wB/Q045NNY/l1Ha2AEmBJNeOoofuwHM4wLy+kBUXErB2pO/+Z6oXJ/ExpY sdoDeKG0m6XnPmfYc7w== X-Received: by 2002:a17:90b:3a48:b0:38e:480b:99a5 with SMTP id 98e67ed59e1d1-39b3d5e53d5mr26180113a91.2.1788992943993; Wed, 09 Sep 2026 15:29:03 -0700 (PDT) Received: from c7-smtp-2026.dev.purestorage.com ([2620:125:9017:12:36:3:6:0]) by smtp-relay.gmail.com with ESMTPS id 98e67ed59e1d1-39cd207d69csm504304a91.3.2026.09.09.15.29.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 09 Sep 2026 15:29:03 -0700 (PDT) X-Relaying-Domain: purestorage.com Received: from dev-csander.dev.purestorage.com (dev-csander.dev.purestorage.com [10.112.12.104]) by c7-smtp-2026.dev.purestorage.com (Postfix) with ESMTP id 2CF4E402B4; Wed, 9 Sep 2026 16:29:03 -0600 (MDT) Received: by dev-csander.dev.purestorage.com (Postfix, from userid 1557716354) id 2A37BE40322; Wed, 9 Sep 2026 16:29:03 -0600 (MDT) From: Caleb Sander Mateos To: Jens Axboe , Keith Busch , Christoph Hellwig , Sagi Grimberg Cc: io-uring@vger.kernel.org, linux-nvme@lists.infradead.org, linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, Caleb Sander Mateos Subject: [PATCH 2/6] nvme/ioctl: remove struct nvme_uring_data Date: Wed, 9 Sep 2026 16:28:32 -0600 Message-ID: <20260909222836.2475352-3-csander@purestorage.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260909222836.2475352-1-csander@purestorage.com> References: <20260909222836.2475352-1-csander@purestorage.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" This struct is only used once as a local variable type. Make the fields separate local variables and remove the struct type to shave some lines. Signed-off-by: Caleb Sander Mateos --- drivers/nvme/host/ioctl.c | 36 +++++++++++++++--------------------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/drivers/nvme/host/ioctl.c b/drivers/nvme/host/ioctl.c index 3aa5d2f2dfbb..748a4cbf7e90 100644 --- a/drivers/nvme/host/ioctl.c +++ b/drivers/nvme/host/ioctl.c @@ -406,18 +406,10 @@ static int nvme_user_cmd64(struct nvme_ctrl *ctrl, st= ruct nvme_ns *ns, } =20 return status; } =20 -struct nvme_uring_data { - __u64 metadata; - __u64 addr; - __u32 data_len; - __u32 metadata_len; - __u32 timeout_ms; -}; - /* * This overlays struct io_uring_cmd pdu. * Expect build errors if this grows larger than that. */ struct nvme_uring_cmd_pdu { @@ -483,17 +475,19 @@ static int nvme_uring_cmd_io(struct nvme_ctrl *ctrl, = struct nvme_ns *ns, struct nvme_uring_cmd_pdu *pdu =3D nvme_uring_cmd_pdu(ioucmd); const struct nvme_uring_cmd *cmd =3D io_uring_sqe128_cmd(ioucmd->sqe, struct nvme_uring_cmd); struct request_queue *q =3D ns ? ns->queue : ctrl->admin_q; bool open_for_write =3D ioucmd->file->f_mode & FMODE_WRITE; - struct nvme_uring_data d; struct nvme_command c; struct iov_iter iter; struct iov_iter *map_iter =3D NULL; struct request *req; blk_opf_t rq_flags =3D 0; blk_mq_req_flags_t blk_flags =3D 0; + u32 metadata_len, data_len; + u64 metadata, addr; + u32 timeout_ms; int ret; =20 c.common.opcode =3D READ_ONCE(cmd->opcode); c.common.flags =3D READ_ONCE(cmd->flags); if (c.common.flags) @@ -516,25 +510,25 @@ static int nvme_uring_cmd_io(struct nvme_ctrl *ctrl, = struct nvme_ns *ns, c.common.cdw15 =3D cpu_to_le32(READ_ONCE(cmd->cdw15)); =20 if (!nvme_cmd_allowed(ctrl, ns, &c, 0, open_for_write)) return -EACCES; =20 - d.metadata =3D READ_ONCE(cmd->metadata); - d.addr =3D READ_ONCE(cmd->addr); - d.data_len =3D READ_ONCE(cmd->data_len); - d.metadata_len =3D READ_ONCE(cmd->metadata_len); - d.timeout_ms =3D READ_ONCE(cmd->timeout_ms); + metadata =3D READ_ONCE(cmd->metadata); + addr =3D READ_ONCE(cmd->addr); + data_len =3D READ_ONCE(cmd->data_len); + metadata_len =3D READ_ONCE(cmd->metadata_len); + timeout_ms =3D READ_ONCE(cmd->timeout_ms); =20 - if (d.data_len && (ioucmd->flags & IORING_URING_CMD_FIXED)) { + if (data_len && (ioucmd->flags & IORING_URING_CMD_FIXED)) { int ddir =3D nvme_is_write(&c) ? WRITE : READ; =20 if (vec) ret =3D io_uring_cmd_import_fixed_vec(ioucmd, - u64_to_user_ptr(d.addr), d.data_len, + u64_to_user_ptr(addr), data_len, ddir, &iter, issue_flags); else - ret =3D io_uring_cmd_import_fixed(d.addr, d.data_len, + ret =3D io_uring_cmd_import_fixed(addr, data_len, ddir, &iter, ioucmd, issue_flags); if (ret < 0) return ret; =20 map_iter =3D &iter; @@ -548,15 +542,15 @@ static int nvme_uring_cmd_io(struct nvme_ctrl *ctrl, = struct nvme_ns *ns, rq_flags |=3D REQ_POLLED; =20 req =3D nvme_alloc_user_request(q, &c, rq_flags, blk_flags); if (IS_ERR(req)) return PTR_ERR(req); - req->timeout =3D d.timeout_ms ? msecs_to_jiffies(d.timeout_ms) : 0; + req->timeout =3D timeout_ms ? msecs_to_jiffies(timeout_ms) : 0; =20 - if (d.data_len) { - ret =3D nvme_map_user_request(req, d.addr, d.data_len, - nvme_to_user_ptr(d.metadata), d.metadata_len, + if (data_len) { + ret =3D nvme_map_user_request(req, addr, data_len, + nvme_to_user_ptr(metadata), metadata_len, map_iter, vec ? NVME_IOCTL_VEC : 0); if (ret) goto out_free_req; } =20 --=20 2.55.0 From nobody Fri Sep 25 17:45:13 2026 Received: from mail-ua1-f98.google.com (mail-ua1-f98.google.com [209.85.222.98]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3906546C847 for ; Wed, 9 Sep 2026 22:29:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.222.98 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788992955; cv=none; b=tTBVXYHsVzawl2XPIfHK+/wcUoQaIMTOdt8o6dUwcRBk/Tff7dPhYrVXxMtaRFGx9Bc6raTuB7GaBZFT2jp0E4js7zEeG5JOJ/b2H3vg8w6PGxWXmnJM4u4WHQ+DN5zmloHv+ODYGCLGwHLHeAxIgL9uoR8pG2P0v0CEOVqqCqU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788992955; c=relaxed/simple; bh=sLx20K+qsQCJyEhfpGSQLav0qN/DYI0usp+NjaEikj4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=lQLz2dTZ/Cb9x/Z6MXB+/WsP0X+GjkRPuQdvHl0sKb1leB851ruH9n7lTWzZ44xjqlR11nDWz/WXoUNM+nEP1pzARTCz9GJMAVS7DvBjMInGjjQZec9a11cVbysDZEywPiC8e+nt3WgDudMwSx1e4dljaVTa/VUPQ4dOQHpx3Os= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=purestorage.com; spf=pass smtp.mailfrom=purestorage.com; dkim=pass (2048-bit key) header.d=purestorage.com header.i=@purestorage.com header.b=KsbjO2R7; arc=none smtp.client-ip=209.85.222.98 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=purestorage.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=purestorage.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=purestorage.com header.i=@purestorage.com header.b="KsbjO2R7" Received: by mail-ua1-f98.google.com with SMTP id a1e0cc1a2514c-97e989aedb3so37807241.1 for ; Wed, 09 Sep 2026 15:29:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=purestorage.com; s=google2022; t=1788992944; x=1789597744; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=bsGabQTCyGBOnewN0WNVIraAhvd9VdUc8vuvn8dczvo=; b=KsbjO2R7+0OPuTjY3C0ERl15E9eo9zWNKvSfvZRhnCNfUd90OlEj7rfh4C7rB4rkP0 2cCEevAEmeEkCHuG9+rH8yckFQWVsVRgXN9OnrAhOgtYBNNGdATsAg/IkLstcw/SGAr1 rqq3GIM50w1PHJo9I9Rtt2WP6nCdfGXhmodTLpi5Crkb7eVcMZOPWeak6oGP4RfzVq5L ax0VGJ/en1AF94r5bTaJ53CMkMrvPonSGJwfF5k+i0VsPl1Kh+YWdRMj/REhPXNWtEmv yUlUNDeMHRDe+IPYSGtsyJy04SXbHxk2d66uwJmLcXRCJhF0QNzkTyZj/sLvHq8A0SfV M8eA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788992944; x=1789597744; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=bsGabQTCyGBOnewN0WNVIraAhvd9VdUc8vuvn8dczvo=; b=Z/kFRGvxUob3VJsaW19uk7p2ou3Qsrh7Oqn4MlnLX2JnYzNWlFmQ1Ix1mr+5CNGNVe N1lKFB1m7cvpGFTajgY0q1LfAZzofGf1KkmBsSKz7cdKMXcoYO2u7OWpHg0gSShKWJhQ 4p3mJRrVv28Ac+o1wR4f2XmT3PoTtSbOGWMlBE4NqFB3GmDu4yBLgbqOJH9MQcr3UlpY Vvr5lUnb4rCGZ9cf388hHgfa9V4O8oyvAkkXerOSpgO420T0KAsn35ffENAPOkyZLLU9 De8FAxsXsrAoLpx/KOwwMNcyFORMBae9lGIXKWZbY7MIfyMaB9PTnIs7lHy4RjppxxRy m4HA== X-Forwarded-Encrypted: i=1; AKwUvBzZdEVhiCMPKbGLMFLtxWpn+ZVHwvTVKLL6D6z3MyuGSP2+Xq++4G1liIuJJTaRNTJTQYKYp784lS5hLyY=@vger.kernel.org X-Gm-Message-State: AFuF++msqQwWBBp+3dmZ7VK4LzN7fslMDntYXee5QWyqbiZnrDXv9GzR e/GuAcrBsMutrrKhOp8aC8bEeTtn4hTqd1yhVbOQm4Vm5ywsUnQlC76xD1WtbamXvmX24UlhTmP rfP6gY06iKQVW0QCcyKdM2a/7fZfrw2pxqblK X-Gm-Gg: AYBFou2uBnU3z89+GrpM+fdtd4jfVWIRpStf2nlMYnmU+QeOPir0z4Xy3UgEVjt4Wu7 ORNAPOw2H7YfO6tW8eLPKHwj3LOxUF7Lqi1V88zfB8gXKjOShavMzG7c1SNeMvjK96+OCYUbXnK c89EuK3NwFdXg5Uz5WW6Vev3WcdQ3v/CvoDI5oaHZkPS18xQDkk4RIjCAtbtNVXq6tsrfAR/msl PE1REchTVYVupF9fwBvcDtbl3lrcKiqu84Ud+a1APesJv/oifWcbRmtCNoBIfIMB9+d0uABmosj U670t4tBwqqYxhfLTPpbuV4yZG0NsV3aAtt/BrXEPRzhURurpO6K6i1GfBXAV+orO+MXlq/0Oax B+ahnJCRm5b8kyCJojc/21ROVcb0Bz/Az X-Received: by 2002:a67:ebd5:0:b0:790:563:8d1b with SMTP id ada2fe7eead31-79005639f22mr1285898137.0.1788992944076; Wed, 09 Sep 2026 15:29:04 -0700 (PDT) Received: from c7-smtp-2026.dev.purestorage.com ([208.88.159.128]) by smtp-relay.gmail.com with ESMTPS id a1e0cc1a2514c-9808e9758adsm5500843241.0.2026.09.09.15.29.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 09 Sep 2026 15:29:04 -0700 (PDT) X-Relaying-Domain: purestorage.com Received: from dev-csander.dev.purestorage.com (bond0.slc5-n17m28-k8s.dev.purestorage.com [IPv6:2620:125:9025:20::a31:41f]) by c7-smtp-2026.dev.purestorage.com (Postfix) with ESMTP id 4F0D6402BA; Wed, 9 Sep 2026 16:29:03 -0600 (MDT) Received: by dev-csander.dev.purestorage.com (Postfix, from userid 1557716354) id 4C79CE40322; Wed, 9 Sep 2026 16:29:03 -0600 (MDT) From: Caleb Sander Mateos To: Jens Axboe , Keith Busch , Christoph Hellwig , Sagi Grimberg Cc: io-uring@vger.kernel.org, linux-nvme@lists.infradead.org, linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, Caleb Sander Mateos Subject: [PATCH 3/6] blk-integrity: pass iov_iter to blk_rq_integrity_map_user() Date: Wed, 9 Sep 2026 16:28:33 -0600 Message-ID: <20260909222836.2475352-4-csander@purestorage.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260909222836.2475352-1-csander@purestorage.com> References: <20260909222836.2475352-1-csander@purestorage.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" To allow blk_rq_integrity_map_user() to accept an io_uring registered buffer (represented as a ITER_BVEC iov_iter), take the buffer as an iov_iter argument. Move the conversion from a user address-length pair into an iov_iter to the caller. Since a non-ITER_UBUF iov_iter could be passed in the future, iov_iter_extract_pages() in bio_integrity_map_user() won't necessarily pin the pages. Condition the page unpins on iov_iter_extract_will_pin(). Add a BIP_PAGE_PINNED bit to bip_flags to track if the pages are pinned. Signed-off-by: Caleb Sander Mateos --- block/bio-integrity.c | 43 +++++++++++++++++++++++------------ block/blk-integrity.c | 7 ++---- drivers/nvme/host/ioctl.c | 6 ++++- include/linux/bio-integrity.h | 1 + include/linux/blk-integrity.h | 6 ++--- 5 files changed, 38 insertions(+), 25 deletions(-) diff --git a/block/bio-integrity.c b/block/bio-integrity.c index 8ba8bfa41f8a..3a5554d3ea2f 100644 --- a/block/bio-integrity.c +++ b/block/bio-integrity.c @@ -187,11 +187,12 @@ static void bio_integrity_uncopy_user(struct bio_inte= grity_payload *bip) =20 iov_iter_bvec(&orig_iter, ITER_DEST, orig_bvecs, orig_nr_vecs, bytes); ret =3D copy_to_iter(bvec_virt(bounce_bvec), bytes, &orig_iter); WARN_ON_ONCE(ret !=3D bytes); =20 - bio_integrity_unpin_bvec(orig_bvecs, orig_nr_vecs); + if (bip->bip_flags & BIP_PAGE_PINNED) + bio_integrity_unpin_bvec(orig_bvecs, orig_nr_vecs); } =20 /** * bio_integrity_unmap_user - Unmap user integrity payload * @bio: bio containing bip to be unmapped @@ -207,11 +208,12 @@ void bio_integrity_unmap_user(struct bio *bio) bio_integrity_uncopy_user(bip); kfree(bvec_virt(bip->bip_vec)); return; } =20 - bio_integrity_unpin_bvec(bip->bip_vec, bip->bip_max_vcnt); + if (bip->bip_flags & BIP_PAGE_PINNED) + bio_integrity_unpin_bvec(bip->bip_vec, bip->bip_max_vcnt); } =20 /** * bio_integrity_add_page - Attach integrity metadata * @bio: bio to update @@ -257,11 +259,11 @@ int bio_integrity_add_page(struct bio *bio, struct pa= ge *page, return len; } EXPORT_SYMBOL(bio_integrity_add_page); =20 static int bio_integrity_copy_user(struct bio *bio, struct bio_vec *bvec, - int nr_vecs, unsigned int len) + int nr_vecs, unsigned int len, bool pinned) { bool write =3D op_is_write(bio_op(bio)); struct bio_integrity_payload *bip; struct iov_iter iter; void *buf; @@ -292,14 +294,18 @@ static int bio_integrity_copy_user(struct bio *bio, s= truct bio_vec *bvec, if (IS_ERR(bip)) { ret =3D PTR_ERR(bip); goto free_buf; } =20 - if (write) - bio_integrity_unpin_bvec(bvec, nr_vecs); - else + if (write) { + if (pinned) + bio_integrity_unpin_bvec(bvec, nr_vecs); + } else { memcpy(&bip->bip_vec[1], bvec, nr_vecs * sizeof(*bvec)); + if (pinned) + bip->bip_flags |=3D BIP_PAGE_PINNED; + } =20 ret =3D bio_integrity_add_page(bio, virt_to_page(buf), len, offset_in_page(buf)); WARN_ON_ONCE(ret !=3D len); bip->bip_flags |=3D BIP_COPY_USER; @@ -308,27 +314,29 @@ static int bio_integrity_copy_user(struct bio *bio, s= truct bio_vec *bvec, kfree(buf); return ret; } =20 static int bio_integrity_init_user(struct bio *bio, struct bio_vec *bvec, - int nr_vecs, unsigned int len) + int nr_vecs, unsigned int len, bool pinned) { struct bio_integrity_payload *bip; =20 bip =3D bio_integrity_alloc(bio, GFP_KERNEL, nr_vecs); if (IS_ERR(bip)) return PTR_ERR(bip); =20 memcpy(bip->bip_vec, bvec, nr_vecs * sizeof(*bvec)); bip->bip_iter.bi_size =3D len; bip->bip_vcnt =3D nr_vecs; + if (pinned) + bip->bip_flags |=3D BIP_PAGE_PINNED; return 0; } =20 static unsigned int bvec_from_pages(struct bio_vec *bvec, struct page **pa= ges, int nr_vecs, ssize_t bytes, ssize_t offset, - bool *is_p2p) + bool *is_p2p, bool pinned) { unsigned int nr_bvecs =3D 0; int i, j; =20 for (i =3D 0; i < nr_vecs; i =3D j) { @@ -340,11 +348,12 @@ static unsigned int bvec_from_pages(struct bio_vec *b= vec, struct page **pages, size_t next =3D min_t(size_t, PAGE_SIZE, bytes); =20 if (page_folio(pages[j]) !=3D folio || pages[j] !=3D pages[j - 1] + 1) break; - unpin_user_page(pages[j]); + if (pinned) + unpin_user_page(pages[j]); size +=3D next; bytes -=3D next; } =20 if (is_pci_p2pdma_page(pages[i])) @@ -361,10 +370,11 @@ static unsigned int bvec_from_pages(struct bio_vec *b= vec, struct page **pages, int bio_integrity_map_user(struct bio *bio, struct iov_iter *iter) { struct request_queue *q =3D bdev_get_queue(bio->bi_bdev); struct page *stack_pages[UIO_FASTIOV], **pages =3D stack_pages; struct bio_vec stack_vec[UIO_FASTIOV], *bvec =3D stack_vec; + bool pinned =3D iov_iter_extract_will_pin(iter); iov_iter_extraction_t extraction_flags =3D 0; size_t offset, bytes =3D iter->count; bool copy, is_p2p =3D false; unsigned int nr_bvecs; int ret, nr_vecs; @@ -397,12 +407,12 @@ int bio_integrity_map_user(struct bio *bio, struct io= v_iter *iter) =20 /* * Handle partial pinning. This can happen when pin_user_pages_fast() * returns fewer pages than requested. */ - if (user_backed_iter(iter) && unlikely(ret !=3D bytes)) { - if (ret > 0) { + if (unlikely(ret !=3D bytes)) { + if (pinned && ret > 0) { int npinned =3D DIV_ROUND_UP(offset + ret, PAGE_SIZE); int i; =20 for (i =3D 0; i < npinned; i++) unpin_user_page(pages[i]); @@ -412,31 +422,34 @@ int bio_integrity_map_user(struct bio *bio, struct io= v_iter *iter) ret =3D -EFAULT; goto free_bvec; } =20 nr_bvecs =3D bvec_from_pages(bvec, pages, nr_vecs, bytes, offset, - &is_p2p); + &is_p2p, pinned); if (pages !=3D stack_pages) kvfree(pages); if (nr_bvecs > queue_max_integrity_segments(q)) copy =3D true; if (is_p2p) bio->bi_opf |=3D REQ_NOMERGE; =20 if (copy) - ret =3D bio_integrity_copy_user(bio, bvec, nr_bvecs, bytes); + ret =3D bio_integrity_copy_user(bio, bvec, nr_bvecs, bytes, + pinned); else - ret =3D bio_integrity_init_user(bio, bvec, nr_bvecs, bytes); + ret =3D bio_integrity_init_user(bio, bvec, nr_bvecs, bytes, + pinned); if (ret) goto release_pages; if (bvec !=3D stack_vec) kfree(bvec); =20 return 0; =20 release_pages: - bio_integrity_unpin_bvec(bvec, nr_bvecs); + if (pinned) + bio_integrity_unpin_bvec(bvec, nr_bvecs); free_bvec: if (bvec !=3D stack_vec) kfree(bvec); return ret; } diff --git a/block/blk-integrity.c b/block/blk-integrity.c index 964eebbee14d..6977bfd96927 100644 --- a/block/blk-integrity.c +++ b/block/blk-integrity.c @@ -118,18 +118,15 @@ int blk_get_meta_cap(struct block_device *bdev, unsig= ned int cmd, out: return copy_struct_to_user(argp, usize, &meta_cap, sizeof(meta_cap), NULL); } =20 -int blk_rq_integrity_map_user(struct request *rq, void __user *ubuf, - ssize_t bytes) +int blk_rq_integrity_map_user(struct request *rq, struct iov_iter *iter) { int ret; - struct iov_iter iter; =20 - iov_iter_ubuf(&iter, rq_data_dir(rq), ubuf, bytes); - ret =3D bio_integrity_map_user(rq->bio, &iter); + ret =3D bio_integrity_map_user(rq->bio, iter); if (ret) return ret; =20 rq->nr_integrity_segments =3D blk_rq_count_integrity_sg(rq->q, rq->bio); rq->cmd_flags |=3D REQ_INTEGRITY; diff --git a/drivers/nvme/host/ioctl.c b/drivers/nvme/host/ioctl.c index 748a4cbf7e90..e69c49c334a0 100644 --- a/drivers/nvme/host/ioctl.c +++ b/drivers/nvme/host/ioctl.c @@ -175,11 +175,15 @@ static int nvme_map_user_request(struct request *req,= u64 ubuffer, 0, rq_data_dir(req)); if (ret) return ret; =20 if (has_metadata) { - ret =3D blk_rq_integrity_map_user(req, meta_buffer, meta_len); + struct iov_iter meta_iter; + + iov_iter_ubuf(&meta_iter, rq_data_dir(req), meta_buffer, + meta_len); + ret =3D blk_rq_integrity_map_user(req, &meta_iter); if (ret) goto out_unmap; } =20 return ret; diff --git a/include/linux/bio-integrity.h b/include/linux/bio-integrity.h index 0ea2a8bf7efb..740acb8c1077 100644 --- a/include/linux/bio-integrity.h +++ b/include/linux/bio-integrity.h @@ -12,10 +12,11 @@ enum bip_flags { BIP_COPY_USER =3D 1 << 4, /* Kernel bounce buffer in use */ BIP_CHECK_GUARD =3D 1 << 5, /* guard check */ BIP_CHECK_REFTAG =3D 1 << 6, /* reftag check */ BIP_CHECK_APPTAG =3D 1 << 7, /* apptag check */ =20 + BIP_PAGE_PINNED =3D 1 << 14, /* pages need to be unpinned */ BIP_MEMPOOL =3D 1 << 15, /* buffer backed by mempool */ }; =20 /* flags that require generate/verify action. */ #define BIP_CHECK_FLAGS (BIP_CHECK_GUARD | BIP_CHECK_REFTAG | BIP_CHECK_AP= PTAG) diff --git a/include/linux/blk-integrity.h b/include/linux/blk-integrity.h index b1b530613c34..8b655ac165e8 100644 --- a/include/linux/blk-integrity.h +++ b/include/linux/blk-integrity.h @@ -28,12 +28,11 @@ static inline bool queue_limits_stack_integrity_bdev(st= ruct queue_limits *t, =20 #ifdef CONFIG_BLK_DEV_INTEGRITY int blk_rq_map_integrity_sg(struct request *, struct scatterlist *); =20 int blk_rq_count_integrity_sg(struct request_queue *, struct bio *); -int blk_rq_integrity_map_user(struct request *rq, void __user *ubuf, - ssize_t bytes); +int blk_rq_integrity_map_user(struct request *rq, struct iov_iter *iter); int blk_get_meta_cap(struct block_device *bdev, unsigned int cmd, struct logical_block_metadata_cap __user *argp); bool blk_rq_integrity_dma_map_iter_start(struct request *req, struct device *dma_dev, struct dma_iova_state *state, struct blk_dma_iter *iter); @@ -116,12 +115,11 @@ static inline int blk_rq_map_integrity_sg(struct requ= est *q, struct scatterlist *s) { return 0; } static inline int blk_rq_integrity_map_user(struct request *rq, - void __user *ubuf, - ssize_t bytes) + struct iov_iter *iter) { return -EINVAL; } static inline bool blk_rq_integrity_dma_map_iter_start(struct request *req, struct device *dma_dev, struct dma_iova_state *state, --=20 2.55.0 From nobody Fri Sep 25 17:45:13 2026 Received: from mail-pj1-f98.google.com (mail-pj1-f98.google.com [209.85.216.98]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E0A68493D24 for ; Wed, 9 Sep 2026 22:29:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.98 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788992962; cv=none; b=s6ZlkP9cU5bgdreZldSw8YfeQ3nYgik0b1qh/dh0XBArts/7JBmhGy3pMdSvATIsgmhLrH/k07c+BE4mG1VjBr4ARPRA6TYdWhg+KyXjqcLJcq+GkoT0785ZJze9syQitHcgjwZhdIfjS/Xfee7Y56w3sN/QMHJ0ITtWl/KKp64= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788992962; c=relaxed/simple; bh=Y6jx5aTPCjcHCvNdP8/O5bbbCvk9DUcwaVIqR2GXaWs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=n3ZL7sT8QJBnJEhgFlDlobhQ4y1GV7hJHJtOSJG+zPtNGdz3fgqfN7P3vKlzZp5CTvlWyBlvhjvlVAEqT6pzxtHwnx2f4SrvLXM2IOs+UY4X3DJFqJGKY6LE1hJ1p1OTQbORmcPkGnmNlNzjeuB6R3/6wpC1AMgOQ/Dlz+m93XY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=purestorage.com; spf=pass smtp.mailfrom=purestorage.com; dkim=pass (2048-bit key) header.d=purestorage.com header.i=@purestorage.com header.b=U3zYG8FG; arc=none smtp.client-ip=209.85.216.98 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=purestorage.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=purestorage.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=purestorage.com header.i=@purestorage.com header.b="U3zYG8FG" Received: by mail-pj1-f98.google.com with SMTP id 98e67ed59e1d1-396555b8c7cso222520a91.3 for ; Wed, 09 Sep 2026 15:29:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=purestorage.com; s=google2022; t=1788992944; x=1789597744; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=l/XCD1uvPOJyUiPbDDQ58GyUdQGYRiCCBtvMcX3nnGY=; b=U3zYG8FGJozjx9rGIndZZqS+MVtMIeRoO/iKFGLw9gpeFcDeX42e98DT19YD+B1Pt/ AMkfyg4isW06WQlhf2REXSWlrAlKgGKw2yMDxuoX1sUX4EBLRnypR3e8mMv4ui3puay2 ClLvJC+wCSefPB5m/UjhgxwP3RFA35/09ruGxKnCm6GZZhEZZnSbrdG9EA4dxzmpMYdv SWuMrc2a/PlPOGbWpcnUiUMwW/YMsTt7K6bM4V3wBOy0VHDl9W+81CZl/yMnv+yJhnEN GromVttp92g68II/uSWS0Q59q6WyKNLxw3yNWWFhlZxf2u6O56XHn97qo/mAsyfWUPSW s63g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788992944; x=1789597744; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=l/XCD1uvPOJyUiPbDDQ58GyUdQGYRiCCBtvMcX3nnGY=; b=apDulc5DaKLgg2RXFJh1zklLK0AJJVXCi2FphGMdCERjR0f4kYkYFquTM/mv63YTaT wWc9AfR5JRAPz98KOMT1XAs7pBZF3hXzCTy6Gp3aQQL3ldJaC+pHQrDC69Z/25z0NVxb /jRSYzk0/VGUZMud7UYiKd57jvRiB/P2NxEYB0R96s+qQaa/yZbjbKqi63+r8vhQyr9S RmX32YzB9c0LW8FcSdMKH3IzNXQRDjncOEkz0VITKGiaj4dmObo5OYfula52G1TqiajG lFBo0tgTWTXlHOzLQe4pW8H3yp8yL24Dh7a2s8xOUdNFHRLqPoLEBwPXqTddu9LPyfNl VFSQ== X-Forwarded-Encrypted: i=1; AKwUvBxEkZXW0vsVqifVpoa7yE1JyblEyHsfQrLyr6bvMMY7MivYljOVzla1wLzvZQ8ZCuEnc8c5Zb5ZjRPWCRE=@vger.kernel.org X-Gm-Message-State: AFuF++n55658MCMn43tgjxuwxHJJTKrvQ5uTAV4v6lkni/bmGOreqAiT juB2/WWqVRy7U7E0T5bRQkkIaaZPyhkHDk09qi4aq1x+RbaH8vWWmi186J6p5L/29pPw5oLds10 mEoLn/TJDJUltptRTDsCCiDj7xkaocLyUZb+b X-Gm-Gg: AYBFou0ZHK0uiikKdg/XrK21OqNgORcVl6np6ajF7O5lzR7dXOHMnKqXU2pmgnvRNyd lnXyykuyTS252I+YHZUCN1NVtNAmsdsvQqe5YMirvk1eS8wqBe88hg/QAuEbK05NklVl+mUKDwe MrYfLuBiI5Q08eRLcHhUg/S2R52PcMmcSB6xNYWRUhINyC86qt85uvM0Db8oSLG6DfMS88yZWp/ 3fHtCS4mcGtjjQpFg8jWIE4u2QUgYazcsCFHzvSKECgwj8dU6V5M3U0u+qVt1nSpPtxL/IwFMLw g1QGM/RHkWuSiEDD2uYTXVIzTY5pPKPxixWGbfQPbqTgwtBVMc1S3E1Qhkr1Qo/wumqnkmId10O eesPujxmdB3064hwoipfJZ4OWqx6TJS4S X-Received: by 2002:a17:90b:4c03:b0:398:bac7:72d0 with SMTP id 98e67ed59e1d1-39b3d86acf2mr28286214a91.5.1788992944093; Wed, 09 Sep 2026 15:29:04 -0700 (PDT) Received: from c7-smtp-2026.dev.purestorage.com ([208.88.159.129]) by smtp-relay.gmail.com with ESMTPS id 98e67ed59e1d1-39d77406179sm490126a91.5.2026.09.09.15.29.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 09 Sep 2026 15:29:04 -0700 (PDT) X-Relaying-Domain: purestorage.com Received: from dev-csander.dev.purestorage.com (bond0.slc5-n17m28-k8s.dev.purestorage.com [IPv6:2620:125:9025:20::a31:41f]) by c7-smtp-2026.dev.purestorage.com (Postfix) with ESMTP id 6EFA1401CC; Wed, 9 Sep 2026 16:29:03 -0600 (MDT) Received: by dev-csander.dev.purestorage.com (Postfix, from userid 1557716354) id 6C2CBE40322; Wed, 9 Sep 2026 16:29:03 -0600 (MDT) From: Caleb Sander Mateos To: Jens Axboe , Keith Busch , Christoph Hellwig , Sagi Grimberg Cc: io-uring@vger.kernel.org, linux-nvme@lists.infradead.org, linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, Caleb Sander Mateos Subject: [PATCH 4/6] nvme/ioctl: pass iov_iter to nvme_map_user_request() Date: Wed, 9 Sep 2026 16:28:34 -0600 Message-ID: <20260909222836.2475352-5-csander@purestorage.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260909222836.2475352-1-csander@purestorage.com> References: <20260909222836.2475352-1-csander@purestorage.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" To allow nvme_map_user_request() to accept an io_uring registered buffer (represented as a ITER_BVEC iov_iter) for the metadata buffer, pass it as an iov_iter argument. Move the conversions from user address-length pairs into iov_iters to the callers. A NULL iov_iter pointer represents no metadata buffer. Signed-off-by: Caleb Sander Mateos --- drivers/nvme/host/ioctl.c | 46 +++++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/drivers/nvme/host/ioctl.c b/drivers/nvme/host/ioctl.c index e69c49c334a0..8e722184ecf1 100644 --- a/drivers/nvme/host/ioctl.c +++ b/drivers/nvme/host/ioctl.c @@ -152,21 +152,20 @@ static struct request *nvme_alloc_user_request(struct= request_queue *q, nvme_req(req)->flags |=3D NVME_REQ_USERCMD; return req; } =20 static int nvme_map_user_request(struct request *req, u64 ubuffer, - unsigned bufflen, void __user *meta_buffer, unsigned meta_len, - struct iov_iter *iter, unsigned int flags) + unsigned bufflen, struct iov_iter *iter, + struct iov_iter *meta_iter, unsigned int flags) { struct request_queue *q =3D req->q; struct nvme_ns *ns =3D q->queuedata; struct block_device *bdev =3D ns ? ns->disk->part0 : NULL; bool supports_metadata =3D bdev && blk_get_integrity(bdev->bd_disk); - bool has_metadata =3D meta_buffer && meta_len; int ret; =20 - if (has_metadata && !supports_metadata) + if (meta_iter && !supports_metadata) return -EINVAL; =20 if (iter) ret =3D blk_rq_map_user_iov(q, req, NULL, iter, GFP_KERNEL); else @@ -174,16 +173,12 @@ static int nvme_map_user_request(struct request *req,= u64 ubuffer, bufflen, GFP_KERNEL, flags & NVME_IOCTL_VEC, 0, 0, rq_data_dir(req)); if (ret) return ret; =20 - if (has_metadata) { - struct iov_iter meta_iter; - - iov_iter_ubuf(&meta_iter, rq_data_dir(req), meta_buffer, - meta_len); - ret =3D blk_rq_integrity_map_user(req, &meta_iter); + if (meta_iter) { + ret =3D blk_rq_integrity_map_user(req, meta_iter); if (ret) goto out_unmap; } =20 return ret; @@ -210,12 +205,20 @@ static int nvme_submit_user_cmd(struct request_queue = *q, if (IS_ERR(req)) return PTR_ERR(req); =20 req->timeout =3D timeout; if (ubuffer && bufflen) { - ret =3D nvme_map_user_request(req, ubuffer, bufflen, meta_buffer, - meta_len, NULL, flags); + struct iov_iter meta_iter; + struct iov_iter *map_meta_iter =3D NULL; + + if (meta_buffer && meta_len) { + iov_iter_ubuf(&meta_iter, rq_data_dir(req), meta_buffer, + meta_len); + map_meta_iter =3D &meta_iter; + } + ret =3D nvme_map_user_request(req, ubuffer, bufflen, NULL, + map_meta_iter, flags); if (ret) goto out_free_req; } =20 bio =3D req->bio; @@ -480,18 +483,19 @@ static int nvme_uring_cmd_io(struct nvme_ctrl *ctrl, = struct nvme_ns *ns, const struct nvme_uring_cmd *cmd =3D io_uring_sqe128_cmd(ioucmd->sqe, struct nvme_uring_cmd); struct request_queue *q =3D ns ? ns->queue : ctrl->admin_q; bool open_for_write =3D ioucmd->file->f_mode & FMODE_WRITE; struct nvme_command c; - struct iov_iter iter; - struct iov_iter *map_iter =3D NULL; + struct iov_iter iter, meta_iter; + struct iov_iter *map_iter =3D NULL, *map_meta_iter =3D NULL; struct request *req; blk_opf_t rq_flags =3D 0; blk_mq_req_flags_t blk_flags =3D 0; u32 metadata_len, data_len; u64 metadata, addr; u32 timeout_ms; + int ddir; int ret; =20 c.common.opcode =3D READ_ONCE(cmd->opcode); c.common.flags =3D READ_ONCE(cmd->flags); if (c.common.flags) @@ -520,13 +524,12 @@ static int nvme_uring_cmd_io(struct nvme_ctrl *ctrl, = struct nvme_ns *ns, addr =3D READ_ONCE(cmd->addr); data_len =3D READ_ONCE(cmd->data_len); metadata_len =3D READ_ONCE(cmd->metadata_len); timeout_ms =3D READ_ONCE(cmd->timeout_ms); =20 + ddir =3D nvme_is_write(&c) ? WRITE : READ; if (data_len && (ioucmd->flags & IORING_URING_CMD_FIXED)) { - int ddir =3D nvme_is_write(&c) ? WRITE : READ; - if (vec) ret =3D io_uring_cmd_import_fixed_vec(ioucmd, u64_to_user_ptr(addr), data_len, ddir, &iter, issue_flags); else @@ -535,10 +538,15 @@ static int nvme_uring_cmd_io(struct nvme_ctrl *ctrl, = struct nvme_ns *ns, if (ret < 0) return ret; =20 map_iter =3D &iter; } + if (data_len && metadata && metadata_len) { + iov_iter_ubuf(&meta_iter, ddir, nvme_to_user_ptr(metadata), + metadata_len); + map_meta_iter =3D &meta_iter; + } =20 if (issue_flags & IO_URING_F_NONBLOCK) { rq_flags |=3D REQ_NOWAIT; blk_flags =3D BLK_MQ_REQ_NOWAIT; } @@ -549,13 +557,13 @@ static int nvme_uring_cmd_io(struct nvme_ctrl *ctrl, = struct nvme_ns *ns, if (IS_ERR(req)) return PTR_ERR(req); req->timeout =3D timeout_ms ? msecs_to_jiffies(timeout_ms) : 0; =20 if (data_len) { - ret =3D nvme_map_user_request(req, addr, data_len, - nvme_to_user_ptr(metadata), metadata_len, - map_iter, vec ? NVME_IOCTL_VEC : 0); + ret =3D nvme_map_user_request(req, addr, data_len, map_iter, + map_meta_iter, + vec ? NVME_IOCTL_VEC : 0); if (ret) goto out_free_req; } =20 /* to free bio on completion, as req->bio will be null at that time */ --=20 2.55.0 From nobody Fri Sep 25 17:45:13 2026 Received: from mail-qk1-f228.google.com (mail-qk1-f228.google.com [209.85.222.228]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 034BF48EC7E for ; Wed, 9 Sep 2026 22:29:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.222.228 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788992968; cv=none; b=dBrLft2B3a4SNcEuZ0qxmdKq9VLUkL0JZto+QamcTtXKn0tly/KAwgDekjwL7XkVi2I75WRh0+r5raSim+6j0S1CBcdveldiyWFALaV51RNNlAeE2UxKA0TdkZWiMuqNO/CxlkM8VNFkxJSgjFEyCWyY4MB0Ytamt2tchL/WGlg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788992968; c=relaxed/simple; bh=B911PpGVigFDT/lyg40PRj0j9/EeMB1ax4L+zlh+iVQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=nYz0aFSDDsHnRVBWgK4XT3kMLIwJacsaF0JwL7VMqjzp3LCcZ1tlqQ45fVE6XRbPOedFCWCmmBKR9BnvrgwJ+jJyKsTDWc222ZpZ8/EadFFzAG8vrrth39f8qwhqeaVrEF0dl6Ws64ncT5GajeY7e0tbz0XUJKUuaH5AazPXBcA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=purestorage.com; spf=pass smtp.mailfrom=purestorage.com; dkim=pass (2048-bit key) header.d=purestorage.com header.i=@purestorage.com header.b=apqMWr8y; arc=none smtp.client-ip=209.85.222.228 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=purestorage.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=purestorage.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=purestorage.com header.i=@purestorage.com header.b="apqMWr8y" Received: by mail-qk1-f228.google.com with SMTP id af79cd13be357-937690ef0c4so8063385a.2 for ; Wed, 09 Sep 2026 15:29:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=purestorage.com; s=google2022; t=1788992944; x=1789597744; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=SaILBiW8UVywRg2XqjSRQl5ll5pe+zqen2OGZ/aVaeY=; b=apqMWr8y1QBmToJJeRZK+n/Q15/jkVnTxyLCjlN3RF4ozMIBzobUxoXqUrnjYF7CDK dSp/1OJc+tPjgV9r5TDfEG8A02MQh3xkbsEDBfA3YUJH/QOkkH9lgXUaVqD3X+uRvfbY JX8DxUvPk4OrX5aMOA2pOV9RYnXIlc2/j9euHcDsfkFDAfAUUEYkDBZRn9A9y09g7YK+ Ca+bna2H7ALrQNLLLU/q9GKtY28TImhEHRDqe+sPQhlAapFIBymueDBcFQ8t5I6FcYuT dFTiU9W6LyGSTyM2aSGOR5wBfjul9sAZeQ0N7+9UZ2iBxnnSgb2q0ReE9Bp7ckqMUWcK U6Gw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788992944; x=1789597744; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=SaILBiW8UVywRg2XqjSRQl5ll5pe+zqen2OGZ/aVaeY=; b=OQsY8FAGwmE8n6SfUX0yghYClT+K074yRQB4zsc3TmJrM3ZaUJFGAwyQ30ST4XcF6p Nsn/XdgVSKgTfP3jisuezq5yC7PPj2UbD5DeL4iLyT+iZEObvFkbidloNmKQmFtFsHBL 8nsl3qvCW8/4zZXIYo/qwmk3lXhxIs8o9+9ss+UmhUfLFqGvb9i0ED6mSLo+PnZiAwfv 7Qaq/0l4lJTGBLEGHbVko6CziO3zG+F1Ll09Ez2kXxNuStkCWJ27rrk/v+++7aimzqLU rmSB87kdBpFPlMOjizEeAf2sqjuwPiT6BIaP88gZJ9kLRsZAlp1kwuBJu25LCoLiYbND zieA== X-Forwarded-Encrypted: i=1; AKwUvBz/X7IHhBG1F/L6JDC76rJWq9+rhgKapwNRGqASuwR7wGuPUAqgVgff/8Ebw8Y9WTUQ/1zGxUgjNLMlXdU=@vger.kernel.org X-Gm-Message-State: AFuF++kYk2UqoX5RDhvTpIFlwjU4rtfGGZ3VnO4Q2W/Eu3HhxBkXFqKT nrSvDk5H1xOUwj+LnfIzwiJphlwJbjTiY6A1a9J65db93C4CUUDfiiAfF/gnPcKusCDk3lMJgwx 6pj7ceC3YKcL28b7uKWIljMibuCa0aueXhXoCMlTUajdKJ0zqxl2s X-Gm-Gg: AYBFou3+NtGxjqCVKhDUPzk2FUdisMAKUh2+vUzZCQGS45H6i5RkNw7PjTlxr9uSoHg mxCbm9YZBA5FdYBTbB7509GMalrqrOu08eEOKYXapt/Qxo6ZtDqcV6JLVJB1Bwb9b1lX/v5Qmz8 XjDBwVGgwNK6fN9fYiRBgT14j3XPhO3p6JfYsrnnTKLugMoks13gUiSY4vohTAAzXceIOPe3Cj/ NWA01YLutnJSnrNL3lV3SR4Ke/7WmbmhOn7r/bLOligNwhhkrNno4FXbqG8iwMtyQPTttwUf6L4 +k/XmKGBu4KRgs8qr0WaV5ruCs9ZVY1YVivtNeEMw1p1+r7ZNI2aCP+IP69ieNkuiw04jWoFrBz 79keYIjhbaXnrWZC7nw== X-Received: by 2002:a05:620a:e85:b0:939:94c4:b799 with SMTP id af79cd13be357-93994c4b856mr1986140585a.5.1788992944190; Wed, 09 Sep 2026 15:29:04 -0700 (PDT) Received: from c7-smtp-2026.dev.purestorage.com ([2620:125:9017:12:36:3:6:0]) by smtp-relay.gmail.com with ESMTPS id af79cd13be357-939981ed680sm140542785a.3.2026.09.09.15.29.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 09 Sep 2026 15:29:04 -0700 (PDT) X-Relaying-Domain: purestorage.com Received: from dev-csander.dev.purestorage.com (dev-csander.dev.purestorage.com [10.112.12.104]) by c7-smtp-2026.dev.purestorage.com (Postfix) with ESMTP id 8F14E402A4; Wed, 9 Sep 2026 16:29:03 -0600 (MDT) Received: by dev-csander.dev.purestorage.com (Postfix, from userid 1557716354) id 8CB61E40322; Wed, 9 Sep 2026 16:29:03 -0600 (MDT) From: Caleb Sander Mateos To: Jens Axboe , Keith Busch , Christoph Hellwig , Sagi Grimberg Cc: io-uring@vger.kernel.org, linux-nvme@lists.infradead.org, linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, Caleb Sander Mateos Subject: [PATCH 5/6] io_uring/cmd: support fixed buffer for metadata Date: Wed, 9 Sep 2026 16:28:35 -0600 Message-ID: <20260909222836.2475352-6-csander@purestorage.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260909222836.2475352-1-csander@purestorage.com> References: <20260909222836.2475352-1-csander@purestorage.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Allow a "metadata" io_uring fixed buffer to be imported by uring_cmds in addition to the existing data buffer node. NVMe passthrough requests will use the new buffer node for their metadata buffers if requested. Provide a function io_uring_cmd_import_fixed_metadata() analogous to io_uring_cmd_import_fixed() that initializes an iov_iter for a user address range contained within a fixed buffer. The buffer node is stored in previously unused space in struct io_uring_cmd so it can be reused if imported multiple times and released once the uring_cmd completes. Whereas a fixed data buffer is indicated by io_uring_sqe's uring_cmd_flags bit IORING_URING_CMD_FIXED and buf_index, how the fixed metadata buffer is specified is left up to the uring_cmd implementation. io_get_buf_node() is split out of io_find_buf_node() and moved to rsrc.h so it can be reused for the metadata buffer. io_import_fixed() is made extern so it can be called from uring_cmd.c, and io_rsrc_node is passed instead of io_mapped_ubuf so uring_cmd.c doesn't have to reach into io_rsrc_node. Signed-off-by: Caleb Sander Mateos --- include/linux/io_uring/cmd.h | 12 +++++++++++- io_uring/rsrc.c | 28 +++++++++++----------------- io_uring/rsrc.h | 17 +++++++++++++++++ io_uring/uring_cmd.c | 30 +++++++++++++++++++++++++++++- 4 files changed, 68 insertions(+), 19 deletions(-) diff --git a/include/linux/io_uring/cmd.h b/include/linux/io_uring/cmd.h index 2e4368d611ee..6df5f3bf5628 100644 --- a/include/linux/io_uring/cmd.h +++ b/include/linux/io_uring/cmd.h @@ -16,11 +16,11 @@ struct io_uring_cmd { struct file *file; const struct io_uring_sqe *sqe; u32 cmd_op; u32 flags; u8 pdu[32]; /* available inline for free use */ - u8 unused[8]; + struct io_rsrc_node *metadata_node; }; =20 #define io_uring_sqe128_cmd(sqe, type) ({ \ BUILD_BUG_ON(sizeof(type) > ((2 * sizeof(struct io_uring_sqe)) - \ offsetof(struct io_uring_sqe, cmd))); \ @@ -68,10 +68,14 @@ int io_uring_cmd_import_fixed(u64 ubuf, unsigned long l= en, int rw, int io_uring_cmd_import_fixed_vec(struct io_uring_cmd *ioucmd, const struct iovec __user *uvec, size_t uvec_segs, int ddir, struct iov_iter *iter, unsigned issue_flags); +int io_uring_cmd_import_fixed_metadata(struct io_uring_cmd *ioucmd, + u16 buf_index, u64 ubuf, size_t len, + int ddir, struct iov_iter *iter, + unsigned int issue_flags); =20 /* * Completes the request, i.e. posts an io_uring CQE and deallocates @iouc= md * and the corresponding io_uring request. * @@ -125,10 +129,16 @@ static inline int io_uring_cmd_import_fixed_vec(struc= t io_uring_cmd *ioucmd, int ddir, struct iov_iter *iter, unsigned issue_flags) { return -EOPNOTSUPP; } +static inline int io_uring_cmd_import_fixed_metadata( + struct io_uring_cmd *ioucmd, u16 buf_index, u64 ubuf, size_t len, + int ddir, struct iov_iter *iter, unsigned int issue_flags) +{ + return -EOPNOTSUPP; +} static inline void __io_uring_cmd_done(struct io_uring_cmd *cmd, unsigned issue_flags) { } static inline void __io_uring_cmd_do_in_task(struct io_uring_cmd *ioucmd, diff --git a/io_uring/rsrc.c b/io_uring/rsrc.c index 174f74cbbf60..4bd69803c470 100644 --- a/io_uring/rsrc.c +++ b/io_uring/rsrc.c @@ -1134,14 +1134,14 @@ static int io_import_kbuf(int ddir, struct iov_iter= *iter, iov_iter_bvec(iter, ddir, imu->bvec, imu->nr_bvecs, count); iov_iter_advance(iter, offset); return 0; } =20 -static int io_import_fixed(int ddir, struct iov_iter *iter, - struct io_mapped_ubuf *imu, - u64 buf_addr, size_t len) +int io_import_fixed(int ddir, struct iov_iter *iter, struct io_rsrc_node *= node, + u64 buf_addr, size_t len) { + struct io_mapped_ubuf *imu =3D node->buf; const struct bio_vec *bvec; size_t folio_mask; unsigned nr_segs; size_t offset; int ret; @@ -1189,28 +1189,22 @@ static int io_import_fixed(int ddir, struct iov_ite= r *iter, } =20 inline struct io_rsrc_node *io_find_buf_node(struct io_kiocb *req, unsigned issue_flags) { - struct io_ring_ctx *ctx =3D req->ctx; struct io_rsrc_node *node; =20 if (req->flags & REQ_F_BUF_NODE) return req->buf_node; - req->flags |=3D REQ_F_BUF_NODE; =20 - io_ring_submit_lock(ctx, issue_flags); - node =3D io_rsrc_node_lookup(&ctx->buf_table, req->buf_index); - if (node) { - node->refs++; - req->buf_node =3D node; - io_ring_submit_unlock(ctx, issue_flags); - return node; - } - req->flags &=3D ~REQ_F_BUF_NODE; - io_ring_submit_unlock(ctx, issue_flags); - return NULL; + node =3D io_get_buf_node(req, req->buf_index, issue_flags); + if (!node) + return NULL; + + req->flags |=3D REQ_F_BUF_NODE; + req->buf_node =3D node; + return node; } =20 int io_import_reg_buf(struct io_kiocb *req, struct iov_iter *iter, u64 buf_addr, size_t len, int ddir, unsigned issue_flags) @@ -1218,11 +1212,11 @@ int io_import_reg_buf(struct io_kiocb *req, struct = iov_iter *iter, struct io_rsrc_node *node; =20 node =3D io_find_buf_node(req, issue_flags); if (!node) return -EFAULT; - return io_import_fixed(ddir, iter, node->buf, buf_addr, len); + return io_import_fixed(ddir, iter, node, buf_addr, len); } =20 static int io_buffer_acct_cloned_hpages(struct io_ring_ctx *ctx, struct io_mapped_ubuf *imu) { diff --git a/io_uring/rsrc.h b/io_uring/rsrc.h index eacfdb70f203..277e2007803d 100644 --- a/io_uring/rsrc.h +++ b/io_uring/rsrc.h @@ -4,10 +4,11 @@ =20 #include #include #include #include +#include "io_uring.h" =20 #define IO_VEC_CACHE_SOFT_CAP 256 =20 enum { IORING_RSRC_FILE =3D 0, @@ -64,10 +65,12 @@ void io_free_rsrc_node(struct io_ring_ctx *ctx, struct = io_rsrc_node *node); void io_rsrc_data_free(struct io_ring_ctx *ctx, struct io_rsrc_data *data); int io_rsrc_data_alloc(struct io_rsrc_data *data, unsigned nr); =20 struct io_rsrc_node *io_find_buf_node(struct io_kiocb *req, unsigned issue_flags); +int io_import_fixed(int ddir, struct iov_iter *iter, struct io_rsrc_node *= node, + u64 buf_addr, size_t len); int io_import_reg_buf(struct io_kiocb *req, struct iov_iter *iter, u64 buf_addr, size_t len, int ddir, unsigned issue_flags); int io_import_reg_vec(int ddir, struct iov_iter *iter, struct io_kiocb *req, struct iou_vec *vec, @@ -100,10 +103,24 @@ static inline struct io_rsrc_node *io_rsrc_node_looku= p(struct io_rsrc_data *data if (index < data->nr) return data->nodes[array_index_nospec(index, data->nr)]; return NULL; } =20 +static inline struct io_rsrc_node * +io_get_buf_node(const struct io_kiocb *req, u16 buf_index, unsigned issue_= flags) +{ + struct io_ring_ctx *ctx =3D req->ctx; + struct io_rsrc_node *node; + + io_ring_submit_lock(ctx, issue_flags); + node =3D io_rsrc_node_lookup(&ctx->buf_table, buf_index); + if (node) + node->refs++; + io_ring_submit_unlock(ctx, issue_flags); + return node; +} + static inline void io_put_rsrc_node(struct io_ring_ctx *ctx, struct io_rsr= c_node *node) { lockdep_assert_held(&ctx->uring_lock); if (!--node->refs) io_free_rsrc_node(ctx, node); diff --git a/io_uring/uring_cmd.c b/io_uring/uring_cmd.c index 3d5d8b5f4ebb..e4b384094392 100644 --- a/io_uring/uring_cmd.c +++ b/io_uring/uring_cmd.c @@ -25,19 +25,25 @@ void io_cmd_cache_free(const void *entry) =20 static void io_req_uring_cleanup(struct io_kiocb *req, unsigned int issue_= flags) { struct io_uring_cmd *ioucmd =3D io_kiocb_to_cmd(req, struct io_uring_cmd); struct io_async_cmd *ac =3D req->async_data; + struct io_ring_ctx *ctx =3D req->ctx; =20 if (issue_flags & IO_URING_F_UNLOCKED) return; =20 + if (ioucmd->metadata_node) { + io_put_rsrc_node(ctx, ioucmd->metadata_node); + ioucmd->metadata_node =3D NULL; + } + io_alloc_cache_vec_kasan(&ac->vec); if (ac->vec.nr > IO_VEC_CACHE_SOFT_CAP) io_vec_free(&ac->vec); =20 - if (io_alloc_cache_put(&req->ctx->cmd_cache, ac)) { + if (io_alloc_cache_put(&ctx->cmd_cache, ac)) { ioucmd->sqe =3D NULL; io_req_async_data_clear(req, REQ_F_NEED_CLEANUP); } else { io_vec_free(&ac->vec); } @@ -194,10 +200,11 @@ int io_uring_cmd_prep(struct io_kiocb *req, const str= uct io_uring_sqe *sqe) if (!ac) return -ENOMEM; if (ac->vec.iovec) req->flags |=3D REQ_F_NEED_CLEANUP; ioucmd->sqe =3D sqe; + ioucmd->metadata_node =3D NULL; return 0; } =20 /* * IORING_SETUP_SQE128 contexts allocate twice the normal SQE size for each @@ -303,10 +310,31 @@ int io_uring_cmd_import_fixed_vec(struct io_uring_cmd= *ioucmd, return io_import_reg_vec(ddir, iter, req, &ac->vec, uvec_segs, issue_flags); } EXPORT_SYMBOL_GPL(io_uring_cmd_import_fixed_vec); =20 +int io_uring_cmd_import_fixed_metadata(struct io_uring_cmd *ioucmd, + u16 buf_index, u64 ubuf, size_t len, + int ddir, struct iov_iter *iter, + unsigned int issue_flags) +{ + struct io_rsrc_node *buf_node =3D ioucmd->metadata_node; + + if (!buf_node) { + struct io_kiocb *req =3D cmd_to_io_kiocb(ioucmd); + + buf_node =3D io_get_buf_node(req, buf_index, issue_flags); + if (!buf_node) + return -EFAULT; + + req->flags |=3D REQ_F_NEED_CLEANUP; + ioucmd->metadata_node =3D buf_node; + } + return io_import_fixed(ddir, iter, buf_node, ubuf, len); +} +EXPORT_SYMBOL_GPL(io_uring_cmd_import_fixed_metadata); + void io_uring_cmd_issue_blocking(struct io_uring_cmd *ioucmd) { struct io_kiocb *req =3D cmd_to_io_kiocb(ioucmd); =20 io_queue_iowq(req); --=20 2.55.0 From nobody Fri Sep 25 17:45:13 2026 Received: from mail-ot1-f100.google.com (mail-ot1-f100.google.com [209.85.210.100]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E5D0D48EC80 for ; Wed, 9 Sep 2026 22:29:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.100 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788992952; cv=none; b=MuPgAXJUKWsfnW/hWuizPBiGEAgVjGmEcnjEvRPL8lipmqUN3oxHc+y+4oR+xXfvABUqTqH+DyVCnHTZ6cZclqtiPDqtiMneZnZ3vR0pUAUSsxL9K83GLSKOm0ATwp7RLPjvfNJtFTBsPNuyA0S9YbJm9Srh6lIwfnGOTFznqxg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788992952; c=relaxed/simple; bh=ZsRCPU0J121h1w/y85vunBI0gv6iQjmpHXlh3qUdYlg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=fh/hJ5aHSNyzuaQwTZ9KwLNGa0dPtB/bwMW3/nQ6q70cEy/MeFcg01N6lhSciE+GDKXmiSHziOPL7L/9r6UF5e1uqT/n7dQTDzxpLeazZL4wgAMiaXQsb5LRjAs4AMRuzL+vnE9MeSTryVLl0s41RbqkNV8IVYGWQ0gnR132r/8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=purestorage.com; spf=pass smtp.mailfrom=purestorage.com; dkim=pass (2048-bit key) header.d=purestorage.com header.i=@purestorage.com header.b=LMnDcxSW; arc=none smtp.client-ip=209.85.210.100 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=purestorage.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=purestorage.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=purestorage.com header.i=@purestorage.com header.b="LMnDcxSW" Received: by mail-ot1-f100.google.com with SMTP id 46e09a7af769-7ec6d9a81b0so78178a34.3 for ; Wed, 09 Sep 2026 15:29:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=purestorage.com; s=google2022; t=1788992944; x=1789597744; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=ImWYQroYLYn1yUntaG3yDyG9poZ7C84uz/cQieFkqu0=; b=LMnDcxSWOPQs3Iluim5mr8nhBkssXls8io+aEc8xhd83PNawOi0+HS6tnL3fvPYHaF Z0iCc+OYZyTwjDW/F7qqK6yJag2bT21rnE2ASpUB/iZ8TmQjXU/O46v3sSrqcT04NA1E dtwypgDV+a3DHU9lUzP0dckuysAdmbq7A/WKjXl5/lKNWkcZBNVY4gyAjX6sEGR6jkpk jCrxkSHb80WRk0Bti8ABy1rfmvmoOn3W9Uw0g44odA4sEEH6c8PkWTw6ii23hZSiGNJc 7pi6YE71ax6Tib3PdUBqj7Cmr7GDnTAkUbGvx7YnJjbSUa9v40Tb0IwmJD7QzcVmYCUY gwDw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788992944; x=1789597744; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=ImWYQroYLYn1yUntaG3yDyG9poZ7C84uz/cQieFkqu0=; b=CnxFMemqKR5I9QRp7DU7MkfqaAC9gmI87XngaxKNPA+bFFIONxK0txbY2/N8zLVL9t sT+RFT9oDciNwEpAUXNBTWRIcGGh+9zfKtFXSSFf5YAEutn3UAtCRM8grzeX1AD3BlF+ P7z9oUUo/Z6mNgZ9RHV+onm+Prnx+dhS8LEfX6lqqNggSZZWjQV4YLXrYlg71wkdqpCw D3dg67t7zoxkMBcNFeMflEBrc9ZxtiQzXWlAowHN+PZAIqUURNOzXTELTUMhBfcX3hHG TjRu3/z9p+42ZoIkaPWgqIcsNt7xzgBOldR5OFYaj0Vg9brGowiG14cnCYc18+bUMf2+ iGEw== X-Forwarded-Encrypted: i=1; AKwUvByLelDqxAbiYm5rvlntvfJlFxnOmCjZPfuTxEccKiWhQQvFbwV9JLxdfcJcVxnHjoJEIsmH6sXoXgap8to=@vger.kernel.org X-Gm-Message-State: AFuF++lEPNJPCgMfVPMsrKhPmlybZu7kVFqrPDe+k3+9v4Ee/ToVTReZ doXwLIYF1zBIzkOyLIh6YexQaf6DVN7KkTCghWz1iE6JfvxUhlPRQW9e8g0NvDek8/zogpRagme t9jgM3hKeCCdS/G5Jcwzs3OY2sOjOrFLs9Yr+ X-Gm-Gg: AYBFou1G/1Q2xPrbXJI41nI+gheSVrj+PyFLpeDz5kXeUJHBCYF6d/tpq3VrRVngcXn GsOEsNZU+FrVUqT1g1XZbgaotntjSQjo078+UMtS2XysAGkQC0DjBCUaqbe6NvjV3BXLXLPyINE c50Ju9rT44CEqgazrqjcPxxQRiCQvDtUfM0QoyU0feT8Fr1eq6i0cFhoNGIFvzFnDNcGyXQtkwc 8QGVcajwRUD3ffbtou9c3CrA0TnYn0f84OYD2cqfHgHJBJ95BHUI3jbnFTVi1S+9BAofLRpP8Fl oiH/R8tCDvq2h5mNcNgeW/B5V4JcTYmpIcgLAl3a1o+IYhRx789wiTYzzs+/XlEdeB/xTOho4VP U6LpQM3n8of0vtQTmdhhocLaBoeJNeuse X-Received: by 2002:a05:6830:f89:b0:7ee:363d:ce16 with SMTP id 46e09a7af769-7fb76e3cd73mr16877278a34.0.1788992944121; Wed, 09 Sep 2026 15:29:04 -0700 (PDT) Received: from c7-smtp-2026.dev.purestorage.com ([208.88.159.129]) by smtp-relay.gmail.com with ESMTPS id 46e09a7af769-7f9f6aa689fsm2773280a34.5.2026.09.09.15.29.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 09 Sep 2026 15:29:04 -0700 (PDT) X-Relaying-Domain: purestorage.com Received: from dev-csander.dev.purestorage.com (dev-csander.dev.purestorage.com [10.112.12.104]) by c7-smtp-2026.dev.purestorage.com (Postfix) with ESMTP id AFA1C402BE; Wed, 9 Sep 2026 16:29:03 -0600 (MDT) Received: by dev-csander.dev.purestorage.com (Postfix, from userid 1557716354) id AD682E40322; Wed, 9 Sep 2026 16:29:03 -0600 (MDT) From: Caleb Sander Mateos To: Jens Axboe , Keith Busch , Christoph Hellwig , Sagi Grimberg Cc: io-uring@vger.kernel.org, linux-nvme@lists.infradead.org, linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, Caleb Sander Mateos Subject: [PATCH 6/6] nvme/ioctl: support fixed buffer for metadata Date: Wed, 9 Sep 2026 16:28:36 -0600 Message-ID: <20260909222836.2475352-7-csander@purestorage.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260909222836.2475352-1-csander@purestorage.com> References: <20260909222836.2475352-1-csander@purestorage.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" io_uring NVMe passthrough supports using a "fixed" (registered) buffer for data, but not metadata. On high-IOPS workloads, the pinning and unpinning overhead for the metadata pages is significant and could be avoided if fixed metadata buffers were supported. Define a NVME_URING_CMD_FIXED_METADATA bit for the nvme_uring_cmd's flags field (which is currently required to be 0) to indicate that the metadata buffer belongs to a fixed buffer registered with the io_uring. The metadata fixed buffer index is specified in a metadata_buf_index field replacing the existing rsvd1 in nvme_uring_cmd. If NVME_URING_CMD_FIXED_METADATA is set, the metadata iov_iter is obtained from io_uring_cmd_import_fixed_metadata() instead of iov_iter_ubuf(). Signed-off-by: Caleb Sander Mateos --- drivers/nvme/host/ioctl.c | 21 ++++++++++++++++----- include/uapi/linux/nvme_ioctl.h | 5 ++++- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/drivers/nvme/host/ioctl.c b/drivers/nvme/host/ioctl.c index 8e722184ecf1..4da8cf92c2e0 100644 --- a/drivers/nvme/host/ioctl.c +++ b/drivers/nvme/host/ioctl.c @@ -488,21 +488,22 @@ static int nvme_uring_cmd_io(struct nvme_ctrl *ctrl, = struct nvme_ns *ns, struct iov_iter iter, meta_iter; struct iov_iter *map_iter =3D NULL, *map_meta_iter =3D NULL; struct request *req; blk_opf_t rq_flags =3D 0; blk_mq_req_flags_t blk_flags =3D 0; + u8 flags =3D READ_ONCE(cmd->flags); u32 metadata_len, data_len; u64 metadata, addr; u32 timeout_ms; int ddir; int ret; =20 - c.common.opcode =3D READ_ONCE(cmd->opcode); - c.common.flags =3D READ_ONCE(cmd->flags); - if (c.common.flags) + if (flags & ~NVME_URING_CMD_FIXED_METADATA) return -EINVAL; =20 + c.common.opcode =3D READ_ONCE(cmd->opcode); + c.common.flags =3D 0; c.common.command_id =3D 0; c.common.nsid =3D cpu_to_le32(cmd->nsid); if (!nvme_validate_passthru_nsid(ctrl, ns, le32_to_cpu(c.common.nsid))) return -EINVAL; =20 @@ -539,12 +540,22 @@ static int nvme_uring_cmd_io(struct nvme_ctrl *ctrl, = struct nvme_ns *ns, return ret; =20 map_iter =3D &iter; } if (data_len && metadata && metadata_len) { - iov_iter_ubuf(&meta_iter, ddir, nvme_to_user_ptr(metadata), - metadata_len); + if (flags & NVME_URING_CMD_FIXED_METADATA) { + u16 buf_index =3D READ_ONCE(cmd->metadata_buf_index); + + ret =3D io_uring_cmd_import_fixed_metadata( + ioucmd, buf_index, metadata, metadata_len, ddir, + &meta_iter, issue_flags); + if (ret < 0) + return ret; + } else { + iov_iter_ubuf(&meta_iter, ddir, nvme_to_user_ptr(metadata), + metadata_len); + } map_meta_iter =3D &meta_iter; } =20 if (issue_flags & IO_URING_F_NONBLOCK) { rq_flags |=3D REQ_NOWAIT; diff --git a/include/uapi/linux/nvme_ioctl.h b/include/uapi/linux/nvme_ioct= l.h index 2f76cba67166..93973f636b48 100644 --- a/include/uapi/linux/nvme_ioctl.h +++ b/include/uapi/linux/nvme_ioctl.h @@ -68,15 +68,18 @@ struct nvme_passthru_cmd64 { __u32 timeout_ms; __u32 rsvd2; __u64 result; }; =20 +/* struct nvme_uring_cmd flags field bits */ +#define NVME_URING_CMD_FIXED_METADATA (1U << 0) + /* same as struct nvme_passthru_cmd64, minus the 8b result field */ struct nvme_uring_cmd { __u8 opcode; __u8 flags; - __u16 rsvd1; + __u16 metadata_buf_index; __u32 nsid; __u32 cdw2; __u32 cdw3; __u64 metadata; __u64 addr; --=20 2.55.0