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

Merge branch 'for-3.5' of git://linux-nfs.org/~bfields/linux

Pull the rest of the nfsd commits from Bruce Fields:
"... and then I cherry-picked the remainder of the patches from the
head of my previous branch"

This is the rest of the original nfsd branch, rebased without the
delegation stuff that I thought really needed to be redone.

I don't like rebasing things like this in general, but in this situation
this was the lesser of two evils.

* 'for-3.5' of git://linux-nfs.org/~bfields/linux: (50 commits)
nfsd4: fix, consolidate client_has_state
nfsd4: don't remove rebooted client record until confirmation
nfsd4: remove some dprintk's and a comment
nfsd4: return "real" sequence id in confirmed case
nfsd4: fix exchange_id to return confirm flag
nfsd4: clarify that renewing expired client is a bug
nfsd4: simpler ordering of setclientid_confirm checks
nfsd4: setclientid: remove pointless assignment
nfsd4: fix error return in non-matching-creds case
nfsd4: fix setclientid_confirm same_cred check
nfsd4: merge 3 setclientid cases to 2
nfsd4: pull out common code from setclientid cases
nfsd4: merge last two setclientid cases
nfsd4: setclientid/confirm comment cleanup
nfsd4: setclientid remove unnecessary terms from a logical expression
nfsd4: move rq_flavor into svc_cred
nfsd4: stricter cred comparison for setclientid/exchange_id
nfsd4: move principal name into svc_cred
nfsd4: allow removing clients not holding state
nfsd4: rearrange exchange_id logic to simplify
...

