1. MBUF有下面四种形态
2. 用下面的方法可以巧妙的解决函数递归调用问题
#define MGET(m, how, type) { \
MALLOC((m), struct mbuf *, MSIZE, mbtypes[type], (how)); \
if (m) { \
(m)->m_type = (type); \
MBUFLOCK(mbstat.m_mtypes[type]++;) \
(m)->m_next = (struct mbuf *)NULL; \
(m)->m_nextpkt = (struct mbuf *)NULL; \
(m)->m_data = (m)->m_dat; \
(m)->m_flags = 0; \
} else \
(m) = m_retry((how), (type)); \
}
struct mbuf * m_retry(i, t)
int i, t;
{
register struct mbuf *m;
m_reclaim();
#define m_retry(i, t) (struct mbuf *)0
MGET(m, i, t);
#undef m_retry
return (m);
}
3. m_pullup函数的说明
struct mbuf * m_pullup(register struct mbuf *n, int len);
函数原型如上,函数的作用是,保证第一个mbuf包含最少len字节的数据,以便执行mtod。
如果请求的len字节数据分布在cluster上,那么会将这些字节复制到一个新的mbuf中,之后将新mbuf和原mbuf拼接成mbuf链。
4. m_copy函数的说明
#define m_copy(m, o, l) m_copym((m), (o), (l), M_DONTWAIT)
函数的作用是,复制mbuf链m中的l字节的数据到一个新的mbuf链
如果mbuf链m中的数据存在于cluster上,则不执行真正的copy动作,而是增加cluster的引用计数。
所有的cluster的引用计数,均在全局数组mclrefcnt[]中维护