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是什么意思?求问 :em02:快来大大啊。。 如果分片了,拷贝后续分片包。
因为第一个包拷贝的时候,包头已经拷过了,后续的包头就不需要拷贝了。
offset - start 是跳过后续分片包的包头。
页:
[1]