net: add opaque struct around skb frag page
authorIan Campbell <Ian.Campbell@citrix.com>
Wed, 19 Oct 2011 23:01:49 +0000 (23:01 +0000)
committerDavid S. Miller <davem@davemloft.net>
Fri, 21 Oct 2011 06:52:53 +0000 (02:52 -0400)
I've split this bit out of the skb frag destructor patch since it helps enforce
the use of the fragment API.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/linux/skbuff.h
net/core/skbuff.c

index 3411f22e7d1606d74466127c07662bafb8ac3d71..94a23ffcc073651471005f8fad721362376a50d1 100644 (file)
@@ -140,7 +140,9 @@ struct sk_buff;
 typedef struct skb_frag_struct skb_frag_t;
 
 struct skb_frag_struct {
-       struct page *page;
+       struct {
+               struct page *p;
+       } page;
 #if (BITS_PER_LONG > 32) || (PAGE_SIZE >= 65536)
        __u32 page_offset;
        __u32 size;
@@ -1175,7 +1177,7 @@ static inline void __skb_fill_page_desc(struct sk_buff *skb, int i,
 {
        skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
 
-       frag->page                = page;
+       frag->page.p              = page;
        frag->page_offset         = off;
        skb_frag_size_set(frag, size);
 }
@@ -1699,7 +1701,7 @@ static inline void netdev_free_page(struct net_device *dev, struct page *page)
  */
 static inline struct page *skb_frag_page(const skb_frag_t *frag)
 {
-       return frag->page;
+       return frag->page.p;
 }
 
 /**
@@ -1785,7 +1787,7 @@ static inline void *skb_frag_address_safe(const skb_frag_t *frag)
  */
 static inline void __skb_frag_set_page(skb_frag_t *frag, struct page *page)
 {
-       frag->page = page;
+       frag->page.p = page;
 }
 
 /**
index e27104039a390bdd03be17fd846211724466ab48..ca4db40e75b84becaab9c9acef48e5677d202a6c 100644 (file)
@@ -668,14 +668,14 @@ int skb_copy_ubufs(struct sk_buff *skb, gfp_t gfp_mask)
 
        /* skb frags release userspace buffers */
        for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
-               put_page(skb_shinfo(skb)->frags[i].page);
+               skb_frag_unref(skb, i);
 
        uarg->callback(uarg);
 
        /* skb frags point to kernel buffers */
        for (i = skb_shinfo(skb)->nr_frags; i > 0; i--) {
-               skb_shinfo(skb)->frags[i - 1].page_offset = 0;
-               skb_shinfo(skb)->frags[i - 1].page = head;
+               __skb_fill_page_desc(skb, i-1, head, 0,
+                                    skb_shinfo(skb)->frags[i - 1].size);
                head = (struct page *)head->private;
        }