Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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
...

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