diff options
Diffstat (limited to 'net/sunrpc')
-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 39bddba53ba1..a3f340c8b79a 100644 --- a/net/sunrpc/cache.c +++ b/net/sunrpc/cache.c | |||
@@ -49,11 +49,17 @@ static void cache_init(struct cache_head *h) | |||
49 | h->last_refresh = now; | 49 | h->last_refresh = now; |
50 | } | 50 | } |
51 | 51 | ||
52 | static inline int cache_is_expired(struct cache_detail *detail, struct cache_head *h) | ||
53 | { | ||
54 | return (h->expiry_time < get_seconds()) || | ||
55 | (detail->flush_time > h->last_refresh); | ||
56 | } | ||
57 | |||
52 | struct cache_head *sunrpc_cache_lookup(struct cache_detail *detail, | 58 | struct cache_head *sunrpc_cache_lookup(struct cache_detail *detail, |
53 | struct cache_head *key, int hash) | 59 | struct cache_head *key, int hash) |
54 | { | 60 | { |
55 | struct cache_head **head, **hp; | 61 | struct cache_head **head, **hp; |
56 | struct cache_head *new = NULL; | 62 | struct cache_head *new = NULL, *freeme = NULL; |
57 | 63 | ||
58 | head = &detail->hash_table[hash]; | 64 | head = &detail->hash_table[hash]; |
59 | 65 | ||
@@ -62,6 +68,9 @@ struct cache_head *sunrpc_cache_lookup(struct cache_detail *detail, | |||
62 | for (hp=head; *hp != NULL ; hp = &(*hp)->next) { | 68 | for (hp=head; *hp != NULL ; hp = &(*hp)->next) { |
63 | struct cache_head *tmp = *hp; | 69 | struct cache_head *tmp = *hp; |
64 | if (detail->match(tmp, key)) { | 70 | if (detail->match(tmp, key)) { |
71 | if (cache_is_expired(detail, tmp)) | ||
72 | /* This entry is expired, we will discard it. */ | ||
73 | break; | ||
65 | cache_get(tmp); | 74 | cache_get(tmp); |
66 | read_unlock(&detail->hash_lock); | 75 | read_unlock(&detail->hash_lock); |
67 | return tmp; | 76 | return tmp; |
@@ -86,6 +95,13 @@ struct cache_head *sunrpc_cache_lookup(struct cache_detail *detail, | |||
86 | for (hp=head; *hp != NULL ; hp = &(*hp)->next) { | 95 | for (hp=head; *hp != NULL ; hp = &(*hp)->next) { |
87 | struct cache_head *tmp = *hp; | 96 | struct cache_head *tmp = *hp; |
88 | if (detail->match(tmp, key)) { | 97 | if (detail->match(tmp, key)) { |
98 | if (cache_is_expired(detail, tmp)) { | ||
99 | *hp = tmp->next; | ||
100 | tmp->next = NULL; | ||
101 | detail->entries --; | ||
102 | freeme = tmp; | ||
103 | break; | ||
104 | } | ||
89 | cache_get(tmp); | 105 | cache_get(tmp); |
90 | write_unlock(&detail->hash_lock); | 106 | write_unlock(&detail->hash_lock); |
91 | cache_put(new, detail); | 107 | cache_put(new, detail); |
@@ -98,6 +114,8 @@ struct cache_head *sunrpc_cache_lookup(struct cache_detail *detail, | |||
98 | cache_get(new); | 114 | cache_get(new); |
99 | write_unlock(&detail->hash_lock); | 115 | write_unlock(&detail->hash_lock); |
100 | 116 | ||
117 | if (freeme) | ||
118 | cache_put(freeme, detail); | ||
101 | return new; | 119 | return new; |
102 | } | 120 | } |
103 | EXPORT_SYMBOL_GPL(sunrpc_cache_lookup); | 121 | EXPORT_SYMBOL_GPL(sunrpc_cache_lookup); |
@@ -183,10 +201,7 @@ static int cache_make_upcall(struct cache_detail *cd, struct cache_head *h) | |||
183 | 201 | ||
184 | static inline int cache_is_valid(struct cache_detail *detail, struct cache_head *h) | 202 | static inline int cache_is_valid(struct cache_detail *detail, struct cache_head *h) |
185 | { | 203 | { |
186 | if (!test_bit(CACHE_VALID, &h->flags) || | 204 | if (!test_bit(CACHE_VALID, &h->flags)) |
187 | h->expiry_time < get_seconds()) | ||
188 | return -EAGAIN; | ||
189 | else if (detail->flush_time > h->last_refresh) | ||
190 | return -EAGAIN; | 205 | return -EAGAIN; |
191 | else { | 206 | else { |
192 | /* entry is valid */ | 207 | /* entry is valid */ |
@@ -397,31 +412,27 @@ static int cache_clean(void) | |||
397 | /* Ok, now to clean this strand */ | 412 | /* Ok, now to clean this strand */ |
398 | 413 | ||
399 | cp = & current_detail->hash_table[current_index]; | 414 | cp = & current_detail->hash_table[current_index]; |
400 | ch = *cp; | 415 | for (ch = *cp ; ch ; cp = & ch->next, ch = *cp) { |
401 | for (; ch; cp= & ch->next, ch= *cp) { | ||
402 | if (current_detail->nextcheck > ch->expiry_time) | 416 | if (current_detail->nextcheck > ch->expiry_time) |
403 | current_detail->nextcheck = ch->expiry_time+1; | 417 | current_detail->nextcheck = ch->expiry_time+1; |
404 | if (ch->expiry_time >= get_seconds() && | 418 | if (!cache_is_expired(current_detail, ch)) |
405 | ch->last_refresh >= current_detail->flush_time) | ||
406 | continue; | 419 | continue; |
407 | if (test_and_clear_bit(CACHE_PENDING, &ch->flags)) | ||
408 | cache_dequeue(current_detail, ch); | ||
409 | 420 | ||
410 | if (atomic_read(&ch->ref.refcount) == 1) | ||
411 | break; | ||
412 | } | ||
413 | if (ch) { | ||
414 | *cp = ch->next; | 421 | *cp = ch->next; |
415 | ch->next = NULL; | 422 | ch->next = NULL; |
416 | current_detail->entries--; | 423 | current_detail->entries--; |
417 | rv = 1; | 424 | rv = 1; |
425 | break; | ||
418 | } | 426 | } |
427 | |||
419 | write_unlock(¤t_detail->hash_lock); | 428 | write_unlock(¤t_detail->hash_lock); |
420 | d = current_detail; | 429 | d = current_detail; |
421 | if (!ch) | 430 | if (!ch) |
422 | current_index ++; | 431 | current_index ++; |
423 | spin_unlock(&cache_list_lock); | 432 | spin_unlock(&cache_list_lock); |
424 | if (ch) { | 433 | if (ch) { |
434 | if (test_and_clear_bit(CACHE_PENDING, &ch->flags)) | ||
435 | cache_dequeue(current_detail, ch); | ||
425 | cache_revisit_request(ch); | 436 | cache_revisit_request(ch); |
426 | cache_put(ch, d); | 437 | cache_put(ch, d); |
427 | } | 438 | } |
@@ -1233,8 +1244,10 @@ static int content_open(struct inode *inode, struct file *file, | |||
1233 | if (!cd || !try_module_get(cd->owner)) | 1244 | if (!cd || !try_module_get(cd->owner)) |
1234 | return -EACCES; | 1245 | return -EACCES; |
1235 | han = __seq_open_private(file, &cache_content_op, sizeof(*han)); | 1246 | han = __seq_open_private(file, &cache_content_op, sizeof(*han)); |
1236 | if (han == NULL) | 1247 | if (han == NULL) { |
1248 | module_put(cd->owner); | ||
1237 | return -ENOMEM; | 1249 | return -ENOMEM; |
1250 | } | ||
1238 | 1251 | ||
1239 | han->cd = cd; | 1252 | han->cd = cd; |
1240 | return 0; | 1253 | 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 | } |