diff options
Diffstat (limited to 'net/iucv/af_iucv.c')
-rw-r--r-- | net/iucv/af_iucv.c | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c index 49e786535dc8..b51c9187c347 100644 --- a/net/iucv/af_iucv.c +++ b/net/iucv/af_iucv.c | |||
@@ -172,6 +172,7 @@ static void iucv_sock_close(struct sock *sk) | |||
172 | err = iucv_sock_wait_state(sk, IUCV_CLOSED, 0, timeo); | 172 | err = iucv_sock_wait_state(sk, IUCV_CLOSED, 0, timeo); |
173 | } | 173 | } |
174 | 174 | ||
175 | case IUCV_CLOSING: /* fall through */ | ||
175 | sk->sk_state = IUCV_CLOSED; | 176 | sk->sk_state = IUCV_CLOSED; |
176 | sk->sk_state_change(sk); | 177 | sk->sk_state_change(sk); |
177 | 178 | ||
@@ -224,6 +225,8 @@ static struct sock *iucv_sock_alloc(struct socket *sock, int proto, gfp_t prio) | |||
224 | spin_lock_init(&iucv_sk(sk)->message_q.lock); | 225 | spin_lock_init(&iucv_sk(sk)->message_q.lock); |
225 | skb_queue_head_init(&iucv_sk(sk)->backlog_skb_q); | 226 | skb_queue_head_init(&iucv_sk(sk)->backlog_skb_q); |
226 | iucv_sk(sk)->send_tag = 0; | 227 | iucv_sk(sk)->send_tag = 0; |
228 | iucv_sk(sk)->path = NULL; | ||
229 | memset(&iucv_sk(sk)->src_user_id , 0, 32); | ||
227 | 230 | ||
228 | sk->sk_destruct = iucv_sock_destruct; | 231 | sk->sk_destruct = iucv_sock_destruct; |
229 | sk->sk_sndtimeo = IUCV_CONN_TIMEOUT; | 232 | sk->sk_sndtimeo = IUCV_CONN_TIMEOUT; |
@@ -811,6 +814,8 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
811 | 814 | ||
812 | target = sock_rcvlowat(sk, flags & MSG_WAITALL, len); | 815 | target = sock_rcvlowat(sk, flags & MSG_WAITALL, len); |
813 | 816 | ||
817 | /* receive/dequeue next skb: | ||
818 | * the function understands MSG_PEEK and, thus, does not dequeue skb */ | ||
814 | skb = skb_recv_datagram(sk, flags, noblock, &err); | 819 | skb = skb_recv_datagram(sk, flags, noblock, &err); |
815 | if (!skb) { | 820 | if (!skb) { |
816 | if (sk->sk_shutdown & RCV_SHUTDOWN) | 821 | if (sk->sk_shutdown & RCV_SHUTDOWN) |
@@ -858,9 +863,7 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
858 | iucv_process_message_q(sk); | 863 | iucv_process_message_q(sk); |
859 | spin_unlock_bh(&iucv->message_q.lock); | 864 | spin_unlock_bh(&iucv->message_q.lock); |
860 | } | 865 | } |
861 | 866 | } | |
862 | } else | ||
863 | skb_queue_head(&sk->sk_receive_queue, skb); | ||
864 | 867 | ||
865 | done: | 868 | done: |
866 | return err ? : copied; | 869 | return err ? : copied; |
@@ -934,6 +937,9 @@ static int iucv_sock_shutdown(struct socket *sock, int how) | |||
934 | 937 | ||
935 | lock_sock(sk); | 938 | lock_sock(sk); |
936 | switch (sk->sk_state) { | 939 | switch (sk->sk_state) { |
940 | case IUCV_DISCONN: | ||
941 | case IUCV_CLOSING: | ||
942 | case IUCV_SEVERED: | ||
937 | case IUCV_CLOSED: | 943 | case IUCV_CLOSED: |
938 | err = -ENOTCONN; | 944 | err = -ENOTCONN; |
939 | goto fail; | 945 | goto fail; |
@@ -1113,8 +1119,12 @@ static void iucv_callback_rx(struct iucv_path *path, struct iucv_message *msg) | |||
1113 | struct sock_msg_q *save_msg; | 1119 | struct sock_msg_q *save_msg; |
1114 | int len; | 1120 | int len; |
1115 | 1121 | ||
1116 | if (sk->sk_shutdown & RCV_SHUTDOWN) | 1122 | if (sk->sk_shutdown & RCV_SHUTDOWN) { |
1123 | iucv_message_reject(path, msg); | ||
1117 | return; | 1124 | return; |
1125 | } | ||
1126 | |||
1127 | spin_lock(&iucv->message_q.lock); | ||
1118 | 1128 | ||
1119 | if (!list_empty(&iucv->message_q.list) || | 1129 | if (!list_empty(&iucv->message_q.list) || |
1120 | !skb_queue_empty(&iucv->backlog_skb_q)) | 1130 | !skb_queue_empty(&iucv->backlog_skb_q)) |
@@ -1129,9 +1139,8 @@ static void iucv_callback_rx(struct iucv_path *path, struct iucv_message *msg) | |||
1129 | if (!skb) | 1139 | if (!skb) |
1130 | goto save_message; | 1140 | goto save_message; |
1131 | 1141 | ||
1132 | spin_lock(&iucv->message_q.lock); | ||
1133 | iucv_process_message(sk, skb, path, msg); | 1142 | iucv_process_message(sk, skb, path, msg); |
1134 | spin_unlock(&iucv->message_q.lock); | 1143 | goto out_unlock; |
1135 | 1144 | ||
1136 | return; | 1145 | return; |
1137 | 1146 | ||
@@ -1142,8 +1151,9 @@ save_message: | |||
1142 | save_msg->path = path; | 1151 | save_msg->path = path; |
1143 | save_msg->msg = *msg; | 1152 | save_msg->msg = *msg; |
1144 | 1153 | ||
1145 | spin_lock(&iucv->message_q.lock); | ||
1146 | list_add_tail(&save_msg->list, &iucv->message_q.list); | 1154 | list_add_tail(&save_msg->list, &iucv->message_q.list); |
1155 | |||
1156 | out_unlock: | ||
1147 | spin_unlock(&iucv->message_q.lock); | 1157 | spin_unlock(&iucv->message_q.lock); |
1148 | } | 1158 | } |
1149 | 1159 | ||