From 75ae257016ec8c5b326d8efc49f888ba35e9234e Mon Sep 17 00:00:00 2001 From: Maksim Yevmenkin Date: Wed, 4 May 2005 18:55:03 +0000 Subject: [PATCH] Change m_uiotombuf so it will accept offset at which data should be copied to the mbuf. Offset cannot exceed MHLEN bytes. This is currently used to fix Ethernet header alignment problem on alpha and sparc64. Also change all users of m_uiotombuf to pass proper offset. Reviewed by: jmg, sam Tested by: Sten Spans "sten AT blinkenlights DOT nl" MFC after: 1 week --- sys/kern/uipc_mbuf.c | 7 +++++-- sys/kern/uipc_syscalls.c | 2 +- sys/net/if_tap.c | 2 +- sys/net/if_tun.c | 2 +- sys/netgraph/ng_device.c | 2 +- sys/sys/mbuf.h | 2 +- 6 files changed, 10 insertions(+), 7 deletions(-) diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c index f5ba9abf6379..ce00553f0ff5 100644 --- a/sys/kern/uipc_mbuf.c +++ b/sys/kern/uipc_mbuf.c @@ -1333,7 +1333,7 @@ nospace: #endif struct mbuf * -m_uiotombuf(struct uio *uio, int how, int len) +m_uiotombuf(struct uio *uio, int how, int len, int align) { struct mbuf *m_new = NULL, *m_final = NULL; int progress = 0, error = 0, length, total; @@ -1342,12 +1342,15 @@ m_uiotombuf(struct uio *uio, int how, int len) total = min(uio->uio_resid, len); else total = uio->uio_resid; - if (total > MHLEN) + if (align >= MHLEN) + goto nospace; + if (total + align > MHLEN) m_final = m_getcl(how, MT_DATA, M_PKTHDR); else m_final = m_gethdr(how, MT_DATA); if (m_final == NULL) goto nospace; + m_final->m_data += align; m_new = m_final; while (progress < total) { length = total - progress; diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c index f4a4b1682ea1..2f59d87ba155 100644 --- a/sys/kern/uipc_syscalls.c +++ b/sys/kern/uipc_syscalls.c @@ -1796,7 +1796,7 @@ do_sendfile(struct thread *td, struct sendfile_args *uap, int compat) hdr_uio->uio_td = td; hdr_uio->uio_rw = UIO_WRITE; if (hdr_uio->uio_resid > 0) { - m_header = m_uiotombuf(hdr_uio, M_DONTWAIT, 0); + m_header = m_uiotombuf(hdr_uio, M_DONTWAIT, 0, 0); if (m_header == NULL) goto done; headersize = m_header->m_pkthdr.len; diff --git a/sys/net/if_tap.c b/sys/net/if_tap.c index cc07baf776ea..2f7474b57bb9 100644 --- a/sys/net/if_tap.c +++ b/sys/net/if_tap.c @@ -827,7 +827,7 @@ tapwrite(dev, uio, flag) return (EIO); } - if ((m = m_uiotombuf(uio, M_DONTWAIT, 0)) == NULL) { + if ((m = m_uiotombuf(uio, M_DONTWAIT, 0, ETHER_ALIGN)) == NULL) { ifp->if_ierrors ++; return (error); } diff --git a/sys/net/if_tun.c b/sys/net/if_tun.c index 6fe7b10c96b3..cd209cb411d9 100644 --- a/sys/net/if_tun.c +++ b/sys/net/if_tun.c @@ -761,7 +761,7 @@ tunwrite(struct cdev *dev, struct uio *uio, int flag) return (EIO); } - if ((m = m_uiotombuf(uio, M_DONTWAIT, 0)) == NULL) { + if ((m = m_uiotombuf(uio, M_DONTWAIT, 0, 0)) == NULL) { ifp->if_ierrors++; return (error); } diff --git a/sys/netgraph/ng_device.c b/sys/netgraph/ng_device.c index df6ee4cc2718..9439a574f209 100644 --- a/sys/netgraph/ng_device.c +++ b/sys/netgraph/ng_device.c @@ -466,7 +466,7 @@ ngdwrite(struct cdev *dev, struct uio *uio, int flag) if (uio->uio_resid < 0 || uio->uio_resid > IP_MAXPACKET) return (EIO); - if ((m = m_uiotombuf(uio, M_DONTWAIT, 0)) == NULL) + if ((m = m_uiotombuf(uio, M_DONTWAIT, 0, 0)) == NULL) return (ENOBUFS); NG_SEND_DATA_ONLY(error, priv->hook, m); diff --git a/sys/sys/mbuf.h b/sys/sys/mbuf.h index a3d2a61aa391..c514e0fb2f5d 100644 --- a/sys/sys/mbuf.h +++ b/sys/sys/mbuf.h @@ -582,7 +582,7 @@ void m_print(const struct mbuf *, int); struct mbuf *m_pulldown(struct mbuf *, int, int, int *); struct mbuf *m_pullup(struct mbuf *, int); struct mbuf *m_split(struct mbuf *, int, int); -struct mbuf *m_uiotombuf(struct uio *, int, int); +struct mbuf *m_uiotombuf(struct uio *, int, int, int); /*- * Network packets may have annotations attached by affixing a list