summaryrefslogtreecommitdiffstats
path: root/net/iucv/af_iucv.c
diff options
context:
space:
mode:
authorHendrik Brueckner <brueckner@linux.vnet.ibm.com>2009-04-21 23:26:21 +0000
committerDavid S. Miller <davem@davemloft.net>2009-04-23 04:04:30 -0700
commitaf88b52def76679c8c5bcdbed199fbe62b6a16d4 (patch)
treea53c8d8f27a5b19cf10e5ca97abcad48261f7c1e /net/iucv/af_iucv.c
parent42e1b4c2c6c823ae26e64c557addf5329a7735b7 (diff)
af_iucv: sync sk shutdown flag if iucv path is quiesced
If the af_iucv communication partner quiesces the path to shutdown its receive direction, provide a quiesce callback implementation to shutdown the (local) send direction. This ensures that both sides are synchronized. Signed-off-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com> Signed-off-by: Ursula Braun <ursula.braun@de.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/iucv/af_iucv.c')
-rw-r--r--net/iucv/af_iucv.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
index 49e786535dc..6cf02b41ef9 100644
--- a/net/iucv/af_iucv.c
+++ b/net/iucv/af_iucv.c
@@ -54,6 +54,7 @@ static void iucv_callback_connack(struct iucv_path *, u8 ipuser[16]);
static int iucv_callback_connreq(struct iucv_path *, u8 ipvmid[8],
u8 ipuser[16]);
static void iucv_callback_connrej(struct iucv_path *, u8 ipuser[16]);
+static void iucv_callback_shutdown(struct iucv_path *, u8 ipuser[16]);
static struct iucv_sock_list iucv_sk_list = {
.lock = __RW_LOCK_UNLOCKED(iucv_sk_list.lock),
@@ -65,7 +66,8 @@ static struct iucv_handler af_iucv_handler = {
.path_complete = iucv_callback_connack,
.path_severed = iucv_callback_connrej,
.message_pending = iucv_callback_rx,
- .message_complete = iucv_callback_txdone
+ .message_complete = iucv_callback_txdone,
+ .path_quiesced = iucv_callback_shutdown,
};
static inline void high_nmcpy(unsigned char *dst, char *src)
@@ -1196,6 +1198,21 @@ static void iucv_callback_connrej(struct iucv_path *path, u8 ipuser[16])
sk->sk_state_change(sk);
}
+/* called if the other communication side shuts down its RECV direction;
+ * in turn, the callback sets SEND_SHUTDOWN to disable sending of data.
+ */
+static void iucv_callback_shutdown(struct iucv_path *path, u8 ipuser[16])
+{
+ struct sock *sk = path->private;
+
+ bh_lock_sock(sk);
+ if (sk->sk_state != IUCV_CLOSED) {
+ sk->sk_shutdown |= SEND_SHUTDOWN;
+ sk->sk_state_change(sk);
+ }
+ bh_unlock_sock(sk);
+}
+
static struct proto_ops iucv_sock_ops = {
.family = PF_IUCV,
.owner = THIS_MODULE,