aboutsummaryrefslogtreecommitdiffstats
path: root/net/iucv/af_iucv.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/iucv/af_iucv.c')
-rw-r--r--net/iucv/af_iucv.c26
1 files changed, 19 insertions, 7 deletions
diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
index 264c6b36931c..0fc00087ea8b 100644
--- a/net/iucv/af_iucv.c
+++ b/net/iucv/af_iucv.c
@@ -215,6 +215,7 @@ static void iucv_sock_close(struct sock *sk)
215 err = iucv_sock_wait_state(sk, IUCV_CLOSED, 0, timeo); 215 err = iucv_sock_wait_state(sk, IUCV_CLOSED, 0, timeo);
216 } 216 }
217 217
218 case IUCV_CLOSING: /* fall through */
218 sk->sk_state = IUCV_CLOSED; 219 sk->sk_state = IUCV_CLOSED;
219 sk->sk_state_change(sk); 220 sk->sk_state_change(sk);
220 221
@@ -269,6 +270,8 @@ static struct sock *iucv_sock_alloc(struct socket *sock, int proto, gfp_t prio)
269 iucv_sk(sk)->send_tag = 0; 270 iucv_sk(sk)->send_tag = 0;
270 iucv_sk(sk)->flags = 0; 271 iucv_sk(sk)->flags = 0;
271 iucv_sk(sk)->msglimit = IUCV_QUEUELEN_DEFAULT; 272 iucv_sk(sk)->msglimit = IUCV_QUEUELEN_DEFAULT;
273 iucv_sk(sk)->path = NULL;
274 memset(&iucv_sk(sk)->src_user_id , 0, 32);
272 275
273 sk->sk_destruct = iucv_sock_destruct; 276 sk->sk_destruct = iucv_sock_destruct;
274 sk->sk_sndtimeo = IUCV_CONN_TIMEOUT; 277 sk->sk_sndtimeo = IUCV_CONN_TIMEOUT;
@@ -979,6 +982,10 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
979 if (flags & (MSG_OOB)) 982 if (flags & (MSG_OOB))
980 return -EOPNOTSUPP; 983 return -EOPNOTSUPP;
981 984
985 target = sock_rcvlowat(sk, flags & MSG_WAITALL, len);
986
987 /* receive/dequeue next skb:
988 * the function understands MSG_PEEK and, thus, does not dequeue skb */
982 skb = skb_recv_datagram(sk, flags, noblock, &err); 989 skb = skb_recv_datagram(sk, flags, noblock, &err);
983 if (!skb) { 990 if (!skb) {
984 if (sk->sk_shutdown & RCV_SHUTDOWN) 991 if (sk->sk_shutdown & RCV_SHUTDOWN)
@@ -1046,9 +1053,7 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
1046 iucv_process_message_q(sk); 1053 iucv_process_message_q(sk);
1047 spin_unlock_bh(&iucv->message_q.lock); 1054 spin_unlock_bh(&iucv->message_q.lock);
1048 } 1055 }
1049 1056 }
1050 } else
1051 skb_queue_head(&sk->sk_receive_queue, skb);
1052 1057
1053done: 1058done:
1054 /* SOCK_SEQPACKET: return real length if MSG_TRUNC is set */ 1059 /* SOCK_SEQPACKET: return real length if MSG_TRUNC is set */
@@ -1125,6 +1130,9 @@ static int iucv_sock_shutdown(struct socket *sock, int how)
1125 1130
1126 lock_sock(sk); 1131 lock_sock(sk);
1127 switch (sk->sk_state) { 1132 switch (sk->sk_state) {
1133 case IUCV_DISCONN:
1134 case IUCV_CLOSING:
1135 case IUCV_SEVERED:
1128 case IUCV_CLOSED: 1136 case IUCV_CLOSED:
1129 err = -ENOTCONN; 1137 err = -ENOTCONN;
1130 goto fail; 1138 goto fail;
@@ -1398,8 +1406,12 @@ static void iucv_callback_rx(struct iucv_path *path, struct iucv_message *msg)
1398 struct sock_msg_q *save_msg; 1406 struct sock_msg_q *save_msg;
1399 int len; 1407 int len;
1400 1408
1401 if (sk->sk_shutdown & RCV_SHUTDOWN) 1409 if (sk->sk_shutdown & RCV_SHUTDOWN) {
1410 iucv_message_reject(path, msg);
1402 return; 1411 return;
1412 }
1413
1414 spin_lock(&iucv->message_q.lock);
1403 1415
1404 if (!list_empty(&iucv->message_q.list) || 1416 if (!list_empty(&iucv->message_q.list) ||
1405 !skb_queue_empty(&iucv->backlog_skb_q)) 1417 !skb_queue_empty(&iucv->backlog_skb_q))
@@ -1414,9 +1426,8 @@ static void iucv_callback_rx(struct iucv_path *path, struct iucv_message *msg)
1414 if (!skb) 1426 if (!skb)
1415 goto save_message; 1427 goto save_message;
1416 1428
1417 spin_lock(&iucv->message_q.lock);
1418 iucv_process_message(sk, skb, path, msg); 1429 iucv_process_message(sk, skb, path, msg);
1419 spin_unlock(&iucv->message_q.lock); 1430 goto out_unlock;
1420 1431
1421 return; 1432 return;
1422 1433
@@ -1427,8 +1438,9 @@ save_message:
1427 save_msg->path = path; 1438 save_msg->path = path;
1428 save_msg->msg = *msg; 1439 save_msg->msg = *msg;
1429 1440
1430 spin_lock(&iucv->message_q.lock);
1431 list_add_tail(&save_msg->list, &iucv->message_q.list); 1441 list_add_tail(&save_msg->list, &iucv->message_q.list);
1442
1443out_unlock:
1432 spin_unlock(&iucv->message_q.lock); 1444 spin_unlock(&iucv->message_q.lock);
1433} 1445}
1434 1446