diff options
author | Hendrik Brueckner <brueckner@linux.vnet.ibm.com> | 2009-04-21 19:26:27 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-04-23 07:04:38 -0400 |
commit | 09488e2e0fab14ebe41135f0d066cfe2c56ba9e5 (patch) | |
tree | d4435618235088720f7cbc2ac9624e4b8cb0bf7a /net/iucv | |
parent | 802788bf90f78e7f248e78d4d0510bb00e976db8 (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')
-rw-r--r-- | net/iucv/af_iucv.c | 27 |
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); |