aboutsummaryrefslogtreecommitdiffstats
path: root/net/iucv/af_iucv.c
diff options
context:
space:
mode:
authorHendrik Brueckner <brueckner@linux.vnet.ibm.com>2009-04-21 19:26:27 -0400
committerDavid S. Miller <davem@davemloft.net>2009-04-23 07:04:38 -0400
commit09488e2e0fab14ebe41135f0d066cfe2c56ba9e5 (patch)
treed4435618235088720f7cbc2ac9624e4b8cb0bf7a /net/iucv/af_iucv.c
parent802788bf90f78e7f248e78d4d0510bb00e976db8 (diff)
af_iucv: New socket option for setting IUCV MSGLIMITs
The SO_MSGLIMIT socket option modifies the message limit for new IUCV communication paths. The message limit specifies the maximum number of outstanding messages that are allowed for connections. This setting can be lowered by z/VM when an IUCV connection is established. Expects an integer value in the range of 1 to 65535. The default value is 65535. The message limit must be set before calling connect() or listen() for sockets. If sockets are already connected or in state listen, changing the message limit is not supported. For reading the message limit value, unconnected sockets return the limit that has been set or the default limit. For connected sockets, the actual message limit is returned. The actual message limit is assigned by z/VM for each connection and it depends on IUCV MSGLIMIT authorizations specified for the z/VM guest virtual machine. 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.c27
1 files changed, 25 insertions, 2 deletions
diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
index f0dea1b8ed4b..264c6b36931c 100644
--- a/net/iucv/af_iucv.c
+++ b/net/iucv/af_iucv.c
@@ -268,6 +268,7 @@ static struct sock *iucv_sock_alloc(struct socket *sock, int proto, gfp_t prio)
268 skb_queue_head_init(&iucv_sk(sk)->backlog_skb_q); 268 skb_queue_head_init(&iucv_sk(sk)->backlog_skb_q);
269 iucv_sk(sk)->send_tag = 0; 269 iucv_sk(sk)->send_tag = 0;
270 iucv_sk(sk)->flags = 0; 270 iucv_sk(sk)->flags = 0;
271 iucv_sk(sk)->msglimit = IUCV_QUEUELEN_DEFAULT;
271 272
272 sk->sk_destruct = iucv_sock_destruct; 273 sk->sk_destruct = iucv_sock_destruct;
273 sk->sk_sndtimeo = IUCV_CONN_TIMEOUT; 274 sk->sk_sndtimeo = IUCV_CONN_TIMEOUT;
@@ -536,7 +537,7 @@ static int iucv_sock_connect(struct socket *sock, struct sockaddr *addr,
536 537
537 iucv = iucv_sk(sk); 538 iucv = iucv_sk(sk);
538 /* Create path. */ 539 /* Create path. */
539 iucv->path = iucv_path_alloc(IUCV_QUEUELEN_DEFAULT, 540 iucv->path = iucv_path_alloc(iucv->msglimit,
540 IUCV_IPRMDATA, GFP_KERNEL); 541 IUCV_IPRMDATA, GFP_KERNEL);
541 if (!iucv->path) { 542 if (!iucv->path) {
542 err = -ENOMEM; 543 err = -ENOMEM;
@@ -1219,6 +1220,20 @@ static int iucv_sock_setsockopt(struct socket *sock, int level, int optname,
1219 else 1220 else
1220 iucv->flags &= ~IUCV_IPRMDATA; 1221 iucv->flags &= ~IUCV_IPRMDATA;
1221 break; 1222 break;
1223 case SO_MSGLIMIT:
1224 switch (sk->sk_state) {
1225 case IUCV_OPEN:
1226 case IUCV_BOUND:
1227 if (val < 1 || val > (u16)(~0))
1228 rc = -EINVAL;
1229 else
1230 iucv->msglimit = val;
1231 break;
1232 default:
1233 rc = -EINVAL;
1234 break;
1235 }
1236 break;
1222 default: 1237 default:
1223 rc = -ENOPROTOOPT; 1238 rc = -ENOPROTOOPT;
1224 break; 1239 break;
@@ -1250,6 +1265,12 @@ static int iucv_sock_getsockopt(struct socket *sock, int level, int optname,
1250 case SO_IPRMDATA_MSG: 1265 case SO_IPRMDATA_MSG:
1251 val = (iucv->flags & IUCV_IPRMDATA) ? 1 : 0; 1266 val = (iucv->flags & IUCV_IPRMDATA) ? 1 : 0;
1252 break; 1267 break;
1268 case SO_MSGLIMIT:
1269 lock_sock(sk);
1270 val = (iucv->path != NULL) ? iucv->path->msglim /* connected */
1271 : iucv->msglimit; /* default */
1272 release_sock(sk);
1273 break;
1253 default: 1274 default:
1254 return -ENOPROTOOPT; 1275 return -ENOPROTOOPT;
1255 } 1276 }
@@ -1339,7 +1360,9 @@ static int iucv_callback_connreq(struct iucv_path *path,
1339 memcpy(nuser_data + 8, niucv->src_name, 8); 1360 memcpy(nuser_data + 8, niucv->src_name, 8);
1340 ASCEBC(nuser_data + 8, 8); 1361 ASCEBC(nuser_data + 8, 8);
1341 1362
1342 path->msglim = IUCV_QUEUELEN_DEFAULT; 1363 /* set message limit for path based on msglimit of accepting socket */
1364 niucv->msglimit = iucv->msglimit;
1365 path->msglim = iucv->msglimit;
1343 err = iucv_path_accept(path, &af_iucv_handler, nuser_data, nsk); 1366 err = iucv_path_accept(path, &af_iucv_handler, nuser_data, nsk);
1344 if (err) { 1367 if (err) {
1345 err = iucv_path_sever(path, user_data); 1368 err = iucv_path_sever(path, user_data);