summaryrefslogtreecommitdiffstats
path: root/sys/kern/uipc_mbuf.c
diff options
context:
space:
mode:
authorandre <andre@FreeBSD.org>2009-06-22 22:20:38 +0000
committerandre <andre@FreeBSD.org>2009-06-22 22:20:38 +0000
commit74f8982f2fa2661fafb8f5d1c357893c78e53293 (patch)
tree34358b0131e50a6171e6f0c8c318b06b5c90c566 /sys/kern/uipc_mbuf.c
parent7bb0d366d621937efe681675e0900dfe1ce76236 (diff)
downloadFreeBSD-src-74f8982f2fa2661fafb8f5d1c357893c78e53293.zip
FreeBSD-src-74f8982f2fa2661fafb8f5d1c357893c78e53293.tar.gz
Add m_mbuftouio() helper function to copy(out) an arbitrary
long mbuf chain into an arbitrary large uio in a single step. It is a functional mirror image of m_uiotombuf(). This function is supposed to be used instead of hand rolled code with the same purpose and to concentrate it into one place for potential further optimization or hardware assistance.
Diffstat (limited to 'sys/kern/uipc_mbuf.c')
-rw-r--r--sys/kern/uipc_mbuf.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c
index d78bee9..bc0e88d 100644
--- a/sys/kern/uipc_mbuf.c
+++ b/sys/kern/uipc_mbuf.c
@@ -1770,6 +1770,34 @@ m_uiotombuf(struct uio *uio, int how, int len, int align, int flags)
}
/*
+ * Copy an mbuf chain into a uio limited by len if set.
+ */
+int
+m_mbuftouio(struct uio *uio, struct mbuf *m, int len)
+{
+ int error, length, total;
+ int progress = 0;
+
+ if (len > 0)
+ total = min(uio->uio_resid, len);
+ else
+ total = uio->uio_resid;
+
+ /* Fill the uio with data from the mbufs. */
+ for (; m != NULL; m = m->m_next) {
+ length = min(m->m_len, total - progress);
+
+ error = uiomove(mtod(m, void *), length, uio);
+ if (error)
+ return (error);
+
+ progress += length;
+ }
+
+ return (0);
+}
+
+/*
* Set the m_data pointer of a newly-allocated mbuf
* to place an object of the specified size at the
* end of the mbuf, longword aligned.
OpenPOWER on IntegriCloud