size = SKB_DATA_ALIGN(size);
 
+       /* Check if we can avoid taking references on fragments if we own
+        * the last reference on skb->head. (see skb_release_data())
+        */
+       if (!skb->cloned)
+               fastpath = true;
+       else {
+               int delta = skb->nohdr ? (1 << SKB_DATAREF_SHIFT) + 1 : 1;
+
+               fastpath = atomic_read(&skb_shinfo(skb)->dataref) == delta;
+       }
+
+       if (fastpath &&
+           size + sizeof(struct skb_shared_info) <= ksize(skb->head)) {
+               memmove(skb->head + size, skb_shinfo(skb),
+                       offsetof(struct skb_shared_info,
+                                frags[skb_shinfo(skb)->nr_frags]));
+               memmove(skb->head + nhead, skb->head,
+                       skb_tail_pointer(skb) - skb->head);
+               off = nhead;
+               goto adjust_others;
+       }
+
        data = kmalloc(size + sizeof(struct skb_shared_info), gfp_mask);
        if (!data)
                goto nodata;
               skb_shinfo(skb),
               offsetof(struct skb_shared_info, frags[skb_shinfo(skb)->nr_frags]));
 
-       /* Check if we can avoid taking references on fragments if we own
-        * the last reference on skb->head. (see skb_release_data())
-        */
-       if (!skb->cloned)
-               fastpath = true;
-       else {
-               int delta = skb->nohdr ? (1 << SKB_DATAREF_SHIFT) + 1 : 1;
-
-               fastpath = atomic_read(&skb_shinfo(skb)->dataref) == delta;
-       }
-
        if (fastpath) {
                kfree(skb->head);
        } else {
        off = (data + nhead) - skb->head;
 
        skb->head     = data;
+adjust_others:
        skb->data    += off;
 #ifdef NET_SKBUFF_DATA_USES_OFFSET
        skb->end      = size;