aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2009-06-09 03:18:15 -0400
committerDavid S. Miller <davem@davemloft.net>2009-06-09 03:18:15 -0400
commit5b1a002ade68173f21b2126a778278df72202ba6 (patch)
treeaeafe74ad3df316bc6413e97e7f514a780e117ad
parentc32ba3f9b8aa2441c7cfcd065f79981cf8cfe9f4 (diff)
datagram: Use frag list abstraction interfaces.
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/core/datagram.c178
1 files changed, 83 insertions, 95 deletions
diff --git a/net/core/datagram.c b/net/core/datagram.c
index 774bcd9119d9..58abee1f1df1 100644
--- a/net/core/datagram.c
+++ b/net/core/datagram.c
@@ -282,6 +282,7 @@ int skb_copy_datagram_iovec(const struct sk_buff *skb, int offset,
282{ 282{
283 int start = skb_headlen(skb); 283 int start = skb_headlen(skb);
284 int i, copy = start - offset; 284 int i, copy = start - offset;
285 struct sk_buff *frag_iter;
285 286
286 /* Copy header. */ 287 /* Copy header. */
287 if (copy > 0) { 288 if (copy > 0) {
@@ -322,28 +323,24 @@ int skb_copy_datagram_iovec(const struct sk_buff *skb, int offset,
322 start = end; 323 start = end;
323 } 324 }
324 325
325 if (skb_shinfo(skb)->frag_list) { 326 skb_walk_frags(skb, frag_iter) {
326 struct sk_buff *list = skb_shinfo(skb)->frag_list; 327 int end;
327 328
328 for (; list; list = list->next) { 329 WARN_ON(start > offset + len);
329 int end; 330
330 331 end = start + frag_iter->len;
331 WARN_ON(start > offset + len); 332 if ((copy = end - offset) > 0) {
332 333 if (copy > len)
333 end = start + list->len; 334 copy = len;
334 if ((copy = end - offset) > 0) { 335 if (skb_copy_datagram_iovec(frag_iter,
335 if (copy > len) 336 offset - start,
336 copy = len; 337 to, copy))
337 if (skb_copy_datagram_iovec(list, 338 goto fault;
338 offset - start, 339 if ((len -= copy) == 0)
339 to, copy)) 340 return 0;
340 goto fault; 341 offset += copy;
341 if ((len -= copy) == 0)
342 return 0;
343 offset += copy;
344 }
345 start = end;
346 } 342 }
343 start = end;
347 } 344 }
348 if (!len) 345 if (!len)
349 return 0; 346 return 0;
@@ -369,6 +366,7 @@ int skb_copy_datagram_const_iovec(const struct sk_buff *skb, int offset,
369{ 366{
370 int start = skb_headlen(skb); 367 int start = skb_headlen(skb);
371 int i, copy = start - offset; 368 int i, copy = start - offset;
369 struct sk_buff *frag_iter;
372 370
373 /* Copy header. */ 371 /* Copy header. */
374 if (copy > 0) { 372 if (copy > 0) {
@@ -411,30 +409,26 @@ int skb_copy_datagram_const_iovec(const struct sk_buff *skb, int offset,
411 start = end; 409 start = end;
412 } 410 }
413 411
414 if (skb_shinfo(skb)->frag_list) { 412 skb_walk_frags(skb, frag_iter) {
415 struct sk_buff *list = skb_shinfo(skb)->frag_list; 413 int end;
416 414
417 for (; list; list = list->next) { 415 WARN_ON(start > offset + len);
418 int end; 416
419 417 end = start + frag_iter->len;
420 WARN_ON(start > offset + len); 418 if ((copy = end - offset) > 0) {
421 419 if (copy > len)
422 end = start + list->len; 420 copy = len;
423 if ((copy = end - offset) > 0) { 421 if (skb_copy_datagram_const_iovec(frag_iter,
424 if (copy > len) 422 offset - start,
425 copy = len; 423 to, to_offset,
426 if (skb_copy_datagram_const_iovec(list, 424 copy))
427 offset - start, 425 goto fault;
428 to, to_offset, 426 if ((len -= copy) == 0)
429 copy)) 427 return 0;
430 goto fault; 428 offset += copy;
431 if ((len -= copy) == 0) 429 to_offset += copy;
432 return 0;
433 offset += copy;
434 to_offset += copy;
435 }
436 start = end;
437 } 430 }
431 start = end;
438 } 432 }
439 if (!len) 433 if (!len)
440 return 0; 434 return 0;
@@ -461,6 +455,7 @@ int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset,
461{ 455{
462 int start = skb_headlen(skb); 456 int start = skb_headlen(skb);
463 int i, copy = start - offset; 457 int i, copy = start - offset;
458 struct sk_buff *frag_iter;
464 459
465 /* Copy header. */ 460 /* Copy header. */
466 if (copy > 0) { 461 if (copy > 0) {
@@ -506,31 +501,27 @@ int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset,
506 start = end; 501 start = end;
507 } 502 }
508 503
509 if (skb_shinfo(skb)->frag_list) { 504 skb_walk_frags(skb, frag_iter) {
510 struct sk_buff *list = skb_shinfo(skb)->frag_list; 505 int end;
511 506
512 for (; list; list = list->next) { 507 WARN_ON(start > offset + len);
513 int end; 508
514 509 end = start + frag_iter->len;
515 WARN_ON(start > offset + len); 510 if ((copy = end - offset) > 0) {
516 511 if (copy > len)
517 end = start + list->len; 512 copy = len;
518 if ((copy = end - offset) > 0) { 513 if (skb_copy_datagram_from_iovec(frag_iter,
519 if (copy > len) 514 offset - start,
520 copy = len; 515 from,
521 if (skb_copy_datagram_from_iovec(list, 516 from_offset,
522 offset - start, 517 copy))
523 from, 518 goto fault;
524 from_offset, 519 if ((len -= copy) == 0)
525 copy)) 520 return 0;
526 goto fault; 521 offset += copy;
527 if ((len -= copy) == 0) 522 from_offset += copy;
528 return 0;
529 offset += copy;
530 from_offset += copy;
531 }
532 start = end;
533 } 523 }
524 start = end;
534 } 525 }
535 if (!len) 526 if (!len)
536 return 0; 527 return 0;
@@ -545,8 +536,9 @@ static int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset,
545 __wsum *csump) 536 __wsum *csump)
546{ 537{
547 int start = skb_headlen(skb); 538 int start = skb_headlen(skb);
548 int pos = 0;
549 int i, copy = start - offset; 539 int i, copy = start - offset;
540 struct sk_buff *frag_iter;
541 int pos = 0;
550 542
551 /* Copy header. */ 543 /* Copy header. */
552 if (copy > 0) { 544 if (copy > 0) {
@@ -597,33 +589,29 @@ static int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset,
597 start = end; 589 start = end;
598 } 590 }
599 591
600 if (skb_shinfo(skb)->frag_list) { 592 skb_walk_frags(skb, frag_iter) {
601 struct sk_buff *list = skb_shinfo(skb)->frag_list; 593 int end;
602 594
603 for (; list; list=list->next) { 595 WARN_ON(start > offset + len);
604 int end; 596
605 597 end = start + frag_iter->len;
606 WARN_ON(start > offset + len); 598 if ((copy = end - offset) > 0) {
607 599 __wsum csum2 = 0;
608 end = start + list->len; 600 if (copy > len)
609 if ((copy = end - offset) > 0) { 601 copy = len;
610 __wsum csum2 = 0; 602 if (skb_copy_and_csum_datagram(frag_iter,
611 if (copy > len) 603 offset - start,
612 copy = len; 604 to, copy,
613 if (skb_copy_and_csum_datagram(list, 605 &csum2))
614 offset - start, 606 goto fault;
615 to, copy, 607 *csump = csum_block_add(*csump, csum2, pos);
616 &csum2)) 608 if ((len -= copy) == 0)
617 goto fault; 609 return 0;
618 *csump = csum_block_add(*csump, csum2, pos); 610 offset += copy;
619 if ((len -= copy) == 0) 611 to += copy;
620 return 0; 612 pos += copy;
621 offset += copy;
622 to += copy;
623 pos += copy;
624 }
625 start = end;
626 } 613 }
614 start = end;
627 } 615 }
628 if (!len) 616 if (!len)
629 return 0; 617 return 0;