aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfsd')
-rw-r--r--fs/nfsd/lockd.c1
-rw-r--r--fs/nfsd/nfs3proc.c8
-rw-r--r--fs/nfsd/nfs4callback.c7
-rw-r--r--fs/nfsd/nfs4proc.c8
-rw-r--r--fs/nfsd/nfs4state.c34
-rw-r--r--fs/nfsd/nfs4xdr.c171
-rw-r--r--fs/nfsd/nfsctl.c5
-rw-r--r--fs/nfsd/nfsfh.c30
-rw-r--r--fs/nfsd/nfsproc.c6
-rw-r--r--fs/nfsd/nfssvc.c20
-rw-r--r--fs/nfsd/vfs.c63
11 files changed, 186 insertions, 167 deletions
diff --git a/fs/nfsd/lockd.c b/fs/nfsd/lockd.c
index 15c6faeec77c..b2786a5f9afe 100644
--- a/fs/nfsd/lockd.c
+++ b/fs/nfsd/lockd.c
@@ -70,7 +70,6 @@ nlm_fclose(struct file *filp)
70static struct nlmsvc_binding nfsd_nlm_ops = { 70static struct nlmsvc_binding nfsd_nlm_ops = {
71 .fopen = nlm_fopen, /* open file for locking */ 71 .fopen = nlm_fopen, /* open file for locking */
72 .fclose = nlm_fclose, /* close file */ 72 .fclose = nlm_fclose, /* close file */
73 .get_grace_period = get_nfs4_grace_period,
74}; 73};
75 74
76void 75void
diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c
index 4d617ea28cfc..9dbd2eb91281 100644
--- a/fs/nfsd/nfs3proc.c
+++ b/fs/nfsd/nfs3proc.c
@@ -63,7 +63,8 @@ nfsd3_proc_getattr(struct svc_rqst *rqstp, struct nfsd_fhandle *argp,
63 SVCFH_fmt(&argp->fh)); 63 SVCFH_fmt(&argp->fh));
64 64
65 fh_copy(&resp->fh, &argp->fh); 65 fh_copy(&resp->fh, &argp->fh);
66 nfserr = fh_verify(rqstp, &resp->fh, 0, NFSD_MAY_NOP); 66 nfserr = fh_verify(rqstp, &resp->fh, 0,
67 NFSD_MAY_NOP | NFSD_MAY_BYPASS_GSS_ON_ROOT);
67 if (nfserr) 68 if (nfserr)
68 RETURN_STATUS(nfserr); 69 RETURN_STATUS(nfserr);
69 70
@@ -530,7 +531,7 @@ nfsd3_proc_fsstat(struct svc_rqst * rqstp, struct nfsd_fhandle *argp,
530 dprintk("nfsd: FSSTAT(3) %s\n", 531 dprintk("nfsd: FSSTAT(3) %s\n",
531 SVCFH_fmt(&argp->fh)); 532 SVCFH_fmt(&argp->fh));
532 533
533 nfserr = nfsd_statfs(rqstp, &argp->fh, &resp->stats); 534 nfserr = nfsd_statfs(rqstp, &argp->fh, &resp->stats, 0);
534 fh_put(&argp->fh); 535 fh_put(&argp->fh);
535 RETURN_STATUS(nfserr); 536 RETURN_STATUS(nfserr);
536} 537}
@@ -558,7 +559,8 @@ nfsd3_proc_fsinfo(struct svc_rqst * rqstp, struct nfsd_fhandle *argp,
558 resp->f_maxfilesize = ~(u32) 0; 559 resp->f_maxfilesize = ~(u32) 0;
559 resp->f_properties = NFS3_FSF_DEFAULT; 560 resp->f_properties = NFS3_FSF_DEFAULT;
560 561
561 nfserr = fh_verify(rqstp, &argp->fh, 0, NFSD_MAY_NOP); 562 nfserr = fh_verify(rqstp, &argp->fh, 0,
563 NFSD_MAY_NOP | NFSD_MAY_BYPASS_GSS_ON_ROOT);
562 564
563 /* Check special features of the file system. May request 565 /* Check special features of the file system. May request
564 * different read/write sizes for file systems known to have 566 * different read/write sizes for file systems known to have
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
index 702fa577aa6e..094747a1227c 100644
--- a/fs/nfsd/nfs4callback.c
+++ b/fs/nfsd/nfs4callback.c
@@ -225,7 +225,8 @@ encode_cb_recall(struct xdr_stream *xdr, struct nfs4_cb_recall *cb_rec)
225 225
226 RESERVE_SPACE(12+sizeof(cb_rec->cbr_stateid) + len); 226 RESERVE_SPACE(12+sizeof(cb_rec->cbr_stateid) + len);
227 WRITE32(OP_CB_RECALL); 227 WRITE32(OP_CB_RECALL);
228 WRITEMEM(&cb_rec->cbr_stateid, sizeof(stateid_t)); 228 WRITE32(cb_rec->cbr_stateid.si_generation);
229 WRITEMEM(&cb_rec->cbr_stateid.si_opaque, sizeof(stateid_opaque_t));
229 WRITE32(cb_rec->cbr_trunc); 230 WRITE32(cb_rec->cbr_trunc);
230 WRITE32(len); 231 WRITE32(len);
231 WRITEMEM(cb_rec->cbr_fhval, len); 232 WRITEMEM(cb_rec->cbr_fhval, len);
@@ -379,6 +380,7 @@ static int do_probe_callback(void *data)
379 .addrsize = sizeof(addr), 380 .addrsize = sizeof(addr),
380 .timeout = &timeparms, 381 .timeout = &timeparms,
381 .program = &cb_program, 382 .program = &cb_program,
383 .prognumber = cb->cb_prog,
382 .version = nfs_cb_version[1]->number, 384 .version = nfs_cb_version[1]->number,
383 .authflavor = RPC_AUTH_UNIX, /* XXX: need AUTH_GSS... */ 385 .authflavor = RPC_AUTH_UNIX, /* XXX: need AUTH_GSS... */
384 .flags = (RPC_CLNT_CREATE_NOPING | RPC_CLNT_CREATE_QUIET), 386 .flags = (RPC_CLNT_CREATE_NOPING | RPC_CLNT_CREATE_QUIET),
@@ -396,9 +398,6 @@ static int do_probe_callback(void *data)
396 addr.sin_port = htons(cb->cb_port); 398 addr.sin_port = htons(cb->cb_port);
397 addr.sin_addr.s_addr = htonl(cb->cb_addr); 399 addr.sin_addr.s_addr = htonl(cb->cb_addr);
398 400
399 /* Initialize rpc_stat */
400 memset(args.program->stats, 0, sizeof(struct rpc_stat));
401
402 /* Create RPC client */ 401 /* Create RPC client */
403 client = rpc_create(&args); 402 client = rpc_create(&args);
404 if (IS_ERR(client)) { 403 if (IS_ERR(client)) {
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index e5b51ffafc6c..669461e291ae 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -201,10 +201,10 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
201 /* Openowner is now set, so sequence id will get bumped. Now we need 201 /* Openowner is now set, so sequence id will get bumped. Now we need
202 * these checks before we do any creates: */ 202 * these checks before we do any creates: */
203 status = nfserr_grace; 203 status = nfserr_grace;
204 if (nfs4_in_grace() && open->op_claim_type != NFS4_OPEN_CLAIM_PREVIOUS) 204 if (locks_in_grace() && open->op_claim_type != NFS4_OPEN_CLAIM_PREVIOUS)
205 goto out; 205 goto out;
206 status = nfserr_no_grace; 206 status = nfserr_no_grace;
207 if (!nfs4_in_grace() && open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS) 207 if (!locks_in_grace() && open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS)
208 goto out; 208 goto out;
209 209
210 switch (open->op_claim_type) { 210 switch (open->op_claim_type) {
@@ -575,7 +575,7 @@ nfsd4_remove(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
575{ 575{
576 __be32 status; 576 __be32 status;
577 577
578 if (nfs4_in_grace()) 578 if (locks_in_grace())
579 return nfserr_grace; 579 return nfserr_grace;
580 status = nfsd_unlink(rqstp, &cstate->current_fh, 0, 580 status = nfsd_unlink(rqstp, &cstate->current_fh, 0,
581 remove->rm_name, remove->rm_namelen); 581 remove->rm_name, remove->rm_namelen);
@@ -596,7 +596,7 @@ nfsd4_rename(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
596 596
597 if (!cstate->save_fh.fh_dentry) 597 if (!cstate->save_fh.fh_dentry)
598 return status; 598 return status;
599 if (nfs4_in_grace() && !(cstate->save_fh.fh_export->ex_flags 599 if (locks_in_grace() && !(cstate->save_fh.fh_export->ex_flags
600 & NFSEXP_NOSUBTREECHECK)) 600 & NFSEXP_NOSUBTREECHECK))
601 return nfserr_grace; 601 return nfserr_grace;
602 status = nfsd_rename(rqstp, &cstate->save_fh, rename->rn_sname, 602 status = nfsd_rename(rqstp, &cstate->save_fh, rename->rn_sname,
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 1578d7a2667e..0cc7ff5d5ab5 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -61,7 +61,6 @@
61static time_t lease_time = 90; /* default lease time */ 61static time_t lease_time = 90; /* default lease time */
62static time_t user_lease_time = 90; 62static time_t user_lease_time = 90;
63static time_t boot_time; 63static time_t boot_time;
64static int in_grace = 1;
65static u32 current_ownerid = 1; 64static u32 current_ownerid = 1;
66static u32 current_fileid = 1; 65static u32 current_fileid = 1;
67static u32 current_delegid = 1; 66static u32 current_delegid = 1;
@@ -1640,7 +1639,7 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_sta
1640 case NFS4_OPEN_CLAIM_NULL: 1639 case NFS4_OPEN_CLAIM_NULL:
1641 /* Let's not give out any delegations till everyone's 1640 /* Let's not give out any delegations till everyone's
1642 * had the chance to reclaim theirs.... */ 1641 * had the chance to reclaim theirs.... */
1643 if (nfs4_in_grace()) 1642 if (locks_in_grace())
1644 goto out; 1643 goto out;
1645 if (!atomic_read(&cb->cb_set) || !sop->so_confirmed) 1644 if (!atomic_read(&cb->cb_set) || !sop->so_confirmed)
1646 goto out; 1645 goto out;
@@ -1816,12 +1815,15 @@ out:
1816 return status; 1815 return status;
1817} 1816}
1818 1817
1818struct lock_manager nfsd4_manager = {
1819};
1820
1819static void 1821static void
1820end_grace(void) 1822nfsd4_end_grace(void)
1821{ 1823{
1822 dprintk("NFSD: end of grace period\n"); 1824 dprintk("NFSD: end of grace period\n");
1823 nfsd4_recdir_purge_old(); 1825 nfsd4_recdir_purge_old();
1824 in_grace = 0; 1826 locks_end_grace(&nfsd4_manager);
1825} 1827}
1826 1828
1827static time_t 1829static time_t
@@ -1838,8 +1840,8 @@ nfs4_laundromat(void)
1838 nfs4_lock_state(); 1840 nfs4_lock_state();
1839 1841
1840 dprintk("NFSD: laundromat service - starting\n"); 1842 dprintk("NFSD: laundromat service - starting\n");
1841 if (in_grace) 1843 if (locks_in_grace())
1842 end_grace(); 1844 nfsd4_end_grace();
1843 list_for_each_safe(pos, next, &client_lru) { 1845 list_for_each_safe(pos, next, &client_lru) {
1844 clp = list_entry(pos, struct nfs4_client, cl_lru); 1846 clp = list_entry(pos, struct nfs4_client, cl_lru);
1845 if (time_after((unsigned long)clp->cl_time, (unsigned long)cutoff)) { 1847 if (time_after((unsigned long)clp->cl_time, (unsigned long)cutoff)) {
@@ -1974,7 +1976,7 @@ check_special_stateids(svc_fh *current_fh, stateid_t *stateid, int flags)
1974 return nfserr_bad_stateid; 1976 return nfserr_bad_stateid;
1975 else if (ONE_STATEID(stateid) && (flags & RD_STATE)) 1977 else if (ONE_STATEID(stateid) && (flags & RD_STATE))
1976 return nfs_ok; 1978 return nfs_ok;
1977 else if (nfs4_in_grace()) { 1979 else if (locks_in_grace()) {
1978 /* Answer in remaining cases depends on existance of 1980 /* Answer in remaining cases depends on existance of
1979 * conflicting state; so we must wait out the grace period. */ 1981 * conflicting state; so we must wait out the grace period. */
1980 return nfserr_grace; 1982 return nfserr_grace;
@@ -1993,7 +1995,7 @@ check_special_stateids(svc_fh *current_fh, stateid_t *stateid, int flags)
1993static inline int 1995static inline int
1994io_during_grace_disallowed(struct inode *inode, int flags) 1996io_during_grace_disallowed(struct inode *inode, int flags)
1995{ 1997{
1996 return nfs4_in_grace() && (flags & (RD_STATE | WR_STATE)) 1998 return locks_in_grace() && (flags & (RD_STATE | WR_STATE))
1997 && mandatory_lock(inode); 1999 && mandatory_lock(inode);
1998} 2000}
1999 2001
@@ -2693,10 +2695,10 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
2693 filp = lock_stp->st_vfs_file; 2695 filp = lock_stp->st_vfs_file;
2694 2696
2695 status = nfserr_grace; 2697 status = nfserr_grace;
2696 if (nfs4_in_grace() && !lock->lk_reclaim) 2698 if (locks_in_grace() && !lock->lk_reclaim)
2697 goto out; 2699 goto out;
2698 status = nfserr_no_grace; 2700 status = nfserr_no_grace;
2699 if (!nfs4_in_grace() && lock->lk_reclaim) 2701 if (!locks_in_grace() && lock->lk_reclaim)
2700 goto out; 2702 goto out;
2701 2703
2702 locks_init_lock(&file_lock); 2704 locks_init_lock(&file_lock);
@@ -2779,7 +2781,7 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
2779 int error; 2781 int error;
2780 __be32 status; 2782 __be32 status;
2781 2783
2782 if (nfs4_in_grace()) 2784 if (locks_in_grace())
2783 return nfserr_grace; 2785 return nfserr_grace;
2784 2786
2785 if (check_lock_length(lockt->lt_offset, lockt->lt_length)) 2787 if (check_lock_length(lockt->lt_offset, lockt->lt_length))
@@ -3192,9 +3194,9 @@ __nfs4_state_start(void)
3192 unsigned long grace_time; 3194 unsigned long grace_time;
3193 3195
3194 boot_time = get_seconds(); 3196 boot_time = get_seconds();
3195 grace_time = get_nfs_grace_period(); 3197 grace_time = get_nfs4_grace_period();
3196 lease_time = user_lease_time; 3198 lease_time = user_lease_time;
3197 in_grace = 1; 3199 locks_start_grace(&nfsd4_manager);
3198 printk(KERN_INFO "NFSD: starting %ld-second grace period\n", 3200 printk(KERN_INFO "NFSD: starting %ld-second grace period\n",
3199 grace_time/HZ); 3201 grace_time/HZ);
3200 laundry_wq = create_singlethread_workqueue("nfsd4"); 3202 laundry_wq = create_singlethread_workqueue("nfsd4");
@@ -3213,12 +3215,6 @@ nfs4_state_start(void)
3213 return; 3215 return;
3214} 3216}
3215 3217
3216int
3217nfs4_in_grace(void)
3218{
3219 return in_grace;
3220}
3221
3222time_t 3218time_t
3223nfs4_lease_time(void) 3219nfs4_lease_time(void)
3224{ 3220{
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 14ba4d9b2859..afcdf4b76843 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -413,6 +413,18 @@ out_nfserr:
413} 413}
414 414
415static __be32 415static __be32
416nfsd4_decode_stateid(struct nfsd4_compoundargs *argp, stateid_t *sid)
417{
418 DECODE_HEAD;
419
420 READ_BUF(sizeof(stateid_t));
421 READ32(sid->si_generation);
422 COPYMEM(&sid->si_opaque, sizeof(stateid_opaque_t));
423
424 DECODE_TAIL;
425}
426
427static __be32
416nfsd4_decode_access(struct nfsd4_compoundargs *argp, struct nfsd4_access *access) 428nfsd4_decode_access(struct nfsd4_compoundargs *argp, struct nfsd4_access *access)
417{ 429{
418 DECODE_HEAD; 430 DECODE_HEAD;
@@ -429,10 +441,9 @@ nfsd4_decode_close(struct nfsd4_compoundargs *argp, struct nfsd4_close *close)
429 DECODE_HEAD; 441 DECODE_HEAD;
430 442
431 close->cl_stateowner = NULL; 443 close->cl_stateowner = NULL;
432 READ_BUF(4 + sizeof(stateid_t)); 444 READ_BUF(4);
433 READ32(close->cl_seqid); 445 READ32(close->cl_seqid);
434 READ32(close->cl_stateid.si_generation); 446 return nfsd4_decode_stateid(argp, &close->cl_stateid);
435 COPYMEM(&close->cl_stateid.si_opaque, sizeof(stateid_opaque_t));
436 447
437 DECODE_TAIL; 448 DECODE_TAIL;
438} 449}
@@ -493,13 +504,7 @@ nfsd4_decode_create(struct nfsd4_compoundargs *argp, struct nfsd4_create *create
493static inline __be32 504static inline __be32
494nfsd4_decode_delegreturn(struct nfsd4_compoundargs *argp, struct nfsd4_delegreturn *dr) 505nfsd4_decode_delegreturn(struct nfsd4_compoundargs *argp, struct nfsd4_delegreturn *dr)
495{ 506{
496 DECODE_HEAD; 507 return nfsd4_decode_stateid(argp, &dr->dr_stateid);
497
498 READ_BUF(sizeof(stateid_t));
499 READ32(dr->dr_stateid.si_generation);
500 COPYMEM(&dr->dr_stateid.si_opaque, sizeof(stateid_opaque_t));
501
502 DECODE_TAIL;
503} 508}
504 509
505static inline __be32 510static inline __be32
@@ -542,20 +547,22 @@ nfsd4_decode_lock(struct nfsd4_compoundargs *argp, struct nfsd4_lock *lock)
542 READ32(lock->lk_is_new); 547 READ32(lock->lk_is_new);
543 548
544 if (lock->lk_is_new) { 549 if (lock->lk_is_new) {
545 READ_BUF(36); 550 READ_BUF(4);
546 READ32(lock->lk_new_open_seqid); 551 READ32(lock->lk_new_open_seqid);
547 READ32(lock->lk_new_open_stateid.si_generation); 552 status = nfsd4_decode_stateid(argp, &lock->lk_new_open_stateid);
548 553 if (status)
549 COPYMEM(&lock->lk_new_open_stateid.si_opaque, sizeof(stateid_opaque_t)); 554 return status;
555 READ_BUF(8 + sizeof(clientid_t));
550 READ32(lock->lk_new_lock_seqid); 556 READ32(lock->lk_new_lock_seqid);
551 COPYMEM(&lock->lk_new_clientid, sizeof(clientid_t)); 557 COPYMEM(&lock->lk_new_clientid, sizeof(clientid_t));
552 READ32(lock->lk_new_owner.len); 558 READ32(lock->lk_new_owner.len);
553 READ_BUF(lock->lk_new_owner.len); 559 READ_BUF(lock->lk_new_owner.len);
554 READMEM(lock->lk_new_owner.data, lock->lk_new_owner.len); 560 READMEM(lock->lk_new_owner.data, lock->lk_new_owner.len);
555 } else { 561 } else {
556 READ_BUF(20); 562 status = nfsd4_decode_stateid(argp, &lock->lk_old_lock_stateid);
557 READ32(lock->lk_old_lock_stateid.si_generation); 563 if (status)
558 COPYMEM(&lock->lk_old_lock_stateid.si_opaque, sizeof(stateid_opaque_t)); 564 return status;
565 READ_BUF(4);
559 READ32(lock->lk_old_lock_seqid); 566 READ32(lock->lk_old_lock_seqid);
560 } 567 }
561 568
@@ -587,13 +594,15 @@ nfsd4_decode_locku(struct nfsd4_compoundargs *argp, struct nfsd4_locku *locku)
587 DECODE_HEAD; 594 DECODE_HEAD;
588 595
589 locku->lu_stateowner = NULL; 596 locku->lu_stateowner = NULL;
590 READ_BUF(24 + sizeof(stateid_t)); 597 READ_BUF(8);
591 READ32(locku->lu_type); 598 READ32(locku->lu_type);
592 if ((locku->lu_type < NFS4_READ_LT) || (locku->lu_type > NFS4_WRITEW_LT)) 599 if ((locku->lu_type < NFS4_READ_LT) || (locku->lu_type > NFS4_WRITEW_LT))
593 goto xdr_error; 600 goto xdr_error;
594 READ32(locku->lu_seqid); 601 READ32(locku->lu_seqid);
595 READ32(locku->lu_stateid.si_generation); 602 status = nfsd4_decode_stateid(argp, &locku->lu_stateid);
596 COPYMEM(&locku->lu_stateid.si_opaque, sizeof(stateid_opaque_t)); 603 if (status)
604 return status;
605 READ_BUF(16);
597 READ64(locku->lu_offset); 606 READ64(locku->lu_offset);
598 READ64(locku->lu_length); 607 READ64(locku->lu_length);
599 608
@@ -678,8 +687,10 @@ nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
678 READ32(open->op_delegate_type); 687 READ32(open->op_delegate_type);
679 break; 688 break;
680 case NFS4_OPEN_CLAIM_DELEGATE_CUR: 689 case NFS4_OPEN_CLAIM_DELEGATE_CUR:
681 READ_BUF(sizeof(stateid_t) + 4); 690 status = nfsd4_decode_stateid(argp, &open->op_delegate_stateid);
682 COPYMEM(&open->op_delegate_stateid, sizeof(stateid_t)); 691 if (status)
692 return status;
693 READ_BUF(4);
683 READ32(open->op_fname.len); 694 READ32(open->op_fname.len);
684 READ_BUF(open->op_fname.len); 695 READ_BUF(open->op_fname.len);
685 SAVEMEM(open->op_fname.data, open->op_fname.len); 696 SAVEMEM(open->op_fname.data, open->op_fname.len);
@@ -699,9 +710,10 @@ nfsd4_decode_open_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_open_con
699 DECODE_HEAD; 710 DECODE_HEAD;
700 711
701 open_conf->oc_stateowner = NULL; 712 open_conf->oc_stateowner = NULL;
702 READ_BUF(4 + sizeof(stateid_t)); 713 status = nfsd4_decode_stateid(argp, &open_conf->oc_req_stateid);
703 READ32(open_conf->oc_req_stateid.si_generation); 714 if (status)
704 COPYMEM(&open_conf->oc_req_stateid.si_opaque, sizeof(stateid_opaque_t)); 715 return status;
716 READ_BUF(4);
705 READ32(open_conf->oc_seqid); 717 READ32(open_conf->oc_seqid);
706 718
707 DECODE_TAIL; 719 DECODE_TAIL;
@@ -713,9 +725,10 @@ nfsd4_decode_open_downgrade(struct nfsd4_compoundargs *argp, struct nfsd4_open_d
713 DECODE_HEAD; 725 DECODE_HEAD;
714 726
715 open_down->od_stateowner = NULL; 727 open_down->od_stateowner = NULL;
716 READ_BUF(12 + sizeof(stateid_t)); 728 status = nfsd4_decode_stateid(argp, &open_down->od_stateid);
717 READ32(open_down->od_stateid.si_generation); 729 if (status)
718 COPYMEM(&open_down->od_stateid.si_opaque, sizeof(stateid_opaque_t)); 730 return status;
731 READ_BUF(12);
719 READ32(open_down->od_seqid); 732 READ32(open_down->od_seqid);
720 READ32(open_down->od_share_access); 733 READ32(open_down->od_share_access);
721 READ32(open_down->od_share_deny); 734 READ32(open_down->od_share_deny);
@@ -743,9 +756,10 @@ nfsd4_decode_read(struct nfsd4_compoundargs *argp, struct nfsd4_read *read)
743{ 756{
744 DECODE_HEAD; 757 DECODE_HEAD;
745 758
746 READ_BUF(sizeof(stateid_t) + 12); 759 status = nfsd4_decode_stateid(argp, &read->rd_stateid);
747 READ32(read->rd_stateid.si_generation); 760 if (status)
748 COPYMEM(&read->rd_stateid.si_opaque, sizeof(stateid_opaque_t)); 761 return status;
762 READ_BUF(12);
749 READ64(read->rd_offset); 763 READ64(read->rd_offset);
750 READ32(read->rd_length); 764 READ32(read->rd_length);
751 765
@@ -834,15 +848,13 @@ nfsd4_decode_secinfo(struct nfsd4_compoundargs *argp,
834static __be32 848static __be32
835nfsd4_decode_setattr(struct nfsd4_compoundargs *argp, struct nfsd4_setattr *setattr) 849nfsd4_decode_setattr(struct nfsd4_compoundargs *argp, struct nfsd4_setattr *setattr)
836{ 850{
837 DECODE_HEAD; 851 __be32 status;
838
839 READ_BUF(sizeof(stateid_t));
840 READ32(setattr->sa_stateid.si_generation);
841 COPYMEM(&setattr->sa_stateid.si_opaque, sizeof(stateid_opaque_t));
842 if ((status = nfsd4_decode_fattr(argp, setattr->sa_bmval, &setattr->sa_iattr, &setattr->sa_acl)))
843 goto out;
844 852
845 DECODE_TAIL; 853 status = nfsd4_decode_stateid(argp, &setattr->sa_stateid);
854 if (status)
855 return status;
856 return nfsd4_decode_fattr(argp, setattr->sa_bmval,
857 &setattr->sa_iattr, &setattr->sa_acl);
846} 858}
847 859
848static __be32 860static __be32
@@ -927,9 +939,10 @@ nfsd4_decode_write(struct nfsd4_compoundargs *argp, struct nfsd4_write *write)
927 int len; 939 int len;
928 DECODE_HEAD; 940 DECODE_HEAD;
929 941
930 READ_BUF(sizeof(stateid_opaque_t) + 20); 942 status = nfsd4_decode_stateid(argp, &write->wr_stateid);
931 READ32(write->wr_stateid.si_generation); 943 if (status)
932 COPYMEM(&write->wr_stateid.si_opaque, sizeof(stateid_opaque_t)); 944 return status;
945 READ_BUF(16);
933 READ64(write->wr_offset); 946 READ64(write->wr_offset);
934 READ32(write->wr_stable_how); 947 READ32(write->wr_stable_how);
935 if (write->wr_stable_how > 2) 948 if (write->wr_stable_how > 2)
@@ -1183,7 +1196,6 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
1183 * Header routine to setup seqid operation replay cache 1196 * Header routine to setup seqid operation replay cache
1184 */ 1197 */
1185#define ENCODE_SEQID_OP_HEAD \ 1198#define ENCODE_SEQID_OP_HEAD \
1186 __be32 *p; \
1187 __be32 *save; \ 1199 __be32 *save; \
1188 \ 1200 \
1189 save = resp->p; 1201 save = resp->p;
@@ -1950,6 +1962,17 @@ fail:
1950 return -EINVAL; 1962 return -EINVAL;
1951} 1963}
1952 1964
1965static void
1966nfsd4_encode_stateid(struct nfsd4_compoundres *resp, stateid_t *sid)
1967{
1968 ENCODE_HEAD;
1969
1970 RESERVE_SPACE(sizeof(stateid_t));
1971 WRITE32(sid->si_generation);
1972 WRITEMEM(&sid->si_opaque, sizeof(stateid_opaque_t));
1973 ADJUST_ARGS();
1974}
1975
1953static __be32 1976static __be32
1954nfsd4_encode_access(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_access *access) 1977nfsd4_encode_access(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_access *access)
1955{ 1978{
@@ -1969,12 +1992,9 @@ nfsd4_encode_close(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_c
1969{ 1992{
1970 ENCODE_SEQID_OP_HEAD; 1993 ENCODE_SEQID_OP_HEAD;
1971 1994
1972 if (!nfserr) { 1995 if (!nfserr)
1973 RESERVE_SPACE(sizeof(stateid_t)); 1996 nfsd4_encode_stateid(resp, &close->cl_stateid);
1974 WRITE32(close->cl_stateid.si_generation); 1997
1975 WRITEMEM(&close->cl_stateid.si_opaque, sizeof(stateid_opaque_t));
1976 ADJUST_ARGS();
1977 }
1978 ENCODE_SEQID_OP_TAIL(close->cl_stateowner); 1998 ENCODE_SEQID_OP_TAIL(close->cl_stateowner);
1979 return nfserr; 1999 return nfserr;
1980} 2000}
@@ -2074,12 +2094,9 @@ nfsd4_encode_lock(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lo
2074{ 2094{
2075 ENCODE_SEQID_OP_HEAD; 2095 ENCODE_SEQID_OP_HEAD;
2076 2096
2077 if (!nfserr) { 2097 if (!nfserr)
2078 RESERVE_SPACE(4 + sizeof(stateid_t)); 2098 nfsd4_encode_stateid(resp, &lock->lk_resp_stateid);
2079 WRITE32(lock->lk_resp_stateid.si_generation); 2099 else if (nfserr == nfserr_denied)
2080 WRITEMEM(&lock->lk_resp_stateid.si_opaque, sizeof(stateid_opaque_t));
2081 ADJUST_ARGS();
2082 } else if (nfserr == nfserr_denied)
2083 nfsd4_encode_lock_denied(resp, &lock->lk_denied); 2100 nfsd4_encode_lock_denied(resp, &lock->lk_denied);
2084 2101
2085 ENCODE_SEQID_OP_TAIL(lock->lk_replay_owner); 2102 ENCODE_SEQID_OP_TAIL(lock->lk_replay_owner);
@@ -2099,13 +2116,9 @@ nfsd4_encode_locku(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_l
2099{ 2116{
2100 ENCODE_SEQID_OP_HEAD; 2117 ENCODE_SEQID_OP_HEAD;
2101 2118
2102 if (!nfserr) { 2119 if (!nfserr)
2103 RESERVE_SPACE(sizeof(stateid_t)); 2120 nfsd4_encode_stateid(resp, &locku->lu_stateid);
2104 WRITE32(locku->lu_stateid.si_generation); 2121
2105 WRITEMEM(&locku->lu_stateid.si_opaque, sizeof(stateid_opaque_t));
2106 ADJUST_ARGS();
2107 }
2108
2109 ENCODE_SEQID_OP_TAIL(locku->lu_stateowner); 2122 ENCODE_SEQID_OP_TAIL(locku->lu_stateowner);
2110 return nfserr; 2123 return nfserr;
2111} 2124}
@@ -2128,14 +2141,14 @@ nfsd4_encode_link(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_li
2128static __be32 2141static __be32
2129nfsd4_encode_open(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open *open) 2142nfsd4_encode_open(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open *open)
2130{ 2143{
2144 ENCODE_HEAD;
2131 ENCODE_SEQID_OP_HEAD; 2145 ENCODE_SEQID_OP_HEAD;
2132 2146
2133 if (nfserr) 2147 if (nfserr)
2134 goto out; 2148 goto out;
2135 2149
2136 RESERVE_SPACE(36 + sizeof(stateid_t)); 2150 nfsd4_encode_stateid(resp, &open->op_stateid);
2137 WRITE32(open->op_stateid.si_generation); 2151 RESERVE_SPACE(40);
2138 WRITEMEM(&open->op_stateid.si_opaque, sizeof(stateid_opaque_t));
2139 WRITECINFO(open->op_cinfo); 2152 WRITECINFO(open->op_cinfo);
2140 WRITE32(open->op_rflags); 2153 WRITE32(open->op_rflags);
2141 WRITE32(2); 2154 WRITE32(2);
@@ -2148,8 +2161,8 @@ nfsd4_encode_open(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_op
2148 case NFS4_OPEN_DELEGATE_NONE: 2161 case NFS4_OPEN_DELEGATE_NONE:
2149 break; 2162 break;
2150 case NFS4_OPEN_DELEGATE_READ: 2163 case NFS4_OPEN_DELEGATE_READ:
2151 RESERVE_SPACE(20 + sizeof(stateid_t)); 2164 nfsd4_encode_stateid(resp, &open->op_delegate_stateid);
2152 WRITEMEM(&open->op_delegate_stateid, sizeof(stateid_t)); 2165 RESERVE_SPACE(20);
2153 WRITE32(open->op_recall); 2166 WRITE32(open->op_recall);
2154 2167
2155 /* 2168 /*
@@ -2162,8 +2175,8 @@ nfsd4_encode_open(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_op
2162 ADJUST_ARGS(); 2175 ADJUST_ARGS();
2163 break; 2176 break;
2164 case NFS4_OPEN_DELEGATE_WRITE: 2177 case NFS4_OPEN_DELEGATE_WRITE:
2165 RESERVE_SPACE(32 + sizeof(stateid_t)); 2178 nfsd4_encode_stateid(resp, &open->op_delegate_stateid);
2166 WRITEMEM(&open->op_delegate_stateid, sizeof(stateid_t)); 2179 RESERVE_SPACE(32);
2167 WRITE32(0); 2180 WRITE32(0);
2168 2181
2169 /* 2182 /*
@@ -2195,13 +2208,9 @@ static __be32
2195nfsd4_encode_open_confirm(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open_confirm *oc) 2208nfsd4_encode_open_confirm(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open_confirm *oc)
2196{ 2209{
2197 ENCODE_SEQID_OP_HEAD; 2210 ENCODE_SEQID_OP_HEAD;
2198 2211
2199 if (!nfserr) { 2212 if (!nfserr)
2200 RESERVE_SPACE(sizeof(stateid_t)); 2213 nfsd4_encode_stateid(resp, &oc->oc_resp_stateid);
2201 WRITE32(oc->oc_resp_stateid.si_generation);
2202 WRITEMEM(&oc->oc_resp_stateid.si_opaque, sizeof(stateid_opaque_t));
2203 ADJUST_ARGS();
2204 }
2205 2214
2206 ENCODE_SEQID_OP_TAIL(oc->oc_stateowner); 2215 ENCODE_SEQID_OP_TAIL(oc->oc_stateowner);
2207 return nfserr; 2216 return nfserr;
@@ -2211,13 +2220,9 @@ static __be32
2211nfsd4_encode_open_downgrade(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open_downgrade *od) 2220nfsd4_encode_open_downgrade(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open_downgrade *od)
2212{ 2221{
2213 ENCODE_SEQID_OP_HEAD; 2222 ENCODE_SEQID_OP_HEAD;
2214 2223
2215 if (!nfserr) { 2224 if (!nfserr)
2216 RESERVE_SPACE(sizeof(stateid_t)); 2225 nfsd4_encode_stateid(resp, &od->od_stateid);
2217 WRITE32(od->od_stateid.si_generation);
2218 WRITEMEM(&od->od_stateid.si_opaque, sizeof(stateid_opaque_t));
2219 ADJUST_ARGS();
2220 }
2221 2226
2222 ENCODE_SEQID_OP_TAIL(od->od_stateowner); 2227 ENCODE_SEQID_OP_TAIL(od->od_stateowner);
2223 return nfserr; 2228 return nfserr;
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index c53e65f8f3a2..97543df58242 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -614,10 +614,9 @@ static ssize_t __write_ports(struct file *file, char *buf, size_t size)
614 return -EINVAL; 614 return -EINVAL;
615 err = nfsd_create_serv(); 615 err = nfsd_create_serv();
616 if (!err) { 616 if (!err) {
617 int proto = 0; 617 err = svc_addsock(nfsd_serv, fd, buf);
618 err = svc_addsock(nfsd_serv, fd, buf, &proto);
619 if (err >= 0) { 618 if (err >= 0) {
620 err = lockd_up(proto); 619 err = lockd_up();
621 if (err < 0) 620 if (err < 0)
622 svc_sock_names(buf+strlen(buf)+1, nfsd_serv, buf); 621 svc_sock_names(buf+strlen(buf)+1, nfsd_serv, buf);
623 } 622 }
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c
index ea37c96f0445..cd25d91895a1 100644
--- a/fs/nfsd/nfsfh.c
+++ b/fs/nfsd/nfsfh.c
@@ -302,17 +302,27 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
302 if (error) 302 if (error)
303 goto out; 303 goto out;
304 304
305 if (!(access & NFSD_MAY_LOCK)) { 305 /*
306 /* 306 * pseudoflavor restrictions are not enforced on NLM,
307 * pseudoflavor restrictions are not enforced on NLM, 307 * which clients virtually always use auth_sys for,
308 * which clients virtually always use auth_sys for, 308 * even while using RPCSEC_GSS for NFS.
309 * even while using RPCSEC_GSS for NFS. 309 */
310 */ 310 if (access & NFSD_MAY_LOCK)
311 error = check_nfsd_access(exp, rqstp); 311 goto skip_pseudoflavor_check;
312 if (error) 312 /*
313 goto out; 313 * Clients may expect to be able to use auth_sys during mount,
314 } 314 * even if they use gss for everything else; see section 2.3.2
315 * of rfc 2623.
316 */
317 if (access & NFSD_MAY_BYPASS_GSS_ON_ROOT
318 && exp->ex_path.dentry == dentry)
319 goto skip_pseudoflavor_check;
320
321 error = check_nfsd_access(exp, rqstp);
322 if (error)
323 goto out;
315 324
325skip_pseudoflavor_check:
316 /* Finally, check access permissions. */ 326 /* Finally, check access permissions. */
317 error = nfsd_permission(rqstp, exp, dentry, access); 327 error = nfsd_permission(rqstp, exp, dentry, access);
318 328
diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c
index 0766f95d236a..5cffeca7acef 100644
--- a/fs/nfsd/nfsproc.c
+++ b/fs/nfsd/nfsproc.c
@@ -65,7 +65,8 @@ nfsd_proc_getattr(struct svc_rqst *rqstp, struct nfsd_fhandle *argp,
65 dprintk("nfsd: GETATTR %s\n", SVCFH_fmt(&argp->fh)); 65 dprintk("nfsd: GETATTR %s\n", SVCFH_fmt(&argp->fh));
66 66
67 fh_copy(&resp->fh, &argp->fh); 67 fh_copy(&resp->fh, &argp->fh);
68 nfserr = fh_verify(rqstp, &resp->fh, 0, NFSD_MAY_NOP); 68 nfserr = fh_verify(rqstp, &resp->fh, 0,
69 NFSD_MAY_NOP | NFSD_MAY_BYPASS_GSS_ON_ROOT);
69 return nfsd_return_attrs(nfserr, resp); 70 return nfsd_return_attrs(nfserr, resp);
70} 71}
71 72
@@ -521,7 +522,8 @@ nfsd_proc_statfs(struct svc_rqst * rqstp, struct nfsd_fhandle *argp,
521 522
522 dprintk("nfsd: STATFS %s\n", SVCFH_fmt(&argp->fh)); 523 dprintk("nfsd: STATFS %s\n", SVCFH_fmt(&argp->fh));
523 524
524 nfserr = nfsd_statfs(rqstp, &argp->fh, &resp->stats); 525 nfserr = nfsd_statfs(rqstp, &argp->fh, &resp->stats,
526 NFSD_MAY_BYPASS_GSS_ON_ROOT);
525 fh_put(&argp->fh); 527 fh_put(&argp->fh);
526 return nfserr; 528 return nfserr;
527} 529}
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index 80292ff5e924..59eeb46f82c5 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -229,6 +229,7 @@ int nfsd_create_serv(void)
229 229
230 atomic_set(&nfsd_busy, 0); 230 atomic_set(&nfsd_busy, 0);
231 nfsd_serv = svc_create_pooled(&nfsd_program, nfsd_max_blksize, 231 nfsd_serv = svc_create_pooled(&nfsd_program, nfsd_max_blksize,
232 AF_INET,
232 nfsd_last_thread, nfsd, THIS_MODULE); 233 nfsd_last_thread, nfsd, THIS_MODULE);
233 if (nfsd_serv == NULL) 234 if (nfsd_serv == NULL)
234 err = -ENOMEM; 235 err = -ENOMEM;
@@ -243,25 +244,20 @@ static int nfsd_init_socks(int port)
243 if (!list_empty(&nfsd_serv->sv_permsocks)) 244 if (!list_empty(&nfsd_serv->sv_permsocks))
244 return 0; 245 return 0;
245 246
246 error = lockd_up(IPPROTO_UDP); 247 error = svc_create_xprt(nfsd_serv, "udp", port,
247 if (error >= 0) {
248 error = svc_create_xprt(nfsd_serv, "udp", port,
249 SVC_SOCK_DEFAULTS); 248 SVC_SOCK_DEFAULTS);
250 if (error < 0)
251 lockd_down();
252 }
253 if (error < 0) 249 if (error < 0)
254 return error; 250 return error;
255 251
256 error = lockd_up(IPPROTO_TCP); 252 error = svc_create_xprt(nfsd_serv, "tcp", port,
257 if (error >= 0) {
258 error = svc_create_xprt(nfsd_serv, "tcp", port,
259 SVC_SOCK_DEFAULTS); 253 SVC_SOCK_DEFAULTS);
260 if (error < 0)
261 lockd_down();
262 }
263 if (error < 0) 254 if (error < 0)
264 return error; 255 return error;
256
257 error = lockd_up();
258 if (error < 0)
259 return error;
260
265 return 0; 261 return 0;
266} 262}
267 263
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 18060bed5267..aa1d0d6489a1 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -83,7 +83,6 @@ struct raparm_hbucket {
83 spinlock_t pb_lock; 83 spinlock_t pb_lock;
84} ____cacheline_aligned_in_smp; 84} ____cacheline_aligned_in_smp;
85 85
86static struct raparms * raparml;
87#define RAPARM_HASH_BITS 4 86#define RAPARM_HASH_BITS 4
88#define RAPARM_HASH_SIZE (1<<RAPARM_HASH_BITS) 87#define RAPARM_HASH_SIZE (1<<RAPARM_HASH_BITS)
89#define RAPARM_HASH_MASK (RAPARM_HASH_SIZE-1) 88#define RAPARM_HASH_MASK (RAPARM_HASH_SIZE-1)
@@ -1866,9 +1865,9 @@ out:
1866 * N.B. After this call fhp needs an fh_put 1865 * N.B. After this call fhp needs an fh_put
1867 */ 1866 */
1868__be32 1867__be32
1869nfsd_statfs(struct svc_rqst *rqstp, struct svc_fh *fhp, struct kstatfs *stat) 1868nfsd_statfs(struct svc_rqst *rqstp, struct svc_fh *fhp, struct kstatfs *stat, int access)
1870{ 1869{
1871 __be32 err = fh_verify(rqstp, fhp, 0, NFSD_MAY_NOP); 1870 __be32 err = fh_verify(rqstp, fhp, 0, NFSD_MAY_NOP | access);
1872 if (!err && vfs_statfs(fhp->fh_dentry,stat)) 1871 if (!err && vfs_statfs(fhp->fh_dentry,stat))
1873 err = nfserr_io; 1872 err = nfserr_io;
1874 return err; 1873 return err;
@@ -1966,11 +1965,20 @@ nfsd_permission(struct svc_rqst *rqstp, struct svc_export *exp,
1966void 1965void
1967nfsd_racache_shutdown(void) 1966nfsd_racache_shutdown(void)
1968{ 1967{
1969 if (!raparml) 1968 struct raparms *raparm, *last_raparm;
1970 return; 1969 unsigned int i;
1970
1971 dprintk("nfsd: freeing readahead buffers.\n"); 1971 dprintk("nfsd: freeing readahead buffers.\n");
1972 kfree(raparml); 1972
1973 raparml = NULL; 1973 for (i = 0; i < RAPARM_HASH_SIZE; i++) {
1974 raparm = raparm_hash[i].pb_head;
1975 while(raparm) {
1976 last_raparm = raparm;
1977 raparm = raparm->p_next;
1978 kfree(last_raparm);
1979 }
1980 raparm_hash[i].pb_head = NULL;
1981 }
1974} 1982}
1975/* 1983/*
1976 * Initialize readahead param cache 1984 * Initialize readahead param cache
@@ -1981,35 +1989,38 @@ nfsd_racache_init(int cache_size)
1981 int i; 1989 int i;
1982 int j = 0; 1990 int j = 0;
1983 int nperbucket; 1991 int nperbucket;
1992 struct raparms **raparm = NULL;
1984 1993
1985 1994
1986 if (raparml) 1995 if (raparm_hash[0].pb_head)
1987 return 0; 1996 return 0;
1988 if (cache_size < 2*RAPARM_HASH_SIZE) 1997 nperbucket = DIV_ROUND_UP(cache_size, RAPARM_HASH_SIZE);
1989 cache_size = 2*RAPARM_HASH_SIZE; 1998 if (nperbucket < 2)
1990 raparml = kcalloc(cache_size, sizeof(struct raparms), GFP_KERNEL); 1999 nperbucket = 2;
1991 2000 cache_size = nperbucket * RAPARM_HASH_SIZE;
1992 if (!raparml) {
1993 printk(KERN_WARNING
1994 "nfsd: Could not allocate memory read-ahead cache.\n");
1995 return -ENOMEM;
1996 }
1997 2001
1998 dprintk("nfsd: allocating %d readahead buffers.\n", cache_size); 2002 dprintk("nfsd: allocating %d readahead buffers.\n", cache_size);
1999 for (i = 0 ; i < RAPARM_HASH_SIZE ; i++) { 2003
2000 raparm_hash[i].pb_head = NULL; 2004 for (i = 0; i < RAPARM_HASH_SIZE; i++) {
2001 spin_lock_init(&raparm_hash[i].pb_lock); 2005 spin_lock_init(&raparm_hash[i].pb_lock);
2002 } 2006
2003 nperbucket = DIV_ROUND_UP(cache_size, RAPARM_HASH_SIZE); 2007 raparm = &raparm_hash[i].pb_head;
2004 for (i = 0; i < cache_size - 1; i++) { 2008 for (j = 0; j < nperbucket; j++) {
2005 if (i % nperbucket == 0) 2009 *raparm = kzalloc(sizeof(struct raparms), GFP_KERNEL);
2006 raparm_hash[j++].pb_head = raparml + i; 2010 if (!*raparm)
2007 if (i % nperbucket < nperbucket-1) 2011 goto out_nomem;
2008 raparml[i].p_next = raparml + i + 1; 2012 raparm = &(*raparm)->p_next;
2013 }
2014 *raparm = NULL;
2009 } 2015 }
2010 2016
2011 nfsdstats.ra_size = cache_size; 2017 nfsdstats.ra_size = cache_size;
2012 return 0; 2018 return 0;
2019
2020out_nomem:
2021 dprintk("nfsd: kmalloc failed, freeing readahead buffers\n");
2022 nfsd_racache_shutdown();
2023 return -ENOMEM;
2013} 2024}
2014 2025
2015#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) 2026#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)