On Fri, 1 Feb 2008, Ilpo Järvinen wrote:

> @@ -1322,6 +1324,206 @@ static int tcp_sacktag_one(struct sk_buff *skb, 
> struct sock *sk,
>       return flag;
>  }
>  
> +/* Attempts to shift up to shiftlen worth of bytes from prev to skb.
> + * Returns number bytes shifted.
> + *
> + * TODO: in case the prev runs out of frag space, operation could be
> + * made to return with a partial result (would allow tighter packing).
> + */
> +static int skb_shift(struct sk_buff *prev, struct sk_buff *skb,
> +                  unsigned int shiftlen)
> +{
> +     int i, to, merge;
> +     unsigned int todo;
> +     struct skb_frag_struct *from, *fragto;
> +
> +     if (skb_cloned(skb) || skb_cloned(prev))
> +             return 0;
> +
> +     todo = shiftlen;
> +     i = 0;
> +     from = &skb_shinfo(skb)->frags[i];
> +     to = skb_shinfo(prev)->nr_frags;
> +
> +     merge = to - 1;
> +     if (!skb_can_coalesce(prev, merge + 1, from->page, from->page_offset))
> +             merge = -1;
> +     if (merge >= 0) {
> +             i++;
> +             if (from->size >= shiftlen)
> +                     goto onlymerge;
> +             todo -= from->size;
> +     }
> +
> +     /* Skip full, not-fitting skb to avoid expensive operations */
> +     if ((shiftlen == skb->len) &&
> +         (skb_shinfo(skb)->nr_frags - merge) < (MAX_SKB_FRAGS - to))

Before somebody else notices it:
  s/merge/i/, a leftover from flag -> idx conversion.

> +             return 0;
> +
> +     while (todo && (i < skb_shinfo(skb)->nr_frags)) {
> +             if (to == MAX_SKB_FRAGS)
> +                     return 0;
> +


-- 
 i.

Reply via email to