m_pullup 观后感

uipc_mbuf.c

/*
 * Rearange an mbuf chain so that len bytes are contiguous
 * and in the data area of an mbuf (so that mtod and dtom
 * will work for a structure of size len).  Returns the resulting
 * mbuf chain on success, frees it and returns null on failure.
 * If there is room, it will add up to max_protohdr-len extra bytes to the
 * contiguous region in an attempt to avoid being called next time.
 */
int MPFail;

struct mbuf *
m_pullup(n, len)
    register struct mbuf *n;
    int len;
{//n 要处理的m_buf; len 首个mbuf需保存的数据量
    register struct mbuf *m;
    register int count;
    int space;

    /*
     * If first mbuf has no cluster, and has room for len bytes
     * without shifting current data, pullup into it,
     * otherwise allocate a new mbuf to prepend to the chain.
     */

   //m_buf没有使用簇,并且可以拥有len长度的数据,有后续的m_buf
    if ((n->m_flags & M_EXT) == 0 &&
        n->m_data + len < &n->m_dat[MLEN] && n->m_next) {

        //如果已有数据的长度达到len,直接返回
        if (n->m_len >= len)
            return (n);

        //设置len为将要从后续m_buf中拷贝的数据量
        m = n;
        n = n->m_next;
        len -= m->m_len;
    } else {

       //m_buf使用了簇或者现有m_buf无法保存len长度数据
        if (len > MHLEN)
            goto bad;

        //创建m_buf,拷贝M_PKTHDR,并且将原m_buf的M_PKTHDR标志清除
        MGET(m, M_DONTWAIT, n->m_type);
        if (m == 0)
            goto bad;
        m->m_len = 0;
        if (n->m_flags & M_PKTHDR) {
            M_COPY_PKTHDR(m, n);
            n->m_flags &= ~M_PKTHDR;
        }
    }

    //现有可以拷贝的空间
    space = &m->m_dat[MLEN] - (m->m_data + m->m_len);
    do {

        //计算合理的count值:)
        count = min(min(max(len, max_protohdr), space), n->m_len);

        //拷贝,修改变量值
        bcopy(mtod(n, caddr_t), mtod(m, caddr_t) + m->m_len,
          (unsigned)count);
        len -= count;
        m->m_len += count;
        n->m_len -= count;
        space -= count;
        if (n->m_len)
            n->m_data += count;
        else

        //如果n数据都拷完了,free
            n = m_free(n);

        //检查是否已copylen长度的数据或者n数据已考完
    } while (len > 0 && n);
    if (len > 0) {
        (void) m_free(m);
        goto bad;
    }
    m->m_next = n;
    return (m);
bad:
    m_freem(n);
    MPFail++;
    return (0);
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值