当我看到这些代码时,我对 Linux 网络协议(protocol)栈中的 ip_append_data 感到困惑:
if (!(rt->u.dst.dev->features&NETIF_F_SG)) {
unsigned int off;
off = skb->len;
if (getfrag(from, skb_put(skb, copy),
offset, copy, off, skb) < 0) {
__skb_trim(skb, off);
err = -EFAULT;
goto error;
}
} else {
int i = skb_shinfo(skb)->nr_frags;
skb_frag_t *frag = &skb_shinfo(skb)->frags[i-1];
struct page *page = sk->sk_sndmsg_page;
int off = sk->sk_sndmsg_off;
unsigned int left;
if (page && (left = PAGE_SIZE - off) > 0) {
if (copy >= left)
copy = left;
if (page != frag->page) {
if (i == MAX_SKB_FRAGS) {
err = -EMSGSIZE;
goto error;
}
get_page(page);
skb_fill_page_desc(skb, i, page, sk->sk_sndmsg_off, 0);
frag = &skb_shinfo(skb)->frags[i];
}
} else if (i < MAX_SKB_FRAGS) {
if (copy > PAGE_SIZE)
copy = PAGE_SIZE;
page = alloc_pages(sk->sk_allocation, 0);
if (page == NULL) {
err = -ENOMEM;
goto error;
}
sk->sk_sndmsg_page = page;
sk->sk_sndmsg_off = 0;
skb_fill_page_desc(skb, i, page, 0, 0);
frag = &skb_shinfo(skb)->frags[i];
skb->truesize += PAGE_SIZE;
atomic_add(PAGE_SIZE, &sk->sk_wmem_alloc);
} else {
err = -EMSGSIZE;
goto error;
}
if (getfrag(from, page_address(frag->page)+frag->page_offset+frag->size, offset, copy, skb->len, skb) < 0) {
err = -EFAULT;
goto error;
}
sk->sk_sndmsg_off += copy;
frag->size += copy;
skb->len += copy;
skb->data_len += copy;
}
我的问题如下:
条件是(page != frag->page),为什么?可以用(!frag->page)代替吗?我认为当 (!frag->page) 为真时 (page == frag->page) 总是为真。希望有人告诉我原因。
if **(page != frag->page)** {
if (i == MAX_SKB_FRAGS) {
err = -EMSGSIZE;
goto error;
}
get_page(page);
skb_fill_page_desc(skb, i, page, sk->sk_sndmsg_off, 0);
frag = &skb_shinfo(skb)->frags[i];
}
最佳答案
The condition is
(page != frag->page)
, why? can it be replaced by(!frag->page)
? I think(page == frag->page)
is always true when(!frag->page)
is true.
如果当 (!frag->page)
为 true 时(page == frag->page)
始终为 true,则当 (!frag->page)
为 true 时 (page != frag->page)
为 false,并且用 (!frag->page)
替换 (page != frag->page)
将替换将 false 值设为 true。
如果您打算写成当 (!frag->page)
为 true 时,(page != frag->page)
始终为 true,并且如果这是正确的,则 (page != frag->page)
不足以等同于 (!frag->page)
,因为 (page != frag->page)
不一定当 (!frag->page)
为 false 时,始终为 false。
关于linux - ip_append_data 中的一个问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26289060/