diff options
author | Jon Paul Maloy <jon.maloy@ericsson.com> | 2017-05-02 12:16:53 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-05-02 15:56:54 -0400 |
commit | e9f8b10101c6da3ab000a2fb17162374c9bd2c69 (patch) | |
tree | e03054477c5282ba28b62fc88702c0a57f957d1d /net/tipc/socket.c | |
parent | b0e92279d3ec3656152c4dfa1c8b28fa40ca66d7 (diff) |
tipc: refactor function tipc_sk_recvmsg()
We try to make this function more readable by improving variable names
and comments, plus some minor changes to the logics.
Reviewed-by: Parthasarathy Bhuvaragan <parthasarathy.bhuvaragan@ericsson.com>
Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc/socket.c')
-rw-r--r-- | net/tipc/socket.c | 109 |
1 files changed, 50 insertions, 59 deletions
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 8a4e9fe5f9eb..3855bfd1fb1b 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
@@ -51,6 +51,7 @@ | |||
51 | #define TIPC_FWD_MSG 1 | 51 | #define TIPC_FWD_MSG 1 |
52 | #define TIPC_MAX_PORT 0xffffffff | 52 | #define TIPC_MAX_PORT 0xffffffff |
53 | #define TIPC_MIN_PORT 1 | 53 | #define TIPC_MIN_PORT 1 |
54 | #define TIPC_ACK_RATE 4 /* ACK at 1/4 of of rcv window size */ | ||
54 | 55 | ||
55 | enum { | 56 | enum { |
56 | TIPC_LISTEN = TCP_LISTEN, | 57 | TIPC_LISTEN = TCP_LISTEN, |
@@ -1290,7 +1291,7 @@ static int tipc_wait_for_rcvmsg(struct socket *sock, long *timeop) | |||
1290 | /** | 1291 | /** |
1291 | * tipc_recvmsg - receive packet-oriented message | 1292 | * tipc_recvmsg - receive packet-oriented message |
1292 | * @m: descriptor for message info | 1293 | * @m: descriptor for message info |
1293 | * @buf_len: total size of user buffer area | 1294 | * @buflen: length of user buffer area |
1294 | * @flags: receive flags | 1295 | * @flags: receive flags |
1295 | * | 1296 | * |
1296 | * Used for SOCK_DGRAM, SOCK_RDM, and SOCK_SEQPACKET messages. | 1297 | * Used for SOCK_DGRAM, SOCK_RDM, and SOCK_SEQPACKET messages. |
@@ -1298,89 +1299,79 @@ static int tipc_wait_for_rcvmsg(struct socket *sock, long *timeop) | |||
1298 | * | 1299 | * |
1299 | * Returns size of returned message data, errno otherwise | 1300 | * Returns size of returned message data, errno otherwise |
1300 | */ | 1301 | */ |
1301 | static int tipc_recvmsg(struct socket *sock, struct msghdr *m, size_t buf_len, | 1302 | static int tipc_recvmsg(struct socket *sock, struct msghdr *m, |
1302 | int flags) | 1303 | size_t buflen, int flags) |
1303 | { | 1304 | { |
1304 | struct sock *sk = sock->sk; | 1305 | struct sock *sk = sock->sk; |
1305 | struct tipc_sock *tsk = tipc_sk(sk); | 1306 | struct tipc_sock *tsk = tipc_sk(sk); |
1306 | struct sk_buff *buf; | 1307 | struct sk_buff *skb; |
1307 | struct tipc_msg *msg; | 1308 | struct tipc_msg *hdr; |
1308 | bool is_connectionless = tipc_sk_type_connectionless(sk); | 1309 | bool connected = !tipc_sk_type_connectionless(sk); |
1309 | long timeo; | 1310 | int rc, err, hlen, dlen, copy; |
1310 | unsigned int sz; | 1311 | long timeout; |
1311 | u32 err; | ||
1312 | int res, hlen; | ||
1313 | 1312 | ||
1314 | /* Catch invalid receive requests */ | 1313 | /* Catch invalid receive requests */ |
1315 | if (unlikely(!buf_len)) | 1314 | if (unlikely(!buflen)) |
1316 | return -EINVAL; | 1315 | return -EINVAL; |
1317 | 1316 | ||
1318 | lock_sock(sk); | 1317 | lock_sock(sk); |
1319 | 1318 | if (unlikely(connected && sk->sk_state == TIPC_OPEN)) { | |
1320 | if (!is_connectionless && unlikely(sk->sk_state == TIPC_OPEN)) { | 1319 | rc = -ENOTCONN; |
1321 | res = -ENOTCONN; | ||
1322 | goto exit; | 1320 | goto exit; |
1323 | } | 1321 | } |
1322 | timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); | ||
1324 | 1323 | ||
1325 | timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); | 1324 | do { |
1326 | restart: | 1325 | /* Look at first msg in receive queue; wait if necessary */ |
1327 | 1326 | rc = tipc_wait_for_rcvmsg(sock, &timeout); | |
1328 | /* Look for a message in receive queue; wait if necessary */ | 1327 | if (unlikely(rc)) |
1329 | res = tipc_wait_for_rcvmsg(sock, &timeo); | 1328 | goto exit; |
1330 | if (res) | 1329 | skb = skb_peek(&sk->sk_receive_queue); |
1331 | goto exit; | 1330 | hdr = buf_msg(skb); |
1332 | 1331 | dlen = msg_data_sz(hdr); | |
1333 | /* Look at first message in receive queue */ | 1332 | hlen = msg_hdr_sz(hdr); |
1334 | buf = skb_peek(&sk->sk_receive_queue); | 1333 | err = msg_errcode(hdr); |
1335 | msg = buf_msg(buf); | 1334 | if (likely(dlen || err)) |
1336 | sz = msg_data_sz(msg); | 1335 | break; |
1337 | hlen = msg_hdr_sz(msg); | ||
1338 | err = msg_errcode(msg); | ||
1339 | |||
1340 | /* Discard an empty non-errored message & try again */ | ||
1341 | if ((!sz) && (!err)) { | ||
1342 | tsk_advance_rx_queue(sk); | 1336 | tsk_advance_rx_queue(sk); |
1343 | goto restart; | 1337 | } while (1); |
1344 | } | ||
1345 | 1338 | ||
1346 | /* Capture sender's address (optional) */ | 1339 | /* Collect msg meta data, including error code and rejected data */ |
1347 | set_orig_addr(m, msg); | 1340 | set_orig_addr(m, hdr); |
1348 | 1341 | rc = tipc_sk_anc_data_recv(m, hdr, tsk); | |
1349 | /* Capture ancillary data (optional) */ | 1342 | if (unlikely(rc)) |
1350 | res = tipc_sk_anc_data_recv(m, msg, tsk); | ||
1351 | if (res) | ||
1352 | goto exit; | 1343 | goto exit; |
1353 | 1344 | ||
1354 | /* Capture message data (if valid) & compute return value (always) */ | 1345 | /* Capture data if non-error msg, otherwise just set return value */ |
1355 | if (!err) { | 1346 | if (likely(!err)) { |
1356 | if (unlikely(buf_len < sz)) { | 1347 | copy = min_t(int, dlen, buflen); |
1357 | sz = buf_len; | 1348 | if (unlikely(copy != dlen)) |
1358 | m->msg_flags |= MSG_TRUNC; | 1349 | m->msg_flags |= MSG_TRUNC; |
1359 | } | 1350 | rc = skb_copy_datagram_msg(skb, hlen, m, copy); |
1360 | res = skb_copy_datagram_msg(buf, hlen, m, sz); | ||
1361 | if (res) | ||
1362 | goto exit; | ||
1363 | res = sz; | ||
1364 | } else { | 1351 | } else { |
1365 | if (is_connectionless || err == TIPC_CONN_SHUTDOWN || | 1352 | copy = 0; |
1366 | m->msg_control) | 1353 | rc = 0; |
1367 | res = 0; | 1354 | if (err != TIPC_CONN_SHUTDOWN && connected && !m->msg_control) |
1368 | else | 1355 | rc = -ECONNRESET; |
1369 | res = -ECONNRESET; | ||
1370 | } | 1356 | } |
1357 | if (unlikely(rc)) | ||
1358 | goto exit; | ||
1371 | 1359 | ||
1360 | /* Caption of data or error code/rejected data was successful */ | ||
1372 | if (unlikely(flags & MSG_PEEK)) | 1361 | if (unlikely(flags & MSG_PEEK)) |
1373 | goto exit; | 1362 | goto exit; |
1374 | 1363 | ||
1375 | if (likely(!is_connectionless)) { | ||
1376 | tsk->rcv_unacked += tsk_inc(tsk, hlen + sz); | ||
1377 | if (unlikely(tsk->rcv_unacked >= (tsk->rcv_win / 4))) | ||
1378 | tipc_sk_send_ack(tsk); | ||
1379 | } | ||
1380 | tsk_advance_rx_queue(sk); | 1364 | tsk_advance_rx_queue(sk); |
1365 | if (likely(!connected)) | ||
1366 | goto exit; | ||
1367 | |||
1368 | /* Send connection flow control ack when applicable */ | ||
1369 | tsk->rcv_unacked += tsk_inc(tsk, hlen + dlen); | ||
1370 | if (tsk->rcv_unacked >= tsk->rcv_win / TIPC_ACK_RATE) | ||
1371 | tipc_sk_send_ack(tsk); | ||
1381 | exit: | 1372 | exit: |
1382 | release_sock(sk); | 1373 | release_sock(sk); |
1383 | return res; | 1374 | return rc ? rc : copy; |
1384 | } | 1375 | } |
1385 | 1376 | ||
1386 | /** | 1377 | /** |