All of lore.kernel.org
 help / color / mirror / Atom feed
From: frank.blaschka@de.ibm.com
To: davem@davemloft.net
Cc: netdev@vger.kernel.org, linux-s390@vger.kernel.org,
	Ursula Braun <ursula.braun@de.ibm.com>,
	Martin Schwidefsky <schwidefsky@de.ibm.com>
Subject: [patch 1/6] [PATCH] af_iucv: remove IUCV-pathes completely
Date: Wed, 08 Feb 2012 11:19:45 +0100	[thread overview]
Message-ID: <20120208102029.117792481@de.ibm.com> (raw)
In-Reply-To: 20120208101944.272235343@de.ibm.com

[-- Attachment #1: 601-af_iucv-remove-path.diff --]
[-- Type: text/plain, Size: 4995 bytes --]

From: Ursula Braun <ursula.braun@de.ibm.com>

A SEVER is missing in the callback of a receiving SEVERED. This may
inhibit z/VM to remove the corresponding IUCV-path completely.
This patch adds a SEVER in iucv_callback_connrej (together with
additional locking.

Signed-off-by: Ursula Braun <ursula.braun@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Frank Blaschka <frank.blaschka@de.ibm.com>
---

 net/iucv/af_iucv.c |   71 +++++++++++++++++++++++++++--------------------------
 1 file changed, 37 insertions(+), 34 deletions(-)

--- a/net/iucv/af_iucv.c
+++ b/net/iucv/af_iucv.c
@@ -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);
@@ -181,11 +182,7 @@ static int afiucv_pm_freeze(struct devic
 		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:
@@ -194,6 +191,8 @@ static int afiucv_pm_freeze(struct devic
 		default:
 			break;
 		}
+		skb_queue_purge(&iucv->send_skb_q);
+		skb_queue_purge(&iucv->backlog_skb_q);
 	}
 	read_unlock(&iucv_sk_list.lock);
 	return err;
@@ -447,10 +446,29 @@ static void iucv_sock_kill(struct sock *
 	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;
@@ -494,25 +512,14 @@ static void iucv_sock_close(struct sock
 		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() */
@@ -894,11 +901,8 @@ static int iucv_sock_connect(struct sock
 	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);
@@ -1565,13 +1569,6 @@ static int iucv_sock_release(struct 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;
@@ -1750,8 +1747,7 @@ static int iucv_callback_connreq(struct
 	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;
 	}
@@ -1828,6 +1824,7 @@ static void iucv_callback_txdone(struct
 	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);
 
@@ -1849,7 +1846,6 @@ static void iucv_callback_txdone(struct
 			iucv_sock_wake_msglim(sk);
 		}
 	}
-	BUG_ON(!this);
 
 	if (sk->sk_state == IUCV_CLOSING) {
 		if (skb_queue_empty(&iucv_sk(sk)->send_skb_q)) {
@@ -1857,6 +1853,7 @@ static void iucv_callback_txdone(struct
 			sk->sk_state_change(sk);
 		}
 	}
+	bh_unlock_sock(sk);
 
 }
 
@@ -1864,9 +1861,15 @@ static void iucv_callback_connrej(struct
 {
 	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;

  reply	other threads:[~2012-02-08 10:20 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-02-08 10:19 [patch 0/6] s390: network driver features and fixes for net-next frank.blaschka
2012-02-08 10:19 ` frank.blaschka [this message]
2012-02-08 10:19 ` [patch 2/6] [PATCH] af_iucv: block writing if msg limit is exceeded frank.blaschka
2012-02-08 10:19 ` [patch 3/6] [PATCH] af_iucv: change net_device handling for HS transport frank.blaschka
2012-02-08 10:19 ` [patch 4/6] [PATCH] af_iucv: allow retrieval of maximum message size frank.blaschka
2012-02-08 10:19 ` [patch 5/6] [PATCH] qeth: add query OSA address table support frank.blaschka
2012-02-08 10:19 ` [patch 6/6] [PATCH] qeth: add wake_up on write channel frank.blaschka
2012-02-09  1:28 ` [patch 0/6] s390: network driver features and fixes for net-next David Miller

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20120208102029.117792481@de.ibm.com \
    --to=frank.blaschka@de.ibm.com \
    --cc=davem@davemloft.net \
    --cc=linux-s390@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=schwidefsky@de.ibm.com \
    --cc=ursula.braun@de.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.