From nobody Mon Apr 08 20:29:47 2024 X-Original-To: dev-commits-src-all@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 4VD10r1wzvz5HjF7; Mon, 8 Apr 2024 20:29:48 +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 4VD10q5jHLz463R; Mon, 8 Apr 2024 20:29:47 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1712608187; 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=2nhgzwLS2jhw8uuQNgx4oNmFQU3ccLEIWT5hk63m5IQ=; b=QkRxTIptYfW36yTL9FuRJ/L/E2AICP3ZxZI2HIOUKlOLAsMgWKvH7gwGRNc9PXFNgOWarS zY8LqsWXXXXtYxEwTOU1SUSRvAk5c1i4kAVuNs38UqnzK+4rvt9TAfF5gZ87kD2Z+GWLmQ jJsGmQg+kezqdVhsb2eQo4T0/KvAOpoS/4W+az1SxkeD8JU9wWPCT3v1kWyO7G9OoWmEYo YknPD7QxDU5JnSp1yNe/LMcv6Qy9P86sylaPU25D8nfkuGwF/IJEKf3jPMeN/J3XcxDNAP TUvBrmbYprpLeWE278f5sAY0XX8310qMIuBfC/yDWJLNPZ9g9c4WlvEJAyzc1Q== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1712608187; a=rsa-sha256; cv=none; b=Lo/TcevMqWKNK1pJefNyOzOGpqGXj0OEEwqtJP9P5mR56V7eAIOO+5NYHxXEnS9RWFiX/J A+RmBwOpQ0wJZBSV+dTwL7RF/FnEOOBq2Hy1u//64QHtRYKwMPIxRCDxx0kmSgPvEtE18T 1VPZy0K0A3tz+iVE17RNn6MZCh1U6tw3ZrDMiOktA58awShWxx6QKga0bQKet2PSVVB6M+ YoE3x6x7EYrcOCpHhOuR8cMe3494+rhQo8qQoMiyGYHqkuwNp54GUBlA1Tgd9dL1Q6+OXZ cw0yLM8HFJmK3Ii3Z6WMfLOhwbozKWDJDUlIt3NWmOR/rzuMCWGjwcpvPBIdfQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1712608187; 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=2nhgzwLS2jhw8uuQNgx4oNmFQU3ccLEIWT5hk63m5IQ=; b=s+OI3N56dHueVfvKVQZsfpiO3CoSJmvhiyrG+nCIG1GXQN0V+L/OwtTsuWhUNFJoUNRykC vsyh0XouDLJqMU5jUKFG1p7zrnVq5yXn+kcwlYjm3is8u4NQQX8IgbtdPiQNVuWjW0dcrP XAelF2KO/xtJL2zhObuvxZ2umzDG0vkBN6zH+TVl245/GLBWvX/JnxpV54zxyJkvJZTOoo TSScd1SHUCyU3EauhRgkbioRWlT7DSPovyPsvTMP1RZAwab+pfvAnfM2lOtyrc/UJmlXui TjnMRux2XWx+h+oDH5NRDwtFpbOJKwDg3PrurmAIgisHuAaCU+17xkqUK7qA2g== 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 4VD10q5KqXzQS6; Mon, 8 Apr 2024 20:29:47 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.17.1/8.17.1) with ESMTP id 438KTlGr041853; Mon, 8 Apr 2024 20:29:47 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 438KTlBE041850; Mon, 8 Apr 2024 20:29:47 GMT (envelope-from git) Date: Mon, 8 Apr 2024 20:29:47 GMT Message-Id: <202404082029.438KTlBE041850@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Gleb Smirnoff Subject: git: aba79b0f4a3f - main - mbuf: provide mc_uiotomc() a function to copy from uio(9) to mchain List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: glebius X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: aba79b0f4a3f69f070ace6effd5700d65226bd20 Auto-Submitted: auto-generated The branch main has been updated by glebius: URL: https://cgit.FreeBSD.org/src/commit/?id=aba79b0f4a3f69f070ace6effd5700d65226bd20 commit aba79b0f4a3f69f070ace6effd5700d65226bd20 Author: Gleb Smirnoff AuthorDate: 2024-04-08 20:16:51 +0000 Commit: Gleb Smirnoff CommitDate: 2024-04-08 20:16:51 +0000 mbuf: provide mc_uiotomc() a function to copy from uio(9) to mchain Implement m_uiotombuf() as a wrapper around mc_uiotomc(). The M_EXTPG is left untouched. The m_uiotombuf() is left as a compat KPI. New code should use either mc_uiotomc() or m_uiotombuf_nomap(). Reviewed by: markj, tuexen Differential Revision: https://reviews.freebsd.org/D44150 --- sys/kern/uipc_mbuf.c | 126 +++++++++++++++++++++++++++++++++------------------ sys/sys/mbuf.h | 1 + 2 files changed, 83 insertions(+), 44 deletions(-) diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c index 2593238d5445..f5f6db752883 100644 --- a/sys/kern/uipc_mbuf.c +++ b/sys/kern/uipc_mbuf.c @@ -1938,65 +1938,103 @@ failed: /* * Copy the contents of uio into a properly sized mbuf chain. + * A compat KPI. Users are recommended to use direct calls to backing + * functions. */ struct mbuf * -m_uiotombuf(struct uio *uio, int how, int len, int align, int flags) +m_uiotombuf(struct uio *uio, int how, int len, int lspace, int flags) { - struct mbuf *m, *mb; - int error, length; - ssize_t total; - int progress = 0; - if (flags & M_EXTPG) - return (m_uiotombuf_nomap(uio, how, len, align, flags)); + if (flags & M_EXTPG) { + /* XXX: 'lspace' magically becomes maxseg! */ + return (m_uiotombuf_nomap(uio, how, len, lspace, flags)); + } else if (__predict_false(uio->uio_resid + len == 0)) { + struct mbuf *m; - /* - * len can be zero or an arbitrary large value bound by - * the total data supplied by the uio. - */ - if (len > 0) - total = (uio->uio_resid < len) ? uio->uio_resid : len; + /* + * m_uiotombuf() is known to return zero length buffer, keep + * this compatibility. mc_uiotomc() won't do that. + */ + if (flags & M_PKTHDR) { + m = m_gethdr(how, MT_DATA); + m->m_pkthdr.memlen = MSIZE; + } else + m = m_get(how, MT_DATA); + if (m != NULL) + m->m_data += lspace; + return (m); + } else { + struct mchain mc; + int error; + + error = mc_uiotomc(&mc, uio, len, lspace, how, flags); + if (__predict_true(error == 0)) { + if (flags & M_PKTHDR) { + mc_first(&mc)->m_pkthdr.len = mc.mc_len; + mc_first(&mc)->m_pkthdr.memlen = mc.mc_mlen; + } + return (mc_first(&mc)); + } else + return (NULL); + } +} + +/* + * Copy the contents of uio into a properly sized mbuf chain. + * In case of failure state of mchain is inconsistent. + * @param length Limit copyout length. If 0 entire uio_resid is copied. + * @param lspace Provide leading space in the first mbuf in the chain. + */ +int +mc_uiotomc(struct mchain *mc, struct uio *uio, u_int length, u_int lspace, + int how, int flags) +{ + struct mbuf *mb; + u_int total; + int error; + + MPASS(lspace < MHLEN); + MPASS(UINT_MAX - lspace >= length); + MPASS(uio->uio_rw == UIO_WRITE); + MPASS(uio->uio_resid >= 0); + + if (length > 0) { + if (uio->uio_resid > length) { + total = length; + flags &= ~M_EOR; + } else + total = uio->uio_resid; + } else if (__predict_false(uio->uio_resid + lspace > UINT_MAX)) + return (EOVERFLOW); else total = uio->uio_resid; - /* - * The smallest unit returned by m_getm2() is a single mbuf - * with pkthdr. We can't align past it. - */ - if (align >= MHLEN) - return (NULL); + if (__predict_false(total + lspace == 0)) { + *mc = MCHAIN_INITIALIZER(mc); + return (0); + } - /* - * Give us the full allocation or nothing. - * If len is zero return the smallest empty mbuf. - */ - m = m_getm2(NULL, max(total + align, 1), how, MT_DATA, flags); - if (m == NULL) - return (NULL); - m->m_data += align; + error = mc_get(mc, total + lspace, how, MT_DATA, flags); + if (__predict_false(error)) + return (error); + mc_first(mc)->m_data += lspace; /* Fill all mbufs with uio data and update header information. */ - for (mb = m; mb != NULL; mb = mb->m_next) { - length = min(M_TRAILINGSPACE(mb), total - progress); - - error = uiomove(mtod(mb, void *), length, uio); - if (error) { - m_freem(m); - return (NULL); - } + STAILQ_FOREACH(mb, &mc->mc_q, m_stailq) { + u_int mlen; - mb->m_len = length; - progress += length; - if (flags & M_PKTHDR) { - m->m_pkthdr.len += length; - m->m_pkthdr.memlen += MSIZE; - if (mb->m_flags & M_EXT) - m->m_pkthdr.memlen += mb->m_ext.ext_size; + mlen = min(M_TRAILINGSPACE(mb), total - mc->mc_len); + error = uiomove(mtod(mb, void *), mlen, uio); + if (__predict_false(error)) { + mc_freem(mc); + return (error); } + mb->m_len = mlen; + mc->mc_len += mlen; } - KASSERT(progress == total, ("%s: progress != total", __func__)); + MPASS(mc->mc_len == total); - return (m); + return (0); } /* diff --git a/sys/sys/mbuf.h b/sys/sys/mbuf.h index 76c0005ae963..e13ba39c27aa 100644 --- a/sys/sys/mbuf.h +++ b/sys/sys/mbuf.h @@ -1797,6 +1797,7 @@ mc_remove(struct mchain *mc, struct mbuf *m) int mc_get(struct mchain *, u_int, int, short, int); int mc_split(struct mchain *, struct mchain *, u_int, int); +int mc_uiotomc(struct mchain *, struct uio *, u_int, u_int, int, int); #ifdef _SYS_TIMESPEC_H_ static inline void