diff options
author | David S. Miller <davem@davemloft.net> | 2009-06-09 03:18:15 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-06-09 03:18:15 -0400 |
commit | 5b1a002ade68173f21b2126a778278df72202ba6 (patch) | |
tree | aeafe74ad3df316bc6413e97e7f514a780e117ad | |
parent | c32ba3f9b8aa2441c7cfcd065f79981cf8cfe9f4 (diff) |
datagram: Use frag list abstraction interfaces.
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/core/datagram.c | 178 |
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; |