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.c28
1 files changed, 27 insertions, 1 deletions
diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
index af3192d2a5a3..eb8a2a0b6eb7 100644
--- a/net/iucv/af_iucv.c
+++ b/net/iucv/af_iucv.c
@@ -494,7 +494,21 @@ static int iucv_sock_connect(struct socket *sock, struct sockaddr *addr,
494 if (err) { 494 if (err) {
495 iucv_path_free(iucv->path); 495 iucv_path_free(iucv->path);
496 iucv->path = NULL; 496 iucv->path = NULL;
497 err = -ECONNREFUSED; 497 switch (err) {
498 case 0x0b: /* Target communicator is not logged on */
499 err = -ENETUNREACH;
500 break;
501 case 0x0d: /* Max connections for this guest exceeded */
502 case 0x0e: /* Max connections for target guest exceeded */
503 err = -EAGAIN;
504 break;
505 case 0x0f: /* Missing IUCV authorization */
506 err = -EACCES;
507 break;
508 default:
509 err = -ECONNREFUSED;
510 break;
511 }
498 goto done; 512 goto done;
499 } 513 }
500 514
@@ -507,6 +521,13 @@ static int iucv_sock_connect(struct socket *sock, struct sockaddr *addr,
507 release_sock(sk); 521 release_sock(sk);
508 return -ECONNREFUSED; 522 return -ECONNREFUSED;
509 } 523 }
524
525 if (err) {
526 iucv_path_sever(iucv->path, NULL);
527 iucv_path_free(iucv->path);
528 iucv->path = NULL;
529 }
530
510done: 531done:
511 release_sock(sk); 532 release_sock(sk);
512 return err; 533 return err;
@@ -1021,12 +1042,14 @@ static int iucv_callback_connreq(struct iucv_path *path,
1021 ASCEBC(user_data, sizeof(user_data)); 1042 ASCEBC(user_data, sizeof(user_data));
1022 if (sk->sk_state != IUCV_LISTEN) { 1043 if (sk->sk_state != IUCV_LISTEN) {
1023 err = iucv_path_sever(path, user_data); 1044 err = iucv_path_sever(path, user_data);
1045 iucv_path_free(path);
1024 goto fail; 1046 goto fail;
1025 } 1047 }
1026 1048
1027 /* Check for backlog size */ 1049 /* Check for backlog size */
1028 if (sk_acceptq_is_full(sk)) { 1050 if (sk_acceptq_is_full(sk)) {
1029 err = iucv_path_sever(path, user_data); 1051 err = iucv_path_sever(path, user_data);
1052 iucv_path_free(path);
1030 goto fail; 1053 goto fail;
1031 } 1054 }
1032 1055
@@ -1034,6 +1057,7 @@ static int iucv_callback_connreq(struct iucv_path *path,
1034 nsk = iucv_sock_alloc(NULL, SOCK_STREAM, GFP_ATOMIC); 1057 nsk = iucv_sock_alloc(NULL, SOCK_STREAM, GFP_ATOMIC);
1035 if (!nsk) { 1058 if (!nsk) {
1036 err = iucv_path_sever(path, user_data); 1059 err = iucv_path_sever(path, user_data);
1060 iucv_path_free(path);
1037 goto fail; 1061 goto fail;
1038 } 1062 }
1039 1063
@@ -1057,6 +1081,8 @@ static int iucv_callback_connreq(struct iucv_path *path,
1057 err = iucv_path_accept(path, &af_iucv_handler, nuser_data, nsk); 1081 err = iucv_path_accept(path, &af_iucv_handler, nuser_data, nsk);
1058 if (err) { 1082 if (err) {
1059 err = iucv_path_sever(path, user_data); 1083 err = iucv_path_sever(path, user_data);
1084 iucv_path_free(path);
1085 iucv_sock_kill(nsk);
1060 goto fail; 1086 goto fail;
1061 } 1087 }
1062 1088