aboutsummaryrefslogtreecommitdiffstats
path: root/net/rxrpc
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2015-02-04 23:46:55 -0500
committerDavid S. Miller <davem@davemloft.net>2015-02-04 23:46:55 -0500
commitf2683b743f2334ef49a5361bf596dd1fbd2c9be4 (patch)
tree7f53b2614742238e966ba8a815ef6c5079422ee2 /net/rxrpc
parent9878196578286c5ed494778ada01da094377a686 (diff)
parent57dd8a0735aabff4862025cf64ad94da3d80e620 (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.c46
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
720success: 694success:
721 ret = copied; 695 ret = copied;