diff options
author | David S. Miller <davem@davemloft.net> | 2015-02-04 23:46:55 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-02-04 23:46:55 -0500 |
commit | f2683b743f2334ef49a5361bf596dd1fbd2c9be4 (patch) | |
tree | 7f53b2614742238e966ba8a815ef6c5079422ee2 /net/rxrpc | |
parent | 9878196578286c5ed494778ada01da094377a686 (diff) | |
parent | 57dd8a0735aabff4862025cf64ad94da3d80e620 (diff) |
Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
More iov_iter work from Al Viro.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/rxrpc')
-rw-r--r-- | net/rxrpc/ar-output.c | 46 |
1 files changed, 10 insertions, 36 deletions
diff --git a/net/rxrpc/ar-output.c b/net/rxrpc/ar-output.c index e1a9373e5979..8331c95e1522 100644 --- a/net/rxrpc/ar-output.c +++ b/net/rxrpc/ar-output.c | |||
@@ -232,10 +232,7 @@ int rxrpc_kernel_send_data(struct rxrpc_call *call, struct msghdr *msg, | |||
232 | call->state != RXRPC_CALL_SERVER_SEND_REPLY) { | 232 | call->state != RXRPC_CALL_SERVER_SEND_REPLY) { |
233 | ret = -EPROTO; /* request phase complete for this client call */ | 233 | ret = -EPROTO; /* request phase complete for this client call */ |
234 | } else { | 234 | } else { |
235 | mm_segment_t oldfs = get_fs(); | ||
236 | set_fs(KERNEL_DS); | ||
237 | ret = rxrpc_send_data(NULL, call->socket, call, msg, len); | 235 | ret = rxrpc_send_data(NULL, call->socket, call, msg, len); |
238 | set_fs(oldfs); | ||
239 | } | 236 | } |
240 | 237 | ||
241 | release_sock(&call->socket->sk); | 238 | release_sock(&call->socket->sk); |
@@ -529,13 +526,11 @@ static int rxrpc_send_data(struct kiocb *iocb, | |||
529 | struct msghdr *msg, size_t len) | 526 | struct msghdr *msg, size_t len) |
530 | { | 527 | { |
531 | struct rxrpc_skb_priv *sp; | 528 | struct rxrpc_skb_priv *sp; |
532 | unsigned char __user *from; | ||
533 | struct sk_buff *skb; | 529 | struct sk_buff *skb; |
534 | const struct iovec *iov; | ||
535 | struct sock *sk = &rx->sk; | 530 | struct sock *sk = &rx->sk; |
536 | long timeo; | 531 | long timeo; |
537 | bool more; | 532 | bool more; |
538 | int ret, ioc, segment, copied; | 533 | int ret, copied; |
539 | 534 | ||
540 | timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT); | 535 | timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT); |
541 | 536 | ||
@@ -545,25 +540,17 @@ static int rxrpc_send_data(struct kiocb *iocb, | |||
545 | if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN)) | 540 | if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN)) |
546 | return -EPIPE; | 541 | return -EPIPE; |
547 | 542 | ||
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; | 543 | more = msg->msg_flags & MSG_MORE; |
554 | 544 | ||
555 | skb = call->tx_pending; | 545 | skb = call->tx_pending; |
556 | call->tx_pending = NULL; | 546 | call->tx_pending = NULL; |
557 | 547 | ||
558 | copied = 0; | 548 | copied = 0; |
559 | do { | 549 | if (len > iov_iter_count(&msg->msg_iter)) |
550 | len = iov_iter_count(&msg->msg_iter); | ||
551 | while (len) { | ||
560 | int copy; | 552 | int copy; |
561 | 553 | ||
562 | if (segment > len) | ||
563 | segment = len; | ||
564 | |||
565 | _debug("SEGMENT %d @%p", segment, from); | ||
566 | |||
567 | if (!skb) { | 554 | if (!skb) { |
568 | size_t size, chunk, max, space; | 555 | size_t size, chunk, max, space; |
569 | 556 | ||
@@ -631,13 +618,13 @@ static int rxrpc_send_data(struct kiocb *iocb, | |||
631 | /* append next segment of data to the current buffer */ | 618 | /* append next segment of data to the current buffer */ |
632 | copy = skb_tailroom(skb); | 619 | copy = skb_tailroom(skb); |
633 | ASSERTCMP(copy, >, 0); | 620 | ASSERTCMP(copy, >, 0); |
634 | if (copy > segment) | 621 | if (copy > len) |
635 | copy = segment; | 622 | copy = len; |
636 | if (copy > sp->remain) | 623 | if (copy > sp->remain) |
637 | copy = sp->remain; | 624 | copy = sp->remain; |
638 | 625 | ||
639 | _debug("add"); | 626 | _debug("add"); |
640 | ret = skb_add_data(skb, from, copy); | 627 | ret = skb_add_data(skb, &msg->msg_iter, copy); |
641 | _debug("added"); | 628 | _debug("added"); |
642 | if (ret < 0) | 629 | if (ret < 0) |
643 | goto efault; | 630 | goto efault; |
@@ -646,18 +633,6 @@ static int rxrpc_send_data(struct kiocb *iocb, | |||
646 | copied += copy; | 633 | copied += copy; |
647 | 634 | ||
648 | len -= copy; | 635 | 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 | 636 | ||
662 | /* check for the far side aborting the call or a network error | 637 | /* check for the far side aborting the call or a network error |
663 | * occurring */ | 638 | * occurring */ |
@@ -665,7 +640,7 @@ static int rxrpc_send_data(struct kiocb *iocb, | |||
665 | goto call_aborted; | 640 | goto call_aborted; |
666 | 641 | ||
667 | /* add the packet to the send queue if it's now full */ | 642 | /* add the packet to the send queue if it's now full */ |
668 | if (sp->remain <= 0 || (segment == 0 && !more)) { | 643 | if (sp->remain <= 0 || (!len && !more)) { |
669 | struct rxrpc_connection *conn = call->conn; | 644 | struct rxrpc_connection *conn = call->conn; |
670 | uint32_t seq; | 645 | uint32_t seq; |
671 | size_t pad; | 646 | size_t pad; |
@@ -711,11 +686,10 @@ static int rxrpc_send_data(struct kiocb *iocb, | |||
711 | 686 | ||
712 | memcpy(skb->head, &sp->hdr, | 687 | memcpy(skb->head, &sp->hdr, |
713 | sizeof(struct rxrpc_header)); | 688 | sizeof(struct rxrpc_header)); |
714 | rxrpc_queue_packet(call, skb, segment == 0 && !more); | 689 | rxrpc_queue_packet(call, skb, !iov_iter_count(&msg->msg_iter) && !more); |
715 | skb = NULL; | 690 | skb = NULL; |
716 | } | 691 | } |
717 | 692 | } | |
718 | } while (segment > 0); | ||
719 | 693 | ||
720 | success: | 694 | success: |
721 | ret = copied; | 695 | ret = copied; |