diff options
| author | Al Viro <viro@zeniv.linux.org.uk> | 2014-11-27 21:44:24 -0500 |
|---|---|---|
| committer | Al Viro <viro@zeniv.linux.org.uk> | 2015-02-04 01:34:14 -0500 |
| commit | af2b040e470b470bfc881981db3c796072853eae (patch) | |
| tree | 9ab10e106e7d5e3dc1a0783abc99d5c6d8e0b882 /net | |
| parent | 4c946d9c11d173c2ea6b9081b248f8072e6b46f1 (diff) | |
rxrpc: switch rxrpc_send_data() to iov_iter primitives
Convert skb_add_data() to iov_iter; allows to get rid of the explicit
messing with iovec in its only caller - skb_add_data() will keep advancing
->msg_iter for us, so there's no need to similate that manually.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'net')
| -rw-r--r-- | net/rxrpc/ar-output.c | 43 |
1 files changed, 10 insertions, 33 deletions
diff --git a/net/rxrpc/ar-output.c b/net/rxrpc/ar-output.c index e1a9373e5979..963a5b91f3e8 100644 --- a/net/rxrpc/ar-output.c +++ b/net/rxrpc/ar-output.c | |||
| @@ -529,13 +529,11 @@ static int rxrpc_send_data(struct kiocb *iocb, | |||
| 529 | struct msghdr *msg, size_t len) | 529 | struct msghdr *msg, size_t len) |
| 530 | { | 530 | { |
| 531 | struct rxrpc_skb_priv *sp; | 531 | struct rxrpc_skb_priv *sp; |
| 532 | unsigned char __user *from; | ||
| 533 | struct sk_buff *skb; | 532 | struct sk_buff *skb; |
| 534 | const struct iovec *iov; | ||
| 535 | struct sock *sk = &rx->sk; | 533 | struct sock *sk = &rx->sk; |
| 536 | long timeo; | 534 | long timeo; |
| 537 | bool more; | 535 | bool more; |
| 538 | int ret, ioc, segment, copied; | 536 | int ret, copied; |
| 539 | 537 | ||
| 540 | timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT); | 538 | timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT); |
| 541 | 539 | ||
| @@ -545,25 +543,17 @@ static int rxrpc_send_data(struct kiocb *iocb, | |||
| 545 | if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN)) | 543 | if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN)) |
| 546 | return -EPIPE; | 544 | return -EPIPE; |
| 547 | 545 | ||
| 548 | iov = msg->msg_iter.iov; | ||
| 549 | ioc = msg->msg_iter.nr_segs - 1; | ||
| 550 | from = iov->iov_base; | ||
| 551 | segment = iov->iov_len; | ||
| 552 | iov++; | ||
| 553 | more = msg->msg_flags & MSG_MORE; | 546 | more = msg->msg_flags & MSG_MORE; |
| 554 | 547 | ||
| 555 | skb = call->tx_pending; | 548 | skb = call->tx_pending; |
| 556 | call->tx_pending = NULL; | 549 | call->tx_pending = NULL; |
| 557 | 550 | ||
| 558 | copied = 0; | 551 | copied = 0; |
| 559 | do { | 552 | if (len > iov_iter_count(&msg->msg_iter)) |
| 553 | len = iov_iter_count(&msg->msg_iter); | ||
| 554 | while (len) { | ||
| 560 | int copy; | 555 | int copy; |
| 561 | 556 | ||
| 562 | if (segment > len) | ||
| 563 | segment = len; | ||
| 564 | |||
| 565 | _debug("SEGMENT %d @%p", segment, from); | ||
| 566 | |||
| 567 | if (!skb) { | 557 | if (!skb) { |
| 568 | size_t size, chunk, max, space; | 558 | size_t size, chunk, max, space; |
| 569 | 559 | ||
| @@ -631,13 +621,13 @@ static int rxrpc_send_data(struct kiocb *iocb, | |||
| 631 | /* append next segment of data to the current buffer */ | 621 | /* append next segment of data to the current buffer */ |
| 632 | copy = skb_tailroom(skb); | 622 | copy = skb_tailroom(skb); |
| 633 | ASSERTCMP(copy, >, 0); | 623 | ASSERTCMP(copy, >, 0); |
| 634 | if (copy > segment) | 624 | if (copy > len) |
| 635 | copy = segment; | 625 | copy = len; |
| 636 | if (copy > sp->remain) | 626 | if (copy > sp->remain) |
| 637 | copy = sp->remain; | 627 | copy = sp->remain; |
| 638 | 628 | ||
| 639 | _debug("add"); | 629 | _debug("add"); |
| 640 | ret = skb_add_data(skb, from, copy); | 630 | ret = skb_add_data(skb, &msg->msg_iter, copy); |
| 641 | _debug("added"); | 631 | _debug("added"); |
| 642 | if (ret < 0) | 632 | if (ret < 0) |
| 643 | goto efault; | 633 | goto efault; |
| @@ -646,18 +636,6 @@ static int rxrpc_send_data(struct kiocb *iocb, | |||
| 646 | copied += copy; | 636 | copied += copy; |
| 647 | 637 | ||
| 648 | len -= copy; | 638 | len -= copy; |
| 649 | segment -= copy; | ||
| 650 | from += copy; | ||
| 651 | while (segment == 0 && ioc > 0) { | ||
| 652 | from = iov->iov_base; | ||
| 653 | segment = iov->iov_len; | ||
| 654 | iov++; | ||
| 655 | ioc--; | ||
| 656 | } | ||
| 657 | if (len == 0) { | ||
| 658 | segment = 0; | ||
| 659 | ioc = 0; | ||
| 660 | } | ||
| 661 | 639 | ||
| 662 | /* check for the far side aborting the call or a network error | 640 | /* check for the far side aborting the call or a network error |
| 663 | * occurring */ | 641 | * occurring */ |
| @@ -665,7 +643,7 @@ static int rxrpc_send_data(struct kiocb *iocb, | |||
| 665 | goto call_aborted; | 643 | goto call_aborted; |
| 666 | 644 | ||
| 667 | /* add the packet to the send queue if it's now full */ | 645 | /* add the packet to the send queue if it's now full */ |
| 668 | if (sp->remain <= 0 || (segment == 0 && !more)) { | 646 | if (sp->remain <= 0 || (!len && !more)) { |
| 669 | struct rxrpc_connection *conn = call->conn; | 647 | struct rxrpc_connection *conn = call->conn; |
| 670 | uint32_t seq; | 648 | uint32_t seq; |
| 671 | size_t pad; | 649 | size_t pad; |
| @@ -711,11 +689,10 @@ static int rxrpc_send_data(struct kiocb *iocb, | |||
| 711 | 689 | ||
| 712 | memcpy(skb->head, &sp->hdr, | 690 | memcpy(skb->head, &sp->hdr, |
| 713 | sizeof(struct rxrpc_header)); | 691 | sizeof(struct rxrpc_header)); |
| 714 | rxrpc_queue_packet(call, skb, segment == 0 && !more); | 692 | rxrpc_queue_packet(call, skb, !iov_iter_count(&msg->msg_iter) && !more); |
| 715 | skb = NULL; | 693 | skb = NULL; |
| 716 | } | 694 | } |
| 717 | 695 | } | |
| 718 | } while (segment > 0); | ||
| 719 | 696 | ||
| 720 | success: | 697 | success: |
| 721 | ret = copied; | 698 | ret = copied; |
