struct scatterlist *sg;
        struct fc_frame *fp = NULL;
        struct fc_lport *lport = fsp->lp;
+       struct page *page;
        size_t remaining;
        size_t t_blen;
        size_t tlen;
        size_t sg_bytes;
        size_t frame_offset, fh_parm_offset;
+       size_t off;
        int error;
        void *data = NULL;
        void *page_addr;
                        fh_parm_offset = frame_offset;
                        fr_max_payload(fp) = fsp->max_payload;
                }
+
+               off = offset + sg->offset;
                sg_bytes = min(tlen, sg->length - offset);
+               sg_bytes = min(sg_bytes,
+                              (size_t) (PAGE_SIZE - (off & ~PAGE_MASK)));
+               page = sg_page(sg) + (off >> PAGE_SHIFT);
                if (using_sg) {
-                       get_page(sg_page(sg));
+                       get_page(page);
                        skb_fill_page_desc(fp_skb(fp),
                                           skb_shinfo(fp_skb(fp))->nr_frags,
-                                          sg_page(sg), sg->offset + offset,
-                                          sg_bytes);
+                                          page, off & ~PAGE_MASK, sg_bytes);
                        fp_skb(fp)->data_len += sg_bytes;
                        fr_len(fp) += sg_bytes;
                        fp_skb(fp)->truesize += PAGE_SIZE;
                } else {
-                       size_t off = offset + sg->offset;
-
                        /*
                         * The scatterlist item may be bigger than PAGE_SIZE,
                         * but we must not cross pages inside the kmap.
                         */
-                       sg_bytes = min(sg_bytes, (size_t) (PAGE_SIZE -
-                                                          (off & ~PAGE_MASK)));
-                       page_addr = kmap_atomic(sg_page(sg) +
-                                               (off >> PAGE_SHIFT),
-                                               KM_SOFTIRQ0);
+                       page_addr = kmap_atomic(page, KM_SOFTIRQ0);
                        memcpy(data, (char *)page_addr + (off & ~PAGE_MASK),
                               sg_bytes);
                        kunmap_atomic(page_addr, KM_SOFTIRQ0);
 
 
        WARN_ON((len % sizeof(u32)) != 0);
        len += sizeof(struct fc_frame_header);
-       skb = dev_alloc_skb(len + FC_FRAME_HEADROOM + FC_FRAME_TAILROOM);
+       skb = alloc_skb_fclone(len + FC_FRAME_HEADROOM + FC_FRAME_TAILROOM +
+                              NET_SKB_PAD, GFP_ATOMIC);
        if (!skb)
                return NULL;
+       skb_reserve(skb, NET_SKB_PAD + FC_FRAME_HEADROOM);
        fp = (struct fc_frame *) skb;
        fc_frame_init(fp);
-       skb_reserve(skb, FC_FRAME_HEADROOM);
        skb_put(skb, len);
        return fp;
 }