diff options
Diffstat (limited to 'net/iucv')
-rw-r--r-- | net/iucv/af_iucv.c | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c index c23ed4ff04c6..d985d163dcfc 100644 --- a/net/iucv/af_iucv.c +++ b/net/iucv/af_iucv.c | |||
@@ -1036,6 +1036,10 @@ out: | |||
1036 | return err; | 1036 | return err; |
1037 | } | 1037 | } |
1038 | 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 | */ | ||
1039 | 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) |
1040 | { | 1044 | { |
1041 | int dataleft, size, copied = 0; | 1045 | int dataleft, size, copied = 0; |
@@ -1070,6 +1074,10 @@ static int iucv_fragment_skb(struct sock *sk, struct sk_buff *skb, int len) | |||
1070 | return 0; | 1074 | return 0; |
1071 | } | 1075 | } |
1072 | 1076 | ||
1077 | /* iucv_process_message() - Receive a single outstanding IUCV message | ||
1078 | * | ||
1079 | * Locking: must be called with message_q.lock held | ||
1080 | */ | ||
1073 | 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, |
1074 | struct iucv_path *path, | 1082 | struct iucv_path *path, |
1075 | struct iucv_message *msg) | 1083 | struct iucv_message *msg) |
@@ -1120,6 +1128,10 @@ static void iucv_process_message(struct sock *sk, struct sk_buff *skb, | |||
1120 | skb_queue_head(&iucv_sk(sk)->backlog_skb_q, skb); | 1128 | skb_queue_head(&iucv_sk(sk)->backlog_skb_q, skb); |
1121 | } | 1129 | } |
1122 | 1130 | ||
1131 | /* iucv_process_message_q() - Process outstanding IUCV messages | ||
1132 | * | ||
1133 | * Locking: must be called with message_q.lock held | ||
1134 | */ | ||
1123 | static void iucv_process_message_q(struct sock *sk) | 1135 | static void iucv_process_message_q(struct sock *sk) |
1124 | { | 1136 | { |
1125 | struct iucv_sock *iucv = iucv_sk(sk); | 1137 | struct iucv_sock *iucv = iucv_sk(sk); |
@@ -1210,6 +1222,7 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1210 | kfree_skb(skb); | 1222 | kfree_skb(skb); |
1211 | 1223 | ||
1212 | /* Queue backlog skbs */ | 1224 | /* Queue backlog skbs */ |
1225 | spin_lock_bh(&iucv->message_q.lock); | ||
1213 | rskb = skb_dequeue(&iucv->backlog_skb_q); | 1226 | rskb = skb_dequeue(&iucv->backlog_skb_q); |
1214 | while (rskb) { | 1227 | while (rskb) { |
1215 | if (sock_queue_rcv_skb(sk, rskb)) { | 1228 | if (sock_queue_rcv_skb(sk, rskb)) { |
@@ -1221,11 +1234,10 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1221 | } | 1234 | } |
1222 | } | 1235 | } |
1223 | if (skb_queue_empty(&iucv->backlog_skb_q)) { | 1236 | if (skb_queue_empty(&iucv->backlog_skb_q)) { |
1224 | spin_lock_bh(&iucv->message_q.lock); | ||
1225 | if (!list_empty(&iucv->message_q.list)) | 1237 | if (!list_empty(&iucv->message_q.list)) |
1226 | iucv_process_message_q(sk); | 1238 | iucv_process_message_q(sk); |
1227 | spin_unlock_bh(&iucv->message_q.lock); | ||
1228 | } | 1239 | } |
1240 | spin_unlock_bh(&iucv->message_q.lock); | ||
1229 | } | 1241 | } |
1230 | 1242 | ||
1231 | done: | 1243 | done: |