aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/9p/trans_fd.c112
-rw-r--r--net/ipv4/Kconfig6
-rw-r--r--net/ipv4/ipconfig.c2
-rw-r--r--net/socket.c108
-rw-r--r--net/sunrpc/sched.c15
-rw-r--r--net/sunrpc/svc_xprt.c31
-rw-r--r--net/sunrpc/svcauth_unix.c53
7 files changed, 140 insertions, 187 deletions
diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c
index 4dd873e3a1bb..be1cb909d8c0 100644
--- a/net/9p/trans_fd.c
+++ b/net/9p/trans_fd.c
@@ -42,6 +42,8 @@
42#include <net/9p/client.h> 42#include <net/9p/client.h>
43#include <net/9p/transport.h> 43#include <net/9p/transport.h>
44 44
45#include <linux/syscalls.h> /* killme */
46
45#define P9_PORT 564 47#define P9_PORT 564
46#define MAX_SOCK_BUF (64*1024) 48#define MAX_SOCK_BUF (64*1024)
47#define MAXPOLLWADDR 2 49#define MAXPOLLWADDR 2
@@ -788,24 +790,41 @@ static int p9_fd_open(struct p9_client *client, int rfd, int wfd)
788 790
789static int p9_socket_open(struct p9_client *client, struct socket *csocket) 791static int p9_socket_open(struct p9_client *client, struct socket *csocket)
790{ 792{
791 int fd, ret; 793 struct p9_trans_fd *p;
794 int ret, fd;
795
796 p = kmalloc(sizeof(struct p9_trans_fd), GFP_KERNEL);
797 if (!p)
798 return -ENOMEM;
792 799
793 csocket->sk->sk_allocation = GFP_NOIO; 800 csocket->sk->sk_allocation = GFP_NOIO;
794 fd = sock_map_fd(csocket, 0); 801 fd = sock_map_fd(csocket, 0);
795 if (fd < 0) { 802 if (fd < 0) {
796 P9_EPRINTK(KERN_ERR, "p9_socket_open: failed to map fd\n"); 803 P9_EPRINTK(KERN_ERR, "p9_socket_open: failed to map fd\n");
804 sock_release(csocket);
805 kfree(p);
797 return fd; 806 return fd;
798 } 807 }
799 808
800 ret = p9_fd_open(client, fd, fd); 809 get_file(csocket->file);
801 if (ret < 0) { 810 get_file(csocket->file);
802 P9_EPRINTK(KERN_ERR, "p9_socket_open: failed to open fd\n"); 811 p->wr = p->rd = csocket->file;
812 client->trans = p;
813 client->status = Connected;
814
815 sys_close(fd); /* still racy */
816
817 p->rd->f_flags |= O_NONBLOCK;
818
819 p->conn = p9_conn_create(client);
820 if (IS_ERR(p->conn)) {
821 ret = PTR_ERR(p->conn);
822 p->conn = NULL;
823 kfree(p);
824 sockfd_put(csocket);
803 sockfd_put(csocket); 825 sockfd_put(csocket);
804 return ret; 826 return ret;
805 } 827 }
806
807 ((struct p9_trans_fd *)client->trans)->rd->f_flags |= O_NONBLOCK;
808
809 return 0; 828 return 0;
810} 829}
811 830
@@ -883,7 +902,6 @@ p9_fd_create_tcp(struct p9_client *client, const char *addr, char *args)
883 struct socket *csocket; 902 struct socket *csocket;
884 struct sockaddr_in sin_server; 903 struct sockaddr_in sin_server;
885 struct p9_fd_opts opts; 904 struct p9_fd_opts opts;
886 struct p9_trans_fd *p = NULL; /* this gets allocated in p9_fd_open */
887 905
888 err = parse_opts(args, &opts); 906 err = parse_opts(args, &opts);
889 if (err < 0) 907 if (err < 0)
@@ -897,12 +915,11 @@ p9_fd_create_tcp(struct p9_client *client, const char *addr, char *args)
897 sin_server.sin_family = AF_INET; 915 sin_server.sin_family = AF_INET;
898 sin_server.sin_addr.s_addr = in_aton(addr); 916 sin_server.sin_addr.s_addr = in_aton(addr);
899 sin_server.sin_port = htons(opts.port); 917 sin_server.sin_port = htons(opts.port);
900 sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, &csocket); 918 err = sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, &csocket);
901 919
902 if (!csocket) { 920 if (err) {
903 P9_EPRINTK(KERN_ERR, "p9_trans_tcp: problem creating socket\n"); 921 P9_EPRINTK(KERN_ERR, "p9_trans_tcp: problem creating socket\n");
904 err = -EIO; 922 return err;
905 goto error;
906 } 923 }
907 924
908 err = csocket->ops->connect(csocket, 925 err = csocket->ops->connect(csocket,
@@ -912,30 +929,11 @@ p9_fd_create_tcp(struct p9_client *client, const char *addr, char *args)
912 P9_EPRINTK(KERN_ERR, 929 P9_EPRINTK(KERN_ERR,
913 "p9_trans_tcp: problem connecting socket to %s\n", 930 "p9_trans_tcp: problem connecting socket to %s\n",
914 addr); 931 addr);
915 goto error;
916 }
917
918 err = p9_socket_open(client, csocket);
919 if (err < 0)
920 goto error;
921
922 p = (struct p9_trans_fd *) client->trans;
923 p->conn = p9_conn_create(client);
924 if (IS_ERR(p->conn)) {
925 err = PTR_ERR(p->conn);
926 p->conn = NULL;
927 goto error;
928 }
929
930 return 0;
931
932error:
933 if (csocket)
934 sock_release(csocket); 932 sock_release(csocket);
933 return err;
934 }
935 935
936 kfree(p); 936 return p9_socket_open(client, csocket);
937
938 return err;
939} 937}
940 938
941static int 939static int
@@ -944,49 +942,33 @@ p9_fd_create_unix(struct p9_client *client, const char *addr, char *args)
944 int err; 942 int err;
945 struct socket *csocket; 943 struct socket *csocket;
946 struct sockaddr_un sun_server; 944 struct sockaddr_un sun_server;
947 struct p9_trans_fd *p = NULL; /* this gets allocated in p9_fd_open */
948 945
949 csocket = NULL; 946 csocket = NULL;
950 947
951 if (strlen(addr) > UNIX_PATH_MAX) { 948 if (strlen(addr) > UNIX_PATH_MAX) {
952 P9_EPRINTK(KERN_ERR, "p9_trans_unix: address too long: %s\n", 949 P9_EPRINTK(KERN_ERR, "p9_trans_unix: address too long: %s\n",
953 addr); 950 addr);
954 err = -ENAMETOOLONG; 951 return -ENAMETOOLONG;
955 goto error;
956 } 952 }
957 953
958 sun_server.sun_family = PF_UNIX; 954 sun_server.sun_family = PF_UNIX;
959 strcpy(sun_server.sun_path, addr); 955 strcpy(sun_server.sun_path, addr);
960 sock_create_kern(PF_UNIX, SOCK_STREAM, 0, &csocket); 956 err = sock_create_kern(PF_UNIX, SOCK_STREAM, 0, &csocket);
957 if (err < 0) {
958 P9_EPRINTK(KERN_ERR, "p9_trans_unix: problem creating socket\n");
959 return err;
960 }
961 err = csocket->ops->connect(csocket, (struct sockaddr *)&sun_server, 961 err = csocket->ops->connect(csocket, (struct sockaddr *)&sun_server,
962 sizeof(struct sockaddr_un) - 1, 0); 962 sizeof(struct sockaddr_un) - 1, 0);
963 if (err < 0) { 963 if (err < 0) {
964 P9_EPRINTK(KERN_ERR, 964 P9_EPRINTK(KERN_ERR,
965 "p9_trans_unix: problem connecting socket: %s: %d\n", 965 "p9_trans_unix: problem connecting socket: %s: %d\n",
966 addr, err); 966 addr, err);
967 goto error;
968 }
969
970 err = p9_socket_open(client, csocket);
971 if (err < 0)
972 goto error;
973
974 p = (struct p9_trans_fd *) client->trans;
975 p->conn = p9_conn_create(client);
976 if (IS_ERR(p->conn)) {
977 err = PTR_ERR(p->conn);
978 p->conn = NULL;
979 goto error;
980 }
981
982 return 0;
983
984error:
985 if (csocket)
986 sock_release(csocket); 967 sock_release(csocket);
968 return err;
969 }
987 970
988 kfree(p); 971 return p9_socket_open(client, csocket);
989 return err;
990} 972}
991 973
992static int 974static int
@@ -994,7 +976,7 @@ p9_fd_create(struct p9_client *client, const char *addr, char *args)
994{ 976{
995 int err; 977 int err;
996 struct p9_fd_opts opts; 978 struct p9_fd_opts opts;
997 struct p9_trans_fd *p = NULL; /* this get allocated in p9_fd_open */ 979 struct p9_trans_fd *p;
998 980
999 parse_opts(args, &opts); 981 parse_opts(args, &opts);
1000 982
@@ -1005,21 +987,19 @@ p9_fd_create(struct p9_client *client, const char *addr, char *args)
1005 987
1006 err = p9_fd_open(client, opts.rfd, opts.wfd); 988 err = p9_fd_open(client, opts.rfd, opts.wfd);
1007 if (err < 0) 989 if (err < 0)
1008 goto error; 990 return err;
1009 991
1010 p = (struct p9_trans_fd *) client->trans; 992 p = (struct p9_trans_fd *) client->trans;
1011 p->conn = p9_conn_create(client); 993 p->conn = p9_conn_create(client);
1012 if (IS_ERR(p->conn)) { 994 if (IS_ERR(p->conn)) {
1013 err = PTR_ERR(p->conn); 995 err = PTR_ERR(p->conn);
1014 p->conn = NULL; 996 p->conn = NULL;
1015 goto error; 997 fput(p->rd);
998 fput(p->wr);
999 return err;
1016 } 1000 }
1017 1001
1018 return 0; 1002 return 0;
1019
1020error:
1021 kfree(p);
1022 return err;
1023} 1003}
1024 1004
1025static struct p9_trans_module p9_tcp_trans = { 1005static struct p9_trans_module p9_tcp_trans = {
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
index 70491d9035eb..0c94a1ac2946 100644
--- a/net/ipv4/Kconfig
+++ b/net/ipv4/Kconfig
@@ -166,7 +166,7 @@ config IP_PNP_DHCP
166 166
167 If unsure, say Y. Note that if you want to use DHCP, a DHCP server 167 If unsure, say Y. Note that if you want to use DHCP, a DHCP server
168 must be operating on your network. Read 168 must be operating on your network. Read
169 <file:Documentation/filesystems/nfsroot.txt> for details. 169 <file:Documentation/filesystems/nfs/nfsroot.txt> for details.
170 170
171config IP_PNP_BOOTP 171config IP_PNP_BOOTP
172 bool "IP: BOOTP support" 172 bool "IP: BOOTP support"
@@ -181,7 +181,7 @@ config IP_PNP_BOOTP
181 does BOOTP itself, providing all necessary information on the kernel 181 does BOOTP itself, providing all necessary information on the kernel
182 command line, you can say N here. If unsure, say Y. Note that if you 182 command line, you can say N here. If unsure, say Y. Note that if you
183 want to use BOOTP, a BOOTP server must be operating on your network. 183 want to use BOOTP, a BOOTP server must be operating on your network.
184 Read <file:Documentation/filesystems/nfsroot.txt> for details. 184 Read <file:Documentation/filesystems/nfs/nfsroot.txt> for details.
185 185
186config IP_PNP_RARP 186config IP_PNP_RARP
187 bool "IP: RARP support" 187 bool "IP: RARP support"
@@ -194,7 +194,7 @@ config IP_PNP_RARP
194 older protocol which is being obsoleted by BOOTP and DHCP), say Y 194 older protocol which is being obsoleted by BOOTP and DHCP), say Y
195 here. Note that if you want to use RARP, a RARP server must be 195 here. Note that if you want to use RARP, a RARP server must be
196 operating on your network. Read 196 operating on your network. Read
197 <file:Documentation/filesystems/nfsroot.txt> for details. 197 <file:Documentation/filesystems/nfs/nfsroot.txt> for details.
198 198
199# not yet ready.. 199# not yet ready..
200# bool ' IP: ARP support' CONFIG_IP_PNP_ARP 200# bool ' IP: ARP support' CONFIG_IP_PNP_ARP
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c
index 4e08b7f2331c..10a6a604bf32 100644
--- a/net/ipv4/ipconfig.c
+++ b/net/ipv4/ipconfig.c
@@ -1446,7 +1446,7 @@ late_initcall(ip_auto_config);
1446 1446
1447/* 1447/*
1448 * Decode any IP configuration options in the "ip=" or "nfsaddrs=" kernel 1448 * Decode any IP configuration options in the "ip=" or "nfsaddrs=" kernel
1449 * command line parameter. See Documentation/filesystems/nfsroot.txt. 1449 * command line parameter. See Documentation/filesystems/nfs/nfsroot.txt.
1450 */ 1450 */
1451static int __init ic_proto_name(char *name) 1451static int __init ic_proto_name(char *name)
1452{ 1452{
diff --git a/net/socket.c b/net/socket.c
index b94c3dd71015..dbfdfa96d29b 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -355,68 +355,61 @@ static const struct dentry_operations sockfs_dentry_operations = {
355 * but we take care of internal coherence yet. 355 * but we take care of internal coherence yet.
356 */ 356 */
357 357
358static int sock_alloc_fd(struct file **filep, int flags) 358static int sock_alloc_file(struct socket *sock, struct file **f, int flags)
359{ 359{
360 struct qstr name = { .name = "" };
361 struct path path;
362 struct file *file;
360 int fd; 363 int fd;
361 364
362 fd = get_unused_fd_flags(flags); 365 fd = get_unused_fd_flags(flags);
363 if (likely(fd >= 0)) { 366 if (unlikely(fd < 0))
364 struct file *file = get_empty_filp(); 367 return fd;
365
366 *filep = file;
367 if (unlikely(!file)) {
368 put_unused_fd(fd);
369 return -ENFILE;
370 }
371 } else
372 *filep = NULL;
373 return fd;
374}
375
376static int sock_attach_fd(struct socket *sock, struct file *file, int flags)
377{
378 struct dentry *dentry;
379 struct qstr name = { .name = "" };
380 368
381 dentry = d_alloc(sock_mnt->mnt_sb->s_root, &name); 369 path.dentry = d_alloc(sock_mnt->mnt_sb->s_root, &name);
382 if (unlikely(!dentry)) 370 if (unlikely(!path.dentry)) {
371 put_unused_fd(fd);
383 return -ENOMEM; 372 return -ENOMEM;
373 }
374 path.mnt = mntget(sock_mnt);
384 375
385 dentry->d_op = &sockfs_dentry_operations; 376 path.dentry->d_op = &sockfs_dentry_operations;
386 /* 377 /*
387 * We dont want to push this dentry into global dentry hash table. 378 * We dont want to push this dentry into global dentry hash table.
388 * We pretend dentry is already hashed, by unsetting DCACHE_UNHASHED 379 * We pretend dentry is already hashed, by unsetting DCACHE_UNHASHED
389 * This permits a working /proc/$pid/fd/XXX on sockets 380 * This permits a working /proc/$pid/fd/XXX on sockets
390 */ 381 */
391 dentry->d_flags &= ~DCACHE_UNHASHED; 382 path.dentry->d_flags &= ~DCACHE_UNHASHED;
392 d_instantiate(dentry, SOCK_INODE(sock)); 383 d_instantiate(path.dentry, SOCK_INODE(sock));
384 SOCK_INODE(sock)->i_fop = &socket_file_ops;
393 385
394 sock->file = file; 386 file = alloc_file(&path, FMODE_READ | FMODE_WRITE,
395 init_file(file, sock_mnt, dentry, FMODE_READ | FMODE_WRITE,
396 &socket_file_ops); 387 &socket_file_ops);
397 SOCK_INODE(sock)->i_fop = &socket_file_ops; 388 if (unlikely(!file)) {
389 /* drop dentry, keep inode */
390 atomic_inc(&path.dentry->d_inode->i_count);
391 path_put(&path);
392 put_unused_fd(fd);
393 return -ENFILE;
394 }
395
396 sock->file = file;
398 file->f_flags = O_RDWR | (flags & O_NONBLOCK); 397 file->f_flags = O_RDWR | (flags & O_NONBLOCK);
399 file->f_pos = 0; 398 file->f_pos = 0;
400 file->private_data = sock; 399 file->private_data = sock;
401 400
402 return 0; 401 *f = file;
402 return fd;
403} 403}
404 404
405int sock_map_fd(struct socket *sock, int flags) 405int sock_map_fd(struct socket *sock, int flags)
406{ 406{
407 struct file *newfile; 407 struct file *newfile;
408 int fd = sock_alloc_fd(&newfile, flags); 408 int fd = sock_alloc_file(sock, &newfile, flags);
409
410 if (likely(fd >= 0)) {
411 int err = sock_attach_fd(sock, newfile, flags);
412 409
413 if (unlikely(err < 0)) { 410 if (likely(fd >= 0))
414 put_filp(newfile);
415 put_unused_fd(fd);
416 return err;
417 }
418 fd_install(fd, newfile); 411 fd_install(fd, newfile);
419 } 412
420 return fd; 413 return fd;
421} 414}
422 415
@@ -1390,29 +1383,19 @@ SYSCALL_DEFINE4(socketpair, int, family, int, type, int, protocol,
1390 if (err < 0) 1383 if (err < 0)
1391 goto out_release_both; 1384 goto out_release_both;
1392 1385
1393 fd1 = sock_alloc_fd(&newfile1, flags & O_CLOEXEC); 1386 fd1 = sock_alloc_file(sock1, &newfile1, flags);
1394 if (unlikely(fd1 < 0)) { 1387 if (unlikely(fd1 < 0)) {
1395 err = fd1; 1388 err = fd1;
1396 goto out_release_both; 1389 goto out_release_both;
1397 } 1390 }
1398 1391
1399 fd2 = sock_alloc_fd(&newfile2, flags & O_CLOEXEC); 1392 fd2 = sock_alloc_file(sock2, &newfile2, flags);
1400 if (unlikely(fd2 < 0)) { 1393 if (unlikely(fd2 < 0)) {
1401 err = fd2; 1394 err = fd2;
1402 put_filp(newfile1);
1403 put_unused_fd(fd1);
1404 goto out_release_both;
1405 }
1406
1407 err = sock_attach_fd(sock1, newfile1, flags & O_NONBLOCK);
1408 if (unlikely(err < 0)) {
1409 goto out_fd2;
1410 }
1411
1412 err = sock_attach_fd(sock2, newfile2, flags & O_NONBLOCK);
1413 if (unlikely(err < 0)) {
1414 fput(newfile1); 1395 fput(newfile1);
1415 goto out_fd1; 1396 put_unused_fd(fd1);
1397 sock_release(sock2);
1398 goto out;
1416 } 1399 }
1417 1400
1418 audit_fd_pair(fd1, fd2); 1401 audit_fd_pair(fd1, fd2);
@@ -1438,16 +1421,6 @@ out_release_1:
1438 sock_release(sock1); 1421 sock_release(sock1);
1439out: 1422out:
1440 return err; 1423 return err;
1441
1442out_fd2:
1443 put_filp(newfile1);
1444 sock_release(sock1);
1445out_fd1:
1446 put_filp(newfile2);
1447 sock_release(sock2);
1448 put_unused_fd(fd1);
1449 put_unused_fd(fd2);
1450 goto out;
1451} 1424}
1452 1425
1453/* 1426/*
@@ -1551,17 +1524,13 @@ SYSCALL_DEFINE4(accept4, int, fd, struct sockaddr __user *, upeer_sockaddr,
1551 */ 1524 */
1552 __module_get(newsock->ops->owner); 1525 __module_get(newsock->ops->owner);
1553 1526
1554 newfd = sock_alloc_fd(&newfile, flags & O_CLOEXEC); 1527 newfd = sock_alloc_file(newsock, &newfile, flags);
1555 if (unlikely(newfd < 0)) { 1528 if (unlikely(newfd < 0)) {
1556 err = newfd; 1529 err = newfd;
1557 sock_release(newsock); 1530 sock_release(newsock);
1558 goto out_put; 1531 goto out_put;
1559 } 1532 }
1560 1533
1561 err = sock_attach_fd(newsock, newfile, flags & O_NONBLOCK);
1562 if (err < 0)
1563 goto out_fd_simple;
1564
1565 err = security_socket_accept(sock, newsock); 1534 err = security_socket_accept(sock, newsock);
1566 if (err) 1535 if (err)
1567 goto out_fd; 1536 goto out_fd;
@@ -1591,11 +1560,6 @@ out_put:
1591 fput_light(sock->file, fput_needed); 1560 fput_light(sock->file, fput_needed);
1592out: 1561out:
1593 return err; 1562 return err;
1594out_fd_simple:
1595 sock_release(newsock);
1596 put_filp(newfile);
1597 put_unused_fd(newfd);
1598 goto out_put;
1599out_fd: 1563out_fd:
1600 fput(newfile); 1564 fput(newfile);
1601 put_unused_fd(newfd); 1565 put_unused_fd(newfd);
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index cef74ba0666c..aae6907fd546 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -210,6 +210,7 @@ void rpc_init_priority_wait_queue(struct rpc_wait_queue *queue, const char *qnam
210{ 210{
211 __rpc_init_priority_wait_queue(queue, qname, RPC_NR_PRIORITY); 211 __rpc_init_priority_wait_queue(queue, qname, RPC_NR_PRIORITY);
212} 212}
213EXPORT_SYMBOL_GPL(rpc_init_priority_wait_queue);
213 214
214void rpc_init_wait_queue(struct rpc_wait_queue *queue, const char *qname) 215void rpc_init_wait_queue(struct rpc_wait_queue *queue, const char *qname)
215{ 216{
@@ -385,6 +386,20 @@ static void rpc_wake_up_task_queue_locked(struct rpc_wait_queue *queue, struct r
385} 386}
386 387
387/* 388/*
389 * Tests whether rpc queue is empty
390 */
391int rpc_queue_empty(struct rpc_wait_queue *queue)
392{
393 int res;
394
395 spin_lock_bh(&queue->lock);
396 res = queue->qlen;
397 spin_unlock_bh(&queue->lock);
398 return (res == 0);
399}
400EXPORT_SYMBOL_GPL(rpc_queue_empty);
401
402/*
388 * Wake up a task on a specific queue 403 * Wake up a task on a specific queue
389 */ 404 */
390void rpc_wake_up_queued_task(struct rpc_wait_queue *queue, struct rpc_task *task) 405void rpc_wake_up_queued_task(struct rpc_wait_queue *queue, struct rpc_task *task)
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
index b845e2293dfe..1c924ee0a1ef 100644
--- a/net/sunrpc/svc_xprt.c
+++ b/net/sunrpc/svc_xprt.c
@@ -16,8 +16,6 @@
16 16
17#define RPCDBG_FACILITY RPCDBG_SVCXPRT 17#define RPCDBG_FACILITY RPCDBG_SVCXPRT
18 18
19#define SVC_MAX_WAKING 5
20
21static struct svc_deferred_req *svc_deferred_dequeue(struct svc_xprt *xprt); 19static struct svc_deferred_req *svc_deferred_dequeue(struct svc_xprt *xprt);
22static int svc_deferred_recv(struct svc_rqst *rqstp); 20static int svc_deferred_recv(struct svc_rqst *rqstp);
23static struct cache_deferred_req *svc_defer(struct cache_req *req); 21static struct cache_deferred_req *svc_defer(struct cache_req *req);
@@ -306,7 +304,6 @@ void svc_xprt_enqueue(struct svc_xprt *xprt)
306 struct svc_pool *pool; 304 struct svc_pool *pool;
307 struct svc_rqst *rqstp; 305 struct svc_rqst *rqstp;
308 int cpu; 306 int cpu;
309 int thread_avail;
310 307
311 if (!(xprt->xpt_flags & 308 if (!(xprt->xpt_flags &
312 ((1<<XPT_CONN)|(1<<XPT_DATA)|(1<<XPT_CLOSE)|(1<<XPT_DEFERRED)))) 309 ((1<<XPT_CONN)|(1<<XPT_DATA)|(1<<XPT_CLOSE)|(1<<XPT_DEFERRED))))
@@ -318,6 +315,12 @@ void svc_xprt_enqueue(struct svc_xprt *xprt)
318 315
319 spin_lock_bh(&pool->sp_lock); 316 spin_lock_bh(&pool->sp_lock);
320 317
318 if (!list_empty(&pool->sp_threads) &&
319 !list_empty(&pool->sp_sockets))
320 printk(KERN_ERR
321 "svc_xprt_enqueue: "
322 "threads and transports both waiting??\n");
323
321 if (test_bit(XPT_DEAD, &xprt->xpt_flags)) { 324 if (test_bit(XPT_DEAD, &xprt->xpt_flags)) {
322 /* Don't enqueue dead transports */ 325 /* Don't enqueue dead transports */
323 dprintk("svc: transport %p is dead, not enqueued\n", xprt); 326 dprintk("svc: transport %p is dead, not enqueued\n", xprt);
@@ -358,15 +361,7 @@ void svc_xprt_enqueue(struct svc_xprt *xprt)
358 } 361 }
359 362
360 process: 363 process:
361 /* Work out whether threads are available */ 364 if (!list_empty(&pool->sp_threads)) {
362 thread_avail = !list_empty(&pool->sp_threads); /* threads are asleep */
363 if (pool->sp_nwaking >= SVC_MAX_WAKING) {
364 /* too many threads are runnable and trying to wake up */
365 thread_avail = 0;
366 pool->sp_stats.overloads_avoided++;
367 }
368
369 if (thread_avail) {
370 rqstp = list_entry(pool->sp_threads.next, 365 rqstp = list_entry(pool->sp_threads.next,
371 struct svc_rqst, 366 struct svc_rqst,
372 rq_list); 367 rq_list);
@@ -381,8 +376,6 @@ void svc_xprt_enqueue(struct svc_xprt *xprt)
381 svc_xprt_get(xprt); 376 svc_xprt_get(xprt);
382 rqstp->rq_reserved = serv->sv_max_mesg; 377 rqstp->rq_reserved = serv->sv_max_mesg;
383 atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved); 378 atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved);
384 rqstp->rq_waking = 1;
385 pool->sp_nwaking++;
386 pool->sp_stats.threads_woken++; 379 pool->sp_stats.threads_woken++;
387 BUG_ON(xprt->xpt_pool != pool); 380 BUG_ON(xprt->xpt_pool != pool);
388 wake_up(&rqstp->rq_wait); 381 wake_up(&rqstp->rq_wait);
@@ -651,11 +644,6 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
651 return -EINTR; 644 return -EINTR;
652 645
653 spin_lock_bh(&pool->sp_lock); 646 spin_lock_bh(&pool->sp_lock);
654 if (rqstp->rq_waking) {
655 rqstp->rq_waking = 0;
656 pool->sp_nwaking--;
657 BUG_ON(pool->sp_nwaking < 0);
658 }
659 xprt = svc_xprt_dequeue(pool); 647 xprt = svc_xprt_dequeue(pool);
660 if (xprt) { 648 if (xprt) {
661 rqstp->rq_xprt = xprt; 649 rqstp->rq_xprt = xprt;
@@ -1204,16 +1192,15 @@ static int svc_pool_stats_show(struct seq_file *m, void *p)
1204 struct svc_pool *pool = p; 1192 struct svc_pool *pool = p;
1205 1193
1206 if (p == SEQ_START_TOKEN) { 1194 if (p == SEQ_START_TOKEN) {
1207 seq_puts(m, "# pool packets-arrived sockets-enqueued threads-woken overloads-avoided threads-timedout\n"); 1195 seq_puts(m, "# pool packets-arrived sockets-enqueued threads-woken threads-timedout\n");
1208 return 0; 1196 return 0;
1209 } 1197 }
1210 1198
1211 seq_printf(m, "%u %lu %lu %lu %lu %lu\n", 1199 seq_printf(m, "%u %lu %lu %lu %lu\n",
1212 pool->sp_id, 1200 pool->sp_id,
1213 pool->sp_stats.packets, 1201 pool->sp_stats.packets,
1214 pool->sp_stats.sockets_queued, 1202 pool->sp_stats.sockets_queued,
1215 pool->sp_stats.threads_woken, 1203 pool->sp_stats.threads_woken,
1216 pool->sp_stats.overloads_avoided,
1217 pool->sp_stats.threads_timedout); 1204 pool->sp_stats.threads_timedout);
1218 1205
1219 return 0; 1206 return 0;
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c
index 4a8f6558718a..d8c041114497 100644
--- a/net/sunrpc/svcauth_unix.c
+++ b/net/sunrpc/svcauth_unix.c
@@ -655,23 +655,25 @@ static struct unix_gid *unix_gid_lookup(uid_t uid)
655 return NULL; 655 return NULL;
656} 656}
657 657
658static int unix_gid_find(uid_t uid, struct group_info **gip, 658static struct group_info *unix_gid_find(uid_t uid, struct svc_rqst *rqstp)
659 struct svc_rqst *rqstp)
660{ 659{
661 struct unix_gid *ug = unix_gid_lookup(uid); 660 struct unix_gid *ug;
661 struct group_info *gi;
662 int ret;
663
664 ug = unix_gid_lookup(uid);
662 if (!ug) 665 if (!ug)
663 return -EAGAIN; 666 return ERR_PTR(-EAGAIN);
664 switch (cache_check(&unix_gid_cache, &ug->h, &rqstp->rq_chandle)) { 667 ret = cache_check(&unix_gid_cache, &ug->h, &rqstp->rq_chandle);
668 switch (ret) {
665 case -ENOENT: 669 case -ENOENT:
666 *gip = NULL; 670 return ERR_PTR(-ENOENT);
667 return 0;
668 case 0: 671 case 0:
669 *gip = ug->gi; 672 gi = get_group_info(ug->gi);
670 get_group_info(*gip);
671 cache_put(&ug->h, &unix_gid_cache); 673 cache_put(&ug->h, &unix_gid_cache);
672 return 0; 674 return gi;
673 default: 675 default:
674 return -EAGAIN; 676 return ERR_PTR(-EAGAIN);
675 } 677 }
676} 678}
677 679
@@ -681,6 +683,8 @@ svcauth_unix_set_client(struct svc_rqst *rqstp)
681 struct sockaddr_in *sin; 683 struct sockaddr_in *sin;
682 struct sockaddr_in6 *sin6, sin6_storage; 684 struct sockaddr_in6 *sin6, sin6_storage;
683 struct ip_map *ipm; 685 struct ip_map *ipm;
686 struct group_info *gi;
687 struct svc_cred *cred = &rqstp->rq_cred;
684 688
685 switch (rqstp->rq_addr.ss_family) { 689 switch (rqstp->rq_addr.ss_family) {
686 case AF_INET: 690 case AF_INET:
@@ -721,6 +725,17 @@ svcauth_unix_set_client(struct svc_rqst *rqstp)
721 ip_map_cached_put(rqstp, ipm); 725 ip_map_cached_put(rqstp, ipm);
722 break; 726 break;
723 } 727 }
728
729 gi = unix_gid_find(cred->cr_uid, rqstp);
730 switch (PTR_ERR(gi)) {
731 case -EAGAIN:
732 return SVC_DROP;
733 case -ENOENT:
734 break;
735 default:
736 put_group_info(cred->cr_group_info);
737 cred->cr_group_info = gi;
738 }
724 return SVC_OK; 739 return SVC_OK;
725} 740}
726 741
@@ -817,19 +832,11 @@ svcauth_unix_accept(struct svc_rqst *rqstp, __be32 *authp)
817 slen = svc_getnl(argv); /* gids length */ 832 slen = svc_getnl(argv); /* gids length */
818 if (slen > 16 || (len -= (slen + 2)*4) < 0) 833 if (slen > 16 || (len -= (slen + 2)*4) < 0)
819 goto badcred; 834 goto badcred;
820 if (unix_gid_find(cred->cr_uid, &cred->cr_group_info, rqstp) 835 cred->cr_group_info = groups_alloc(slen);
821 == -EAGAIN) 836 if (cred->cr_group_info == NULL)
822 return SVC_DROP; 837 return SVC_DROP;
823 if (cred->cr_group_info == NULL) { 838 for (i = 0; i < slen; i++)
824 cred->cr_group_info = groups_alloc(slen); 839 GROUP_AT(cred->cr_group_info, i) = svc_getnl(argv);
825 if (cred->cr_group_info == NULL)
826 return SVC_DROP;
827 for (i = 0; i < slen; i++)
828 GROUP_AT(cred->cr_group_info, i) = svc_getnl(argv);
829 } else {
830 for (i = 0; i < slen ; i++)
831 svc_getnl(argv);
832 }
833 if (svc_getu32(argv) != htonl(RPC_AUTH_NULL) || svc_getu32(argv) != 0) { 840 if (svc_getu32(argv) != htonl(RPC_AUTH_NULL) || svc_getu32(argv) != 0) {
834 *authp = rpc_autherr_badverf; 841 *authp = rpc_autherr_badverf;
835 return SVC_DENIED; 842 return SVC_DENIED;