+526 -439
+92 -57
fs/lockd/svc.c
··· 251 251 return err; 252 252 } 253 253 254 - static int lockd_up_net(struct net *net) 254 + static int lockd_up_net(struct svc_serv *serv, struct net *net) 255 255 { 256 256 struct lockd_net *ln = net_generic(net, lockd_net_id); 257 - struct svc_serv *serv = nlmsvc_rqst->rq_server; 258 257 int error; 259 258 260 - if (ln->nlmsvc_users) 259 + if (ln->nlmsvc_users++) 261 260 return 0; 262 261 263 - error = svc_rpcb_setup(serv, net); 262 + error = svc_bind(serv, net); 264 263 if (error) 265 - goto err_rpcb; 264 + goto err_bind; 266 265 267 266 error = make_socks(serv, net); 268 267 if (error < 0) 269 268 goto err_socks; 269 + dprintk("lockd_up_net: per-net data created; net=%p\n", net); 270 270 return 0; 271 271 272 272 err_socks: 273 273 svc_rpcb_cleanup(serv, net); 274 - err_rpcb: 274 + err_bind: 275 + ln->nlmsvc_users--; 275 276 return error; 276 277 } 277 278 278 - static void lockd_down_net(struct net *net) 279 + static void lockd_down_net(struct svc_serv *serv, struct net *net) 279 280 { 280 281 struct lockd_net *ln = net_generic(net, lockd_net_id); 281 - struct svc_serv *serv = nlmsvc_rqst->rq_server; 282 282 283 283 if (ln->nlmsvc_users) { 284 284 if (--ln->nlmsvc_users == 0) { 285 285 nlm_shutdown_hosts_net(net); 286 286 svc_shutdown_net(serv, net); 287 + dprintk("lockd_down_net: per-net data destroyed; net=%p\n", net); 287 288 } 288 289 } else { 289 290 printk(KERN_ERR "lockd_down_net: no users! task=%p, net=%p\n", ··· 293 292 } 294 293 } 295 294 296 - /* 297 - * Bring up the lockd process if it's not already up. 298 - */ 299 - int lockd_up(struct net *net) 295 + static int lockd_start_svc(struct svc_serv *serv) 296 + { 297 + int error; 298 + 299 + if (nlmsvc_rqst) 300 + return 0; 301 + 302 + /* 303 + * Create the kernel thread and wait for it to start. 304 + */ 305 + nlmsvc_rqst = svc_prepare_thread(serv, &serv->sv_pools[0], NUMA_NO_NODE); 306 + if (IS_ERR(nlmsvc_rqst)) { 307 + error = PTR_ERR(nlmsvc_rqst); 308 + printk(KERN_WARNING 309 + "lockd_up: svc_rqst allocation failed, error=%d\n", 310 + error); 311 + goto out_rqst; 312 + } 313 + 314 + svc_sock_update_bufs(serv); 315 + serv->sv_maxconn = nlm_max_connections; 316 + 317 + nlmsvc_task = kthread_run(lockd, nlmsvc_rqst, serv->sv_name); 318 + if (IS_ERR(nlmsvc_task)) { 319 + error = PTR_ERR(nlmsvc_task); 320 + printk(KERN_WARNING 321 + "lockd_up: kthread_run failed, error=%d\n", error); 322 + goto out_task; 323 + } 324 + dprintk("lockd_up: service started\n"); 325 + return 0; 326 + 327 + out_task: 328 + svc_exit_thread(nlmsvc_rqst); 329 + nlmsvc_task = NULL; 330 + out_rqst: 331 + nlmsvc_rqst = NULL; 332 + return error; 333 + } 334 + 335 + static struct svc_serv *lockd_create_svc(void) 300 336 { 301 337 struct svc_serv *serv; 302 - int error = 0; 303 338 304 - mutex_lock(&nlmsvc_mutex); 305 339 /* 306 340 * Check whether we're already up and running. 307 341 */ 308 342 if (nlmsvc_rqst) { 309 - error = lockd_up_net(net); 310 - goto out; 343 + /* 344 + * Note: increase service usage, because later in case of error 345 + * svc_destroy() will be called. 346 + */ 347 + svc_get(nlmsvc_rqst->rq_server); 348 + return nlmsvc_rqst->rq_server; 311 349 } 312 350 313 351 /* ··· 357 317 printk(KERN_WARNING 358 318 "lockd_up: no pid, %d users??\n", nlmsvc_users); 359 319 360 - error = -ENOMEM; 361 320 serv = svc_create(&nlmsvc_program, LOCKD_BUFSIZE, NULL); 362 321 if (!serv) { 363 322 printk(KERN_WARNING "lockd_up: create service failed\n"); 364 - goto out; 323 + return ERR_PTR(-ENOMEM); 324 + } 325 + dprintk("lockd_up: service created\n"); 326 + return serv; 327 + } 328 + 329 + /* 330 + * Bring up the lockd process if it's not already up. 331 + */ 332 + int lockd_up(struct net *net) 333 + { 334 + struct svc_serv *serv; 335 + int error; 336 + 337 + mutex_lock(&nlmsvc_mutex); 338 + 339 + serv = lockd_create_svc(); 340 + if (IS_ERR(serv)) { 341 + error = PTR_ERR(serv); 342 + goto err_create; 365 343 } 366 344 367 - error = make_socks(serv, net); 345 + error = lockd_up_net(serv, net); 368 346 if (error < 0) 369 - goto destroy_and_out; 347 + goto err_net; 370 348 371 - /* 372 - * Create the kernel thread and wait for it to start. 373 - */ 374 - nlmsvc_rqst = svc_prepare_thread(serv, &serv->sv_pools[0], NUMA_NO_NODE); 375 - if (IS_ERR(nlmsvc_rqst)) { 376 - error = PTR_ERR(nlmsvc_rqst); 377 - nlmsvc_rqst = NULL; 378 - printk(KERN_WARNING 379 - "lockd_up: svc_rqst allocation failed, error=%d\n", 380 - error); 381 - goto destroy_and_out; 382 - } 349 + error = lockd_start_svc(serv); 350 + if (error < 0) 351 + goto err_start; 383 352 384 - svc_sock_update_bufs(serv); 385 - serv->sv_maxconn = nlm_max_connections; 386 - 387 - nlmsvc_task = kthread_run(lockd, nlmsvc_rqst, serv->sv_name); 388 - if (IS_ERR(nlmsvc_task)) { 389 - error = PTR_ERR(nlmsvc_task); 390 - svc_exit_thread(nlmsvc_rqst); 391 - nlmsvc_task = NULL; 392 - nlmsvc_rqst = NULL; 393 - printk(KERN_WARNING 394 - "lockd_up: kthread_run failed, error=%d\n", error); 395 - goto destroy_and_out; 396 - } 397 - 353 + nlmsvc_users++; 398 354 /* 399 355 * Note: svc_serv structures have an initial use count of 1, 400 356 * so we exit through here on both success and failure. 401 357 */ 402 - destroy_and_out: 358 + err_net: 403 359 svc_destroy(serv); 404 - out: 405 - if (!error) { 406 - struct lockd_net *ln = net_generic(net, lockd_net_id); 407 - 408 - ln->nlmsvc_users++; 409 - nlmsvc_users++; 410 - } 360 + err_create: 411 361 mutex_unlock(&nlmsvc_mutex); 412 362 return error; 363 + 364 + err_start: 365 + lockd_down_net(serv, net); 366 + goto err_net; 413 367 } 414 368 EXPORT_SYMBOL_GPL(lockd_up); 415 369 ··· 414 380 lockd_down(struct net *net) 415 381 { 416 382 mutex_lock(&nlmsvc_mutex); 383 + lockd_down_net(nlmsvc_rqst->rq_server, net); 417 384 if (nlmsvc_users) { 418 - if (--nlmsvc_users) { 419 - lockd_down_net(net); 385 + if (--nlmsvc_users) 420 386 goto out; 421 - } 422 387 } else { 423 388 printk(KERN_ERR "lockd_down: no users! task=%p\n", 424 389 nlmsvc_task); ··· 429 396 BUG(); 430 397 } 431 398 kthread_stop(nlmsvc_task); 399 + dprintk("lockd_down: service stopped\n"); 432 400 svc_exit_thread(nlmsvc_rqst); 401 + dprintk("lockd_down: service destroyed\n"); 433 402 nlmsvc_task = NULL; 434 403 nlmsvc_rqst = NULL; 435 404 out:
+12 -1
fs/nfs/callback.c
··· 17 17 #include <linux/kthread.h> 18 18 #include <linux/sunrpc/svcauth_gss.h> 19 19 #include <linux/sunrpc/bc_xprt.h> 20 + #include <linux/nsproxy.h> 20 21 21 22 #include <net/inet_sock.h> 22 23 ··· 254 253 char svc_name[12]; 255 254 int ret = 0; 256 255 int minorversion_setup; 256 + struct net *net = current->nsproxy->net_ns; 257 257 258 258 mutex_lock(&nfs_callback_mutex); 259 259 if (cb_info->users++ || cb_info->task != NULL) { ··· 264 262 serv = svc_create(&nfs4_callback_program, NFS4_CALLBACK_BUFSIZE, NULL); 265 263 if (!serv) { 266 264 ret = -ENOMEM; 265 + goto out_err; 266 + } 267 + 268 + ret = svc_bind(serv, net); 269 + if (ret < 0) { 270 + printk(KERN_WARNING "NFS: bind callback service failed\n"); 267 271 goto out_err; 268 272 } 269 273 ··· 314 306 dprintk("NFS: Couldn't create callback socket or server thread; " 315 307 "err = %d\n", ret); 316 308 cb_info->users--; 309 + if (serv) 310 + svc_shutdown_net(serv, net); 317 311 goto out; 318 312 } 319 313 ··· 330 320 cb_info->users--; 331 321 if (cb_info->users == 0 && cb_info->task != NULL) { 332 322 kthread_stop(cb_info->task); 323 + svc_shutdown_net(cb_info->serv, current->nsproxy->net_ns); 333 324 svc_exit_thread(cb_info->rqst); 334 325 cb_info->serv = NULL; 335 326 cb_info->rqst = NULL; ··· 343 332 int 344 333 check_gss_callback_principal(struct nfs_client *clp, struct svc_rqst *rqstp) 345 334 { 346 - char *p = svc_gss_principal(rqstp); 335 + char *p = rqstp->rq_cred.cr_principal; 347 336 348 337 if (rqstp->rq_authop->flavour != RPC_AUTH_GSS) 349 338 return 1;
+1 -1
fs/nfsd/auth.c
··· 11 11 struct exp_flavor_info *end = exp->ex_flavors + exp->ex_nflavors; 12 12 13 13 for (f = exp->ex_flavors; f < end; f++) { 14 - if (f->pseudoflavor == rqstp->rq_flavor) 14 + if (f->pseudoflavor == rqstp->rq_cred.cr_flavor) 15 15 return f->flags; 16 16 } 17 17 return exp->ex_flags;
+4 -4
fs/nfsd/export.c
··· 706 706 return NULL; 707 707 } 708 708 709 - struct cache_detail svc_export_cache_template = { 709 + static struct cache_detail svc_export_cache_template = { 710 710 .owner = THIS_MODULE, 711 711 .hash_size = EXPORT_HASHMAX, 712 712 .name = "nfsd.export", ··· 904 904 return 0; 905 905 /* ip-address based client; check sec= export option: */ 906 906 for (f = exp->ex_flavors; f < end; f++) { 907 - if (f->pseudoflavor == rqstp->rq_flavor) 907 + if (f->pseudoflavor == rqstp->rq_cred.cr_flavor) 908 908 return 0; 909 909 } 910 910 /* defaults in absence of sec= options: */ 911 911 if (exp->ex_nflavors == 0) { 912 - if (rqstp->rq_flavor == RPC_AUTH_NULL || 913 - rqstp->rq_flavor == RPC_AUTH_UNIX) 912 + if (rqstp->rq_cred.cr_flavor == RPC_AUTH_NULL || 913 + rqstp->rq_cred.cr_flavor == RPC_AUTH_UNIX) 914 914 return 0; 915 915 } 916 916 return nfserr_wrongsec;
+1
fs/nfsd/fault_inject.c
··· 58 58 59 59 static int nfsd_inject_get(void *data, u64 *val) 60 60 { 61 + *val = 0; 61 62 return 0; 62 63 } 63 64
+3 -2
fs/nfsd/nfs4callback.c
··· 650 650 struct rpc_clnt *client; 651 651 652 652 if (clp->cl_minorversion == 0) { 653 - if (!clp->cl_principal && (clp->cl_flavor >= RPC_AUTH_GSS_KRB5)) 653 + if (!clp->cl_cred.cr_principal && 654 + (clp->cl_flavor >= RPC_AUTH_GSS_KRB5)) 654 655 return -EINVAL; 655 - args.client_name = clp->cl_principal; 656 + args.client_name = clp->cl_cred.cr_principal; 656 657 args.prognumber = conn->cb_prog, 657 658 args.protocol = XPRT_TRANSPORT_TCP; 658 659 args.authflavor = clp->cl_flavor;
+2 -2
fs/nfsd/nfs4idmap.c
··· 605 605 static __be32 606 606 do_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen, uid_t *id) 607 607 { 608 - if (nfs4_disable_idmapping && rqstp->rq_flavor < RPC_AUTH_GSS) 608 + if (nfs4_disable_idmapping && rqstp->rq_cred.cr_flavor < RPC_AUTH_GSS) 609 609 if (numeric_name_to_id(rqstp, type, name, namelen, id)) 610 610 return 0; 611 611 /* ··· 618 618 static int 619 619 do_id_to_name(struct svc_rqst *rqstp, int type, uid_t id, char *name) 620 620 { 621 - if (nfs4_disable_idmapping && rqstp->rq_flavor < RPC_AUTH_GSS) 621 + if (nfs4_disable_idmapping && rqstp->rq_cred.cr_flavor < RPC_AUTH_GSS) 622 622 return sprintf(name, "%u", id); 623 623 return idmap_id_to_name(rqstp, type, id, name); 624 624 }
+2 -2
fs/nfsd/nfs4recover.c
··· 570 570 cld_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) 571 571 { 572 572 struct cld_upcall *tmp, *cup; 573 - struct cld_msg *cmsg = (struct cld_msg *)src; 573 + struct cld_msg __user *cmsg = (struct cld_msg __user *)src; 574 574 uint32_t xid; 575 575 struct nfsd_net *nn = net_generic(filp->f_dentry->d_sb->s_fs_info, 576 576 nfsd_net_id); ··· 1029 1029 return ret; 1030 1030 } 1031 1031 1032 - struct notifier_block nfsd4_cld_block = { 1032 + static struct notifier_block nfsd4_cld_block = { 1033 1033 .notifier_call = rpc_pipefs_event, 1034 1034 }; 1035 1035
+244 -285
fs/nfsd/nfs4state.c
··· 42 42 #include <linux/sunrpc/clnt.h> 43 43 #include "xdr4.h" 44 44 #include "vfs.h" 45 + #include "current_stateid.h" 45 46 46 47 #define NFSDDBG_FACILITY NFSDDBG_PROC 47 48 ··· 448 447 * 449 448 * which we should reject. 450 449 */ 451 - static void 452 - set_access(unsigned int *access, unsigned long bmap) { 450 + static unsigned int 451 + bmap_to_share_mode(unsigned long bmap) { 453 452 int i; 453 + unsigned int access = 0; 454 454 455 - *access = 0; 456 455 for (i = 1; i < 4; i++) { 457 456 if (test_bit(i, &bmap)) 458 - *access |= i; 457 + access |= i; 459 458 } 459 + return access; 460 460 } 461 461 462 - static void 463 - set_deny(unsigned int *deny, unsigned long bmap) { 464 - int i; 465 - 466 - *deny = 0; 467 - for (i = 0; i < 4; i++) { 468 - if (test_bit(i, &bmap)) 469 - *deny |= i ; 470 - } 471 - } 472 - 473 - static int 462 + static bool 474 463 test_share(struct nfs4_ol_stateid *stp, struct nfsd4_open *open) { 475 464 unsigned int access, deny; 476 465 477 - set_access(&access, stp->st_access_bmap); 478 - set_deny(&deny, stp->st_deny_bmap); 466 + access = bmap_to_share_mode(stp->st_access_bmap); 467 + deny = bmap_to_share_mode(stp->st_deny_bmap); 479 468 if ((access & open->op_share_deny) || (deny & open->op_share_access)) 480 - return 0; 481 - return 1; 469 + return false; 470 + return true; 471 + } 472 + 473 + /* set share access for a given stateid */ 474 + static inline void 475 + set_access(u32 access, struct nfs4_ol_stateid *stp) 476 + { 477 + __set_bit(access, &stp->st_access_bmap); 478 + } 479 + 480 + /* clear share access for a given stateid */ 481 + static inline void 482 + clear_access(u32 access, struct nfs4_ol_stateid *stp) 483 + { 484 + __clear_bit(access, &stp->st_access_bmap); 485 + } 486 + 487 + /* test whether a given stateid has access */ 488 + static inline bool 489 + test_access(u32 access, struct nfs4_ol_stateid *stp) 490 + { 491 + return test_bit(access, &stp->st_access_bmap); 492 + } 493 + 494 + /* set share deny for a given stateid */ 495 + static inline void 496 + set_deny(u32 access, struct nfs4_ol_stateid *stp) 497 + { 498 + __set_bit(access, &stp->st_deny_bmap); 499 + } 500 + 501 + /* clear share deny for a given stateid */ 502 + static inline void 503 + clear_deny(u32 access, struct nfs4_ol_stateid *stp) 504 + { 505 + __clear_bit(access, &stp->st_deny_bmap); 506 + } 507 + 508 + /* test whether a given stateid is denying specific access */ 509 + static inline bool 510 + test_deny(u32 access, struct nfs4_ol_stateid *stp) 511 + { 512 + return test_bit(access, &stp->st_deny_bmap); 482 513 } 483 514 484 515 static int nfs4_access_to_omode(u32 access) ··· 526 493 BUG(); 527 494 } 528 495 496 + /* release all access and file references for a given stateid */ 497 + static void 498 + release_all_access(struct nfs4_ol_stateid *stp) 499 + { 500 + int i; 501 + 502 + for (i = 1; i < 4; i++) { 503 + if (test_access(i, stp)) 504 + nfs4_file_put_access(stp->st_file, 505 + nfs4_access_to_omode(i)); 506 + clear_access(i, stp); 507 + } 508 + } 509 + 529 510 static void unhash_generic_stateid(struct nfs4_ol_stateid *stp) 530 511 { 531 512 list_del(&stp->st_perfile); ··· 548 501 549 502 static void close_generic_stateid(struct nfs4_ol_stateid *stp) 550 503 { 551 - int i; 552 - 553 - if (stp->st_access_bmap) { 554 - for (i = 1; i < 4; i++) { 555 - if (test_bit(i, &stp->st_access_bmap)) 556 - nfs4_file_put_access(stp->st_file, 557 - nfs4_access_to_omode(i)); 558 - __clear_bit(i, &stp->st_access_bmap); 559 - } 560 - } 504 + release_all_access(stp); 561 505 put_nfs4_file(stp->st_file); 562 506 stp->st_file = NULL; 563 507 } ··· 923 885 struct nfsd4_session *new; 924 886 struct nfsd4_channel_attrs *fchan = &cses->fore_channel; 925 887 int numslots, slotsize; 926 - int status; 888 + __be32 status; 927 889 int idx; 928 890 929 891 /* ··· 1022 984 renew_client_locked(struct nfs4_client *clp) 1023 985 { 1024 986 if (is_client_expired(clp)) { 1025 - dprintk("%s: client (clientid %08x/%08x) already expired\n", 987 + WARN_ON(1); 988 + printk("%s: client (clientid %08x/%08x) already expired\n", 1026 989 __func__, 1027 990 clp->cl_clientid.cl_boot, 1028 991 clp->cl_clientid.cl_id); ··· 1088 1049 list_del(&ses->se_perclnt); 1089 1050 nfsd4_put_session_locked(ses); 1090 1051 } 1091 - if (clp->cl_cred.cr_group_info) 1092 - put_group_info(clp->cl_cred.cr_group_info); 1093 - kfree(clp->cl_principal); 1052 + free_svc_cred(&clp->cl_cred); 1094 1053 kfree(clp->cl_name.data); 1095 1054 kfree(clp); 1096 1055 } ··· 1169 1132 target->cl_clientid.cl_id = source->cl_clientid.cl_id; 1170 1133 } 1171 1134 1172 - static void copy_cred(struct svc_cred *target, struct svc_cred *source) 1135 + static int copy_cred(struct svc_cred *target, struct svc_cred *source) 1173 1136 { 1137 + if (source->cr_principal) { 1138 + target->cr_principal = 1139 + kstrdup(source->cr_principal, GFP_KERNEL); 1140 + if (target->cr_principal == NULL) 1141 + return -ENOMEM; 1142 + } else 1143 + target->cr_principal = NULL; 1144 + target->cr_flavor = source->cr_flavor; 1174 1145 target->cr_uid = source->cr_uid; 1175 1146 target->cr_gid = source->cr_gid; 1176 1147 target->cr_group_info = source->cr_group_info; 1177 1148 get_group_info(target->cr_group_info); 1149 + return 0; 1178 1150 } 1179 1151 1180 1152 static int same_name(const char *n1, const char *n2) ··· 1203 1157 return (cl1->cl_boot == cl2->cl_boot) && (cl1->cl_id == cl2->cl_id); 1204 1158 } 1205 1159 1206 - /* XXX what about NGROUP */ 1160 + static bool groups_equal(struct group_info *g1, struct group_info *g2) 1161 + { 1162 + int i; 1163 + 1164 + if (g1->ngroups != g2->ngroups) 1165 + return false; 1166 + for (i=0; i<g1->ngroups; i++) 1167 + if (GROUP_AT(g1, i) != GROUP_AT(g2, i)) 1168 + return false; 1169 + return true; 1170 + } 1171 + 1207 1172 static int 1208 1173 same_creds(struct svc_cred *cr1, struct svc_cred *cr2) 1209 1174 { 1210 - return cr1->cr_uid == cr2->cr_uid; 1175 + if ((cr1->cr_flavor != cr2->cr_flavor) 1176 + || (cr1->cr_uid != cr2->cr_uid) 1177 + || (cr1->cr_gid != cr2->cr_gid) 1178 + || !groups_equal(cr1->cr_group_info, cr2->cr_group_info)) 1179 + return false; 1180 + if (cr1->cr_principal == cr2->cr_principal) 1181 + return true; 1182 + if (!cr1->cr_principal || !cr2->cr_principal) 1183 + return false; 1184 + return 0 == strcmp(cr1->cr_principal, cr1->cr_principal); 1211 1185 } 1212 1186 1213 1187 static void gen_clid(struct nfs4_client *clp) ··· 1270 1204 { 1271 1205 struct nfs4_client *clp; 1272 1206 struct sockaddr *sa = svc_addr(rqstp); 1273 - char *princ; 1207 + int ret; 1274 1208 1275 1209 clp = alloc_client(name); 1276 1210 if (clp == NULL) 1277 1211 return NULL; 1278 1212 1279 1213 INIT_LIST_HEAD(&clp->cl_sessions); 1280 - 1281 - princ = svc_gss_principal(rqstp); 1282 - if (princ) { 1283 - clp->cl_principal = kstrdup(princ, GFP_KERNEL); 1284 - if (clp->cl_principal == NULL) { 1285 - spin_lock(&client_lock); 1286 - free_client(clp); 1287 - spin_unlock(&client_lock); 1288 - return NULL; 1289 - } 1214 + ret = copy_cred(&clp->cl_cred, &rqstp->rq_cred); 1215 + if (ret) { 1216 + spin_lock(&client_lock); 1217 + free_client(clp); 1218 + spin_unlock(&client_lock); 1219 + return NULL; 1290 1220 } 1291 - 1292 1221 idr_init(&clp->cl_stateids); 1293 1222 memcpy(clp->cl_recdir, recdir, HEXDIR_LEN); 1294 1223 atomic_set(&clp->cl_refcount, 0); ··· 1301 1240 rpc_init_wait_queue(&clp->cl_cb_waitq, "Backchannel slot table"); 1302 1241 copy_verf(clp, verf); 1303 1242 rpc_copy_addr((struct sockaddr *) &clp->cl_addr, sa); 1304 - clp->cl_flavor = rqstp->rq_flavor; 1305 - copy_cred(&clp->cl_cred, &rqstp->rq_cred); 1306 1243 gen_confirm(clp); 1307 1244 clp->cl_cb_session = NULL; 1308 1245 return clp; ··· 1529 1470 clid->flags = new->cl_exchange_flags; 1530 1471 } 1531 1472 1473 + static bool client_has_state(struct nfs4_client *clp) 1474 + { 1475 + /* 1476 + * Note clp->cl_openowners check isn't quite right: there's no 1477 + * need to count owners without stateid's. 1478 + * 1479 + * Also note we should probably be using this in 4.0 case too. 1480 + */ 1481 + return !list_empty(&clp->cl_openowners) 1482 + || !list_empty(&clp->cl_delegations) 1483 + || !list_empty(&clp->cl_sessions); 1484 + } 1485 + 1532 1486 __be32 1533 1487 nfsd4_exchange_id(struct svc_rqst *rqstp, 1534 1488 struct nfsd4_compound_state *cstate, 1535 1489 struct nfsd4_exchange_id *exid) 1536 1490 { 1537 1491 struct nfs4_client *unconf, *conf, *new; 1538 - int status; 1492 + __be32 status; 1539 1493 unsigned int strhashval; 1540 1494 char dname[HEXDIR_LEN]; 1541 1495 char addr_str[INET6_ADDRSTRLEN]; 1542 1496 nfs4_verifier verf = exid->verifier; 1543 1497 struct sockaddr *sa = svc_addr(rqstp); 1498 + bool update = exid->flags & EXCHGID4_FLAG_UPD_CONFIRMED_REC_A; 1544 1499 1545 1500 rpc_ntop(sa, addr_str, sizeof(addr_str)); 1546 1501 dprintk("%s rqstp=%p exid=%p clname.len=%u clname.data=%p " ··· 1580 1507 status = nfs4_make_rec_clidname(dname, &exid->clname); 1581 1508 1582 1509 if (status) 1583 - goto error; 1510 + return status; 1584 1511 1585 1512 strhashval = clientstr_hashval(dname); 1586 1513 1514 + /* Cases below refer to rfc 5661 section 18.35.4: */ 1587 1515 nfs4_lock_state(); 1588 - status = nfs_ok; 1589 - 1590 1516 conf = find_confirmed_client_by_str(dname, strhashval); 1591 1517 if (conf) { 1592 - if (!clp_used_exchangeid(conf)) { 1593 - status = nfserr_clid_inuse; /* XXX: ? */ 1594 - goto out; 1595 - } 1596 - if (!same_verf(&verf, &conf->cl_verifier)) { 1597 - /* 18.35.4 case 8 */ 1598 - if (exid->flags & EXCHGID4_FLAG_UPD_CONFIRMED_REC_A) { 1599 - status = nfserr_not_same; 1518 + bool creds_match = same_creds(&conf->cl_cred, &rqstp->rq_cred); 1519 + bool verfs_match = same_verf(&verf, &conf->cl_verifier); 1520 + 1521 + if (update) { 1522 + if (!clp_used_exchangeid(conf)) { /* buggy client */ 1523 + status = nfserr_inval; 1600 1524 goto out; 1601 1525 } 1602 - /* Client reboot: destroy old state */ 1603 - expire_client(conf); 1604 - goto out_new; 1605 - } 1606 - if (!same_creds(&conf->cl_cred, &rqstp->rq_cred)) { 1607 - /* 18.35.4 case 9 */ 1608 - if (exid->flags & EXCHGID4_FLAG_UPD_CONFIRMED_REC_A) { 1526 + if (!creds_match) { /* case 9 */ 1609 1527 status = nfserr_perm; 1610 1528 goto out; 1611 1529 } 1530 + if (!verfs_match) { /* case 8 */ 1531 + status = nfserr_not_same; 1532 + goto out; 1533 + } 1534 + /* case 6 */ 1535 + exid->flags |= EXCHGID4_FLAG_CONFIRMED_R; 1536 + new = conf; 1537 + goto out_copy; 1538 + } 1539 + if (!creds_match) { /* case 3 */ 1540 + if (client_has_state(conf)) { 1541 + status = nfserr_clid_inuse; 1542 + goto out; 1543 + } 1612 1544 expire_client(conf); 1613 1545 goto out_new; 1614 1546 } 1615 - /* 1616 - * Set bit when the owner id and verifier map to an already 1617 - * confirmed client id (18.35.3). 1618 - */ 1619 - exid->flags |= EXCHGID4_FLAG_CONFIRMED_R; 1620 - 1621 - /* 1622 - * Falling into 18.35.4 case 2, possible router replay. 1623 - * Leave confirmed record intact and return same result. 1624 - */ 1625 - copy_verf(conf, &verf); 1626 - new = conf; 1627 - goto out_copy; 1547 + if (verfs_match) { /* case 2 */ 1548 + conf->cl_exchange_flags |= EXCHGID4_FLAG_CONFIRMED_R; 1549 + new = conf; 1550 + goto out_copy; 1551 + } 1552 + /* case 5, client reboot */ 1553 + goto out_new; 1628 1554 } 1629 1555 1630 - /* 18.35.4 case 7 */ 1631 - if (exid->flags & EXCHGID4_FLAG_UPD_CONFIRMED_REC_A) { 1556 + if (update) { /* case 7 */ 1632 1557 status = nfserr_noent; 1633 1558 goto out; 1634 1559 } 1635 1560 1636 1561 unconf = find_unconfirmed_client_by_str(dname, strhashval); 1637 - if (unconf) { 1638 - /* 1639 - * Possible retry or client restart. Per 18.35.4 case 4, 1640 - * a new unconfirmed record should be generated regardless 1641 - * of whether any properties have changed. 1642 - */ 1562 + if (unconf) /* case 4, possible retry or client restart */ 1643 1563 expire_client(unconf); 1644 - } 1645 1564 1565 + /* case 1 (normal case) */ 1646 1566 out_new: 1647 - /* Normal case */ 1648 1567 new = create_client(exid->clname, dname, rqstp, &verf); 1649 1568 if (new == NULL) { 1650 1569 status = nfserr_jukebox; ··· 1649 1584 exid->clientid.cl_boot = new->cl_clientid.cl_boot; 1650 1585 exid->clientid.cl_id = new->cl_clientid.cl_id; 1651 1586 1652 - exid->seqid = 1; 1587 + exid->seqid = new->cl_cs_slot.sl_seqid + 1; 1653 1588 nfsd4_set_ex_flags(new, exid); 1654 1589 1655 1590 dprintk("nfsd4_exchange_id seqid %d flags %x\n", ··· 1658 1593 1659 1594 out: 1660 1595 nfs4_unlock_state(); 1661 - error: 1662 - dprintk("nfsd4_exchange_id returns %d\n", ntohl(status)); 1663 1596 return status; 1664 1597 } 1665 1598 1666 - static int 1599 + static __be32 1667 1600 check_slot_seqid(u32 seqid, u32 slot_seqid, int slot_inuse) 1668 1601 { 1669 1602 dprintk("%s enter. seqid %d slot_seqid %d\n", __func__, seqid, ··· 1689 1626 */ 1690 1627 static void 1691 1628 nfsd4_cache_create_session(struct nfsd4_create_session *cr_ses, 1692 - struct nfsd4_clid_slot *slot, int nfserr) 1629 + struct nfsd4_clid_slot *slot, __be32 nfserr) 1693 1630 { 1694 1631 slot->sl_status = nfserr; 1695 1632 memcpy(&slot->sl_cr_ses, cr_ses, sizeof(*cr_ses)); ··· 1720 1657 /* seqid, slotID, slotID, slotID, status */ \ 1721 1658 5 ) * sizeof(__be32)) 1722 1659 1723 - static __be32 check_forechannel_attrs(struct nfsd4_channel_attrs fchannel) 1660 + static bool check_forechannel_attrs(struct nfsd4_channel_attrs fchannel) 1724 1661 { 1725 1662 return fchannel.maxreq_sz < NFSD_MIN_REQ_HDR_SEQ_SZ 1726 1663 || fchannel.maxresp_sz < NFSD_MIN_RESP_HDR_SEQ_SZ; ··· 1736 1673 struct nfsd4_session *new; 1737 1674 struct nfsd4_clid_slot *cs_slot = NULL; 1738 1675 bool confirm_me = false; 1739 - int status = 0; 1676 + __be32 status = 0; 1740 1677 1741 1678 if (cr_ses->flags & ~SESSION4_FLAG_MASK_A) 1742 1679 return nfserr_inval; ··· 1749 1686 cs_slot = &conf->cl_cs_slot; 1750 1687 status = check_slot_seqid(cr_ses->seqid, cs_slot->sl_seqid, 0); 1751 1688 if (status == nfserr_replay_cache) { 1752 - dprintk("Got a create_session replay! seqid= %d\n", 1753 - cs_slot->sl_seqid); 1754 - /* Return the cached reply status */ 1755 1689 status = nfsd4_replay_create_session(cr_ses, cs_slot); 1756 1690 goto out; 1757 1691 } else if (cr_ses->seqid != cs_slot->sl_seqid + 1) { 1758 1692 status = nfserr_seq_misordered; 1759 - dprintk("Sequence misordered!\n"); 1760 - dprintk("Expected seqid= %d but got seqid= %d\n", 1761 - cs_slot->sl_seqid, cr_ses->seqid); 1762 1693 goto out; 1763 1694 } 1764 1695 } else if (unconf) { ··· 1761 1704 status = nfserr_clid_inuse; 1762 1705 goto out; 1763 1706 } 1764 - 1765 1707 cs_slot = &unconf->cl_cs_slot; 1766 1708 status = check_slot_seqid(cr_ses->seqid, cs_slot->sl_seqid, 0); 1767 1709 if (status) { ··· 1768 1712 status = nfserr_seq_misordered; 1769 1713 goto out; 1770 1714 } 1771 - 1772 1715 confirm_me = true; 1773 1716 conf = unconf; 1774 1717 } else { ··· 1804 1749 1805 1750 /* cache solo and embedded create sessions under the state lock */ 1806 1751 nfsd4_cache_create_session(cr_ses, cs_slot, status); 1807 - if (confirm_me) 1752 + if (confirm_me) { 1753 + unsigned int hash = clientstr_hashval(unconf->cl_recdir); 1754 + struct nfs4_client *old = 1755 + find_confirmed_client_by_str(conf->cl_recdir, hash); 1756 + if (old) 1757 + expire_client(old); 1808 1758 move_to_confirmed(conf); 1759 + } 1809 1760 out: 1810 1761 nfs4_unlock_state(); 1811 1762 dprintk("%s returns %d\n", __func__, ntohl(status)); ··· 1879 1818 struct nfsd4_destroy_session *sessionid) 1880 1819 { 1881 1820 struct nfsd4_session *ses; 1882 - u32 status = nfserr_badsession; 1821 + __be32 status = nfserr_badsession; 1883 1822 1884 1823 /* Notes: 1885 1824 * - The confirmed nfs4_client->cl_sessionid holds destroyed sessinid ··· 1975 1914 struct nfsd4_session *session; 1976 1915 struct nfsd4_slot *slot; 1977 1916 struct nfsd4_conn *conn; 1978 - int status; 1917 + __be32 status; 1979 1918 1980 1919 if (resp->opcnt != 1) 1981 1920 return nfserr_sequence_pos; ··· 2069 2008 return status; 2070 2009 } 2071 2010 2072 - static inline bool has_resources(struct nfs4_client *clp) 2073 - { 2074 - return !list_empty(&clp->cl_openowners) 2075 - || !list_empty(&clp->cl_delegations) 2076 - || !list_empty(&clp->cl_sessions); 2077 - } 2078 - 2079 2011 __be32 2080 2012 nfsd4_destroy_clientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_destroy_clientid *dc) 2081 2013 { 2082 2014 struct nfs4_client *conf, *unconf, *clp; 2083 - int status = 0; 2015 + __be32 status = 0; 2084 2016 2085 2017 nfs4_lock_state(); 2086 2018 unconf = find_unconfirmed_client(&dc->clientid); ··· 2082 2028 if (conf) { 2083 2029 clp = conf; 2084 2030 2085 - if (!is_client_expired(conf) && has_resources(conf)) { 2031 + if (!is_client_expired(conf) && client_has_state(conf)) { 2086 2032 status = nfserr_clientid_busy; 2087 2033 goto out; 2088 2034 } ··· 2109 2055 __be32 2110 2056 nfsd4_reclaim_complete(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_reclaim_complete *rc) 2111 2057 { 2112 - int status = 0; 2058 + __be32 status = 0; 2113 2059 2114 2060 if (rc->rca_one_fs) { 2115 2061 if (!cstate->current_fh.fh_dentry) ··· 2160 2106 if (status) 2161 2107 return status; 2162 2108 2163 - /* 2164 - * XXX The Duplicate Request Cache (DRC) has been checked (??) 2165 - * We get here on a DRC miss. 2166 - */ 2167 - 2168 2109 strhashval = clientstr_hashval(dname); 2169 2110 2111 + /* Cases below refer to rfc 3530 section 14.2.33: */ 2170 2112 nfs4_lock_state(); 2171 2113 conf = find_confirmed_client_by_str(dname, strhashval); 2172 2114 if (conf) { 2173 - /* RFC 3530 14.2.33 CASE 0: */ 2115 + /* case 0: */ 2174 2116 status = nfserr_clid_inuse; 2175 2117 if (clp_used_exchangeid(conf)) 2176 2118 goto out; ··· 2179 2129 goto out; 2180 2130 } 2181 2131 } 2182 - /* 2183 - * section 14.2.33 of RFC 3530 (under the heading "IMPLEMENTATION") 2184 - * has a description of SETCLIENTID request processing consisting 2185 - * of 5 bullet points, labeled as CASE0 - CASE4 below. 2186 - */ 2187 2132 unconf = find_unconfirmed_client_by_str(dname, strhashval); 2188 - status = nfserr_jukebox; 2189 - if (!conf) { 2190 - /* 2191 - * RFC 3530 14.2.33 CASE 4: 2192 - * placed first, because it is the normal case 2193 - */ 2194 - if (unconf) 2195 - expire_client(unconf); 2196 - new = create_client(clname, dname, rqstp, &clverifier); 2197 - if (new == NULL) 2198 - goto out; 2199 - gen_clid(new); 2200 - } else if (same_verf(&conf->cl_verifier, &clverifier)) { 2201 - /* 2202 - * RFC 3530 14.2.33 CASE 1: 2203 - * probable callback update 2204 - */ 2205 - if (unconf) { 2206 - /* Note this is removing unconfirmed {*x***}, 2207 - * which is stronger than RFC recommended {vxc**}. 2208 - * This has the advantage that there is at most 2209 - * one {*x***} in either list at any time. 2210 - */ 2211 - expire_client(unconf); 2212 - } 2213 - new = create_client(clname, dname, rqstp, &clverifier); 2214 - if (new == NULL) 2215 - goto out; 2216 - copy_clid(new, conf); 2217 - } else if (!unconf) { 2218 - /* 2219 - * RFC 3530 14.2.33 CASE 2: 2220 - * probable client reboot; state will be removed if 2221 - * confirmed. 2222 - */ 2223 - new = create_client(clname, dname, rqstp, &clverifier); 2224 - if (new == NULL) 2225 - goto out; 2226 - gen_clid(new); 2227 - } else { 2228 - /* 2229 - * RFC 3530 14.2.33 CASE 3: 2230 - * probable client reboot; state will be removed if 2231 - * confirmed. 2232 - */ 2133 + if (unconf) 2233 2134 expire_client(unconf); 2234 - new = create_client(clname, dname, rqstp, &clverifier); 2235 - if (new == NULL) 2236 - goto out; 2135 + status = nfserr_jukebox; 2136 + new = create_client(clname, dname, rqstp, &clverifier); 2137 + if (new == NULL) 2138 + goto out; 2139 + if (conf && same_verf(&conf->cl_verifier, &clverifier)) 2140 + /* case 1: probable callback update */ 2141 + copy_clid(new, conf); 2142 + else /* case 4 (new client) or cases 2, 3 (client reboot): */ 2237 2143 gen_clid(new); 2238 - } 2239 2144 /* 2240 2145 * XXX: we should probably set this at creation time, and check 2241 2146 * for consistent minorversion use throughout: ··· 2208 2203 } 2209 2204 2210 2205 2211 - /* 2212 - * Section 14.2.34 of RFC 3530 (under the heading "IMPLEMENTATION") has 2213 - * a description of SETCLIENTID_CONFIRM request processing consisting of 4 2214 - * bullets, labeled as CASE1 - CASE4 below. 2215 - */ 2216 2206 __be32 2217 2207 nfsd4_setclientid_confirm(struct svc_rqst *rqstp, 2218 2208 struct nfsd4_compound_state *cstate, 2219 2209 struct nfsd4_setclientid_confirm *setclientid_confirm) 2220 2210 { 2221 - struct sockaddr *sa = svc_addr(rqstp); 2222 2211 struct nfs4_client *conf, *unconf; 2223 2212 nfs4_verifier confirm = setclientid_confirm->sc_confirm; 2224 2213 clientid_t * clid = &setclientid_confirm->sc_clientid; ··· 2220 2221 2221 2222 if (STALE_CLIENTID(clid)) 2222 2223 return nfserr_stale_clientid; 2223 - /* 2224 - * XXX The Duplicate Request Cache (DRC) has been checked (??) 2225 - * We get here on a DRC miss. 2226 - */ 2227 - 2228 2224 nfs4_lock_state(); 2229 2225 2230 2226 conf = find_confirmed_client(clid); 2231 2227 unconf = find_unconfirmed_client(clid); 2232 - 2233 - status = nfserr_clid_inuse; 2234 - if (conf && !rpc_cmp_addr((struct sockaddr *) &conf->cl_addr, sa)) 2235 - goto out; 2236 - if (unconf && !rpc_cmp_addr((struct sockaddr *) &unconf->cl_addr, sa)) 2237 - goto out; 2238 - 2239 2228 /* 2240 - * section 14.2.34 of RFC 3530 has a description of 2241 - * SETCLIENTID_CONFIRM request processing consisting 2242 - * of 4 bullet points, labeled as CASE1 - CASE4 below. 2229 + * We try hard to give out unique clientid's, so if we get an 2230 + * attempt to confirm the same clientid with a different cred, 2231 + * there's a bug somewhere. Let's charitably assume it's our 2232 + * bug. 2243 2233 */ 2244 - if (conf && unconf && same_verf(&confirm, &unconf->cl_confirm)) { 2245 - /* 2246 - * RFC 3530 14.2.34 CASE 1: 2247 - * callback update 2248 - */ 2249 - if (!same_creds(&conf->cl_cred, &unconf->cl_cred)) 2250 - status = nfserr_clid_inuse; 2251 - else { 2252 - nfsd4_change_callback(conf, &unconf->cl_cb_conn); 2253 - nfsd4_probe_callback(conf); 2254 - expire_client(unconf); 2234 + status = nfserr_serverfault; 2235 + if (unconf && !same_creds(&unconf->cl_cred, &rqstp->rq_cred)) 2236 + goto out; 2237 + if (conf && !same_creds(&conf->cl_cred, &rqstp->rq_cred)) 2238 + goto out; 2239 + /* cases below refer to rfc 3530 section 14.2.34: */ 2240 + if (!unconf || !same_verf(&confirm, &unconf->cl_confirm)) { 2241 + if (conf && !unconf) /* case 2: probable retransmit */ 2255 2242 status = nfs_ok; 2243 + else /* case 4: client hasn't noticed we rebooted yet? */ 2244 + status = nfserr_stale_clientid; 2245 + goto out; 2246 + } 2247 + status = nfs_ok; 2248 + if (conf) { /* case 1: callback update */ 2249 + nfsd4_change_callback(conf, &unconf->cl_cb_conn); 2250 + nfsd4_probe_callback(conf); 2251 + expire_client(unconf); 2252 + } else { /* case 3: normal case; new or rebooted client */ 2253 + unsigned int hash = clientstr_hashval(unconf->cl_recdir); 2256 2254 2255 + conf = find_confirmed_client_by_str(unconf->cl_recdir, hash); 2256 + if (conf) { 2257 + nfsd4_client_record_remove(conf); 2258 + expire_client(conf); 2257 2259 } 2258 - } else if (conf && !unconf) { 2259 - /* 2260 - * RFC 3530 14.2.34 CASE 2: 2261 - * probable retransmitted request; play it safe and 2262 - * do nothing. 2263 - */ 2264 - if (!same_creds(&conf->cl_cred, &rqstp->rq_cred)) 2265 - status = nfserr_clid_inuse; 2266 - else 2267 - status = nfs_ok; 2268 - } else if (!conf && unconf 2269 - && same_verf(&unconf->cl_confirm, &confirm)) { 2270 - /* 2271 - * RFC 3530 14.2.34 CASE 3: 2272 - * Normal case; new or rebooted client: 2273 - */ 2274 - if (!same_creds(&unconf->cl_cred, &rqstp->rq_cred)) { 2275 - status = nfserr_clid_inuse; 2276 - } else { 2277 - unsigned int hash = 2278 - clientstr_hashval(unconf->cl_recdir); 2279 - conf = find_confirmed_client_by_str(unconf->cl_recdir, 2280 - hash); 2281 - if (conf) { 2282 - nfsd4_client_record_remove(conf); 2283 - expire_client(conf); 2284 - } 2285 - move_to_confirmed(unconf); 2286 - conf = unconf; 2287 - nfsd4_probe_callback(conf); 2288 - status = nfs_ok; 2289 - } 2290 - } else if ((!conf || (conf && !same_verf(&conf->cl_confirm, &confirm))) 2291 - && (!unconf || (unconf && !same_verf(&unconf->cl_confirm, 2292 - &confirm)))) { 2293 - /* 2294 - * RFC 3530 14.2.34 CASE 4: 2295 - * Client probably hasn't noticed that we rebooted yet. 2296 - */ 2297 - status = nfserr_stale_clientid; 2298 - } else { 2299 - /* check that we have hit one of the cases...*/ 2300 - status = nfserr_clid_inuse; 2260 + move_to_confirmed(unconf); 2261 + nfsd4_probe_callback(unconf); 2301 2262 } 2302 2263 out: 2303 2264 nfs4_unlock_state(); ··· 2413 2454 stp->st_file = fp; 2414 2455 stp->st_access_bmap = 0; 2415 2456 stp->st_deny_bmap = 0; 2416 - __set_bit(open->op_share_access, &stp->st_access_bmap); 2417 - __set_bit(open->op_share_deny, &stp->st_deny_bmap); 2457 + set_access(open->op_share_access, stp); 2458 + set_deny(open->op_share_deny, stp); 2418 2459 stp->st_openstp = NULL; 2419 2460 } 2420 2461 ··· 2493 2534 ret = nfserr_locked; 2494 2535 /* Search for conflicting share reservations */ 2495 2536 list_for_each_entry(stp, &fp->fi_stateids, st_perfile) { 2496 - if (test_bit(deny_type, &stp->st_deny_bmap) || 2497 - test_bit(NFS4_SHARE_DENY_BOTH, &stp->st_deny_bmap)) 2537 + if (test_deny(deny_type, stp) || 2538 + test_deny(NFS4_SHARE_DENY_BOTH, stp)) 2498 2539 goto out; 2499 2540 } 2500 2541 ret = nfs_ok; ··· 2750 2791 bool new_access; 2751 2792 __be32 status; 2752 2793 2753 - new_access = !test_bit(op_share_access, &stp->st_access_bmap); 2794 + new_access = !test_access(op_share_access, stp); 2754 2795 if (new_access) { 2755 2796 status = nfs4_get_vfs_file(rqstp, fp, cur_fh, open); 2756 2797 if (status) ··· 2765 2806 return status; 2766 2807 } 2767 2808 /* remember the open */ 2768 - __set_bit(op_share_access, &stp->st_access_bmap); 2769 - __set_bit(open->op_share_deny, &stp->st_deny_bmap); 2809 + set_access(op_share_access, stp); 2810 + set_deny(open->op_share_deny, stp); 2770 2811 2771 2812 return nfs_ok; 2772 2813 } ··· 3241 3282 } 3242 3283 3243 3284 static inline int 3244 - access_permit_read(unsigned long access_bmap) 3285 + access_permit_read(struct nfs4_ol_stateid *stp) 3245 3286 { 3246 - return test_bit(NFS4_SHARE_ACCESS_READ, &access_bmap) || 3247 - test_bit(NFS4_SHARE_ACCESS_BOTH, &access_bmap) || 3248 - test_bit(NFS4_SHARE_ACCESS_WRITE, &access_bmap); 3287 + return test_access(NFS4_SHARE_ACCESS_READ, stp) || 3288 + test_access(NFS4_SHARE_ACCESS_BOTH, stp) || 3289 + test_access(NFS4_SHARE_ACCESS_WRITE, stp); 3249 3290 } 3250 3291 3251 3292 static inline int 3252 - access_permit_write(unsigned long access_bmap) 3293 + access_permit_write(struct nfs4_ol_stateid *stp) 3253 3294 { 3254 - return test_bit(NFS4_SHARE_ACCESS_WRITE, &access_bmap) || 3255 - test_bit(NFS4_SHARE_ACCESS_BOTH, &access_bmap); 3295 + return test_access(NFS4_SHARE_ACCESS_WRITE, stp) || 3296 + test_access(NFS4_SHARE_ACCESS_BOTH, stp); 3256 3297 } 3257 3298 3258 3299 static ··· 3263 3304 /* For lock stateid's, we test the parent open, not the lock: */ 3264 3305 if (stp->st_openstp) 3265 3306 stp = stp->st_openstp; 3266 - if ((flags & WR_STATE) && (!access_permit_write(stp->st_access_bmap))) 3307 + if ((flags & WR_STATE) && !access_permit_write(stp)) 3267 3308 goto out; 3268 - if ((flags & RD_STATE) && (!access_permit_read(stp->st_access_bmap))) 3309 + if ((flags & RD_STATE) && !access_permit_read(stp)) 3269 3310 goto out; 3270 3311 status = nfs_ok; 3271 3312 out: ··· 3305 3346 return (s32)a->si_generation - (s32)b->si_generation > 0; 3306 3347 } 3307 3348 3308 - static int check_stateid_generation(stateid_t *in, stateid_t *ref, bool has_session) 3349 + static __be32 check_stateid_generation(stateid_t *in, stateid_t *ref, bool has_session) 3309 3350 { 3310 3351 /* 3311 3352 * When sessions are used the stateid generation number is ignored ··· 3614 3655 3615 3656 static inline void nfs4_stateid_downgrade_bit(struct nfs4_ol_stateid *stp, u32 access) 3616 3657 { 3617 - if (!test_bit(access, &stp->st_access_bmap)) 3658 + if (!test_access(access, stp)) 3618 3659 return; 3619 3660 nfs4_file_put_access(stp->st_file, nfs4_access_to_omode(access)); 3620 - __clear_bit(access, &stp->st_access_bmap); 3661 + clear_access(access, stp); 3621 3662 } 3622 3663 3623 3664 static inline void nfs4_stateid_downgrade(struct nfs4_ol_stateid *stp, u32 to_access) ··· 3639 3680 } 3640 3681 3641 3682 static void 3642 - reset_union_bmap_deny(unsigned long deny, unsigned long *bmap) 3683 + reset_union_bmap_deny(unsigned long deny, struct nfs4_ol_stateid *stp) 3643 3684 { 3644 3685 int i; 3645 3686 for (i = 0; i < 4; i++) { 3646 3687 if ((i & deny) != i) 3647 - __clear_bit(i, bmap); 3688 + clear_deny(i, stp); 3648 3689 } 3649 3690 } 3650 3691 ··· 3671 3712 if (status) 3672 3713 goto out; 3673 3714 status = nfserr_inval; 3674 - if (!test_bit(od->od_share_access, &stp->st_access_bmap)) { 3675 - dprintk("NFSD:access not a subset current bitmap: 0x%lx, input access=%08x\n", 3715 + if (!test_access(od->od_share_access, stp)) { 3716 + dprintk("NFSD: access not a subset current bitmap: 0x%lx, input access=%08x\n", 3676 3717 stp->st_access_bmap, od->od_share_access); 3677 3718 goto out; 3678 3719 } 3679 - if (!test_bit(od->od_share_deny, &stp->st_deny_bmap)) { 3720 + if (!test_deny(od->od_share_deny, stp)) { 3680 3721 dprintk("NFSD:deny not a subset current bitmap: 0x%lx, input deny=%08x\n", 3681 3722 stp->st_deny_bmap, od->od_share_deny); 3682 3723 goto out; 3683 3724 } 3684 3725 nfs4_stateid_downgrade(stp, od->od_share_access); 3685 3726 3686 - reset_union_bmap_deny(od->od_share_deny, &stp->st_deny_bmap); 3727 + reset_union_bmap_deny(od->od_share_deny, stp); 3687 3728 3688 3729 update_stateid(&stp->st_stid.sc_stateid); 3689 3730 memcpy(&od->od_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t)); ··· 3973 4014 struct nfs4_file *fp = lock_stp->st_file; 3974 4015 int oflag = nfs4_access_to_omode(access); 3975 4016 3976 - if (test_bit(access, &lock_stp->st_access_bmap)) 4017 + if (test_access(access, lock_stp)) 3977 4018 return; 3978 4019 nfs4_file_get_access(fp, oflag); 3979 - __set_bit(access, &lock_stp->st_access_bmap); 4020 + set_access(access, lock_stp); 3980 4021 } 3981 4022 3982 - __be32 lookup_or_create_lock_state(struct nfsd4_compound_state *cstate, struct nfs4_ol_stateid *ost, struct nfsd4_lock *lock, struct nfs4_ol_stateid **lst, bool *new) 4023 + static __be32 lookup_or_create_lock_state(struct nfsd4_compound_state *cstate, struct nfs4_ol_stateid *ost, struct nfsd4_lock *lock, struct nfs4_ol_stateid **lst, bool *new) 3983 4024 { 3984 4025 struct nfs4_file *fi = ost->st_file; 3985 4026 struct nfs4_openowner *oo = openowner(ost->st_stateowner);
+44 -18
fs/nfsd/nfs4xdr.c
··· 1674 1674 1675 1675 static void write32(__be32 **p, u32 n) 1676 1676 { 1677 - *(*p)++ = n; 1677 + *(*p)++ = htonl(n); 1678 1678 } 1679 1679 1680 1680 static void write64(__be32 **p, u64 n) 1681 1681 { 1682 - write32(p, (u32)(n >> 32)); 1682 + write32(p, (n >> 32)); 1683 1683 write32(p, (u32)n); 1684 1684 } 1685 1685 ··· 1744 1744 } 1745 1745 1746 1746 /* Encode as an array of strings the string given with components 1747 - * separated @sep. 1747 + * separated @sep, escaped with esc_enter and esc_exit. 1748 1748 */ 1749 - static __be32 nfsd4_encode_components(char sep, char *components, 1750 - __be32 **pp, int *buflen) 1749 + static __be32 nfsd4_encode_components_esc(char sep, char *components, 1750 + __be32 **pp, int *buflen, 1751 + char esc_enter, char esc_exit) 1751 1752 { 1752 1753 __be32 *p = *pp; 1753 1754 __be32 *countp = p; 1754 1755 int strlen, count=0; 1755 - char *str, *end; 1756 + char *str, *end, *next; 1756 1757 1757 1758 dprintk("nfsd4_encode_components(%s)\n", components); 1758 1759 if ((*buflen -= 4) < 0) ··· 1761 1760 WRITE32(0); /* We will fill this in with @count later */ 1762 1761 end = str = components; 1763 1762 while (*end) { 1764 - for (; *end && (*end != sep); end++) 1765 - ; /* Point to end of component */ 1763 + bool found_esc = false; 1764 + 1765 + /* try to parse as esc_start, ..., esc_end, sep */ 1766 + if (*str == esc_enter) { 1767 + for (; *end && (*end != esc_exit); end++) 1768 + /* find esc_exit or end of string */; 1769 + next = end + 1; 1770 + if (*end && (!*next || *next == sep)) { 1771 + str++; 1772 + found_esc = true; 1773 + } 1774 + } 1775 + 1776 + if (!found_esc) 1777 + for (; *end && (*end != sep); end++) 1778 + /* find sep or end of string */; 1779 + 1766 1780 strlen = end - str; 1767 1781 if (strlen) { 1768 1782 if ((*buflen -= ((XDR_QUADLEN(strlen) << 2) + 4)) < 0) ··· 1796 1780 return 0; 1797 1781 } 1798 1782 1783 + /* Encode as an array of strings the string given with components 1784 + * separated @sep. 1785 + */ 1786 + static __be32 nfsd4_encode_components(char sep, char *components, 1787 + __be32 **pp, int *buflen) 1788 + { 1789 + return nfsd4_encode_components_esc(sep, components, pp, buflen, 0, 0); 1790 + } 1791 + 1799 1792 /* 1800 1793 * encode a location element of a fs_locations structure 1801 1794 */ ··· 1814 1789 __be32 status; 1815 1790 __be32 *p = *pp; 1816 1791 1817 - status = nfsd4_encode_components(':', location->hosts, &p, buflen); 1792 + status = nfsd4_encode_components_esc(':', location->hosts, &p, buflen, 1793 + '[', ']'); 1818 1794 if (status) 1819 1795 return status; 1820 1796 status = nfsd4_encode_components('/', location->path, &p, buflen); ··· 3277 3251 } 3278 3252 3279 3253 static __be32 3280 - nfsd4_encode_exchange_id(struct nfsd4_compoundres *resp, int nfserr, 3254 + nfsd4_encode_exchange_id(struct nfsd4_compoundres *resp, __be32 nfserr, 3281 3255 struct nfsd4_exchange_id *exid) 3282 3256 { 3283 3257 __be32 *p; ··· 3332 3306 } 3333 3307 3334 3308 static __be32 3335 - nfsd4_encode_create_session(struct nfsd4_compoundres *resp, int nfserr, 3309 + nfsd4_encode_create_session(struct nfsd4_compoundres *resp, __be32 nfserr, 3336 3310 struct nfsd4_create_session *sess) 3337 3311 { 3338 3312 __be32 *p; ··· 3381 3355 } 3382 3356 3383 3357 static __be32 3384 - nfsd4_encode_destroy_session(struct nfsd4_compoundres *resp, int nfserr, 3358 + nfsd4_encode_destroy_session(struct nfsd4_compoundres *resp, __be32 nfserr, 3385 3359 struct nfsd4_destroy_session *destroy_session) 3386 3360 { 3387 3361 return nfserr; 3388 3362 } 3389 3363 3390 3364 static __be32 3391 - nfsd4_encode_free_stateid(struct nfsd4_compoundres *resp, int nfserr, 3365 + nfsd4_encode_free_stateid(struct nfsd4_compoundres *resp, __be32 nfserr, 3392 3366 struct nfsd4_free_stateid *free_stateid) 3393 3367 { 3394 3368 __be32 *p; ··· 3397 3371 return nfserr; 3398 3372 3399 3373 RESERVE_SPACE(4); 3400 - WRITE32(nfserr); 3374 + *p++ = nfserr; 3401 3375 ADJUST_ARGS(); 3402 3376 return nfserr; 3403 3377 } 3404 3378 3405 3379 static __be32 3406 - nfsd4_encode_sequence(struct nfsd4_compoundres *resp, int nfserr, 3380 + nfsd4_encode_sequence(struct nfsd4_compoundres *resp, __be32 nfserr, 3407 3381 struct nfsd4_sequence *seq) 3408 3382 { 3409 3383 __be32 *p; ··· 3425 3399 return 0; 3426 3400 } 3427 3401 3428 - __be32 3429 - nfsd4_encode_test_stateid(struct nfsd4_compoundres *resp, int nfserr, 3402 + static __be32 3403 + nfsd4_encode_test_stateid(struct nfsd4_compoundres *resp, __be32 nfserr, 3430 3404 struct nfsd4_test_stateid *test_stateid) 3431 3405 { 3432 3406 struct nfsd4_test_stateid_id *stateid, *next; ··· 3529 3503 * Our se_fmaxresp_cached will always be a multiple of PAGE_SIZE, and so 3530 3504 * will be at least a page and will therefore hold the xdr_buf head. 3531 3505 */ 3532 - int nfsd4_check_resp_size(struct nfsd4_compoundres *resp, u32 pad) 3506 + __be32 nfsd4_check_resp_size(struct nfsd4_compoundres *resp, u32 pad) 3533 3507 { 3534 3508 struct xdr_buf *xb = &resp->rqstp->rq_res; 3535 3509 struct nfsd4_session *session = NULL;
+9 -3
fs/nfsd/nfsctl.c
··· 661 661 { 662 662 char *mesg = buf; 663 663 int fd, err; 664 + struct net *net = &init_net; 664 665 665 666 err = get_int(&mesg, &fd); 666 667 if (err != 0 || fd < 0) ··· 673 672 674 673 err = svc_addsock(nfsd_serv, fd, buf, SIMPLE_TRANSACTION_LIMIT); 675 674 if (err < 0) { 675 + if (nfsd_serv->sv_nrthreads == 1) 676 + svc_shutdown_net(nfsd_serv, net); 676 677 svc_destroy(nfsd_serv); 677 678 return err; 678 679 } ··· 712 709 char transport[16]; 713 710 struct svc_xprt *xprt; 714 711 int port, err; 712 + struct net *net = &init_net; 715 713 716 714 if (sscanf(buf, "%15s %4u", transport, &port) != 2) 717 715 return -EINVAL; ··· 724 720 if (err != 0) 725 721 return err; 726 722 727 - err = svc_create_xprt(nfsd_serv, transport, &init_net, 723 + err = svc_create_xprt(nfsd_serv, transport, net, 728 724 PF_INET, port, SVC_SOCK_ANONYMOUS); 729 725 if (err < 0) 730 726 goto out_err; 731 727 732 - err = svc_create_xprt(nfsd_serv, transport, &init_net, 728 + err = svc_create_xprt(nfsd_serv, transport, net, 733 729 PF_INET6, port, SVC_SOCK_ANONYMOUS); 734 730 if (err < 0 && err != -EAFNOSUPPORT) 735 731 goto out_close; ··· 738 734 nfsd_serv->sv_nrthreads--; 739 735 return 0; 740 736 out_close: 741 - xprt = svc_find_xprt(nfsd_serv, transport, &init_net, PF_INET, port); 737 + xprt = svc_find_xprt(nfsd_serv, transport, net, PF_INET, port); 742 738 if (xprt != NULL) { 743 739 svc_close_xprt(xprt); 744 740 svc_xprt_put(xprt); 745 741 } 746 742 out_err: 743 + if (nfsd_serv->sv_nrthreads == 1) 744 + svc_shutdown_net(nfsd_serv, net); 747 745 svc_destroy(nfsd_serv); 748 746 return err; 749 747 }
+23
fs/nfsd/nfssvc.c
··· 11 11 #include <linux/module.h> 12 12 #include <linux/fs_struct.h> 13 13 #include <linux/swap.h> 14 + #include <linux/nsproxy.h> 14 15 15 16 #include <linux/sunrpc/stats.h> 16 17 #include <linux/sunrpc/svcsock.h> ··· 331 330 332 331 int nfsd_create_serv(void) 333 332 { 333 + int error; 334 + 334 335 WARN_ON(!mutex_is_locked(&nfsd_mutex)); 335 336 if (nfsd_serv) { 336 337 svc_get(nfsd_serv); ··· 345 342 nfsd_last_thread, nfsd, THIS_MODULE); 346 343 if (nfsd_serv == NULL) 347 344 return -ENOMEM; 345 + 346 + error = svc_bind(nfsd_serv, current->nsproxy->net_ns); 347 + if (error < 0) { 348 + svc_destroy(nfsd_serv); 349 + return error; 350 + } 348 351 349 352 set_max_drc(); 350 353 do_gettimeofday(&nfssvc_boot); /* record boot time */ ··· 382 373 int i = 0; 383 374 int tot = 0; 384 375 int err = 0; 376 + struct net *net = &init_net; 385 377 386 378 WARN_ON(!mutex_is_locked(&nfsd_mutex)); 387 379 ··· 427 417 if (err) 428 418 break; 429 419 } 420 + 421 + if (nfsd_serv->sv_nrthreads == 1) 422 + svc_shutdown_net(nfsd_serv, net); 430 423 svc_destroy(nfsd_serv); 431 424 432 425 return err; ··· 445 432 { 446 433 int error; 447 434 bool nfsd_up_before; 435 + struct net *net = &init_net; 448 436 449 437 mutex_lock(&nfsd_mutex); 450 438 dprintk("nfsd: creating service\n"); ··· 478 464 if (error < 0 && !nfsd_up_before) 479 465 nfsd_shutdown(); 480 466 out_destroy: 467 + if (nfsd_serv->sv_nrthreads == 1) 468 + svc_shutdown_net(nfsd_serv, net); 481 469 svc_destroy(nfsd_serv); /* Release server */ 482 470 out: 483 471 mutex_unlock(&nfsd_mutex); ··· 563 547 nfsdstats.th_cnt --; 564 548 565 549 out: 550 + if (rqstp->rq_server->sv_nrthreads == 1) 551 + svc_shutdown_net(rqstp->rq_server, &init_net); 552 + 566 553 /* Release the thread */ 567 554 svc_exit_thread(rqstp); 568 555 ··· 678 659 int nfsd_pool_stats_release(struct inode *inode, struct file *file) 679 660 { 680 661 int ret = seq_release(inode, file); 662 + struct net *net = &init_net; 663 + 681 664 mutex_lock(&nfsd_mutex); 682 665 /* this function really, really should have been called svc_put() */ 666 + if (nfsd_serv->sv_nrthreads == 1) 667 + svc_shutdown_net(nfsd_serv, net); 683 668 svc_destroy(nfsd_serv); 684 669 mutex_unlock(&nfsd_mutex); 685 670 return ret;
-1
fs/nfsd/state.h
··· 232 232 time_t cl_time; /* time of last lease renewal */ 233 233 struct sockaddr_storage cl_addr; /* client ipaddress */ 234 234 u32 cl_flavor; /* setclientid pseudoflavor */ 235 - char *cl_principal; /* setclientid principal name */ 236 235 struct svc_cred cl_cred; /* setclientid principal */ 237 236 clientid_t cl_clientid; /* generated by server */ 238 237 nfs4_verifier cl_confirm; /* generated by server */
+3 -3
fs/nfsd/xdr4.h
··· 60 60 __be32 *datap; 61 61 size_t iovlen; 62 62 u32 minorversion; 63 - u32 status; 63 + __be32 status; 64 64 stateid_t current_stateid; 65 65 stateid_t save_stateid; 66 66 /* to indicate current and saved state id presents */ ··· 364 364 }; 365 365 366 366 struct nfsd4_test_stateid { 367 - __be32 ts_num_ids; 367 + u32 ts_num_ids; 368 368 struct list_head ts_stateid_list; 369 369 }; 370 370 ··· 549 549 struct nfsd4_compoundargs *); 550 550 int nfs4svc_encode_compoundres(struct svc_rqst *, __be32 *, 551 551 struct nfsd4_compoundres *); 552 - int nfsd4_check_resp_size(struct nfsd4_compoundres *, u32); 552 + __be32 nfsd4_check_resp_size(struct nfsd4_compoundres *, u32); 553 553 void nfsd4_encode_operation(struct nfsd4_compoundres *, struct nfsd4_op *); 554 554 void nfsd4_encode_replay(struct nfsd4_compoundres *resp, struct nfsd4_op *op); 555 555 __be32 nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
+1 -1
include/linux/sunrpc/svc.h
··· 232 232 struct svc_pool * rq_pool; /* thread pool */ 233 233 struct svc_procedure * rq_procinfo; /* procedure info */ 234 234 struct auth_ops * rq_authop; /* authentication flavour */ 235 - u32 rq_flavor; /* pseudoflavor */ 236 235 struct svc_cred rq_cred; /* auth info */ 237 236 void * rq_xprt_ctxt; /* transport specific context ptr */ 238 237 struct svc_deferred_req*rq_deferred; /* deferred request we are replaying */ ··· 415 416 */ 416 417 int svc_rpcb_setup(struct svc_serv *serv, struct net *net); 417 418 void svc_rpcb_cleanup(struct svc_serv *serv, struct net *net); 419 + int svc_bind(struct svc_serv *serv, struct net *net); 418 420 struct svc_serv *svc_create(struct svc_program *, unsigned int, 419 421 void (*shutdown)(struct svc_serv *, struct net *net)); 420 422 struct svc_rqst *svc_prepare_thread(struct svc_serv *serv,
+10
include/linux/sunrpc/svcauth.h
··· 15 15 #include <linux/sunrpc/msg_prot.h> 16 16 #include <linux/sunrpc/cache.h> 17 17 #include <linux/hash.h> 18 + #include <linux/cred.h> 18 19 19 20 struct svc_cred { 20 21 uid_t cr_uid; 21 22 gid_t cr_gid; 22 23 struct group_info *cr_group_info; 24 + u32 cr_flavor; /* pseudoflavor */ 25 + char *cr_principal; /* for gss */ 23 26 }; 27 + 28 + static inline void free_svc_cred(struct svc_cred *cred) 29 + { 30 + if (cred->cr_group_info) 31 + put_group_info(cred->cr_group_info); 32 + kfree(cred->cr_principal); 33 + } 24 34 25 35 struct svc_rqst; /* forward decl */ 26 36 struct in6_addr;
-1
include/linux/sunrpc/svcauth_gss.h
··· 22 22 void gss_svc_shutdown_net(struct net *net); 23 23 int svcauth_gss_register_pseudoflavor(u32 pseudoflavor, char * name); 24 24 u32 svcauth_gss_flavor(struct auth_domain *dom); 25 - char *svc_gss_principal(struct svc_rqst *); 26 25 27 26 #endif /* __KERNEL__ */ 28 27 #endif /* _LINUX_SUNRPC_SVCAUTH_GSS_H */
+45 -16
net/sunrpc/auth_gss/gss_krb5_wrap.c
··· 381 381 } 382 382 383 383 /* 384 - * We cannot currently handle tokens with rotated data. We need a 385 - * generalized routine to rotate the data in place. It is anticipated 386 - * that we won't encounter rotated data in the general case. 384 + * We can shift data by up to LOCAL_BUF_LEN bytes in a pass. If we need 385 + * to do more than that, we shift repeatedly. Kevin Coffman reports 386 + * seeing 28 bytes as the value used by Microsoft clients and servers 387 + * with AES, so this constant is chosen to allow handling 28 in one pass 388 + * without using too much stack space. 389 + * 390 + * If that proves to a problem perhaps we could use a more clever 391 + * algorithm. 387 392 */ 388 - static u32 389 - rotate_left(struct krb5_ctx *kctx, u32 offset, struct xdr_buf *buf, u16 rrc) 393 + #define LOCAL_BUF_LEN 32u 394 + 395 + static void rotate_buf_a_little(struct xdr_buf *buf, unsigned int shift) 390 396 { 391 - unsigned int realrrc = rrc % (buf->len - offset - GSS_KRB5_TOK_HDR_LEN); 397 + char head[LOCAL_BUF_LEN]; 398 + char tmp[LOCAL_BUF_LEN]; 399 + unsigned int this_len, i; 392 400 393 - if (realrrc == 0) 394 - return 0; 401 + BUG_ON(shift > LOCAL_BUF_LEN); 395 402 396 - dprintk("%s: cannot process token with rotated data: " 397 - "rrc %u, realrrc %u\n", __func__, rrc, realrrc); 398 - return 1; 403 + read_bytes_from_xdr_buf(buf, 0, head, shift); 404 + for (i = 0; i + shift < buf->len; i += LOCAL_BUF_LEN) { 405 + this_len = min(LOCAL_BUF_LEN, buf->len - (i + shift)); 406 + read_bytes_from_xdr_buf(buf, i+shift, tmp, this_len); 407 + write_bytes_to_xdr_buf(buf, i, tmp, this_len); 408 + } 409 + write_bytes_to_xdr_buf(buf, buf->len - shift, head, shift); 410 + } 411 + 412 + static void _rotate_left(struct xdr_buf *buf, unsigned int shift) 413 + { 414 + int shifted = 0; 415 + int this_shift; 416 + 417 + shift %= buf->len; 418 + while (shifted < shift) { 419 + this_shift = min(shift - shifted, LOCAL_BUF_LEN); 420 + rotate_buf_a_little(buf, this_shift); 421 + shifted += this_shift; 422 + } 423 + } 424 + 425 + static void rotate_left(u32 base, struct xdr_buf *buf, unsigned int shift) 426 + { 427 + struct xdr_buf subbuf; 428 + 429 + xdr_buf_subsegment(buf, &subbuf, base, buf->len - base); 430 + _rotate_left(&subbuf, shift); 399 431 } 400 432 401 433 static u32 ··· 527 495 528 496 seqnum = be64_to_cpup((__be64 *)(ptr + 8)); 529 497 530 - if (rrc != 0) { 531 - err = rotate_left(kctx, offset, buf, rrc); 532 - if (err) 533 - return GSS_S_FAILURE; 534 - } 498 + if (rrc != 0) 499 + rotate_left(offset + 16, buf, rrc); 535 500 536 501 err = (*kctx->gk5e->decrypt_v2)(kctx, offset, buf, 537 502 &headskip, &tailskip);
+7 -20
net/sunrpc/auth_gss/svcauth_gss.c
··· 336 336 struct svc_cred cred; 337 337 struct gss_svc_seq_data seqdata; 338 338 struct gss_ctx *mechctx; 339 - char *client_name; 340 339 }; 341 340 342 341 static struct rsc *rsc_update(struct cache_detail *cd, struct rsc *new, struct rsc *old); ··· 346 347 kfree(rsci->handle.data); 347 348 if (rsci->mechctx) 348 349 gss_delete_sec_context(&rsci->mechctx); 349 - if (rsci->cred.cr_group_info) 350 - put_group_info(rsci->cred.cr_group_info); 351 - kfree(rsci->client_name); 350 + free_svc_cred(&rsci->cred); 352 351 } 353 352 354 353 static void rsc_put(struct kref *ref) ··· 384 387 tmp->handle.data = NULL; 385 388 new->mechctx = NULL; 386 389 new->cred.cr_group_info = NULL; 387 - new->client_name = NULL; 390 + new->cred.cr_principal = NULL; 388 391 } 389 392 390 393 static void ··· 399 402 spin_lock_init(&new->seqdata.sd_lock); 400 403 new->cred = tmp->cred; 401 404 tmp->cred.cr_group_info = NULL; 402 - new->client_name = tmp->client_name; 403 - tmp->client_name = NULL; 405 + new->cred.cr_principal = tmp->cred.cr_principal; 406 + tmp->cred.cr_principal = NULL; 404 407 } 405 408 406 409 static struct cache_head * ··· 498 501 /* get client name */ 499 502 len = qword_get(&mesg, buf, mlen); 500 503 if (len > 0) { 501 - rsci.client_name = kstrdup(buf, GFP_KERNEL); 502 - if (!rsci.client_name) 504 + rsci.cred.cr_principal = kstrdup(buf, GFP_KERNEL); 505 + if (!rsci.cred.cr_principal) 503 506 goto out; 504 507 } 505 508 ··· 929 932 struct rsc *rsci; 930 933 }; 931 934 932 - char *svc_gss_principal(struct svc_rqst *rqstp) 933 - { 934 - struct gss_svc_data *gd = (struct gss_svc_data *)rqstp->rq_auth_data; 935 - 936 - if (gd && gd->rsci) 937 - return gd->rsci->client_name; 938 - return NULL; 939 - } 940 - EXPORT_SYMBOL_GPL(svc_gss_principal); 941 - 942 935 static int 943 936 svcauth_gss_set_client(struct svc_rqst *rqstp) 944 937 { ··· 1207 1220 } 1208 1221 svcdata->rsci = rsci; 1209 1222 cache_get(&rsci->h); 1210 - rqstp->rq_flavor = gss_svc_to_pseudoflavor( 1223 + rqstp->rq_cred.cr_flavor = gss_svc_to_pseudoflavor( 1211 1224 rsci->mechctx->mech_type, gc->gc_svc); 1212 1225 ret = SVC_OK; 1213 1226 goto out;
+7 -5
net/sunrpc/rpcb_clnt.c
··· 180 180 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); 181 181 struct rpc_clnt *clnt = sn->rpcb_local_clnt; 182 182 struct rpc_clnt *clnt4 = sn->rpcb_local_clnt4; 183 - int shutdown; 183 + int shutdown = 0; 184 184 185 185 spin_lock(&sn->rpcb_clnt_lock); 186 - if (--sn->rpcb_users == 0) { 187 - sn->rpcb_local_clnt = NULL; 188 - sn->rpcb_local_clnt4 = NULL; 186 + if (sn->rpcb_users) { 187 + if (--sn->rpcb_users == 0) { 188 + sn->rpcb_local_clnt = NULL; 189 + sn->rpcb_local_clnt4 = NULL; 190 + } 191 + shutdown = !sn->rpcb_users; 189 192 } 190 - shutdown = !sn->rpcb_users; 191 193 spin_unlock(&sn->rpcb_clnt_lock); 192 194 193 195 if (shutdown) {
+10 -13
net/sunrpc/svc.c
··· 407 407 return 0; 408 408 } 409 409 410 + int svc_bind(struct svc_serv *serv, struct net *net) 411 + { 412 + if (!svc_uses_rpcbind(serv)) 413 + return 0; 414 + return svc_rpcb_setup(serv, net); 415 + } 416 + EXPORT_SYMBOL_GPL(svc_bind); 417 + 410 418 /* 411 419 * Create an RPC service 412 420 */ ··· 479 471 spin_lock_init(&pool->sp_lock); 480 472 } 481 473 482 - if (svc_uses_rpcbind(serv)) { 483 - if (svc_rpcb_setup(serv, current->nsproxy->net_ns) < 0) { 484 - kfree(serv->sv_pools); 485 - kfree(serv); 486 - return NULL; 487 - } 488 - if (!serv->sv_shutdown) 489 - serv->sv_shutdown = svc_rpcb_cleanup; 490 - } 474 + if (svc_uses_rpcbind(serv) && (!serv->sv_shutdown)) 475 + serv->sv_shutdown = svc_rpcb_cleanup; 491 476 492 477 return serv; 493 478 } ··· 537 536 void 538 537 svc_destroy(struct svc_serv *serv) 539 538 { 540 - struct net *net = current->nsproxy->net_ns; 541 - 542 539 dprintk("svc: svc_destroy(%s, %d)\n", 543 540 serv->sv_program->pg_name, 544 541 serv->sv_nrthreads); ··· 550 551 printk("svc_destroy: no threads for serv=%p!\n", serv); 551 552 552 553 del_timer_sync(&serv->sv_temptimer); 553 - 554 - svc_shutdown_net(serv, net); 555 554 556 555 /* 557 556 * The last user is gone and thus all sockets have to be destroyed to
+2 -2
net/sunrpc/svc_xprt.c
··· 598 598 599 599 /* now allocate needed pages. If we get a failure, sleep briefly */ 600 600 pages = (serv->sv_max_mesg + PAGE_SIZE) / PAGE_SIZE; 601 + BUG_ON(pages >= RPCSVC_MAXPAGES); 601 602 for (i = 0; i < pages ; i++) 602 603 while (rqstp->rq_pages[i] == NULL) { 603 604 struct page *p = alloc_page(GFP_KERNEL); ··· 613 612 rqstp->rq_pages[i] = p; 614 613 } 615 614 rqstp->rq_pages[i++] = NULL; /* this might be seen in nfs_read_actor */ 616 - BUG_ON(pages >= RPCSVC_MAXPAGES); 617 615 618 616 /* Make arg->head point to first page and arg->pages point to rest */ 619 617 arg = &rqstp->rq_arg; ··· 973 973 svc_clear_pools(serv, net); 974 974 /* 975 975 * At this point the sp_sockets lists will stay empty, since 976 - * svc_enqueue will not add new entries without taking the 976 + * svc_xprt_enqueue will not add new entries without taking the 977 977 * sp_lock and checking XPT_BUSY. 978 978 */ 979 979 svc_clear_list(&serv->sv_tempsocks, net);
+4 -2
net/sunrpc/svcauth_unix.c
··· 746 746 struct svc_cred *cred = &rqstp->rq_cred; 747 747 748 748 cred->cr_group_info = NULL; 749 + cred->cr_principal = NULL; 749 750 rqstp->rq_client = NULL; 750 751 751 752 if (argv->iov_len < 3*4) ··· 774 773 svc_putnl(resv, RPC_AUTH_NULL); 775 774 svc_putnl(resv, 0); 776 775 777 - rqstp->rq_flavor = RPC_AUTH_NULL; 776 + rqstp->rq_cred.cr_flavor = RPC_AUTH_NULL; 778 777 return SVC_OK; 779 778 } 780 779 ··· 812 811 int len = argv->iov_len; 813 812 814 813 cred->cr_group_info = NULL; 814 + cred->cr_principal = NULL; 815 815 rqstp->rq_client = NULL; 816 816 817 817 if ((len -= 3*4) < 0) ··· 849 847 svc_putnl(resv, RPC_AUTH_NULL); 850 848 svc_putnl(resv, 0); 851 849 852 - rqstp->rq_flavor = RPC_AUTH_UNIX; 850 + rqstp->rq_cred.cr_flavor = RPC_AUTH_UNIX; 853 851 return SVC_OK; 854 852 855 853 badcred: