黎明748 发表于 2014-07-29 17:05

skb_copy_datagram_iovec疑问

int skb_copy_datagram_iovec(const struct sk_buff *skb, int offset,
                          struct iovec *to, int len)
{
        int start = skb_headlen(skb);
        int i, copy = start - offset;

        /* Copy header. */
        if (copy > 0) {
                if (copy > len)
                        copy = len;
                if (memcpy_toiovec(to, skb->data + offset, copy))
                        goto fault;
                if ((len -= copy) == 0)
                        return 0;
                offset += copy;
        }

        /* Copy paged appendix. Hmm... why does this look so complicated? */
        for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
                int end;

                BUG_TRAP(start <= offset + len);

                end = start + skb_shinfo(skb)->frags.size;
                if ((copy = end - offset) > 0) {
                        int err;
                        u8*vaddr;
                        skb_frag_t *frag = &skb_shinfo(skb)->frags;
                        struct page *page = frag->page;

                        if (copy > len)
                                copy = len;
                        vaddr = kmap(page);
                        err = memcpy_toiovec(to, vaddr + frag->page_offset +
                                             offset - start, copy);
                        kunmap(page);
                        if (err)
                                goto fault;
                        if (!(len -= copy))
                                return 0;
                        offset += copy;
                }
                start = end;
        }

        if (skb_shinfo(skb)->frag_list) {
                struct sk_buff *list = skb_shinfo(skb)->frag_list;

                for (; list; list = list->next) {
                        int end;

                        BUG_TRAP(start <= offset + len);

                        end = start + list->len;
                        if ((copy = end - offset) > 0) {
                                if (copy > len)
                                        copy = len;
                                if (skb_copy_datagram_iovec(list,
                                                          offset - start,
                                                          to, copy))
                                        goto fault;
                                if ((len -= copy) == 0)
                                        return 0;
                                offset += copy;
                        }
                        start = end;
                }
        }
        if (!len)
                return 0;

fault:
        return -EFAULT;
}

memcpy_toiovec(to, vaddr + frag->page_offset +offset - start, copy);想不明白offset - start是什么意思?求问

黎明748 发表于 2014-07-29 21:13

:em02:快来大大啊。。

Agimsn 发表于 2015-09-07 20:03

如果分片了,拷贝后续分片包。
因为第一个包拷贝的时候,包头已经拷过了,后续的包头就不需要拷贝了。
offset - start 是跳过后续分片包的包头。
页: [1]
查看完整版本: skb_copy_datagram_iovec疑问