public inbox for passt-dev@passt.top
 help / color / mirror / code / Atom feed
blob ba1fda5de2cba98279caa77ca958e2c9e70cd92e 4953 bytes (raw)

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
 
// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * iov.c - helpers for using (partial) iovecs.
 *
 * Copyrigh Red Hat
 * Author: Laurent Vivier <lvivier@redhat.com>
 *
 * This file also contains code originally from QEMU include/qemu/iov.h:
 *
 * Author(s):
 *  Amit Shah <amit.shah@redhat.com>
 *  Michael Tokarev <mjt@tls.msk.ru>
 */

#ifndef IOVEC_H
#define IOVEC_H

#include <unistd.h>
#include <string.h>

#define IOV_OF_LVALUE(lval) \
	(struct iovec){ .iov_base = &(lval), .iov_len = sizeof(lval) }

size_t iov_skip_bytes(const struct iovec *iov, size_t n,
		      size_t skip, size_t *offset);
size_t iov_from_buf(const struct iovec *iov, size_t iov_cnt,
                    size_t offset, const void *buf, size_t bytes);
size_t iov_to_buf(const struct iovec *iov, size_t iov_cnt,
                  size_t offset, void *buf, size_t bytes);
size_t iov_size(const struct iovec *iov, size_t iov_cnt);

/*
 * DOC: Theory of Operation, struct iov_tail
 *
 * Sometimes a single logical network frame is split across multiple buffers,
 * represented by an IO vector (struct iovec[]).  We often want to process this
 * one header / network layer at a time.  So, it's useful to maintain a "tail"
 * of the vector representing the parts we haven't yet extracted.
 *
 * The headers we extract need not line up with buffer boundaries (though we do
 * assume they're contiguous within a single buffer for now).  So, we could
 * represent that tail as another struct iovec[], but that would mean copying
 * the whole array of struct iovecs, just so we can adjust the offset and length
 * on the first one.
 *
 * So, instead represent the tail as pointer into an existing struct iovec[],
 * with an explicit offset for where the "tail" starts within it.  If we extract
 * enough headers that some buffers of the original vector no longer contain
 * part of the tail, we (lazily) advance our struct iovec * to the first buffer
 * we still need, and adjust the vector length and offset to match.
 */

/**
 * struct iov_tail - An IO vector which may have some headers logically removed
 * @iov:	IO vector
 * @cnt:	Number of entries in @iov
 * @off:	Current offset in @iov
 */
struct iov_tail {
	const struct iovec *iov;
	size_t cnt, off;
};

/**
 * IOV_TAIL() - Create a new IOV tail
 * @iov_:	IO vector to create tail from
 * @cnt_:	Length of the IO vector at @iov_
 * @off_:	Byte offset in the IO vector where the tail begins
 */
#define IOV_TAIL(iov_, cnt_, off_) \
	(struct iov_tail){ .iov = (iov_), .cnt = (cnt_), .off = (off_) }

/**
 * IOV_TAIL_FROM_BUF() - Create a new IOV tail from a buffer
 * @buf_:	Buffer address to use in the iovec
 * @len_:	Buffer size
 * @off_:	Byte offset in the buffer where the tail begins
 */
#define IOV_TAIL_FROM_BUF(buf_, len_, off_) \
	IOV_TAIL((&(const struct iovec){ .iov_base = (buf_),		\
					 .iov_len = (len_) }),		\
		 1,							\
		 (off_))

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);
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);

/**
 * IOV_PEEK_HEADER() - Get typed pointer to a header from an IOV tail
 * @tail_:	IOV tail to get header from
 * @var_:	Temporary buffer of the type of the header to use if
 *		the memory in the iovec array is not contiguous.
 *
 * @tail_ may be pruned, but will represent the same bytes as before.
 *
 * Return: pointer of type (@type_ *) located at the start of @tail_
 *         or to @var_ if iovec memory is not contiguous, NULL if
 *         that overruns the iovec.
 */

#define IOV_PEEK_HEADER(tail_, var_)					\
	((__typeof__(var_) *)(iov_peek_header_((tail_), &(var_),	\
					       sizeof(var_),		\
					       __alignof__(var_))))

/**
 * IOV_REMOVE_HEADER() - Remove and return typed header from an IOV tail
 * @tail_:	IOV tail to remove header from (modified)
 * @var_:	Temporary buffer of the type of the header to use if
 *		the memory in the iovec array is not contiguous.
 *
 * On success, @tail_ is updated so that it longer includes the bytes of the
 * returned header.
 *
 * Return: pointer of type (@type_ *) located at the start of @tail_
 *         or to @var_ if iovec memory is not contiguous, NULL if
 *         that overruns the iovec.
 */

#define IOV_REMOVE_HEADER(tail_, var_)					\
	((__typeof__(var_) *)(iov_remove_header_((tail_), &(var_),	\
				    sizeof(var_), __alignof__(var_))))

/** 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
 *
 * Return: true if the tail still contains any bytes, otherwise false
 */
#define IOV_DROP_HEADER(tail_, type_) 	iov_drop_header((tail_), sizeof(type_))

#endif /* IOVEC_H */

debug log:

solving ba1fda5de2cb ...
found ba1fda5de2cb in https://archives.passt.top/passt-dev/20250814094849.919709-5-lvivier@redhat.com/
found 1821b40b1cb5 in https://archives.passt.top/passt-dev/20250814094849.919709-4-lvivier@redhat.com/
found c94fabe1eb43 in https://archives.passt.top/passt-dev/20250814094849.919709-3-lvivier@redhat.com/
found 3fc96ab9755a in https://passt.top/passt
preparing index
index prepared:
100644 3fc96ab9755ab19602fdbd835d8cd40ccb566a34	iov.h

applying [1/3] https://archives.passt.top/passt-dev/20250814094849.919709-3-lvivier@redhat.com/
diff --git a/iov.h b/iov.h
index 3fc96ab9755a..c94fabe1eb43 100644


applying [2/3] https://archives.passt.top/passt-dev/20250814094849.919709-4-lvivier@redhat.com/
diff --git a/iov.h b/iov.h
index c94fabe1eb43..1821b40b1cb5 100644


applying [3/3] https://archives.passt.top/passt-dev/20250814094849.919709-5-lvivier@redhat.com/
diff --git a/iov.h b/iov.h
index 1821b40b1cb5..ba1fda5de2cb 100644

Checking patch iov.h...
Applied patch iov.h cleanly.
Checking patch iov.h...
Applied patch iov.h cleanly.
Checking patch iov.h...
Applied patch iov.h cleanly.

index at:
100644 ba1fda5de2cba98279caa77ca958e2c9e70cd92e	iov.h

Code repositories for project(s) associated with this public inbox

	https://passt.top/passt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for IMAP folder(s).