Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 290060
b: refs/heads/master
c: 7d316b9
h: refs/heads/master
v: v3
  • Loading branch information
Ursula Braun authored and David S. Miller committed Feb 8, 2012
1 parent b6f8bd6 commit c4764c0
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 35 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 1ab0d2ec9aeb4489c05158e8a2b00bad89f67e03
refs/heads/master: 7d316b9453523498246e9e19a659c423d4c5081e
71 changes: 37 additions & 34 deletions trunk/net/iucv/af_iucv.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ do { \

static void iucv_sock_kill(struct sock *sk);
static void iucv_sock_close(struct sock *sk);
static void iucv_sever_path(struct sock *, int);

static int afiucv_hs_rcv(struct sk_buff *skb, struct net_device *dev,
struct packet_type *pt, struct net_device *orig_dev);
Expand Down Expand Up @@ -181,11 +182,7 @@ static int afiucv_pm_freeze(struct device *dev)
case IUCV_DISCONN:
case IUCV_CLOSING:
case IUCV_CONNECTED:
if (iucv->path) {
err = pr_iucv->path_sever(iucv->path, NULL);
iucv_path_free(iucv->path);
iucv->path = NULL;
}
iucv_sever_path(sk, 0);
break;
case IUCV_OPEN:
case IUCV_BOUND:
Expand All @@ -194,6 +191,8 @@ static int afiucv_pm_freeze(struct device *dev)
default:
break;
}
skb_queue_purge(&iucv->send_skb_q);
skb_queue_purge(&iucv->backlog_skb_q);
}
read_unlock(&iucv_sk_list.lock);
return err;
Expand Down Expand Up @@ -447,10 +446,29 @@ static void iucv_sock_kill(struct sock *sk)
sock_put(sk);
}

/* Terminate an IUCV path */
static void iucv_sever_path(struct sock *sk, int with_user_data)
{
unsigned char user_data[16];
struct iucv_sock *iucv = iucv_sk(sk);
struct iucv_path *path = iucv->path;

if (iucv->path) {
iucv->path = NULL;
if (with_user_data) {
low_nmcpy(user_data, iucv->src_name);
high_nmcpy(user_data, iucv->dst_name);
ASCEBC(user_data, sizeof(user_data));
pr_iucv->path_sever(path, user_data);
} else
pr_iucv->path_sever(path, NULL);
iucv_path_free(path);
}
}

/* Close an IUCV socket */
static void iucv_sock_close(struct sock *sk)
{
unsigned char user_data[16];
struct iucv_sock *iucv = iucv_sk(sk);
unsigned long timeo;
int err, blen;
Expand Down Expand Up @@ -494,25 +512,14 @@ static void iucv_sock_close(struct sock *sk)
sk->sk_state = IUCV_CLOSED;
sk->sk_state_change(sk);

if (iucv->path) {
low_nmcpy(user_data, iucv->src_name);
high_nmcpy(user_data, iucv->dst_name);
ASCEBC(user_data, sizeof(user_data));
pr_iucv->path_sever(iucv->path, user_data);
iucv_path_free(iucv->path);
iucv->path = NULL;
}

sk->sk_err = ECONNRESET;
sk->sk_state_change(sk);

iucv_skb_queue_purge(&iucv->send_skb_q);
skb_queue_purge(&iucv->backlog_skb_q);
break;

default:
/* nothing to do here */
break;
default: /* fall through */
iucv_sever_path(sk, 1);
}

/* mark socket for deletion by iucv_sock_kill() */
Expand Down Expand Up @@ -894,11 +901,8 @@ static int iucv_sock_connect(struct socket *sock, struct sockaddr *addr,
if (sk->sk_state == IUCV_DISCONN || sk->sk_state == IUCV_CLOSED)
err = -ECONNREFUSED;

if (err && iucv->transport == AF_IUCV_TRANS_IUCV) {
pr_iucv->path_sever(iucv->path, NULL);
iucv_path_free(iucv->path);
iucv->path = NULL;
}
if (err && iucv->transport == AF_IUCV_TRANS_IUCV)
iucv_sever_path(sk, 0);

done:
release_sock(sk);
Expand Down Expand Up @@ -1565,13 +1569,6 @@ static int iucv_sock_release(struct socket *sock)

iucv_sock_close(sk);

/* Unregister with IUCV base support */
if (iucv_sk(sk)->path) {
pr_iucv->path_sever(iucv_sk(sk)->path, NULL);
iucv_path_free(iucv_sk(sk)->path);
iucv_sk(sk)->path = NULL;
}

sock_orphan(sk);
iucv_sock_kill(sk);
return err;
Expand Down Expand Up @@ -1750,8 +1747,7 @@ static int iucv_callback_connreq(struct iucv_path *path,
path->msglim = iucv->msglimit;
err = pr_iucv->path_accept(path, &af_iucv_handler, nuser_data, nsk);
if (err) {
err = pr_iucv->path_sever(path, user_data);
iucv_path_free(path);
iucv_sever_path(nsk, 1);
iucv_sock_kill(nsk);
goto fail;
}
Expand Down Expand Up @@ -1828,6 +1824,7 @@ static void iucv_callback_txdone(struct iucv_path *path,
struct sk_buff *list_skb = list->next;
unsigned long flags;

bh_lock_sock(sk);
if (!skb_queue_empty(list)) {
spin_lock_irqsave(&list->lock, flags);

Expand All @@ -1849,24 +1846,30 @@ static void iucv_callback_txdone(struct iucv_path *path,
iucv_sock_wake_msglim(sk);
}
}
BUG_ON(!this);

if (sk->sk_state == IUCV_CLOSING) {
if (skb_queue_empty(&iucv_sk(sk)->send_skb_q)) {
sk->sk_state = IUCV_CLOSED;
sk->sk_state_change(sk);
}
}
bh_unlock_sock(sk);

}

static void iucv_callback_connrej(struct iucv_path *path, u8 ipuser[16])
{
struct sock *sk = path->private;

if (sk->sk_state == IUCV_CLOSED)
return;

bh_lock_sock(sk);
iucv_sever_path(sk, 1);
sk->sk_state = IUCV_DISCONN;

sk->sk_state_change(sk);
bh_unlock_sock(sk);
}

/* called if the other communication side shuts down its RECV direction;
Expand Down

0 comments on commit c4764c0

Please sign in to comment.