Commit 19900cde authored by Ed L. Cashin's avatar Ed L. Cashin Committed by Linus Torvalds

[PATCH] fix aoe without scatter-gather [Bug 7662]

Fix a bug that only appears when AoE goes over a network card that does not
support scatter-gather.  The headers in the linear part of the skb appeared
to be larger than they really were, resulting in data that was offset by 24
bytes.

This patch eliminates the offset data on cards that don't support
scatter-gather or have had scatter-gather turned off.  There remains an
unrelated issue that I'll address in a separate email.

Fixes bugzilla #7662
Signed-off-by: default avatar"Ed L. Cashin" <ecashin@coraid.com>
Cc: <stable@kernel.org>
Cc: Greg KH <greg@kroah.com>
Cc: <boddingt@optusnet.com.au>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 58637ec9
...@@ -30,8 +30,6 @@ new_skb(ulong len) ...@@ -30,8 +30,6 @@ new_skb(ulong len)
skb->nh.raw = skb->mac.raw = skb->data; skb->nh.raw = skb->mac.raw = skb->data;
skb->protocol = __constant_htons(ETH_P_AOE); skb->protocol = __constant_htons(ETH_P_AOE);
skb->priority = 0; skb->priority = 0;
skb_put(skb, len);
memset(skb->head, 0, len);
skb->next = skb->prev = NULL; skb->next = skb->prev = NULL;
/* tell the network layer not to perform IP checksums /* tell the network layer not to perform IP checksums
...@@ -122,8 +120,8 @@ aoecmd_ata_rw(struct aoedev *d, struct frame *f) ...@@ -122,8 +120,8 @@ aoecmd_ata_rw(struct aoedev *d, struct frame *f)
skb = f->skb; skb = f->skb;
h = (struct aoe_hdr *) skb->mac.raw; h = (struct aoe_hdr *) skb->mac.raw;
ah = (struct aoe_atahdr *) (h+1); ah = (struct aoe_atahdr *) (h+1);
skb->len = sizeof *h + sizeof *ah; skb_put(skb, sizeof *h + sizeof *ah);
memset(h, 0, ETH_ZLEN); memset(h, 0, skb->len);
f->tag = aoehdr_atainit(d, h); f->tag = aoehdr_atainit(d, h);
f->waited = 0; f->waited = 0;
f->buf = buf; f->buf = buf;
...@@ -149,7 +147,6 @@ aoecmd_ata_rw(struct aoedev *d, struct frame *f) ...@@ -149,7 +147,6 @@ aoecmd_ata_rw(struct aoedev *d, struct frame *f)
skb->len += bcnt; skb->len += bcnt;
skb->data_len = bcnt; skb->data_len = bcnt;
} else { } else {
skb->len = ETH_ZLEN;
writebit = 0; writebit = 0;
} }
...@@ -206,6 +203,7 @@ aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff **tail) ...@@ -206,6 +203,7 @@ aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff **tail)
printk(KERN_INFO "aoe: skb alloc failure\n"); printk(KERN_INFO "aoe: skb alloc failure\n");
continue; continue;
} }
skb_put(skb, sizeof *h + sizeof *ch);
skb->dev = ifp; skb->dev = ifp;
if (sl_tail == NULL) if (sl_tail == NULL)
sl_tail = skb; sl_tail = skb;
...@@ -243,6 +241,7 @@ freeframe(struct aoedev *d) ...@@ -243,6 +241,7 @@ freeframe(struct aoedev *d)
continue; continue;
if (atomic_read(&skb_shinfo(f->skb)->dataref) == 1) { if (atomic_read(&skb_shinfo(f->skb)->dataref) == 1) {
skb_shinfo(f->skb)->nr_frags = f->skb->data_len = 0; skb_shinfo(f->skb)->nr_frags = f->skb->data_len = 0;
skb_trim(f->skb, 0);
return f; return f;
} }
n++; n++;
...@@ -698,8 +697,8 @@ aoecmd_ata_id(struct aoedev *d) ...@@ -698,8 +697,8 @@ aoecmd_ata_id(struct aoedev *d)
skb = f->skb; skb = f->skb;
h = (struct aoe_hdr *) skb->mac.raw; h = (struct aoe_hdr *) skb->mac.raw;
ah = (struct aoe_atahdr *) (h+1); ah = (struct aoe_atahdr *) (h+1);
skb->len = ETH_ZLEN; skb_put(skb, sizeof *h + sizeof *ah);
memset(h, 0, ETH_ZLEN); memset(h, 0, skb->len);
f->tag = aoehdr_atainit(d, h); f->tag = aoehdr_atainit(d, h);
f->waited = 0; f->waited = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment