diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-16 13:43:34 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-16 13:43:34 -0500 |
commit | 37c24b37fb2454e95136139d10bb6828967105bf (patch) | |
tree | d5c3fa61fa689567caeb2a7cb5891473e444ff7d /net/sunrpc | |
parent | 5ac4d630eb87656bd4dc313b910776d54d88ea28 (diff) | |
parent | 7663dacd926584093dfc350892792054692b6cb3 (diff) |
Merge branch 'for-2.6.33' of git://linux-nfs.org/~bfields/linux
* 'for-2.6.33' of git://linux-nfs.org/~bfields/linux: (42 commits)
nfsd: remove pointless paths in file headers
nfsd: move most of nfsfh.h to fs/nfsd
nfsd: remove unused field rq_reffh
nfsd: enable V4ROOT exports
nfsd: make V4ROOT exports read-only
nfsd: restrict filehandles accepted in V4ROOT case
nfsd: allow exports of symlinks
nfsd: filter readdir results in V4ROOT case
nfsd: filter lookup results in V4ROOT case
nfsd4: don't continue "under" mounts in V4ROOT case
nfsd: introduce export flag for v4 pseudoroot
nfsd: let "insecure" flag vary by pseudoflavor
nfsd: new interface to advertise export features
nfsd: Move private headers to source directory
vfs: nfsctl.c un-used nfsd #includes
lockd: Remove un-used nfsd headers #includes
s390: remove un-used nfsd #includes
sparc: remove un-used nfsd #includes
parsic: remove un-used nfsd #includes
compat.c: Remove dependence on nfsd private headers
...
Diffstat (limited to 'net/sunrpc')
-rw-r--r-- | net/sunrpc/svc_xprt.c | 31 | ||||
-rw-r--r-- | net/sunrpc/svcauth_unix.c | 53 |
2 files changed, 39 insertions, 45 deletions
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 | |||
21 | static struct svc_deferred_req *svc_deferred_dequeue(struct svc_xprt *xprt); | 19 | static struct svc_deferred_req *svc_deferred_dequeue(struct svc_xprt *xprt); |
22 | static int svc_deferred_recv(struct svc_rqst *rqstp); | 20 | static int svc_deferred_recv(struct svc_rqst *rqstp); |
23 | static struct cache_deferred_req *svc_defer(struct cache_req *req); | 21 | static 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 | ||
658 | static int unix_gid_find(uid_t uid, struct group_info **gip, | 658 | static 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; |