aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-02-28 21:02:55 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-02-28 21:02:55 -0500
commitb6669737d3db7df79fad07180837c23dbe581db5 (patch)
tree671a9d13fe5ab00d6a3c7c5c5c466802ca96d38a
parent1cf0209c431fa7790253c532039d53b0773193aa (diff)
parentdc107402ae06286a9ed33c32daf3f35514a7cb8d (diff)
Merge branch 'for-3.9' of git://linux-nfs.org/~bfields/linux
Pull nfsd changes from J Bruce Fields: "Miscellaneous bugfixes, plus: - An overhaul of the DRC cache by Jeff Layton. The main effect is just to make it larger. This decreases the chances of intermittent errors especially in the UDP case. But we'll need to watch for any reports of performance regressions. - Containerized nfsd: with some limitations, we now support per-container nfs-service, thanks to extensive work from Stanislav Kinsbursky over the last year." Some notes about conflicts, since there were *two* non-data semantic conflicts here: - idr_remove_all() had been added by a memory leak fix, but has since become deprecated since idr_destroy() does it for us now. - xs_local_connect() had been added by this branch to make AF_LOCAL connections be synchronous, but in the meantime Trond had changed the calling convention in order to avoid a RCU dereference. There were a couple of more obvious actual source-level conflicts due to the hlist traversal changes and one just due to code changes next to each other, but those were trivial. * 'for-3.9' of git://linux-nfs.org/~bfields/linux: (49 commits) SUNRPC: make AF_LOCAL connect synchronous nfsd: fix compiler warning about ambiguous types in nfsd_cache_csum svcrpc: fix rpc server shutdown races svcrpc: make svc_age_temp_xprts enqueue under sv_lock lockd: nlmclnt_reclaim(): avoid stack overflow nfsd: enable NFSv4 state in containers nfsd: disable usermode helper client tracker in container nfsd: use proper net while reading "exports" file nfsd: containerize NFSd filesystem nfsd: fix comments on nfsd_cache_lookup SUNRPC: move cache_detail->cache_request callback call to cache_read() SUNRPC: remove "cache_request" argument in sunrpc_cache_pipe_upcall() function SUNRPC: rework cache upcall logic SUNRPC: introduce cache_detail->cache_request callback NFS: simplify and clean cache library NFS: use SUNRPC cache creation and destruction helper for DNS cache nfsd4: free_stid can be static nfsd: keep a checksum of the first 256 bytes of request sunrpc: trim off trailing checksum before returning decrypted or integrity authenticated buffer sunrpc: fix comment in struct xdr_buf definition ...
-rw-r--r--fs/lockd/clntlock.c14
-rw-r--r--fs/lockd/clntproc.c6
-rw-r--r--fs/lockd/host.c1
-rw-r--r--fs/lockd/mon.c1
-rw-r--r--fs/lockd/svcsubs.c2
-rw-r--r--fs/nfs/cache_lib.c12
-rw-r--r--fs/nfs/cache_lib.h2
-rw-r--r--fs/nfs/dns_resolve.c67
-rw-r--r--fs/nfs/nfs4client.c1
-rw-r--r--fs/nfs/nfs4filelayoutdev.c1
-rw-r--r--fs/nfs/nfs4namespace.c1
-rw-r--r--fs/nfs/super.c1
-rw-r--r--fs/nfsd/cache.h17
-rw-r--r--fs/nfsd/export.c16
-rw-r--r--fs/nfsd/fault_inject.c2
-rw-r--r--fs/nfsd/nfs4idmap.c16
-rw-r--r--fs/nfsd/nfs4proc.c7
-rw-r--r--fs/nfsd/nfs4recover.c6
-rw-r--r--fs/nfsd/nfs4state.c101
-rw-r--r--fs/nfsd/nfs4xdr.c21
-rw-r--r--fs/nfsd/nfscache.c352
-rw-r--r--fs/nfsd/nfsctl.c81
-rw-r--r--fs/nfsd/nfssvc.c6
-rw-r--r--fs/nfsd/xdr4.h2
-rw-r--r--include/linux/lockd/lockd.h3
-rw-r--r--include/linux/sunrpc/addr.h170
-rw-r--r--include/linux/sunrpc/cache.h10
-rw-r--r--include/linux/sunrpc/clnt.h152
-rw-r--r--include/linux/sunrpc/svc.h1
-rw-r--r--include/linux/sunrpc/xdr.h3
-rw-r--r--net/sunrpc/addr.c3
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_wrap.c2
-rw-r--r--net/sunrpc/auth_gss/svcauth_gss.c18
-rw-r--r--net/sunrpc/cache.c51
-rw-r--r--net/sunrpc/clnt.c1
-rw-r--r--net/sunrpc/rpcb_clnt.c1
-rw-r--r--net/sunrpc/svc.c13
-rw-r--r--net/sunrpc/svc_xprt.c81
-rw-r--r--net/sunrpc/svcauth_unix.c16
-rw-r--r--net/sunrpc/xdr.c41
-rw-r--r--net/sunrpc/xprtrdma/transport.c1
-rw-r--r--net/sunrpc/xprtsock.c35
42 files changed, 831 insertions, 507 deletions
diff --git a/fs/lockd/clntlock.c b/fs/lockd/clntlock.c
index a2717408c478..0796c45d0d4d 100644
--- a/fs/lockd/clntlock.c
+++ b/fs/lockd/clntlock.c
@@ -11,7 +11,7 @@
11#include <linux/slab.h> 11#include <linux/slab.h>
12#include <linux/time.h> 12#include <linux/time.h>
13#include <linux/nfs_fs.h> 13#include <linux/nfs_fs.h>
14#include <linux/sunrpc/clnt.h> 14#include <linux/sunrpc/addr.h>
15#include <linux/sunrpc/svc.h> 15#include <linux/sunrpc/svc.h>
16#include <linux/lockd/lockd.h> 16#include <linux/lockd/lockd.h>
17#include <linux/kthread.h> 17#include <linux/kthread.h>
@@ -220,10 +220,19 @@ reclaimer(void *ptr)
220{ 220{
221 struct nlm_host *host = (struct nlm_host *) ptr; 221 struct nlm_host *host = (struct nlm_host *) ptr;
222 struct nlm_wait *block; 222 struct nlm_wait *block;
223 struct nlm_rqst *req;
223 struct file_lock *fl, *next; 224 struct file_lock *fl, *next;
224 u32 nsmstate; 225 u32 nsmstate;
225 struct net *net = host->net; 226 struct net *net = host->net;
226 227
228 req = kmalloc(sizeof(*req), GFP_KERNEL);
229 if (!req) {
230 printk(KERN_ERR "lockd: reclaimer unable to alloc memory."
231 " Locks for %s won't be reclaimed!\n",
232 host->h_name);
233 return 0;
234 }
235
227 allow_signal(SIGKILL); 236 allow_signal(SIGKILL);
228 237
229 down_write(&host->h_rwsem); 238 down_write(&host->h_rwsem);
@@ -253,7 +262,7 @@ restart:
253 */ 262 */
254 if (signalled()) 263 if (signalled())
255 continue; 264 continue;
256 if (nlmclnt_reclaim(host, fl) != 0) 265 if (nlmclnt_reclaim(host, fl, req) != 0)
257 continue; 266 continue;
258 list_add_tail(&fl->fl_u.nfs_fl.list, &host->h_granted); 267 list_add_tail(&fl->fl_u.nfs_fl.list, &host->h_granted);
259 if (host->h_nsmstate != nsmstate) { 268 if (host->h_nsmstate != nsmstate) {
@@ -279,5 +288,6 @@ restart:
279 /* Release host handle after use */ 288 /* Release host handle after use */
280 nlmclnt_release_host(host); 289 nlmclnt_release_host(host);
281 lockd_down(net); 290 lockd_down(net);
291 kfree(req);
282 return 0; 292 return 0;
283} 293}
diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c
index 366277190b82..7e529c3c45c0 100644
--- a/fs/lockd/clntproc.c
+++ b/fs/lockd/clntproc.c
@@ -618,17 +618,15 @@ out_unlock:
618 * RECLAIM: Try to reclaim a lock 618 * RECLAIM: Try to reclaim a lock
619 */ 619 */
620int 620int
621nlmclnt_reclaim(struct nlm_host *host, struct file_lock *fl) 621nlmclnt_reclaim(struct nlm_host *host, struct file_lock *fl,
622 struct nlm_rqst *req)
622{ 623{
623 struct nlm_rqst reqst, *req;
624 int status; 624 int status;
625 625
626 req = &reqst;
627 memset(req, 0, sizeof(*req)); 626 memset(req, 0, sizeof(*req));
628 locks_init_lock(&req->a_args.lock.fl); 627 locks_init_lock(&req->a_args.lock.fl);
629 locks_init_lock(&req->a_res.lock.fl); 628 locks_init_lock(&req->a_res.lock.fl);
630 req->a_host = host; 629 req->a_host = host;
631 req->a_flags = 0;
632 630
633 /* Set up the argument struct */ 631 /* Set up the argument struct */
634 nlmclnt_setlockargs(req, fl); 632 nlmclnt_setlockargs(req, fl);
diff --git a/fs/lockd/host.c b/fs/lockd/host.c
index abdd75d44dd4..969d589c848d 100644
--- a/fs/lockd/host.c
+++ b/fs/lockd/host.c
@@ -13,6 +13,7 @@
13#include <linux/in.h> 13#include <linux/in.h>
14#include <linux/in6.h> 14#include <linux/in6.h>
15#include <linux/sunrpc/clnt.h> 15#include <linux/sunrpc/clnt.h>
16#include <linux/sunrpc/addr.h>
16#include <linux/sunrpc/svc.h> 17#include <linux/sunrpc/svc.h>
17#include <linux/lockd/lockd.h> 18#include <linux/lockd/lockd.h>
18#include <linux/mutex.h> 19#include <linux/mutex.h>
diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c
index 3c2cfc683631..1812f026960c 100644
--- a/fs/lockd/mon.c
+++ b/fs/lockd/mon.c
@@ -12,6 +12,7 @@
12#include <linux/slab.h> 12#include <linux/slab.h>
13 13
14#include <linux/sunrpc/clnt.h> 14#include <linux/sunrpc/clnt.h>
15#include <linux/sunrpc/addr.h>
15#include <linux/sunrpc/xprtsock.h> 16#include <linux/sunrpc/xprtsock.h>
16#include <linux/sunrpc/svc.h> 17#include <linux/sunrpc/svc.h>
17#include <linux/lockd/lockd.h> 18#include <linux/lockd/lockd.h>
diff --git a/fs/lockd/svcsubs.c b/fs/lockd/svcsubs.c
index d17bb62b06d6..97e87415b145 100644
--- a/fs/lockd/svcsubs.c
+++ b/fs/lockd/svcsubs.c
@@ -13,7 +13,7 @@
13#include <linux/slab.h> 13#include <linux/slab.h>
14#include <linux/mutex.h> 14#include <linux/mutex.h>
15#include <linux/sunrpc/svc.h> 15#include <linux/sunrpc/svc.h>
16#include <linux/sunrpc/clnt.h> 16#include <linux/sunrpc/addr.h>
17#include <linux/nfsd/nfsfh.h> 17#include <linux/nfsd/nfsfh.h>
18#include <linux/nfsd/export.h> 18#include <linux/nfsd/export.h>
19#include <linux/lockd/lockd.h> 19#include <linux/lockd/lockd.h>
diff --git a/fs/nfs/cache_lib.c b/fs/nfs/cache_lib.c
index 862a2f16db64..5f7b053720ee 100644
--- a/fs/nfs/cache_lib.c
+++ b/fs/nfs/cache_lib.c
@@ -128,10 +128,13 @@ int nfs_cache_register_net(struct net *net, struct cache_detail *cd)
128 struct super_block *pipefs_sb; 128 struct super_block *pipefs_sb;
129 int ret = 0; 129 int ret = 0;
130 130
131 sunrpc_init_cache_detail(cd);
131 pipefs_sb = rpc_get_sb_net(net); 132 pipefs_sb = rpc_get_sb_net(net);
132 if (pipefs_sb) { 133 if (pipefs_sb) {
133 ret = nfs_cache_register_sb(pipefs_sb, cd); 134 ret = nfs_cache_register_sb(pipefs_sb, cd);
134 rpc_put_sb_net(net); 135 rpc_put_sb_net(net);
136 if (ret)
137 sunrpc_destroy_cache_detail(cd);
135 } 138 }
136 return ret; 139 return ret;
137} 140}
@@ -151,14 +154,5 @@ void nfs_cache_unregister_net(struct net *net, struct cache_detail *cd)
151 nfs_cache_unregister_sb(pipefs_sb, cd); 154 nfs_cache_unregister_sb(pipefs_sb, cd);
152 rpc_put_sb_net(net); 155 rpc_put_sb_net(net);
153 } 156 }
154}
155
156void nfs_cache_init(struct cache_detail *cd)
157{
158 sunrpc_init_cache_detail(cd);
159}
160
161void nfs_cache_destroy(struct cache_detail *cd)
162{
163 sunrpc_destroy_cache_detail(cd); 157 sunrpc_destroy_cache_detail(cd);
164} 158}
diff --git a/fs/nfs/cache_lib.h b/fs/nfs/cache_lib.h
index 317db95e37f8..4116d2c3f52f 100644
--- a/fs/nfs/cache_lib.h
+++ b/fs/nfs/cache_lib.h
@@ -23,8 +23,6 @@ extern struct nfs_cache_defer_req *nfs_cache_defer_req_alloc(void);
23extern void nfs_cache_defer_req_put(struct nfs_cache_defer_req *dreq); 23extern void nfs_cache_defer_req_put(struct nfs_cache_defer_req *dreq);
24extern int nfs_cache_wait_for_upcall(struct nfs_cache_defer_req *dreq); 24extern int nfs_cache_wait_for_upcall(struct nfs_cache_defer_req *dreq);
25 25
26extern void nfs_cache_init(struct cache_detail *cd);
27extern void nfs_cache_destroy(struct cache_detail *cd);
28extern int nfs_cache_register_net(struct net *net, struct cache_detail *cd); 26extern int nfs_cache_register_net(struct net *net, struct cache_detail *cd);
29extern void nfs_cache_unregister_net(struct net *net, struct cache_detail *cd); 27extern void nfs_cache_unregister_net(struct net *net, struct cache_detail *cd);
30extern int nfs_cache_register_sb(struct super_block *sb, 28extern int nfs_cache_register_sb(struct super_block *sb,
diff --git a/fs/nfs/dns_resolve.c b/fs/nfs/dns_resolve.c
index ca4b11ec87a2..945527092295 100644
--- a/fs/nfs/dns_resolve.c
+++ b/fs/nfs/dns_resolve.c
@@ -10,6 +10,7 @@
10 10
11#include <linux/module.h> 11#include <linux/module.h>
12#include <linux/sunrpc/clnt.h> 12#include <linux/sunrpc/clnt.h>
13#include <linux/sunrpc/addr.h>
13#include <linux/dns_resolver.h> 14#include <linux/dns_resolver.h>
14#include "dns_resolve.h" 15#include "dns_resolve.h"
15 16
@@ -42,6 +43,7 @@ EXPORT_SYMBOL_GPL(nfs_dns_resolve_name);
42#include <linux/seq_file.h> 43#include <linux/seq_file.h>
43#include <linux/inet.h> 44#include <linux/inet.h>
44#include <linux/sunrpc/clnt.h> 45#include <linux/sunrpc/clnt.h>
46#include <linux/sunrpc/addr.h>
45#include <linux/sunrpc/cache.h> 47#include <linux/sunrpc/cache.h>
46#include <linux/sunrpc/svcauth.h> 48#include <linux/sunrpc/svcauth.h>
47#include <linux/sunrpc/rpc_pipe_fs.h> 49#include <linux/sunrpc/rpc_pipe_fs.h>
@@ -142,7 +144,7 @@ static int nfs_dns_upcall(struct cache_detail *cd,
142 144
143 ret = nfs_cache_upcall(cd, key->hostname); 145 ret = nfs_cache_upcall(cd, key->hostname);
144 if (ret) 146 if (ret)
145 ret = sunrpc_cache_pipe_upcall(cd, ch, nfs_dns_request); 147 ret = sunrpc_cache_pipe_upcall(cd, ch);
146 return ret; 148 return ret;
147} 149}
148 150
@@ -351,60 +353,47 @@ ssize_t nfs_dns_resolve_name(struct net *net, char *name,
351} 353}
352EXPORT_SYMBOL_GPL(nfs_dns_resolve_name); 354EXPORT_SYMBOL_GPL(nfs_dns_resolve_name);
353 355
356static struct cache_detail nfs_dns_resolve_template = {
357 .owner = THIS_MODULE,
358 .hash_size = NFS_DNS_HASHTBL_SIZE,
359 .name = "dns_resolve",
360 .cache_put = nfs_dns_ent_put,
361 .cache_upcall = nfs_dns_upcall,
362 .cache_request = nfs_dns_request,
363 .cache_parse = nfs_dns_parse,
364 .cache_show = nfs_dns_show,
365 .match = nfs_dns_match,
366 .init = nfs_dns_ent_init,
367 .update = nfs_dns_ent_update,
368 .alloc = nfs_dns_ent_alloc,
369};
370
371
354int nfs_dns_resolver_cache_init(struct net *net) 372int nfs_dns_resolver_cache_init(struct net *net)
355{ 373{
356 int err = -ENOMEM; 374 int err;
357 struct nfs_net *nn = net_generic(net, nfs_net_id); 375 struct nfs_net *nn = net_generic(net, nfs_net_id);
358 struct cache_detail *cd;
359 struct cache_head **tbl;
360 376
361 cd = kzalloc(sizeof(struct cache_detail), GFP_KERNEL); 377 nn->nfs_dns_resolve = cache_create_net(&nfs_dns_resolve_template, net);
362 if (cd == NULL) 378 if (IS_ERR(nn->nfs_dns_resolve))
363 goto err_cd; 379 return PTR_ERR(nn->nfs_dns_resolve);
364 380
365 tbl = kzalloc(NFS_DNS_HASHTBL_SIZE * sizeof(struct cache_head *), 381 err = nfs_cache_register_net(net, nn->nfs_dns_resolve);
366 GFP_KERNEL);
367 if (tbl == NULL)
368 goto err_tbl;
369
370 cd->owner = THIS_MODULE,
371 cd->hash_size = NFS_DNS_HASHTBL_SIZE,
372 cd->hash_table = tbl,
373 cd->name = "dns_resolve",
374 cd->cache_put = nfs_dns_ent_put,
375 cd->cache_upcall = nfs_dns_upcall,
376 cd->cache_parse = nfs_dns_parse,
377 cd->cache_show = nfs_dns_show,
378 cd->match = nfs_dns_match,
379 cd->init = nfs_dns_ent_init,
380 cd->update = nfs_dns_ent_update,
381 cd->alloc = nfs_dns_ent_alloc,
382
383 nfs_cache_init(cd);
384 err = nfs_cache_register_net(net, cd);
385 if (err) 382 if (err)
386 goto err_reg; 383 goto err_reg;
387 nn->nfs_dns_resolve = cd;
388 return 0; 384 return 0;
389 385
390err_reg: 386err_reg:
391 nfs_cache_destroy(cd); 387 cache_destroy_net(nn->nfs_dns_resolve, net);
392 kfree(cd->hash_table);
393err_tbl:
394 kfree(cd);
395err_cd:
396 return err; 388 return err;
397} 389}
398 390
399void nfs_dns_resolver_cache_destroy(struct net *net) 391void nfs_dns_resolver_cache_destroy(struct net *net)
400{ 392{
401 struct nfs_net *nn = net_generic(net, nfs_net_id); 393 struct nfs_net *nn = net_generic(net, nfs_net_id);
402 struct cache_detail *cd = nn->nfs_dns_resolve;
403 394
404 nfs_cache_unregister_net(net, cd); 395 nfs_cache_unregister_net(net, nn->nfs_dns_resolve);
405 nfs_cache_destroy(cd); 396 cache_destroy_net(nn->nfs_dns_resolve, net);
406 kfree(cd->hash_table);
407 kfree(cd);
408} 397}
409 398
410static int rpc_pipefs_event(struct notifier_block *nb, unsigned long event, 399static int rpc_pipefs_event(struct notifier_block *nb, unsigned long event,
diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c
index 47d100872390..ac4fc9a8fdbc 100644
--- a/fs/nfs/nfs4client.c
+++ b/fs/nfs/nfs4client.c
@@ -6,6 +6,7 @@
6#include <linux/nfs_fs.h> 6#include <linux/nfs_fs.h>
7#include <linux/nfs_idmap.h> 7#include <linux/nfs_idmap.h>
8#include <linux/nfs_mount.h> 8#include <linux/nfs_mount.h>
9#include <linux/sunrpc/addr.h>
9#include <linux/sunrpc/auth.h> 10#include <linux/sunrpc/auth.h>
10#include <linux/sunrpc/xprt.h> 11#include <linux/sunrpc/xprt.h>
11#include <linux/sunrpc/bc_xprt.h> 12#include <linux/sunrpc/bc_xprt.h>
diff --git a/fs/nfs/nfs4filelayoutdev.c b/fs/nfs/nfs4filelayoutdev.c
index b720064bcd7f..1fe284f01f8b 100644
--- a/fs/nfs/nfs4filelayoutdev.c
+++ b/fs/nfs/nfs4filelayoutdev.c
@@ -31,6 +31,7 @@
31#include <linux/nfs_fs.h> 31#include <linux/nfs_fs.h>
32#include <linux/vmalloc.h> 32#include <linux/vmalloc.h>
33#include <linux/module.h> 33#include <linux/module.h>
34#include <linux/sunrpc/addr.h>
34 35
35#include "internal.h" 36#include "internal.h"
36#include "nfs4session.h" 37#include "nfs4session.h"
diff --git a/fs/nfs/nfs4namespace.c b/fs/nfs/nfs4namespace.c
index 1e09eb78543b..0dd766079e1c 100644
--- a/fs/nfs/nfs4namespace.c
+++ b/fs/nfs/nfs4namespace.c
@@ -14,6 +14,7 @@
14#include <linux/slab.h> 14#include <linux/slab.h>
15#include <linux/string.h> 15#include <linux/string.h>
16#include <linux/sunrpc/clnt.h> 16#include <linux/sunrpc/clnt.h>
17#include <linux/sunrpc/addr.h>
17#include <linux/vfs.h> 18#include <linux/vfs.h>
18#include <linux/inet.h> 19#include <linux/inet.h>
19#include "internal.h" 20#include "internal.h"
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index a9dc5fc29955..17b32b722457 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -31,6 +31,7 @@
31#include <linux/errno.h> 31#include <linux/errno.h>
32#include <linux/unistd.h> 32#include <linux/unistd.h>
33#include <linux/sunrpc/clnt.h> 33#include <linux/sunrpc/clnt.h>
34#include <linux/sunrpc/addr.h>
34#include <linux/sunrpc/stats.h> 35#include <linux/sunrpc/stats.h>
35#include <linux/sunrpc/metrics.h> 36#include <linux/sunrpc/metrics.h>
36#include <linux/sunrpc/xprtsock.h> 37#include <linux/sunrpc/xprtsock.h>
diff --git a/fs/nfsd/cache.h b/fs/nfsd/cache.h
index 93cc9d34c459..87fd1410b737 100644
--- a/fs/nfsd/cache.h
+++ b/fs/nfsd/cache.h
@@ -12,6 +12,10 @@
12 12
13/* 13/*
14 * Representation of a reply cache entry. 14 * Representation of a reply cache entry.
15 *
16 * Note that we use a sockaddr_in6 to hold the address instead of the more
17 * typical sockaddr_storage. This is for space reasons, since sockaddr_storage
18 * is much larger than a sockaddr_in6.
15 */ 19 */
16struct svc_cacherep { 20struct svc_cacherep {
17 struct hlist_node c_hash; 21 struct hlist_node c_hash;
@@ -20,11 +24,13 @@ struct svc_cacherep {
20 unsigned char c_state, /* unused, inprog, done */ 24 unsigned char c_state, /* unused, inprog, done */
21 c_type, /* status, buffer */ 25 c_type, /* status, buffer */
22 c_secure : 1; /* req came from port < 1024 */ 26 c_secure : 1; /* req came from port < 1024 */
23 struct sockaddr_in c_addr; 27 struct sockaddr_in6 c_addr;
24 __be32 c_xid; 28 __be32 c_xid;
25 u32 c_prot; 29 u32 c_prot;
26 u32 c_proc; 30 u32 c_proc;
27 u32 c_vers; 31 u32 c_vers;
32 unsigned int c_len;
33 __wsum c_csum;
28 unsigned long c_timestamp; 34 unsigned long c_timestamp;
29 union { 35 union {
30 struct kvec u_vec; 36 struct kvec u_vec;
@@ -46,8 +52,7 @@ enum {
46enum { 52enum {
47 RC_DROPIT, 53 RC_DROPIT,
48 RC_REPLY, 54 RC_REPLY,
49 RC_DOIT, 55 RC_DOIT
50 RC_INTR
51}; 56};
52 57
53/* 58/*
@@ -67,6 +72,12 @@ enum {
67 */ 72 */
68#define RC_DELAY (HZ/5) 73#define RC_DELAY (HZ/5)
69 74
75/* Cache entries expire after this time period */
76#define RC_EXPIRE (120 * HZ)
77
78/* Checksum this amount of the request */
79#define RC_CSUMLEN (256U)
80
70int nfsd_reply_cache_init(void); 81int nfsd_reply_cache_init(void);
71void nfsd_reply_cache_shutdown(void); 82void nfsd_reply_cache_shutdown(void);
72int nfsd_cache_lookup(struct svc_rqst *); 83int nfsd_cache_lookup(struct svc_rqst *);
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
index 5681c5906f08..5f38ea36e266 100644
--- a/fs/nfsd/export.c
+++ b/fs/nfsd/export.c
@@ -67,11 +67,6 @@ static void expkey_request(struct cache_detail *cd,
67 (*bpp)[-1] = '\n'; 67 (*bpp)[-1] = '\n';
68} 68}
69 69
70static int expkey_upcall(struct cache_detail *cd, struct cache_head *h)
71{
72 return sunrpc_cache_pipe_upcall(cd, h, expkey_request);
73}
74
75static struct svc_expkey *svc_expkey_update(struct cache_detail *cd, struct svc_expkey *new, 70static struct svc_expkey *svc_expkey_update(struct cache_detail *cd, struct svc_expkey *new,
76 struct svc_expkey *old); 71 struct svc_expkey *old);
77static struct svc_expkey *svc_expkey_lookup(struct cache_detail *cd, struct svc_expkey *); 72static struct svc_expkey *svc_expkey_lookup(struct cache_detail *cd, struct svc_expkey *);
@@ -245,7 +240,7 @@ static struct cache_detail svc_expkey_cache_template = {
245 .hash_size = EXPKEY_HASHMAX, 240 .hash_size = EXPKEY_HASHMAX,
246 .name = "nfsd.fh", 241 .name = "nfsd.fh",
247 .cache_put = expkey_put, 242 .cache_put = expkey_put,
248 .cache_upcall = expkey_upcall, 243 .cache_request = expkey_request,
249 .cache_parse = expkey_parse, 244 .cache_parse = expkey_parse,
250 .cache_show = expkey_show, 245 .cache_show = expkey_show,
251 .match = expkey_match, 246 .match = expkey_match,
@@ -315,6 +310,7 @@ static void svc_export_put(struct kref *ref)
315 path_put(&exp->ex_path); 310 path_put(&exp->ex_path);
316 auth_domain_put(exp->ex_client); 311 auth_domain_put(exp->ex_client);
317 nfsd4_fslocs_free(&exp->ex_fslocs); 312 nfsd4_fslocs_free(&exp->ex_fslocs);
313 kfree(exp->ex_uuid);
318 kfree(exp); 314 kfree(exp);
319} 315}
320 316
@@ -337,11 +333,6 @@ static void svc_export_request(struct cache_detail *cd,
337 (*bpp)[-1] = '\n'; 333 (*bpp)[-1] = '\n';
338} 334}
339 335
340static int svc_export_upcall(struct cache_detail *cd, struct cache_head *h)
341{
342 return sunrpc_cache_pipe_upcall(cd, h, svc_export_request);
343}
344
345static struct svc_export *svc_export_update(struct svc_export *new, 336static struct svc_export *svc_export_update(struct svc_export *new,
346 struct svc_export *old); 337 struct svc_export *old);
347static struct svc_export *svc_export_lookup(struct svc_export *); 338static struct svc_export *svc_export_lookup(struct svc_export *);
@@ -674,6 +665,7 @@ static void svc_export_init(struct cache_head *cnew, struct cache_head *citem)
674 new->ex_fslocs.locations = NULL; 665 new->ex_fslocs.locations = NULL;
675 new->ex_fslocs.locations_count = 0; 666 new->ex_fslocs.locations_count = 0;
676 new->ex_fslocs.migrated = 0; 667 new->ex_fslocs.migrated = 0;
668 new->ex_uuid = NULL;
677 new->cd = item->cd; 669 new->cd = item->cd;
678} 670}
679 671
@@ -715,7 +707,7 @@ static struct cache_detail svc_export_cache_template = {
715 .hash_size = EXPORT_HASHMAX, 707 .hash_size = EXPORT_HASHMAX,
716 .name = "nfsd.export", 708 .name = "nfsd.export",
717 .cache_put = svc_export_put, 709 .cache_put = svc_export_put,
718 .cache_upcall = svc_export_upcall, 710 .cache_request = svc_export_request,
719 .cache_parse = svc_export_parse, 711 .cache_parse = svc_export_parse,
720 .cache_show = svc_export_show, 712 .cache_show = svc_export_show,
721 .match = svc_export_match, 713 .match = svc_export_match,
diff --git a/fs/nfsd/fault_inject.c b/fs/nfsd/fault_inject.c
index 497584c70366..d620e7f81429 100644
--- a/fs/nfsd/fault_inject.c
+++ b/fs/nfsd/fault_inject.c
@@ -9,7 +9,7 @@
9#include <linux/debugfs.h> 9#include <linux/debugfs.h>
10#include <linux/module.h> 10#include <linux/module.h>
11#include <linux/nsproxy.h> 11#include <linux/nsproxy.h>
12#include <linux/sunrpc/clnt.h> 12#include <linux/sunrpc/addr.h>
13#include <asm/uaccess.h> 13#include <asm/uaccess.h>
14 14
15#include "state.h" 15#include "state.h"
diff --git a/fs/nfsd/nfs4idmap.c b/fs/nfsd/nfs4idmap.c
index 0ce12346df9c..4832fd819f88 100644
--- a/fs/nfsd/nfs4idmap.c
+++ b/fs/nfsd/nfs4idmap.c
@@ -140,12 +140,6 @@ idtoname_request(struct cache_detail *cd, struct cache_head *ch, char **bpp,
140} 140}
141 141
142static int 142static int
143idtoname_upcall(struct cache_detail *cd, struct cache_head *ch)
144{
145 return sunrpc_cache_pipe_upcall(cd, ch, idtoname_request);
146}
147
148static int
149idtoname_match(struct cache_head *ca, struct cache_head *cb) 143idtoname_match(struct cache_head *ca, struct cache_head *cb)
150{ 144{
151 struct ent *a = container_of(ca, struct ent, h); 145 struct ent *a = container_of(ca, struct ent, h);
@@ -192,7 +186,7 @@ static struct cache_detail idtoname_cache_template = {
192 .hash_size = ENT_HASHMAX, 186 .hash_size = ENT_HASHMAX,
193 .name = "nfs4.idtoname", 187 .name = "nfs4.idtoname",
194 .cache_put = ent_put, 188 .cache_put = ent_put,
195 .cache_upcall = idtoname_upcall, 189 .cache_request = idtoname_request,
196 .cache_parse = idtoname_parse, 190 .cache_parse = idtoname_parse,
197 .cache_show = idtoname_show, 191 .cache_show = idtoname_show,
198 .warn_no_listener = warn_no_idmapd, 192 .warn_no_listener = warn_no_idmapd,
@@ -321,12 +315,6 @@ nametoid_request(struct cache_detail *cd, struct cache_head *ch, char **bpp,
321} 315}
322 316
323static int 317static int
324nametoid_upcall(struct cache_detail *cd, struct cache_head *ch)
325{
326 return sunrpc_cache_pipe_upcall(cd, ch, nametoid_request);
327}
328
329static int
330nametoid_match(struct cache_head *ca, struct cache_head *cb) 318nametoid_match(struct cache_head *ca, struct cache_head *cb)
331{ 319{
332 struct ent *a = container_of(ca, struct ent, h); 320 struct ent *a = container_of(ca, struct ent, h);
@@ -365,7 +353,7 @@ static struct cache_detail nametoid_cache_template = {
365 .hash_size = ENT_HASHMAX, 353 .hash_size = ENT_HASHMAX,
366 .name = "nfs4.nametoid", 354 .name = "nfs4.nametoid",
367 .cache_put = ent_put, 355 .cache_put = ent_put,
368 .cache_upcall = nametoid_upcall, 356 .cache_request = nametoid_request,
369 .cache_parse = nametoid_parse, 357 .cache_parse = nametoid_parse,
370 .cache_show = nametoid_show, 358 .cache_show = nametoid_show,
371 .warn_no_listener = warn_no_idmapd, 359 .warn_no_listener = warn_no_idmapd,
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 9d1c5dba2bbb..ae73175e6e68 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -993,14 +993,15 @@ _nfsd4_verify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
993 if (!buf) 993 if (!buf)
994 return nfserr_jukebox; 994 return nfserr_jukebox;
995 995
996 p = buf;
996 status = nfsd4_encode_fattr(&cstate->current_fh, 997 status = nfsd4_encode_fattr(&cstate->current_fh,
997 cstate->current_fh.fh_export, 998 cstate->current_fh.fh_export,
998 cstate->current_fh.fh_dentry, buf, 999 cstate->current_fh.fh_dentry, &p,
999 &count, verify->ve_bmval, 1000 count, verify->ve_bmval,
1000 rqstp, 0); 1001 rqstp, 0);
1001 1002
1002 /* this means that nfsd4_encode_fattr() ran out of space */ 1003 /* this means that nfsd4_encode_fattr() ran out of space */
1003 if (status == nfserr_resource && count == 0) 1004 if (status == nfserr_resource)
1004 status = nfserr_not_same; 1005 status = nfserr_not_same;
1005 if (status) 1006 if (status)
1006 goto out_kfree; 1007 goto out_kfree;
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
index 4914af4a817e..899ca26dd194 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -1185,6 +1185,12 @@ bin_to_hex_dup(const unsigned char *src, int srclen)
1185static int 1185static int
1186nfsd4_umh_cltrack_init(struct net __attribute__((unused)) *net) 1186nfsd4_umh_cltrack_init(struct net __attribute__((unused)) *net)
1187{ 1187{
1188 /* XXX: The usermode helper s not working in container yet. */
1189 if (net != &init_net) {
1190 WARN(1, KERN_ERR "NFSD: attempt to initialize umh client "
1191 "tracking in a container!\n");
1192 return -EINVAL;
1193 }
1188 return nfsd4_umh_cltrack_upcall("init", NULL, NULL); 1194 return nfsd4_umh_cltrack_upcall("init", NULL, NULL);
1189} 1195}
1190 1196
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 9e7103b6e0ad..16d39c6c4fbb 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -40,7 +40,7 @@
40#include <linux/pagemap.h> 40#include <linux/pagemap.h>
41#include <linux/ratelimit.h> 41#include <linux/ratelimit.h>
42#include <linux/sunrpc/svcauth_gss.h> 42#include <linux/sunrpc/svcauth_gss.h>
43#include <linux/sunrpc/clnt.h> 43#include <linux/sunrpc/addr.h>
44#include "xdr4.h" 44#include "xdr4.h"
45#include "vfs.h" 45#include "vfs.h"
46#include "current_stateid.h" 46#include "current_stateid.h"
@@ -261,33 +261,46 @@ static inline int get_new_stid(struct nfs4_stid *stid)
261 return new_stid; 261 return new_stid;
262} 262}
263 263
264static void init_stid(struct nfs4_stid *stid, struct nfs4_client *cl, unsigned char type) 264static struct nfs4_stid *nfs4_alloc_stid(struct nfs4_client *cl, struct
265kmem_cache *slab)
265{ 266{
266 stateid_t *s = &stid->sc_stateid; 267 struct idr *stateids = &cl->cl_stateids;
268 static int min_stateid = 0;
269 struct nfs4_stid *stid;
267 int new_id; 270 int new_id;
268 271
269 stid->sc_type = type; 272 stid = kmem_cache_alloc(slab, GFP_KERNEL);
273 if (!stid)
274 return NULL;
275
276 if (!idr_pre_get(stateids, GFP_KERNEL))
277 goto out_free;
278 if (idr_get_new_above(stateids, stid, min_stateid, &new_id))
279 goto out_free;
270 stid->sc_client = cl; 280 stid->sc_client = cl;
271 s->si_opaque.so_clid = cl->cl_clientid; 281 stid->sc_type = 0;
272 new_id = get_new_stid(stid); 282 stid->sc_stateid.si_opaque.so_id = new_id;
273 s->si_opaque.so_id = (u32)new_id; 283 stid->sc_stateid.si_opaque.so_clid = cl->cl_clientid;
274 /* Will be incremented before return to client: */ 284 /* Will be incremented before return to client: */
275 s->si_generation = 0; 285 stid->sc_stateid.si_generation = 0;
276}
277
278static struct nfs4_stid *nfs4_alloc_stid(struct nfs4_client *cl, struct kmem_cache *slab)
279{
280 struct idr *stateids = &cl->cl_stateids;
281 286
282 if (!idr_pre_get(stateids, GFP_KERNEL))
283 return NULL;
284 /* 287 /*
285 * Note: if we fail here (or any time between now and the time 288 * It shouldn't be a problem to reuse an opaque stateid value.
286 * we actually get the new idr), we won't need to undo the idr 289 * I don't think it is for 4.1. But with 4.0 I worry that, for
287 * preallocation, since the idr code caps the number of 290 * example, a stray write retransmission could be accepted by
288 * preallocated entries. 291 * the server when it should have been rejected. Therefore,
292 * adopt a trick from the sctp code to attempt to maximize the
293 * amount of time until an id is reused, by ensuring they always
294 * "increase" (mod INT_MAX):
289 */ 295 */
290 return kmem_cache_alloc(slab, GFP_KERNEL); 296
297 min_stateid = new_id+1;
298 if (min_stateid == INT_MAX)
299 min_stateid = 0;
300 return stid;
301out_free:
302 kfree(stid);
303 return NULL;
291} 304}
292 305
293static struct nfs4_ol_stateid * nfs4_alloc_stateid(struct nfs4_client *clp) 306static struct nfs4_ol_stateid * nfs4_alloc_stateid(struct nfs4_client *clp)
@@ -316,7 +329,7 @@ alloc_init_deleg(struct nfs4_client *clp, struct nfs4_ol_stateid *stp, struct sv
316 dp = delegstateid(nfs4_alloc_stid(clp, deleg_slab)); 329 dp = delegstateid(nfs4_alloc_stid(clp, deleg_slab));
317 if (dp == NULL) 330 if (dp == NULL)
318 return dp; 331 return dp;
319 init_stid(&dp->dl_stid, clp, NFS4_DELEG_STID); 332 dp->dl_stid.sc_type = NFS4_DELEG_STID;
320 /* 333 /*
321 * delegation seqid's are never incremented. The 4.1 special 334 * delegation seqid's are never incremented. The 4.1 special
322 * meaning of seqid 0 isn't meaningful, really, but let's avoid 335 * meaning of seqid 0 isn't meaningful, really, but let's avoid
@@ -337,13 +350,21 @@ alloc_init_deleg(struct nfs4_client *clp, struct nfs4_ol_stateid *stp, struct sv
337 return dp; 350 return dp;
338} 351}
339 352
353static void free_stid(struct nfs4_stid *s, struct kmem_cache *slab)
354{
355 struct idr *stateids = &s->sc_client->cl_stateids;
356
357 idr_remove(stateids, s->sc_stateid.si_opaque.so_id);
358 kmem_cache_free(slab, s);
359}
360
340void 361void
341nfs4_put_delegation(struct nfs4_delegation *dp) 362nfs4_put_delegation(struct nfs4_delegation *dp)
342{ 363{
343 if (atomic_dec_and_test(&dp->dl_count)) { 364 if (atomic_dec_and_test(&dp->dl_count)) {
344 dprintk("NFSD: freeing dp %p\n",dp); 365 dprintk("NFSD: freeing dp %p\n",dp);
345 put_nfs4_file(dp->dl_file); 366 put_nfs4_file(dp->dl_file);
346 kmem_cache_free(deleg_slab, dp); 367 free_stid(&dp->dl_stid, deleg_slab);
347 num_delegations--; 368 num_delegations--;
348 } 369 }
349} 370}
@@ -360,9 +381,7 @@ static void nfs4_put_deleg_lease(struct nfs4_file *fp)
360 381
361static void unhash_stid(struct nfs4_stid *s) 382static void unhash_stid(struct nfs4_stid *s)
362{ 383{
363 struct idr *stateids = &s->sc_client->cl_stateids; 384 s->sc_type = 0;
364
365 idr_remove(stateids, s->sc_stateid.si_opaque.so_id);
366} 385}
367 386
368/* Called under the state lock. */ 387/* Called under the state lock. */
@@ -519,7 +538,7 @@ static void close_generic_stateid(struct nfs4_ol_stateid *stp)
519 538
520static void free_generic_stateid(struct nfs4_ol_stateid *stp) 539static void free_generic_stateid(struct nfs4_ol_stateid *stp)
521{ 540{
522 kmem_cache_free(stateid_slab, stp); 541 free_stid(&stp->st_stid, stateid_slab);
523} 542}
524 543
525static void release_lock_stateid(struct nfs4_ol_stateid *stp) 544static void release_lock_stateid(struct nfs4_ol_stateid *stp)
@@ -905,7 +924,7 @@ static struct nfsd4_session *alloc_session(struct nfsd4_channel_attrs *fchan,
905 924
906 new = __alloc_session(slotsize, numslots); 925 new = __alloc_session(slotsize, numslots);
907 if (!new) { 926 if (!new) {
908 nfsd4_put_drc_mem(slotsize, fchan->maxreqs); 927 nfsd4_put_drc_mem(slotsize, numslots);
909 return NULL; 928 return NULL;
910 } 929 }
911 init_forechannel_attrs(&new->se_fchannel, fchan, numslots, slotsize, nn); 930 init_forechannel_attrs(&new->se_fchannel, fchan, numslots, slotsize, nn);
@@ -1048,7 +1067,7 @@ static struct nfs4_client *alloc_client(struct xdr_netobj name)
1048static inline void 1067static inline void
1049free_client(struct nfs4_client *clp) 1068free_client(struct nfs4_client *clp)
1050{ 1069{
1051 struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id); 1070 struct nfsd_net __maybe_unused *nn = net_generic(clp->net, nfsd_net_id);
1052 1071
1053 lockdep_assert_held(&nn->client_lock); 1072 lockdep_assert_held(&nn->client_lock);
1054 while (!list_empty(&clp->cl_sessions)) { 1073 while (!list_empty(&clp->cl_sessions)) {
@@ -1060,6 +1079,7 @@ free_client(struct nfs4_client *clp)
1060 } 1079 }
1061 free_svc_cred(&clp->cl_cred); 1080 free_svc_cred(&clp->cl_cred);
1062 kfree(clp->cl_name.data); 1081 kfree(clp->cl_name.data);
1082 idr_destroy(&clp->cl_stateids);
1063 kfree(clp); 1083 kfree(clp);
1064} 1084}
1065 1085
@@ -1258,7 +1278,12 @@ static void gen_confirm(struct nfs4_client *clp)
1258 1278
1259static struct nfs4_stid *find_stateid(struct nfs4_client *cl, stateid_t *t) 1279static struct nfs4_stid *find_stateid(struct nfs4_client *cl, stateid_t *t)
1260{ 1280{
1261 return idr_find(&cl->cl_stateids, t->si_opaque.so_id); 1281 struct nfs4_stid *ret;
1282
1283 ret = idr_find(&cl->cl_stateids, t->si_opaque.so_id);
1284 if (!ret || !ret->sc_type)
1285 return NULL;
1286 return ret;
1262} 1287}
1263 1288
1264static struct nfs4_stid *find_stateid_by_type(struct nfs4_client *cl, stateid_t *t, char typemask) 1289static struct nfs4_stid *find_stateid_by_type(struct nfs4_client *cl, stateid_t *t, char typemask)
@@ -1844,11 +1869,12 @@ nfsd4_create_session(struct svc_rqst *rqstp,
1844 1869
1845 /* cache solo and embedded create sessions under the state lock */ 1870 /* cache solo and embedded create sessions under the state lock */
1846 nfsd4_cache_create_session(cr_ses, cs_slot, status); 1871 nfsd4_cache_create_session(cr_ses, cs_slot, status);
1847out:
1848 nfs4_unlock_state(); 1872 nfs4_unlock_state();
1873out:
1849 dprintk("%s returns %d\n", __func__, ntohl(status)); 1874 dprintk("%s returns %d\n", __func__, ntohl(status));
1850 return status; 1875 return status;
1851out_free_conn: 1876out_free_conn:
1877 nfs4_unlock_state();
1852 free_conn(conn); 1878 free_conn(conn);
1853out_free_session: 1879out_free_session:
1854 __free_session(new); 1880 __free_session(new);
@@ -2443,9 +2469,8 @@ alloc_init_open_stateowner(unsigned int strhashval, struct nfs4_client *clp, str
2443 2469
2444static void init_open_stateid(struct nfs4_ol_stateid *stp, struct nfs4_file *fp, struct nfsd4_open *open) { 2470static void init_open_stateid(struct nfs4_ol_stateid *stp, struct nfs4_file *fp, struct nfsd4_open *open) {
2445 struct nfs4_openowner *oo = open->op_openowner; 2471 struct nfs4_openowner *oo = open->op_openowner;
2446 struct nfs4_client *clp = oo->oo_owner.so_client;
2447 2472
2448 init_stid(&stp->st_stid, clp, NFS4_OPEN_STID); 2473 stp->st_stid.sc_type = NFS4_OPEN_STID;
2449 INIT_LIST_HEAD(&stp->st_lockowners); 2474 INIT_LIST_HEAD(&stp->st_lockowners);
2450 list_add(&stp->st_perstateowner, &oo->oo_owner.so_stateids); 2475 list_add(&stp->st_perstateowner, &oo->oo_owner.so_stateids);
2451 list_add(&stp->st_perfile, &fp->fi_stateids); 2476 list_add(&stp->st_perfile, &fp->fi_stateids);
@@ -4031,7 +4056,7 @@ alloc_init_lock_stateid(struct nfs4_lockowner *lo, struct nfs4_file *fp, struct
4031 stp = nfs4_alloc_stateid(clp); 4056 stp = nfs4_alloc_stateid(clp);
4032 if (stp == NULL) 4057 if (stp == NULL)
4033 return NULL; 4058 return NULL;
4034 init_stid(&stp->st_stid, clp, NFS4_LOCK_STID); 4059 stp->st_stid.sc_type = NFS4_LOCK_STID;
4035 list_add(&stp->st_perfile, &fp->fi_stateids); 4060 list_add(&stp->st_perfile, &fp->fi_stateids);
4036 list_add(&stp->st_perstateowner, &lo->lo_owner.so_stateids); 4061 list_add(&stp->st_perstateowner, &lo->lo_owner.so_stateids);
4037 stp->st_stateowner = &lo->lo_owner; 4062 stp->st_stateowner = &lo->lo_owner;
@@ -4913,16 +4938,6 @@ nfs4_state_start_net(struct net *net)
4913 struct nfsd_net *nn = net_generic(net, nfsd_net_id); 4938 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
4914 int ret; 4939 int ret;
4915 4940
4916 /*
4917 * FIXME: For now, we hang most of the pernet global stuff off of
4918 * init_net until nfsd is fully containerized. Eventually, we'll
4919 * need to pass a net pointer into this function, take a reference
4920 * to that instead and then do most of the rest of this on a per-net
4921 * basis.
4922 */
4923 if (net != &init_net)
4924 return -EINVAL;
4925
4926 ret = nfs4_state_create_net(net); 4941 ret = nfs4_state_create_net(net);
4927 if (ret) 4942 if (ret)
4928 return ret; 4943 return ret;
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 8ca6d17f6cf3..01168865dd37 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -2024,12 +2024,11 @@ static int get_parent_attributes(struct svc_export *exp, struct kstat *stat)
2024 * Note: @fhp can be NULL; in this case, we might have to compose the filehandle 2024 * Note: @fhp can be NULL; in this case, we might have to compose the filehandle
2025 * ourselves. 2025 * ourselves.
2026 * 2026 *
2027 * @countp is the buffer size in _words_; upon successful return this becomes 2027 * countp is the buffer size in _words_
2028 * replaced with the number of words written.
2029 */ 2028 */
2030__be32 2029__be32
2031nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp, 2030nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
2032 struct dentry *dentry, __be32 *buffer, int *countp, u32 *bmval, 2031 struct dentry *dentry, __be32 **buffer, int count, u32 *bmval,
2033 struct svc_rqst *rqstp, int ignore_crossmnt) 2032 struct svc_rqst *rqstp, int ignore_crossmnt)
2034{ 2033{
2035 u32 bmval0 = bmval[0]; 2034 u32 bmval0 = bmval[0];
@@ -2038,12 +2037,12 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
2038 struct kstat stat; 2037 struct kstat stat;
2039 struct svc_fh tempfh; 2038 struct svc_fh tempfh;
2040 struct kstatfs statfs; 2039 struct kstatfs statfs;
2041 int buflen = *countp << 2; 2040 int buflen = count << 2;
2042 __be32 *attrlenp; 2041 __be32 *attrlenp;
2043 u32 dummy; 2042 u32 dummy;
2044 u64 dummy64; 2043 u64 dummy64;
2045 u32 rdattr_err = 0; 2044 u32 rdattr_err = 0;
2046 __be32 *p = buffer; 2045 __be32 *p = *buffer;
2047 __be32 status; 2046 __be32 status;
2048 int err; 2047 int err;
2049 int aclsupport = 0; 2048 int aclsupport = 0;
@@ -2447,7 +2446,7 @@ out_acl:
2447 } 2446 }
2448 2447
2449 *attrlenp = htonl((char *)p - (char *)attrlenp - 4); 2448 *attrlenp = htonl((char *)p - (char *)attrlenp - 4);
2450 *countp = p - buffer; 2449 *buffer = p;
2451 status = nfs_ok; 2450 status = nfs_ok;
2452 2451
2453out: 2452out:
@@ -2459,7 +2458,6 @@ out_nfserr:
2459 status = nfserrno(err); 2458 status = nfserrno(err);
2460 goto out; 2459 goto out;
2461out_resource: 2460out_resource:
2462 *countp = 0;
2463 status = nfserr_resource; 2461 status = nfserr_resource;
2464 goto out; 2462 goto out;
2465out_serverfault: 2463out_serverfault:
@@ -2478,7 +2476,7 @@ static inline int attributes_need_mount(u32 *bmval)
2478 2476
2479static __be32 2477static __be32
2480nfsd4_encode_dirent_fattr(struct nfsd4_readdir *cd, 2478nfsd4_encode_dirent_fattr(struct nfsd4_readdir *cd,
2481 const char *name, int namlen, __be32 *p, int *buflen) 2479 const char *name, int namlen, __be32 **p, int buflen)
2482{ 2480{
2483 struct svc_export *exp = cd->rd_fhp->fh_export; 2481 struct svc_export *exp = cd->rd_fhp->fh_export;
2484 struct dentry *dentry; 2482 struct dentry *dentry;
@@ -2584,10 +2582,9 @@ nfsd4_encode_dirent(void *ccdv, const char *name, int namlen,
2584 p = xdr_encode_hyper(p, NFS_OFFSET_MAX); /* offset of next entry */ 2582 p = xdr_encode_hyper(p, NFS_OFFSET_MAX); /* offset of next entry */
2585 p = xdr_encode_array(p, name, namlen); /* name length & name */ 2583 p = xdr_encode_array(p, name, namlen); /* name length & name */
2586 2584
2587 nfserr = nfsd4_encode_dirent_fattr(cd, name, namlen, p, &buflen); 2585 nfserr = nfsd4_encode_dirent_fattr(cd, name, namlen, &p, buflen);
2588 switch (nfserr) { 2586 switch (nfserr) {
2589 case nfs_ok: 2587 case nfs_ok:
2590 p += buflen;
2591 break; 2588 break;
2592 case nfserr_resource: 2589 case nfserr_resource:
2593 nfserr = nfserr_toosmall; 2590 nfserr = nfserr_toosmall;
@@ -2714,10 +2711,8 @@ nfsd4_encode_getattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4
2714 2711
2715 buflen = resp->end - resp->p - (COMPOUND_ERR_SLACK_SPACE >> 2); 2712 buflen = resp->end - resp->p - (COMPOUND_ERR_SLACK_SPACE >> 2);
2716 nfserr = nfsd4_encode_fattr(fhp, fhp->fh_export, fhp->fh_dentry, 2713 nfserr = nfsd4_encode_fattr(fhp, fhp->fh_export, fhp->fh_dentry,
2717 resp->p, &buflen, getattr->ga_bmval, 2714 &resp->p, buflen, getattr->ga_bmval,
2718 resp->rqstp, 0); 2715 resp->rqstp, 0);
2719 if (!nfserr)
2720 resp->p += buflen;
2721 return nfserr; 2716 return nfserr;
2722} 2717}
2723 2718
diff --git a/fs/nfsd/nfscache.c b/fs/nfsd/nfscache.c
index da3dbd0f8979..62c1ee128aeb 100644
--- a/fs/nfsd/nfscache.c
+++ b/fs/nfsd/nfscache.c
@@ -9,22 +9,22 @@
9 */ 9 */
10 10
11#include <linux/slab.h> 11#include <linux/slab.h>
12#include <linux/sunrpc/addr.h>
13#include <linux/highmem.h>
14#include <net/checksum.h>
12 15
13#include "nfsd.h" 16#include "nfsd.h"
14#include "cache.h" 17#include "cache.h"
15 18
16/* Size of reply cache. Common values are: 19#define NFSDDBG_FACILITY NFSDDBG_REPCACHE
17 * 4.3BSD: 128 20
18 * 4.4BSD: 256
19 * Solaris2: 1024
20 * DEC Unix: 512-4096
21 */
22#define CACHESIZE 1024
23#define HASHSIZE 64 21#define HASHSIZE 64
24 22
25static struct hlist_head * cache_hash; 23static struct hlist_head * cache_hash;
26static struct list_head lru_head; 24static struct list_head lru_head;
27static int cache_disabled = 1; 25static struct kmem_cache *drc_slab;
26static unsigned int num_drc_entries;
27static unsigned int max_drc_entries;
28 28
29/* 29/*
30 * Calculate the hash index from an XID. 30 * Calculate the hash index from an XID.
@@ -37,6 +37,14 @@ static inline u32 request_hash(u32 xid)
37} 37}
38 38
39static int nfsd_cache_append(struct svc_rqst *rqstp, struct kvec *vec); 39static int nfsd_cache_append(struct svc_rqst *rqstp, struct kvec *vec);
40static void cache_cleaner_func(struct work_struct *unused);
41static int nfsd_reply_cache_shrink(struct shrinker *shrink,
42 struct shrink_control *sc);
43
44struct shrinker nfsd_reply_cache_shrinker = {
45 .shrink = nfsd_reply_cache_shrink,
46 .seeks = 1,
47};
40 48
41/* 49/*
42 * locking for the reply cache: 50 * locking for the reply cache:
@@ -44,30 +52,86 @@ static int nfsd_cache_append(struct svc_rqst *rqstp, struct kvec *vec);
44 * Otherwise, it when accessing _prev or _next, the lock must be held. 52 * Otherwise, it when accessing _prev or _next, the lock must be held.
45 */ 53 */
46static DEFINE_SPINLOCK(cache_lock); 54static DEFINE_SPINLOCK(cache_lock);
55static DECLARE_DELAYED_WORK(cache_cleaner, cache_cleaner_func);
47 56
48int nfsd_reply_cache_init(void) 57/*
58 * Put a cap on the size of the DRC based on the amount of available
59 * low memory in the machine.
60 *
61 * 64MB: 8192
62 * 128MB: 11585
63 * 256MB: 16384
64 * 512MB: 23170
65 * 1GB: 32768
66 * 2GB: 46340
67 * 4GB: 65536
68 * 8GB: 92681
69 * 16GB: 131072
70 *
71 * ...with a hard cap of 256k entries. In the worst case, each entry will be
72 * ~1k, so the above numbers should give a rough max of the amount of memory
73 * used in k.
74 */
75static unsigned int
76nfsd_cache_size_limit(void)
77{
78 unsigned int limit;
79 unsigned long low_pages = totalram_pages - totalhigh_pages;
80
81 limit = (16 * int_sqrt(low_pages)) << (PAGE_SHIFT-10);
82 return min_t(unsigned int, limit, 256*1024);
83}
84
85static struct svc_cacherep *
86nfsd_reply_cache_alloc(void)
49{ 87{
50 struct svc_cacherep *rp; 88 struct svc_cacherep *rp;
51 int i;
52 89
53 INIT_LIST_HEAD(&lru_head); 90 rp = kmem_cache_alloc(drc_slab, GFP_KERNEL);
54 i = CACHESIZE; 91 if (rp) {
55 while (i) {
56 rp = kmalloc(sizeof(*rp), GFP_KERNEL);
57 if (!rp)
58 goto out_nomem;
59 list_add(&rp->c_lru, &lru_head);
60 rp->c_state = RC_UNUSED; 92 rp->c_state = RC_UNUSED;
61 rp->c_type = RC_NOCACHE; 93 rp->c_type = RC_NOCACHE;
94 INIT_LIST_HEAD(&rp->c_lru);
62 INIT_HLIST_NODE(&rp->c_hash); 95 INIT_HLIST_NODE(&rp->c_hash);
63 i--;
64 } 96 }
97 return rp;
98}
65 99
66 cache_hash = kcalloc (HASHSIZE, sizeof(struct hlist_head), GFP_KERNEL); 100static void
101nfsd_reply_cache_free_locked(struct svc_cacherep *rp)
102{
103 if (rp->c_type == RC_REPLBUFF)
104 kfree(rp->c_replvec.iov_base);
105 hlist_del(&rp->c_hash);
106 list_del(&rp->c_lru);
107 --num_drc_entries;
108 kmem_cache_free(drc_slab, rp);
109}
110
111static void
112nfsd_reply_cache_free(struct svc_cacherep *rp)
113{
114 spin_lock(&cache_lock);
115 nfsd_reply_cache_free_locked(rp);
116 spin_unlock(&cache_lock);
117}
118
119int nfsd_reply_cache_init(void)
120{
121 register_shrinker(&nfsd_reply_cache_shrinker);
122 drc_slab = kmem_cache_create("nfsd_drc", sizeof(struct svc_cacherep),
123 0, 0, NULL);
124 if (!drc_slab)
125 goto out_nomem;
126
127 cache_hash = kcalloc(HASHSIZE, sizeof(struct hlist_head), GFP_KERNEL);
67 if (!cache_hash) 128 if (!cache_hash)
68 goto out_nomem; 129 goto out_nomem;
69 130
70 cache_disabled = 0; 131 INIT_LIST_HEAD(&lru_head);
132 max_drc_entries = nfsd_cache_size_limit();
133 num_drc_entries = 0;
134
71 return 0; 135 return 0;
72out_nomem: 136out_nomem:
73 printk(KERN_ERR "nfsd: failed to allocate reply cache\n"); 137 printk(KERN_ERR "nfsd: failed to allocate reply cache\n");
@@ -79,27 +143,33 @@ void nfsd_reply_cache_shutdown(void)
79{ 143{
80 struct svc_cacherep *rp; 144 struct svc_cacherep *rp;
81 145
146 unregister_shrinker(&nfsd_reply_cache_shrinker);
147 cancel_delayed_work_sync(&cache_cleaner);
148
82 while (!list_empty(&lru_head)) { 149 while (!list_empty(&lru_head)) {
83 rp = list_entry(lru_head.next, struct svc_cacherep, c_lru); 150 rp = list_entry(lru_head.next, struct svc_cacherep, c_lru);
84 if (rp->c_state == RC_DONE && rp->c_type == RC_REPLBUFF) 151 nfsd_reply_cache_free_locked(rp);
85 kfree(rp->c_replvec.iov_base);
86 list_del(&rp->c_lru);
87 kfree(rp);
88 } 152 }
89 153
90 cache_disabled = 1;
91
92 kfree (cache_hash); 154 kfree (cache_hash);
93 cache_hash = NULL; 155 cache_hash = NULL;
156
157 if (drc_slab) {
158 kmem_cache_destroy(drc_slab);
159 drc_slab = NULL;
160 }
94} 161}
95 162
96/* 163/*
97 * Move cache entry to end of LRU list 164 * Move cache entry to end of LRU list, and queue the cleaner to run if it's
165 * not already scheduled.
98 */ 166 */
99static void 167static void
100lru_put_end(struct svc_cacherep *rp) 168lru_put_end(struct svc_cacherep *rp)
101{ 169{
170 rp->c_timestamp = jiffies;
102 list_move_tail(&rp->c_lru, &lru_head); 171 list_move_tail(&rp->c_lru, &lru_head);
172 schedule_delayed_work(&cache_cleaner, RC_EXPIRE);
103} 173}
104 174
105/* 175/*
@@ -112,82 +182,214 @@ hash_refile(struct svc_cacherep *rp)
112 hlist_add_head(&rp->c_hash, cache_hash + request_hash(rp->c_xid)); 182 hlist_add_head(&rp->c_hash, cache_hash + request_hash(rp->c_xid));
113} 183}
114 184
185static inline bool
186nfsd_cache_entry_expired(struct svc_cacherep *rp)
187{
188 return rp->c_state != RC_INPROG &&
189 time_after(jiffies, rp->c_timestamp + RC_EXPIRE);
190}
191
192/*
193 * Walk the LRU list and prune off entries that are older than RC_EXPIRE.
194 * Also prune the oldest ones when the total exceeds the max number of entries.
195 */
196static void
197prune_cache_entries(void)
198{
199 struct svc_cacherep *rp, *tmp;
200
201 list_for_each_entry_safe(rp, tmp, &lru_head, c_lru) {
202 if (!nfsd_cache_entry_expired(rp) &&
203 num_drc_entries <= max_drc_entries)
204 break;
205 nfsd_reply_cache_free_locked(rp);
206 }
207
208 /*
209 * Conditionally rearm the job. If we cleaned out the list, then
210 * cancel any pending run (since there won't be any work to do).
211 * Otherwise, we rearm the job or modify the existing one to run in
212 * RC_EXPIRE since we just ran the pruner.
213 */
214 if (list_empty(&lru_head))
215 cancel_delayed_work(&cache_cleaner);
216 else
217 mod_delayed_work(system_wq, &cache_cleaner, RC_EXPIRE);
218}
219
220static void
221cache_cleaner_func(struct work_struct *unused)
222{
223 spin_lock(&cache_lock);
224 prune_cache_entries();
225 spin_unlock(&cache_lock);
226}
227
228static int
229nfsd_reply_cache_shrink(struct shrinker *shrink, struct shrink_control *sc)
230{
231 unsigned int num;
232
233 spin_lock(&cache_lock);
234 if (sc->nr_to_scan)
235 prune_cache_entries();
236 num = num_drc_entries;
237 spin_unlock(&cache_lock);
238
239 return num;
240}
241
242/*
243 * Walk an xdr_buf and get a CRC for at most the first RC_CSUMLEN bytes
244 */
245static __wsum
246nfsd_cache_csum(struct svc_rqst *rqstp)
247{
248 int idx;
249 unsigned int base;
250 __wsum csum;
251 struct xdr_buf *buf = &rqstp->rq_arg;
252 const unsigned char *p = buf->head[0].iov_base;
253 size_t csum_len = min_t(size_t, buf->head[0].iov_len + buf->page_len,
254 RC_CSUMLEN);
255 size_t len = min(buf->head[0].iov_len, csum_len);
256
257 /* rq_arg.head first */
258 csum = csum_partial(p, len, 0);
259 csum_len -= len;
260
261 /* Continue into page array */
262 idx = buf->page_base / PAGE_SIZE;
263 base = buf->page_base & ~PAGE_MASK;
264 while (csum_len) {
265 p = page_address(buf->pages[idx]) + base;
266 len = min_t(size_t, PAGE_SIZE - base, csum_len);
267 csum = csum_partial(p, len, csum);
268 csum_len -= len;
269 base = 0;
270 ++idx;
271 }
272 return csum;
273}
274
275/*
276 * Search the request hash for an entry that matches the given rqstp.
277 * Must be called with cache_lock held. Returns the found entry or
278 * NULL on failure.
279 */
280static struct svc_cacherep *
281nfsd_cache_search(struct svc_rqst *rqstp, __wsum csum)
282{
283 struct svc_cacherep *rp;
284 struct hlist_head *rh;
285 __be32 xid = rqstp->rq_xid;
286 u32 proto = rqstp->rq_prot,
287 vers = rqstp->rq_vers,
288 proc = rqstp->rq_proc;
289
290 rh = &cache_hash[request_hash(xid)];
291 hlist_for_each_entry(rp, rh, c_hash) {
292 if (xid == rp->c_xid && proc == rp->c_proc &&
293 proto == rp->c_prot && vers == rp->c_vers &&
294 rqstp->rq_arg.len == rp->c_len && csum == rp->c_csum &&
295 rpc_cmp_addr(svc_addr(rqstp), (struct sockaddr *)&rp->c_addr) &&
296 rpc_get_port(svc_addr(rqstp)) == rpc_get_port((struct sockaddr *)&rp->c_addr))
297 return rp;
298 }
299 return NULL;
300}
301
115/* 302/*
116 * Try to find an entry matching the current call in the cache. When none 303 * Try to find an entry matching the current call in the cache. When none
117 * is found, we grab the oldest unlocked entry off the LRU list. 304 * is found, we try to grab the oldest expired entry off the LRU list. If
118 * Note that no operation within the loop may sleep. 305 * a suitable one isn't there, then drop the cache_lock and allocate a
306 * new one, then search again in case one got inserted while this thread
307 * didn't hold the lock.
119 */ 308 */
120int 309int
121nfsd_cache_lookup(struct svc_rqst *rqstp) 310nfsd_cache_lookup(struct svc_rqst *rqstp)
122{ 311{
123 struct hlist_head *rh; 312 struct svc_cacherep *rp, *found;
124 struct svc_cacherep *rp;
125 __be32 xid = rqstp->rq_xid; 313 __be32 xid = rqstp->rq_xid;
126 u32 proto = rqstp->rq_prot, 314 u32 proto = rqstp->rq_prot,
127 vers = rqstp->rq_vers, 315 vers = rqstp->rq_vers,
128 proc = rqstp->rq_proc; 316 proc = rqstp->rq_proc;
317 __wsum csum;
129 unsigned long age; 318 unsigned long age;
130 int type = rqstp->rq_cachetype; 319 int type = rqstp->rq_cachetype;
131 int rtn; 320 int rtn;
132 321
133 rqstp->rq_cacherep = NULL; 322 rqstp->rq_cacherep = NULL;
134 if (cache_disabled || type == RC_NOCACHE) { 323 if (type == RC_NOCACHE) {
135 nfsdstats.rcnocache++; 324 nfsdstats.rcnocache++;
136 return RC_DOIT; 325 return RC_DOIT;
137 } 326 }
138 327
328 csum = nfsd_cache_csum(rqstp);
329
139 spin_lock(&cache_lock); 330 spin_lock(&cache_lock);
140 rtn = RC_DOIT; 331 rtn = RC_DOIT;
141 332
142 rh = &cache_hash[request_hash(xid)]; 333 rp = nfsd_cache_search(rqstp, csum);
143 hlist_for_each_entry(rp, rh, c_hash) { 334 if (rp)
144 if (rp->c_state != RC_UNUSED && 335 goto found_entry;
145 xid == rp->c_xid && proc == rp->c_proc && 336
146 proto == rp->c_prot && vers == rp->c_vers && 337 /* Try to use the first entry on the LRU */
147 time_before(jiffies, rp->c_timestamp + 120*HZ) && 338 if (!list_empty(&lru_head)) {
148 memcmp((char*)&rqstp->rq_addr, (char*)&rp->c_addr, sizeof(rp->c_addr))==0) { 339 rp = list_first_entry(&lru_head, struct svc_cacherep, c_lru);
149 nfsdstats.rchits++; 340 if (nfsd_cache_entry_expired(rp) ||
150 goto found_entry; 341 num_drc_entries >= max_drc_entries) {
342 lru_put_end(rp);
343 prune_cache_entries();
344 goto setup_entry;
151 } 345 }
152 } 346 }
153 nfsdstats.rcmisses++;
154 347
155 /* This loop shouldn't take more than a few iterations normally */ 348 /* Drop the lock and allocate a new entry */
156 { 349 spin_unlock(&cache_lock);
157 int safe = 0; 350 rp = nfsd_reply_cache_alloc();
158 list_for_each_entry(rp, &lru_head, c_lru) { 351 if (!rp) {
159 if (rp->c_state != RC_INPROG) 352 dprintk("nfsd: unable to allocate DRC entry!\n");
160 break; 353 return RC_DOIT;
161 if (safe++ > CACHESIZE) {
162 printk("nfsd: loop in repcache LRU list\n");
163 cache_disabled = 1;
164 goto out;
165 }
166 } 354 }
355 spin_lock(&cache_lock);
356 ++num_drc_entries;
357
358 /*
359 * Must search again just in case someone inserted one
360 * after we dropped the lock above.
361 */
362 found = nfsd_cache_search(rqstp, csum);
363 if (found) {
364 nfsd_reply_cache_free_locked(rp);
365 rp = found;
366 goto found_entry;
167 } 367 }
168 368
169 /* All entries on the LRU are in-progress. This should not happen */ 369 /*
170 if (&rp->c_lru == &lru_head) { 370 * We're keeping the one we just allocated. Are we now over the
171 static int complaints; 371 * limit? Prune one off the tip of the LRU in trade for the one we
172 372 * just allocated if so.
173 printk(KERN_WARNING "nfsd: all repcache entries locked!\n"); 373 */
174 if (++complaints > 5) { 374 if (num_drc_entries >= max_drc_entries)
175 printk(KERN_WARNING "nfsd: disabling repcache.\n"); 375 nfsd_reply_cache_free_locked(list_first_entry(&lru_head,
176 cache_disabled = 1; 376 struct svc_cacherep, c_lru));
177 }
178 goto out;
179 }
180 377
378setup_entry:
379 nfsdstats.rcmisses++;
181 rqstp->rq_cacherep = rp; 380 rqstp->rq_cacherep = rp;
182 rp->c_state = RC_INPROG; 381 rp->c_state = RC_INPROG;
183 rp->c_xid = xid; 382 rp->c_xid = xid;
184 rp->c_proc = proc; 383 rp->c_proc = proc;
185 memcpy(&rp->c_addr, svc_addr_in(rqstp), sizeof(rp->c_addr)); 384 rpc_copy_addr((struct sockaddr *)&rp->c_addr, svc_addr(rqstp));
385 rpc_set_port((struct sockaddr *)&rp->c_addr, rpc_get_port(svc_addr(rqstp)));
186 rp->c_prot = proto; 386 rp->c_prot = proto;
187 rp->c_vers = vers; 387 rp->c_vers = vers;
188 rp->c_timestamp = jiffies; 388 rp->c_len = rqstp->rq_arg.len;
389 rp->c_csum = csum;
189 390
190 hash_refile(rp); 391 hash_refile(rp);
392 lru_put_end(rp);
191 393
192 /* release any buffer */ 394 /* release any buffer */
193 if (rp->c_type == RC_REPLBUFF) { 395 if (rp->c_type == RC_REPLBUFF) {
@@ -200,9 +402,9 @@ nfsd_cache_lookup(struct svc_rqst *rqstp)
200 return rtn; 402 return rtn;
201 403
202found_entry: 404found_entry:
405 nfsdstats.rchits++;
203 /* We found a matching entry which is either in progress or done. */ 406 /* We found a matching entry which is either in progress or done. */
204 age = jiffies - rp->c_timestamp; 407 age = jiffies - rp->c_timestamp;
205 rp->c_timestamp = jiffies;
206 lru_put_end(rp); 408 lru_put_end(rp);
207 409
208 rtn = RC_DROPIT; 410 rtn = RC_DROPIT;
@@ -231,7 +433,7 @@ found_entry:
231 break; 433 break;
232 default: 434 default:
233 printk(KERN_WARNING "nfsd: bad repcache type %d\n", rp->c_type); 435 printk(KERN_WARNING "nfsd: bad repcache type %d\n", rp->c_type);
234 rp->c_state = RC_UNUSED; 436 nfsd_reply_cache_free_locked(rp);
235 } 437 }
236 438
237 goto out; 439 goto out;
@@ -256,11 +458,11 @@ found_entry:
256void 458void
257nfsd_cache_update(struct svc_rqst *rqstp, int cachetype, __be32 *statp) 459nfsd_cache_update(struct svc_rqst *rqstp, int cachetype, __be32 *statp)
258{ 460{
259 struct svc_cacherep *rp; 461 struct svc_cacherep *rp = rqstp->rq_cacherep;
260 struct kvec *resv = &rqstp->rq_res.head[0], *cachv; 462 struct kvec *resv = &rqstp->rq_res.head[0], *cachv;
261 int len; 463 int len;
262 464
263 if (!(rp = rqstp->rq_cacherep) || cache_disabled) 465 if (!rp)
264 return; 466 return;
265 467
266 len = resv->iov_len - ((char*)statp - (char*)resv->iov_base); 468 len = resv->iov_len - ((char*)statp - (char*)resv->iov_base);
@@ -268,7 +470,7 @@ nfsd_cache_update(struct svc_rqst *rqstp, int cachetype, __be32 *statp)
268 470
269 /* Don't cache excessive amounts of data and XDR failures */ 471 /* Don't cache excessive amounts of data and XDR failures */
270 if (!statp || len > (256 >> 2)) { 472 if (!statp || len > (256 >> 2)) {
271 rp->c_state = RC_UNUSED; 473 nfsd_reply_cache_free(rp);
272 return; 474 return;
273 } 475 }
274 476
@@ -282,21 +484,21 @@ nfsd_cache_update(struct svc_rqst *rqstp, int cachetype, __be32 *statp)
282 cachv = &rp->c_replvec; 484 cachv = &rp->c_replvec;
283 cachv->iov_base = kmalloc(len << 2, GFP_KERNEL); 485 cachv->iov_base = kmalloc(len << 2, GFP_KERNEL);
284 if (!cachv->iov_base) { 486 if (!cachv->iov_base) {
285 spin_lock(&cache_lock); 487 nfsd_reply_cache_free(rp);
286 rp->c_state = RC_UNUSED;
287 spin_unlock(&cache_lock);
288 return; 488 return;
289 } 489 }
290 cachv->iov_len = len << 2; 490 cachv->iov_len = len << 2;
291 memcpy(cachv->iov_base, statp, len << 2); 491 memcpy(cachv->iov_base, statp, len << 2);
292 break; 492 break;
493 case RC_NOCACHE:
494 nfsd_reply_cache_free(rp);
495 return;
293 } 496 }
294 spin_lock(&cache_lock); 497 spin_lock(&cache_lock);
295 lru_put_end(rp); 498 lru_put_end(rp);
296 rp->c_secure = rqstp->rq_secure; 499 rp->c_secure = rqstp->rq_secure;
297 rp->c_type = cachetype; 500 rp->c_type = cachetype;
298 rp->c_state = RC_DONE; 501 rp->c_state = RC_DONE;
299 rp->c_timestamp = jiffies;
300 spin_unlock(&cache_lock); 502 spin_unlock(&cache_lock);
301 return; 503 return;
302} 504}
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index 2db7021b01ae..13a21c8fca49 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -10,7 +10,7 @@
10 10
11#include <linux/sunrpc/svcsock.h> 11#include <linux/sunrpc/svcsock.h>
12#include <linux/lockd/lockd.h> 12#include <linux/lockd/lockd.h>
13#include <linux/sunrpc/clnt.h> 13#include <linux/sunrpc/addr.h>
14#include <linux/sunrpc/gss_api.h> 14#include <linux/sunrpc/gss_api.h>
15#include <linux/sunrpc/gss_krb5_enctypes.h> 15#include <linux/sunrpc/gss_krb5_enctypes.h>
16#include <linux/sunrpc/rpc_pipe_fs.h> 16#include <linux/sunrpc/rpc_pipe_fs.h>
@@ -125,11 +125,11 @@ static const struct file_operations transaction_ops = {
125 .llseek = default_llseek, 125 .llseek = default_llseek,
126}; 126};
127 127
128static int exports_open(struct inode *inode, struct file *file) 128static int exports_net_open(struct net *net, struct file *file)
129{ 129{
130 int err; 130 int err;
131 struct seq_file *seq; 131 struct seq_file *seq;
132 struct nfsd_net *nn = net_generic(&init_net, nfsd_net_id); 132 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
133 133
134 err = seq_open(file, &nfs_exports_op); 134 err = seq_open(file, &nfs_exports_op);
135 if (err) 135 if (err)
@@ -140,8 +140,26 @@ static int exports_open(struct inode *inode, struct file *file)
140 return 0; 140 return 0;
141} 141}
142 142
143static const struct file_operations exports_operations = { 143static int exports_proc_open(struct inode *inode, struct file *file)
144 .open = exports_open, 144{
145 return exports_net_open(current->nsproxy->net_ns, file);
146}
147
148static const struct file_operations exports_proc_operations = {
149 .open = exports_proc_open,
150 .read = seq_read,
151 .llseek = seq_lseek,
152 .release = seq_release,
153 .owner = THIS_MODULE,
154};
155
156static int exports_nfsd_open(struct inode *inode, struct file *file)
157{
158 return exports_net_open(inode->i_sb->s_fs_info, file);
159}
160
161static const struct file_operations exports_nfsd_operations = {
162 .open = exports_nfsd_open,
145 .read = seq_read, 163 .read = seq_read,
146 .llseek = seq_lseek, 164 .llseek = seq_lseek,
147 .release = seq_release, 165 .release = seq_release,
@@ -220,6 +238,7 @@ static ssize_t write_unlock_ip(struct file *file, char *buf, size_t size)
220 struct sockaddr *sap = (struct sockaddr *)&address; 238 struct sockaddr *sap = (struct sockaddr *)&address;
221 size_t salen = sizeof(address); 239 size_t salen = sizeof(address);
222 char *fo_path; 240 char *fo_path;
241 struct net *net = file->f_dentry->d_sb->s_fs_info;
223 242
224 /* sanity check */ 243 /* sanity check */
225 if (size == 0) 244 if (size == 0)
@@ -232,7 +251,7 @@ static ssize_t write_unlock_ip(struct file *file, char *buf, size_t size)
232 if (qword_get(&buf, fo_path, size) < 0) 251 if (qword_get(&buf, fo_path, size) < 0)
233 return -EINVAL; 252 return -EINVAL;
234 253
235 if (rpc_pton(&init_net, fo_path, size, sap, salen) == 0) 254 if (rpc_pton(net, fo_path, size, sap, salen) == 0)
236 return -EINVAL; 255 return -EINVAL;
237 256
238 return nlmsvc_unlock_all_by_ip(sap); 257 return nlmsvc_unlock_all_by_ip(sap);
@@ -317,6 +336,7 @@ static ssize_t write_filehandle(struct file *file, char *buf, size_t size)
317 int len; 336 int len;
318 struct auth_domain *dom; 337 struct auth_domain *dom;
319 struct knfsd_fh fh; 338 struct knfsd_fh fh;
339 struct net *net = file->f_dentry->d_sb->s_fs_info;
320 340
321 if (size == 0) 341 if (size == 0)
322 return -EINVAL; 342 return -EINVAL;
@@ -352,7 +372,7 @@ static ssize_t write_filehandle(struct file *file, char *buf, size_t size)
352 if (!dom) 372 if (!dom)
353 return -ENOMEM; 373 return -ENOMEM;
354 374
355 len = exp_rootfh(&init_net, dom, path, &fh, maxsize); 375 len = exp_rootfh(net, dom, path, &fh, maxsize);
356 auth_domain_put(dom); 376 auth_domain_put(dom);
357 if (len) 377 if (len)
358 return len; 378 return len;
@@ -396,7 +416,7 @@ static ssize_t write_threads(struct file *file, char *buf, size_t size)
396{ 416{
397 char *mesg = buf; 417 char *mesg = buf;
398 int rv; 418 int rv;
399 struct net *net = &init_net; 419 struct net *net = file->f_dentry->d_sb->s_fs_info;
400 420
401 if (size > 0) { 421 if (size > 0) {
402 int newthreads; 422 int newthreads;
@@ -447,7 +467,7 @@ static ssize_t write_pool_threads(struct file *file, char *buf, size_t size)
447 int len; 467 int len;
448 int npools; 468 int npools;
449 int *nthreads; 469 int *nthreads;
450 struct net *net = &init_net; 470 struct net *net = file->f_dentry->d_sb->s_fs_info;
451 471
452 mutex_lock(&nfsd_mutex); 472 mutex_lock(&nfsd_mutex);
453 npools = nfsd_nrpools(net); 473 npools = nfsd_nrpools(net);
@@ -510,7 +530,7 @@ static ssize_t __write_versions(struct file *file, char *buf, size_t size)
510 unsigned minor; 530 unsigned minor;
511 ssize_t tlen = 0; 531 ssize_t tlen = 0;
512 char *sep; 532 char *sep;
513 struct net *net = &init_net; 533 struct net *net = file->f_dentry->d_sb->s_fs_info;
514 struct nfsd_net *nn = net_generic(net, nfsd_net_id); 534 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
515 535
516 if (size>0) { 536 if (size>0) {
@@ -534,7 +554,7 @@ static ssize_t __write_versions(struct file *file, char *buf, size_t size)
534 else 554 else
535 num = simple_strtol(vers, &minorp, 0); 555 num = simple_strtol(vers, &minorp, 0);
536 if (*minorp == '.') { 556 if (*minorp == '.') {
537 if (num < 4) 557 if (num != 4)
538 return -EINVAL; 558 return -EINVAL;
539 minor = simple_strtoul(minorp+1, NULL, 0); 559 minor = simple_strtoul(minorp+1, NULL, 0);
540 if (minor == 0) 560 if (minor == 0)
@@ -792,7 +812,7 @@ static ssize_t __write_ports(struct file *file, char *buf, size_t size,
792static ssize_t write_ports(struct file *file, char *buf, size_t size) 812static ssize_t write_ports(struct file *file, char *buf, size_t size)
793{ 813{
794 ssize_t rv; 814 ssize_t rv;
795 struct net *net = &init_net; 815 struct net *net = file->f_dentry->d_sb->s_fs_info;
796 816
797 mutex_lock(&nfsd_mutex); 817 mutex_lock(&nfsd_mutex);
798 rv = __write_ports(file, buf, size, net); 818 rv = __write_ports(file, buf, size, net);
@@ -827,7 +847,7 @@ int nfsd_max_blksize;
827static ssize_t write_maxblksize(struct file *file, char *buf, size_t size) 847static ssize_t write_maxblksize(struct file *file, char *buf, size_t size)
828{ 848{
829 char *mesg = buf; 849 char *mesg = buf;
830 struct net *net = &init_net; 850 struct net *net = file->f_dentry->d_sb->s_fs_info;
831 struct nfsd_net *nn = net_generic(net, nfsd_net_id); 851 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
832 852
833 if (size > 0) { 853 if (size > 0) {
@@ -923,7 +943,8 @@ static ssize_t nfsd4_write_time(struct file *file, char *buf, size_t size,
923 */ 943 */
924static ssize_t write_leasetime(struct file *file, char *buf, size_t size) 944static ssize_t write_leasetime(struct file *file, char *buf, size_t size)
925{ 945{
926 struct nfsd_net *nn = net_generic(&init_net, nfsd_net_id); 946 struct net *net = file->f_dentry->d_sb->s_fs_info;
947 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
927 return nfsd4_write_time(file, buf, size, &nn->nfsd4_lease, nn); 948 return nfsd4_write_time(file, buf, size, &nn->nfsd4_lease, nn);
928} 949}
929 950
@@ -939,7 +960,8 @@ static ssize_t write_leasetime(struct file *file, char *buf, size_t size)
939 */ 960 */
940static ssize_t write_gracetime(struct file *file, char *buf, size_t size) 961static ssize_t write_gracetime(struct file *file, char *buf, size_t size)
941{ 962{
942 struct nfsd_net *nn = net_generic(&init_net, nfsd_net_id); 963 struct net *net = file->f_dentry->d_sb->s_fs_info;
964 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
943 return nfsd4_write_time(file, buf, size, &nn->nfsd4_grace, nn); 965 return nfsd4_write_time(file, buf, size, &nn->nfsd4_grace, nn);
944} 966}
945 967
@@ -995,7 +1017,8 @@ static ssize_t __write_recoverydir(struct file *file, char *buf, size_t size,
995static ssize_t write_recoverydir(struct file *file, char *buf, size_t size) 1017static ssize_t write_recoverydir(struct file *file, char *buf, size_t size)
996{ 1018{
997 ssize_t rv; 1019 ssize_t rv;
998 struct nfsd_net *nn = net_generic(&init_net, nfsd_net_id); 1020 struct net *net = file->f_dentry->d_sb->s_fs_info;
1021 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
999 1022
1000 mutex_lock(&nfsd_mutex); 1023 mutex_lock(&nfsd_mutex);
1001 rv = __write_recoverydir(file, buf, size, nn); 1024 rv = __write_recoverydir(file, buf, size, nn);
@@ -1013,7 +1036,7 @@ static ssize_t write_recoverydir(struct file *file, char *buf, size_t size)
1013static int nfsd_fill_super(struct super_block * sb, void * data, int silent) 1036static int nfsd_fill_super(struct super_block * sb, void * data, int silent)
1014{ 1037{
1015 static struct tree_descr nfsd_files[] = { 1038 static struct tree_descr nfsd_files[] = {
1016 [NFSD_List] = {"exports", &exports_operations, S_IRUGO}, 1039 [NFSD_List] = {"exports", &exports_nfsd_operations, S_IRUGO},
1017 [NFSD_Export_features] = {"export_features", 1040 [NFSD_Export_features] = {"export_features",
1018 &export_features_operations, S_IRUGO}, 1041 &export_features_operations, S_IRUGO},
1019 [NFSD_FO_UnlockIP] = {"unlock_ip", 1042 [NFSD_FO_UnlockIP] = {"unlock_ip",
@@ -1037,20 +1060,35 @@ static int nfsd_fill_super(struct super_block * sb, void * data, int silent)
1037#endif 1060#endif
1038 /* last one */ {""} 1061 /* last one */ {""}
1039 }; 1062 };
1040 return simple_fill_super(sb, 0x6e667364, nfsd_files); 1063 struct net *net = data;
1064 int ret;
1065
1066 ret = simple_fill_super(sb, 0x6e667364, nfsd_files);
1067 if (ret)
1068 return ret;
1069 sb->s_fs_info = get_net(net);
1070 return 0;
1041} 1071}
1042 1072
1043static struct dentry *nfsd_mount(struct file_system_type *fs_type, 1073static struct dentry *nfsd_mount(struct file_system_type *fs_type,
1044 int flags, const char *dev_name, void *data) 1074 int flags, const char *dev_name, void *data)
1045{ 1075{
1046 return mount_single(fs_type, flags, data, nfsd_fill_super); 1076 return mount_ns(fs_type, flags, current->nsproxy->net_ns, nfsd_fill_super);
1077}
1078
1079static void nfsd_umount(struct super_block *sb)
1080{
1081 struct net *net = sb->s_fs_info;
1082
1083 kill_litter_super(sb);
1084 put_net(net);
1047} 1085}
1048 1086
1049static struct file_system_type nfsd_fs_type = { 1087static struct file_system_type nfsd_fs_type = {
1050 .owner = THIS_MODULE, 1088 .owner = THIS_MODULE,
1051 .name = "nfsd", 1089 .name = "nfsd",
1052 .mount = nfsd_mount, 1090 .mount = nfsd_mount,
1053 .kill_sb = kill_litter_super, 1091 .kill_sb = nfsd_umount,
1054}; 1092};
1055 1093
1056#ifdef CONFIG_PROC_FS 1094#ifdef CONFIG_PROC_FS
@@ -1061,7 +1099,8 @@ static int create_proc_exports_entry(void)
1061 entry = proc_mkdir("fs/nfs", NULL); 1099 entry = proc_mkdir("fs/nfs", NULL);
1062 if (!entry) 1100 if (!entry)
1063 return -ENOMEM; 1101 return -ENOMEM;
1064 entry = proc_create("exports", 0, entry, &exports_operations); 1102 entry = proc_create("exports", 0, entry,
1103 &exports_proc_operations);
1065 if (!entry) 1104 if (!entry)
1066 return -ENOMEM; 1105 return -ENOMEM;
1067 return 0; 1106 return 0;
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index be7af509930c..262df5ccbf59 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -652,7 +652,6 @@ nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp)
652 652
653 /* Check whether we have this call in the cache. */ 653 /* Check whether we have this call in the cache. */
654 switch (nfsd_cache_lookup(rqstp)) { 654 switch (nfsd_cache_lookup(rqstp)) {
655 case RC_INTR:
656 case RC_DROPIT: 655 case RC_DROPIT:
657 return 0; 656 return 0;
658 case RC_REPLY: 657 case RC_REPLY:
@@ -703,8 +702,7 @@ nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp)
703int nfsd_pool_stats_open(struct inode *inode, struct file *file) 702int nfsd_pool_stats_open(struct inode *inode, struct file *file)
704{ 703{
705 int ret; 704 int ret;
706 struct net *net = &init_net; 705 struct nfsd_net *nn = net_generic(inode->i_sb->s_fs_info, nfsd_net_id);
707 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
708 706
709 mutex_lock(&nfsd_mutex); 707 mutex_lock(&nfsd_mutex);
710 if (nn->nfsd_serv == NULL) { 708 if (nn->nfsd_serv == NULL) {
@@ -721,7 +719,7 @@ int nfsd_pool_stats_open(struct inode *inode, struct file *file)
721int nfsd_pool_stats_release(struct inode *inode, struct file *file) 719int nfsd_pool_stats_release(struct inode *inode, struct file *file)
722{ 720{
723 int ret = seq_release(inode, file); 721 int ret = seq_release(inode, file);
724 struct net *net = &init_net; 722 struct net *net = inode->i_sb->s_fs_info;
725 723
726 mutex_lock(&nfsd_mutex); 724 mutex_lock(&nfsd_mutex);
727 /* this function really, really should have been called svc_put() */ 725 /* this function really, really should have been called svc_put() */
diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h
index 0889bfb43dc9..546f8983ecf1 100644
--- a/fs/nfsd/xdr4.h
+++ b/fs/nfsd/xdr4.h
@@ -563,7 +563,7 @@ __be32 nfsd4_check_resp_size(struct nfsd4_compoundres *, u32);
563void nfsd4_encode_operation(struct nfsd4_compoundres *, struct nfsd4_op *); 563void nfsd4_encode_operation(struct nfsd4_compoundres *, struct nfsd4_op *);
564void nfsd4_encode_replay(struct nfsd4_compoundres *resp, struct nfsd4_op *op); 564void nfsd4_encode_replay(struct nfsd4_compoundres *resp, struct nfsd4_op *op);
565__be32 nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp, 565__be32 nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
566 struct dentry *dentry, __be32 *buffer, int *countp, 566 struct dentry *dentry, __be32 **buffer, int countp,
567 u32 *bmval, struct svc_rqst *, int ignore_crossmnt); 567 u32 *bmval, struct svc_rqst *, int ignore_crossmnt);
568extern __be32 nfsd4_setclientid(struct svc_rqst *rqstp, 568extern __be32 nfsd4_setclientid(struct svc_rqst *rqstp,
569 struct nfsd4_compound_state *, 569 struct nfsd4_compound_state *,
diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h
index 0e62d84f9f7f..dcaad79f54ed 100644
--- a/include/linux/lockd/lockd.h
+++ b/include/linux/lockd/lockd.h
@@ -212,7 +212,8 @@ int nlmclnt_block(struct nlm_wait *block, struct nlm_rqst *req, long timeout)
212__be32 nlmclnt_grant(const struct sockaddr *addr, 212__be32 nlmclnt_grant(const struct sockaddr *addr,
213 const struct nlm_lock *lock); 213 const struct nlm_lock *lock);
214void nlmclnt_recovery(struct nlm_host *); 214void nlmclnt_recovery(struct nlm_host *);
215int nlmclnt_reclaim(struct nlm_host *, struct file_lock *); 215int nlmclnt_reclaim(struct nlm_host *, struct file_lock *,
216 struct nlm_rqst *);
216void nlmclnt_next_cookie(struct nlm_cookie *); 217void nlmclnt_next_cookie(struct nlm_cookie *);
217 218
218/* 219/*
diff --git a/include/linux/sunrpc/addr.h b/include/linux/sunrpc/addr.h
new file mode 100644
index 000000000000..07d8e53bedfc
--- /dev/null
+++ b/include/linux/sunrpc/addr.h
@@ -0,0 +1,170 @@
1/*
2 * linux/include/linux/sunrpc/addr.h
3 *
4 * Various routines for copying and comparing sockaddrs and for
5 * converting them to and from presentation format.
6 */
7#ifndef _LINUX_SUNRPC_ADDR_H
8#define _LINUX_SUNRPC_ADDR_H
9
10#include <linux/socket.h>
11#include <linux/in.h>
12#include <linux/in6.h>
13#include <net/ipv6.h>
14
15size_t rpc_ntop(const struct sockaddr *, char *, const size_t);
16size_t rpc_pton(struct net *, const char *, const size_t,
17 struct sockaddr *, const size_t);
18char * rpc_sockaddr2uaddr(const struct sockaddr *, gfp_t);
19size_t rpc_uaddr2sockaddr(struct net *, const char *, const size_t,
20 struct sockaddr *, const size_t);
21
22static inline unsigned short rpc_get_port(const struct sockaddr *sap)
23{
24 switch (sap->sa_family) {
25 case AF_INET:
26 return ntohs(((struct sockaddr_in *)sap)->sin_port);
27 case AF_INET6:
28 return ntohs(((struct sockaddr_in6 *)sap)->sin6_port);
29 }
30 return 0;
31}
32
33static inline void rpc_set_port(struct sockaddr *sap,
34 const unsigned short port)
35{
36 switch (sap->sa_family) {
37 case AF_INET:
38 ((struct sockaddr_in *)sap)->sin_port = htons(port);
39 break;
40 case AF_INET6:
41 ((struct sockaddr_in6 *)sap)->sin6_port = htons(port);
42 break;
43 }
44}
45
46#define IPV6_SCOPE_DELIMITER '%'
47#define IPV6_SCOPE_ID_LEN sizeof("%nnnnnnnnnn")
48
49static inline bool __rpc_cmp_addr4(const struct sockaddr *sap1,
50 const struct sockaddr *sap2)
51{
52 const struct sockaddr_in *sin1 = (const struct sockaddr_in *)sap1;
53 const struct sockaddr_in *sin2 = (const struct sockaddr_in *)sap2;
54
55 return sin1->sin_addr.s_addr == sin2->sin_addr.s_addr;
56}
57
58static inline bool __rpc_copy_addr4(struct sockaddr *dst,
59 const struct sockaddr *src)
60{
61 const struct sockaddr_in *ssin = (struct sockaddr_in *) src;
62 struct sockaddr_in *dsin = (struct sockaddr_in *) dst;
63
64 dsin->sin_family = ssin->sin_family;
65 dsin->sin_addr.s_addr = ssin->sin_addr.s_addr;
66 return true;
67}
68
69#if IS_ENABLED(CONFIG_IPV6)
70static inline bool __rpc_cmp_addr6(const struct sockaddr *sap1,
71 const struct sockaddr *sap2)
72{
73 const struct sockaddr_in6 *sin1 = (const struct sockaddr_in6 *)sap1;
74 const struct sockaddr_in6 *sin2 = (const struct sockaddr_in6 *)sap2;
75
76 if (!ipv6_addr_equal(&sin1->sin6_addr, &sin2->sin6_addr))
77 return false;
78 else if (ipv6_addr_type(&sin1->sin6_addr) & IPV6_ADDR_LINKLOCAL)
79 return sin1->sin6_scope_id == sin2->sin6_scope_id;
80
81 return true;
82}
83
84static inline bool __rpc_copy_addr6(struct sockaddr *dst,
85 const struct sockaddr *src)
86{
87 const struct sockaddr_in6 *ssin6 = (const struct sockaddr_in6 *) src;
88 struct sockaddr_in6 *dsin6 = (struct sockaddr_in6 *) dst;
89
90 dsin6->sin6_family = ssin6->sin6_family;
91 dsin6->sin6_addr = ssin6->sin6_addr;
92 dsin6->sin6_scope_id = ssin6->sin6_scope_id;
93 return true;
94}
95#else /* !(IS_ENABLED(CONFIG_IPV6) */
96static inline bool __rpc_cmp_addr6(const struct sockaddr *sap1,
97 const struct sockaddr *sap2)
98{
99 return false;
100}
101
102static inline bool __rpc_copy_addr6(struct sockaddr *dst,
103 const struct sockaddr *src)
104{
105 return false;
106}
107#endif /* !(IS_ENABLED(CONFIG_IPV6) */
108
109/**
110 * rpc_cmp_addr - compare the address portion of two sockaddrs.
111 * @sap1: first sockaddr
112 * @sap2: second sockaddr
113 *
114 * Just compares the family and address portion. Ignores port, but
115 * compares the scope if it's a link-local address.
116 *
117 * Returns true if the addrs are equal, false if they aren't.
118 */
119static inline bool rpc_cmp_addr(const struct sockaddr *sap1,
120 const struct sockaddr *sap2)
121{
122 if (sap1->sa_family == sap2->sa_family) {
123 switch (sap1->sa_family) {
124 case AF_INET:
125 return __rpc_cmp_addr4(sap1, sap2);
126 case AF_INET6:
127 return __rpc_cmp_addr6(sap1, sap2);
128 }
129 }
130 return false;
131}
132
133/**
134 * rpc_copy_addr - copy the address portion of one sockaddr to another
135 * @dst: destination sockaddr
136 * @src: source sockaddr
137 *
138 * Just copies the address portion and family. Ignores port, scope, etc.
139 * Caller is responsible for making certain that dst is large enough to hold
140 * the address in src. Returns true if address family is supported. Returns
141 * false otherwise.
142 */
143static inline bool rpc_copy_addr(struct sockaddr *dst,
144 const struct sockaddr *src)
145{
146 switch (src->sa_family) {
147 case AF_INET:
148 return __rpc_copy_addr4(dst, src);
149 case AF_INET6:
150 return __rpc_copy_addr6(dst, src);
151 }
152 return false;
153}
154
155/**
156 * rpc_get_scope_id - return scopeid for a given sockaddr
157 * @sa: sockaddr to get scopeid from
158 *
159 * Returns the value of the sin6_scope_id for AF_INET6 addrs, or 0 if
160 * not an AF_INET6 address.
161 */
162static inline u32 rpc_get_scope_id(const struct sockaddr *sa)
163{
164 if (sa->sa_family != AF_INET6)
165 return 0;
166
167 return ((struct sockaddr_in6 *) sa)->sin6_scope_id;
168}
169
170#endif /* _LINUX_SUNRPC_ADDR_H */
diff --git a/include/linux/sunrpc/cache.h b/include/linux/sunrpc/cache.h
index 5dc9ee4d616e..303399b1ba59 100644
--- a/include/linux/sunrpc/cache.h
+++ b/include/linux/sunrpc/cache.h
@@ -83,6 +83,10 @@ struct cache_detail {
83 int (*cache_upcall)(struct cache_detail *, 83 int (*cache_upcall)(struct cache_detail *,
84 struct cache_head *); 84 struct cache_head *);
85 85
86 void (*cache_request)(struct cache_detail *cd,
87 struct cache_head *ch,
88 char **bpp, int *blen);
89
86 int (*cache_parse)(struct cache_detail *, 90 int (*cache_parse)(struct cache_detail *,
87 char *buf, int len); 91 char *buf, int len);
88 92
@@ -157,11 +161,7 @@ sunrpc_cache_update(struct cache_detail *detail,
157 struct cache_head *new, struct cache_head *old, int hash); 161 struct cache_head *new, struct cache_head *old, int hash);
158 162
159extern int 163extern int
160sunrpc_cache_pipe_upcall(struct cache_detail *detail, struct cache_head *h, 164sunrpc_cache_pipe_upcall(struct cache_detail *detail, struct cache_head *h);
161 void (*cache_request)(struct cache_detail *,
162 struct cache_head *,
163 char **,
164 int *));
165 165
166 166
167extern void cache_clean_deferred(void *owner); 167extern void cache_clean_deferred(void *owner);
diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
index 34206b84d8da..4a4abde000cb 100644
--- a/include/linux/sunrpc/clnt.h
+++ b/include/linux/sunrpc/clnt.h
@@ -165,157 +165,5 @@ size_t rpc_peeraddr(struct rpc_clnt *, struct sockaddr *, size_t);
165const char *rpc_peeraddr2str(struct rpc_clnt *, enum rpc_display_format_t); 165const char *rpc_peeraddr2str(struct rpc_clnt *, enum rpc_display_format_t);
166int rpc_localaddr(struct rpc_clnt *, struct sockaddr *, size_t); 166int rpc_localaddr(struct rpc_clnt *, struct sockaddr *, size_t);
167 167
168size_t rpc_ntop(const struct sockaddr *, char *, const size_t);
169size_t rpc_pton(struct net *, const char *, const size_t,
170 struct sockaddr *, const size_t);
171char * rpc_sockaddr2uaddr(const struct sockaddr *, gfp_t);
172size_t rpc_uaddr2sockaddr(struct net *, const char *, const size_t,
173 struct sockaddr *, const size_t);
174
175static inline unsigned short rpc_get_port(const struct sockaddr *sap)
176{
177 switch (sap->sa_family) {
178 case AF_INET:
179 return ntohs(((struct sockaddr_in *)sap)->sin_port);
180 case AF_INET6:
181 return ntohs(((struct sockaddr_in6 *)sap)->sin6_port);
182 }
183 return 0;
184}
185
186static inline void rpc_set_port(struct sockaddr *sap,
187 const unsigned short port)
188{
189 switch (sap->sa_family) {
190 case AF_INET:
191 ((struct sockaddr_in *)sap)->sin_port = htons(port);
192 break;
193 case AF_INET6:
194 ((struct sockaddr_in6 *)sap)->sin6_port = htons(port);
195 break;
196 }
197}
198
199#define IPV6_SCOPE_DELIMITER '%'
200#define IPV6_SCOPE_ID_LEN sizeof("%nnnnnnnnnn")
201
202static inline bool __rpc_cmp_addr4(const struct sockaddr *sap1,
203 const struct sockaddr *sap2)
204{
205 const struct sockaddr_in *sin1 = (const struct sockaddr_in *)sap1;
206 const struct sockaddr_in *sin2 = (const struct sockaddr_in *)sap2;
207
208 return sin1->sin_addr.s_addr == sin2->sin_addr.s_addr;
209}
210
211static inline bool __rpc_copy_addr4(struct sockaddr *dst,
212 const struct sockaddr *src)
213{
214 const struct sockaddr_in *ssin = (struct sockaddr_in *) src;
215 struct sockaddr_in *dsin = (struct sockaddr_in *) dst;
216
217 dsin->sin_family = ssin->sin_family;
218 dsin->sin_addr.s_addr = ssin->sin_addr.s_addr;
219 return true;
220}
221
222#if IS_ENABLED(CONFIG_IPV6)
223static inline bool __rpc_cmp_addr6(const struct sockaddr *sap1,
224 const struct sockaddr *sap2)
225{
226 const struct sockaddr_in6 *sin1 = (const struct sockaddr_in6 *)sap1;
227 const struct sockaddr_in6 *sin2 = (const struct sockaddr_in6 *)sap2;
228
229 if (!ipv6_addr_equal(&sin1->sin6_addr, &sin2->sin6_addr))
230 return false;
231 else if (ipv6_addr_type(&sin1->sin6_addr) & IPV6_ADDR_LINKLOCAL)
232 return sin1->sin6_scope_id == sin2->sin6_scope_id;
233
234 return true;
235}
236
237static inline bool __rpc_copy_addr6(struct sockaddr *dst,
238 const struct sockaddr *src)
239{
240 const struct sockaddr_in6 *ssin6 = (const struct sockaddr_in6 *) src;
241 struct sockaddr_in6 *dsin6 = (struct sockaddr_in6 *) dst;
242
243 dsin6->sin6_family = ssin6->sin6_family;
244 dsin6->sin6_addr = ssin6->sin6_addr;
245 return true;
246}
247#else /* !(IS_ENABLED(CONFIG_IPV6) */
248static inline bool __rpc_cmp_addr6(const struct sockaddr *sap1,
249 const struct sockaddr *sap2)
250{
251 return false;
252}
253
254static inline bool __rpc_copy_addr6(struct sockaddr *dst,
255 const struct sockaddr *src)
256{
257 return false;
258}
259#endif /* !(IS_ENABLED(CONFIG_IPV6) */
260
261/**
262 * rpc_cmp_addr - compare the address portion of two sockaddrs.
263 * @sap1: first sockaddr
264 * @sap2: second sockaddr
265 *
266 * Just compares the family and address portion. Ignores port, scope, etc.
267 * Returns true if the addrs are equal, false if they aren't.
268 */
269static inline bool rpc_cmp_addr(const struct sockaddr *sap1,
270 const struct sockaddr *sap2)
271{
272 if (sap1->sa_family == sap2->sa_family) {
273 switch (sap1->sa_family) {
274 case AF_INET:
275 return __rpc_cmp_addr4(sap1, sap2);
276 case AF_INET6:
277 return __rpc_cmp_addr6(sap1, sap2);
278 }
279 }
280 return false;
281}
282
283/**
284 * rpc_copy_addr - copy the address portion of one sockaddr to another
285 * @dst: destination sockaddr
286 * @src: source sockaddr
287 *
288 * Just copies the address portion and family. Ignores port, scope, etc.
289 * Caller is responsible for making certain that dst is large enough to hold
290 * the address in src. Returns true if address family is supported. Returns
291 * false otherwise.
292 */
293static inline bool rpc_copy_addr(struct sockaddr *dst,
294 const struct sockaddr *src)
295{
296 switch (src->sa_family) {
297 case AF_INET:
298 return __rpc_copy_addr4(dst, src);
299 case AF_INET6:
300 return __rpc_copy_addr6(dst, src);
301 }
302 return false;
303}
304
305/**
306 * rpc_get_scope_id - return scopeid for a given sockaddr
307 * @sa: sockaddr to get scopeid from
308 *
309 * Returns the value of the sin6_scope_id for AF_INET6 addrs, or 0 if
310 * not an AF_INET6 address.
311 */
312static inline u32 rpc_get_scope_id(const struct sockaddr *sa)
313{
314 if (sa->sa_family != AF_INET6)
315 return 0;
316
317 return ((struct sockaddr_in6 *) sa)->sin6_scope_id;
318}
319
320#endif /* __KERNEL__ */ 168#endif /* __KERNEL__ */
321#endif /* _LINUX_SUNRPC_CLNT_H */ 169#endif /* _LINUX_SUNRPC_CLNT_H */
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
index 676ddf53b3ee..1f0216b9a6c9 100644
--- a/include/linux/sunrpc/svc.h
+++ b/include/linux/sunrpc/svc.h
@@ -50,6 +50,7 @@ struct svc_pool {
50 unsigned int sp_nrthreads; /* # of threads in pool */ 50 unsigned int sp_nrthreads; /* # of threads in pool */
51 struct list_head sp_all_threads; /* all server threads */ 51 struct list_head sp_all_threads; /* all server threads */
52 struct svc_pool_stats sp_stats; /* statistics on pool operation */ 52 struct svc_pool_stats sp_stats; /* statistics on pool operation */
53 int sp_task_pending;/* has pending task */
53} ____cacheline_aligned_in_smp; 54} ____cacheline_aligned_in_smp;
54 55
55/* 56/*
diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h
index 63988990bd36..15f9204ee70b 100644
--- a/include/linux/sunrpc/xdr.h
+++ b/include/linux/sunrpc/xdr.h
@@ -56,7 +56,7 @@ struct xdr_buf {
56 struct kvec head[1], /* RPC header + non-page data */ 56 struct kvec head[1], /* RPC header + non-page data */
57 tail[1]; /* Appended after page data */ 57 tail[1]; /* Appended after page data */
58 58
59 struct page ** pages; /* Array of contiguous pages */ 59 struct page ** pages; /* Array of pages */
60 unsigned int page_base, /* Start of page data */ 60 unsigned int page_base, /* Start of page data */
61 page_len, /* Length of page data */ 61 page_len, /* Length of page data */
62 flags; /* Flags for data disposition */ 62 flags; /* Flags for data disposition */
@@ -152,6 +152,7 @@ xdr_adjust_iovec(struct kvec *iov, __be32 *p)
152extern void xdr_shift_buf(struct xdr_buf *, size_t); 152extern void xdr_shift_buf(struct xdr_buf *, size_t);
153extern void xdr_buf_from_iov(struct kvec *, struct xdr_buf *); 153extern void xdr_buf_from_iov(struct kvec *, struct xdr_buf *);
154extern int xdr_buf_subsegment(struct xdr_buf *, struct xdr_buf *, unsigned int, unsigned int); 154extern int xdr_buf_subsegment(struct xdr_buf *, struct xdr_buf *, unsigned int, unsigned int);
155extern void xdr_buf_trim(struct xdr_buf *, unsigned int);
155extern int xdr_buf_read_netobj(struct xdr_buf *, struct xdr_netobj *, unsigned int); 156extern int xdr_buf_read_netobj(struct xdr_buf *, struct xdr_netobj *, unsigned int);
156extern int read_bytes_from_xdr_buf(struct xdr_buf *, unsigned int, void *, unsigned int); 157extern int read_bytes_from_xdr_buf(struct xdr_buf *, unsigned int, void *, unsigned int);
157extern int write_bytes_to_xdr_buf(struct xdr_buf *, unsigned int, void *, unsigned int); 158extern int write_bytes_to_xdr_buf(struct xdr_buf *, unsigned int, void *, unsigned int);
diff --git a/net/sunrpc/addr.c b/net/sunrpc/addr.c
index d11418f97f1f..a622ad64acd8 100644
--- a/net/sunrpc/addr.c
+++ b/net/sunrpc/addr.c
@@ -17,7 +17,8 @@
17 */ 17 */
18 18
19#include <net/ipv6.h> 19#include <net/ipv6.h>
20#include <linux/sunrpc/clnt.h> 20#include <linux/sunrpc/addr.h>
21#include <linux/sunrpc/msg_prot.h>
21#include <linux/slab.h> 22#include <linux/slab.h>
22#include <linux/export.h> 23#include <linux/export.h>
23 24
diff --git a/net/sunrpc/auth_gss/gss_krb5_wrap.c b/net/sunrpc/auth_gss/gss_krb5_wrap.c
index 107c4528654f..88edec929d73 100644
--- a/net/sunrpc/auth_gss/gss_krb5_wrap.c
+++ b/net/sunrpc/auth_gss/gss_krb5_wrap.c
@@ -574,6 +574,8 @@ gss_unwrap_kerberos_v2(struct krb5_ctx *kctx, int offset, struct xdr_buf *buf)
574 buf->head[0].iov_len -= GSS_KRB5_TOK_HDR_LEN + headskip; 574 buf->head[0].iov_len -= GSS_KRB5_TOK_HDR_LEN + headskip;
575 buf->len -= GSS_KRB5_TOK_HDR_LEN + headskip; 575 buf->len -= GSS_KRB5_TOK_HDR_LEN + headskip;
576 576
577 /* Trim off the checksum blob */
578 xdr_buf_trim(buf, GSS_KRB5_TOK_HDR_LEN + tailskip);
577 return GSS_S_COMPLETE; 579 return GSS_S_COMPLETE;
578} 580}
579 581
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
index ecd1d58bf611..f7d34e7b6f81 100644
--- a/net/sunrpc/auth_gss/svcauth_gss.c
+++ b/net/sunrpc/auth_gss/svcauth_gss.c
@@ -182,12 +182,6 @@ static void rsi_request(struct cache_detail *cd,
182 (*bpp)[-1] = '\n'; 182 (*bpp)[-1] = '\n';
183} 183}
184 184
185static int rsi_upcall(struct cache_detail *cd, struct cache_head *h)
186{
187 return sunrpc_cache_pipe_upcall(cd, h, rsi_request);
188}
189
190
191static int rsi_parse(struct cache_detail *cd, 185static int rsi_parse(struct cache_detail *cd,
192 char *mesg, int mlen) 186 char *mesg, int mlen)
193{ 187{
@@ -275,7 +269,7 @@ static struct cache_detail rsi_cache_template = {
275 .hash_size = RSI_HASHMAX, 269 .hash_size = RSI_HASHMAX,
276 .name = "auth.rpcsec.init", 270 .name = "auth.rpcsec.init",
277 .cache_put = rsi_put, 271 .cache_put = rsi_put,
278 .cache_upcall = rsi_upcall, 272 .cache_request = rsi_request,
279 .cache_parse = rsi_parse, 273 .cache_parse = rsi_parse,
280 .match = rsi_match, 274 .match = rsi_match,
281 .init = rsi_init, 275 .init = rsi_init,
@@ -825,13 +819,17 @@ read_u32_from_xdr_buf(struct xdr_buf *buf, int base, u32 *obj)
825 * The server uses base of head iovec as read pointer, while the 819 * The server uses base of head iovec as read pointer, while the
826 * client uses separate pointer. */ 820 * client uses separate pointer. */
827static int 821static int
828unwrap_integ_data(struct xdr_buf *buf, u32 seq, struct gss_ctx *ctx) 822unwrap_integ_data(struct svc_rqst *rqstp, struct xdr_buf *buf, u32 seq, struct gss_ctx *ctx)
829{ 823{
830 int stat = -EINVAL; 824 int stat = -EINVAL;
831 u32 integ_len, maj_stat; 825 u32 integ_len, maj_stat;
832 struct xdr_netobj mic; 826 struct xdr_netobj mic;
833 struct xdr_buf integ_buf; 827 struct xdr_buf integ_buf;
834 828
829 /* Did we already verify the signature on the original pass through? */
830 if (rqstp->rq_deferred)
831 return 0;
832
835 integ_len = svc_getnl(&buf->head[0]); 833 integ_len = svc_getnl(&buf->head[0]);
836 if (integ_len & 3) 834 if (integ_len & 3)
837 return stat; 835 return stat;
@@ -854,6 +852,8 @@ unwrap_integ_data(struct xdr_buf *buf, u32 seq, struct gss_ctx *ctx)
854 goto out; 852 goto out;
855 if (svc_getnl(&buf->head[0]) != seq) 853 if (svc_getnl(&buf->head[0]) != seq)
856 goto out; 854 goto out;
855 /* trim off the mic at the end before returning */
856 xdr_buf_trim(buf, mic.len + 4);
857 stat = 0; 857 stat = 0;
858out: 858out:
859 kfree(mic.data); 859 kfree(mic.data);
@@ -1198,7 +1198,7 @@ svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp)
1198 /* placeholders for length and seq. number: */ 1198 /* placeholders for length and seq. number: */
1199 svc_putnl(resv, 0); 1199 svc_putnl(resv, 0);
1200 svc_putnl(resv, 0); 1200 svc_putnl(resv, 0);
1201 if (unwrap_integ_data(&rqstp->rq_arg, 1201 if (unwrap_integ_data(rqstp, &rqstp->rq_arg,
1202 gc->gc_seq, rsci->mechctx)) 1202 gc->gc_seq, rsci->mechctx))
1203 goto garbage_args; 1203 goto garbage_args;
1204 break; 1204 break;
diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c
index 39a4112faf54..25d58e766014 100644
--- a/net/sunrpc/cache.c
+++ b/net/sunrpc/cache.c
@@ -196,9 +196,9 @@ EXPORT_SYMBOL_GPL(sunrpc_cache_update);
196 196
197static int cache_make_upcall(struct cache_detail *cd, struct cache_head *h) 197static int cache_make_upcall(struct cache_detail *cd, struct cache_head *h)
198{ 198{
199 if (!cd->cache_upcall) 199 if (cd->cache_upcall)
200 return -EINVAL; 200 return cd->cache_upcall(cd, h);
201 return cd->cache_upcall(cd, h); 201 return sunrpc_cache_pipe_upcall(cd, h);
202} 202}
203 203
204static inline int cache_is_valid(struct cache_detail *detail, struct cache_head *h) 204static inline int cache_is_valid(struct cache_detail *detail, struct cache_head *h)
@@ -750,6 +750,18 @@ struct cache_reader {
750 int offset; /* if non-0, we have a refcnt on next request */ 750 int offset; /* if non-0, we have a refcnt on next request */
751}; 751};
752 752
753static int cache_request(struct cache_detail *detail,
754 struct cache_request *crq)
755{
756 char *bp = crq->buf;
757 int len = PAGE_SIZE;
758
759 detail->cache_request(detail, crq->item, &bp, &len);
760 if (len < 0)
761 return -EAGAIN;
762 return PAGE_SIZE - len;
763}
764
753static ssize_t cache_read(struct file *filp, char __user *buf, size_t count, 765static ssize_t cache_read(struct file *filp, char __user *buf, size_t count,
754 loff_t *ppos, struct cache_detail *cd) 766 loff_t *ppos, struct cache_detail *cd)
755{ 767{
@@ -784,6 +796,13 @@ static ssize_t cache_read(struct file *filp, char __user *buf, size_t count,
784 rq->readers++; 796 rq->readers++;
785 spin_unlock(&queue_lock); 797 spin_unlock(&queue_lock);
786 798
799 if (rq->len == 0) {
800 err = cache_request(cd, rq);
801 if (err < 0)
802 goto out;
803 rq->len = err;
804 }
805
787 if (rp->offset == 0 && !test_bit(CACHE_PENDING, &rq->item->flags)) { 806 if (rp->offset == 0 && !test_bit(CACHE_PENDING, &rq->item->flags)) {
788 err = -EAGAIN; 807 err = -EAGAIN;
789 spin_lock(&queue_lock); 808 spin_lock(&queue_lock);
@@ -1140,17 +1159,14 @@ static bool cache_listeners_exist(struct cache_detail *detail)
1140 * 1159 *
1141 * Each request is at most one page long. 1160 * Each request is at most one page long.
1142 */ 1161 */
1143int sunrpc_cache_pipe_upcall(struct cache_detail *detail, struct cache_head *h, 1162int sunrpc_cache_pipe_upcall(struct cache_detail *detail, struct cache_head *h)
1144 void (*cache_request)(struct cache_detail *,
1145 struct cache_head *,
1146 char **,
1147 int *))
1148{ 1163{
1149 1164
1150 char *buf; 1165 char *buf;
1151 struct cache_request *crq; 1166 struct cache_request *crq;
1152 char *bp; 1167
1153 int len; 1168 if (!detail->cache_request)
1169 return -EINVAL;
1154 1170
1155 if (!cache_listeners_exist(detail)) { 1171 if (!cache_listeners_exist(detail)) {
1156 warn_no_listener(detail); 1172 warn_no_listener(detail);
@@ -1167,19 +1183,10 @@ int sunrpc_cache_pipe_upcall(struct cache_detail *detail, struct cache_head *h,
1167 return -EAGAIN; 1183 return -EAGAIN;
1168 } 1184 }
1169 1185
1170 bp = buf; len = PAGE_SIZE;
1171
1172 cache_request(detail, h, &bp, &len);
1173
1174 if (len < 0) {
1175 kfree(buf);
1176 kfree(crq);
1177 return -EAGAIN;
1178 }
1179 crq->q.reader = 0; 1186 crq->q.reader = 0;
1180 crq->item = cache_get(h); 1187 crq->item = cache_get(h);
1181 crq->buf = buf; 1188 crq->buf = buf;
1182 crq->len = PAGE_SIZE - len; 1189 crq->len = 0;
1183 crq->readers = 0; 1190 crq->readers = 0;
1184 spin_lock(&queue_lock); 1191 spin_lock(&queue_lock);
1185 list_add_tail(&crq->q.list, &detail->queue); 1192 list_add_tail(&crq->q.list, &detail->queue);
@@ -1605,7 +1612,7 @@ static int create_cache_proc_entries(struct cache_detail *cd, struct net *net)
1605 if (p == NULL) 1612 if (p == NULL)
1606 goto out_nomem; 1613 goto out_nomem;
1607 1614
1608 if (cd->cache_upcall || cd->cache_parse) { 1615 if (cd->cache_request || cd->cache_parse) {
1609 p = proc_create_data("channel", S_IFREG|S_IRUSR|S_IWUSR, 1616 p = proc_create_data("channel", S_IFREG|S_IRUSR|S_IWUSR,
1610 cd->u.procfs.proc_ent, 1617 cd->u.procfs.proc_ent,
1611 &cache_file_operations_procfs, cd); 1618 &cache_file_operations_procfs, cd);
@@ -1614,7 +1621,7 @@ static int create_cache_proc_entries(struct cache_detail *cd, struct net *net)
1614 goto out_nomem; 1621 goto out_nomem;
1615 } 1622 }
1616 if (cd->cache_show) { 1623 if (cd->cache_show) {
1617 p = proc_create_data("content", S_IFREG|S_IRUSR|S_IWUSR, 1624 p = proc_create_data("content", S_IFREG|S_IRUSR,
1618 cd->u.procfs.proc_ent, 1625 cd->u.procfs.proc_ent,
1619 &content_file_operations_procfs, cd); 1626 &content_file_operations_procfs, cd);
1620 cd->u.procfs.content_ent = p; 1627 cd->u.procfs.content_ent = p;
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index a9f7906c1a6a..d7a369e61085 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -33,6 +33,7 @@
33#include <linux/rcupdate.h> 33#include <linux/rcupdate.h>
34 34
35#include <linux/sunrpc/clnt.h> 35#include <linux/sunrpc/clnt.h>
36#include <linux/sunrpc/addr.h>
36#include <linux/sunrpc/rpc_pipe_fs.h> 37#include <linux/sunrpc/rpc_pipe_fs.h>
37#include <linux/sunrpc/metrics.h> 38#include <linux/sunrpc/metrics.h>
38#include <linux/sunrpc/bc_xprt.h> 39#include <linux/sunrpc/bc_xprt.h>
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
index 795a0f4e920b..3df764dc330c 100644
--- a/net/sunrpc/rpcb_clnt.c
+++ b/net/sunrpc/rpcb_clnt.c
@@ -26,6 +26,7 @@
26#include <net/ipv6.h> 26#include <net/ipv6.h>
27 27
28#include <linux/sunrpc/clnt.h> 28#include <linux/sunrpc/clnt.h>
29#include <linux/sunrpc/addr.h>
29#include <linux/sunrpc/sched.h> 30#include <linux/sunrpc/sched.h>
30#include <linux/sunrpc/xprtsock.h> 31#include <linux/sunrpc/xprtsock.h>
31 32
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index dbf12ac5ecb7..89a588b4478b 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -515,15 +515,6 @@ EXPORT_SYMBOL_GPL(svc_create_pooled);
515 515
516void svc_shutdown_net(struct svc_serv *serv, struct net *net) 516void svc_shutdown_net(struct svc_serv *serv, struct net *net)
517{ 517{
518 /*
519 * The set of xprts (contained in the sv_tempsocks and
520 * sv_permsocks lists) is now constant, since it is modified
521 * only by accepting new sockets (done by service threads in
522 * svc_recv) or aging old ones (done by sv_temptimer), or
523 * configuration changes (excluded by whatever locking the
524 * caller is using--nfsd_mutex in the case of nfsd). So it's
525 * safe to traverse those lists and shut everything down:
526 */
527 svc_close_net(serv, net); 518 svc_close_net(serv, net);
528 519
529 if (serv->sv_shutdown) 520 if (serv->sv_shutdown)
@@ -1042,6 +1033,7 @@ static void svc_unregister(const struct svc_serv *serv, struct net *net)
1042/* 1033/*
1043 * dprintk the given error with the address of the client that caused it. 1034 * dprintk the given error with the address of the client that caused it.
1044 */ 1035 */
1036#ifdef RPC_DEBUG
1045static __printf(2, 3) 1037static __printf(2, 3)
1046void svc_printk(struct svc_rqst *rqstp, const char *fmt, ...) 1038void svc_printk(struct svc_rqst *rqstp, const char *fmt, ...)
1047{ 1039{
@@ -1058,6 +1050,9 @@ void svc_printk(struct svc_rqst *rqstp, const char *fmt, ...)
1058 1050
1059 va_end(args); 1051 va_end(args);
1060} 1052}
1053#else
1054static __printf(2,3) void svc_printk(struct svc_rqst *rqstp, const char *fmt, ...) {}
1055#endif
1061 1056
1062/* 1057/*
1063 * Common routine for processing the RPC request. 1058 * Common routine for processing the RPC request.
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
index b8e47fac7315..80a6640f329b 100644
--- a/net/sunrpc/svc_xprt.c
+++ b/net/sunrpc/svc_xprt.c
@@ -499,7 +499,8 @@ void svc_wake_up(struct svc_serv *serv)
499 rqstp->rq_xprt = NULL; 499 rqstp->rq_xprt = NULL;
500 */ 500 */
501 wake_up(&rqstp->rq_wait); 501 wake_up(&rqstp->rq_wait);
502 } 502 } else
503 pool->sp_task_pending = 1;
503 spin_unlock_bh(&pool->sp_lock); 504 spin_unlock_bh(&pool->sp_lock);
504 } 505 }
505} 506}
@@ -634,7 +635,13 @@ struct svc_xprt *svc_get_next_xprt(struct svc_rqst *rqstp, long timeout)
634 * long for cache updates. 635 * long for cache updates.
635 */ 636 */
636 rqstp->rq_chandle.thread_wait = 1*HZ; 637 rqstp->rq_chandle.thread_wait = 1*HZ;
638 pool->sp_task_pending = 0;
637 } else { 639 } else {
640 if (pool->sp_task_pending) {
641 pool->sp_task_pending = 0;
642 spin_unlock_bh(&pool->sp_lock);
643 return ERR_PTR(-EAGAIN);
644 }
638 /* No data pending. Go to sleep */ 645 /* No data pending. Go to sleep */
639 svc_thread_enqueue(pool, rqstp); 646 svc_thread_enqueue(pool, rqstp);
640 647
@@ -856,7 +863,6 @@ static void svc_age_temp_xprts(unsigned long closure)
856 struct svc_serv *serv = (struct svc_serv *)closure; 863 struct svc_serv *serv = (struct svc_serv *)closure;
857 struct svc_xprt *xprt; 864 struct svc_xprt *xprt;
858 struct list_head *le, *next; 865 struct list_head *le, *next;
859 LIST_HEAD(to_be_aged);
860 866
861 dprintk("svc_age_temp_xprts\n"); 867 dprintk("svc_age_temp_xprts\n");
862 868
@@ -877,25 +883,15 @@ static void svc_age_temp_xprts(unsigned long closure)
877 if (atomic_read(&xprt->xpt_ref.refcount) > 1 || 883 if (atomic_read(&xprt->xpt_ref.refcount) > 1 ||
878 test_bit(XPT_BUSY, &xprt->xpt_flags)) 884 test_bit(XPT_BUSY, &xprt->xpt_flags))
879 continue; 885 continue;
880 svc_xprt_get(xprt); 886 list_del_init(le);
881 list_move(le, &to_be_aged);
882 set_bit(XPT_CLOSE, &xprt->xpt_flags); 887 set_bit(XPT_CLOSE, &xprt->xpt_flags);
883 set_bit(XPT_DETACHED, &xprt->xpt_flags); 888 set_bit(XPT_DETACHED, &xprt->xpt_flags);
884 }
885 spin_unlock_bh(&serv->sv_lock);
886
887 while (!list_empty(&to_be_aged)) {
888 le = to_be_aged.next;
889 /* fiddling the xpt_list node is safe 'cos we're XPT_DETACHED */
890 list_del_init(le);
891 xprt = list_entry(le, struct svc_xprt, xpt_list);
892
893 dprintk("queuing xprt %p for closing\n", xprt); 889 dprintk("queuing xprt %p for closing\n", xprt);
894 890
895 /* a thread will dequeue and close it soon */ 891 /* a thread will dequeue and close it soon */
896 svc_xprt_enqueue(xprt); 892 svc_xprt_enqueue(xprt);
897 svc_xprt_put(xprt);
898 } 893 }
894 spin_unlock_bh(&serv->sv_lock);
899 895
900 mod_timer(&serv->sv_temptimer, jiffies + svc_conn_age_period * HZ); 896 mod_timer(&serv->sv_temptimer, jiffies + svc_conn_age_period * HZ);
901} 897}
@@ -959,21 +955,24 @@ void svc_close_xprt(struct svc_xprt *xprt)
959} 955}
960EXPORT_SYMBOL_GPL(svc_close_xprt); 956EXPORT_SYMBOL_GPL(svc_close_xprt);
961 957
962static void svc_close_list(struct svc_serv *serv, struct list_head *xprt_list, struct net *net) 958static int svc_close_list(struct svc_serv *serv, struct list_head *xprt_list, struct net *net)
963{ 959{
964 struct svc_xprt *xprt; 960 struct svc_xprt *xprt;
961 int ret = 0;
965 962
966 spin_lock(&serv->sv_lock); 963 spin_lock(&serv->sv_lock);
967 list_for_each_entry(xprt, xprt_list, xpt_list) { 964 list_for_each_entry(xprt, xprt_list, xpt_list) {
968 if (xprt->xpt_net != net) 965 if (xprt->xpt_net != net)
969 continue; 966 continue;
967 ret++;
970 set_bit(XPT_CLOSE, &xprt->xpt_flags); 968 set_bit(XPT_CLOSE, &xprt->xpt_flags);
971 set_bit(XPT_BUSY, &xprt->xpt_flags); 969 svc_xprt_enqueue(xprt);
972 } 970 }
973 spin_unlock(&serv->sv_lock); 971 spin_unlock(&serv->sv_lock);
972 return ret;
974} 973}
975 974
976static void svc_clear_pools(struct svc_serv *serv, struct net *net) 975static struct svc_xprt *svc_dequeue_net(struct svc_serv *serv, struct net *net)
977{ 976{
978 struct svc_pool *pool; 977 struct svc_pool *pool;
979 struct svc_xprt *xprt; 978 struct svc_xprt *xprt;
@@ -988,42 +987,46 @@ static void svc_clear_pools(struct svc_serv *serv, struct net *net)
988 if (xprt->xpt_net != net) 987 if (xprt->xpt_net != net)
989 continue; 988 continue;
990 list_del_init(&xprt->xpt_ready); 989 list_del_init(&xprt->xpt_ready);
990 spin_unlock_bh(&pool->sp_lock);
991 return xprt;
991 } 992 }
992 spin_unlock_bh(&pool->sp_lock); 993 spin_unlock_bh(&pool->sp_lock);
993 } 994 }
995 return NULL;
994} 996}
995 997
996static void svc_clear_list(struct svc_serv *serv, struct list_head *xprt_list, struct net *net) 998static void svc_clean_up_xprts(struct svc_serv *serv, struct net *net)
997{ 999{
998 struct svc_xprt *xprt; 1000 struct svc_xprt *xprt;
999 struct svc_xprt *tmp;
1000 LIST_HEAD(victims);
1001 1001
1002 spin_lock(&serv->sv_lock); 1002 while ((xprt = svc_dequeue_net(serv, net))) {
1003 list_for_each_entry_safe(xprt, tmp, xprt_list, xpt_list) { 1003 set_bit(XPT_CLOSE, &xprt->xpt_flags);
1004 if (xprt->xpt_net != net)
1005 continue;
1006 list_move(&xprt->xpt_list, &victims);
1007 }
1008 spin_unlock(&serv->sv_lock);
1009
1010 list_for_each_entry_safe(xprt, tmp, &victims, xpt_list)
1011 svc_delete_xprt(xprt); 1004 svc_delete_xprt(xprt);
1005 }
1012} 1006}
1013 1007
1008/*
1009 * Server threads may still be running (especially in the case where the
1010 * service is still running in other network namespaces).
1011 *
1012 * So we shut down sockets the same way we would on a running server, by
1013 * setting XPT_CLOSE, enqueuing, and letting a thread pick it up to do
1014 * the close. In the case there are no such other threads,
1015 * threads running, svc_clean_up_xprts() does a simple version of a
1016 * server's main event loop, and in the case where there are other
1017 * threads, we may need to wait a little while and then check again to
1018 * see if they're done.
1019 */
1014void svc_close_net(struct svc_serv *serv, struct net *net) 1020void svc_close_net(struct svc_serv *serv, struct net *net)
1015{ 1021{
1016 svc_close_list(serv, &serv->sv_tempsocks, net); 1022 int delay = 0;
1017 svc_close_list(serv, &serv->sv_permsocks, net);
1018 1023
1019 svc_clear_pools(serv, net); 1024 while (svc_close_list(serv, &serv->sv_permsocks, net) +
1020 /* 1025 svc_close_list(serv, &serv->sv_tempsocks, net)) {
1021 * At this point the sp_sockets lists will stay empty, since 1026
1022 * svc_xprt_enqueue will not add new entries without taking the 1027 svc_clean_up_xprts(serv, net);
1023 * sp_lock and checking XPT_BUSY. 1028 msleep(delay++);
1024 */ 1029 }
1025 svc_clear_list(serv, &serv->sv_tempsocks, net);
1026 svc_clear_list(serv, &serv->sv_permsocks, net);
1027} 1030}
1028 1031
1029/* 1032/*
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c
index a1852e19ed0c..c3f9e1ef7f53 100644
--- a/net/sunrpc/svcauth_unix.c
+++ b/net/sunrpc/svcauth_unix.c
@@ -6,6 +6,7 @@
6#include <linux/sunrpc/svcsock.h> 6#include <linux/sunrpc/svcsock.h>
7#include <linux/sunrpc/svcauth.h> 7#include <linux/sunrpc/svcauth.h>
8#include <linux/sunrpc/gss_api.h> 8#include <linux/sunrpc/gss_api.h>
9#include <linux/sunrpc/addr.h>
9#include <linux/err.h> 10#include <linux/err.h>
10#include <linux/seq_file.h> 11#include <linux/seq_file.h>
11#include <linux/hash.h> 12#include <linux/hash.h>
@@ -17,7 +18,6 @@
17#include <linux/user_namespace.h> 18#include <linux/user_namespace.h>
18#define RPCDBG_FACILITY RPCDBG_AUTH 19#define RPCDBG_FACILITY RPCDBG_AUTH
19 20
20#include <linux/sunrpc/clnt.h>
21 21
22#include "netns.h" 22#include "netns.h"
23 23
@@ -157,11 +157,6 @@ static void ip_map_request(struct cache_detail *cd,
157 (*bpp)[-1] = '\n'; 157 (*bpp)[-1] = '\n';
158} 158}
159 159
160static int ip_map_upcall(struct cache_detail *cd, struct cache_head *h)
161{
162 return sunrpc_cache_pipe_upcall(cd, h, ip_map_request);
163}
164
165static struct ip_map *__ip_map_lookup(struct cache_detail *cd, char *class, struct in6_addr *addr); 160static struct ip_map *__ip_map_lookup(struct cache_detail *cd, char *class, struct in6_addr *addr);
166static int __ip_map_update(struct cache_detail *cd, struct ip_map *ipm, struct unix_domain *udom, time_t expiry); 161static int __ip_map_update(struct cache_detail *cd, struct ip_map *ipm, struct unix_domain *udom, time_t expiry);
167 162
@@ -475,11 +470,6 @@ static void unix_gid_request(struct cache_detail *cd,
475 (*bpp)[-1] = '\n'; 470 (*bpp)[-1] = '\n';
476} 471}
477 472
478static int unix_gid_upcall(struct cache_detail *cd, struct cache_head *h)
479{
480 return sunrpc_cache_pipe_upcall(cd, h, unix_gid_request);
481}
482
483static struct unix_gid *unix_gid_lookup(struct cache_detail *cd, kuid_t uid); 473static struct unix_gid *unix_gid_lookup(struct cache_detail *cd, kuid_t uid);
484 474
485static int unix_gid_parse(struct cache_detail *cd, 475static int unix_gid_parse(struct cache_detail *cd,
@@ -586,7 +576,7 @@ static struct cache_detail unix_gid_cache_template = {
586 .hash_size = GID_HASHMAX, 576 .hash_size = GID_HASHMAX,
587 .name = "auth.unix.gid", 577 .name = "auth.unix.gid",
588 .cache_put = unix_gid_put, 578 .cache_put = unix_gid_put,
589 .cache_upcall = unix_gid_upcall, 579 .cache_request = unix_gid_request,
590 .cache_parse = unix_gid_parse, 580 .cache_parse = unix_gid_parse,
591 .cache_show = unix_gid_show, 581 .cache_show = unix_gid_show,
592 .match = unix_gid_match, 582 .match = unix_gid_match,
@@ -885,7 +875,7 @@ static struct cache_detail ip_map_cache_template = {
885 .hash_size = IP_HASHMAX, 875 .hash_size = IP_HASHMAX,
886 .name = "auth.unix.ip", 876 .name = "auth.unix.ip",
887 .cache_put = ip_map_put, 877 .cache_put = ip_map_put,
888 .cache_upcall = ip_map_upcall, 878 .cache_request = ip_map_request,
889 .cache_parse = ip_map_parse, 879 .cache_parse = ip_map_parse,
890 .cache_show = ip_map_show, 880 .cache_show = ip_map_show,
891 .match = ip_map_match, 881 .match = ip_map_match,
diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c
index 56055632f151..75edcfad6e26 100644
--- a/net/sunrpc/xdr.c
+++ b/net/sunrpc/xdr.c
@@ -879,6 +879,47 @@ xdr_buf_subsegment(struct xdr_buf *buf, struct xdr_buf *subbuf,
879} 879}
880EXPORT_SYMBOL_GPL(xdr_buf_subsegment); 880EXPORT_SYMBOL_GPL(xdr_buf_subsegment);
881 881
882/**
883 * xdr_buf_trim - lop at most "len" bytes off the end of "buf"
884 * @buf: buf to be trimmed
885 * @len: number of bytes to reduce "buf" by
886 *
887 * Trim an xdr_buf by the given number of bytes by fixing up the lengths. Note
888 * that it's possible that we'll trim less than that amount if the xdr_buf is
889 * too small, or if (for instance) it's all in the head and the parser has
890 * already read too far into it.
891 */
892void xdr_buf_trim(struct xdr_buf *buf, unsigned int len)
893{
894 size_t cur;
895 unsigned int trim = len;
896
897 if (buf->tail[0].iov_len) {
898 cur = min_t(size_t, buf->tail[0].iov_len, trim);
899 buf->tail[0].iov_len -= cur;
900 trim -= cur;
901 if (!trim)
902 goto fix_len;
903 }
904
905 if (buf->page_len) {
906 cur = min_t(unsigned int, buf->page_len, trim);
907 buf->page_len -= cur;
908 trim -= cur;
909 if (!trim)
910 goto fix_len;
911 }
912
913 if (buf->head[0].iov_len) {
914 cur = min_t(size_t, buf->head[0].iov_len, trim);
915 buf->head[0].iov_len -= cur;
916 trim -= cur;
917 }
918fix_len:
919 buf->len -= (len - trim);
920}
921EXPORT_SYMBOL_GPL(xdr_buf_trim);
922
882static void __read_bytes_from_xdr_buf(struct xdr_buf *subbuf, void *obj, unsigned int len) 923static void __read_bytes_from_xdr_buf(struct xdr_buf *subbuf, void *obj, unsigned int len)
883{ 924{
884 unsigned int this_len; 925 unsigned int this_len;
diff --git a/net/sunrpc/xprtrdma/transport.c b/net/sunrpc/xprtrdma/transport.c
index d0074289708e..794312f22b9b 100644
--- a/net/sunrpc/xprtrdma/transport.c
+++ b/net/sunrpc/xprtrdma/transport.c
@@ -51,6 +51,7 @@
51#include <linux/init.h> 51#include <linux/init.h>
52#include <linux/slab.h> 52#include <linux/slab.h>
53#include <linux/seq_file.h> 53#include <linux/seq_file.h>
54#include <linux/sunrpc/addr.h>
54 55
55#include "xprt_rdma.h" 56#include "xprt_rdma.h"
56 57
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 37cbda63f45c..c1d8476b7692 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -33,6 +33,7 @@
33#include <linux/udp.h> 33#include <linux/udp.h>
34#include <linux/tcp.h> 34#include <linux/tcp.h>
35#include <linux/sunrpc/clnt.h> 35#include <linux/sunrpc/clnt.h>
36#include <linux/sunrpc/addr.h>
36#include <linux/sunrpc/sched.h> 37#include <linux/sunrpc/sched.h>
37#include <linux/sunrpc/svcsock.h> 38#include <linux/sunrpc/svcsock.h>
38#include <linux/sunrpc/xprtsock.h> 39#include <linux/sunrpc/xprtsock.h>
@@ -1867,13 +1868,9 @@ static int xs_local_finish_connecting(struct rpc_xprt *xprt,
1867 * @xprt: RPC transport to connect 1868 * @xprt: RPC transport to connect
1868 * @transport: socket transport to connect 1869 * @transport: socket transport to connect
1869 * @create_sock: function to create a socket of the correct type 1870 * @create_sock: function to create a socket of the correct type
1870 *
1871 * Invoked by a work queue tasklet.
1872 */ 1871 */
1873static void xs_local_setup_socket(struct work_struct *work) 1872static int xs_local_setup_socket(struct sock_xprt *transport)
1874{ 1873{
1875 struct sock_xprt *transport =
1876 container_of(work, struct sock_xprt, connect_worker.work);
1877 struct rpc_xprt *xprt = &transport->xprt; 1874 struct rpc_xprt *xprt = &transport->xprt;
1878 struct socket *sock; 1875 struct socket *sock;
1879 int status = -EIO; 1876 int status = -EIO;
@@ -1918,6 +1915,30 @@ out:
1918 xprt_clear_connecting(xprt); 1915 xprt_clear_connecting(xprt);
1919 xprt_wake_pending_tasks(xprt, status); 1916 xprt_wake_pending_tasks(xprt, status);
1920 current->flags &= ~PF_FSTRANS; 1917 current->flags &= ~PF_FSTRANS;
1918 return status;
1919}
1920
1921static void xs_local_connect(struct rpc_xprt *xprt, struct rpc_task *task)
1922{
1923 struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
1924 int ret;
1925
1926 if (RPC_IS_ASYNC(task)) {
1927 /*
1928 * We want the AF_LOCAL connect to be resolved in the
1929 * filesystem namespace of the process making the rpc
1930 * call. Thus we connect synchronously.
1931 *
1932 * If we want to support asynchronous AF_LOCAL calls,
1933 * we'll need to figure out how to pass a namespace to
1934 * connect.
1935 */
1936 rpc_exit(task, -ENOTCONN);
1937 return;
1938 }
1939 ret = xs_local_setup_socket(transport);
1940 if (ret && !RPC_IS_SOFTCONN(task))
1941 msleep_interruptible(15000);
1921} 1942}
1922 1943
1923#ifdef CONFIG_SUNRPC_SWAP 1944#ifdef CONFIG_SUNRPC_SWAP
@@ -2455,7 +2476,7 @@ static struct rpc_xprt_ops xs_local_ops = {
2455 .alloc_slot = xprt_alloc_slot, 2476 .alloc_slot = xprt_alloc_slot,
2456 .rpcbind = xs_local_rpcbind, 2477 .rpcbind = xs_local_rpcbind,
2457 .set_port = xs_local_set_port, 2478 .set_port = xs_local_set_port,
2458 .connect = xs_connect, 2479 .connect = xs_local_connect,
2459 .buf_alloc = rpc_malloc, 2480 .buf_alloc = rpc_malloc,
2460 .buf_free = rpc_free, 2481 .buf_free = rpc_free,
2461 .send_request = xs_local_send_request, 2482 .send_request = xs_local_send_request,
@@ -2628,8 +2649,6 @@ static struct rpc_xprt *xs_setup_local(struct xprt_create *args)
2628 goto out_err; 2649 goto out_err;
2629 } 2650 }
2630 xprt_set_bound(xprt); 2651 xprt_set_bound(xprt);
2631 INIT_DELAYED_WORK(&transport->connect_worker,
2632 xs_local_setup_socket);
2633 xs_format_peer_addresses(xprt, "local", RPCBIND_NETID_LOCAL); 2652 xs_format_peer_addresses(xprt, "local", RPCBIND_NETID_LOCAL);
2634 break; 2653 break;
2635 default: 2654 default: