From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: passt.top; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: passt.top; dkim=pass (2048-bit key; secure) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.a=rsa-sha256 header.s=202602 header.b=WPQfc0Ew; dkim-atps=neutral Received: from mail.ozlabs.org (gandalf.ozlabs.org [150.107.74.76]) by passt.top (Postfix) with ESMTPS id 2B6655A0265 for ; Wed, 25 Mar 2026 00:46:56 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gibson.dropbear.id.au; s=202602; t=1774396012; bh=jQJd5k1L3CUGLrIc5moZy3p8IfV6iUdvQGHFcMFGi/I=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=WPQfc0EwVzRgdlr9T2+TOLavLjWqy7b/hr+2eVBq8S7Hd48QjaUTDRN/OJqX9Yca8 kAEN4UP6n8hr8oi4N7h1NAp2Y7nCMZWN5szmKI2N28tmxPzhqo1EKX8VH6mQzkBt/X ZWlHUgb9Y5+mZW3XXKh1YtLRiBqJyJXZa5oORJK1jk/Qdbm/JXaEeTbh8XscOpzTHE I6AjfyUvas/Rw9Bee36Mbj0UqzQmoOL9/KGpvzDXucw2Sw9BkZQ3gsQGhU7opodh0J uxRnU29c0HeOOEZLdvsSmDEtNkNERI0xhlIEkcntVAlFRJ7v3WwzYbJnA6+yTrpl8c mXYYhdr/Qgzxw== Received: by gandalf.ozlabs.org (Postfix, from userid 1007) id 4fgRXD4b4hz4wH2; Wed, 25 Mar 2026 10:46:52 +1100 (AEDT) Date: Wed, 25 Mar 2026 10:38:07 +1100 From: David Gibson To: Laurent Vivier Subject: Re: [PATCH v4 4/5] iov: Add IOV_PUT_HEADER() and with_header() to write header data back to iov_tail Message-ID: References: <20260323143151.538673-1-lvivier@redhat.com> <20260323143151.538673-5-lvivier@redhat.com> <0ca2db00-8982-46dc-b49e-15787720878e@redhat.com> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha512; protocol="application/pgp-signature"; boundary="1VXE6Bo9UA7QJjqd" Content-Disposition: inline In-Reply-To: <0ca2db00-8982-46dc-b49e-15787720878e@redhat.com> Message-ID-Hash: HOXTKCYVPBU6MJ25UBW4YF3DQ4JDYX4O X-Message-ID-Hash: HOXTKCYVPBU6MJ25UBW4YF3DQ4JDYX4O X-MailFrom: dgibson@gandalf.ozlabs.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: passt-dev@passt.top X-Mailman-Version: 3.3.8 Precedence: list List-Id: Development discussion and patches for passt Archived-At: Archived-At: List-Archive: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: --1VXE6Bo9UA7QJjqd Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Tue, Mar 24, 2026 at 08:16:50AM +0100, Laurent Vivier wrote: > On 3/24/26 03:41, David Gibson wrote: > > On Mon, Mar 23, 2026 at 03:31:50PM +0100, Laurent Vivier wrote: > > > Add iov_put_header_() and its wrapper macro IOV_PUT_HEADER() as a > > > counterpart to IOV_PEEK_HEADER(). This writes header data back to an > > > iov_tail after modification. If the header pointer matches the > > > original iov buffer location, the data was already modified in place > > > and no copy is needed. Otherwise, it copies the data back using > > > iov_from_buf(). > > >=20 > > > Add with_header(), a for-loop macro that combines IOV_PEEK_HEADER() > > > and IOV_PUT_HEADER() to allow modifying a header in place within a > > > block scope. > > >=20 > > > Signed-off-by: Laurent Vivier > > > --- > > > iov.c | 22 ++++++++++++++++++++++ > > > iov.h | 25 ++++++++++++++++++++++++- > > > 2 files changed, 46 insertions(+), 1 deletion(-) > > >=20 > > > diff --git a/iov.c b/iov.c > > > index 8134b8c9f988..7fc9c3c78a32 100644 > > > --- a/iov.c > > > +++ b/iov.c > > > @@ -308,6 +308,28 @@ void *iov_peek_header_(struct iov_tail *tail, vo= id *v, size_t len, size_t align) > > > return v; > > > } > > > +/** > > > + * iov_put_header_() - Write header back to an IOV tail > > > + * @tail: IOV tail to write header to > > > + * @v: Pointer to header data to write > > > + * @len: Length of header to write, in bytes > > > + * > > > + * Return: number of bytes written > > > + */ > > > +/* cppcheck-suppress unusedFunction */ > > > +size_t iov_put_header_(const struct iov_tail *tail, const void *v, s= ize_t len) > > > +{ > > > + size_t l =3D len; > > > + > > > + /* iov_peek_header_() already called iov_check_header() */ > > > + if ((char *)tail->iov[0].iov_base + tail->off !=3D v) > > > + l =3D iov_from_buf(tail->iov, tail->cnt, tail->off, v, len); > > > + > > > + assert(l =3D=3D len); > > > + > > > + return l; > > > +} > > > + > > > /** > > > * iov_remove_header_() - Remove a header from an IOV tail > > > * @tail: IOV tail to remove header from (modified) > > > diff --git a/iov.h b/iov.h > > > index d295d05b3bab..4ce425ccdbe5 100644 > > > --- a/iov.h > > > +++ b/iov.h > > > @@ -90,6 +90,7 @@ bool iov_tail_prune(struct iov_tail *tail); > > > size_t iov_tail_size(struct iov_tail *tail); > > > bool iov_drop_header(struct iov_tail *tail, size_t len); > > > void *iov_peek_header_(struct iov_tail *tail, void *v, size_t len, = size_t align); > > > +size_t iov_put_header_(const struct iov_tail *tail, const void *v, s= ize_t len); > > > void *iov_remove_header_(struct iov_tail *tail, void *v, size_t len= , size_t align); > > > ssize_t iov_tail_clone(struct iovec *dst_iov, size_t dst_iov_cnt, > > > struct iov_tail *tail); > > > @@ -112,6 +113,16 @@ ssize_t iov_tail_clone(struct iovec *dst_iov, si= ze_t dst_iov_cnt, > > > sizeof(var_), \ > > > __alignof__(var_)))) > > > +/** > > > + * IOV_PUT_HEADER() - Write header back to an IOV tail > > > + * @tail_: IOV tail to write header to > > > + * @var_: Pointer to a variable containing the header data to write > > > + * > > > + * Return: number of bytes written > > > + */ > > > +#define IOV_PUT_HEADER(tail_, var_) \ > > > + (iov_put_header_((tail_), (var_), sizeof(*var_))) > > > + > > > /** > > > * IOV_REMOVE_HEADER() - Remove and return typed header from an IOV= tail > > > * @tail_: IOV tail to remove header from (modified) > > > @@ -130,7 +141,8 @@ ssize_t iov_tail_clone(struct iovec *dst_iov, siz= e_t dst_iov_cnt, > > > ((__typeof__(var_) *)(iov_remove_header_((tail_), &(var_), \ > > > sizeof(var_), __alignof__(var_)))) > > > -/** IOV_DROP_HEADER() - Remove a typed header from an IOV tail > > > +/** > > > + * IOV_DROP_HEADER() - Remove a typed header from an IOV tail > > > * @tail_: IOV tail to remove header from (modified) > > > * @type_: Data type of the header to remove > > > * > > > @@ -138,4 +150,15 @@ ssize_t iov_tail_clone(struct iovec *dst_iov, si= ze_t dst_iov_cnt, > > > */ > > > #define IOV_DROP_HEADER(tail_, type_) iov_drop_header((tail_), siz= eof(type_)) > > > +/** > > > + * with_header() - Execute a block on a given header > > > + * @type: Data type of the header to modify > >=20 > > We already use __typeof__ in IOV_PEEK_HEADER(), so we should be able > > to use that to avoid explicitly passing the type. >=20 > I tried but it's not possible to put a declaration and an initialization = in > the first part of the for(). >=20 > for instance >=20 > #define with_header(hdr_, tail_)\ > for (__typeof__(*hdr_) store_, hdr_ =3D IOV_PEEK_HEADER(tail_, store_);\ > hdr_;\ > IOV_PUT_HEADER(tail_, hdr_), hdr_ =3D NULL) >=20 > Then : >=20 > struct ethhdr *eh; > struct iov_tail *tail; >=20 > with_header(eh, tail) >=20 > becomes: >=20 > for (struct ethhdr store_, eh =3D IOV_PEEK_HEADER(tail, store_); > eh; > IOV_PUT_HEADER(store, eh), eh =3D NULL) Huh, right. I'd never realised that limitation. > And >=20 > struct ethhdr store_, eh =3D IOV_PEEK_HEADER(tail, store_); >=20 > declares store_, but also declares eh, that is already declared. >=20 > We could do something like: >=20 > #define with_header(hdr_, tail_)\ > for (__typeof__(*hdr_) store_, *tmp_hdr_ =3D (hdr_ =3D IOV_PEEK_HEADER(ta= il_, store_));\ > hdr_;\ > IOV_PUT_HEADER(tail_, hdr_), hdr_ =3D NULL) >=20 > But I preferred to introduce the type rather than a dummy variable. Hmm. I actually prefer this second solution. It's ugly inside the macro, but it makes it neater for the caller. The temporary is never used, so should get pruned by the compiler (although I guess we need to see if it makes cppcheck unhappy. > Moreover, doing as I did, the variable is local to the body of the for() = and > cannot be used outside. Uh.. that should be true for both variants. --=20 David Gibson (he or they) | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you, not the other way | around. http://www.ozlabs.org/~dgibson --1VXE6Bo9UA7QJjqd Content-Type: application/pgp-signature; name=signature.asc -----BEGIN PGP SIGNATURE----- iQIzBAEBCgAdFiEEO+dNsU4E3yXUXRK2zQJF27ox2GcFAmnDIFsACgkQzQJF27ox 2GdkYRAAnJ8pmEQEUpqfQswOUgGKqmnXNAfMyjqqUpvaa1DgYQ9ULnPbZP6gkKlT Dn92GOwu18lJXl5p8I3wq6Wc8P1JsnrptyOEgt8lcriistV5Y/vCHwyBEyhsEQi9 mBFnCPV83/92G01J7PDKVOEIa9KhSx9uRGiK4jGpWVKodbRySyHUlJtEqFmtmUy7 xs+9/rfH6it82BvDMr7JmZVofUNGRcH6rgCYCL3Dz7Hi7PQR9gw/PbjOlx09smIp etnme6Qdv+ZvszH3Az8C0iuU9i7537aZm2YtbspVj2D4+z12cxKPxVYTFD48YqXy ctdUUbI1n+vx3mPZtyjLetxrLfPXMyhqLxVhO6X17KB0QTe+EMR9a3ISK65ivls9 XcrKb1CtOMCwHzQb/5xV1mHj5N9cbASq211S3sfPgcyD/lA65dXcQQ1eH3YlvKsS lw4M9DCse07Na5FPVEHIHORtqzTRbwdwb1QaDtUGggti+7ypT8wwmYIB/gVfDdMT LIv6NjL7J4n3RpzfTQGBUZJ4wjNzVFs3I50DTz+PPVdoR62ipzpRiw1+tHrrqUFJ 2ncusdkqB0r0+4Cyh8ZaQy0xE1x/OFh1/qZUBMznySfsUKHILTOZTfNnDZGop8FU JLEXdRZwAJHdr0Ch87p3g5CbaqCsmeztxOrvqN5gKpVzylitNZc= =rf4x -----END PGP SIGNATURE----- --1VXE6Bo9UA7QJjqd--