summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoremax <emax@FreeBSD.org>2005-05-04 18:55:03 +0000
committeremax <emax@FreeBSD.org>2005-05-04 18:55:03 +0000
commita52b6c9ce3aa7dd40c5d127ac564eff86c4b0aa9 (patch)
tree23d014d52a31e5e55ad4c1184ad09e522e889e51
parent40a0d434da94827c13d74391779c80cde4aa9b35 (diff)
downloadFreeBSD-src-a52b6c9ce3aa7dd40c5d127ac564eff86c4b0aa9.zip
FreeBSD-src-a52b6c9ce3aa7dd40c5d127ac564eff86c4b0aa9.tar.gz
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
-rw-r--r--sys/kern/uipc_mbuf.c7
-rw-r--r--sys/kern/uipc_syscalls.c2
-rw-r--r--sys/net/if_tap.c2
-rw-r--r--sys/net/if_tun.c2
-rw-r--r--sys/netgraph/ng_device.c2
-rw-r--r--sys/sys/mbuf.h2
6 files changed, 10 insertions, 7 deletions
diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c
index f5ba9ab..ce00553 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 f4a4b16..2f59d87 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 cc07baf..2f7474b 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 6fe7b10..cd209cb 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 df6ee4c..9439a57 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 a3d2a61..c514e0f 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
OpenPOWER on IntegriCloud