diff options
Diffstat (limited to 'net/iucv/af_iucv.c')
-rw-r--r-- | net/iucv/af_iucv.c | 33 |
1 files changed, 23 insertions, 10 deletions
diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c index 49c15b48408e..d985d163dcfc 100644 --- a/net/iucv/af_iucv.c +++ b/net/iucv/af_iucv.c | |||
@@ -34,7 +34,7 @@ | |||
34 | 34 | ||
35 | static char iucv_userid[80]; | 35 | static char iucv_userid[80]; |
36 | 36 | ||
37 | static struct proto_ops iucv_sock_ops; | 37 | static const struct proto_ops iucv_sock_ops; |
38 | 38 | ||
39 | static struct proto iucv_proto = { | 39 | static struct proto iucv_proto = { |
40 | .name = "AF_IUCV", | 40 | .name = "AF_IUCV", |
@@ -59,8 +59,8 @@ do { \ | |||
59 | DEFINE_WAIT(__wait); \ | 59 | DEFINE_WAIT(__wait); \ |
60 | long __timeo = timeo; \ | 60 | long __timeo = timeo; \ |
61 | ret = 0; \ | 61 | ret = 0; \ |
62 | prepare_to_wait(sk->sk_sleep, &__wait, TASK_INTERRUPTIBLE); \ | ||
62 | while (!(condition)) { \ | 63 | while (!(condition)) { \ |
63 | prepare_to_wait(sk->sk_sleep, &__wait, TASK_INTERRUPTIBLE); \ | ||
64 | if (!__timeo) { \ | 64 | if (!__timeo) { \ |
65 | ret = -EAGAIN; \ | 65 | ret = -EAGAIN; \ |
66 | break; \ | 66 | break; \ |
@@ -361,10 +361,9 @@ static void iucv_sock_cleanup_listen(struct sock *parent) | |||
361 | } | 361 | } |
362 | 362 | ||
363 | parent->sk_state = IUCV_CLOSED; | 363 | parent->sk_state = IUCV_CLOSED; |
364 | sock_set_flag(parent, SOCK_ZAPPED); | ||
365 | } | 364 | } |
366 | 365 | ||
367 | /* Kill socket */ | 366 | /* Kill socket (only if zapped and orphaned) */ |
368 | static void iucv_sock_kill(struct sock *sk) | 367 | static void iucv_sock_kill(struct sock *sk) |
369 | { | 368 | { |
370 | if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket) | 369 | if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket) |
@@ -426,17 +425,18 @@ static void iucv_sock_close(struct sock *sk) | |||
426 | 425 | ||
427 | skb_queue_purge(&iucv->send_skb_q); | 426 | skb_queue_purge(&iucv->send_skb_q); |
428 | skb_queue_purge(&iucv->backlog_skb_q); | 427 | skb_queue_purge(&iucv->backlog_skb_q); |
429 | |||
430 | sock_set_flag(sk, SOCK_ZAPPED); | ||
431 | break; | 428 | break; |
432 | 429 | ||
433 | default: | 430 | default: |
434 | sock_set_flag(sk, SOCK_ZAPPED); | 431 | sock_set_flag(sk, SOCK_ZAPPED); |
432 | /* nothing to do here */ | ||
435 | break; | 433 | break; |
436 | } | 434 | } |
437 | 435 | ||
436 | /* mark socket for deletion by iucv_sock_kill() */ | ||
437 | sock_set_flag(sk, SOCK_ZAPPED); | ||
438 | |||
438 | release_sock(sk); | 439 | release_sock(sk); |
439 | iucv_sock_kill(sk); | ||
440 | } | 440 | } |
441 | 441 | ||
442 | static void iucv_sock_init(struct sock *sk, struct sock *parent) | 442 | static void iucv_sock_init(struct sock *sk, struct sock *parent) |
@@ -569,6 +569,7 @@ struct sock *iucv_accept_dequeue(struct sock *parent, struct socket *newsock) | |||
569 | 569 | ||
570 | if (sk->sk_state == IUCV_CONNECTED || | 570 | if (sk->sk_state == IUCV_CONNECTED || |
571 | sk->sk_state == IUCV_SEVERED || | 571 | sk->sk_state == IUCV_SEVERED || |
572 | sk->sk_state == IUCV_DISCONN || /* due to PM restore */ | ||
572 | !newsock) { | 573 | !newsock) { |
573 | iucv_accept_unlink(sk); | 574 | iucv_accept_unlink(sk); |
574 | if (newsock) | 575 | if (newsock) |
@@ -1035,6 +1036,10 @@ out: | |||
1035 | return err; | 1036 | return err; |
1036 | } | 1037 | } |
1037 | 1038 | ||
1039 | /* iucv_fragment_skb() - Fragment a single IUCV message into multiple skb's | ||
1040 | * | ||
1041 | * Locking: must be called with message_q.lock held | ||
1042 | */ | ||
1038 | static int iucv_fragment_skb(struct sock *sk, struct sk_buff *skb, int len) | 1043 | static int iucv_fragment_skb(struct sock *sk, struct sk_buff *skb, int len) |
1039 | { | 1044 | { |
1040 | int dataleft, size, copied = 0; | 1045 | int dataleft, size, copied = 0; |
@@ -1069,6 +1074,10 @@ static int iucv_fragment_skb(struct sock *sk, struct sk_buff *skb, int len) | |||
1069 | return 0; | 1074 | return 0; |
1070 | } | 1075 | } |
1071 | 1076 | ||
1077 | /* iucv_process_message() - Receive a single outstanding IUCV message | ||
1078 | * | ||
1079 | * Locking: must be called with message_q.lock held | ||
1080 | */ | ||
1072 | static void iucv_process_message(struct sock *sk, struct sk_buff *skb, | 1081 | static void iucv_process_message(struct sock *sk, struct sk_buff *skb, |
1073 | struct iucv_path *path, | 1082 | struct iucv_path *path, |
1074 | struct iucv_message *msg) | 1083 | struct iucv_message *msg) |
@@ -1119,6 +1128,10 @@ static void iucv_process_message(struct sock *sk, struct sk_buff *skb, | |||
1119 | skb_queue_head(&iucv_sk(sk)->backlog_skb_q, skb); | 1128 | skb_queue_head(&iucv_sk(sk)->backlog_skb_q, skb); |
1120 | } | 1129 | } |
1121 | 1130 | ||
1131 | /* iucv_process_message_q() - Process outstanding IUCV messages | ||
1132 | * | ||
1133 | * Locking: must be called with message_q.lock held | ||
1134 | */ | ||
1122 | static void iucv_process_message_q(struct sock *sk) | 1135 | static void iucv_process_message_q(struct sock *sk) |
1123 | { | 1136 | { |
1124 | struct iucv_sock *iucv = iucv_sk(sk); | 1137 | struct iucv_sock *iucv = iucv_sk(sk); |
@@ -1209,6 +1222,7 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1209 | kfree_skb(skb); | 1222 | kfree_skb(skb); |
1210 | 1223 | ||
1211 | /* Queue backlog skbs */ | 1224 | /* Queue backlog skbs */ |
1225 | spin_lock_bh(&iucv->message_q.lock); | ||
1212 | rskb = skb_dequeue(&iucv->backlog_skb_q); | 1226 | rskb = skb_dequeue(&iucv->backlog_skb_q); |
1213 | while (rskb) { | 1227 | while (rskb) { |
1214 | if (sock_queue_rcv_skb(sk, rskb)) { | 1228 | if (sock_queue_rcv_skb(sk, rskb)) { |
@@ -1220,11 +1234,10 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1220 | } | 1234 | } |
1221 | } | 1235 | } |
1222 | if (skb_queue_empty(&iucv->backlog_skb_q)) { | 1236 | if (skb_queue_empty(&iucv->backlog_skb_q)) { |
1223 | spin_lock_bh(&iucv->message_q.lock); | ||
1224 | if (!list_empty(&iucv->message_q.list)) | 1237 | if (!list_empty(&iucv->message_q.list)) |
1225 | iucv_process_message_q(sk); | 1238 | iucv_process_message_q(sk); |
1226 | spin_unlock_bh(&iucv->message_q.lock); | ||
1227 | } | 1239 | } |
1240 | spin_unlock_bh(&iucv->message_q.lock); | ||
1228 | } | 1241 | } |
1229 | 1242 | ||
1230 | done: | 1243 | done: |
@@ -1682,7 +1695,7 @@ static void iucv_callback_shutdown(struct iucv_path *path, u8 ipuser[16]) | |||
1682 | bh_unlock_sock(sk); | 1695 | bh_unlock_sock(sk); |
1683 | } | 1696 | } |
1684 | 1697 | ||
1685 | static struct proto_ops iucv_sock_ops = { | 1698 | static const struct proto_ops iucv_sock_ops = { |
1686 | .family = PF_IUCV, | 1699 | .family = PF_IUCV, |
1687 | .owner = THIS_MODULE, | 1700 | .owner = THIS_MODULE, |
1688 | .release = iucv_sock_release, | 1701 | .release = iucv_sock_release, |