Merge branch 'master' of /home/davem/src/GIT/linux-2.6/
[pandora-kernel.git] / net / core / skbuff.c
index c543dd2..4e7ac09 100644 (file)
@@ -482,22 +482,22 @@ EXPORT_SYMBOL(consume_skb);
  *     reference count dropping and cleans up the skbuff as if it
  *     just came from __alloc_skb().
  */
-int skb_recycle_check(struct sk_buff *skb, int skb_size)
+bool skb_recycle_check(struct sk_buff *skb, int skb_size)
 {
        struct skb_shared_info *shinfo;
 
        if (irqs_disabled())
-               return 0;
+               return false;
 
        if (skb_is_nonlinear(skb) || skb->fclone != SKB_FCLONE_UNAVAILABLE)
-               return 0;
+               return false;
 
        skb_size = SKB_DATA_ALIGN(skb_size + NET_SKB_PAD);
        if (skb_end_pointer(skb) - skb->head < skb_size)
-               return 0;
+               return false;
 
        if (skb_shared(skb) || skb_cloned(skb))
-               return 0;
+               return false;
 
        skb_release_head_state(skb);
 
@@ -509,7 +509,7 @@ int skb_recycle_check(struct sk_buff *skb, int skb_size)
        skb->data = skb->head + NET_SKB_PAD;
        skb_reset_tail_pointer(skb);
 
-       return 1;
+       return true;
 }
 EXPORT_SYMBOL(skb_recycle_check);
 
@@ -1406,12 +1406,13 @@ new_page:
 /*
  * Fill page/offset/length into spd, if it can hold more pages.
  */
