static int __new_pgfrag(struct sk_buff *skb, struct sk_buff *pskb, int size, int i, int shift) { int off = 0; struct page *page = NULL; skb_frag_t *frag; BUG_ON(i > MAX_SKB_FRAGS); frag = __lookup_pgfrag_room(skb, size); if (frag) { page = skb_frag_page(frag); off = ss_skb_frag_len(frag); __skb_frag_ref(frag); } else { page = alloc_page(GFP_ATOMIC); if (!page) return -ENOMEM; } if (__extend_pgfrags(skb, pskb, i, shift)) { if (!frag) __free_page(page); return -ENOMEM; } if (i == MAX_SKB_FRAGS) { /* * Insert a new paged fragment right after the last one * in @skb, i.e. as the first fragment of the next skb. */ skb = skb_shinfo(pskb ? : skb)->frag_list; i = 0; }
/* * Make room for @shift fragments starting with slot @i. Then make * a new fragment in slot @i that can hold @size bytes, and it set up. */ static int __new_pgfrag(struct sk_buff *skb, int size, int i, int shift, TfwStr *it) { int off = 0; struct page *page = NULL; skb_frag_t *frag; BUG_ON(i > MAX_SKB_FRAGS); /* * Try to find room for @size bytes in SKB fragments. * If none found, then allocate a new page for the fragment. */ frag = __lookup_pgfrag_room(skb, size); if (frag) { page = skb_frag_page(frag); off = ss_skb_frag_len(frag); __skb_frag_ref(frag); /* get_page(page); */ } else { page = alloc_page(GFP_ATOMIC); if (!page) return -ENOMEM; } /* Make room for @shift fragments starting with slot @i. */ if (__extend_pgfrags(skb, i, shift, it)) { if (frag) __skb_frag_unref(frag); /* put_page(page); */ else __free_page(page); return -ENOMEM; } /* * When the requested slot is right outside the range of the * array of paged fragments, then the new fragment is put as * the first fragment of the next SKB. */ if (i == MAX_SKB_FRAGS) { i = 0; skb = it->skb; } /* Set up the new fragment in slot @i to hold @size bytes. */ __skb_fill_page_desc(skb, i, page, off, size); ss_skb_adjust_data_len(skb, size); return 0; }