diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-19 20:24:54 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-19 20:24:54 -0400 |
commit | f72caf7e496465182eeda842ac66a5e75404ddf1 (patch) | |
tree | 682e2e4b34d6240ea5dbc516d368dd14b21de182 /net | |
parent | 6a6be470c3071559970c5659354484d4f664050e (diff) | |
parent | e4e83ea47babd9d4bf95a13aed87f8ef51e46472 (diff) |
Merge branch 'for-2.6.35' of git://linux-nfs.org/~bfields/linux
* 'for-2.6.35' of git://linux-nfs.org/~bfields/linux: (45 commits)
Revert "nfsd4: distinguish expired from stale stateids"
nfsd: safer initialization order in find_file()
nfs4: minor callback code simplification, comment
NFSD: don't report compiled-out versions as present
nfsd4: implement reclaim_complete
nfsd4: nfsd4_destroy_session must set callback client under the state lock
nfsd4: keep a reference count on client while in use
nfsd4: mark_client_expired
nfsd4: introduce nfs4_client.cl_refcount
nfsd4: refactor expire_client
nfsd4: extend the client_lock to cover cl_lru
nfsd4: use list_move in move_to_confirmed
nfsd4: fold release_session into expire_client
nfsd4: rename sessionid_lock to client_lock
nfsd4: fix bare destroy_session null dereference
nfsd4: use local variable in nfs4svc_encode_compoundres
nfsd: further comment typos
sunrpc: centralise most calls to svc_xprt_received
nfsd4: fix unlikely race in session replay case
nfsd4: fix filehandle comment
...
Diffstat (limited to 'net')
-rw-r--r-- | net/sunrpc/cache.c | 45 | ||||
-rw-r--r-- | net/sunrpc/svc_xprt.c | 6 | ||||
-rw-r--r-- | net/sunrpc/svcsock.c | 15 | ||||
-rw-r--r-- | net/sunrpc/xprtrdma/svc_rdma_recvfrom.c | 3 |
4 files changed, 34 insertions, 35 deletions
diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c index 77970fe8bff2..c2173ebdb33c 100644 --- a/net/sunrpc/cache.c +++ b/net/sunrpc/cache.c | |||
@@ -50,11 +50,17 @@ static void cache_init(struct cache_head *h) | |||
50 | h->last_refresh = now; | 50 | h->last_refresh = now; |
51 | } | 51 | } |
52 | 52 | ||
53 | static inline int cache_is_expired(struct cache_detail *detail, struct cache_head *h) | ||
54 | { | ||
55 | return (h->expiry_time < get_seconds()) || | ||
56 | (detail->flush_time > h->last_refresh); | ||
57 | } | ||
58 | |||
53 | struct cache_head *sunrpc_cache_lookup(struct cache_detail *detail, | 59 | struct cache_head *sunrpc_cache_lookup(struct cache_detail *detail, |
54 | struct cache_head *key, int hash) | 60 | struct cache_head *key, int hash) |
55 | { | 61 | { |
56 | struct cache_head **head, **hp; | 62 | struct cache_head **head, **hp; |
57 | struct cache_head *new = NULL; | 63 | struct cache_head *new = NULL, *freeme = NULL; |
58 | 64 | ||
59 | head = &detail->hash_table[hash]; | 65 | head = &detail->hash_table[hash]; |
60 | 66 | ||
@@ -63,6 +69,9 @@ struct cache_head *sunrpc_cache_lookup(struct cache_detail *detail, | |||
63 | for (hp=head; *hp != NULL ; hp = &(*hp)->next) { | 69 | for (hp=head; *hp != NULL ; hp = &(*hp)->next) { |
64 | struct cache_head *tmp = *hp; | 70 | struct cache_head *tmp = *hp; |
65 | if (detail->match(tmp, key)) { | 71 | if (detail->match(tmp, key)) { |
72 | if (cache_is_expired(detail, tmp)) | ||
73 | /* This entry is expired, we will discard it. */ | ||
74 | break; | ||
66 | cache_get(tmp); | 75 | cache_get(tmp); |
67 | read_unlock(&detail->hash_lock); | 76 | read_unlock(&detail->hash_lock); |
68 | return tmp; | 77 | return tmp; |
@@ -87,6 +96,13 @@ struct cache_head *sunrpc_cache_lookup(struct cache_detail *detail, | |||
87 | for (hp=head; *hp != NULL ; hp = &(*hp)->next) { | 96 | for (hp=head; *hp != NULL ; hp = &(*hp)->next) { |
88 | struct cache_head *tmp = *hp; | 97 | struct cache_head *tmp = *hp; |
89 | if (detail->match(tmp, key)) { | 98 | if (detail->match(tmp, key)) { |
99 | if (cache_is_expired(detail, tmp)) { | ||
100 | *hp = tmp->next; | ||
101 | tmp->next = NULL; | ||
102 | detail->entries --; | ||
103 | freeme = tmp; | ||
104 | break; | ||
105 | } | ||
90 | cache_get(tmp); | 106 | cache_get(tmp); |
91 | write_unlock(&detail->hash_lock); | 107 | write_unlock(&detail->hash_lock); |
92 | cache_put(new, detail); | 108 | cache_put(new, detail); |
@@ -99,6 +115,8 @@ struct cache_head *sunrpc_cache_lookup(struct cache_detail *detail, | |||
99 | cache_get(new); | 115 | cache_get(new); |
100 | write_unlock(&detail->hash_lock); | 116 | write_unlock(&detail->hash_lock); |
101 | 117 | ||
118 | if (freeme) | ||
119 | cache_put(freeme, detail); | ||
102 | return new; | 120 | return new; |
103 | } | 121 | } |
104 | EXPORT_SYMBOL_GPL(sunrpc_cache_lookup); | 122 | EXPORT_SYMBOL_GPL(sunrpc_cache_lookup); |
@@ -184,10 +202,7 @@ static int cache_make_upcall(struct cache_detail *cd, struct cache_head *h) | |||
184 | 202 | ||
185 | static inline int cache_is_valid(struct cache_detail *detail, struct cache_head *h) | 203 | static inline int cache_is_valid(struct cache_detail *detail, struct cache_head *h) |
186 | { | 204 | { |
187 | if (!test_bit(CACHE_VALID, &h->flags) || | 205 | if (!test_bit(CACHE_VALID, &h->flags)) |
188 | h->expiry_time < get_seconds()) | ||
189 | return -EAGAIN; | ||
190 | else if (detail->flush_time > h->last_refresh) | ||
191 | return -EAGAIN; | 206 | return -EAGAIN; |
192 | else { | 207 | else { |
193 | /* entry is valid */ | 208 | /* entry is valid */ |
@@ -398,31 +413,27 @@ static int cache_clean(void) | |||
398 | /* Ok, now to clean this strand */ | 413 | /* Ok, now to clean this strand */ |
399 | 414 | ||
400 | cp = & current_detail->hash_table[current_index]; | 415 | cp = & current_detail->hash_table[current_index]; |
401 | ch = *cp; | 416 | for (ch = *cp ; ch ; cp = & ch->next, ch = *cp) { |
402 | for (; ch; cp= & ch->next, ch= *cp) { | ||
403 | if (current_detail->nextcheck > ch->expiry_time) | 417 | if (current_detail->nextcheck > ch->expiry_time) |
404 | current_detail->nextcheck = ch->expiry_time+1; | 418 | current_detail->nextcheck = ch->expiry_time+1; |
405 | if (ch->expiry_time >= get_seconds() && | 419 | if (!cache_is_expired(current_detail, ch)) |
406 | ch->last_refresh >= current_detail->flush_time) | ||
407 | continue; | 420 | continue; |
408 | if (test_and_clear_bit(CACHE_PENDING, &ch->flags)) | ||
409 | cache_dequeue(current_detail, ch); | ||
410 | 421 | ||
411 | if (atomic_read(&ch->ref.refcount) == 1) | ||
412 | break; | ||
413 | } | ||
414 | if (ch) { | ||
415 | *cp = ch->next; | 422 | *cp = ch->next; |
416 | ch->next = NULL; | 423 | ch->next = NULL; |
417 | current_detail->entries--; | 424 | current_detail->entries--; |
418 | rv = 1; | 425 | rv = 1; |
426 | break; | ||
419 | } | 427 | } |
428 | |||
420 | write_unlock(¤t_detail->hash_lock); | 429 | write_unlock(¤t_detail->hash_lock); |
421 | d = current_detail; | 430 | d = current_detail; |
422 | if (!ch) | 431 | if (!ch) |
423 | current_index ++; | 432 | current_index ++; |
424 | spin_unlock(&cache_list_lock); | 433 | spin_unlock(&cache_list_lock); |
425 | if (ch) { | 434 | if (ch) { |
435 | if (test_and_clear_bit(CACHE_PENDING, &ch->flags)) | ||
436 | cache_dequeue(current_detail, ch); | ||
426 | cache_revisit_request(ch); | 437 | cache_revisit_request(ch); |
427 | cache_put(ch, d); | 438 | cache_put(ch, d); |
428 | } | 439 | } |
@@ -1234,8 +1245,10 @@ static int content_open(struct inode *inode, struct file *file, | |||
1234 | if (!cd || !try_module_get(cd->owner)) | 1245 | if (!cd || !try_module_get(cd->owner)) |
1235 | return -EACCES; | 1246 | return -EACCES; |
1236 | han = __seq_open_private(file, &cache_content_op, sizeof(*han)); | 1247 | han = __seq_open_private(file, &cache_content_op, sizeof(*han)); |
1237 | if (han == NULL) | 1248 | if (han == NULL) { |
1249 | module_put(cd->owner); | ||
1238 | return -ENOMEM; | 1250 | return -ENOMEM; |
1251 | } | ||
1239 | 1252 | ||
1240 | han->cd = cd; | 1253 | han->cd = cd; |
1241 | return 0; | 1254 | return 0; |
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index 061b2e0f9118..cbc084939dd8 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c | |||
@@ -744,8 +744,10 @@ int svc_recv(struct svc_rqst *rqstp, long timeout) | |||
744 | if (rqstp->rq_deferred) { | 744 | if (rqstp->rq_deferred) { |
745 | svc_xprt_received(xprt); | 745 | svc_xprt_received(xprt); |
746 | len = svc_deferred_recv(rqstp); | 746 | len = svc_deferred_recv(rqstp); |
747 | } else | 747 | } else { |
748 | len = xprt->xpt_ops->xpo_recvfrom(rqstp); | 748 | len = xprt->xpt_ops->xpo_recvfrom(rqstp); |
749 | svc_xprt_received(xprt); | ||
750 | } | ||
749 | dprintk("svc: got len=%d\n", len); | 751 | dprintk("svc: got len=%d\n", len); |
750 | } | 752 | } |
751 | 753 | ||
@@ -893,12 +895,12 @@ void svc_delete_xprt(struct svc_xprt *xprt) | |||
893 | */ | 895 | */ |
894 | if (test_bit(XPT_TEMP, &xprt->xpt_flags)) | 896 | if (test_bit(XPT_TEMP, &xprt->xpt_flags)) |
895 | serv->sv_tmpcnt--; | 897 | serv->sv_tmpcnt--; |
898 | spin_unlock_bh(&serv->sv_lock); | ||
896 | 899 | ||
897 | while ((dr = svc_deferred_dequeue(xprt)) != NULL) | 900 | while ((dr = svc_deferred_dequeue(xprt)) != NULL) |
898 | kfree(dr); | 901 | kfree(dr); |
899 | 902 | ||
900 | svc_xprt_put(xprt); | 903 | svc_xprt_put(xprt); |
901 | spin_unlock_bh(&serv->sv_lock); | ||
902 | } | 904 | } |
903 | 905 | ||
904 | void svc_close_xprt(struct svc_xprt *xprt) | 906 | void svc_close_xprt(struct svc_xprt *xprt) |
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index a29f259204e6..a33892733643 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c | |||
@@ -547,7 +547,6 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp) | |||
547 | dprintk("svc: recvfrom returned error %d\n", -err); | 547 | dprintk("svc: recvfrom returned error %d\n", -err); |
548 | set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); | 548 | set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); |
549 | } | 549 | } |
550 | svc_xprt_received(&svsk->sk_xprt); | ||
551 | return -EAGAIN; | 550 | return -EAGAIN; |
552 | } | 551 | } |
553 | len = svc_addr_len(svc_addr(rqstp)); | 552 | len = svc_addr_len(svc_addr(rqstp)); |
@@ -562,11 +561,6 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp) | |||
562 | svsk->sk_sk->sk_stamp = skb->tstamp; | 561 | svsk->sk_sk->sk_stamp = skb->tstamp; |
563 | set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); /* there may be more data... */ | 562 | set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); /* there may be more data... */ |
564 | 563 | ||
565 | /* | ||
566 | * Maybe more packets - kick another thread ASAP. | ||
567 | */ | ||
568 | svc_xprt_received(&svsk->sk_xprt); | ||
569 | |||
570 | len = skb->len - sizeof(struct udphdr); | 564 | len = skb->len - sizeof(struct udphdr); |
571 | rqstp->rq_arg.len = len; | 565 | rqstp->rq_arg.len = len; |
572 | 566 | ||
@@ -917,7 +911,6 @@ static int svc_tcp_recv_record(struct svc_sock *svsk, struct svc_rqst *rqstp) | |||
917 | if (len < want) { | 911 | if (len < want) { |
918 | dprintk("svc: short recvfrom while reading record " | 912 | dprintk("svc: short recvfrom while reading record " |
919 | "length (%d of %d)\n", len, want); | 913 | "length (%d of %d)\n", len, want); |
920 | svc_xprt_received(&svsk->sk_xprt); | ||
921 | goto err_again; /* record header not complete */ | 914 | goto err_again; /* record header not complete */ |
922 | } | 915 | } |
923 | 916 | ||
@@ -953,7 +946,6 @@ static int svc_tcp_recv_record(struct svc_sock *svsk, struct svc_rqst *rqstp) | |||
953 | if (len < svsk->sk_reclen) { | 946 | if (len < svsk->sk_reclen) { |
954 | dprintk("svc: incomplete TCP record (%d of %d)\n", | 947 | dprintk("svc: incomplete TCP record (%d of %d)\n", |
955 | len, svsk->sk_reclen); | 948 | len, svsk->sk_reclen); |
956 | svc_xprt_received(&svsk->sk_xprt); | ||
957 | goto err_again; /* record not complete */ | 949 | goto err_again; /* record not complete */ |
958 | } | 950 | } |
959 | len = svsk->sk_reclen; | 951 | len = svsk->sk_reclen; |
@@ -961,14 +953,11 @@ static int svc_tcp_recv_record(struct svc_sock *svsk, struct svc_rqst *rqstp) | |||
961 | 953 | ||
962 | return len; | 954 | return len; |
963 | error: | 955 | error: |
964 | if (len == -EAGAIN) { | 956 | if (len == -EAGAIN) |
965 | dprintk("RPC: TCP recv_record got EAGAIN\n"); | 957 | dprintk("RPC: TCP recv_record got EAGAIN\n"); |
966 | svc_xprt_received(&svsk->sk_xprt); | ||
967 | } | ||
968 | return len; | 958 | return len; |
969 | err_delete: | 959 | err_delete: |
970 | set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags); | 960 | set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags); |
971 | svc_xprt_received(&svsk->sk_xprt); | ||
972 | err_again: | 961 | err_again: |
973 | return -EAGAIN; | 962 | return -EAGAIN; |
974 | } | 963 | } |
@@ -1110,7 +1099,6 @@ out: | |||
1110 | svsk->sk_tcplen = 0; | 1099 | svsk->sk_tcplen = 0; |
1111 | 1100 | ||
1112 | svc_xprt_copy_addrs(rqstp, &svsk->sk_xprt); | 1101 | svc_xprt_copy_addrs(rqstp, &svsk->sk_xprt); |
1113 | svc_xprt_received(&svsk->sk_xprt); | ||
1114 | if (serv->sv_stats) | 1102 | if (serv->sv_stats) |
1115 | serv->sv_stats->nettcpcnt++; | 1103 | serv->sv_stats->nettcpcnt++; |
1116 | 1104 | ||
@@ -1119,7 +1107,6 @@ out: | |||
1119 | err_again: | 1107 | err_again: |
1120 | if (len == -EAGAIN) { | 1108 | if (len == -EAGAIN) { |
1121 | dprintk("RPC: TCP recvfrom got EAGAIN\n"); | 1109 | dprintk("RPC: TCP recvfrom got EAGAIN\n"); |
1122 | svc_xprt_received(&svsk->sk_xprt); | ||
1123 | return len; | 1110 | return len; |
1124 | } | 1111 | } |
1125 | error: | 1112 | error: |
diff --git a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c index f92e37eb413c..0194de814933 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c +++ b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c | |||
@@ -566,7 +566,6 @@ static int rdma_read_complete(struct svc_rqst *rqstp, | |||
566 | ret, rqstp->rq_arg.len, rqstp->rq_arg.head[0].iov_base, | 566 | ret, rqstp->rq_arg.len, rqstp->rq_arg.head[0].iov_base, |
567 | rqstp->rq_arg.head[0].iov_len); | 567 | rqstp->rq_arg.head[0].iov_len); |
568 | 568 | ||
569 | svc_xprt_received(rqstp->rq_xprt); | ||
570 | return ret; | 569 | return ret; |
571 | } | 570 | } |
572 | 571 | ||
@@ -665,7 +664,6 @@ int svc_rdma_recvfrom(struct svc_rqst *rqstp) | |||
665 | rqstp->rq_arg.head[0].iov_len); | 664 | rqstp->rq_arg.head[0].iov_len); |
666 | rqstp->rq_prot = IPPROTO_MAX; | 665 | rqstp->rq_prot = IPPROTO_MAX; |
667 | svc_xprt_copy_addrs(rqstp, xprt); | 666 | svc_xprt_copy_addrs(rqstp, xprt); |
668 | svc_xprt_received(xprt); | ||
669 | return ret; | 667 | return ret; |
670 | 668 | ||
671 | close_out: | 669 | close_out: |
@@ -678,6 +676,5 @@ int svc_rdma_recvfrom(struct svc_rqst *rqstp) | |||
678 | */ | 676 | */ |
679 | set_bit(XPT_CLOSE, &xprt->xpt_flags); | 677 | set_bit(XPT_CLOSE, &xprt->xpt_flags); |
680 | defer: | 678 | defer: |
681 | svc_xprt_received(xprt); | ||
682 | return 0; | 679 | return 0; |
683 | } | 680 | } |