summaryrefslogtreecommitdiff
path: root/sys/kern
diff options
context:
space:
mode:
authorBret Lambert <blambert@cvs.openbsd.org>2010-07-02 02:40:18 +0000
committerBret Lambert <blambert@cvs.openbsd.org>2010-07-02 02:40:18 +0000
commitbfc9493d9280a5a8ab43b8df30cd772c910140ba (patch)
tree32334a91bf10c89a8551f90fe6749d45476d9ad8 /sys/kern
parent364840df3893a5f720df05ee307b996c62195a07 (diff)
m_copyback can fail to allocate memory, but is a void fucntion so gymnastics
are required to detect that. Change the function to take a wait argument (used in nfs server, but M_NOWAIT everywhere else for now) and to return an error ok claudio@ henning@ krw@
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/uipc_mbuf.c25
1 files changed, 17 insertions, 8 deletions
diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c
index dcf977c50a4..9940151a3e0 100644
--- a/sys/kern/uipc_mbuf.c
+++ b/sys/kern/uipc_mbuf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uipc_mbuf.c,v 1.139 2010/07/01 19:23:51 beck Exp $ */
+/* $OpenBSD: uipc_mbuf.c,v 1.140 2010/07/02 02:40:16 blambert Exp $ */
/* $NetBSD: uipc_mbuf.c,v 1.15.4.1 1996/06/13 17:11:44 cgd Exp $ */
/*
@@ -726,26 +726,30 @@ m_copydata(struct mbuf *m, int off, int len, caddr_t cp)
* chain if necessary. The mbuf needs to be properly initialized
* including the setting of m_len.
*/
-void
-m_copyback(struct mbuf *m0, int off, int len, const void *_cp)
+int
+m_copyback(struct mbuf *m0, int off, int len, const void *_cp, int wait)
{
int mlen, totlen = 0;
struct mbuf *m = m0, *n;
caddr_t cp = (caddr_t)_cp;
+ int error = 0;
if (m0 == NULL)
- return;
+ return (0);
while (off > (mlen = m->m_len)) {
off -= mlen;
totlen += mlen;
if (m->m_next == NULL) {
- if ((n = m_get(M_DONTWAIT, m->m_type)) == NULL)
+ if ((n = m_get(wait, m->m_type)) == NULL) {
+ error = ENOBUFS;
goto out;
+ }
if (off + len > MLEN) {
- MCLGETI(n, M_DONTWAIT, NULL, off + len);
+ MCLGETI(n, wait, NULL, off + len);
if (!(n->m_flags & M_EXT)) {
m_free(n);
+ error = ENOBUFS;
goto out;
}
}
@@ -770,13 +774,16 @@ m_copyback(struct mbuf *m0, int off, int len, const void *_cp)
off = 0;
if (m->m_next == NULL) {
- if ((n = m_get(M_DONTWAIT, m->m_type)) == NULL)
+ if ((n = m_get(wait, m->m_type)) == NULL) {
+ error = ENOBUFS;
goto out;
+ }
if (len > MLEN) {
- MCLGETI(n, M_DONTWAIT, NULL, len);
+ MCLGETI(n, wait, NULL, len);
if (!(n->m_flags & M_EXT)) {
m_free(n);
+ error = ENOBUFS;
goto out;
}
}
@@ -788,6 +795,8 @@ m_copyback(struct mbuf *m0, int off, int len, const void *_cp)
out:
if (((m = m0)->m_flags & M_PKTHDR) && (m->m_pkthdr.len < totlen))
m->m_pkthdr.len = totlen;
+
+ return (error);
}
/*