Unbreak writes of 0 bytes. Zero byte writes happen when only ancillary

control data but no payload data is passed.

Change m_uiotombuf() to return at least one empty mbuf if the requested
length was zero.  Add comment to sosend_dgram and sosend_generic().

Diagnoses by:		jhb
Regression test by:	rwatson
Pointy hat to.		andre
This commit is contained in:
andre 2007-01-22 14:50:28 +00:00
parent 3530b41545
commit 4a22f82e6c
2 changed files with 15 additions and 2 deletions

View File

@ -1643,8 +1643,11 @@ m_uiotombuf(struct uio *uio, int how, int len, int align, int flags)
if (align >= MHLEN)
return (NULL);
/* Give us all or nothing. */
m = m_getm2(NULL, total + align, how, MT_DATA, flags);
/*
* Give us the full allocation or nothing.
* If len is zero return the smallest empty mbuf.
*/
m = m_getm2(NULL, max(total + align, 1), how, MT_DATA, flags);
if (m == NULL)
return (NULL);
m->m_data += align;

View File

@ -1055,6 +1055,11 @@ sosend_dgram(so, addr, uio, top, control, flags, td)
if (error)
goto out;
#else
/*
* Copy the data from userland into a mbuf chain.
* If no data is to be copied in, a single empty mbuf
* is returned.
*/
top = m_uiotombuf(uio, M_WAITOK, space, max_hdr,
(M_PKTHDR | ((flags & MSG_EOR) ? M_EOR : 0)));
if (top == NULL) {
@ -1230,6 +1235,11 @@ sosend_generic(so, addr, uio, top, control, flags, td)
goto release;
}
#else
/*
* Copy the data from userland into a mbuf
* chain. If no data is to be copied in,
* a single empty mbuf is returned.
*/
top = m_uiotombuf(uio, M_WAITOK, space,
(atomic ? max_hdr : 0),
(atomic ? M_PKTHDR : 0) |