This version is cleaner and easy to read. Thanks. You may add the tag if you like.
Reviewed-by: Parthasarathy Bhuvaragan <[email protected]> /Partha On 04/29/2017 02:50 AM, Jon Maloy wrote: > We try to make this function more readable by improving variable names > and comments, using more stack variables, and doing some smaller changes > to the logics. We also rename the function to make it consistent with > naming conventions used elsewhere in the code. > > Signed-off-by: Jon Maloy <[email protected]> > --- > net/tipc/socket.c | 155 > +++++++++++++++++++++++++----------------------------- > 1 file changed, 71 insertions(+), 84 deletions(-) > > diff --git a/net/tipc/socket.c b/net/tipc/socket.c > index 9621630..0d4f2f4 100644 > --- a/net/tipc/socket.c > +++ b/net/tipc/socket.c > @@ -1390,9 +1390,9 @@ static int tipc_recvmsg(struct socket *sock, struct > msghdr *m, > } > > /** > - * tipc_recv_stream - receive stream-oriented data > + * tipc_recvstream - receive stream-oriented data > * @m: descriptor for message info > - * @buf_len: total size of user buffer area > + * @buflen: total size of user buffer area > * @flags: receive flags > * > * Used for SOCK_STREAM messages only. If not enough data is available > @@ -1400,111 +1400,98 @@ static int tipc_recvmsg(struct socket *sock, struct > msghdr *m, > * > * Returns size of returned message data, errno otherwise > */ > -static int tipc_recv_stream(struct socket *sock, struct msghdr *m, > - size_t buf_len, int flags) > +static int tipc_recvstream(struct socket *sock, struct msghdr *m, > + size_t buflen, int flags) > { > struct sock *sk = sock->sk; > struct tipc_sock *tsk = tipc_sk(sk); > - struct sk_buff *buf; > - struct tipc_msg *msg; > - long timeo; > - unsigned int sz; > - int target; > - int sz_copied = 0; > - u32 err; > - int res = 0, hlen; > + struct sk_buff *skb; > + struct tipc_msg *hdr; > + struct tipc_skb_cb *skb_cb; > + bool peek = flags & MSG_PEEK; > + int offset, required, copy, copied = 0; > + int hlen, dlen, err, rc; > + long timeout; > > /* Catch invalid receive attempts */ > - if (unlikely(!buf_len)) > + if (unlikely(!buflen)) > return -EINVAL; > > lock_sock(sk); > > if (unlikely(sk->sk_state == TIPC_OPEN)) { > - res = -ENOTCONN; > - goto exit; > - } > - > - target = sock_rcvlowat(sk, flags & MSG_WAITALL, buf_len); > - timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); > - > -restart: > - /* Look for a message in receive queue; wait if necessary */ > - res = tipc_wait_for_rcvmsg(sock, &timeo); > - if (res) > + rc = -ENOTCONN; > goto exit; > - > - /* Look at first message in receive queue */ > - buf = skb_peek(&sk->sk_receive_queue); > - msg = buf_msg(buf); > - sz = msg_data_sz(msg); > - hlen = msg_hdr_sz(msg); > - err = msg_errcode(msg); > - > - /* Discard an empty non-errored message & try again */ > - if ((!sz) && (!err)) { > - tsk_advance_rx_queue(sk); > - goto restart; > } > + required = sock_rcvlowat(sk, flags & MSG_WAITALL, buflen); > + timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); > > - /* Optionally capture sender's address & ancillary data of first msg */ > - if (sz_copied == 0) { > - set_orig_addr(m, msg); > - res = tipc_sk_anc_data_recv(m, msg, tsk); > - if (res) > - goto exit; > - } > - > - /* Capture message data (if valid) & compute return value (always) */ > - if (!err) { > - u32 offset = TIPC_SKB_CB(buf)->bytes_read; > - u32 needed; > - int sz_to_copy; > - > - sz -= offset; > - needed = (buf_len - sz_copied); > - sz_to_copy = min(sz, needed); > + do { > + /* Look at first msg in receive queue; wait if necessary */ > + rc = tipc_wait_for_rcvmsg(sock, &timeout); > + if (unlikely(rc)) > + break; > + skb = skb_peek(&sk->sk_receive_queue); > + skb_cb = TIPC_SKB_CB(skb); > + hdr = buf_msg(skb); > + dlen = msg_data_sz(hdr); > + hlen = msg_hdr_sz(hdr); > + err = msg_errcode(hdr); > > - res = skb_copy_datagram_msg(buf, hlen + offset, m, sz_to_copy); > - if (res) > - goto exit; > + /* Discard any empty non-errored (SYN-) message */ > + if (unlikely(!dlen && !err)) { > + tsk_advance_rx_queue(sk); > + continue; > + } > > - sz_copied += sz_to_copy; > + /* Collect msg meta data, incl. error code and rejected data */ > + if (!copied) { > + set_orig_addr(m, hdr); > + rc = tipc_sk_anc_data_recv(m, hdr, tsk); > + if (rc) > + break; > + } > > - if (sz_to_copy < sz) { > - if (!(flags & MSG_PEEK)) > - TIPC_SKB_CB(buf)->bytes_read = > - offset + sz_to_copy; > - goto exit; > + /* Copy data if msg ok, otherwise return error/partial data */ > + if (likely(!err)) { > + offset = skb_cb->bytes_read; > + copy = min_t(int, dlen - offset, buflen - copied); > + rc = skb_copy_datagram_msg(skb, hlen + offset, m, copy); > + if (unlikely(rc)) > + break; > + copied += copy; > + offset += copy; > + if (unlikely(offset < dlen)) { > + if (!peek) > + skb_cb->bytes_read = offset; > + break; > + } > + } else { > + rc = 0; > + if ((err != TIPC_CONN_SHUTDOWN) && !m->msg_control) > + rc = -ECONNRESET; > + if (copied || rc) > + break; > } > - } else { > - if (sz_copied != 0) > - goto exit; /* can't add error msg to valid data */ > > - if ((err == TIPC_CONN_SHUTDOWN) || m->msg_control) > - res = 0; > - else > - res = -ECONNRESET; > - } > + if (unlikely(peek)) > + break; > > - if (unlikely(flags & MSG_PEEK)) > - goto exit; > + tsk_advance_rx_queue(sk); > > - tsk->rcv_unacked += tsk_inc(tsk, hlen + msg_data_sz(msg)); > - if (unlikely(tsk->rcv_unacked >= (tsk->rcv_win / 4))) > - tipc_sk_send_ack(tsk); > - tsk_advance_rx_queue(sk); > + /* Send connection flow control advertisement when applicable */ > + tsk->rcv_unacked += tsk_inc(tsk, hlen + dlen); > + if (unlikely(tsk->rcv_unacked >= tsk->rcv_win / TIPC_ACK_RATE)) > + tipc_sk_send_ack(tsk); > > - /* Loop around if more data is required */ > - if ((sz_copied < buf_len) && /* didn't get all requested data */ > - (!skb_queue_empty(&sk->sk_receive_queue) || > - (sz_copied < target)) && /* and more is ready or required */ > - (!err)) /* and haven't reached a FIN */ > - goto restart; > + /* Exit if all requested data or FIN/error received */ > + if (copied == buflen || err) > + break; > > + } while (!skb_queue_empty(&sk->sk_receive_queue) || copied < required); > exit: > release_sock(sk); > - return sz_copied ? sz_copied : res; > + return copied ? copied : rc; > } > > /** > @@ -2610,7 +2597,7 @@ static const struct proto_ops stream_ops = { > .setsockopt = tipc_setsockopt, > .getsockopt = tipc_getsockopt, > .sendmsg = tipc_sendstream, > - .recvmsg = tipc_recv_stream, > + .recvmsg = tipc_recvstream, > .mmap = sock_no_mmap, > .sendpage = sock_no_sendpage > }; > ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot _______________________________________________ tipc-discussion mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/tipc-discussion
