netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Ursula Braun <ursula.braun@de.ibm.com>
To: davem@davemloft.net, netdev@vger.kernel.org, linux-s390@vger.kernel.org
Cc: schwidefsky@de.ibm.com, heiko.carstens@de.ibm.com,
	Hendrik Brueckner <brueckner@linux.vnet.ibm.com>,
	Ursula Braun <ursula.braun@de.ibm.com>
Subject: [patch 6/8] [PATCH] af_iucv: Provide new socket type SOCK_SEQPACKET
Date: Wed, 22 Apr 2009 11:26:25 +0200	[thread overview]
Message-ID: <20090422093430.459769000@linux.vnet.ibm.com> (raw)
In-Reply-To: 20090422092619.451973000@linux.vnet.ibm.com

[-- Attachment #1: 610-af_iucv-seqpacket-socket.diff --]
[-- Type: text/plain, Size: 5717 bytes --]

From: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>

This patch provides the socket type SOCK_SEQPACKET in addition to
SOCK_STREAM.

AF_IUCV sockets of type SOCK_SEQPACKET supports an 1:1 mapping of
socket read or write operations to complete IUCV messages.
Socket data or IUCV message data is not fragmented as this is the
case for SOCK_STREAM sockets.

The intention is to help application developers who write
applications or device drivers using native IUCV interfaces
(Linux kernel or z/VM IUCV interfaces).

Signed-off-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
Signed-off-by: Ursula Braun <ursula.braun@de.ibm.com>
---

 net/iucv/af_iucv.c |   73 ++++++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 56 insertions(+), 17 deletions(-)

Index: net-next-2.6-uschi/net/iucv/af_iucv.c
===================================================================
--- net-next-2.6-uschi.orig/net/iucv/af_iucv.c
+++ net-next-2.6-uschi/net/iucv/af_iucv.c
@@ -289,11 +289,22 @@ static int iucv_sock_create(struct net *
 {
 	struct sock *sk;
 
-	if (sock->type != SOCK_STREAM)
-		return -ESOCKTNOSUPPORT;
+	if (protocol && protocol != PF_IUCV)
+		return -EPROTONOSUPPORT;
 
 	sock->state = SS_UNCONNECTED;
-	sock->ops = &iucv_sock_ops;
+
+	switch (sock->type) {
+	case SOCK_STREAM:
+		sock->ops = &iucv_sock_ops;
+		break;
+	case SOCK_SEQPACKET:
+		/* currently, proto ops can handle both sk types */
+		sock->ops = &iucv_sock_ops;
+		break;
+	default:
+		return -ESOCKTNOSUPPORT;
+	}
 
 	sk = iucv_sock_alloc(sock, protocol, GFP_KERNEL);
 	if (!sk)
@@ -504,11 +515,9 @@ static int iucv_sock_connect(struct sock
 	if (sk->sk_state != IUCV_OPEN && sk->sk_state != IUCV_BOUND)
 		return -EBADFD;
 
-	if (sk->sk_type != SOCK_STREAM)
+	if (sk->sk_type != SOCK_STREAM && sk->sk_type != SOCK_SEQPACKET)
 		return -EINVAL;
 
-	iucv = iucv_sk(sk);
-
 	if (sk->sk_state == IUCV_OPEN) {
 		err = iucv_sock_autobind(sk);
 		if (unlikely(err))
@@ -585,7 +594,10 @@ static int iucv_sock_listen(struct socke
 	lock_sock(sk);
 
 	err = -EINVAL;
-	if (sk->sk_state != IUCV_BOUND || sock->type != SOCK_STREAM)
+	if (sk->sk_state != IUCV_BOUND)
+		goto done;
+
+	if (sock->type != SOCK_STREAM && sock->type != SOCK_SEQPACKET)
 		goto done;
 
 	sk->sk_max_ack_backlog = backlog;
@@ -720,6 +732,10 @@ static int iucv_sock_sendmsg(struct kioc
 	if (msg->msg_flags & MSG_OOB)
 		return -EOPNOTSUPP;
 
+	/* SOCK_SEQPACKET: we do not support segmented records */
+	if (sk->sk_type == SOCK_SEQPACKET && !(msg->msg_flags & MSG_EOR))
+		return -EOPNOTSUPP;
+
 	lock_sock(sk);
 
 	if (sk->sk_shutdown & SEND_SHUTDOWN) {
@@ -770,6 +786,10 @@ static int iucv_sock_sendmsg(struct kioc
 			}
 		}
 
+		/* allocate one skb for each iucv message:
+		 * this is fine for SOCK_SEQPACKET (unless we want to support
+		 * segmented records using the MSG_EOR flag), but
+		 * for SOCK_STREAM we might want to improve it in future */
 		if (!(skb = sock_alloc_send_skb(sk, len,
 						msg->msg_flags & MSG_DONTWAIT,
 						&err)))
@@ -897,7 +917,11 @@ static void iucv_process_message(struct 
 			kfree_skb(skb);
 			return;
 		}
-		if (skb->truesize >= sk->sk_rcvbuf / 4) {
+		/* we need to fragment iucv messages for SOCK_STREAM only;
+		 * for SOCK_SEQPACKET, it is only relevant if we support
+		 * record segmentation using MSG_EOR (see also recvmsg()) */
+		if (sk->sk_type == SOCK_STREAM &&
+		    skb->truesize >= sk->sk_rcvbuf / 4) {
 			rc = iucv_fragment_skb(sk, skb, len);
 			kfree_skb(skb);
 			skb = NULL;
@@ -941,7 +965,8 @@ static int iucv_sock_recvmsg(struct kioc
 	int noblock = flags & MSG_DONTWAIT;
 	struct sock *sk = sock->sk;
 	struct iucv_sock *iucv = iucv_sk(sk);
-	int target, copied = 0;
+	int target;
+	unsigned int copied, rlen;
 	struct sk_buff *skb, *rskb, *cskb;
 	int err = 0;
 
@@ -963,7 +988,8 @@ static int iucv_sock_recvmsg(struct kioc
 		return err;
 	}
 
-	copied = min_t(unsigned int, skb->len, len);
+	rlen   = skb->len;		/* real length of skb */
+	copied = min_t(unsigned int, rlen, len);
 
 	cskb = skb;
 	if (memcpy_toiovec(msg->msg_iov, cskb->data, copied)) {
@@ -973,7 +999,13 @@ static int iucv_sock_recvmsg(struct kioc
 		goto done;
 	}
 
-	len -= copied;
+	/* SOCK_SEQPACKET: set MSG_TRUNC if recv buf size is too small */
+	if (sk->sk_type == SOCK_SEQPACKET) {
+		if (copied < rlen)
+			msg->msg_flags |= MSG_TRUNC;
+		/* each iucv message contains a complete record */
+		msg->msg_flags |= MSG_EOR;
+	}
 
 	/* create control message to store iucv msg target class:
 	 * get the trgcls from the control buffer of the skb due to
@@ -988,11 +1020,14 @@ static int iucv_sock_recvmsg(struct kioc
 
 	/* Mark read part of skb as used */
 	if (!(flags & MSG_PEEK)) {
-		skb_pull(skb, copied);
 
-		if (skb->len) {
-			skb_queue_head(&sk->sk_receive_queue, skb);
-			goto done;
+		/* SOCK_STREAM: re-queue skb if it contains unreceived data */
+		if (sk->sk_type == SOCK_STREAM) {
+			skb_pull(skb, copied);
+			if (skb->len) {
+				skb_queue_head(&sk->sk_receive_queue, skb);
+				goto done;
+			}
 		}
 
 		kfree_skb(skb);
@@ -1019,7 +1054,11 @@ static int iucv_sock_recvmsg(struct kioc
 		skb_queue_head(&sk->sk_receive_queue, skb);
 
 done:
-	return err ? : copied;
+	/* SOCK_SEQPACKET: return real length if MSG_TRUNC is set */
+	if (sk->sk_type == SOCK_SEQPACKET && (flags & MSG_TRUNC))
+		copied = rlen;
+
+	return copied;
 }
 
 static inline unsigned int iucv_accept_poll(struct sock *parent)
@@ -1281,7 +1320,7 @@ static int iucv_callback_connreq(struct 
 	}
 
 	/* Create the new socket */
-	nsk = iucv_sock_alloc(NULL, SOCK_STREAM, GFP_ATOMIC);
+	nsk = iucv_sock_alloc(NULL, sk->sk_type, GFP_ATOMIC);
 	if (!nsk) {
 		err = iucv_path_sever(path, user_data);
 		iucv_path_free(path);


  parent reply	other threads:[~2009-04-22  9:35 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-04-22  9:26 [patch 0/8] iucv / af_iucv patches for net-next-2.6.30-rc1 Ursula Braun
2009-04-22  9:26 ` [patch 1/8] [PATCH] iucv: provide second per-cpu IUCV command parameter block Ursula Braun
2009-04-22  9:26 ` [patch 2/8] [PATCH] af_iucv: sync sk shutdown flag if iucv path is quiesced Ursula Braun
2009-04-22  9:26 ` [patch 3/8] [PATCH] af_iucv: add sockopt() to enable/disable use of IPRM_DATA msgs Ursula Braun
2009-04-22  9:26 ` [patch 4/8] [PATCH] af_iucv: Support data in IUCV msg parameter lists (IPRMDATA) Ursula Braun
2009-04-22  9:26 ` [patch 5/8] [PATCH] af_iucv: Modify iucv msg target class using control msghdr Ursula Braun
2009-04-22  9:26 ` Ursula Braun [this message]
2009-04-22  9:26 ` [patch 7/8] [PATCH] af_iucv: cleanup and refactor recvmsg() EFAULT handling Ursula Braun
2009-04-22  9:26 ` [patch 8/8] [PATCH] af_iucv: New socket option for setting IUCV MSGLIMITs Ursula Braun
2009-04-22  9:48 ` [patch 0/8] iucv / af_iucv patches for net-next-2.6.30-rc1 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=20090422093430.459769000@linux.vnet.ibm.com \
    --to=ursula.braun@de.ibm.com \
    --cc=brueckner@linux.vnet.ibm.com \
    --cc=davem@davemloft.net \
    --cc=heiko.carstens@de.ibm.com \
    --cc=linux-s390@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=schwidefsky@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).