aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEd L. Cashin <ecashin@coraid.com>2006-12-22 04:09:21 -0500
committerLinus Torvalds <torvalds@woody.osdl.org>2006-12-22 11:55:49 -0500
commit19900cdee29c812857ce938ab449e1053d516252 (patch)
treee8563f7147955a435012ade82837395f5fc84897
parent58637ec90b7ceed5909e726ac90118852f79d2b1 (diff)
[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: "Ed L. Cashin" <ecashin@coraid.com> Cc: <stable@kernel.org> Cc: Greg KH <greg@kroah.com> Cc: <boddingt@optusnet.com.au> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--drivers/block/aoe/aoecmd.c13
1 files changed, 6 insertions, 7 deletions
diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c
index 97f7f535f412..bb022ed4a866 100644
--- a/drivers/block/aoe/aoecmd.c
+++ b/drivers/block/aoe/aoecmd.c
@@ -30,8 +30,6 @@ new_skb(ulong len)
30 skb->nh.raw = skb->mac.raw = skb->data; 30 skb->nh.raw = skb->mac.raw = skb->data;
31 skb->protocol = __constant_htons(ETH_P_AOE); 31 skb->protocol = __constant_htons(ETH_P_AOE);
32 skb->priority = 0; 32 skb->priority = 0;
33 skb_put(skb, len);
34 memset(skb->head, 0, len);
35 skb->next = skb->prev = NULL; 33 skb->next = skb->prev = NULL;
36 34
37 /* tell the network layer not to perform IP checksums 35 /* tell the network layer not to perform IP checksums
@@ -122,8 +120,8 @@ aoecmd_ata_rw(struct aoedev *d, struct frame *f)
122 skb = f->skb; 120 skb = f->skb;
123 h = (struct aoe_hdr *) skb->mac.raw; 121 h = (struct aoe_hdr *) skb->mac.raw;
124 ah = (struct aoe_atahdr *) (h+1); 122 ah = (struct aoe_atahdr *) (h+1);
125 skb->len = sizeof *h + sizeof *ah; 123 skb_put(skb, sizeof *h + sizeof *ah);
126 memset(h, 0, ETH_ZLEN); 124 memset(h, 0, skb->len);
127 f->tag = aoehdr_atainit(d, h); 125 f->tag = aoehdr_atainit(d, h);
128 f->waited = 0; 126 f->waited = 0;
129 f->buf = buf; 127 f->buf = buf;
@@ -149,7 +147,6 @@ aoecmd_ata_rw(struct aoedev *d, struct frame *f)
149 skb->len += bcnt; 147 skb->len += bcnt;
150 skb->data_len = bcnt; 148 skb->data_len = bcnt;
151 } else { 149 } else {
152 skb->len = ETH_ZLEN;
153 writebit = 0; 150 writebit = 0;
154 } 151 }
155 152
@@ -206,6 +203,7 @@ aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff **tail)
206 printk(KERN_INFO "aoe: skb alloc failure\n"); 203 printk(KERN_INFO "aoe: skb alloc failure\n");
207 continue; 204 continue;
208 } 205 }
206 skb_put(skb, sizeof *h + sizeof *ch);
209 skb->dev = ifp; 207 skb->dev = ifp;
210 if (sl_tail == NULL) 208 if (sl_tail == NULL)
211 sl_tail = skb; 209 sl_tail = skb;
@@ -243,6 +241,7 @@ freeframe(struct aoedev *d)
243 continue; 241 continue;
244 if (atomic_read(&skb_shinfo(f->skb)->dataref) == 1) { 242 if (atomic_read(&skb_shinfo(f->skb)->dataref) == 1) {
245 skb_shinfo(f->skb)->nr_frags = f->skb->data_len = 0; 243 skb_shinfo(f->skb)->nr_frags = f->skb->data_len = 0;
244 skb_trim(f->skb, 0);
246 return f; 245 return f;
247 } 246 }
248 n++; 247 n++;
@@ -698,8 +697,8 @@ aoecmd_ata_id(struct aoedev *d)
698 skb = f->skb; 697 skb = f->skb;
699 h = (struct aoe_hdr *) skb->mac.raw; 698 h = (struct aoe_hdr *) skb->mac.raw;
700 ah = (struct aoe_atahdr *) (h+1); 699 ah = (struct aoe_atahdr *) (h+1);
701 skb->len = ETH_ZLEN; 700 skb_put(skb, sizeof *h + sizeof *ah);
702 memset(h, 0, ETH_ZLEN); 701 memset(h, 0, skb->len);
703 f->tag = aoehdr_atainit(d, h); 702 f->tag = aoehdr_atainit(d, h);
704 f->waited = 0; 703 f->waited = 0;
705 704