linux - ip_append_data 中的一个问题

标签 linux networking kernel

当我看到这些代码时,我对 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/

相关文章:

kernel - Windows下如何在内核模式下生成PID(进程标识符)?

c - 一个简单的 x86 反汇编器开源内核使用

python - 内核在 jupyter 笔记本中不断死亡

c# - Gstreamer-sharp.dll 在 linux (mono) 下运行

android - 在 ADB 中找不到 Phone Wiko Kite

java - 同时从不同的计算机上部分下载文件

c++ - 类未注册 0x80040154

linux - 使用 sed 命令用正则表达式替换行

c - 文件描述符和fildes有什么区别

java - In & Out 无法解析为类型 (Java Socket)