-static inline int spd_fill_page(struct splice_pipe_desc *spd, struct page *page,
+static inline int spd_fill_page(struct splice_pipe_desc *spd,
+                               struct pipe_inode_info *pipe, struct page *page,
                                unsigned int *len, unsigned int offset,
                                struct sk_buff *skb, int linear,
                                struct sock *sk)
 {
-       if (unlikely(spd->nr_pages == PIPE_BUFFERS))
+       if (unlikely(spd->nr_pages == pipe->buffers))
                return 1;
 
        if (linear) {
@@ -1447,7 +1448,8 @@ static inline int __splice_segment(struct page *page, unsigned int poff,
                                   unsigned int plen, unsigned int *off,
                                   unsigned int *len, struct sk_buff *skb,
                                   struct splice_pipe_desc *spd, int linear,
-                                  struct sock *sk)
+                                  struct sock *sk,
+                                  struct pipe_inode_info *pipe)
 {
        if (!*len)
                return 1;
@@ -1470,7 +1472,7 @@ static inline int __splice_segment(struct page *page, unsigned int poff,
                /* the linear region may spread across several pages  */
                flen = min_t(unsigned int, flen, PAGE_SIZE - poff);
 
-               if (spd_fill_page(spd, page, &flen, poff, skb, linear, sk))
+               if (spd_fill_page(spd, pipe, page, &flen, poff, skb, linear, sk))
                        return 1;
 
                __segment_seek(&page, &poff, &plen, flen);
@@ -1485,9 +1487,9 @@ static inline int __splice_segment(struct page *page, unsigned int poff,
  * Map linear and fragment data from the skb to spd. It reports failure if the
  * pipe is full or if we already spliced the requested length.
  */
-static int __skb_splice_bits(struct sk_buff *skb, unsigned int *offset,
-                            unsigned int *len, struct splice_pipe_desc *spd,
-                            struct sock *sk)
+static int __skb_splice_bits(struct sk_buff *skb, struct pipe_inode_info *pipe,
+                            unsigned int *offset, unsigned int *len,
+                            struct splice_pipe_desc *spd, struct sock *sk)
 {
        int seg;
 
@@ -1497,7 +1499,7 @@ static int __skb_splice_bits(struct sk_buff *skb, unsigned int *offset,
        if (__splice_segment(virt_to_page(skb->data),
                             (unsigned long) skb->data & (PAGE_SIZE - 1),
                             skb_headlen(skb),
-                            offset, len, skb, spd, 1, sk))
+                            offset, len, skb, spd, 1, sk, pipe))
                return 1;
 
        /*
@@ -1507,7 +1509,7 @@ static int __skb_splice_bits(struct sk_buff *skb, unsigned int *offset,
                const skb_frag_t *f = &skb_shinfo(skb)->frags[seg];
 
                if (__splice_segment(f->page, f->page_offset, f->size,
-                                    offset, len, skb, spd, 0, sk))
+                                    offset, len, skb, spd, 0, sk, pipe))
                        return 1;
        }
 
@@ -1524,8 +1526,8 @@ int skb_splice_bits(struct sk_buff *skb, unsigned int offset,
                    struct pipe_inode_info *pipe, unsigned int tlen,
                    unsigned int flags)
 {
-       struct partial_page partial[PIPE_BUFFERS];
-       struct page *pages[PIPE_BUFFERS];
+       struct partial_page partial[PIPE_DEF_BUFFERS];
+       struct page *pages[PIPE_DEF_BUFFERS];
        struct splice_pipe_desc spd = {
                .pages = pages,
                .partial = partial,
@@ -1535,12 +1537,16 @@ int skb_splice_bits(struct sk_buff *skb, unsigned int offset,
        };
        struct sk_buff *frag_iter;
        struct sock *sk = skb->sk;
+       int ret = 0;
+
+       if (splice_grow_spd(pipe, &spd))
+               return -ENOMEM;
 
        /*
         * __skb_splice_bits() only fails if the output has no room left,
         * so no point in going over the frag_list for the error case.
         */
-       if (__skb_splice_bits(skb, &offset, &tlen, &spd, sk))
+       if (__skb_splice_bits(skb, pipe, &offset, &tlen, &spd, sk))
                goto done;
        else if (!tlen)
                goto done;
@@ -1551,14 +1557,12 @@ int skb_splice_bits(struct sk_buff *skb, unsigned int offset,
        skb_walk_frags(skb, frag_iter) {
                if (!tlen)
                        break;
-               if (__skb_splice_bits(frag_iter, &offset, &tlen, &spd, sk))
+               if (__skb_splice_bits(frag_iter, pipe, &offset, &tlen, &spd, sk))
                        break;
        }
 
 done:
        if (spd.nr_pages) {
-               int ret;
-
                /*
                 * Drop the socket lock, otherwise we have reverse
                 * locking dependencies between sk_lock and i_mutex
@@ -1571,10 +1575,10 @@ done:
                release_sock(sk);
                ret = splice_to_pipe(pipe, &spd);
                lock_sock(sk);
-               return ret;
        }
 
-       return 0;
+       splice_shrink_spd(pipe, &spd);
+       return ret;
 }
 
 /**
@@ -2718,6 +2722,7 @@ int skb_gro_receive(struct sk_buff **head, struct sk_buff *skb)
        *NAPI_GRO_CB(nskb) = *NAPI_GRO_CB(p);
        skb_shinfo(nskb)->frag_list = p;
        skb_shinfo(nskb)->gso_size = pinfo->gso_size;
+       pinfo->gso_size = 0;
        skb_header_release(p);
        nskb->prev = p;
 
@@ -2991,7 +2996,11 @@ void skb_tstamp_tx(struct sk_buff *orig_skb,
        memset(serr, 0, sizeof(*serr));
        serr->ee.ee_errno = ENOMSG;
        serr->ee.ee_origin = SO_EE_ORIGIN_TIMESTAMPING;
+
+       bh_lock_sock(sk);
        err = sock_queue_err_skb(sk, skb);
+       bh_unlock_sock(sk);
+
        if (err)
                kfree_skb(skb);
 }