Contrary to what the deleted comment said, the m_move_pkthdr()

will not smash the M_EXT and data pointer, so it is safe to
pass an mbuf with external storage procuded by m_getcl() to
m_move_pkthdr().

Reviewed by:	andre
Sponsored by:	Nginx, Inc.
This commit is contained in:
Gleb Smirnoff 2013-03-16 08:55:21 +00:00
parent 80daa4713c
commit 5368b81eb0
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=248371

View File

@ -1968,43 +1968,18 @@ m_unshare(struct mbuf *m0, int how)
}
/*
* Allocate new space to hold the copy...
*/
/* XXX why can M_PKTHDR be set past the first mbuf? */
if (mprev == NULL && (m->m_flags & M_PKTHDR)) {
/*
* NB: if a packet header is present we must
* allocate the mbuf separately from any cluster
* because M_MOVE_PKTHDR will smash the data
* pointer and drop the M_EXT marker.
*/
MGETHDR(n, how, m->m_type);
if (n == NULL) {
m_freem(m0);
return (NULL);
}
M_MOVE_PKTHDR(n, m);
MCLGET(n, how);
if ((n->m_flags & M_EXT) == 0) {
m_free(n);
m_freem(m0);
return (NULL);
}
} else {
n = m_getcl(how, m->m_type, m->m_flags);
if (n == NULL) {
m_freem(m0);
return (NULL);
}
}
/*
* ... and copy the data. We deal with jumbo mbufs
* (i.e. m_len > MCLBYTES) by splitting them into
* clusters. We could just malloc a buffer and make
* it external but too many device drivers don't know
* how to break up the non-contiguous memory when
* Allocate new space to hold the copy and copy the data.
* We deal with jumbo mbufs (i.e. m_len > MCLBYTES) by
* splitting them into clusters. We could just malloc a
* buffer and make it external but too many device drivers
* don't know how to break up the non-contiguous memory when
* doing DMA.
*/
n = m_getcl(how, m->m_type, m->m_flags);
if (n == NULL) {
m_freem(m0);
return (NULL);
}
len = m->m_len;
off = 0;
mfirst = n;