diff options
Diffstat (limited to 'net/ax25/af_ax25.c')
-rw-r--r-- | net/ax25/af_ax25.c | 77 |
1 files changed, 37 insertions, 40 deletions
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c index 5f28887822e9..6ded95272a53 100644 --- a/net/ax25/af_ax25.c +++ b/net/ax25/af_ax25.c | |||
@@ -1127,22 +1127,22 @@ static int __must_check ax25_connect(struct socket *sock, | |||
1127 | switch (sk->sk_state) { | 1127 | switch (sk->sk_state) { |
1128 | case TCP_SYN_SENT: /* still trying */ | 1128 | case TCP_SYN_SENT: /* still trying */ |
1129 | err = -EINPROGRESS; | 1129 | err = -EINPROGRESS; |
1130 | goto out; | 1130 | goto out_release; |
1131 | 1131 | ||
1132 | case TCP_ESTABLISHED: /* connection established */ | 1132 | case TCP_ESTABLISHED: /* connection established */ |
1133 | sock->state = SS_CONNECTED; | 1133 | sock->state = SS_CONNECTED; |
1134 | goto out; | 1134 | goto out_release; |
1135 | 1135 | ||
1136 | case TCP_CLOSE: /* connection refused */ | 1136 | case TCP_CLOSE: /* connection refused */ |
1137 | sock->state = SS_UNCONNECTED; | 1137 | sock->state = SS_UNCONNECTED; |
1138 | err = -ECONNREFUSED; | 1138 | err = -ECONNREFUSED; |
1139 | goto out; | 1139 | goto out_release; |
1140 | } | 1140 | } |
1141 | } | 1141 | } |
1142 | 1142 | ||
1143 | if (sk->sk_state == TCP_ESTABLISHED && sk->sk_type == SOCK_SEQPACKET) { | 1143 | if (sk->sk_state == TCP_ESTABLISHED && sk->sk_type == SOCK_SEQPACKET) { |
1144 | err = -EISCONN; /* No reconnect on a seqpacket socket */ | 1144 | err = -EISCONN; /* No reconnect on a seqpacket socket */ |
1145 | goto out; | 1145 | goto out_release; |
1146 | } | 1146 | } |
1147 | 1147 | ||
1148 | sk->sk_state = TCP_CLOSE; | 1148 | sk->sk_state = TCP_CLOSE; |
@@ -1159,12 +1159,12 @@ static int __must_check ax25_connect(struct socket *sock, | |||
1159 | /* Valid number of digipeaters ? */ | 1159 | /* Valid number of digipeaters ? */ |
1160 | if (fsa->fsa_ax25.sax25_ndigis < 1 || fsa->fsa_ax25.sax25_ndigis > AX25_MAX_DIGIS) { | 1160 | if (fsa->fsa_ax25.sax25_ndigis < 1 || fsa->fsa_ax25.sax25_ndigis > AX25_MAX_DIGIS) { |
1161 | err = -EINVAL; | 1161 | err = -EINVAL; |
1162 | goto out; | 1162 | goto out_release; |
1163 | } | 1163 | } |
1164 | 1164 | ||
1165 | if ((digi = kmalloc(sizeof(ax25_digi), GFP_KERNEL)) == NULL) { | 1165 | if ((digi = kmalloc(sizeof(ax25_digi), GFP_KERNEL)) == NULL) { |
1166 | err = -ENOBUFS; | 1166 | err = -ENOBUFS; |
1167 | goto out; | 1167 | goto out_release; |
1168 | } | 1168 | } |
1169 | 1169 | ||
1170 | digi->ndigi = fsa->fsa_ax25.sax25_ndigis; | 1170 | digi->ndigi = fsa->fsa_ax25.sax25_ndigis; |
@@ -1194,7 +1194,7 @@ static int __must_check ax25_connect(struct socket *sock, | |||
1194 | current->comm); | 1194 | current->comm); |
1195 | if ((err = ax25_rt_autobind(ax25, &fsa->fsa_ax25.sax25_call)) < 0) { | 1195 | if ((err = ax25_rt_autobind(ax25, &fsa->fsa_ax25.sax25_call)) < 0) { |
1196 | kfree(digi); | 1196 | kfree(digi); |
1197 | goto out; | 1197 | goto out_release; |
1198 | } | 1198 | } |
1199 | 1199 | ||
1200 | ax25_fillin_cb(ax25, ax25->ax25_dev); | 1200 | ax25_fillin_cb(ax25, ax25->ax25_dev); |
@@ -1203,7 +1203,7 @@ static int __must_check ax25_connect(struct socket *sock, | |||
1203 | if (ax25->ax25_dev == NULL) { | 1203 | if (ax25->ax25_dev == NULL) { |
1204 | kfree(digi); | 1204 | kfree(digi); |
1205 | err = -EHOSTUNREACH; | 1205 | err = -EHOSTUNREACH; |
1206 | goto out; | 1206 | goto out_release; |
1207 | } | 1207 | } |
1208 | } | 1208 | } |
1209 | 1209 | ||
@@ -1213,7 +1213,7 @@ static int __must_check ax25_connect(struct socket *sock, | |||
1213 | kfree(digi); | 1213 | kfree(digi); |
1214 | err = -EADDRINUSE; /* Already such a connection */ | 1214 | err = -EADDRINUSE; /* Already such a connection */ |
1215 | ax25_cb_put(ax25t); | 1215 | ax25_cb_put(ax25t); |
1216 | goto out; | 1216 | goto out_release; |
1217 | } | 1217 | } |
1218 | 1218 | ||
1219 | ax25->dest_addr = fsa->fsa_ax25.sax25_call; | 1219 | ax25->dest_addr = fsa->fsa_ax25.sax25_call; |
@@ -1223,7 +1223,7 @@ static int __must_check ax25_connect(struct socket *sock, | |||
1223 | if (sk->sk_type != SOCK_SEQPACKET) { | 1223 | if (sk->sk_type != SOCK_SEQPACKET) { |
1224 | sock->state = SS_CONNECTED; | 1224 | sock->state = SS_CONNECTED; |
1225 | sk->sk_state = TCP_ESTABLISHED; | 1225 | sk->sk_state = TCP_ESTABLISHED; |
1226 | goto out; | 1226 | goto out_release; |
1227 | } | 1227 | } |
1228 | 1228 | ||
1229 | /* Move to connecting socket, ax.25 lapb WAIT_UA.. */ | 1229 | /* Move to connecting socket, ax.25 lapb WAIT_UA.. */ |
@@ -1255,55 +1255,53 @@ static int __must_check ax25_connect(struct socket *sock, | |||
1255 | /* Now the loop */ | 1255 | /* Now the loop */ |
1256 | if (sk->sk_state != TCP_ESTABLISHED && (flags & O_NONBLOCK)) { | 1256 | if (sk->sk_state != TCP_ESTABLISHED && (flags & O_NONBLOCK)) { |
1257 | err = -EINPROGRESS; | 1257 | err = -EINPROGRESS; |
1258 | goto out; | 1258 | goto out_release; |
1259 | } | 1259 | } |
1260 | 1260 | ||
1261 | if (sk->sk_state == TCP_SYN_SENT) { | 1261 | if (sk->sk_state == TCP_SYN_SENT) { |
1262 | struct task_struct *tsk = current; | 1262 | DEFINE_WAIT(wait); |
1263 | DECLARE_WAITQUEUE(wait, tsk); | ||
1264 | 1263 | ||
1265 | add_wait_queue(sk->sk_sleep, &wait); | ||
1266 | for (;;) { | 1264 | for (;;) { |
1265 | prepare_to_wait(sk->sk_sleep, &wait, | ||
1266 | TASK_INTERRUPTIBLE); | ||
1267 | if (sk->sk_state != TCP_SYN_SENT) | 1267 | if (sk->sk_state != TCP_SYN_SENT) |
1268 | break; | 1268 | break; |
1269 | set_current_state(TASK_INTERRUPTIBLE); | 1269 | if (!signal_pending(current)) { |
1270 | release_sock(sk); | 1270 | release_sock(sk); |
1271 | if (!signal_pending(tsk)) { | ||
1272 | schedule(); | 1271 | schedule(); |
1273 | lock_sock(sk); | 1272 | lock_sock(sk); |
1274 | continue; | 1273 | continue; |
1275 | } | 1274 | } |
1276 | current->state = TASK_RUNNING; | 1275 | err = -ERESTARTSYS; |
1277 | remove_wait_queue(sk->sk_sleep, &wait); | 1276 | break; |
1278 | return -ERESTARTSYS; | ||
1279 | } | 1277 | } |
1280 | current->state = TASK_RUNNING; | 1278 | finish_wait(sk->sk_sleep, &wait); |
1281 | remove_wait_queue(sk->sk_sleep, &wait); | 1279 | |
1280 | if (err) | ||
1281 | goto out_release; | ||
1282 | } | 1282 | } |
1283 | 1283 | ||
1284 | if (sk->sk_state != TCP_ESTABLISHED) { | 1284 | if (sk->sk_state != TCP_ESTABLISHED) { |
1285 | /* Not in ABM, not in WAIT_UA -> failed */ | 1285 | /* Not in ABM, not in WAIT_UA -> failed */ |
1286 | sock->state = SS_UNCONNECTED; | 1286 | sock->state = SS_UNCONNECTED; |
1287 | err = sock_error(sk); /* Always set at this point */ | 1287 | err = sock_error(sk); /* Always set at this point */ |
1288 | goto out; | 1288 | goto out_release; |
1289 | } | 1289 | } |
1290 | 1290 | ||
1291 | sock->state = SS_CONNECTED; | 1291 | sock->state = SS_CONNECTED; |
1292 | 1292 | ||
1293 | err=0; | 1293 | err = 0; |
1294 | out: | 1294 | out_release: |
1295 | release_sock(sk); | 1295 | release_sock(sk); |
1296 | 1296 | ||
1297 | return err; | 1297 | return err; |
1298 | } | 1298 | } |
1299 | 1299 | ||
1300 | |||
1301 | static int ax25_accept(struct socket *sock, struct socket *newsock, int flags) | 1300 | static int ax25_accept(struct socket *sock, struct socket *newsock, int flags) |
1302 | { | 1301 | { |
1303 | struct task_struct *tsk = current; | ||
1304 | DECLARE_WAITQUEUE(wait, tsk); | ||
1305 | struct sk_buff *skb; | 1302 | struct sk_buff *skb; |
1306 | struct sock *newsk; | 1303 | struct sock *newsk; |
1304 | DEFINE_WAIT(wait); | ||
1307 | struct sock *sk; | 1305 | struct sock *sk; |
1308 | int err = 0; | 1306 | int err = 0; |
1309 | 1307 | ||
@@ -1328,30 +1326,29 @@ static int ax25_accept(struct socket *sock, struct socket *newsock, int flags) | |||
1328 | * The read queue this time is holding sockets ready to use | 1326 | * The read queue this time is holding sockets ready to use |
1329 | * hooked into the SABM we saved | 1327 | * hooked into the SABM we saved |
1330 | */ | 1328 | */ |
1331 | add_wait_queue(sk->sk_sleep, &wait); | ||
1332 | for (;;) { | 1329 | for (;;) { |
1330 | prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); | ||
1333 | skb = skb_dequeue(&sk->sk_receive_queue); | 1331 | skb = skb_dequeue(&sk->sk_receive_queue); |
1334 | if (skb) | 1332 | if (skb) |
1335 | break; | 1333 | break; |
1336 | 1334 | ||
1337 | release_sock(sk); | ||
1338 | current->state = TASK_INTERRUPTIBLE; | ||
1339 | if (flags & O_NONBLOCK) { | 1335 | if (flags & O_NONBLOCK) { |
1340 | current->state = TASK_RUNNING; | 1336 | err = -EWOULDBLOCK; |
1341 | remove_wait_queue(sk->sk_sleep, &wait); | 1337 | break; |
1342 | return -EWOULDBLOCK; | ||
1343 | } | 1338 | } |
1344 | if (!signal_pending(tsk)) { | 1339 | if (!signal_pending(current)) { |
1340 | release_sock(sk); | ||
1345 | schedule(); | 1341 | schedule(); |
1346 | lock_sock(sk); | 1342 | lock_sock(sk); |
1347 | continue; | 1343 | continue; |
1348 | } | 1344 | } |
1349 | current->state = TASK_RUNNING; | 1345 | err = -ERESTARTSYS; |
1350 | remove_wait_queue(sk->sk_sleep, &wait); | 1346 | break; |
1351 | return -ERESTARTSYS; | ||
1352 | } | 1347 | } |
1353 | current->state = TASK_RUNNING; | 1348 | finish_wait(sk->sk_sleep, &wait); |
1354 | remove_wait_queue(sk->sk_sleep, &wait); | 1349 | |
1350 | if (err) | ||
1351 | goto out; | ||
1355 | 1352 | ||
1356 | newsk = skb->sk; | 1353 | newsk = skb->sk; |
1357 | newsk->sk_socket = newsock; | 1354 | newsk->sk_socket = newsock; |