From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: passt.top; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: passt.top; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=TkJZzXtg; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by passt.top (Postfix) with ESMTPS id DE2FB5A0274 for ; Mon, 16 Mar 2026 19:07:37 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1773684456; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=SNQWFTjUgQTi6dB9TgEb2MpVymWJrBjwB/pVHPGv9SY=; b=TkJZzXtgEDsfYzEuoKq56yQEBZKMJiQGTceq7EANBygExQ22WjDVgwJKw/N3Iu3ORD0PnA onYk93tN8SpTi02xbYRSGvkOylh2De36AVLThuS65TO/REectIlgd6zuk/uDyfkPLHY5jN +3QPqGBzvxniDJxIvUbgLjxb972xltc= Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-97-u1A3YeFRN7yNjkLxQWRjEQ-1; Mon, 16 Mar 2026 14:07:35 -0400 X-MC-Unique: u1A3YeFRN7yNjkLxQWRjEQ-1 X-Mimecast-MFC-AGG-ID: u1A3YeFRN7yNjkLxQWRjEQ_1773684455 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id D5AD619560AF for ; Mon, 16 Mar 2026 18:07:34 +0000 (UTC) Received: from lenovo-t14s.redhat.com (unknown [10.44.35.65]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id E12BC1800361; Mon, 16 Mar 2026 18:07:33 +0000 (UTC) From: Laurent Vivier To: passt-dev@passt.top Subject: [PATCH v3 7/8] iov: Add IOV_PUT_HEADER() and with_header() to write header data back to iov_tail Date: Mon, 16 Mar 2026 19:07:20 +0100 Message-ID: <20260316180721.2230640-8-lvivier@redhat.com> In-Reply-To: <20260316180721.2230640-1-lvivier@redhat.com> References: <20260316180721.2230640-1-lvivier@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: MMmCDR9RNREGgo4eyydZpJUt3Ym7k6SJDVNKtSi5VYk_1773684455 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: 8bit content-type: text/plain; charset="US-ASCII"; x-default=true Message-ID-Hash: D3TEGNMU2K7CB4HYCL27MSUBOAJUHHWM X-Message-ID-Hash: D3TEGNMU2K7CB4HYCL27MSUBOAJUHHWM X-MailFrom: lvivier@redhat.com 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: Laurent Vivier 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: 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(). 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. Signed-off-by: Laurent Vivier --- iov.c | 22 ++++++++++++++++++++++ iov.h | 25 ++++++++++++++++++++++++- 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/iov.c b/iov.c index 34d42c7a2264..41e418aab2cc 100644 --- a/iov.c +++ b/iov.c @@ -307,6 +307,28 @@ void *iov_peek_header_(struct iov_tail *tail, void *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, size_t len) +{ + size_t l = len; + + /* iov_peek_header_() already called iov_check_header() */ + if ((char *)tail->iov[0].iov_base + tail->off != v) + l = iov_from_buf(tail->iov, tail->cnt, tail->off, v, len); + + ASSERT(l == 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, size_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, size_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, size_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, size_t dst_iov_cnt, */ #define IOV_DROP_HEADER(tail_, type_) iov_drop_header((tail_), sizeof(type_)) +/** + * with_header() - Execute a block on a given header + * @type: Data type of the header to modify + * @hdr_: Variable name to receive the header pointer + * @tail_: IOV tail to peek/put the header from/to + */ +#define with_header(type_, hdr_, tail_) \ + for (type_ store_, *hdr_ = IOV_PEEK_HEADER(tail_, store_); \ + hdr_; \ + IOV_PUT_HEADER(tail_, hdr_), hdr_ = NULL) + #endif /* IOVEC_H */ -- 2.53.0