diff options
Diffstat (limited to 'net/iucv/af_iucv.c')
-rw-r--r-- | net/iucv/af_iucv.c | 28 |
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 | |||
510 | done: | 531 | done: |
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 | ||