aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/socket.c
diff options
context:
space:
mode:
authorJon Paul Maloy <jon.maloy@ericsson.com>2017-05-02 12:16:53 -0400
committerDavid S. Miller <davem@davemloft.net>2017-05-02 15:56:54 -0400
commite9f8b10101c6da3ab000a2fb17162374c9bd2c69 (patch)
treee03054477c5282ba28b62fc88702c0a57f957d1d /net/tipc/socket.c
parentb0e92279d3ec3656152c4dfa1c8b28fa40ca66d7 (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.c109
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
55enum { 56enum {
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 */
1301static int tipc_recvmsg(struct socket *sock, struct msghdr *m, size_t buf_len, 1302static 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 {
1326restart: 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);
1381exit: 1372exit:
1382 release_sock(sk); 1373 release_sock(sk);
1383 return res; 1374 return rc ? rc : copy;
1384} 1375}
1385 1376
1386/** 1377/**