aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc
diff options
context:
space:
mode:
Diffstat (limited to 'net/sunrpc')
-rw-r--r--net/sunrpc/cache.c66
-rw-r--r--net/sunrpc/svcauth_unix.c1
-rw-r--r--net/sunrpc/svcsock.c84
-rw-r--r--net/sunrpc/xprtrdma/svc_rdma_transport.c4
4 files changed, 100 insertions, 55 deletions
diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c
index 45cdaff9b361..ade8a7e99cd3 100644
--- a/net/sunrpc/cache.c
+++ b/net/sunrpc/cache.c
@@ -103,7 +103,7 @@ struct cache_head *sunrpc_cache_lookup(struct cache_detail *detail,
103EXPORT_SYMBOL_GPL(sunrpc_cache_lookup); 103EXPORT_SYMBOL_GPL(sunrpc_cache_lookup);
104 104
105 105
106static void queue_loose(struct cache_detail *detail, struct cache_head *ch); 106static void cache_dequeue(struct cache_detail *detail, struct cache_head *ch);
107 107
108static int cache_fresh_locked(struct cache_head *head, time_t expiry) 108static int cache_fresh_locked(struct cache_head *head, time_t expiry)
109{ 109{
@@ -119,7 +119,7 @@ static void cache_fresh_unlocked(struct cache_head *head,
119 cache_revisit_request(head); 119 cache_revisit_request(head);
120 if (test_and_clear_bit(CACHE_PENDING, &head->flags)) { 120 if (test_and_clear_bit(CACHE_PENDING, &head->flags)) {
121 cache_revisit_request(head); 121 cache_revisit_request(head);
122 queue_loose(detail, head); 122 cache_dequeue(detail, head);
123 } 123 }
124} 124}
125 125
@@ -184,6 +184,22 @@ static int cache_make_upcall(struct cache_detail *cd, struct cache_head *h)
184 return cd->cache_upcall(cd, h); 184 return cd->cache_upcall(cd, h);
185} 185}
186 186
187static inline int cache_is_valid(struct cache_detail *detail, struct cache_head *h)
188{
189 if (!test_bit(CACHE_VALID, &h->flags) ||
190 h->expiry_time < get_seconds())
191 return -EAGAIN;
192 else if (detail->flush_time > h->last_refresh)
193 return -EAGAIN;
194 else {
195 /* entry is valid */
196 if (test_bit(CACHE_NEGATIVE, &h->flags))
197 return -ENOENT;
198 else
199 return 0;
200 }
201}
202
187/* 203/*
188 * This is the generic cache management routine for all 204 * This is the generic cache management routine for all
189 * the authentication caches. 205 * the authentication caches.
@@ -192,8 +208,10 @@ static int cache_make_upcall(struct cache_detail *cd, struct cache_head *h)
192 * 208 *
193 * 209 *
194 * Returns 0 if the cache_head can be used, or cache_puts it and returns 210 * Returns 0 if the cache_head can be used, or cache_puts it and returns
195 * -EAGAIN if upcall is pending, 211 * -EAGAIN if upcall is pending and request has been queued
196 * -ETIMEDOUT if upcall failed and should be retried, 212 * -ETIMEDOUT if upcall failed or request could not be queue or
213 * upcall completed but item is still invalid (implying that
214 * the cache item has been replaced with a newer one).
197 * -ENOENT if cache entry was negative 215 * -ENOENT if cache entry was negative
198 */ 216 */
199int cache_check(struct cache_detail *detail, 217int cache_check(struct cache_detail *detail,
@@ -203,17 +221,7 @@ int cache_check(struct cache_detail *detail,
203 long refresh_age, age; 221 long refresh_age, age;
204 222
205 /* First decide return status as best we can */ 223 /* First decide return status as best we can */
206 if (!test_bit(CACHE_VALID, &h->flags) || 224 rv = cache_is_valid(detail, h);
207 h->expiry_time < get_seconds())
208 rv = -EAGAIN;
209 else if (detail->flush_time > h->last_refresh)
210 rv = -EAGAIN;
211 else {
212 /* entry is valid */
213 if (test_bit(CACHE_NEGATIVE, &h->flags))
214 rv = -ENOENT;
215 else rv = 0;
216 }
217 225
218 /* now see if we want to start an upcall */ 226 /* now see if we want to start an upcall */
219 refresh_age = (h->expiry_time - h->last_refresh); 227 refresh_age = (h->expiry_time - h->last_refresh);
@@ -229,6 +237,7 @@ int cache_check(struct cache_detail *detail,
229 switch (cache_make_upcall(detail, h)) { 237 switch (cache_make_upcall(detail, h)) {
230 case -EINVAL: 238 case -EINVAL:
231 clear_bit(CACHE_PENDING, &h->flags); 239 clear_bit(CACHE_PENDING, &h->flags);
240 cache_revisit_request(h);
232 if (rv == -EAGAIN) { 241 if (rv == -EAGAIN) {
233 set_bit(CACHE_NEGATIVE, &h->flags); 242 set_bit(CACHE_NEGATIVE, &h->flags);
234 cache_fresh_unlocked(h, detail, 243 cache_fresh_unlocked(h, detail,
@@ -245,10 +254,14 @@ int cache_check(struct cache_detail *detail,
245 } 254 }
246 } 255 }
247 256
248 if (rv == -EAGAIN) 257 if (rv == -EAGAIN) {
249 if (cache_defer_req(rqstp, h) != 0) 258 if (cache_defer_req(rqstp, h) == 0) {
250 rv = -ETIMEDOUT; 259 /* Request is not deferred */
251 260 rv = cache_is_valid(detail, h);
261 if (rv == -EAGAIN)
262 rv = -ETIMEDOUT;
263 }
264 }
252 if (rv) 265 if (rv)
253 cache_put(h, detail); 266 cache_put(h, detail);
254 return rv; 267 return rv;
@@ -396,7 +409,7 @@ static int cache_clean(void)
396 ) 409 )
397 continue; 410 continue;
398 if (test_and_clear_bit(CACHE_PENDING, &ch->flags)) 411 if (test_and_clear_bit(CACHE_PENDING, &ch->flags))
399 queue_loose(current_detail, ch); 412 cache_dequeue(current_detail, ch);
400 413
401 if (atomic_read(&ch->ref.refcount) == 1) 414 if (atomic_read(&ch->ref.refcount) == 1)
402 break; 415 break;
@@ -412,8 +425,10 @@ static int cache_clean(void)
412 if (!ch) 425 if (!ch)
413 current_index ++; 426 current_index ++;
414 spin_unlock(&cache_list_lock); 427 spin_unlock(&cache_list_lock);
415 if (ch) 428 if (ch) {
429 cache_revisit_request(ch);
416 cache_put(ch, d); 430 cache_put(ch, d);
431 }
417 } else 432 } else
418 spin_unlock(&cache_list_lock); 433 spin_unlock(&cache_list_lock);
419 434
@@ -496,11 +511,11 @@ static int cache_defer_req(struct cache_req *req, struct cache_head *item)
496 * or continue and drop the oldest below 511 * or continue and drop the oldest below
497 */ 512 */
498 if (net_random()&1) 513 if (net_random()&1)
499 return -ETIMEDOUT; 514 return 0;
500 } 515 }
501 dreq = req->defer(req); 516 dreq = req->defer(req);
502 if (dreq == NULL) 517 if (dreq == NULL)
503 return -ETIMEDOUT; 518 return 0;
504 519
505 dreq->item = item; 520 dreq->item = item;
506 521
@@ -530,8 +545,9 @@ static int cache_defer_req(struct cache_req *req, struct cache_head *item)
530 if (!test_bit(CACHE_PENDING, &item->flags)) { 545 if (!test_bit(CACHE_PENDING, &item->flags)) {
531 /* must have just been validated... */ 546 /* must have just been validated... */
532 cache_revisit_request(item); 547 cache_revisit_request(item);
548 return 0;
533 } 549 }
534 return 0; 550 return 1;
535} 551}
536 552
537static void cache_revisit_request(struct cache_head *item) 553static void cache_revisit_request(struct cache_head *item)
@@ -887,7 +903,7 @@ static int cache_release(struct inode *inode, struct file *filp,
887 903
888 904
889 905
890static void queue_loose(struct cache_detail *detail, struct cache_head *ch) 906static void cache_dequeue(struct cache_detail *detail, struct cache_head *ch)
891{ 907{
892 struct cache_queue *cq; 908 struct cache_queue *cq;
893 spin_lock(&queue_lock); 909 spin_lock(&queue_lock);
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c
index 6caffa34ac01..117f68a8aa40 100644
--- a/net/sunrpc/svcauth_unix.c
+++ b/net/sunrpc/svcauth_unix.c
@@ -668,6 +668,7 @@ static int unix_gid_find(uid_t uid, struct group_info **gip,
668 case 0: 668 case 0:
669 *gip = ug->gi; 669 *gip = ug->gi;
670 get_group_info(*gip); 670 get_group_info(*gip);
671 cache_put(&ug->h, &unix_gid_cache);
671 return 0; 672 return 0;
672 default: 673 default:
673 return -EAGAIN; 674 return -EAGAIN;
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 23128ee191ae..99a826dcc32e 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -432,29 +432,49 @@ static void svc_tcp_write_space(struct sock *sk)
432} 432}
433 433
434/* 434/*
435 * See net/ipv6/ip_sockglue.c : ip_cmsg_recv_pktinfo
436 */
437static int svc_udp_get_dest_address4(struct svc_rqst *rqstp,
438 struct cmsghdr *cmh)
439{
440 struct in_pktinfo *pki = CMSG_DATA(cmh);
441 if (cmh->cmsg_type != IP_PKTINFO)
442 return 0;
443 rqstp->rq_daddr.addr.s_addr = pki->ipi_spec_dst.s_addr;
444 return 1;
445}
446
447/*
448 * See net/ipv6/datagram.c : datagram_recv_ctl
449 */
450static int svc_udp_get_dest_address6(struct svc_rqst *rqstp,
451 struct cmsghdr *cmh)
452{
453 struct in6_pktinfo *pki = CMSG_DATA(cmh);
454 if (cmh->cmsg_type != IPV6_PKTINFO)
455 return 0;
456 ipv6_addr_copy(&rqstp->rq_daddr.addr6, &pki->ipi6_addr);
457 return 1;
458}
459
460/*
435 * Copy the UDP datagram's destination address to the rqstp structure. 461 * Copy the UDP datagram's destination address to the rqstp structure.
436 * The 'destination' address in this case is the address to which the 462 * The 'destination' address in this case is the address to which the
437 * peer sent the datagram, i.e. our local address. For multihomed 463 * peer sent the datagram, i.e. our local address. For multihomed
438 * hosts, this can change from msg to msg. Note that only the IP 464 * hosts, this can change from msg to msg. Note that only the IP
439 * address changes, the port number should remain the same. 465 * address changes, the port number should remain the same.
440 */ 466 */
441static void svc_udp_get_dest_address(struct svc_rqst *rqstp, 467static int svc_udp_get_dest_address(struct svc_rqst *rqstp,
442 struct cmsghdr *cmh) 468 struct cmsghdr *cmh)
443{ 469{
444 struct svc_sock *svsk = 470 switch (cmh->cmsg_level) {
445 container_of(rqstp->rq_xprt, struct svc_sock, sk_xprt); 471 case SOL_IP:
446 switch (svsk->sk_sk->sk_family) { 472 return svc_udp_get_dest_address4(rqstp, cmh);
447 case AF_INET: { 473 case SOL_IPV6:
448 struct in_pktinfo *pki = CMSG_DATA(cmh); 474 return svc_udp_get_dest_address6(rqstp, cmh);
449 rqstp->rq_daddr.addr.s_addr = pki->ipi_spec_dst.s_addr;
450 break;
451 }
452 case AF_INET6: {
453 struct in6_pktinfo *pki = CMSG_DATA(cmh);
454 ipv6_addr_copy(&rqstp->rq_daddr.addr6, &pki->ipi6_addr);
455 break;
456 }
457 } 475 }
476
477 return 0;
458} 478}
459 479
460/* 480/*
@@ -531,16 +551,15 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp)
531 551
532 rqstp->rq_prot = IPPROTO_UDP; 552 rqstp->rq_prot = IPPROTO_UDP;
533 553
534 if (cmh->cmsg_level != IPPROTO_IP || 554 if (!svc_udp_get_dest_address(rqstp, cmh)) {
535 cmh->cmsg_type != IP_PKTINFO) {
536 if (net_ratelimit()) 555 if (net_ratelimit())
537 printk("rpcsvc: received unknown control message:" 556 printk(KERN_WARNING
538 "%d/%d\n", 557 "svc: received unknown control message %d/%d; "
539 cmh->cmsg_level, cmh->cmsg_type); 558 "dropping RPC reply datagram\n",
559 cmh->cmsg_level, cmh->cmsg_type);
540 skb_free_datagram(svsk->sk_sk, skb); 560 skb_free_datagram(svsk->sk_sk, skb);
541 return 0; 561 return 0;
542 } 562 }
543 svc_udp_get_dest_address(rqstp, cmh);
544 563
545 if (skb_is_nonlinear(skb)) { 564 if (skb_is_nonlinear(skb)) {
546 /* we have to copy */ 565 /* we have to copy */
@@ -651,8 +670,7 @@ static struct svc_xprt_class svc_udp_class = {
651 670
652static void svc_udp_init(struct svc_sock *svsk, struct svc_serv *serv) 671static void svc_udp_init(struct svc_sock *svsk, struct svc_serv *serv)
653{ 672{
654 int one = 1; 673 int err, level, optname, one = 1;
655 mm_segment_t oldfs;
656 674
657 svc_xprt_init(&svc_udp_class, &svsk->sk_xprt, serv); 675 svc_xprt_init(&svc_udp_class, &svsk->sk_xprt, serv);
658 clear_bit(XPT_CACHE_AUTH, &svsk->sk_xprt.xpt_flags); 676 clear_bit(XPT_CACHE_AUTH, &svsk->sk_xprt.xpt_flags);
@@ -671,12 +689,22 @@ static void svc_udp_init(struct svc_sock *svsk, struct svc_serv *serv)
671 set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); 689 set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags);
672 set_bit(XPT_CHNGBUF, &svsk->sk_xprt.xpt_flags); 690 set_bit(XPT_CHNGBUF, &svsk->sk_xprt.xpt_flags);
673 691
674 oldfs = get_fs();
675 set_fs(KERNEL_DS);
676 /* make sure we get destination address info */ 692 /* make sure we get destination address info */
677 svsk->sk_sock->ops->setsockopt(svsk->sk_sock, IPPROTO_IP, IP_PKTINFO, 693 switch (svsk->sk_sk->sk_family) {
678 (char __user *)&one, sizeof(one)); 694 case AF_INET:
679 set_fs(oldfs); 695 level = SOL_IP;
696 optname = IP_PKTINFO;
697 break;
698 case AF_INET6:
699 level = SOL_IPV6;
700 optname = IPV6_RECVPKTINFO;
701 break;
702 default:
703 BUG();
704 }
705 err = kernel_setsockopt(svsk->sk_sock, level, optname,
706 (char *)&one, sizeof(one));
707 dprintk("svc: kernel_setsockopt returned %d\n", err);
680} 708}
681 709
682/* 710/*
diff --git a/net/sunrpc/xprtrdma/svc_rdma_transport.c b/net/sunrpc/xprtrdma/svc_rdma_transport.c
index 5151f9f6c573..0cf5e8c27a10 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_transport.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c
@@ -730,12 +730,12 @@ static struct svc_rdma_fastreg_mr *rdma_alloc_frmr(struct svcxprt_rdma *xprt)
730 goto err; 730 goto err;
731 731
732 mr = ib_alloc_fast_reg_mr(xprt->sc_pd, RPCSVC_MAXPAGES); 732 mr = ib_alloc_fast_reg_mr(xprt->sc_pd, RPCSVC_MAXPAGES);
733 if (!mr) 733 if (IS_ERR(mr))
734 goto err_free_frmr; 734 goto err_free_frmr;
735 735
736 pl = ib_alloc_fast_reg_page_list(xprt->sc_cm_id->device, 736 pl = ib_alloc_fast_reg_page_list(xprt->sc_cm_id->device,
737 RPCSVC_MAXPAGES); 737 RPCSVC_MAXPAGES);
738 if (!pl) 738 if (IS_ERR(pl))
739 goto err_free_mr; 739 goto err_free_mr;
740 740
741 frmr->mr = mr; 741 frmr->mr = mr;