From nobody Thu Feb 3 14:38:19 2022 X-Original-To: dev-commits-src-branches@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 8DF7C198A307; Thu, 3 Feb 2022 14:38:19 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4JqLrC39Rdz3Fxv; Thu, 3 Feb 2022 14:38:19 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1643899099; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=Ui94ZFMoCtwtwBYx+irzcpomE0H3fw9lM1QxLoEBpEo=; b=Bw/Lzt0Ff25S351l/+7WFf95qUN9i/F58Td8lbhev/2FO1wRr3V3wjCXRuveblb+b9X8Ch x9afukeeFyj9dVXIpza5aSSmB2sUlWZRlBjfqhBrY2TDfkR7IHAhtTZLRMmjuHP1JqU2yt rZz3F+b1vOu5nDhOn6rNIDXh0Ky9vxNgDOOzsS3S4T4gS1VkiYhAOnXrAq352Ao1IU5oY1 kAEzqbQY7oPrsGuqqDnIrAFvBDDWZTbz1ZyOz3ibpEe5Sk2kU5LLfIDXYhLci/raj8B6Ml RdbzAE2OVvPWYfZx7OK8Tc5ps369IBmHW4uFjXXiims5tjocy1IHdO24sfmHQg== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4DF3F1985D; Thu, 3 Feb 2022 14:38:19 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 213EcJ0i037123; Thu, 3 Feb 2022 14:38:19 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 213EcJ68037122; Thu, 3 Feb 2022 14:38:19 GMT (envelope-from git) Date: Thu, 3 Feb 2022 14:38:19 GMT Message-Id: <202202031438.213EcJ68037122@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Mark Johnston Subject: git: f6e755d1b26b - stable/13 - geom: Handle partial I/O in g_{read,write,delete}_data() List-Id: Commits to the stable branches of the FreeBSD src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-branches@freebsd.org X-BeenThere: dev-commits-src-branches@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: markj X-Git-Repository: src X-Git-Refname: refs/heads/stable/13 X-Git-Reftype: branch X-Git-Commit: f6e755d1b26bf0ef476cf81749c3c83534f3a9a7 Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1643899099; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=Ui94ZFMoCtwtwBYx+irzcpomE0H3fw9lM1QxLoEBpEo=; b=I9NwwygDS2srHFfBT67eXRI7ni7Mq3CFKNHtFwXC7R/JQ+ZmnNVj0F6lITezEl7LIZcdp/ ZOOqPtQa75z0Qc5MtABJZmaAd+I5vn57hcIy7sBYk25Y78BvgdvZ0SGUwiesVud+sLBUE5 f1B3nBXqB5iFv0ia5NLyrnSm3+5IC7r7d+ucUxaiQXpxei/UXEL0k0egIvnhUE5tjWrDJu nj6RwB5MF52D7iFPrinNx7qKX0RwasGDt+pqY2dHV/wfSO/geAzU3cpYd87ZF6ez8hdXkd ZuwfAjqiKowotJbj9lSoz6XdeRlnYl12s6VNqeVE3AE9Gmc7okHZ2PFr2bg2ow== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1643899099; a=rsa-sha256; cv=none; b=HybGLgEa3+7VegLrYXbXNasDPFSzxaTV8MQ9TZbtJ2/hT+XuXC6FX+tEsqzJ03TLf1cVmQ 0zqvmKtVkblT75s8rnlMWfGiFsSUN7tODUKtGB/AP7CCmGllM/HWOoOEP8cgZ66h+Zilt3 cFnPdN3gYGsiXxPlFN9w8U904EWBA/zZ+bArKC0ne+xM01PHOLiAKrf6zUCdoUauzjRhhb dPCL3Hg2tGM11rst0r4jNrdcby/QU1EmWH8CS/pl9bl45kGZKAjJ8EXNkAzfRhPp6VgfEb AaB38XR0jW6F+rLgFZ7UpoxpiL87UZUioFi8G227LsdJz+gZsoqynztb9DK2BA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch stable/13 has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=f6e755d1b26bf0ef476cf81749c3c83534f3a9a7 commit f6e755d1b26bf0ef476cf81749c3c83534f3a9a7 Author: Mark Johnston AuthorDate: 2022-01-20 13:25:27 +0000 Commit: Mark Johnston CommitDate: 2022-02-03 14:34:27 +0000 geom: Handle partial I/O in g_{read,write,delete}_data() These routines are used internally by GEOM to dispatch I/O requests to a provider, typically for tasting or for updating GEOM class metadata blocks. These routines assumed that partial I/O did not occur without setting BIO_ERROR, but this is possible in at least two cases: - Some or all of the I/O range is beyond the provider's mediasize. In this scenario g_io_check() truncates the bounds of the request before it is handed to the target provider. - A read from vnode-backed md(4) device returns EOF (the backing vnode is allowed to be smaller than the device itself) or partial vnode I/O occurs. In these scenarios g_read_data() could return a partially uninitialized buffer. Many consumers are not affected by the first case, since the offsets used for provider metadata or tasting are relative to the provider's mediasize, but in some cases metadata is read at fixed offsets, such as when searching for a UFS superblock using the offsets defined by SBLOCKSEARCH. Thus, modify the routines to explicitly check for a non-zero residual and return EIO in that case. Remove a related check from the DIOCGDELETE ioctl handler, it is handled within g_delete_data() now. Reviewed by: mav, imp, kib Reported by: KMSAN Sponsored by: The FreeBSD Foundation (cherry picked from commit d91d2b513eb30a226e87f0e52e2f9f232a2e1ca3) --- sys/geom/geom_dev.c | 13 ------------- sys/geom/geom_io.c | 6 ++++++ 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/sys/geom/geom_dev.c b/sys/geom/geom_dev.c index 9c33ab71e6c8..24ab14e90c1b 100644 --- a/sys/geom/geom_dev.c +++ b/sys/geom/geom_dev.c @@ -634,19 +634,6 @@ g_dev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, struct thread error = EINVAL; break; } - if ((pp->mediasize > 0) && (offset >= pp->mediasize)) { - /* - * Catch out-of-bounds requests here. The problem is - * that due to historical GEOM I/O implementation - * peculatities, g_delete_data() would always return - * success for requests starting just the next byte - * after providers media boundary. Condition check on - * non-zero media size, since that condition would - * (most likely) cause ENXIO instead. - */ - error = EIO; - break; - } while (length > 0) { chunk = length; if (g_dev_del_max_sectors != 0 && diff --git a/sys/geom/geom_io.c b/sys/geom/geom_io.c index 4134645fe618..9bdcd12bf240 100644 --- a/sys/geom/geom_io.c +++ b/sys/geom/geom_io.c @@ -886,6 +886,8 @@ g_read_data(struct g_consumer *cp, off_t offset, off_t length, int *error) bp->bio_data = ptr; g_io_request(bp, cp); errorc = biowait(bp, "gread"); + if (errorc == 0 && bp->bio_completed != length) + errorc = EIO; if (error != NULL) *error = errorc; g_destroy_bio(bp); @@ -940,6 +942,8 @@ g_write_data(struct g_consumer *cp, off_t offset, void *ptr, off_t length) bp->bio_data = ptr; g_io_request(bp, cp); error = biowait(bp, "gwrite"); + if (error == 0 && bp->bio_completed != length) + error = EIO; g_destroy_bio(bp); return (error); } @@ -971,6 +975,8 @@ g_delete_data(struct g_consumer *cp, off_t offset, off_t length) bp->bio_data = NULL; g_io_request(bp, cp); error = biowait(bp, "gdelete"); + if (error == 0 && bp->bio_completed != length) + error = EIO; g_destroy_bio(bp); return (error); }