aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2006-10-21 11:46:04 -0400
committerDavid Woodhouse <dwmw2@infradead.org>2006-10-21 11:46:04 -0400
commit513b046c96cc2fbce730a3474f6f7ff0c4fdd05c (patch)
treee8006368b6f643067486f92405a404757807d6da /fs/nfsd
parent82810b7b6cc7a74c68881a13b0eb66c7a6370fcc (diff)
parentc7a3bd177f248d01ee18a01d22048c80e071c331 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'fs/nfsd')
-rw-r--r--fs/nfsd/export.c153
-rw-r--r--fs/nfsd/lockd.c16
-rw-r--r--fs/nfsd/nfs2acl.c37
-rw-r--r--fs/nfsd/nfs3acl.c23
-rw-r--r--fs/nfsd/nfs3proc.c108
-rw-r--r--fs/nfsd/nfs3xdr.c182
-rw-r--r--fs/nfsd/nfs4acl.c711
-rw-r--r--fs/nfsd/nfs4callback.c26
-rw-r--r--fs/nfsd/nfs4proc.c140
-rw-r--r--fs/nfsd/nfs4recover.c14
-rw-r--r--fs/nfsd/nfs4state.c119
-rw-r--r--fs/nfsd/nfs4xdr.c454
-rw-r--r--fs/nfsd/nfscache.c8
-rw-r--r--fs/nfsd/nfsctl.c49
-rw-r--r--fs/nfsd/nfsfh.c10
-rw-r--r--fs/nfsd/nfsproc.c91
-rw-r--r--fs/nfsd/nfssvc.c29
-rw-r--r--fs/nfsd/nfsxdr.c115
-rw-r--r--fs/nfsd/vfs.c381
19 files changed, 1491 insertions, 1175 deletions
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
index cfe141e5d759..f37df46d2eaa 100644
--- a/fs/nfsd/export.c
+++ b/fs/nfsd/export.c
@@ -319,12 +319,25 @@ svc_expkey_update(struct svc_expkey *new, struct svc_expkey *old)
319 319
320static struct cache_head *export_table[EXPORT_HASHMAX]; 320static struct cache_head *export_table[EXPORT_HASHMAX];
321 321
322static void nfsd4_fslocs_free(struct nfsd4_fs_locations *fsloc)
323{
324 int i;
325
326 for (i = 0; i < fsloc->locations_count; i++) {
327 kfree(fsloc->locations[i].path);
328 kfree(fsloc->locations[i].hosts);
329 }
330 kfree(fsloc->locations);
331}
332
322static void svc_export_put(struct kref *ref) 333static void svc_export_put(struct kref *ref)
323{ 334{
324 struct svc_export *exp = container_of(ref, struct svc_export, h.ref); 335 struct svc_export *exp = container_of(ref, struct svc_export, h.ref);
325 dput(exp->ex_dentry); 336 dput(exp->ex_dentry);
326 mntput(exp->ex_mnt); 337 mntput(exp->ex_mnt);
327 auth_domain_put(exp->ex_client); 338 auth_domain_put(exp->ex_client);
339 kfree(exp->ex_path);
340 nfsd4_fslocs_free(&exp->ex_fslocs);
328 kfree(exp); 341 kfree(exp);
329} 342}
330 343
@@ -386,6 +399,69 @@ static int check_export(struct inode *inode, int flags)
386 399
387} 400}
388 401
402#ifdef CONFIG_NFSD_V4
403
404static int
405fsloc_parse(char **mesg, char *buf, struct nfsd4_fs_locations *fsloc)
406{
407 int len;
408 int migrated, i, err;
409
410 len = qword_get(mesg, buf, PAGE_SIZE);
411 if (len != 5 || memcmp(buf, "fsloc", 5))
412 return 0;
413
414 /* listsize */
415 err = get_int(mesg, &fsloc->locations_count);
416 if (err)
417 return err;
418 if (fsloc->locations_count > MAX_FS_LOCATIONS)
419 return -EINVAL;
420 if (fsloc->locations_count == 0)
421 return 0;
422
423 fsloc->locations = kzalloc(fsloc->locations_count
424 * sizeof(struct nfsd4_fs_location), GFP_KERNEL);
425 if (!fsloc->locations)
426 return -ENOMEM;
427 for (i=0; i < fsloc->locations_count; i++) {
428 /* colon separated host list */
429 err = -EINVAL;
430 len = qword_get(mesg, buf, PAGE_SIZE);
431 if (len <= 0)
432 goto out_free_all;
433 err = -ENOMEM;
434 fsloc->locations[i].hosts = kstrdup(buf, GFP_KERNEL);
435 if (!fsloc->locations[i].hosts)
436 goto out_free_all;
437 err = -EINVAL;
438 /* slash separated path component list */
439 len = qword_get(mesg, buf, PAGE_SIZE);
440 if (len <= 0)
441 goto out_free_all;
442 err = -ENOMEM;
443 fsloc->locations[i].path = kstrdup(buf, GFP_KERNEL);
444 if (!fsloc->locations[i].path)
445 goto out_free_all;
446 }
447 /* migrated */
448 err = get_int(mesg, &migrated);
449 if (err)
450 goto out_free_all;
451 err = -EINVAL;
452 if (migrated < 0 || migrated > 1)
453 goto out_free_all;
454 fsloc->migrated = migrated;
455 return 0;
456out_free_all:
457 nfsd4_fslocs_free(fsloc);
458 return err;
459}
460
461#else /* CONFIG_NFSD_V4 */
462static inline int fsloc_parse(char **mesg, char *buf, struct nfsd4_fs_locations *fsloc) { return 0; }
463#endif
464
389static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen) 465static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
390{ 466{
391 /* client path expiry [flags anonuid anongid fsid] */ 467 /* client path expiry [flags anonuid anongid fsid] */
@@ -398,6 +474,7 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
398 int an_int; 474 int an_int;
399 475
400 nd.dentry = NULL; 476 nd.dentry = NULL;
477 exp.ex_path = NULL;
401 478
402 if (mesg[mlen-1] != '\n') 479 if (mesg[mlen-1] != '\n')
403 return -EINVAL; 480 return -EINVAL;
@@ -428,6 +505,10 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
428 exp.ex_client = dom; 505 exp.ex_client = dom;
429 exp.ex_mnt = nd.mnt; 506 exp.ex_mnt = nd.mnt;
430 exp.ex_dentry = nd.dentry; 507 exp.ex_dentry = nd.dentry;
508 exp.ex_path = kstrdup(buf, GFP_KERNEL);
509 err = -ENOMEM;
510 if (!exp.ex_path)
511 goto out;
431 512
432 /* expiry */ 513 /* expiry */
433 err = -EINVAL; 514 err = -EINVAL;
@@ -435,6 +516,11 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
435 if (exp.h.expiry_time == 0) 516 if (exp.h.expiry_time == 0)
436 goto out; 517 goto out;
437 518
519 /* fs locations */
520 exp.ex_fslocs.locations = NULL;
521 exp.ex_fslocs.locations_count = 0;
522 exp.ex_fslocs.migrated = 0;
523
438 /* flags */ 524 /* flags */
439 err = get_int(&mesg, &an_int); 525 err = get_int(&mesg, &an_int);
440 if (err == -ENOENT) 526 if (err == -ENOENT)
@@ -460,6 +546,10 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
460 546
461 err = check_export(nd.dentry->d_inode, exp.ex_flags); 547 err = check_export(nd.dentry->d_inode, exp.ex_flags);
462 if (err) goto out; 548 if (err) goto out;
549
550 err = fsloc_parse(&mesg, buf, &exp.ex_fslocs);
551 if (err)
552 goto out;
463 } 553 }
464 554
465 expp = svc_export_lookup(&exp); 555 expp = svc_export_lookup(&exp);
@@ -473,6 +563,7 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
473 else 563 else
474 exp_put(expp); 564 exp_put(expp);
475 out: 565 out:
566 kfree(exp.ex_path);
476 if (nd.dentry) 567 if (nd.dentry)
477 path_release(&nd); 568 path_release(&nd);
478 out_no_path: 569 out_no_path:
@@ -482,7 +573,8 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
482 return err; 573 return err;
483} 574}
484 575
485static void exp_flags(struct seq_file *m, int flag, int fsid, uid_t anonu, uid_t anong); 576static void exp_flags(struct seq_file *m, int flag, int fsid,
577 uid_t anonu, uid_t anong, struct nfsd4_fs_locations *fslocs);
486 578
487static int svc_export_show(struct seq_file *m, 579static int svc_export_show(struct seq_file *m,
488 struct cache_detail *cd, 580 struct cache_detail *cd,
@@ -501,8 +593,8 @@ static int svc_export_show(struct seq_file *m,
501 seq_putc(m, '('); 593 seq_putc(m, '(');
502 if (test_bit(CACHE_VALID, &h->flags) && 594 if (test_bit(CACHE_VALID, &h->flags) &&
503 !test_bit(CACHE_NEGATIVE, &h->flags)) 595 !test_bit(CACHE_NEGATIVE, &h->flags))
504 exp_flags(m, exp->ex_flags, exp->ex_fsid, 596 exp_flags(m, exp->ex_flags, exp->ex_fsid,
505 exp->ex_anon_uid, exp->ex_anon_gid); 597 exp->ex_anon_uid, exp->ex_anon_gid, &exp->ex_fslocs);
506 seq_puts(m, ")\n"); 598 seq_puts(m, ")\n");
507 return 0; 599 return 0;
508} 600}
@@ -524,6 +616,10 @@ static void svc_export_init(struct cache_head *cnew, struct cache_head *citem)
524 new->ex_client = item->ex_client; 616 new->ex_client = item->ex_client;
525 new->ex_dentry = dget(item->ex_dentry); 617 new->ex_dentry = dget(item->ex_dentry);
526 new->ex_mnt = mntget(item->ex_mnt); 618 new->ex_mnt = mntget(item->ex_mnt);
619 new->ex_path = NULL;
620 new->ex_fslocs.locations = NULL;
621 new->ex_fslocs.locations_count = 0;
622 new->ex_fslocs.migrated = 0;
527} 623}
528 624
529static void export_update(struct cache_head *cnew, struct cache_head *citem) 625static void export_update(struct cache_head *cnew, struct cache_head *citem)
@@ -535,6 +631,14 @@ static void export_update(struct cache_head *cnew, struct cache_head *citem)
535 new->ex_anon_uid = item->ex_anon_uid; 631 new->ex_anon_uid = item->ex_anon_uid;
536 new->ex_anon_gid = item->ex_anon_gid; 632 new->ex_anon_gid = item->ex_anon_gid;
537 new->ex_fsid = item->ex_fsid; 633 new->ex_fsid = item->ex_fsid;
634 new->ex_path = item->ex_path;
635 item->ex_path = NULL;
636 new->ex_fslocs.locations = item->ex_fslocs.locations;
637 item->ex_fslocs.locations = NULL;
638 new->ex_fslocs.locations_count = item->ex_fslocs.locations_count;
639 item->ex_fslocs.locations_count = 0;
640 new->ex_fslocs.migrated = item->ex_fslocs.migrated;
641 item->ex_fslocs.migrated = 0;
538} 642}
539 643
540static struct cache_head *svc_export_alloc(void) 644static struct cache_head *svc_export_alloc(void)
@@ -1044,34 +1148,25 @@ exp_find(struct auth_domain *clp, int fsid_type, u32 *fsidv,
1044 * for a given NFSv4 client. The root is defined to be the 1148 * for a given NFSv4 client. The root is defined to be the
1045 * export point with fsid==0 1149 * export point with fsid==0
1046 */ 1150 */
1047int 1151__be32
1048exp_pseudoroot(struct auth_domain *clp, struct svc_fh *fhp, 1152exp_pseudoroot(struct auth_domain *clp, struct svc_fh *fhp,
1049 struct cache_req *creq) 1153 struct cache_req *creq)
1050{ 1154{
1051 struct svc_expkey *fsid_key;
1052 struct svc_export *exp; 1155 struct svc_export *exp;
1053 int rv; 1156 __be32 rv;
1054 u32 fsidv[2]; 1157 u32 fsidv[2];
1055 1158
1056 mk_fsid_v1(fsidv, 0); 1159 mk_fsid_v1(fsidv, 0);
1057 1160
1058 fsid_key = exp_find_key(clp, 1, fsidv, creq); 1161 exp = exp_find(clp, 1, fsidv, creq);
1059 if (IS_ERR(fsid_key) && PTR_ERR(fsid_key) == -EAGAIN) 1162 if (IS_ERR(exp) && PTR_ERR(exp) == -EAGAIN)
1060 return nfserr_dropit; 1163 return nfserr_dropit;
1061 if (!fsid_key || IS_ERR(fsid_key))
1062 return nfserr_perm;
1063
1064 exp = exp_get_by_name(clp, fsid_key->ek_mnt, fsid_key->ek_dentry, creq);
1065 if (exp == NULL) 1164 if (exp == NULL)
1066 rv = nfserr_perm; 1165 return nfserr_perm;
1067 else if (IS_ERR(exp)) 1166 else if (IS_ERR(exp))
1068 rv = nfserrno(PTR_ERR(exp)); 1167 return nfserrno(PTR_ERR(exp));
1069 else { 1168 rv = fh_compose(fhp, exp, exp->ex_dentry, NULL);
1070 rv = fh_compose(fhp, exp, 1169 exp_put(exp);
1071 fsid_key->ek_dentry, NULL);
1072 exp_put(exp);
1073 }
1074 cache_put(&fsid_key->h, &svc_expkey_cache);
1075 return rv; 1170 return rv;
1076} 1171}
1077 1172
@@ -1158,7 +1253,8 @@ static struct flags {
1158 { 0, {"", ""}} 1253 { 0, {"", ""}}
1159}; 1254};
1160 1255
1161static void exp_flags(struct seq_file *m, int flag, int fsid, uid_t anonu, uid_t anong) 1256static void exp_flags(struct seq_file *m, int flag, int fsid,
1257 uid_t anonu, uid_t anong, struct nfsd4_fs_locations *fsloc)
1162{ 1258{
1163 int first = 0; 1259 int first = 0;
1164 struct flags *flg; 1260 struct flags *flg;
@@ -1174,6 +1270,21 @@ static void exp_flags(struct seq_file *m, int flag, int fsid, uid_t anonu, uid_t
1174 seq_printf(m, "%sanonuid=%d", first++?",":"", anonu); 1270 seq_printf(m, "%sanonuid=%d", first++?",":"", anonu);
1175 if (anong != (gid_t)-2 && anong != (0x10000-2)) 1271 if (anong != (gid_t)-2 && anong != (0x10000-2))
1176 seq_printf(m, "%sanongid=%d", first++?",":"", anong); 1272 seq_printf(m, "%sanongid=%d", first++?",":"", anong);
1273 if (fsloc && fsloc->locations_count > 0) {
1274 char *loctype = (fsloc->migrated) ? "refer" : "replicas";
1275 int i;
1276
1277 seq_printf(m, "%s%s=", first++?",":"", loctype);
1278 seq_escape(m, fsloc->locations[0].path, ",;@ \t\n\\");
1279 seq_putc(m, '@');
1280 seq_escape(m, fsloc->locations[0].hosts, ",;@ \t\n\\");
1281 for (i = 1; i < fsloc->locations_count; i++) {
1282 seq_putc(m, ';');
1283 seq_escape(m, fsloc->locations[i].path, ",;@ \t\n\\");
1284 seq_putc(m, '@');
1285 seq_escape(m, fsloc->locations[i].hosts, ",;@ \t\n\\");
1286 }
1287 }
1177} 1288}
1178 1289
1179static int e_show(struct seq_file *m, void *p) 1290static int e_show(struct seq_file *m, void *p)
diff --git a/fs/nfsd/lockd.c b/fs/nfsd/lockd.c
index 7b889ff15ae6..11fdaf7721b4 100644
--- a/fs/nfsd/lockd.c
+++ b/fs/nfsd/lockd.c
@@ -25,7 +25,7 @@
25static u32 25static u32
26nlm_fopen(struct svc_rqst *rqstp, struct nfs_fh *f, struct file **filp) 26nlm_fopen(struct svc_rqst *rqstp, struct nfs_fh *f, struct file **filp)
27{ 27{
28 u32 nfserr; 28 __be32 nfserr;
29 struct svc_fh fh; 29 struct svc_fh fh;
30 30
31 /* must initialize before using! but maxsize doesn't matter */ 31 /* must initialize before using! but maxsize doesn't matter */
@@ -39,18 +39,20 @@ nlm_fopen(struct svc_rqst *rqstp, struct nfs_fh *f, struct file **filp)
39 fh_put(&fh); 39 fh_put(&fh);
40 rqstp->rq_client = NULL; 40 rqstp->rq_client = NULL;
41 exp_readunlock(); 41 exp_readunlock();
42 /* nlm and nfsd don't share error codes. 42 /* We return nlm error codes as nlm doesn't know
43 * we invent: 0 = no error 43 * about nfsd, but nfsd does know about nlm..
44 * 1 = stale file handle
45 * 2 = other error
46 */ 44 */
47 switch (nfserr) { 45 switch (nfserr) {
48 case nfs_ok: 46 case nfs_ok:
49 return 0; 47 return 0;
48 case nfserr_dropit:
49 return nlm_drop_reply;
50#ifdef CONFIG_LOCKD_V4
50 case nfserr_stale: 51 case nfserr_stale:
51 return 1; 52 return nlm4_stale_fh;
53#endif
52 default: 54 default:
53 return 2; 55 return nlm_lck_denied;
54 } 56 }
55} 57}
56 58
diff --git a/fs/nfsd/nfs2acl.c b/fs/nfsd/nfs2acl.c
index fe56b38364cc..e3eca0816986 100644
--- a/fs/nfsd/nfs2acl.c
+++ b/fs/nfsd/nfs2acl.c
@@ -21,7 +21,7 @@
21/* 21/*
22 * NULL call. 22 * NULL call.
23 */ 23 */
24static int 24static __be32
25nfsacld_proc_null(struct svc_rqst *rqstp, void *argp, void *resp) 25nfsacld_proc_null(struct svc_rqst *rqstp, void *argp, void *resp)
26{ 26{
27 return nfs_ok; 27 return nfs_ok;
@@ -30,12 +30,12 @@ nfsacld_proc_null(struct svc_rqst *rqstp, void *argp, void *resp)
30/* 30/*
31 * Get the Access and/or Default ACL of a file. 31 * Get the Access and/or Default ACL of a file.
32 */ 32 */
33static int nfsacld_proc_getacl(struct svc_rqst * rqstp, 33static __be32 nfsacld_proc_getacl(struct svc_rqst * rqstp,
34 struct nfsd3_getaclargs *argp, struct nfsd3_getaclres *resp) 34 struct nfsd3_getaclargs *argp, struct nfsd3_getaclres *resp)
35{ 35{
36 svc_fh *fh; 36 svc_fh *fh;
37 struct posix_acl *acl; 37 struct posix_acl *acl;
38 int nfserr = 0; 38 __be32 nfserr = 0;
39 39
40 dprintk("nfsd: GETACL(2acl) %s\n", SVCFH_fmt(&argp->fh)); 40 dprintk("nfsd: GETACL(2acl) %s\n", SVCFH_fmt(&argp->fh));
41 41
@@ -97,12 +97,12 @@ fail:
97/* 97/*
98 * Set the Access and/or Default ACL of a file. 98 * Set the Access and/or Default ACL of a file.
99 */ 99 */
100static int nfsacld_proc_setacl(struct svc_rqst * rqstp, 100static __be32 nfsacld_proc_setacl(struct svc_rqst * rqstp,
101 struct nfsd3_setaclargs *argp, 101 struct nfsd3_setaclargs *argp,
102 struct nfsd_attrstat *resp) 102 struct nfsd_attrstat *resp)
103{ 103{
104 svc_fh *fh; 104 svc_fh *fh;
105 int nfserr = 0; 105 __be32 nfserr = 0;
106 106
107 dprintk("nfsd: SETACL(2acl) %s\n", SVCFH_fmt(&argp->fh)); 107 dprintk("nfsd: SETACL(2acl) %s\n", SVCFH_fmt(&argp->fh));
108 108
@@ -128,7 +128,7 @@ static int nfsacld_proc_setacl(struct svc_rqst * rqstp,
128/* 128/*
129 * Check file attributes 129 * Check file attributes
130 */ 130 */
131static int nfsacld_proc_getattr(struct svc_rqst * rqstp, 131static __be32 nfsacld_proc_getattr(struct svc_rqst * rqstp,
132 struct nfsd_fhandle *argp, struct nfsd_attrstat *resp) 132 struct nfsd_fhandle *argp, struct nfsd_attrstat *resp)
133{ 133{
134 dprintk("nfsd: GETATTR %s\n", SVCFH_fmt(&argp->fh)); 134 dprintk("nfsd: GETATTR %s\n", SVCFH_fmt(&argp->fh));
@@ -140,10 +140,10 @@ static int nfsacld_proc_getattr(struct svc_rqst * rqstp,
140/* 140/*
141 * Check file access 141 * Check file access
142 */ 142 */
143static int nfsacld_proc_access(struct svc_rqst *rqstp, struct nfsd3_accessargs *argp, 143static __be32 nfsacld_proc_access(struct svc_rqst *rqstp, struct nfsd3_accessargs *argp,
144 struct nfsd3_accessres *resp) 144 struct nfsd3_accessres *resp)
145{ 145{
146 int nfserr; 146 __be32 nfserr;
147 147
148 dprintk("nfsd: ACCESS(2acl) %s 0x%x\n", 148 dprintk("nfsd: ACCESS(2acl) %s 0x%x\n",
149 SVCFH_fmt(&argp->fh), 149 SVCFH_fmt(&argp->fh),
@@ -158,7 +158,7 @@ static int nfsacld_proc_access(struct svc_rqst *rqstp, struct nfsd3_accessargs *
158/* 158/*
159 * XDR decode functions 159 * XDR decode functions
160 */ 160 */
161static int nfsaclsvc_decode_getaclargs(struct svc_rqst *rqstp, u32 *p, 161static int nfsaclsvc_decode_getaclargs(struct svc_rqst *rqstp, __be32 *p,
162 struct nfsd3_getaclargs *argp) 162 struct nfsd3_getaclargs *argp)
163{ 163{
164 if (!(p = nfs2svc_decode_fh(p, &argp->fh))) 164 if (!(p = nfs2svc_decode_fh(p, &argp->fh)))
@@ -169,7 +169,7 @@ static int nfsaclsvc_decode_getaclargs(struct svc_rqst *rqstp, u32 *p,
169} 169}
170 170
171 171
172static int nfsaclsvc_decode_setaclargs(struct svc_rqst *rqstp, u32 *p, 172static int nfsaclsvc_decode_setaclargs(struct svc_rqst *rqstp, __be32 *p,
173 struct nfsd3_setaclargs *argp) 173 struct nfsd3_setaclargs *argp)
174{ 174{
175 struct kvec *head = rqstp->rq_arg.head; 175 struct kvec *head = rqstp->rq_arg.head;
@@ -194,7 +194,7 @@ static int nfsaclsvc_decode_setaclargs(struct svc_rqst *rqstp, u32 *p,
194 return (n > 0); 194 return (n > 0);
195} 195}
196 196
197static int nfsaclsvc_decode_fhandleargs(struct svc_rqst *rqstp, u32 *p, 197static int nfsaclsvc_decode_fhandleargs(struct svc_rqst *rqstp, __be32 *p,
198 struct nfsd_fhandle *argp) 198 struct nfsd_fhandle *argp)
199{ 199{
200 if (!(p = nfs2svc_decode_fh(p, &argp->fh))) 200 if (!(p = nfs2svc_decode_fh(p, &argp->fh)))
@@ -202,7 +202,7 @@ static int nfsaclsvc_decode_fhandleargs(struct svc_rqst *rqstp, u32 *p,
202 return xdr_argsize_check(rqstp, p); 202 return xdr_argsize_check(rqstp, p);
203} 203}
204 204
205static int nfsaclsvc_decode_accessargs(struct svc_rqst *rqstp, u32 *p, 205static int nfsaclsvc_decode_accessargs(struct svc_rqst *rqstp, __be32 *p,
206 struct nfsd3_accessargs *argp) 206 struct nfsd3_accessargs *argp)
207{ 207{
208 if (!(p = nfs2svc_decode_fh(p, &argp->fh))) 208 if (!(p = nfs2svc_decode_fh(p, &argp->fh)))
@@ -217,7 +217,7 @@ static int nfsaclsvc_decode_accessargs(struct svc_rqst *rqstp, u32 *p,
217 */ 217 */
218 218
219/* GETACL */ 219/* GETACL */
220static int nfsaclsvc_encode_getaclres(struct svc_rqst *rqstp, u32 *p, 220static int nfsaclsvc_encode_getaclres(struct svc_rqst *rqstp, __be32 *p,
221 struct nfsd3_getaclres *resp) 221 struct nfsd3_getaclres *resp)
222{ 222{
223 struct dentry *dentry = resp->fh.fh_dentry; 223 struct dentry *dentry = resp->fh.fh_dentry;
@@ -241,7 +241,7 @@ static int nfsaclsvc_encode_getaclres(struct svc_rqst *rqstp, u32 *p,
241 241
242 rqstp->rq_res.page_len = w; 242 rqstp->rq_res.page_len = w;
243 while (w > 0) { 243 while (w > 0) {
244 if (!svc_take_res_page(rqstp)) 244 if (!rqstp->rq_respages[rqstp->rq_resused++])
245 return 0; 245 return 0;
246 w -= PAGE_SIZE; 246 w -= PAGE_SIZE;
247 } 247 }
@@ -259,7 +259,7 @@ static int nfsaclsvc_encode_getaclres(struct svc_rqst *rqstp, u32 *p,
259 return 1; 259 return 1;
260} 260}
261 261
262static int nfsaclsvc_encode_attrstatres(struct svc_rqst *rqstp, u32 *p, 262static int nfsaclsvc_encode_attrstatres(struct svc_rqst *rqstp, __be32 *p,
263 struct nfsd_attrstat *resp) 263 struct nfsd_attrstat *resp)
264{ 264{
265 p = nfs2svc_encode_fattr(rqstp, p, &resp->fh); 265 p = nfs2svc_encode_fattr(rqstp, p, &resp->fh);
@@ -267,7 +267,7 @@ static int nfsaclsvc_encode_attrstatres(struct svc_rqst *rqstp, u32 *p,
267} 267}
268 268
269/* ACCESS */ 269/* ACCESS */
270static int nfsaclsvc_encode_accessres(struct svc_rqst *rqstp, u32 *p, 270static int nfsaclsvc_encode_accessres(struct svc_rqst *rqstp, __be32 *p,
271 struct nfsd3_accessres *resp) 271 struct nfsd3_accessres *resp)
272{ 272{
273 p = nfs2svc_encode_fattr(rqstp, p, &resp->fh); 273 p = nfs2svc_encode_fattr(rqstp, p, &resp->fh);
@@ -278,7 +278,7 @@ static int nfsaclsvc_encode_accessres(struct svc_rqst *rqstp, u32 *p,
278/* 278/*
279 * XDR release functions 279 * XDR release functions
280 */ 280 */
281static int nfsaclsvc_release_getacl(struct svc_rqst *rqstp, u32 *p, 281static int nfsaclsvc_release_getacl(struct svc_rqst *rqstp, __be32 *p,
282 struct nfsd3_getaclres *resp) 282 struct nfsd3_getaclres *resp)
283{ 283{
284 fh_put(&resp->fh); 284 fh_put(&resp->fh);
@@ -287,7 +287,7 @@ static int nfsaclsvc_release_getacl(struct svc_rqst *rqstp, u32 *p,
287 return 1; 287 return 1;
288} 288}
289 289
290static int nfsaclsvc_release_fhandle(struct svc_rqst *rqstp, u32 *p, 290static int nfsaclsvc_release_fhandle(struct svc_rqst *rqstp, __be32 *p,
291 struct nfsd_fhandle *resp) 291 struct nfsd_fhandle *resp)
292{ 292{
293 fh_put(&resp->fh); 293 fh_put(&resp->fh);
@@ -333,4 +333,5 @@ struct svc_version nfsd_acl_version2 = {
333 .vs_proc = nfsd_acl_procedures2, 333 .vs_proc = nfsd_acl_procedures2,
334 .vs_dispatch = nfsd_dispatch, 334 .vs_dispatch = nfsd_dispatch,
335 .vs_xdrsize = NFS3_SVC_XDRSIZE, 335 .vs_xdrsize = NFS3_SVC_XDRSIZE,
336 .vs_hidden = 1,
336}; 337};
diff --git a/fs/nfsd/nfs3acl.c b/fs/nfsd/nfs3acl.c
index 16e10c170aed..fcad2895ddb0 100644
--- a/fs/nfsd/nfs3acl.c
+++ b/fs/nfsd/nfs3acl.c
@@ -19,7 +19,7 @@
19/* 19/*
20 * NULL call. 20 * NULL call.
21 */ 21 */
22static int 22static __be32
23nfsd3_proc_null(struct svc_rqst *rqstp, void *argp, void *resp) 23nfsd3_proc_null(struct svc_rqst *rqstp, void *argp, void *resp)
24{ 24{
25 return nfs_ok; 25 return nfs_ok;
@@ -28,12 +28,12 @@ nfsd3_proc_null(struct svc_rqst *rqstp, void *argp, void *resp)
28/* 28/*
29 * Get the Access and/or Default ACL of a file. 29 * Get the Access and/or Default ACL of a file.
30 */ 30 */
31static int nfsd3_proc_getacl(struct svc_rqst * rqstp, 31static __be32 nfsd3_proc_getacl(struct svc_rqst * rqstp,
32 struct nfsd3_getaclargs *argp, struct nfsd3_getaclres *resp) 32 struct nfsd3_getaclargs *argp, struct nfsd3_getaclres *resp)
33{ 33{
34 svc_fh *fh; 34 svc_fh *fh;
35 struct posix_acl *acl; 35 struct posix_acl *acl;
36 int nfserr = 0; 36 __be32 nfserr = 0;
37 37
38 fh = fh_copy(&resp->fh, &argp->fh); 38 fh = fh_copy(&resp->fh, &argp->fh);
39 if ((nfserr = fh_verify(rqstp, &resp->fh, 0, MAY_NOP))) 39 if ((nfserr = fh_verify(rqstp, &resp->fh, 0, MAY_NOP)))
@@ -93,12 +93,12 @@ fail:
93/* 93/*
94 * Set the Access and/or Default ACL of a file. 94 * Set the Access and/or Default ACL of a file.
95 */ 95 */
96static int nfsd3_proc_setacl(struct svc_rqst * rqstp, 96static __be32 nfsd3_proc_setacl(struct svc_rqst * rqstp,
97 struct nfsd3_setaclargs *argp, 97 struct nfsd3_setaclargs *argp,
98 struct nfsd3_attrstat *resp) 98 struct nfsd3_attrstat *resp)
99{ 99{
100 svc_fh *fh; 100 svc_fh *fh;
101 int nfserr = 0; 101 __be32 nfserr = 0;
102 102
103 fh = fh_copy(&resp->fh, &argp->fh); 103 fh = fh_copy(&resp->fh, &argp->fh);
104 nfserr = fh_verify(rqstp, &resp->fh, 0, MAY_SATTR); 104 nfserr = fh_verify(rqstp, &resp->fh, 0, MAY_SATTR);
@@ -122,7 +122,7 @@ static int nfsd3_proc_setacl(struct svc_rqst * rqstp,
122/* 122/*
123 * XDR decode functions 123 * XDR decode functions
124 */ 124 */
125static int nfs3svc_decode_getaclargs(struct svc_rqst *rqstp, u32 *p, 125static int nfs3svc_decode_getaclargs(struct svc_rqst *rqstp, __be32 *p,
126 struct nfsd3_getaclargs *args) 126 struct nfsd3_getaclargs *args)
127{ 127{
128 if (!(p = nfs3svc_decode_fh(p, &args->fh))) 128 if (!(p = nfs3svc_decode_fh(p, &args->fh)))
@@ -133,7 +133,7 @@ static int nfs3svc_decode_getaclargs(struct svc_rqst *rqstp, u32 *p,
133} 133}
134 134
135 135
136static int nfs3svc_decode_setaclargs(struct svc_rqst *rqstp, u32 *p, 136static int nfs3svc_decode_setaclargs(struct svc_rqst *rqstp, __be32 *p,
137 struct nfsd3_setaclargs *args) 137 struct nfsd3_setaclargs *args)
138{ 138{
139 struct kvec *head = rqstp->rq_arg.head; 139 struct kvec *head = rqstp->rq_arg.head;
@@ -163,7 +163,7 @@ static int nfs3svc_decode_setaclargs(struct svc_rqst *rqstp, u32 *p,
163 */ 163 */
164 164
165/* GETACL */ 165/* GETACL */
166static int nfs3svc_encode_getaclres(struct svc_rqst *rqstp, u32 *p, 166static int nfs3svc_encode_getaclres(struct svc_rqst *rqstp, __be32 *p,
167 struct nfsd3_getaclres *resp) 167 struct nfsd3_getaclres *resp)
168{ 168{
169 struct dentry *dentry = resp->fh.fh_dentry; 169 struct dentry *dentry = resp->fh.fh_dentry;
@@ -185,7 +185,7 @@ static int nfs3svc_encode_getaclres(struct svc_rqst *rqstp, u32 *p,
185 185
186 rqstp->rq_res.page_len = w; 186 rqstp->rq_res.page_len = w;
187 while (w > 0) { 187 while (w > 0) {
188 if (!svc_take_res_page(rqstp)) 188 if (!rqstp->rq_respages[rqstp->rq_resused++])
189 return 0; 189 return 0;
190 w -= PAGE_SIZE; 190 w -= PAGE_SIZE;
191 } 191 }
@@ -208,7 +208,7 @@ static int nfs3svc_encode_getaclres(struct svc_rqst *rqstp, u32 *p,
208} 208}
209 209
210/* SETACL */ 210/* SETACL */
211static int nfs3svc_encode_setaclres(struct svc_rqst *rqstp, u32 *p, 211static int nfs3svc_encode_setaclres(struct svc_rqst *rqstp, __be32 *p,
212 struct nfsd3_attrstat *resp) 212 struct nfsd3_attrstat *resp)
213{ 213{
214 p = nfs3svc_encode_post_op_attr(rqstp, p, &resp->fh); 214 p = nfs3svc_encode_post_op_attr(rqstp, p, &resp->fh);
@@ -219,7 +219,7 @@ static int nfs3svc_encode_setaclres(struct svc_rqst *rqstp, u32 *p,
219/* 219/*
220 * XDR release functions 220 * XDR release functions
221 */ 221 */
222static int nfs3svc_release_getacl(struct svc_rqst *rqstp, u32 *p, 222static int nfs3svc_release_getacl(struct svc_rqst *rqstp, __be32 *p,
223 struct nfsd3_getaclres *resp) 223 struct nfsd3_getaclres *resp)
224{ 224{
225 fh_put(&resp->fh); 225 fh_put(&resp->fh);
@@ -263,5 +263,6 @@ struct svc_version nfsd_acl_version3 = {
263 .vs_proc = nfsd_acl_procedures3, 263 .vs_proc = nfsd_acl_procedures3,
264 .vs_dispatch = nfsd_dispatch, 264 .vs_dispatch = nfsd_dispatch,
265 .vs_xdrsize = NFS3_SVC_XDRSIZE, 265 .vs_xdrsize = NFS3_SVC_XDRSIZE,
266 .vs_hidden = 1,
266}; 267};
267 268
diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c
index f61142afea44..64db601c2bd2 100644
--- a/fs/nfsd/nfs3proc.c
+++ b/fs/nfsd/nfs3proc.c
@@ -43,7 +43,7 @@ static int nfs3_ftypes[] = {
43/* 43/*
44 * NULL call. 44 * NULL call.
45 */ 45 */
46static int 46static __be32
47nfsd3_proc_null(struct svc_rqst *rqstp, void *argp, void *resp) 47nfsd3_proc_null(struct svc_rqst *rqstp, void *argp, void *resp)
48{ 48{
49 return nfs_ok; 49 return nfs_ok;
@@ -52,11 +52,12 @@ nfsd3_proc_null(struct svc_rqst *rqstp, void *argp, void *resp)
52/* 52/*
53 * Get a file's attributes 53 * Get a file's attributes
54 */ 54 */
55static int 55static __be32
56nfsd3_proc_getattr(struct svc_rqst *rqstp, struct nfsd_fhandle *argp, 56nfsd3_proc_getattr(struct svc_rqst *rqstp, struct nfsd_fhandle *argp,
57 struct nfsd3_attrstat *resp) 57 struct nfsd3_attrstat *resp)
58{ 58{
59 int err, nfserr; 59 int err;
60 __be32 nfserr;
60 61
61 dprintk("nfsd: GETATTR(3) %s\n", 62 dprintk("nfsd: GETATTR(3) %s\n",
62 SVCFH_fmt(&argp->fh)); 63 SVCFH_fmt(&argp->fh));
@@ -76,11 +77,11 @@ nfsd3_proc_getattr(struct svc_rqst *rqstp, struct nfsd_fhandle *argp,
76/* 77/*
77 * Set a file's attributes 78 * Set a file's attributes
78 */ 79 */
79static int 80static __be32
80nfsd3_proc_setattr(struct svc_rqst *rqstp, struct nfsd3_sattrargs *argp, 81nfsd3_proc_setattr(struct svc_rqst *rqstp, struct nfsd3_sattrargs *argp,
81 struct nfsd3_attrstat *resp) 82 struct nfsd3_attrstat *resp)
82{ 83{
83 int nfserr; 84 __be32 nfserr;
84 85
85 dprintk("nfsd: SETATTR(3) %s\n", 86 dprintk("nfsd: SETATTR(3) %s\n",
86 SVCFH_fmt(&argp->fh)); 87 SVCFH_fmt(&argp->fh));
@@ -94,11 +95,11 @@ nfsd3_proc_setattr(struct svc_rqst *rqstp, struct nfsd3_sattrargs *argp,
94/* 95/*
95 * Look up a path name component 96 * Look up a path name component
96 */ 97 */
97static int 98static __be32
98nfsd3_proc_lookup(struct svc_rqst *rqstp, struct nfsd3_diropargs *argp, 99nfsd3_proc_lookup(struct svc_rqst *rqstp, struct nfsd3_diropargs *argp,
99 struct nfsd3_diropres *resp) 100 struct nfsd3_diropres *resp)
100{ 101{
101 int nfserr; 102 __be32 nfserr;
102 103
103 dprintk("nfsd: LOOKUP(3) %s %.*s\n", 104 dprintk("nfsd: LOOKUP(3) %s %.*s\n",
104 SVCFH_fmt(&argp->fh), 105 SVCFH_fmt(&argp->fh),
@@ -118,11 +119,11 @@ nfsd3_proc_lookup(struct svc_rqst *rqstp, struct nfsd3_diropargs *argp,
118/* 119/*
119 * Check file access 120 * Check file access
120 */ 121 */
121static int 122static __be32
122nfsd3_proc_access(struct svc_rqst *rqstp, struct nfsd3_accessargs *argp, 123nfsd3_proc_access(struct svc_rqst *rqstp, struct nfsd3_accessargs *argp,
123 struct nfsd3_accessres *resp) 124 struct nfsd3_accessres *resp)
124{ 125{
125 int nfserr; 126 __be32 nfserr;
126 127
127 dprintk("nfsd: ACCESS(3) %s 0x%x\n", 128 dprintk("nfsd: ACCESS(3) %s 0x%x\n",
128 SVCFH_fmt(&argp->fh), 129 SVCFH_fmt(&argp->fh),
@@ -137,11 +138,11 @@ nfsd3_proc_access(struct svc_rqst *rqstp, struct nfsd3_accessargs *argp,
137/* 138/*
138 * Read a symlink. 139 * Read a symlink.
139 */ 140 */
140static int 141static __be32
141nfsd3_proc_readlink(struct svc_rqst *rqstp, struct nfsd3_readlinkargs *argp, 142nfsd3_proc_readlink(struct svc_rqst *rqstp, struct nfsd3_readlinkargs *argp,
142 struct nfsd3_readlinkres *resp) 143 struct nfsd3_readlinkres *resp)
143{ 144{
144 int nfserr; 145 __be32 nfserr;
145 146
146 dprintk("nfsd: READLINK(3) %s\n", SVCFH_fmt(&argp->fh)); 147 dprintk("nfsd: READLINK(3) %s\n", SVCFH_fmt(&argp->fh));
147 148
@@ -155,11 +156,12 @@ nfsd3_proc_readlink(struct svc_rqst *rqstp, struct nfsd3_readlinkargs *argp,
155/* 156/*
156 * Read a portion of a file. 157 * Read a portion of a file.
157 */ 158 */
158static int 159static __be32
159nfsd3_proc_read(struct svc_rqst *rqstp, struct nfsd3_readargs *argp, 160nfsd3_proc_read(struct svc_rqst *rqstp, struct nfsd3_readargs *argp,
160 struct nfsd3_readres *resp) 161 struct nfsd3_readres *resp)
161{ 162{
162 int nfserr; 163 __be32 nfserr;
164 u32 max_blocksize = svc_max_payload(rqstp);
163 165
164 dprintk("nfsd: READ(3) %s %lu bytes at %lu\n", 166 dprintk("nfsd: READ(3) %s %lu bytes at %lu\n",
165 SVCFH_fmt(&argp->fh), 167 SVCFH_fmt(&argp->fh),
@@ -172,15 +174,15 @@ nfsd3_proc_read(struct svc_rqst *rqstp, struct nfsd3_readargs *argp,
172 */ 174 */
173 175
174 resp->count = argp->count; 176 resp->count = argp->count;
175 if (NFSSVC_MAXBLKSIZE < resp->count) 177 if (max_blocksize < resp->count)
176 resp->count = NFSSVC_MAXBLKSIZE; 178 resp->count = max_blocksize;
177 179
178 svc_reserve(rqstp, ((1 + NFS3_POST_OP_ATTR_WORDS + 3)<<2) + resp->count +4); 180 svc_reserve(rqstp, ((1 + NFS3_POST_OP_ATTR_WORDS + 3)<<2) + resp->count +4);
179 181
180 fh_copy(&resp->fh, &argp->fh); 182 fh_copy(&resp->fh, &argp->fh);
181 nfserr = nfsd_read(rqstp, &resp->fh, NULL, 183 nfserr = nfsd_read(rqstp, &resp->fh, NULL,
182 argp->offset, 184 argp->offset,
183 argp->vec, argp->vlen, 185 rqstp->rq_vec, argp->vlen,
184 &resp->count); 186 &resp->count);
185 if (nfserr == 0) { 187 if (nfserr == 0) {
186 struct inode *inode = resp->fh.fh_dentry->d_inode; 188 struct inode *inode = resp->fh.fh_dentry->d_inode;
@@ -194,11 +196,11 @@ nfsd3_proc_read(struct svc_rqst *rqstp, struct nfsd3_readargs *argp,
194/* 196/*
195 * Write data to a file 197 * Write data to a file
196 */ 198 */
197static int 199static __be32
198nfsd3_proc_write(struct svc_rqst *rqstp, struct nfsd3_writeargs *argp, 200nfsd3_proc_write(struct svc_rqst *rqstp, struct nfsd3_writeargs *argp,
199 struct nfsd3_writeres *resp) 201 struct nfsd3_writeres *resp)
200{ 202{
201 int nfserr; 203 __be32 nfserr;
202 204
203 dprintk("nfsd: WRITE(3) %s %d bytes at %ld%s\n", 205 dprintk("nfsd: WRITE(3) %s %d bytes at %ld%s\n",
204 SVCFH_fmt(&argp->fh), 206 SVCFH_fmt(&argp->fh),
@@ -210,7 +212,7 @@ nfsd3_proc_write(struct svc_rqst *rqstp, struct nfsd3_writeargs *argp,
210 resp->committed = argp->stable; 212 resp->committed = argp->stable;
211 nfserr = nfsd_write(rqstp, &resp->fh, NULL, 213 nfserr = nfsd_write(rqstp, &resp->fh, NULL,
212 argp->offset, 214 argp->offset,
213 argp->vec, argp->vlen, 215 rqstp->rq_vec, argp->vlen,
214 argp->len, 216 argp->len,
215 &resp->committed); 217 &resp->committed);
216 resp->count = argp->count; 218 resp->count = argp->count;
@@ -222,13 +224,13 @@ nfsd3_proc_write(struct svc_rqst *rqstp, struct nfsd3_writeargs *argp,
222 * At least in theory; we'll see how it fares in practice when the 224 * At least in theory; we'll see how it fares in practice when the
223 * first reports about SunOS compatibility problems start to pour in... 225 * first reports about SunOS compatibility problems start to pour in...
224 */ 226 */
225static int 227static __be32
226nfsd3_proc_create(struct svc_rqst *rqstp, struct nfsd3_createargs *argp, 228nfsd3_proc_create(struct svc_rqst *rqstp, struct nfsd3_createargs *argp,
227 struct nfsd3_diropres *resp) 229 struct nfsd3_diropres *resp)
228{ 230{
229 svc_fh *dirfhp, *newfhp = NULL; 231 svc_fh *dirfhp, *newfhp = NULL;
230 struct iattr *attr; 232 struct iattr *attr;
231 u32 nfserr; 233 __be32 nfserr;
232 234
233 dprintk("nfsd: CREATE(3) %s %.*s\n", 235 dprintk("nfsd: CREATE(3) %s %.*s\n",
234 SVCFH_fmt(&argp->fh), 236 SVCFH_fmt(&argp->fh),
@@ -264,11 +266,11 @@ nfsd3_proc_create(struct svc_rqst *rqstp, struct nfsd3_createargs *argp,
264/* 266/*
265 * Make directory. This operation is not idempotent. 267 * Make directory. This operation is not idempotent.
266 */ 268 */
267static int 269static __be32
268nfsd3_proc_mkdir(struct svc_rqst *rqstp, struct nfsd3_createargs *argp, 270nfsd3_proc_mkdir(struct svc_rqst *rqstp, struct nfsd3_createargs *argp,
269 struct nfsd3_diropres *resp) 271 struct nfsd3_diropres *resp)
270{ 272{
271 int nfserr; 273 __be32 nfserr;
272 274
273 dprintk("nfsd: MKDIR(3) %s %.*s\n", 275 dprintk("nfsd: MKDIR(3) %s %.*s\n",
274 SVCFH_fmt(&argp->fh), 276 SVCFH_fmt(&argp->fh),
@@ -284,11 +286,11 @@ nfsd3_proc_mkdir(struct svc_rqst *rqstp, struct nfsd3_createargs *argp,
284 RETURN_STATUS(nfserr); 286 RETURN_STATUS(nfserr);
285} 287}
286 288
287static int 289static __be32
288nfsd3_proc_symlink(struct svc_rqst *rqstp, struct nfsd3_symlinkargs *argp, 290nfsd3_proc_symlink(struct svc_rqst *rqstp, struct nfsd3_symlinkargs *argp,
289 struct nfsd3_diropres *resp) 291 struct nfsd3_diropres *resp)
290{ 292{
291 int nfserr; 293 __be32 nfserr;
292 294
293 dprintk("nfsd: SYMLINK(3) %s %.*s -> %.*s\n", 295 dprintk("nfsd: SYMLINK(3) %s %.*s -> %.*s\n",
294 SVCFH_fmt(&argp->ffh), 296 SVCFH_fmt(&argp->ffh),
@@ -306,11 +308,12 @@ nfsd3_proc_symlink(struct svc_rqst *rqstp, struct nfsd3_symlinkargs *argp,
306/* 308/*
307 * Make socket/fifo/device. 309 * Make socket/fifo/device.
308 */ 310 */
309static int 311static __be32
310nfsd3_proc_mknod(struct svc_rqst *rqstp, struct nfsd3_mknodargs *argp, 312nfsd3_proc_mknod(struct svc_rqst *rqstp, struct nfsd3_mknodargs *argp,
311 struct nfsd3_diropres *resp) 313 struct nfsd3_diropres *resp)
312{ 314{
313 int nfserr, type; 315 __be32 nfserr;
316 int type;
314 dev_t rdev = 0; 317 dev_t rdev = 0;
315 318
316 dprintk("nfsd: MKNOD(3) %s %.*s\n", 319 dprintk("nfsd: MKNOD(3) %s %.*s\n",
@@ -342,11 +345,11 @@ nfsd3_proc_mknod(struct svc_rqst *rqstp, struct nfsd3_mknodargs *argp,
342/* 345/*
343 * Remove file/fifo/socket etc. 346 * Remove file/fifo/socket etc.
344 */ 347 */
345static int 348static __be32
346nfsd3_proc_remove(struct svc_rqst *rqstp, struct nfsd3_diropargs *argp, 349nfsd3_proc_remove(struct svc_rqst *rqstp, struct nfsd3_diropargs *argp,
347 struct nfsd3_attrstat *resp) 350 struct nfsd3_attrstat *resp)
348{ 351{
349 int nfserr; 352 __be32 nfserr;
350 353
351 dprintk("nfsd: REMOVE(3) %s %.*s\n", 354 dprintk("nfsd: REMOVE(3) %s %.*s\n",
352 SVCFH_fmt(&argp->fh), 355 SVCFH_fmt(&argp->fh),
@@ -362,11 +365,11 @@ nfsd3_proc_remove(struct svc_rqst *rqstp, struct nfsd3_diropargs *argp,
362/* 365/*
363 * Remove a directory 366 * Remove a directory
364 */ 367 */
365static int 368static __be32
366nfsd3_proc_rmdir(struct svc_rqst *rqstp, struct nfsd3_diropargs *argp, 369nfsd3_proc_rmdir(struct svc_rqst *rqstp, struct nfsd3_diropargs *argp,
367 struct nfsd3_attrstat *resp) 370 struct nfsd3_attrstat *resp)
368{ 371{
369 int nfserr; 372 __be32 nfserr;
370 373
371 dprintk("nfsd: RMDIR(3) %s %.*s\n", 374 dprintk("nfsd: RMDIR(3) %s %.*s\n",
372 SVCFH_fmt(&argp->fh), 375 SVCFH_fmt(&argp->fh),
@@ -378,11 +381,11 @@ nfsd3_proc_rmdir(struct svc_rqst *rqstp, struct nfsd3_diropargs *argp,
378 RETURN_STATUS(nfserr); 381 RETURN_STATUS(nfserr);
379} 382}
380 383
381static int 384static __be32
382nfsd3_proc_rename(struct svc_rqst *rqstp, struct nfsd3_renameargs *argp, 385nfsd3_proc_rename(struct svc_rqst *rqstp, struct nfsd3_renameargs *argp,
383 struct nfsd3_renameres *resp) 386 struct nfsd3_renameres *resp)
384{ 387{
385 int nfserr; 388 __be32 nfserr;
386 389
387 dprintk("nfsd: RENAME(3) %s %.*s ->\n", 390 dprintk("nfsd: RENAME(3) %s %.*s ->\n",
388 SVCFH_fmt(&argp->ffh), 391 SVCFH_fmt(&argp->ffh),
@@ -400,11 +403,11 @@ nfsd3_proc_rename(struct svc_rqst *rqstp, struct nfsd3_renameargs *argp,
400 RETURN_STATUS(nfserr); 403 RETURN_STATUS(nfserr);
401} 404}
402 405
403static int 406static __be32
404nfsd3_proc_link(struct svc_rqst *rqstp, struct nfsd3_linkargs *argp, 407nfsd3_proc_link(struct svc_rqst *rqstp, struct nfsd3_linkargs *argp,
405 struct nfsd3_linkres *resp) 408 struct nfsd3_linkres *resp)
406{ 409{
407 int nfserr; 410 __be32 nfserr;
408 411
409 dprintk("nfsd: LINK(3) %s ->\n", 412 dprintk("nfsd: LINK(3) %s ->\n",
410 SVCFH_fmt(&argp->ffh)); 413 SVCFH_fmt(&argp->ffh));
@@ -423,11 +426,12 @@ nfsd3_proc_link(struct svc_rqst *rqstp, struct nfsd3_linkargs *argp,
423/* 426/*
424 * Read a portion of a directory. 427 * Read a portion of a directory.
425 */ 428 */
426static int 429static __be32
427nfsd3_proc_readdir(struct svc_rqst *rqstp, struct nfsd3_readdirargs *argp, 430nfsd3_proc_readdir(struct svc_rqst *rqstp, struct nfsd3_readdirargs *argp,
428 struct nfsd3_readdirres *resp) 431 struct nfsd3_readdirres *resp)
429{ 432{
430 int nfserr, count; 433 __be32 nfserr;
434 int count;
431 435
432 dprintk("nfsd: READDIR(3) %s %d bytes at %d\n", 436 dprintk("nfsd: READDIR(3) %s %d bytes at %d\n",
433 SVCFH_fmt(&argp->fh), 437 SVCFH_fmt(&argp->fh),
@@ -458,11 +462,12 @@ nfsd3_proc_readdir(struct svc_rqst *rqstp, struct nfsd3_readdirargs *argp,
458 * Read a portion of a directory, including file handles and attrs. 462 * Read a portion of a directory, including file handles and attrs.
459 * For now, we choose to ignore the dircount parameter. 463 * For now, we choose to ignore the dircount parameter.
460 */ 464 */
461static int 465static __be32
462nfsd3_proc_readdirplus(struct svc_rqst *rqstp, struct nfsd3_readdirargs *argp, 466nfsd3_proc_readdirplus(struct svc_rqst *rqstp, struct nfsd3_readdirargs *argp,
463 struct nfsd3_readdirres *resp) 467 struct nfsd3_readdirres *resp)
464{ 468{
465 int nfserr, count = 0; 469 __be32 nfserr;
470 int count = 0;
466 loff_t offset; 471 loff_t offset;
467 int i; 472 int i;
468 caddr_t page_addr = NULL; 473 caddr_t page_addr = NULL;
@@ -516,11 +521,11 @@ nfsd3_proc_readdirplus(struct svc_rqst *rqstp, struct nfsd3_readdirargs *argp,
516/* 521/*
517 * Get file system stats 522 * Get file system stats
518 */ 523 */
519static int 524static __be32
520nfsd3_proc_fsstat(struct svc_rqst * rqstp, struct nfsd_fhandle *argp, 525nfsd3_proc_fsstat(struct svc_rqst * rqstp, struct nfsd_fhandle *argp,
521 struct nfsd3_fsstatres *resp) 526 struct nfsd3_fsstatres *resp)
522{ 527{
523 int nfserr; 528 __be32 nfserr;
524 529
525 dprintk("nfsd: FSSTAT(3) %s\n", 530 dprintk("nfsd: FSSTAT(3) %s\n",
526 SVCFH_fmt(&argp->fh)); 531 SVCFH_fmt(&argp->fh));
@@ -533,20 +538,21 @@ nfsd3_proc_fsstat(struct svc_rqst * rqstp, struct nfsd_fhandle *argp,
533/* 538/*
534 * Get file system info 539 * Get file system info
535 */ 540 */
536static int 541static __be32
537nfsd3_proc_fsinfo(struct svc_rqst * rqstp, struct nfsd_fhandle *argp, 542nfsd3_proc_fsinfo(struct svc_rqst * rqstp, struct nfsd_fhandle *argp,
538 struct nfsd3_fsinfores *resp) 543 struct nfsd3_fsinfores *resp)
539{ 544{
540 int nfserr; 545 __be32 nfserr;
546 u32 max_blocksize = svc_max_payload(rqstp);
541 547
542 dprintk("nfsd: FSINFO(3) %s\n", 548 dprintk("nfsd: FSINFO(3) %s\n",
543 SVCFH_fmt(&argp->fh)); 549 SVCFH_fmt(&argp->fh));
544 550
545 resp->f_rtmax = NFSSVC_MAXBLKSIZE; 551 resp->f_rtmax = max_blocksize;
546 resp->f_rtpref = NFSSVC_MAXBLKSIZE; 552 resp->f_rtpref = max_blocksize;
547 resp->f_rtmult = PAGE_SIZE; 553 resp->f_rtmult = PAGE_SIZE;
548 resp->f_wtmax = NFSSVC_MAXBLKSIZE; 554 resp->f_wtmax = max_blocksize;
549 resp->f_wtpref = NFSSVC_MAXBLKSIZE; 555 resp->f_wtpref = max_blocksize;
550 resp->f_wtmult = PAGE_SIZE; 556 resp->f_wtmult = PAGE_SIZE;
551 resp->f_dtpref = PAGE_SIZE; 557 resp->f_dtpref = PAGE_SIZE;
552 resp->f_maxfilesize = ~(u32) 0; 558 resp->f_maxfilesize = ~(u32) 0;
@@ -574,11 +580,11 @@ nfsd3_proc_fsinfo(struct svc_rqst * rqstp, struct nfsd_fhandle *argp,
574/* 580/*
575 * Get pathconf info for the specified file 581 * Get pathconf info for the specified file
576 */ 582 */
577static int 583static __be32
578nfsd3_proc_pathconf(struct svc_rqst * rqstp, struct nfsd_fhandle *argp, 584nfsd3_proc_pathconf(struct svc_rqst * rqstp, struct nfsd_fhandle *argp,
579 struct nfsd3_pathconfres *resp) 585 struct nfsd3_pathconfres *resp)
580{ 586{
581 int nfserr; 587 __be32 nfserr;
582 588
583 dprintk("nfsd: PATHCONF(3) %s\n", 589 dprintk("nfsd: PATHCONF(3) %s\n",
584 SVCFH_fmt(&argp->fh)); 590 SVCFH_fmt(&argp->fh));
@@ -617,11 +623,11 @@ nfsd3_proc_pathconf(struct svc_rqst * rqstp, struct nfsd_fhandle *argp,
617/* 623/*
618 * Commit a file (range) to stable storage. 624 * Commit a file (range) to stable storage.
619 */ 625 */
620static int 626static __be32
621nfsd3_proc_commit(struct svc_rqst * rqstp, struct nfsd3_commitargs *argp, 627nfsd3_proc_commit(struct svc_rqst * rqstp, struct nfsd3_commitargs *argp,
622 struct nfsd3_commitres *resp) 628 struct nfsd3_commitres *resp)
623{ 629{
624 int nfserr; 630 __be32 nfserr;
625 631
626 dprintk("nfsd: COMMIT(3) %s %u@%Lu\n", 632 dprintk("nfsd: COMMIT(3) %s %u@%Lu\n",
627 SVCFH_fmt(&argp->fh), 633 SVCFH_fmt(&argp->fh),
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index 243d94b9653a..b4baca3053c3 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -42,23 +42,23 @@ static u32 nfs3_ftypes[] = {
42/* 42/*
43 * XDR functions for basic NFS types 43 * XDR functions for basic NFS types
44 */ 44 */
45static inline u32 * 45static inline __be32 *
46encode_time3(u32 *p, struct timespec *time) 46encode_time3(__be32 *p, struct timespec *time)
47{ 47{
48 *p++ = htonl((u32) time->tv_sec); *p++ = htonl(time->tv_nsec); 48 *p++ = htonl((u32) time->tv_sec); *p++ = htonl(time->tv_nsec);
49 return p; 49 return p;
50} 50}
51 51
52static inline u32 * 52static inline __be32 *
53decode_time3(u32 *p, struct timespec *time) 53decode_time3(__be32 *p, struct timespec *time)
54{ 54{
55 time->tv_sec = ntohl(*p++); 55 time->tv_sec = ntohl(*p++);
56 time->tv_nsec = ntohl(*p++); 56 time->tv_nsec = ntohl(*p++);
57 return p; 57 return p;
58} 58}
59 59
60static inline u32 * 60static inline __be32 *
61decode_fh(u32 *p, struct svc_fh *fhp) 61decode_fh(__be32 *p, struct svc_fh *fhp)
62{ 62{
63 unsigned int size; 63 unsigned int size;
64 fh_init(fhp, NFS3_FHSIZE); 64 fh_init(fhp, NFS3_FHSIZE);
@@ -72,13 +72,13 @@ decode_fh(u32 *p, struct svc_fh *fhp)
72} 72}
73 73
74/* Helper function for NFSv3 ACL code */ 74/* Helper function for NFSv3 ACL code */
75u32 *nfs3svc_decode_fh(u32 *p, struct svc_fh *fhp) 75__be32 *nfs3svc_decode_fh(__be32 *p, struct svc_fh *fhp)
76{ 76{
77 return decode_fh(p, fhp); 77 return decode_fh(p, fhp);
78} 78}
79 79
80static inline u32 * 80static inline __be32 *
81encode_fh(u32 *p, struct svc_fh *fhp) 81encode_fh(__be32 *p, struct svc_fh *fhp)
82{ 82{
83 unsigned int size = fhp->fh_handle.fh_size; 83 unsigned int size = fhp->fh_handle.fh_size;
84 *p++ = htonl(size); 84 *p++ = htonl(size);
@@ -91,8 +91,8 @@ encode_fh(u32 *p, struct svc_fh *fhp)
91 * Decode a file name and make sure that the path contains 91 * Decode a file name and make sure that the path contains
92 * no slashes or null bytes. 92 * no slashes or null bytes.
93 */ 93 */
94static inline u32 * 94static inline __be32 *
95decode_filename(u32 *p, char **namp, int *lenp) 95decode_filename(__be32 *p, char **namp, int *lenp)
96{ 96{
97 char *name; 97 char *name;
98 int i; 98 int i;
@@ -107,8 +107,8 @@ decode_filename(u32 *p, char **namp, int *lenp)
107 return p; 107 return p;
108} 108}
109 109
110static inline u32 * 110static inline __be32 *
111decode_sattr3(u32 *p, struct iattr *iap) 111decode_sattr3(__be32 *p, struct iattr *iap)
112{ 112{
113 u32 tmp; 113 u32 tmp;
114 114
@@ -153,8 +153,8 @@ decode_sattr3(u32 *p, struct iattr *iap)
153 return p; 153 return p;
154} 154}
155 155
156static inline u32 * 156static inline __be32 *
157encode_fattr3(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp, 157encode_fattr3(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp,
158 struct kstat *stat) 158 struct kstat *stat)
159{ 159{
160 struct dentry *dentry = fhp->fh_dentry; 160 struct dentry *dentry = fhp->fh_dentry;
@@ -186,8 +186,8 @@ encode_fattr3(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp,
186 return p; 186 return p;
187} 187}
188 188
189static inline u32 * 189static inline __be32 *
190encode_saved_post_attr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp) 190encode_saved_post_attr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp)
191{ 191{
192 struct inode *inode = fhp->fh_dentry->d_inode; 192 struct inode *inode = fhp->fh_dentry->d_inode;
193 193
@@ -224,8 +224,8 @@ encode_saved_post_attr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp)
224 * The inode may be NULL if the call failed because of a stale file 224 * The inode may be NULL if the call failed because of a stale file
225 * handle. In this case, no attributes are returned. 225 * handle. In this case, no attributes are returned.
226 */ 226 */
227static u32 * 227static __be32 *
228encode_post_op_attr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp) 228encode_post_op_attr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp)
229{ 229{
230 struct dentry *dentry = fhp->fh_dentry; 230 struct dentry *dentry = fhp->fh_dentry;
231 if (dentry && dentry->d_inode != NULL) { 231 if (dentry && dentry->d_inode != NULL) {
@@ -243,8 +243,8 @@ encode_post_op_attr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp)
243} 243}
244 244
245/* Helper for NFSv3 ACLs */ 245/* Helper for NFSv3 ACLs */
246u32 * 246__be32 *
247nfs3svc_encode_post_op_attr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp) 247nfs3svc_encode_post_op_attr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp)
248{ 248{
249 return encode_post_op_attr(rqstp, p, fhp); 249 return encode_post_op_attr(rqstp, p, fhp);
250} 250}
@@ -252,8 +252,8 @@ nfs3svc_encode_post_op_attr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp)
252/* 252/*
253 * Enocde weak cache consistency data 253 * Enocde weak cache consistency data
254 */ 254 */
255static u32 * 255static __be32 *
256encode_wcc_data(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp) 256encode_wcc_data(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp)
257{ 257{
258 struct dentry *dentry = fhp->fh_dentry; 258 struct dentry *dentry = fhp->fh_dentry;
259 259
@@ -278,7 +278,7 @@ encode_wcc_data(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp)
278 * XDR decode functions 278 * XDR decode functions
279 */ 279 */
280int 280int
281nfs3svc_decode_fhandle(struct svc_rqst *rqstp, u32 *p, struct nfsd_fhandle *args) 281nfs3svc_decode_fhandle(struct svc_rqst *rqstp, __be32 *p, struct nfsd_fhandle *args)
282{ 282{
283 if (!(p = decode_fh(p, &args->fh))) 283 if (!(p = decode_fh(p, &args->fh)))
284 return 0; 284 return 0;
@@ -286,7 +286,7 @@ nfs3svc_decode_fhandle(struct svc_rqst *rqstp, u32 *p, struct nfsd_fhandle *args
286} 286}
287 287
288int 288int
289nfs3svc_decode_sattrargs(struct svc_rqst *rqstp, u32 *p, 289nfs3svc_decode_sattrargs(struct svc_rqst *rqstp, __be32 *p,
290 struct nfsd3_sattrargs *args) 290 struct nfsd3_sattrargs *args)
291{ 291{
292 if (!(p = decode_fh(p, &args->fh)) 292 if (!(p = decode_fh(p, &args->fh))
@@ -303,7 +303,7 @@ nfs3svc_decode_sattrargs(struct svc_rqst *rqstp, u32 *p,
303} 303}
304 304
305int 305int
306nfs3svc_decode_diropargs(struct svc_rqst *rqstp, u32 *p, 306nfs3svc_decode_diropargs(struct svc_rqst *rqstp, __be32 *p,
307 struct nfsd3_diropargs *args) 307 struct nfsd3_diropargs *args)
308{ 308{
309 if (!(p = decode_fh(p, &args->fh)) 309 if (!(p = decode_fh(p, &args->fh))
@@ -314,7 +314,7 @@ nfs3svc_decode_diropargs(struct svc_rqst *rqstp, u32 *p,
314} 314}
315 315
316int 316int
317nfs3svc_decode_accessargs(struct svc_rqst *rqstp, u32 *p, 317nfs3svc_decode_accessargs(struct svc_rqst *rqstp, __be32 *p,
318 struct nfsd3_accessargs *args) 318 struct nfsd3_accessargs *args)
319{ 319{
320 if (!(p = decode_fh(p, &args->fh))) 320 if (!(p = decode_fh(p, &args->fh)))
@@ -325,11 +325,12 @@ nfs3svc_decode_accessargs(struct svc_rqst *rqstp, u32 *p,
325} 325}
326 326
327int 327int
328nfs3svc_decode_readargs(struct svc_rqst *rqstp, u32 *p, 328nfs3svc_decode_readargs(struct svc_rqst *rqstp, __be32 *p,
329 struct nfsd3_readargs *args) 329 struct nfsd3_readargs *args)
330{ 330{
331 unsigned int len; 331 unsigned int len;
332 int v,pn; 332 int v,pn;
333 u32 max_blocksize = svc_max_payload(rqstp);
333 334
334 if (!(p = decode_fh(p, &args->fh)) 335 if (!(p = decode_fh(p, &args->fh))
335 || !(p = xdr_decode_hyper(p, &args->offset))) 336 || !(p = xdr_decode_hyper(p, &args->offset)))
@@ -337,17 +338,16 @@ nfs3svc_decode_readargs(struct svc_rqst *rqstp, u32 *p,
337 338
338 len = args->count = ntohl(*p++); 339 len = args->count = ntohl(*p++);
339 340
340 if (len > NFSSVC_MAXBLKSIZE) 341 if (len > max_blocksize)
341 len = NFSSVC_MAXBLKSIZE; 342 len = max_blocksize;
342 343
343 /* set up the kvec */ 344 /* set up the kvec */
344 v=0; 345 v=0;
345 while (len > 0) { 346 while (len > 0) {
346 pn = rqstp->rq_resused; 347 pn = rqstp->rq_resused++;
347 svc_take_page(rqstp); 348 rqstp->rq_vec[v].iov_base = page_address(rqstp->rq_respages[pn]);
348 args->vec[v].iov_base = page_address(rqstp->rq_respages[pn]); 349 rqstp->rq_vec[v].iov_len = len < PAGE_SIZE? len : PAGE_SIZE;
349 args->vec[v].iov_len = len < PAGE_SIZE? len : PAGE_SIZE; 350 len -= rqstp->rq_vec[v].iov_len;
350 len -= args->vec[v].iov_len;
351 v++; 351 v++;
352 } 352 }
353 args->vlen = v; 353 args->vlen = v;
@@ -355,10 +355,11 @@ nfs3svc_decode_readargs(struct svc_rqst *rqstp, u32 *p,
355} 355}
356 356
357int 357int
358nfs3svc_decode_writeargs(struct svc_rqst *rqstp, u32 *p, 358nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p,
359 struct nfsd3_writeargs *args) 359 struct nfsd3_writeargs *args)
360{ 360{
361 unsigned int len, v, hdr; 361 unsigned int len, v, hdr;
362 u32 max_blocksize = svc_max_payload(rqstp);
362 363
363 if (!(p = decode_fh(p, &args->fh)) 364 if (!(p = decode_fh(p, &args->fh))
364 || !(p = xdr_decode_hyper(p, &args->offset))) 365 || !(p = xdr_decode_hyper(p, &args->offset)))
@@ -373,26 +374,26 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, u32 *p,
373 rqstp->rq_arg.len - hdr < len) 374 rqstp->rq_arg.len - hdr < len)
374 return 0; 375 return 0;
375 376
376 args->vec[0].iov_base = (void*)p; 377 rqstp->rq_vec[0].iov_base = (void*)p;
377 args->vec[0].iov_len = rqstp->rq_arg.head[0].iov_len - hdr; 378 rqstp->rq_vec[0].iov_len = rqstp->rq_arg.head[0].iov_len - hdr;
378 379
379 if (len > NFSSVC_MAXBLKSIZE) 380 if (len > max_blocksize)
380 len = NFSSVC_MAXBLKSIZE; 381 len = max_blocksize;
381 v= 0; 382 v= 0;
382 while (len > args->vec[v].iov_len) { 383 while (len > rqstp->rq_vec[v].iov_len) {
383 len -= args->vec[v].iov_len; 384 len -= rqstp->rq_vec[v].iov_len;
384 v++; 385 v++;
385 args->vec[v].iov_base = page_address(rqstp->rq_argpages[v]); 386 rqstp->rq_vec[v].iov_base = page_address(rqstp->rq_pages[v]);
386 args->vec[v].iov_len = PAGE_SIZE; 387 rqstp->rq_vec[v].iov_len = PAGE_SIZE;
387 } 388 }
388 args->vec[v].iov_len = len; 389 rqstp->rq_vec[v].iov_len = len;
389 args->vlen = v+1; 390 args->vlen = v+1;
390 391
391 return args->count == args->len && args->vec[0].iov_len > 0; 392 return args->count == args->len && rqstp->rq_vec[0].iov_len > 0;
392} 393}
393 394
394int 395int
395nfs3svc_decode_createargs(struct svc_rqst *rqstp, u32 *p, 396nfs3svc_decode_createargs(struct svc_rqst *rqstp, __be32 *p,
396 struct nfsd3_createargs *args) 397 struct nfsd3_createargs *args)
397{ 398{
398 if (!(p = decode_fh(p, &args->fh)) 399 if (!(p = decode_fh(p, &args->fh))
@@ -416,7 +417,7 @@ nfs3svc_decode_createargs(struct svc_rqst *rqstp, u32 *p,
416 return xdr_argsize_check(rqstp, p); 417 return xdr_argsize_check(rqstp, p);
417} 418}
418int 419int
419nfs3svc_decode_mkdirargs(struct svc_rqst *rqstp, u32 *p, 420nfs3svc_decode_mkdirargs(struct svc_rqst *rqstp, __be32 *p,
420 struct nfsd3_createargs *args) 421 struct nfsd3_createargs *args)
421{ 422{
422 if (!(p = decode_fh(p, &args->fh)) 423 if (!(p = decode_fh(p, &args->fh))
@@ -428,7 +429,7 @@ nfs3svc_decode_mkdirargs(struct svc_rqst *rqstp, u32 *p,
428} 429}
429 430
430int 431int
431nfs3svc_decode_symlinkargs(struct svc_rqst *rqstp, u32 *p, 432nfs3svc_decode_symlinkargs(struct svc_rqst *rqstp, __be32 *p,
432 struct nfsd3_symlinkargs *args) 433 struct nfsd3_symlinkargs *args)
433{ 434{
434 unsigned int len; 435 unsigned int len;
@@ -446,11 +447,11 @@ nfs3svc_decode_symlinkargs(struct svc_rqst *rqstp, u32 *p,
446 * This page appears in the rq_res.pages list, but as pages_len is always 447 * This page appears in the rq_res.pages list, but as pages_len is always
447 * 0, it won't get in the way 448 * 0, it won't get in the way
448 */ 449 */
449 svc_take_page(rqstp);
450 len = ntohl(*p++); 450 len = ntohl(*p++);
451 if (len == 0 || len > NFS3_MAXPATHLEN || len >= PAGE_SIZE) 451 if (len == 0 || len > NFS3_MAXPATHLEN || len >= PAGE_SIZE)
452 return 0; 452 return 0;
453 args->tname = new = page_address(rqstp->rq_respages[rqstp->rq_resused-1]); 453 args->tname = new =
454 page_address(rqstp->rq_respages[rqstp->rq_resused++]);
454 args->tlen = len; 455 args->tlen = len;
455 /* first copy and check from the first page */ 456 /* first copy and check from the first page */
456 old = (char*)p; 457 old = (char*)p;
@@ -480,7 +481,7 @@ nfs3svc_decode_symlinkargs(struct svc_rqst *rqstp, u32 *p,
480} 481}
481 482
482int 483int
483nfs3svc_decode_mknodargs(struct svc_rqst *rqstp, u32 *p, 484nfs3svc_decode_mknodargs(struct svc_rqst *rqstp, __be32 *p,
484 struct nfsd3_mknodargs *args) 485 struct nfsd3_mknodargs *args)
485{ 486{
486 if (!(p = decode_fh(p, &args->fh)) 487 if (!(p = decode_fh(p, &args->fh))
@@ -504,7 +505,7 @@ nfs3svc_decode_mknodargs(struct svc_rqst *rqstp, u32 *p,
504} 505}
505 506
506int 507int
507nfs3svc_decode_renameargs(struct svc_rqst *rqstp, u32 *p, 508nfs3svc_decode_renameargs(struct svc_rqst *rqstp, __be32 *p,
508 struct nfsd3_renameargs *args) 509 struct nfsd3_renameargs *args)
509{ 510{
510 if (!(p = decode_fh(p, &args->ffh)) 511 if (!(p = decode_fh(p, &args->ffh))
@@ -517,19 +518,19 @@ nfs3svc_decode_renameargs(struct svc_rqst *rqstp, u32 *p,
517} 518}
518 519
519int 520int
520nfs3svc_decode_readlinkargs(struct svc_rqst *rqstp, u32 *p, 521nfs3svc_decode_readlinkargs(struct svc_rqst *rqstp, __be32 *p,
521 struct nfsd3_readlinkargs *args) 522 struct nfsd3_readlinkargs *args)
522{ 523{
523 if (!(p = decode_fh(p, &args->fh))) 524 if (!(p = decode_fh(p, &args->fh)))
524 return 0; 525 return 0;
525 svc_take_page(rqstp); 526 args->buffer =
526 args->buffer = page_address(rqstp->rq_respages[rqstp->rq_resused-1]); 527 page_address(rqstp->rq_respages[rqstp->rq_resused++]);
527 528
528 return xdr_argsize_check(rqstp, p); 529 return xdr_argsize_check(rqstp, p);
529} 530}
530 531
531int 532int
532nfs3svc_decode_linkargs(struct svc_rqst *rqstp, u32 *p, 533nfs3svc_decode_linkargs(struct svc_rqst *rqstp, __be32 *p,
533 struct nfsd3_linkargs *args) 534 struct nfsd3_linkargs *args)
534{ 535{
535 if (!(p = decode_fh(p, &args->ffh)) 536 if (!(p = decode_fh(p, &args->ffh))
@@ -541,7 +542,7 @@ nfs3svc_decode_linkargs(struct svc_rqst *rqstp, u32 *p,
541} 542}
542 543
543int 544int
544nfs3svc_decode_readdirargs(struct svc_rqst *rqstp, u32 *p, 545nfs3svc_decode_readdirargs(struct svc_rqst *rqstp, __be32 *p,
545 struct nfsd3_readdirargs *args) 546 struct nfsd3_readdirargs *args)
546{ 547{
547 if (!(p = decode_fh(p, &args->fh))) 548 if (!(p = decode_fh(p, &args->fh)))
@@ -554,17 +555,18 @@ nfs3svc_decode_readdirargs(struct svc_rqst *rqstp, u32 *p,
554 if (args->count > PAGE_SIZE) 555 if (args->count > PAGE_SIZE)
555 args->count = PAGE_SIZE; 556 args->count = PAGE_SIZE;
556 557
557 svc_take_page(rqstp); 558 args->buffer =
558 args->buffer = page_address(rqstp->rq_respages[rqstp->rq_resused-1]); 559 page_address(rqstp->rq_respages[rqstp->rq_resused++]);
559 560
560 return xdr_argsize_check(rqstp, p); 561 return xdr_argsize_check(rqstp, p);
561} 562}
562 563
563int 564int
564nfs3svc_decode_readdirplusargs(struct svc_rqst *rqstp, u32 *p, 565nfs3svc_decode_readdirplusargs(struct svc_rqst *rqstp, __be32 *p,
565 struct nfsd3_readdirargs *args) 566 struct nfsd3_readdirargs *args)
566{ 567{
567 int len, pn; 568 int len, pn;
569 u32 max_blocksize = svc_max_payload(rqstp);
568 570
569 if (!(p = decode_fh(p, &args->fh))) 571 if (!(p = decode_fh(p, &args->fh)))
570 return 0; 572 return 0;
@@ -573,13 +575,12 @@ nfs3svc_decode_readdirplusargs(struct svc_rqst *rqstp, u32 *p,
573 args->dircount = ntohl(*p++); 575 args->dircount = ntohl(*p++);
574 args->count = ntohl(*p++); 576 args->count = ntohl(*p++);
575 577
576 len = (args->count > NFSSVC_MAXBLKSIZE) ? NFSSVC_MAXBLKSIZE : 578 len = (args->count > max_blocksize) ? max_blocksize :
577 args->count; 579 args->count;
578 args->count = len; 580 args->count = len;
579 581
580 while (len > 0) { 582 while (len > 0) {
581 pn = rqstp->rq_resused; 583 pn = rqstp->rq_resused++;
582 svc_take_page(rqstp);
583 if (!args->buffer) 584 if (!args->buffer)
584 args->buffer = page_address(rqstp->rq_respages[pn]); 585 args->buffer = page_address(rqstp->rq_respages[pn]);
585 len -= PAGE_SIZE; 586 len -= PAGE_SIZE;
@@ -589,7 +590,7 @@ nfs3svc_decode_readdirplusargs(struct svc_rqst *rqstp, u32 *p,
589} 590}
590 591
591int 592int
592nfs3svc_decode_commitargs(struct svc_rqst *rqstp, u32 *p, 593nfs3svc_decode_commitargs(struct svc_rqst *rqstp, __be32 *p,
593 struct nfsd3_commitargs *args) 594 struct nfsd3_commitargs *args)
594{ 595{
595 if (!(p = decode_fh(p, &args->fh))) 596 if (!(p = decode_fh(p, &args->fh)))
@@ -608,14 +609,14 @@ nfs3svc_decode_commitargs(struct svc_rqst *rqstp, u32 *p,
608 * will work properly. 609 * will work properly.
609 */ 610 */
610int 611int
611nfs3svc_encode_voidres(struct svc_rqst *rqstp, u32 *p, void *dummy) 612nfs3svc_encode_voidres(struct svc_rqst *rqstp, __be32 *p, void *dummy)
612{ 613{
613 return xdr_ressize_check(rqstp, p); 614 return xdr_ressize_check(rqstp, p);
614} 615}
615 616
616/* GETATTR */ 617/* GETATTR */
617int 618int
618nfs3svc_encode_attrstat(struct svc_rqst *rqstp, u32 *p, 619nfs3svc_encode_attrstat(struct svc_rqst *rqstp, __be32 *p,
619 struct nfsd3_attrstat *resp) 620 struct nfsd3_attrstat *resp)
620{ 621{
621 if (resp->status == 0) 622 if (resp->status == 0)
@@ -625,7 +626,7 @@ nfs3svc_encode_attrstat(struct svc_rqst *rqstp, u32 *p,
625 626
626/* SETATTR, REMOVE, RMDIR */ 627/* SETATTR, REMOVE, RMDIR */
627int 628int
628nfs3svc_encode_wccstat(struct svc_rqst *rqstp, u32 *p, 629nfs3svc_encode_wccstat(struct svc_rqst *rqstp, __be32 *p,
629 struct nfsd3_attrstat *resp) 630 struct nfsd3_attrstat *resp)
630{ 631{
631 p = encode_wcc_data(rqstp, p, &resp->fh); 632 p = encode_wcc_data(rqstp, p, &resp->fh);
@@ -634,7 +635,7 @@ nfs3svc_encode_wccstat(struct svc_rqst *rqstp, u32 *p,
634 635
635/* LOOKUP */ 636/* LOOKUP */
636int 637int
637nfs3svc_encode_diropres(struct svc_rqst *rqstp, u32 *p, 638nfs3svc_encode_diropres(struct svc_rqst *rqstp, __be32 *p,
638 struct nfsd3_diropres *resp) 639 struct nfsd3_diropres *resp)
639{ 640{
640 if (resp->status == 0) { 641 if (resp->status == 0) {
@@ -647,7 +648,7 @@ nfs3svc_encode_diropres(struct svc_rqst *rqstp, u32 *p,
647 648
648/* ACCESS */ 649/* ACCESS */
649int 650int
650nfs3svc_encode_accessres(struct svc_rqst *rqstp, u32 *p, 651nfs3svc_encode_accessres(struct svc_rqst *rqstp, __be32 *p,
651 struct nfsd3_accessres *resp) 652 struct nfsd3_accessres *resp)
652{ 653{
653 p = encode_post_op_attr(rqstp, p, &resp->fh); 654 p = encode_post_op_attr(rqstp, p, &resp->fh);
@@ -658,7 +659,7 @@ nfs3svc_encode_accessres(struct svc_rqst *rqstp, u32 *p,
658 659
659/* READLINK */ 660/* READLINK */
660int 661int
661nfs3svc_encode_readlinkres(struct svc_rqst *rqstp, u32 *p, 662nfs3svc_encode_readlinkres(struct svc_rqst *rqstp, __be32 *p,
662 struct nfsd3_readlinkres *resp) 663 struct nfsd3_readlinkres *resp)
663{ 664{
664 p = encode_post_op_attr(rqstp, p, &resp->fh); 665 p = encode_post_op_attr(rqstp, p, &resp->fh);
@@ -668,7 +669,6 @@ nfs3svc_encode_readlinkres(struct svc_rqst *rqstp, u32 *p,
668 rqstp->rq_res.page_len = resp->len; 669 rqstp->rq_res.page_len = resp->len;
669 if (resp->len & 3) { 670 if (resp->len & 3) {
670 /* need to pad the tail */ 671 /* need to pad the tail */
671 rqstp->rq_restailpage = 0;
672 rqstp->rq_res.tail[0].iov_base = p; 672 rqstp->rq_res.tail[0].iov_base = p;
673 *p = 0; 673 *p = 0;
674 rqstp->rq_res.tail[0].iov_len = 4 - (resp->len&3); 674 rqstp->rq_res.tail[0].iov_len = 4 - (resp->len&3);
@@ -680,7 +680,7 @@ nfs3svc_encode_readlinkres(struct svc_rqst *rqstp, u32 *p,
680 680
681/* READ */ 681/* READ */
682int 682int
683nfs3svc_encode_readres(struct svc_rqst *rqstp, u32 *p, 683nfs3svc_encode_readres(struct svc_rqst *rqstp, __be32 *p,
684 struct nfsd3_readres *resp) 684 struct nfsd3_readres *resp)
685{ 685{
686 p = encode_post_op_attr(rqstp, p, &resp->fh); 686 p = encode_post_op_attr(rqstp, p, &resp->fh);
@@ -693,7 +693,6 @@ nfs3svc_encode_readres(struct svc_rqst *rqstp, u32 *p,
693 rqstp->rq_res.page_len = resp->count; 693 rqstp->rq_res.page_len = resp->count;
694 if (resp->count & 3) { 694 if (resp->count & 3) {
695 /* need to pad the tail */ 695 /* need to pad the tail */
696 rqstp->rq_restailpage = 0;
697 rqstp->rq_res.tail[0].iov_base = p; 696 rqstp->rq_res.tail[0].iov_base = p;
698 *p = 0; 697 *p = 0;
699 rqstp->rq_res.tail[0].iov_len = 4 - (resp->count & 3); 698 rqstp->rq_res.tail[0].iov_len = 4 - (resp->count & 3);
@@ -705,7 +704,7 @@ nfs3svc_encode_readres(struct svc_rqst *rqstp, u32 *p,
705 704
706/* WRITE */ 705/* WRITE */
707int 706int
708nfs3svc_encode_writeres(struct svc_rqst *rqstp, u32 *p, 707nfs3svc_encode_writeres(struct svc_rqst *rqstp, __be32 *p,
709 struct nfsd3_writeres *resp) 708 struct nfsd3_writeres *resp)
710{ 709{
711 p = encode_wcc_data(rqstp, p, &resp->fh); 710 p = encode_wcc_data(rqstp, p, &resp->fh);
@@ -720,7 +719,7 @@ nfs3svc_encode_writeres(struct svc_rqst *rqstp, u32 *p,
720 719
721/* CREATE, MKDIR, SYMLINK, MKNOD */ 720/* CREATE, MKDIR, SYMLINK, MKNOD */
722int 721int
723nfs3svc_encode_createres(struct svc_rqst *rqstp, u32 *p, 722nfs3svc_encode_createres(struct svc_rqst *rqstp, __be32 *p,
724 struct nfsd3_diropres *resp) 723 struct nfsd3_diropres *resp)
725{ 724{
726 if (resp->status == 0) { 725 if (resp->status == 0) {
@@ -734,7 +733,7 @@ nfs3svc_encode_createres(struct svc_rqst *rqstp, u32 *p,
734 733
735/* RENAME */ 734/* RENAME */
736int 735int
737nfs3svc_encode_renameres(struct svc_rqst *rqstp, u32 *p, 736nfs3svc_encode_renameres(struct svc_rqst *rqstp, __be32 *p,
738 struct nfsd3_renameres *resp) 737 struct nfsd3_renameres *resp)
739{ 738{
740 p = encode_wcc_data(rqstp, p, &resp->ffh); 739 p = encode_wcc_data(rqstp, p, &resp->ffh);
@@ -744,7 +743,7 @@ nfs3svc_encode_renameres(struct svc_rqst *rqstp, u32 *p,
744 743
745/* LINK */ 744/* LINK */
746int 745int
747nfs3svc_encode_linkres(struct svc_rqst *rqstp, u32 *p, 746nfs3svc_encode_linkres(struct svc_rqst *rqstp, __be32 *p,
748 struct nfsd3_linkres *resp) 747 struct nfsd3_linkres *resp)
749{ 748{
750 p = encode_post_op_attr(rqstp, p, &resp->fh); 749 p = encode_post_op_attr(rqstp, p, &resp->fh);
@@ -754,7 +753,7 @@ nfs3svc_encode_linkres(struct svc_rqst *rqstp, u32 *p,
754 753
755/* READDIR */ 754/* READDIR */
756int 755int
757nfs3svc_encode_readdirres(struct svc_rqst *rqstp, u32 *p, 756nfs3svc_encode_readdirres(struct svc_rqst *rqstp, __be32 *p,
758 struct nfsd3_readdirres *resp) 757 struct nfsd3_readdirres *resp)
759{ 758{
760 p = encode_post_op_attr(rqstp, p, &resp->fh); 759 p = encode_post_op_attr(rqstp, p, &resp->fh);
@@ -768,7 +767,6 @@ nfs3svc_encode_readdirres(struct svc_rqst *rqstp, u32 *p,
768 rqstp->rq_res.page_len = (resp->count) << 2; 767 rqstp->rq_res.page_len = (resp->count) << 2;
769 768
770 /* add the 'tail' to the end of the 'head' page - page 0. */ 769 /* add the 'tail' to the end of the 'head' page - page 0. */
771 rqstp->rq_restailpage = 0;
772 rqstp->rq_res.tail[0].iov_base = p; 770 rqstp->rq_res.tail[0].iov_base = p;
773 *p++ = 0; /* no more entries */ 771 *p++ = 0; /* no more entries */
774 *p++ = htonl(resp->common.err == nfserr_eof); 772 *p++ = htonl(resp->common.err == nfserr_eof);
@@ -778,8 +776,8 @@ nfs3svc_encode_readdirres(struct svc_rqst *rqstp, u32 *p,
778 return xdr_ressize_check(rqstp, p); 776 return xdr_ressize_check(rqstp, p);
779} 777}
780 778
781static inline u32 * 779static inline __be32 *
782encode_entry_baggage(struct nfsd3_readdirres *cd, u32 *p, const char *name, 780encode_entry_baggage(struct nfsd3_readdirres *cd, __be32 *p, const char *name,
783 int namlen, ino_t ino) 781 int namlen, ino_t ino)
784{ 782{
785 *p++ = xdr_one; /* mark entry present */ 783 *p++ = xdr_one; /* mark entry present */
@@ -792,8 +790,8 @@ encode_entry_baggage(struct nfsd3_readdirres *cd, u32 *p, const char *name,
792 return p; 790 return p;
793} 791}
794 792
795static inline u32 * 793static inline __be32 *
796encode_entryplus_baggage(struct nfsd3_readdirres *cd, u32 *p, 794encode_entryplus_baggage(struct nfsd3_readdirres *cd, __be32 *p,
797 struct svc_fh *fhp) 795 struct svc_fh *fhp)
798{ 796{
799 p = encode_post_op_attr(cd->rqstp, p, fhp); 797 p = encode_post_op_attr(cd->rqstp, p, fhp);
@@ -855,7 +853,7 @@ encode_entry(struct readdir_cd *ccd, const char *name,
855{ 853{
856 struct nfsd3_readdirres *cd = container_of(ccd, struct nfsd3_readdirres, 854 struct nfsd3_readdirres *cd = container_of(ccd, struct nfsd3_readdirres,
857 common); 855 common);
858 u32 *p = cd->buffer; 856 __be32 *p = cd->buffer;
859 caddr_t curr_page_addr = NULL; 857 caddr_t curr_page_addr = NULL;
860 int pn; /* current page number */ 858 int pn; /* current page number */
861 int slen; /* string (name) length */ 859 int slen; /* string (name) length */
@@ -921,7 +919,7 @@ encode_entry(struct readdir_cd *ccd, const char *name,
921 } else if (cd->rqstp->rq_respages[pn+1] != NULL) { 919 } else if (cd->rqstp->rq_respages[pn+1] != NULL) {
922 /* temporarily encode entry into next page, then move back to 920 /* temporarily encode entry into next page, then move back to
923 * current and next page in rq_respages[] */ 921 * current and next page in rq_respages[] */
924 u32 *p1, *tmp; 922 __be32 *p1, *tmp;
925 int len1, len2; 923 int len1, len2;
926 924
927 /* grab next page for temporary storage of entry */ 925 /* grab next page for temporary storage of entry */
@@ -1011,7 +1009,7 @@ nfs3svc_encode_entry_plus(struct readdir_cd *cd, const char *name,
1011 1009
1012/* FSSTAT */ 1010/* FSSTAT */
1013int 1011int
1014nfs3svc_encode_fsstatres(struct svc_rqst *rqstp, u32 *p, 1012nfs3svc_encode_fsstatres(struct svc_rqst *rqstp, __be32 *p,
1015 struct nfsd3_fsstatres *resp) 1013 struct nfsd3_fsstatres *resp)
1016{ 1014{
1017 struct kstatfs *s = &resp->stats; 1015 struct kstatfs *s = &resp->stats;
@@ -1033,7 +1031,7 @@ nfs3svc_encode_fsstatres(struct svc_rqst *rqstp, u32 *p,
1033 1031
1034/* FSINFO */ 1032/* FSINFO */
1035int 1033int
1036nfs3svc_encode_fsinfores(struct svc_rqst *rqstp, u32 *p, 1034nfs3svc_encode_fsinfores(struct svc_rqst *rqstp, __be32 *p,
1037 struct nfsd3_fsinfores *resp) 1035 struct nfsd3_fsinfores *resp)
1038{ 1036{
1039 *p++ = xdr_zero; /* no post_op_attr */ 1037 *p++ = xdr_zero; /* no post_op_attr */
@@ -1057,7 +1055,7 @@ nfs3svc_encode_fsinfores(struct svc_rqst *rqstp, u32 *p,
1057 1055
1058/* PATHCONF */ 1056/* PATHCONF */
1059int 1057int
1060nfs3svc_encode_pathconfres(struct svc_rqst *rqstp, u32 *p, 1058nfs3svc_encode_pathconfres(struct svc_rqst *rqstp, __be32 *p,
1061 struct nfsd3_pathconfres *resp) 1059 struct nfsd3_pathconfres *resp)
1062{ 1060{
1063 *p++ = xdr_zero; /* no post_op_attr */ 1061 *p++ = xdr_zero; /* no post_op_attr */
@@ -1076,7 +1074,7 @@ nfs3svc_encode_pathconfres(struct svc_rqst *rqstp, u32 *p,
1076 1074
1077/* COMMIT */ 1075/* COMMIT */
1078int 1076int
1079nfs3svc_encode_commitres(struct svc_rqst *rqstp, u32 *p, 1077nfs3svc_encode_commitres(struct svc_rqst *rqstp, __be32 *p,
1080 struct nfsd3_commitres *resp) 1078 struct nfsd3_commitres *resp)
1081{ 1079{
1082 p = encode_wcc_data(rqstp, p, &resp->fh); 1080 p = encode_wcc_data(rqstp, p, &resp->fh);
@@ -1092,7 +1090,7 @@ nfs3svc_encode_commitres(struct svc_rqst *rqstp, u32 *p,
1092 * XDR release functions 1090 * XDR release functions
1093 */ 1091 */
1094int 1092int
1095nfs3svc_release_fhandle(struct svc_rqst *rqstp, u32 *p, 1093nfs3svc_release_fhandle(struct svc_rqst *rqstp, __be32 *p,
1096 struct nfsd3_attrstat *resp) 1094 struct nfsd3_attrstat *resp)
1097{ 1095{
1098 fh_put(&resp->fh); 1096 fh_put(&resp->fh);
@@ -1100,7 +1098,7 @@ nfs3svc_release_fhandle(struct svc_rqst *rqstp, u32 *p,
1100} 1098}
1101 1099
1102int 1100int
1103nfs3svc_release_fhandle2(struct svc_rqst *rqstp, u32 *p, 1101nfs3svc_release_fhandle2(struct svc_rqst *rqstp, __be32 *p,
1104 struct nfsd3_fhandle_pair *resp) 1102 struct nfsd3_fhandle_pair *resp)
1105{ 1103{
1106 fh_put(&resp->fh1); 1104 fh_put(&resp->fh1);
diff --git a/fs/nfsd/nfs4acl.c b/fs/nfsd/nfs4acl.c
index edb107e61b91..5d94555cdc83 100644
--- a/fs/nfsd/nfs4acl.c
+++ b/fs/nfsd/nfs4acl.c
@@ -63,6 +63,8 @@
63#define NFS4_INHERITANCE_FLAGS (NFS4_ACE_FILE_INHERIT_ACE \ 63#define NFS4_INHERITANCE_FLAGS (NFS4_ACE_FILE_INHERIT_ACE \
64 | NFS4_ACE_DIRECTORY_INHERIT_ACE | NFS4_ACE_INHERIT_ONLY_ACE) 64 | NFS4_ACE_DIRECTORY_INHERIT_ACE | NFS4_ACE_INHERIT_ONLY_ACE)
65 65
66#define NFS4_SUPPORTED_FLAGS (NFS4_INHERITANCE_FLAGS | NFS4_ACE_IDENTIFIER_GROUP)
67
66#define MASK_EQUAL(mask1, mask2) \ 68#define MASK_EQUAL(mask1, mask2) \
67 ( ((mask1) & NFS4_ACE_MASK_ALL) == ((mask2) & NFS4_ACE_MASK_ALL) ) 69 ( ((mask1) & NFS4_ACE_MASK_ALL) == ((mask2) & NFS4_ACE_MASK_ALL) )
68 70
@@ -96,24 +98,26 @@ deny_mask(u32 allow_mask, unsigned int flags)
96/* XXX: modify functions to return NFS errors; they're only ever 98/* XXX: modify functions to return NFS errors; they're only ever
97 * used by nfs code, after all.... */ 99 * used by nfs code, after all.... */
98 100
99static int 101/* We only map from NFSv4 to POSIX ACLs when setting ACLs, when we err on the
100mode_from_nfs4(u32 perm, unsigned short *mode, unsigned int flags) 102 * side of being more restrictive, so the mode bit mapping below is
103 * pessimistic. An optimistic version would be needed to handle DENY's,
104 * but we espect to coalesce all ALLOWs and DENYs before mapping to mode
105 * bits. */
106
107static void
108low_mode_from_nfs4(u32 perm, unsigned short *mode, unsigned int flags)
101{ 109{
102 u32 ignore = 0; 110 u32 write_mode = NFS4_WRITE_MODE;
103 111
104 if (!(flags & NFS4_ACL_DIR)) 112 if (flags & NFS4_ACL_DIR)
105 ignore |= NFS4_ACE_DELETE_CHILD; /* ignore it */ 113 write_mode |= NFS4_ACE_DELETE_CHILD;
106 perm |= ignore;
107 *mode = 0; 114 *mode = 0;
108 if ((perm & NFS4_READ_MODE) == NFS4_READ_MODE) 115 if ((perm & NFS4_READ_MODE) == NFS4_READ_MODE)
109 *mode |= ACL_READ; 116 *mode |= ACL_READ;
110 if ((perm & NFS4_WRITE_MODE) == NFS4_WRITE_MODE) 117 if ((perm & write_mode) == write_mode)
111 *mode |= ACL_WRITE; 118 *mode |= ACL_WRITE;
112 if ((perm & NFS4_EXECUTE_MODE) == NFS4_EXECUTE_MODE) 119 if ((perm & NFS4_EXECUTE_MODE) == NFS4_EXECUTE_MODE)
113 *mode |= ACL_EXECUTE; 120 *mode |= ACL_EXECUTE;
114 if (!MASK_EQUAL(perm, ignore|mask_from_posix(*mode, flags)))
115 return -EINVAL;
116 return 0;
117} 121}
118 122
119struct ace_container { 123struct ace_container {
@@ -338,38 +342,6 @@ sort_pacl(struct posix_acl *pacl)
338 return; 342 return;
339} 343}
340 344
341static int
342write_pace(struct nfs4_ace *ace, struct posix_acl *pacl,
343 struct posix_acl_entry **pace, short tag, unsigned int flags)
344{
345 struct posix_acl_entry *this = *pace;
346
347 if (*pace == pacl->a_entries + pacl->a_count)
348 return -EINVAL; /* fell off the end */
349 (*pace)++;
350 this->e_tag = tag;
351 if (tag == ACL_USER_OBJ)
352 flags |= NFS4_ACL_OWNER;
353 if (mode_from_nfs4(ace->access_mask, &this->e_perm, flags))
354 return -EINVAL;
355 this->e_id = (tag == ACL_USER || tag == ACL_GROUP ?
356 ace->who : ACL_UNDEFINED_ID);
357 return 0;
358}
359
360static struct nfs4_ace *
361get_next_v4_ace(struct list_head **p, struct list_head *head)
362{
363 struct nfs4_ace *ace;
364
365 *p = (*p)->next;
366 if (*p == head)
367 return NULL;
368 ace = list_entry(*p, struct nfs4_ace, l_ace);
369
370 return ace;
371}
372
373int 345int
374nfs4_acl_nfsv4_to_posix(struct nfs4_acl *acl, struct posix_acl **pacl, 346nfs4_acl_nfsv4_to_posix(struct nfs4_acl *acl, struct posix_acl **pacl,
375 struct posix_acl **dpacl, unsigned int flags) 347 struct posix_acl **dpacl, unsigned int flags)
@@ -385,42 +357,23 @@ nfs4_acl_nfsv4_to_posix(struct nfs4_acl *acl, struct posix_acl **pacl,
385 goto out; 357 goto out;
386 358
387 error = nfs4_acl_split(acl, dacl); 359 error = nfs4_acl_split(acl, dacl);
388 if (error < 0) 360 if (error)
389 goto out_acl; 361 goto out_acl;
390 362
391 if (pacl != NULL) { 363 *pacl = _nfsv4_to_posix_one(acl, flags);
392 if (acl->naces == 0) { 364 if (IS_ERR(*pacl)) {
393 error = -ENODATA; 365 error = PTR_ERR(*pacl);
394 goto try_dpacl; 366 *pacl = NULL;
395 } 367 goto out_acl;
396
397 *pacl = _nfsv4_to_posix_one(acl, flags);
398 if (IS_ERR(*pacl)) {
399 error = PTR_ERR(*pacl);
400 *pacl = NULL;
401 goto out_acl;
402 }
403 } 368 }
404 369
405try_dpacl: 370 *dpacl = _nfsv4_to_posix_one(dacl, flags);
406 if (dpacl != NULL) { 371 if (IS_ERR(*dpacl)) {
407 if (dacl->naces == 0) { 372 error = PTR_ERR(*dpacl);
408 if (pacl == NULL || *pacl == NULL) 373 *dpacl = NULL;
409 error = -ENODATA;
410 goto out_acl;
411 }
412
413 error = 0;
414 *dpacl = _nfsv4_to_posix_one(dacl, flags);
415 if (IS_ERR(*dpacl)) {
416 error = PTR_ERR(*dpacl);
417 *dpacl = NULL;
418 goto out_acl;
419 }
420 } 374 }
421
422out_acl: 375out_acl:
423 if (error && pacl) { 376 if (error) {
424 posix_acl_release(*pacl); 377 posix_acl_release(*pacl);
425 *pacl = NULL; 378 *pacl = NULL;
426 } 379 }
@@ -429,349 +382,311 @@ out:
429 return error; 382 return error;
430} 383}
431 384
385/*
386 * While processing the NFSv4 ACE, this maintains bitmasks representing
387 * which permission bits have been allowed and which denied to a given
388 * entity: */
389struct posix_ace_state {
390 u32 allow;
391 u32 deny;
392};
393
394struct posix_user_ace_state {
395 uid_t uid;
396 struct posix_ace_state perms;
397};
398
399struct posix_ace_state_array {
400 int n;
401 struct posix_user_ace_state aces[];
402};
403
404/*
405 * While processing the NFSv4 ACE, this maintains the partial permissions
406 * calculated so far: */
407
408struct posix_acl_state {
409 struct posix_ace_state owner;
410 struct posix_ace_state group;
411 struct posix_ace_state other;
412 struct posix_ace_state everyone;
413 struct posix_ace_state mask; /* Deny unused in this case */
414 struct posix_ace_state_array *users;
415 struct posix_ace_state_array *groups;
416};
417
432static int 418static int
433same_who(struct nfs4_ace *a, struct nfs4_ace *b) 419init_state(struct posix_acl_state *state, int cnt)
434{ 420{
435 return a->whotype == b->whotype && 421 int alloc;
436 (a->whotype != NFS4_ACL_WHO_NAMED || a->who == b->who); 422
423 memset(state, 0, sizeof(struct posix_acl_state));
424 /*
425 * In the worst case, each individual acl could be for a distinct
426 * named user or group, but we don't no which, so we allocate
427 * enough space for either:
428 */
429 alloc = sizeof(struct posix_ace_state_array)
430 + cnt*sizeof(struct posix_ace_state);
431 state->users = kzalloc(alloc, GFP_KERNEL);
432 if (!state->users)
433 return -ENOMEM;
434 state->groups = kzalloc(alloc, GFP_KERNEL);
435 if (!state->groups) {
436 kfree(state->users);
437 return -ENOMEM;
438 }
439 return 0;
437} 440}
438 441
439static int 442static void
440complementary_ace_pair(struct nfs4_ace *allow, struct nfs4_ace *deny, 443free_state(struct posix_acl_state *state) {
441 unsigned int flags) 444 kfree(state->users);
442{ 445 kfree(state->groups);
443 int ignore = 0;
444 if (!(flags & NFS4_ACL_DIR))
445 ignore |= NFS4_ACE_DELETE_CHILD;
446 return MASK_EQUAL(ignore|deny_mask(allow->access_mask, flags),
447 ignore|deny->access_mask) &&
448 allow->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE &&
449 deny->type == NFS4_ACE_ACCESS_DENIED_ACE_TYPE &&
450 allow->flag == deny->flag &&
451 same_who(allow, deny);
452} 446}
453 447
454static inline int 448static inline void add_to_mask(struct posix_acl_state *state, struct posix_ace_state *astate)
455user_obj_from_v4(struct nfs4_acl *n4acl, struct list_head **p,
456 struct posix_acl *pacl, struct posix_acl_entry **pace,
457 unsigned int flags)
458{ 449{
459 int error = -EINVAL; 450 state->mask.allow |= astate->allow;
460 struct nfs4_ace *ace, *ace2;
461
462 ace = get_next_v4_ace(p, &n4acl->ace_head);
463 if (ace == NULL)
464 goto out;
465 if (ace2type(ace) != ACL_USER_OBJ)
466 goto out;
467 error = write_pace(ace, pacl, pace, ACL_USER_OBJ, flags);
468 if (error < 0)
469 goto out;
470 error = -EINVAL;
471 ace2 = get_next_v4_ace(p, &n4acl->ace_head);
472 if (ace2 == NULL)
473 goto out;
474 if (!complementary_ace_pair(ace, ace2, flags))
475 goto out;
476 error = 0;
477out:
478 return error;
479} 451}
480 452
481static inline int 453/*
482users_from_v4(struct nfs4_acl *n4acl, struct list_head **p, 454 * Certain bits (SYNCHRONIZE, DELETE, WRITE_OWNER, READ/WRITE_NAMED_ATTRS,
483 struct nfs4_ace **mask_ace, 455 * READ_ATTRIBUTES, READ_ACL) are currently unenforceable and don't translate
484 struct posix_acl *pacl, struct posix_acl_entry **pace, 456 * to traditional read/write/execute permissions.
485 unsigned int flags) 457 *
486{ 458 * It's problematic to reject acls that use certain mode bits, because it
487 int error = -EINVAL; 459 * places the burden on users to learn the rules about which bits one
488 struct nfs4_ace *ace, *ace2; 460 * particular server sets, without giving the user a lot of help--we return an
461 * error that could mean any number of different things. To make matters
462 * worse, the problematic bits might be introduced by some application that's
463 * automatically mapping from some other acl model.
464 *
465 * So wherever possible we accept anything, possibly erring on the side of
466 * denying more permissions than necessary.
467 *
468 * However we do reject *explicit* DENY's of a few bits representing
469 * permissions we could never deny:
470 */
489 471
490 ace = get_next_v4_ace(p, &n4acl->ace_head); 472static inline int check_deny(u32 mask, int isowner)
491 if (ace == NULL) 473{
492 goto out; 474 if (mask & (NFS4_ACE_READ_ATTRIBUTES | NFS4_ACE_READ_ACL))
493 while (ace2type(ace) == ACL_USER) { 475 return -EINVAL;
494 if (ace->type != NFS4_ACE_ACCESS_DENIED_ACE_TYPE) 476 if (!isowner)
495 goto out; 477 return 0;
496 if (*mask_ace && 478 if (mask & (NFS4_ACE_WRITE_ATTRIBUTES | NFS4_ACE_WRITE_ACL))
497 !MASK_EQUAL(ace->access_mask, (*mask_ace)->access_mask)) 479 return -EINVAL;
498 goto out; 480 return 0;
499 *mask_ace = ace;
500 ace = get_next_v4_ace(p, &n4acl->ace_head);
501 if (ace == NULL)
502 goto out;
503 if (ace->type != NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE)
504 goto out;
505 error = write_pace(ace, pacl, pace, ACL_USER, flags);
506 if (error < 0)
507 goto out;
508 error = -EINVAL;
509 ace2 = get_next_v4_ace(p, &n4acl->ace_head);
510 if (ace2 == NULL)
511 goto out;
512 if (!complementary_ace_pair(ace, ace2, flags))
513 goto out;
514 if ((*mask_ace)->flag != ace2->flag ||
515 !same_who(*mask_ace, ace2))
516 goto out;
517 ace = get_next_v4_ace(p, &n4acl->ace_head);
518 if (ace == NULL)
519 goto out;
520 }
521 error = 0;
522out:
523 return error;
524} 481}
525 482
526static inline int 483static struct posix_acl *
527group_obj_and_groups_from_v4(struct nfs4_acl *n4acl, struct list_head **p, 484posix_state_to_acl(struct posix_acl_state *state, unsigned int flags)
528 struct nfs4_ace **mask_ace,
529 struct posix_acl *pacl, struct posix_acl_entry **pace,
530 unsigned int flags)
531{ 485{
532 int error = -EINVAL; 486 struct posix_acl_entry *pace;
533 struct nfs4_ace *ace, *ace2; 487 struct posix_acl *pacl;
534 struct ace_container *ac; 488 int nace;
535 struct list_head group_l; 489 int i, error = 0;
536
537 INIT_LIST_HEAD(&group_l);
538 ace = list_entry(*p, struct nfs4_ace, l_ace);
539
540 /* group owner (mask and allow aces) */
541 490
542 if (pacl->a_count != 3) { 491 nace = 4 + state->users->n + state->groups->n;
543 /* then the group owner should be preceded by mask */ 492 pacl = posix_acl_alloc(nace, GFP_KERNEL);
544 if (ace->type != NFS4_ACE_ACCESS_DENIED_ACE_TYPE) 493 if (!pacl)
545 goto out; 494 return ERR_PTR(-ENOMEM);
546 if (*mask_ace &&
547 !MASK_EQUAL(ace->access_mask, (*mask_ace)->access_mask))
548 goto out;
549 *mask_ace = ace;
550 ace = get_next_v4_ace(p, &n4acl->ace_head);
551 if (ace == NULL)
552 goto out;
553 495
554 if ((*mask_ace)->flag != ace->flag || !same_who(*mask_ace, ace)) 496 pace = pacl->a_entries;
555 goto out; 497 pace->e_tag = ACL_USER_OBJ;
498 error = check_deny(state->owner.deny, 1);
499 if (error)
500 goto out_err;
501 low_mode_from_nfs4(state->owner.allow, &pace->e_perm, flags);
502 pace->e_id = ACL_UNDEFINED_ID;
503
504 for (i=0; i < state->users->n; i++) {
505 pace++;
506 pace->e_tag = ACL_USER;
507 error = check_deny(state->users->aces[i].perms.deny, 0);
508 if (error)
509 goto out_err;
510 low_mode_from_nfs4(state->users->aces[i].perms.allow,
511 &pace->e_perm, flags);
512 pace->e_id = state->users->aces[i].uid;
513 add_to_mask(state, &state->users->aces[i].perms);
556 } 514 }
557 515
558 if (ace2type(ace) != ACL_GROUP_OBJ) 516 pace++;
559 goto out; 517 pace->e_tag = ACL_GROUP_OBJ;
560 518 error = check_deny(state->group.deny, 0);
561 ac = kmalloc(sizeof(*ac), GFP_KERNEL); 519 if (error)
562 error = -ENOMEM; 520 goto out_err;
563 if (ac == NULL) 521 low_mode_from_nfs4(state->group.allow, &pace->e_perm, flags);
564 goto out; 522 pace->e_id = ACL_UNDEFINED_ID;
565 ac->ace = ace; 523 add_to_mask(state, &state->group);
566 list_add_tail(&ac->ace_l, &group_l); 524
567 525 for (i=0; i < state->groups->n; i++) {
568 error = -EINVAL; 526 pace++;
569 if (ace->type != NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) 527 pace->e_tag = ACL_GROUP;
570 goto out; 528 error = check_deny(state->groups->aces[i].perms.deny, 0);
571 529 if (error)
572 error = write_pace(ace, pacl, pace, ACL_GROUP_OBJ, flags); 530 goto out_err;
573 if (error < 0) 531 low_mode_from_nfs4(state->groups->aces[i].perms.allow,
574 goto out; 532 &pace->e_perm, flags);
575 533 pace->e_id = state->groups->aces[i].uid;
576 error = -EINVAL; 534 add_to_mask(state, &state->groups->aces[i].perms);
577 ace = get_next_v4_ace(p, &n4acl->ace_head); 535 }
578 if (ace == NULL)
579 goto out;
580
581 /* groups (mask and allow aces) */
582
583 while (ace2type(ace) == ACL_GROUP) {
584 if (*mask_ace == NULL)
585 goto out;
586
587 if (ace->type != NFS4_ACE_ACCESS_DENIED_ACE_TYPE ||
588 !MASK_EQUAL(ace->access_mask, (*mask_ace)->access_mask))
589 goto out;
590 *mask_ace = ace;
591 536
592 ace = get_next_v4_ace(p, &n4acl->ace_head); 537 pace++;
593 if (ace == NULL) 538 pace->e_tag = ACL_MASK;
594 goto out; 539 low_mode_from_nfs4(state->mask.allow, &pace->e_perm, flags);
595 ac = kmalloc(sizeof(*ac), GFP_KERNEL); 540 pace->e_id = ACL_UNDEFINED_ID;
596 error = -ENOMEM;
597 if (ac == NULL)
598 goto out;
599 error = -EINVAL;
600 if (ace->type != NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE ||
601 !same_who(ace, *mask_ace))
602 goto out;
603 541
604 ac->ace = ace; 542 pace++;
605 list_add_tail(&ac->ace_l, &group_l); 543 pace->e_tag = ACL_OTHER;
544 error = check_deny(state->other.deny, 0);
545 if (error)
546 goto out_err;
547 low_mode_from_nfs4(state->other.allow, &pace->e_perm, flags);
548 pace->e_id = ACL_UNDEFINED_ID;
606 549
607 error = write_pace(ace, pacl, pace, ACL_GROUP, flags); 550 return pacl;
608 if (error < 0) 551out_err:
609 goto out; 552 posix_acl_release(pacl);
610 error = -EINVAL; 553 return ERR_PTR(error);
611 ace = get_next_v4_ace(p, &n4acl->ace_head); 554}
612 if (ace == NULL)
613 goto out;
614 }
615 555
616 /* group owner (deny ace) */ 556static inline void allow_bits(struct posix_ace_state *astate, u32 mask)
557{
558 /* Allow all bits in the mask not already denied: */
559 astate->allow |= mask & ~astate->deny;
560}
617 561
618 if (ace2type(ace) != ACL_GROUP_OBJ) 562static inline void deny_bits(struct posix_ace_state *astate, u32 mask)
619 goto out; 563{
620 ac = list_entry(group_l.next, struct ace_container, ace_l); 564 /* Deny all bits in the mask not already allowed: */
621 ace2 = ac->ace; 565 astate->deny |= mask & ~astate->allow;
622 if (!complementary_ace_pair(ace2, ace, flags)) 566}
623 goto out;
624 list_del(group_l.next);
625 kfree(ac);
626 567
627 /* groups (deny aces) */ 568static int find_uid(struct posix_acl_state *state, struct posix_ace_state_array *a, uid_t uid)
569{
570 int i;
628 571
629 while (!list_empty(&group_l)) { 572 for (i = 0; i < a->n; i++)
630 ace = get_next_v4_ace(p, &n4acl->ace_head); 573 if (a->aces[i].uid == uid)
631 if (ace == NULL) 574 return i;
632 goto out; 575 /* Not found: */
633 if (ace2type(ace) != ACL_GROUP) 576 a->n++;
634 goto out; 577 a->aces[i].uid = uid;
635 ac = list_entry(group_l.next, struct ace_container, ace_l); 578 a->aces[i].perms.allow = state->everyone.allow;
636 ace2 = ac->ace; 579 a->aces[i].perms.deny = state->everyone.deny;
637 if (!complementary_ace_pair(ace2, ace, flags))
638 goto out;
639 list_del(group_l.next);
640 kfree(ac);
641 }
642 580
643 ace = get_next_v4_ace(p, &n4acl->ace_head); 581 return i;
644 if (ace == NULL)
645 goto out;
646 if (ace2type(ace) != ACL_OTHER)
647 goto out;
648 error = 0;
649out:
650 while (!list_empty(&group_l)) {
651 ac = list_entry(group_l.next, struct ace_container, ace_l);
652 list_del(group_l.next);
653 kfree(ac);
654 }
655 return error;
656} 582}
657 583
658static inline int 584static void deny_bits_array(struct posix_ace_state_array *a, u32 mask)
659mask_from_v4(struct nfs4_acl *n4acl, struct list_head **p,
660 struct nfs4_ace **mask_ace,
661 struct posix_acl *pacl, struct posix_acl_entry **pace,
662 unsigned int flags)
663{ 585{
664 int error = -EINVAL; 586 int i;
665 struct nfs4_ace *ace;
666 587
667 ace = list_entry(*p, struct nfs4_ace, l_ace); 588 for (i=0; i < a->n; i++)
668 if (pacl->a_count != 3) { 589 deny_bits(&a->aces[i].perms, mask);
669 if (*mask_ace == NULL)
670 goto out;
671 (*mask_ace)->access_mask = deny_mask((*mask_ace)->access_mask, flags);
672 write_pace(*mask_ace, pacl, pace, ACL_MASK, flags);
673 }
674 error = 0;
675out:
676 return error;
677} 590}
678 591
679static inline int 592static void allow_bits_array(struct posix_ace_state_array *a, u32 mask)
680other_from_v4(struct nfs4_acl *n4acl, struct list_head **p,
681 struct posix_acl *pacl, struct posix_acl_entry **pace,
682 unsigned int flags)
683{ 593{
684 int error = -EINVAL; 594 int i;
685 struct nfs4_ace *ace, *ace2;
686 595
687 ace = list_entry(*p, struct nfs4_ace, l_ace); 596 for (i=0; i < a->n; i++)
688 if (ace->type != NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) 597 allow_bits(&a->aces[i].perms, mask);
689 goto out;
690 error = write_pace(ace, pacl, pace, ACL_OTHER, flags);
691 if (error < 0)
692 goto out;
693 error = -EINVAL;
694 ace2 = get_next_v4_ace(p, &n4acl->ace_head);
695 if (ace2 == NULL)
696 goto out;
697 if (!complementary_ace_pair(ace, ace2, flags))
698 goto out;
699 error = 0;
700out:
701 return error;
702} 598}
703 599
704static int 600static void process_one_v4_ace(struct posix_acl_state *state,
705calculate_posix_ace_count(struct nfs4_acl *n4acl) 601 struct nfs4_ace *ace)
706{ 602{
707 if (n4acl->naces == 6) /* owner, owner group, and other only */ 603 u32 mask = ace->access_mask;
708 return 3; 604 int i;
709 else { /* Otherwise there must be a mask entry. */ 605
710 /* Also, the remaining entries are for named users and 606 switch (ace2type(ace)) {
711 * groups, and come in threes (mask, allow, deny): */ 607 case ACL_USER_OBJ:
712 if (n4acl->naces < 7) 608 if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) {
713 return -EINVAL; 609 allow_bits(&state->owner, mask);
714 if ((n4acl->naces - 7) % 3) 610 } else {
715 return -EINVAL; 611 deny_bits(&state->owner, mask);
716 return 4 + (n4acl->naces - 7)/3; 612 }
613 break;
614 case ACL_USER:
615 i = find_uid(state, state->users, ace->who);
616 if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) {
617 allow_bits(&state->users->aces[i].perms, mask);
618 } else {
619 deny_bits(&state->users->aces[i].perms, mask);
620 mask = state->users->aces[i].perms.deny;
621 deny_bits(&state->owner, mask);
622 }
623 break;
624 case ACL_GROUP_OBJ:
625 if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) {
626 allow_bits(&state->group, mask);
627 } else {
628 deny_bits(&state->group, mask);
629 mask = state->group.deny;
630 deny_bits(&state->owner, mask);
631 deny_bits(&state->everyone, mask);
632 deny_bits_array(state->users, mask);
633 deny_bits_array(state->groups, mask);
634 }
635 break;
636 case ACL_GROUP:
637 i = find_uid(state, state->groups, ace->who);
638 if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) {
639 allow_bits(&state->groups->aces[i].perms, mask);
640 } else {
641 deny_bits(&state->groups->aces[i].perms, mask);
642 mask = state->groups->aces[i].perms.deny;
643 deny_bits(&state->owner, mask);
644 deny_bits(&state->group, mask);
645 deny_bits(&state->everyone, mask);
646 deny_bits_array(state->users, mask);
647 deny_bits_array(state->groups, mask);
648 }
649 break;
650 case ACL_OTHER:
651 if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) {
652 allow_bits(&state->owner, mask);
653 allow_bits(&state->group, mask);
654 allow_bits(&state->other, mask);
655 allow_bits(&state->everyone, mask);
656 allow_bits_array(state->users, mask);
657 allow_bits_array(state->groups, mask);
658 } else {
659 deny_bits(&state->owner, mask);
660 deny_bits(&state->group, mask);
661 deny_bits(&state->other, mask);
662 deny_bits(&state->everyone, mask);
663 deny_bits_array(state->users, mask);
664 deny_bits_array(state->groups, mask);
665 }
717 } 666 }
718} 667}
719 668
720
721static struct posix_acl * 669static struct posix_acl *
722_nfsv4_to_posix_one(struct nfs4_acl *n4acl, unsigned int flags) 670_nfsv4_to_posix_one(struct nfs4_acl *n4acl, unsigned int flags)
723{ 671{
672 struct posix_acl_state state;
724 struct posix_acl *pacl; 673 struct posix_acl *pacl;
725 int error = -EINVAL, nace = 0; 674 struct nfs4_ace *ace;
726 struct list_head *p; 675 int ret;
727 struct nfs4_ace *mask_ace = NULL;
728 struct posix_acl_entry *pace;
729
730 nace = calculate_posix_ace_count(n4acl);
731 if (nace < 0)
732 goto out_err;
733
734 pacl = posix_acl_alloc(nace, GFP_KERNEL);
735 error = -ENOMEM;
736 if (pacl == NULL)
737 goto out_err;
738
739 pace = &pacl->a_entries[0];
740 p = &n4acl->ace_head;
741
742 error = user_obj_from_v4(n4acl, &p, pacl, &pace, flags);
743 if (error)
744 goto out_acl;
745
746 error = users_from_v4(n4acl, &p, &mask_ace, pacl, &pace, flags);
747 if (error)
748 goto out_acl;
749 676
750 error = group_obj_and_groups_from_v4(n4acl, &p, &mask_ace, pacl, &pace, 677 ret = init_state(&state, n4acl->naces);
751 flags); 678 if (ret)
752 if (error) 679 return ERR_PTR(ret);
753 goto out_acl;
754 680
755 error = mask_from_v4(n4acl, &p, &mask_ace, pacl, &pace, flags); 681 list_for_each_entry(ace, &n4acl->ace_head, l_ace)
756 if (error) 682 process_one_v4_ace(&state, ace);
757 goto out_acl;
758 error = other_from_v4(n4acl, &p, pacl, &pace, flags);
759 if (error)
760 goto out_acl;
761 683
762 error = -EINVAL; 684 pacl = posix_state_to_acl(&state, flags);
763 if (p->next != &n4acl->ace_head)
764 goto out_acl;
765 if (pace != pacl->a_entries + pacl->a_count)
766 goto out_acl;
767 685
768 sort_pacl(pacl); 686 free_state(&state);
769 687
770 return pacl; 688 if (!IS_ERR(pacl))
771out_acl: 689 sort_pacl(pacl);
772 posix_acl_release(pacl);
773out_err:
774 pacl = ERR_PTR(error);
775 return pacl; 690 return pacl;
776} 691}
777 692
@@ -785,22 +700,41 @@ nfs4_acl_split(struct nfs4_acl *acl, struct nfs4_acl *dacl)
785 list_for_each_safe(h, n, &acl->ace_head) { 700 list_for_each_safe(h, n, &acl->ace_head) {
786 ace = list_entry(h, struct nfs4_ace, l_ace); 701 ace = list_entry(h, struct nfs4_ace, l_ace);
787 702
788 if ((ace->flag & NFS4_INHERITANCE_FLAGS) 703 if (ace->type != NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE &&
789 != NFS4_INHERITANCE_FLAGS) 704 ace->type != NFS4_ACE_ACCESS_DENIED_ACE_TYPE)
790 continue; 705 return -EINVAL;
791 706
792 error = nfs4_acl_add_ace(dacl, ace->type, ace->flag, 707 if (ace->flag & ~NFS4_SUPPORTED_FLAGS)
793 ace->access_mask, ace->whotype, ace->who); 708 return -EINVAL;
794 if (error < 0)
795 goto out;
796 709
797 list_del(h); 710 switch (ace->flag & NFS4_INHERITANCE_FLAGS) {
798 kfree(ace); 711 case 0:
799 acl->naces--; 712 /* Leave this ace in the effective acl: */
713 continue;
714 case NFS4_INHERITANCE_FLAGS:
715 /* Add this ace to the default acl and remove it
716 * from the effective acl: */
717 error = nfs4_acl_add_ace(dacl, ace->type, ace->flag,
718 ace->access_mask, ace->whotype, ace->who);
719 if (error)
720 return error;
721 list_del(h);
722 kfree(ace);
723 acl->naces--;
724 break;
725 case NFS4_INHERITANCE_FLAGS & ~NFS4_ACE_INHERIT_ONLY_ACE:
726 /* Add this ace to the default, but leave it in
727 * the effective acl as well: */
728 error = nfs4_acl_add_ace(dacl, ace->type, ace->flag,
729 ace->access_mask, ace->whotype, ace->who);
730 if (error)
731 return error;
732 break;
733 default:
734 return -EINVAL;
735 }
800 } 736 }
801 737 return 0;
802out:
803 return error;
804} 738}
805 739
806static short 740static short
@@ -930,23 +864,6 @@ nfs4_acl_write_who(int who, char *p)
930 return -1; 864 return -1;
931} 865}
932 866
933static inline int
934match_who(struct nfs4_ace *ace, uid_t owner, gid_t group, uid_t who)
935{
936 switch (ace->whotype) {
937 case NFS4_ACL_WHO_NAMED:
938 return who == ace->who;
939 case NFS4_ACL_WHO_OWNER:
940 return who == owner;
941 case NFS4_ACL_WHO_GROUP:
942 return who == group;
943 case NFS4_ACL_WHO_EVERYONE:
944 return 1;
945 default:
946 return 0;
947 }
948}
949
950EXPORT_SYMBOL(nfs4_acl_new); 867EXPORT_SYMBOL(nfs4_acl_new);
951EXPORT_SYMBOL(nfs4_acl_free); 868EXPORT_SYMBOL(nfs4_acl_free);
952EXPORT_SYMBOL(nfs4_acl_add_ace); 869EXPORT_SYMBOL(nfs4_acl_add_ace);
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
index f6ca9fb3fc63..f57655a7a2b6 100644
--- a/fs/nfsd/nfs4callback.c
+++ b/fs/nfsd/nfs4callback.c
@@ -85,8 +85,8 @@ enum nfs_cb_opnum4 {
85/* 85/*
86* Generic encode routines from fs/nfs/nfs4xdr.c 86* Generic encode routines from fs/nfs/nfs4xdr.c
87*/ 87*/
88static inline u32 * 88static inline __be32 *
89xdr_writemem(u32 *p, const void *ptr, int nbytes) 89xdr_writemem(__be32 *p, const void *ptr, int nbytes)
90{ 90{
91 int tmp = XDR_QUADLEN(nbytes); 91 int tmp = XDR_QUADLEN(nbytes);
92 if (!tmp) 92 if (!tmp)
@@ -205,7 +205,7 @@ nfs_cb_stat_to_errno(int stat)
205static int 205static int
206encode_cb_compound_hdr(struct xdr_stream *xdr, struct nfs4_cb_compound_hdr *hdr) 206encode_cb_compound_hdr(struct xdr_stream *xdr, struct nfs4_cb_compound_hdr *hdr)
207{ 207{
208 u32 * p; 208 __be32 * p;
209 209
210 RESERVE_SPACE(16); 210 RESERVE_SPACE(16);
211 WRITE32(0); /* tag length is always 0 */ 211 WRITE32(0); /* tag length is always 0 */
@@ -218,7 +218,7 @@ encode_cb_compound_hdr(struct xdr_stream *xdr, struct nfs4_cb_compound_hdr *hdr)
218static int 218static int
219encode_cb_recall(struct xdr_stream *xdr, struct nfs4_cb_recall *cb_rec) 219encode_cb_recall(struct xdr_stream *xdr, struct nfs4_cb_recall *cb_rec)
220{ 220{
221 u32 *p; 221 __be32 *p;
222 int len = cb_rec->cbr_fhlen; 222 int len = cb_rec->cbr_fhlen;
223 223
224 RESERVE_SPACE(12+sizeof(cb_rec->cbr_stateid) + len); 224 RESERVE_SPACE(12+sizeof(cb_rec->cbr_stateid) + len);
@@ -231,7 +231,7 @@ encode_cb_recall(struct xdr_stream *xdr, struct nfs4_cb_recall *cb_rec)
231} 231}
232 232
233static int 233static int
234nfs4_xdr_enc_cb_null(struct rpc_rqst *req, u32 *p) 234nfs4_xdr_enc_cb_null(struct rpc_rqst *req, __be32 *p)
235{ 235{
236 struct xdr_stream xdrs, *xdr = &xdrs; 236 struct xdr_stream xdrs, *xdr = &xdrs;
237 237
@@ -241,7 +241,7 @@ nfs4_xdr_enc_cb_null(struct rpc_rqst *req, u32 *p)
241} 241}
242 242
243static int 243static int
244nfs4_xdr_enc_cb_recall(struct rpc_rqst *req, u32 *p, struct nfs4_cb_recall *args) 244nfs4_xdr_enc_cb_recall(struct rpc_rqst *req, __be32 *p, struct nfs4_cb_recall *args)
245{ 245{
246 struct xdr_stream xdr; 246 struct xdr_stream xdr;
247 struct nfs4_cb_compound_hdr hdr = { 247 struct nfs4_cb_compound_hdr hdr = {
@@ -257,7 +257,7 @@ nfs4_xdr_enc_cb_recall(struct rpc_rqst *req, u32 *p, struct nfs4_cb_recall *args
257 257
258static int 258static int
259decode_cb_compound_hdr(struct xdr_stream *xdr, struct nfs4_cb_compound_hdr *hdr){ 259decode_cb_compound_hdr(struct xdr_stream *xdr, struct nfs4_cb_compound_hdr *hdr){
260 u32 *p; 260 __be32 *p;
261 261
262 READ_BUF(8); 262 READ_BUF(8);
263 READ32(hdr->status); 263 READ32(hdr->status);
@@ -272,7 +272,7 @@ decode_cb_compound_hdr(struct xdr_stream *xdr, struct nfs4_cb_compound_hdr *hdr)
272static int 272static int
273decode_cb_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected) 273decode_cb_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected)
274{ 274{
275 u32 *p; 275 __be32 *p;
276 u32 op; 276 u32 op;
277 int32_t nfserr; 277 int32_t nfserr;
278 278
@@ -291,13 +291,13 @@ decode_cb_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected)
291} 291}
292 292
293static int 293static int
294nfs4_xdr_dec_cb_null(struct rpc_rqst *req, u32 *p) 294nfs4_xdr_dec_cb_null(struct rpc_rqst *req, __be32 *p)
295{ 295{
296 return 0; 296 return 0;
297} 297}
298 298
299static int 299static int
300nfs4_xdr_dec_cb_recall(struct rpc_rqst *rqstp, u32 *p) 300nfs4_xdr_dec_cb_recall(struct rpc_rqst *rqstp, __be32 *p)
301{ 301{
302 struct xdr_stream xdr; 302 struct xdr_stream xdr;
303 struct nfs4_cb_compound_hdr hdr; 303 struct nfs4_cb_compound_hdr hdr;
@@ -421,7 +421,7 @@ nfsd4_probe_callback(struct nfs4_client *clp)
421 421
422 /* Create RPC client */ 422 /* Create RPC client */
423 cb->cb_client = rpc_create(&args); 423 cb->cb_client = rpc_create(&args);
424 if (!cb->cb_client) { 424 if (IS_ERR(cb->cb_client)) {
425 dprintk("NFSD: couldn't create callback client\n"); 425 dprintk("NFSD: couldn't create callback client\n");
426 goto out_err; 426 goto out_err;
427 } 427 }
@@ -448,10 +448,10 @@ nfsd4_probe_callback(struct nfs4_client *clp)
448out_rpciod: 448out_rpciod:
449 atomic_dec(&clp->cl_count); 449 atomic_dec(&clp->cl_count);
450 rpciod_down(); 450 rpciod_down();
451 cb->cb_client = NULL;
452out_clnt: 451out_clnt:
453 rpc_shutdown_client(cb->cb_client); 452 rpc_shutdown_client(cb->cb_client);
454out_err: 453out_err:
454 cb->cb_client = NULL;
455 dprintk("NFSD: warning: no callback path to client %.*s\n", 455 dprintk("NFSD: warning: no callback path to client %.*s\n",
456 (int)clp->cl_name.len, clp->cl_name.data); 456 (int)clp->cl_name.len, clp->cl_name.data);
457} 457}
@@ -461,7 +461,7 @@ nfs4_cb_null(struct rpc_task *task, void *dummy)
461{ 461{
462 struct nfs4_client *clp = (struct nfs4_client *)task->tk_msg.rpc_argp; 462 struct nfs4_client *clp = (struct nfs4_client *)task->tk_msg.rpc_argp;
463 struct nfs4_callback *cb = &clp->cl_callback; 463 struct nfs4_callback *cb = &clp->cl_callback;
464 u32 addr = htonl(cb->cb_addr); 464 __be32 addr = htonl(cb->cb_addr);
465 465
466 dprintk("NFSD: nfs4_cb_null task->tk_status %d\n", task->tk_status); 466 dprintk("NFSD: nfs4_cb_null task->tk_status %d\n", task->tk_status);
467 467
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 15ded7a30a72..0a7bbdc4a10a 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -67,32 +67,32 @@ fh_dup2(struct svc_fh *dst, struct svc_fh *src)
67 *dst = *src; 67 *dst = *src;
68} 68}
69 69
70static int 70static __be32
71do_open_permission(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open) 71do_open_permission(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open, int accmode)
72{ 72{
73 int accmode, status; 73 __be32 status;
74 74
75 if (open->op_truncate && 75 if (open->op_truncate &&
76 !(open->op_share_access & NFS4_SHARE_ACCESS_WRITE)) 76 !(open->op_share_access & NFS4_SHARE_ACCESS_WRITE))
77 return nfserr_inval; 77 return nfserr_inval;
78 78
79 accmode = MAY_NOP;
80 if (open->op_share_access & NFS4_SHARE_ACCESS_READ) 79 if (open->op_share_access & NFS4_SHARE_ACCESS_READ)
81 accmode = MAY_READ; 80 accmode |= MAY_READ;
82 if (open->op_share_deny & NFS4_SHARE_ACCESS_WRITE) 81 if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE)
83 accmode |= (MAY_WRITE | MAY_TRUNC); 82 accmode |= (MAY_WRITE | MAY_TRUNC);
84 accmode |= MAY_OWNER_OVERRIDE; 83 if (open->op_share_deny & NFS4_SHARE_DENY_WRITE)
84 accmode |= MAY_WRITE;
85 85
86 status = fh_verify(rqstp, current_fh, S_IFREG, accmode); 86 status = fh_verify(rqstp, current_fh, S_IFREG, accmode);
87 87
88 return status; 88 return status;
89} 89}
90 90
91static int 91static __be32
92do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open) 92do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open)
93{ 93{
94 struct svc_fh resfh; 94 struct svc_fh resfh;
95 int status; 95 __be32 status;
96 96
97 fh_init(&resfh, NFS4_FHSIZE); 97 fh_init(&resfh, NFS4_FHSIZE);
98 open->op_truncate = 0; 98 open->op_truncate = 0;
@@ -124,17 +124,17 @@ do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_o
124 &resfh.fh_handle.fh_base, 124 &resfh.fh_handle.fh_base,
125 resfh.fh_handle.fh_size); 125 resfh.fh_handle.fh_size);
126 126
127 status = do_open_permission(rqstp, current_fh, open); 127 status = do_open_permission(rqstp, current_fh, open, MAY_NOP);
128 } 128 }
129 129
130 fh_put(&resfh); 130 fh_put(&resfh);
131 return status; 131 return status;
132} 132}
133 133
134static int 134static __be32
135do_open_fhandle(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open) 135do_open_fhandle(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open)
136{ 136{
137 int status; 137 __be32 status;
138 138
139 /* Only reclaims from previously confirmed clients are valid */ 139 /* Only reclaims from previously confirmed clients are valid */
140 if ((status = nfs4_check_open_reclaim(&open->op_clientid))) 140 if ((status = nfs4_check_open_reclaim(&open->op_clientid)))
@@ -155,16 +155,16 @@ do_open_fhandle(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_
155 open->op_truncate = (open->op_iattr.ia_valid & ATTR_SIZE) && 155 open->op_truncate = (open->op_iattr.ia_valid & ATTR_SIZE) &&
156 (open->op_iattr.ia_size == 0); 156 (open->op_iattr.ia_size == 0);
157 157
158 status = do_open_permission(rqstp, current_fh, open); 158 status = do_open_permission(rqstp, current_fh, open, MAY_OWNER_OVERRIDE);
159 159
160 return status; 160 return status;
161} 161}
162 162
163 163
164static inline int 164static inline __be32
165nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open, struct nfs4_stateowner **replay_owner) 165nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open, struct nfs4_stateowner **replay_owner)
166{ 166{
167 int status; 167 __be32 status;
168 dprintk("NFSD: nfsd4_open filename %.*s op_stateowner %p\n", 168 dprintk("NFSD: nfsd4_open filename %.*s op_stateowner %p\n",
169 (int)open->op_fname.len, open->op_fname.data, 169 (int)open->op_fname.len, open->op_fname.data,
170 open->op_stateowner); 170 open->op_stateowner);
@@ -177,7 +177,7 @@ nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open
177 177
178 /* check seqid for replay. set nfs4_owner */ 178 /* check seqid for replay. set nfs4_owner */
179 status = nfsd4_process_open1(open); 179 status = nfsd4_process_open1(open);
180 if (status == NFSERR_REPLAY_ME) { 180 if (status == nfserr_replay_me) {
181 struct nfs4_replay *rp = &open->op_stateowner->so_replay; 181 struct nfs4_replay *rp = &open->op_stateowner->so_replay;
182 fh_put(current_fh); 182 fh_put(current_fh);
183 current_fh->fh_handle.fh_size = rp->rp_openfh_len; 183 current_fh->fh_handle.fh_size = rp->rp_openfh_len;
@@ -188,7 +188,7 @@ nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open
188 dprintk("nfsd4_open: replay failed" 188 dprintk("nfsd4_open: replay failed"
189 " restoring previous filehandle\n"); 189 " restoring previous filehandle\n");
190 else 190 else
191 status = NFSERR_REPLAY_ME; 191 status = nfserr_replay_me;
192 } 192 }
193 if (status) 193 if (status)
194 goto out; 194 goto out;
@@ -261,7 +261,7 @@ out:
261/* 261/*
262 * filehandle-manipulating ops. 262 * filehandle-manipulating ops.
263 */ 263 */
264static inline int 264static inline __be32
265nfsd4_getfh(struct svc_fh *current_fh, struct svc_fh **getfh) 265nfsd4_getfh(struct svc_fh *current_fh, struct svc_fh **getfh)
266{ 266{
267 if (!current_fh->fh_dentry) 267 if (!current_fh->fh_dentry)
@@ -271,7 +271,7 @@ nfsd4_getfh(struct svc_fh *current_fh, struct svc_fh **getfh)
271 return nfs_ok; 271 return nfs_ok;
272} 272}
273 273
274static inline int 274static inline __be32
275nfsd4_putfh(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_putfh *putfh) 275nfsd4_putfh(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_putfh *putfh)
276{ 276{
277 fh_put(current_fh); 277 fh_put(current_fh);
@@ -280,10 +280,10 @@ nfsd4_putfh(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_putf
280 return fh_verify(rqstp, current_fh, 0, MAY_NOP); 280 return fh_verify(rqstp, current_fh, 0, MAY_NOP);
281} 281}
282 282
283static inline int 283static inline __be32
284nfsd4_putrootfh(struct svc_rqst *rqstp, struct svc_fh *current_fh) 284nfsd4_putrootfh(struct svc_rqst *rqstp, struct svc_fh *current_fh)
285{ 285{
286 int status; 286 __be32 status;
287 287
288 fh_put(current_fh); 288 fh_put(current_fh);
289 status = exp_pseudoroot(rqstp->rq_client, current_fh, 289 status = exp_pseudoroot(rqstp->rq_client, current_fh,
@@ -291,7 +291,7 @@ nfsd4_putrootfh(struct svc_rqst *rqstp, struct svc_fh *current_fh)
291 return status; 291 return status;
292} 292}
293 293
294static inline int 294static inline __be32
295nfsd4_restorefh(struct svc_fh *current_fh, struct svc_fh *save_fh) 295nfsd4_restorefh(struct svc_fh *current_fh, struct svc_fh *save_fh)
296{ 296{
297 if (!save_fh->fh_dentry) 297 if (!save_fh->fh_dentry)
@@ -301,7 +301,7 @@ nfsd4_restorefh(struct svc_fh *current_fh, struct svc_fh *save_fh)
301 return nfs_ok; 301 return nfs_ok;
302} 302}
303 303
304static inline int 304static inline __be32
305nfsd4_savefh(struct svc_fh *current_fh, struct svc_fh *save_fh) 305nfsd4_savefh(struct svc_fh *current_fh, struct svc_fh *save_fh)
306{ 306{
307 if (!current_fh->fh_dentry) 307 if (!current_fh->fh_dentry)
@@ -314,7 +314,7 @@ nfsd4_savefh(struct svc_fh *current_fh, struct svc_fh *save_fh)
314/* 314/*
315 * misc nfsv4 ops 315 * misc nfsv4 ops
316 */ 316 */
317static inline int 317static inline __be32
318nfsd4_access(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_access *access) 318nfsd4_access(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_access *access)
319{ 319{
320 if (access->ac_req_access & ~NFS3_ACCESS_FULL) 320 if (access->ac_req_access & ~NFS3_ACCESS_FULL)
@@ -324,10 +324,10 @@ nfsd4_access(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_acc
324 return nfsd_access(rqstp, current_fh, &access->ac_resp_access, &access->ac_supported); 324 return nfsd_access(rqstp, current_fh, &access->ac_resp_access, &access->ac_supported);
325} 325}
326 326
327static inline int 327static inline __be32
328nfsd4_commit(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_commit *commit) 328nfsd4_commit(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_commit *commit)
329{ 329{
330 int status; 330 __be32 status;
331 331
332 u32 *p = (u32 *)commit->co_verf.data; 332 u32 *p = (u32 *)commit->co_verf.data;
333 *p++ = nfssvc_boot.tv_sec; 333 *p++ = nfssvc_boot.tv_sec;
@@ -339,11 +339,11 @@ nfsd4_commit(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_com
339 return status; 339 return status;
340} 340}
341 341
342static int 342static __be32
343nfsd4_create(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_create *create) 343nfsd4_create(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_create *create)
344{ 344{
345 struct svc_fh resfh; 345 struct svc_fh resfh;
346 int status; 346 __be32 status;
347 dev_t rdev; 347 dev_t rdev;
348 348
349 fh_init(&resfh, NFS4_FHSIZE); 349 fh_init(&resfh, NFS4_FHSIZE);
@@ -423,10 +423,10 @@ nfsd4_create(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_cre
423 return status; 423 return status;
424} 424}
425 425
426static inline int 426static inline __be32
427nfsd4_getattr(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_getattr *getattr) 427nfsd4_getattr(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_getattr *getattr)
428{ 428{
429 int status; 429 __be32 status;
430 430
431 status = fh_verify(rqstp, current_fh, 0, MAY_NOP); 431 status = fh_verify(rqstp, current_fh, 0, MAY_NOP);
432 if (status) 432 if (status)
@@ -442,11 +442,11 @@ nfsd4_getattr(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_ge
442 return nfs_ok; 442 return nfs_ok;
443} 443}
444 444
445static inline int 445static inline __be32
446nfsd4_link(struct svc_rqst *rqstp, struct svc_fh *current_fh, 446nfsd4_link(struct svc_rqst *rqstp, struct svc_fh *current_fh,
447 struct svc_fh *save_fh, struct nfsd4_link *link) 447 struct svc_fh *save_fh, struct nfsd4_link *link)
448{ 448{
449 int status = nfserr_nofilehandle; 449 __be32 status = nfserr_nofilehandle;
450 450
451 if (!save_fh->fh_dentry) 451 if (!save_fh->fh_dentry)
452 return status; 452 return status;
@@ -456,11 +456,11 @@ nfsd4_link(struct svc_rqst *rqstp, struct svc_fh *current_fh,
456 return status; 456 return status;
457} 457}
458 458
459static int 459static __be32
460nfsd4_lookupp(struct svc_rqst *rqstp, struct svc_fh *current_fh) 460nfsd4_lookupp(struct svc_rqst *rqstp, struct svc_fh *current_fh)
461{ 461{
462 struct svc_fh tmp_fh; 462 struct svc_fh tmp_fh;
463 int ret; 463 __be32 ret;
464 464
465 fh_init(&tmp_fh, NFS4_FHSIZE); 465 fh_init(&tmp_fh, NFS4_FHSIZE);
466 if((ret = exp_pseudoroot(rqstp->rq_client, &tmp_fh, 466 if((ret = exp_pseudoroot(rqstp->rq_client, &tmp_fh,
@@ -474,16 +474,16 @@ nfsd4_lookupp(struct svc_rqst *rqstp, struct svc_fh *current_fh)
474 return nfsd_lookup(rqstp, current_fh, "..", 2, current_fh); 474 return nfsd_lookup(rqstp, current_fh, "..", 2, current_fh);
475} 475}
476 476
477static inline int 477static inline __be32
478nfsd4_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lookup *lookup) 478nfsd4_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lookup *lookup)
479{ 479{
480 return nfsd_lookup(rqstp, current_fh, lookup->lo_name, lookup->lo_len, current_fh); 480 return nfsd_lookup(rqstp, current_fh, lookup->lo_name, lookup->lo_len, current_fh);
481} 481}
482 482
483static inline int 483static inline __be32
484nfsd4_read(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_read *read) 484nfsd4_read(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_read *read)
485{ 485{
486 int status; 486 __be32 status;
487 487
488 /* no need to check permission - this will be done in nfsd_read() */ 488 /* no need to check permission - this will be done in nfsd_read() */
489 489
@@ -508,7 +508,7 @@ out:
508 return status; 508 return status;
509} 509}
510 510
511static inline int 511static inline __be32
512nfsd4_readdir(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_readdir *readdir) 512nfsd4_readdir(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_readdir *readdir)
513{ 513{
514 u64 cookie = readdir->rd_cookie; 514 u64 cookie = readdir->rd_cookie;
@@ -531,7 +531,7 @@ nfsd4_readdir(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_re
531 return nfs_ok; 531 return nfs_ok;
532} 532}
533 533
534static inline int 534static inline __be32
535nfsd4_readlink(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_readlink *readlink) 535nfsd4_readlink(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_readlink *readlink)
536{ 536{
537 readlink->rl_rqstp = rqstp; 537 readlink->rl_rqstp = rqstp;
@@ -539,10 +539,10 @@ nfsd4_readlink(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_r
539 return nfs_ok; 539 return nfs_ok;
540} 540}
541 541
542static inline int 542static inline __be32
543nfsd4_remove(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_remove *remove) 543nfsd4_remove(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_remove *remove)
544{ 544{
545 int status; 545 __be32 status;
546 546
547 if (nfs4_in_grace()) 547 if (nfs4_in_grace())
548 return nfserr_grace; 548 return nfserr_grace;
@@ -556,11 +556,11 @@ nfsd4_remove(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_rem
556 return status; 556 return status;
557} 557}
558 558
559static inline int 559static inline __be32
560nfsd4_rename(struct svc_rqst *rqstp, struct svc_fh *current_fh, 560nfsd4_rename(struct svc_rqst *rqstp, struct svc_fh *current_fh,
561 struct svc_fh *save_fh, struct nfsd4_rename *rename) 561 struct svc_fh *save_fh, struct nfsd4_rename *rename)
562{ 562{
563 int status = nfserr_nofilehandle; 563 __be32 status = nfserr_nofilehandle;
564 564
565 if (!save_fh->fh_dentry) 565 if (!save_fh->fh_dentry)
566 return status; 566 return status;
@@ -589,10 +589,10 @@ nfsd4_rename(struct svc_rqst *rqstp, struct svc_fh *current_fh,
589 return status; 589 return status;
590} 590}
591 591
592static inline int 592static inline __be32
593nfsd4_setattr(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_setattr *setattr) 593nfsd4_setattr(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_setattr *setattr)
594{ 594{
595 int status = nfs_ok; 595 __be32 status = nfs_ok;
596 596
597 if (setattr->sa_iattr.ia_valid & ATTR_SIZE) { 597 if (setattr->sa_iattr.ia_valid & ATTR_SIZE) {
598 nfs4_lock_state(); 598 nfs4_lock_state();
@@ -614,13 +614,13 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_se
614 return status; 614 return status;
615} 615}
616 616
617static inline int 617static inline __be32
618nfsd4_write(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_write *write) 618nfsd4_write(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_write *write)
619{ 619{
620 stateid_t *stateid = &write->wr_stateid; 620 stateid_t *stateid = &write->wr_stateid;
621 struct file *filp = NULL; 621 struct file *filp = NULL;
622 u32 *p; 622 u32 *p;
623 int status = nfs_ok; 623 __be32 status = nfs_ok;
624 624
625 /* no need to check permission - this will be done in nfsd_write() */ 625 /* no need to check permission - this will be done in nfsd_write() */
626 626
@@ -646,7 +646,7 @@ nfsd4_write(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_writ
646 *p++ = nfssvc_boot.tv_usec; 646 *p++ = nfssvc_boot.tv_usec;
647 647
648 status = nfsd_write(rqstp, current_fh, filp, write->wr_offset, 648 status = nfsd_write(rqstp, current_fh, filp, write->wr_offset,
649 write->wr_vec, write->wr_vlen, write->wr_buflen, 649 rqstp->rq_vec, write->wr_vlen, write->wr_buflen,
650 &write->wr_how_written); 650 &write->wr_how_written);
651 if (filp) 651 if (filp)
652 fput(filp); 652 fput(filp);
@@ -661,12 +661,12 @@ nfsd4_write(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_writ
661 * attributes matched. VERIFY is implemented by mapping NFSERR_SAME 661 * attributes matched. VERIFY is implemented by mapping NFSERR_SAME
662 * to NFS_OK after the call; NVERIFY by mapping NFSERR_NOT_SAME to NFS_OK. 662 * to NFS_OK after the call; NVERIFY by mapping NFSERR_NOT_SAME to NFS_OK.
663 */ 663 */
664static int 664static __be32
665nfsd4_verify(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_verify *verify) 665nfsd4_verify(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_verify *verify)
666{ 666{
667 u32 *buf, *p; 667 __be32 *buf, *p;
668 int count; 668 int count;
669 int status; 669 __be32 status;
670 670
671 status = fh_verify(rqstp, current_fh, 0, MAY_NOP); 671 status = fh_verify(rqstp, current_fh, 0, MAY_NOP);
672 if (status) 672 if (status)
@@ -715,7 +715,7 @@ out_kfree:
715/* 715/*
716 * NULL call. 716 * NULL call.
717 */ 717 */
718static int 718static __be32
719nfsd4_proc_null(struct svc_rqst *rqstp, void *argp, void *resp) 719nfsd4_proc_null(struct svc_rqst *rqstp, void *argp, void *resp)
720{ 720{
721 return nfs_ok; 721 return nfs_ok;
@@ -731,7 +731,7 @@ static inline void nfsd4_increment_op_stats(u32 opnum)
731/* 731/*
732 * COMPOUND call. 732 * COMPOUND call.
733 */ 733 */
734static int 734static __be32
735nfsd4_proc_compound(struct svc_rqst *rqstp, 735nfsd4_proc_compound(struct svc_rqst *rqstp,
736 struct nfsd4_compoundargs *args, 736 struct nfsd4_compoundargs *args,
737 struct nfsd4_compoundres *resp) 737 struct nfsd4_compoundres *resp)
@@ -741,7 +741,7 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
741 struct svc_fh *save_fh = NULL; 741 struct svc_fh *save_fh = NULL;
742 struct nfs4_stateowner *replay_owner = NULL; 742 struct nfs4_stateowner *replay_owner = NULL;
743 int slack_space; /* in words, not bytes! */ 743 int slack_space; /* in words, not bytes! */
744 int status; 744 __be32 status;
745 745
746 status = nfserr_resource; 746 status = nfserr_resource;
747 current_fh = kmalloc(sizeof(*current_fh), GFP_KERNEL); 747 current_fh = kmalloc(sizeof(*current_fh), GFP_KERNEL);
@@ -802,13 +802,29 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
802 * SETCLIENTID_CONFIRM, PUTFH and PUTROOTFH 802 * SETCLIENTID_CONFIRM, PUTFH and PUTROOTFH
803 * require a valid current filehandle 803 * require a valid current filehandle
804 */ 804 */
805 if ((!current_fh->fh_dentry) && 805 if (!current_fh->fh_dentry) {
806 !((op->opnum == OP_PUTFH) || (op->opnum == OP_PUTROOTFH) || 806 if (!((op->opnum == OP_PUTFH) ||
807 (op->opnum == OP_SETCLIENTID) || 807 (op->opnum == OP_PUTROOTFH) ||
808 (op->opnum == OP_SETCLIENTID_CONFIRM) || 808 (op->opnum == OP_SETCLIENTID) ||
809 (op->opnum == OP_RENEW) || (op->opnum == OP_RESTOREFH) || 809 (op->opnum == OP_SETCLIENTID_CONFIRM) ||
810 (op->opnum == OP_RELEASE_LOCKOWNER))) { 810 (op->opnum == OP_RENEW) ||
811 op->status = nfserr_nofilehandle; 811 (op->opnum == OP_RESTOREFH) ||
812 (op->opnum == OP_RELEASE_LOCKOWNER))) {
813 op->status = nfserr_nofilehandle;
814 goto encode_op;
815 }
816 }
817 /* Check must be done at start of each operation, except
818 * for GETATTR and ops not listed as returning NFS4ERR_MOVED
819 */
820 else if (current_fh->fh_export->ex_fslocs.migrated &&
821 !((op->opnum == OP_GETATTR) ||
822 (op->opnum == OP_PUTROOTFH) ||
823 (op->opnum == OP_PUTPUBFH) ||
824 (op->opnum == OP_RENEW) ||
825 (op->opnum == OP_SETCLIENTID) ||
826 (op->opnum == OP_RELEASE_LOCKOWNER))) {
827 op->status = nfserr_moved;
812 goto encode_op; 828 goto encode_op;
813 } 829 }
814 switch (op->opnum) { 830 switch (op->opnum) {
@@ -921,7 +937,7 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
921 } 937 }
922 938
923encode_op: 939encode_op:
924 if (op->status == NFSERR_REPLAY_ME) { 940 if (op->status == nfserr_replay_me) {
925 op->replay = &replay_owner->so_replay; 941 op->replay = &replay_owner->so_replay;
926 nfsd4_encode_replay(resp, op); 942 nfsd4_encode_replay(resp, op);
927 status = op->status = op->replay->rp_status; 943 status = op->status = op->replay->rp_status;
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
index 1cbd2e4ee122..e9d07704680e 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -83,13 +83,13 @@ md5_to_hex(char *out, char *md5)
83 *out = '\0'; 83 *out = '\0';
84} 84}
85 85
86int 86__be32
87nfs4_make_rec_clidname(char *dname, struct xdr_netobj *clname) 87nfs4_make_rec_clidname(char *dname, struct xdr_netobj *clname)
88{ 88{
89 struct xdr_netobj cksum; 89 struct xdr_netobj cksum;
90 struct hash_desc desc; 90 struct hash_desc desc;
91 struct scatterlist sg[1]; 91 struct scatterlist sg[1];
92 int status = nfserr_resource; 92 __be32 status = nfserr_resource;
93 93
94 dprintk("NFSD: nfs4_make_rec_clidname for %.*s\n", 94 dprintk("NFSD: nfs4_make_rec_clidname for %.*s\n",
95 clname->len, clname->data); 95 clname->len, clname->data);
@@ -193,7 +193,7 @@ nfsd4_build_dentrylist(void *arg, const char *name, int namlen,
193 struct dentry_list *child; 193 struct dentry_list *child;
194 194
195 if (name && isdotent(name, namlen)) 195 if (name && isdotent(name, namlen))
196 return nfs_ok; 196 return 0;
197 dentry = lookup_one_len(name, parent, namlen); 197 dentry = lookup_one_len(name, parent, namlen);
198 if (IS_ERR(dentry)) 198 if (IS_ERR(dentry))
199 return PTR_ERR(dentry); 199 return PTR_ERR(dentry);
@@ -333,14 +333,14 @@ purge_old(struct dentry *parent, struct dentry *child)
333 int status; 333 int status;
334 334
335 if (nfs4_has_reclaimed_state(child->d_name.name)) 335 if (nfs4_has_reclaimed_state(child->d_name.name))
336 return nfs_ok; 336 return 0;
337 337
338 status = nfsd4_clear_clid_dir(parent, child); 338 status = nfsd4_clear_clid_dir(parent, child);
339 if (status) 339 if (status)
340 printk("failed to remove client recovery directory %s\n", 340 printk("failed to remove client recovery directory %s\n",
341 child->d_name.name); 341 child->d_name.name);
342 /* Keep trying, success or failure: */ 342 /* Keep trying, success or failure: */
343 return nfs_ok; 343 return 0;
344} 344}
345 345
346void 346void
@@ -365,10 +365,10 @@ load_recdir(struct dentry *parent, struct dentry *child)
365 printk("nfsd4: illegal name %s in recovery directory\n", 365 printk("nfsd4: illegal name %s in recovery directory\n",
366 child->d_name.name); 366 child->d_name.name);
367 /* Keep trying; maybe the others are OK: */ 367 /* Keep trying; maybe the others are OK: */
368 return nfs_ok; 368 return 0;
369 } 369 }
370 nfs4_client_to_reclaim(child->d_name.name); 370 nfs4_client_to_reclaim(child->d_name.name);
371 return nfs_ok; 371 return 0;
372} 372}
373 373
374int 374int
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index ebcf226a9e4a..293b6495829f 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -710,10 +710,10 @@ out_err:
710 * as described above. 710 * as described above.
711 * 711 *
712 */ 712 */
713int 713__be32
714nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_setclientid *setclid) 714nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_setclientid *setclid)
715{ 715{
716 u32 ip_addr = rqstp->rq_addr.sin_addr.s_addr; 716 __be32 ip_addr = rqstp->rq_addr.sin_addr.s_addr;
717 struct xdr_netobj clname = { 717 struct xdr_netobj clname = {
718 .len = setclid->se_namelen, 718 .len = setclid->se_namelen,
719 .data = setclid->se_name, 719 .data = setclid->se_name,
@@ -721,7 +721,7 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_setclientid *setclid)
721 nfs4_verifier clverifier = setclid->se_verf; 721 nfs4_verifier clverifier = setclid->se_verf;
722 unsigned int strhashval; 722 unsigned int strhashval;
723 struct nfs4_client *conf, *unconf, *new; 723 struct nfs4_client *conf, *unconf, *new;
724 int status; 724 __be32 status;
725 char dname[HEXDIR_LEN]; 725 char dname[HEXDIR_LEN];
726 726
727 if (!check_name(clname)) 727 if (!check_name(clname))
@@ -875,14 +875,14 @@ out:
875 * 875 *
876 * NOTE: callback information will be processed here in a future patch 876 * NOTE: callback information will be processed here in a future patch
877 */ 877 */
878int 878__be32
879nfsd4_setclientid_confirm(struct svc_rqst *rqstp, struct nfsd4_setclientid_confirm *setclientid_confirm) 879nfsd4_setclientid_confirm(struct svc_rqst *rqstp, struct nfsd4_setclientid_confirm *setclientid_confirm)
880{ 880{
881 u32 ip_addr = rqstp->rq_addr.sin_addr.s_addr; 881 __be32 ip_addr = rqstp->rq_addr.sin_addr.s_addr;
882 struct nfs4_client *conf, *unconf; 882 struct nfs4_client *conf, *unconf;
883 nfs4_verifier confirm = setclientid_confirm->sc_confirm; 883 nfs4_verifier confirm = setclientid_confirm->sc_confirm;
884 clientid_t * clid = &setclientid_confirm->sc_clientid; 884 clientid_t * clid = &setclientid_confirm->sc_clientid;
885 int status; 885 __be32 status;
886 886
887 if (STALE_CLIENTID(clid)) 887 if (STALE_CLIENTID(clid))
888 return nfserr_stale_clientid; 888 return nfserr_stale_clientid;
@@ -1280,13 +1280,13 @@ test_share(struct nfs4_stateid *stp, struct nfsd4_open *open) {
1280 * Called to check deny when READ with all zero stateid or 1280 * Called to check deny when READ with all zero stateid or
1281 * WRITE with all zero or all one stateid 1281 * WRITE with all zero or all one stateid
1282 */ 1282 */
1283static int 1283static __be32
1284nfs4_share_conflict(struct svc_fh *current_fh, unsigned int deny_type) 1284nfs4_share_conflict(struct svc_fh *current_fh, unsigned int deny_type)
1285{ 1285{
1286 struct inode *ino = current_fh->fh_dentry->d_inode; 1286 struct inode *ino = current_fh->fh_dentry->d_inode;
1287 struct nfs4_file *fp; 1287 struct nfs4_file *fp;
1288 struct nfs4_stateid *stp; 1288 struct nfs4_stateid *stp;
1289 int ret; 1289 __be32 ret;
1290 1290
1291 dprintk("NFSD: nfs4_share_conflict\n"); 1291 dprintk("NFSD: nfs4_share_conflict\n");
1292 1292
@@ -1444,7 +1444,7 @@ static struct lock_manager_operations nfsd_lease_mng_ops = {
1444}; 1444};
1445 1445
1446 1446
1447int 1447__be32
1448nfsd4_process_open1(struct nfsd4_open *open) 1448nfsd4_process_open1(struct nfsd4_open *open)
1449{ 1449{
1450 clientid_t *clientid = &open->op_clientid; 1450 clientid_t *clientid = &open->op_clientid;
@@ -1477,7 +1477,7 @@ nfsd4_process_open1(struct nfsd4_open *open)
1477 } 1477 }
1478 if (open->op_seqid == sop->so_seqid - 1) { 1478 if (open->op_seqid == sop->so_seqid - 1) {
1479 if (sop->so_replay.rp_buflen) 1479 if (sop->so_replay.rp_buflen)
1480 return NFSERR_REPLAY_ME; 1480 return nfserr_replay_me;
1481 /* The original OPEN failed so spectacularly 1481 /* The original OPEN failed so spectacularly
1482 * that we don't even have replay data saved! 1482 * that we don't even have replay data saved!
1483 * Therefore, we have no choice but to continue 1483 * Therefore, we have no choice but to continue
@@ -1501,7 +1501,7 @@ renew:
1501 return nfs_ok; 1501 return nfs_ok;
1502} 1502}
1503 1503
1504static inline int 1504static inline __be32
1505nfs4_check_delegmode(struct nfs4_delegation *dp, int flags) 1505nfs4_check_delegmode(struct nfs4_delegation *dp, int flags)
1506{ 1506{
1507 if ((flags & WR_STATE) && (dp->dl_type == NFS4_OPEN_DELEGATE_READ)) 1507 if ((flags & WR_STATE) && (dp->dl_type == NFS4_OPEN_DELEGATE_READ))
@@ -1522,12 +1522,12 @@ find_delegation_file(struct nfs4_file *fp, stateid_t *stid)
1522 return NULL; 1522 return NULL;
1523} 1523}
1524 1524
1525static int 1525static __be32
1526nfs4_check_deleg(struct nfs4_file *fp, struct nfsd4_open *open, 1526nfs4_check_deleg(struct nfs4_file *fp, struct nfsd4_open *open,
1527 struct nfs4_delegation **dp) 1527 struct nfs4_delegation **dp)
1528{ 1528{
1529 int flags; 1529 int flags;
1530 int status = nfserr_bad_stateid; 1530 __be32 status = nfserr_bad_stateid;
1531 1531
1532 *dp = find_delegation_file(fp, &open->op_delegate_stateid); 1532 *dp = find_delegation_file(fp, &open->op_delegate_stateid);
1533 if (*dp == NULL) 1533 if (*dp == NULL)
@@ -1546,11 +1546,11 @@ out:
1546 return nfs_ok; 1546 return nfs_ok;
1547} 1547}
1548 1548
1549static int 1549static __be32
1550nfs4_check_open(struct nfs4_file *fp, struct nfsd4_open *open, struct nfs4_stateid **stpp) 1550nfs4_check_open(struct nfs4_file *fp, struct nfsd4_open *open, struct nfs4_stateid **stpp)
1551{ 1551{
1552 struct nfs4_stateid *local; 1552 struct nfs4_stateid *local;
1553 int status = nfserr_share_denied; 1553 __be32 status = nfserr_share_denied;
1554 struct nfs4_stateowner *sop = open->op_stateowner; 1554 struct nfs4_stateowner *sop = open->op_stateowner;
1555 1555
1556 list_for_each_entry(local, &fp->fi_stateids, st_perfile) { 1556 list_for_each_entry(local, &fp->fi_stateids, st_perfile) {
@@ -1575,7 +1575,7 @@ nfs4_alloc_stateid(void)
1575 return kmem_cache_alloc(stateid_slab, GFP_KERNEL); 1575 return kmem_cache_alloc(stateid_slab, GFP_KERNEL);
1576} 1576}
1577 1577
1578static int 1578static __be32
1579nfs4_new_open(struct svc_rqst *rqstp, struct nfs4_stateid **stpp, 1579nfs4_new_open(struct svc_rqst *rqstp, struct nfs4_stateid **stpp,
1580 struct nfs4_delegation *dp, 1580 struct nfs4_delegation *dp,
1581 struct svc_fh *cur_fh, int flags) 1581 struct svc_fh *cur_fh, int flags)
@@ -1590,7 +1590,7 @@ nfs4_new_open(struct svc_rqst *rqstp, struct nfs4_stateid **stpp,
1590 get_file(dp->dl_vfs_file); 1590 get_file(dp->dl_vfs_file);
1591 stp->st_vfs_file = dp->dl_vfs_file; 1591 stp->st_vfs_file = dp->dl_vfs_file;
1592 } else { 1592 } else {
1593 int status; 1593 __be32 status;
1594 status = nfsd_open(rqstp, cur_fh, S_IFREG, flags, 1594 status = nfsd_open(rqstp, cur_fh, S_IFREG, flags,
1595 &stp->st_vfs_file); 1595 &stp->st_vfs_file);
1596 if (status) { 1596 if (status) {
@@ -1604,7 +1604,7 @@ nfs4_new_open(struct svc_rqst *rqstp, struct nfs4_stateid **stpp,
1604 return 0; 1604 return 0;
1605} 1605}
1606 1606
1607static inline int 1607static inline __be32
1608nfsd4_truncate(struct svc_rqst *rqstp, struct svc_fh *fh, 1608nfsd4_truncate(struct svc_rqst *rqstp, struct svc_fh *fh,
1609 struct nfsd4_open *open) 1609 struct nfsd4_open *open)
1610{ 1610{
@@ -1619,22 +1619,22 @@ nfsd4_truncate(struct svc_rqst *rqstp, struct svc_fh *fh,
1619 return nfsd_setattr(rqstp, fh, &iattr, 0, (time_t)0); 1619 return nfsd_setattr(rqstp, fh, &iattr, 0, (time_t)0);
1620} 1620}
1621 1621
1622static int 1622static __be32
1623nfs4_upgrade_open(struct svc_rqst *rqstp, struct svc_fh *cur_fh, struct nfs4_stateid *stp, struct nfsd4_open *open) 1623nfs4_upgrade_open(struct svc_rqst *rqstp, struct svc_fh *cur_fh, struct nfs4_stateid *stp, struct nfsd4_open *open)
1624{ 1624{
1625 struct file *filp = stp->st_vfs_file; 1625 struct file *filp = stp->st_vfs_file;
1626 struct inode *inode = filp->f_dentry->d_inode; 1626 struct inode *inode = filp->f_dentry->d_inode;
1627 unsigned int share_access, new_writer; 1627 unsigned int share_access, new_writer;
1628 int status; 1628 __be32 status;
1629 1629
1630 set_access(&share_access, stp->st_access_bmap); 1630 set_access(&share_access, stp->st_access_bmap);
1631 new_writer = (~share_access) & open->op_share_access 1631 new_writer = (~share_access) & open->op_share_access
1632 & NFS4_SHARE_ACCESS_WRITE; 1632 & NFS4_SHARE_ACCESS_WRITE;
1633 1633
1634 if (new_writer) { 1634 if (new_writer) {
1635 status = get_write_access(inode); 1635 int err = get_write_access(inode);
1636 if (status) 1636 if (err)
1637 return nfserrno(status); 1637 return nfserrno(err);
1638 } 1638 }
1639 status = nfsd4_truncate(rqstp, cur_fh, open); 1639 status = nfsd4_truncate(rqstp, cur_fh, open);
1640 if (status) { 1640 if (status) {
@@ -1738,14 +1738,14 @@ out:
1738/* 1738/*
1739 * called with nfs4_lock_state() held. 1739 * called with nfs4_lock_state() held.
1740 */ 1740 */
1741int 1741__be32
1742nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open) 1742nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open)
1743{ 1743{
1744 struct nfs4_file *fp = NULL; 1744 struct nfs4_file *fp = NULL;
1745 struct inode *ino = current_fh->fh_dentry->d_inode; 1745 struct inode *ino = current_fh->fh_dentry->d_inode;
1746 struct nfs4_stateid *stp = NULL; 1746 struct nfs4_stateid *stp = NULL;
1747 struct nfs4_delegation *dp = NULL; 1747 struct nfs4_delegation *dp = NULL;
1748 int status; 1748 __be32 status;
1749 1749
1750 status = nfserr_inval; 1750 status = nfserr_inval;
1751 if (!access_valid(open->op_share_access) 1751 if (!access_valid(open->op_share_access)
@@ -1833,11 +1833,11 @@ static struct work_struct laundromat_work;
1833static void laundromat_main(void *); 1833static void laundromat_main(void *);
1834static DECLARE_WORK(laundromat_work, laundromat_main, NULL); 1834static DECLARE_WORK(laundromat_work, laundromat_main, NULL);
1835 1835
1836int 1836__be32
1837nfsd4_renew(clientid_t *clid) 1837nfsd4_renew(clientid_t *clid)
1838{ 1838{
1839 struct nfs4_client *clp; 1839 struct nfs4_client *clp;
1840 int status; 1840 __be32 status;
1841 1841
1842 nfs4_lock_state(); 1842 nfs4_lock_state();
1843 dprintk("process_renew(%08x/%08x): starting\n", 1843 dprintk("process_renew(%08x/%08x): starting\n",
@@ -1996,9 +1996,9 @@ access_permit_write(unsigned long access_bmap)
1996} 1996}
1997 1997
1998static 1998static
1999int nfs4_check_openmode(struct nfs4_stateid *stp, int flags) 1999__be32 nfs4_check_openmode(struct nfs4_stateid *stp, int flags)
2000{ 2000{
2001 int status = nfserr_openmode; 2001 __be32 status = nfserr_openmode;
2002 2002
2003 if ((flags & WR_STATE) && (!access_permit_write(stp->st_access_bmap))) 2003 if ((flags & WR_STATE) && (!access_permit_write(stp->st_access_bmap)))
2004 goto out; 2004 goto out;
@@ -2009,7 +2009,7 @@ out:
2009 return status; 2009 return status;
2010} 2010}
2011 2011
2012static inline int 2012static inline __be32
2013check_special_stateids(svc_fh *current_fh, stateid_t *stateid, int flags) 2013check_special_stateids(svc_fh *current_fh, stateid_t *stateid, int flags)
2014{ 2014{
2015 /* Trying to call delegreturn with a special stateid? Yuch: */ 2015 /* Trying to call delegreturn with a special stateid? Yuch: */
@@ -2043,14 +2043,14 @@ io_during_grace_disallowed(struct inode *inode, int flags)
2043/* 2043/*
2044* Checks for stateid operations 2044* Checks for stateid operations
2045*/ 2045*/
2046int 2046__be32
2047nfs4_preprocess_stateid_op(struct svc_fh *current_fh, stateid_t *stateid, int flags, struct file **filpp) 2047nfs4_preprocess_stateid_op(struct svc_fh *current_fh, stateid_t *stateid, int flags, struct file **filpp)
2048{ 2048{
2049 struct nfs4_stateid *stp = NULL; 2049 struct nfs4_stateid *stp = NULL;
2050 struct nfs4_delegation *dp = NULL; 2050 struct nfs4_delegation *dp = NULL;
2051 stateid_t *stidp; 2051 stateid_t *stidp;
2052 struct inode *ino = current_fh->fh_dentry->d_inode; 2052 struct inode *ino = current_fh->fh_dentry->d_inode;
2053 int status; 2053 __be32 status;
2054 2054
2055 dprintk("NFSD: preprocess_stateid_op: stateid = (%08x/%08x/%08x/%08x)\n", 2055 dprintk("NFSD: preprocess_stateid_op: stateid = (%08x/%08x/%08x/%08x)\n",
2056 stateid->si_boot, stateid->si_stateownerid, 2056 stateid->si_boot, stateid->si_stateownerid,
@@ -2125,7 +2125,7 @@ setlkflg (int type)
2125/* 2125/*
2126 * Checks for sequence id mutating operations. 2126 * Checks for sequence id mutating operations.
2127 */ 2127 */
2128static int 2128static __be32
2129nfs4_preprocess_seqid_op(struct svc_fh *current_fh, u32 seqid, stateid_t *stateid, int flags, struct nfs4_stateowner **sopp, struct nfs4_stateid **stpp, struct nfsd4_lock *lock) 2129nfs4_preprocess_seqid_op(struct svc_fh *current_fh, u32 seqid, stateid_t *stateid, int flags, struct nfs4_stateowner **sopp, struct nfs4_stateid **stpp, struct nfsd4_lock *lock)
2130{ 2130{
2131 struct nfs4_stateid *stp; 2131 struct nfs4_stateid *stp;
@@ -2169,7 +2169,7 @@ nfs4_preprocess_seqid_op(struct svc_fh *current_fh, u32 seqid, stateid_t *statei
2169 clientid_t *lockclid = &lock->v.new.clientid; 2169 clientid_t *lockclid = &lock->v.new.clientid;
2170 struct nfs4_client *clp = sop->so_client; 2170 struct nfs4_client *clp = sop->so_client;
2171 int lkflg = 0; 2171 int lkflg = 0;
2172 int status; 2172 __be32 status;
2173 2173
2174 lkflg = setlkflg(lock->lk_type); 2174 lkflg = setlkflg(lock->lk_type);
2175 2175
@@ -2233,7 +2233,7 @@ check_replay:
2233 if (seqid == sop->so_seqid - 1) { 2233 if (seqid == sop->so_seqid - 1) {
2234 dprintk("NFSD: preprocess_seqid_op: retransmission?\n"); 2234 dprintk("NFSD: preprocess_seqid_op: retransmission?\n");
2235 /* indicate replay to calling function */ 2235 /* indicate replay to calling function */
2236 return NFSERR_REPLAY_ME; 2236 return nfserr_replay_me;
2237 } 2237 }
2238 printk("NFSD: preprocess_seqid_op: bad seqid (expected %d, got %d)\n", 2238 printk("NFSD: preprocess_seqid_op: bad seqid (expected %d, got %d)\n",
2239 sop->so_seqid, seqid); 2239 sop->so_seqid, seqid);
@@ -2241,10 +2241,10 @@ check_replay:
2241 return nfserr_bad_seqid; 2241 return nfserr_bad_seqid;
2242} 2242}
2243 2243
2244int 2244__be32
2245nfsd4_open_confirm(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open_confirm *oc, struct nfs4_stateowner **replay_owner) 2245nfsd4_open_confirm(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open_confirm *oc, struct nfs4_stateowner **replay_owner)
2246{ 2246{
2247 int status; 2247 __be32 status;
2248 struct nfs4_stateowner *sop; 2248 struct nfs4_stateowner *sop;
2249 struct nfs4_stateid *stp; 2249 struct nfs4_stateid *stp;
2250 2250
@@ -2310,10 +2310,10 @@ reset_union_bmap_deny(unsigned long deny, unsigned long *bmap)
2310 } 2310 }
2311} 2311}
2312 2312
2313int 2313__be32
2314nfsd4_open_downgrade(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open_downgrade *od, struct nfs4_stateowner **replay_owner) 2314nfsd4_open_downgrade(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open_downgrade *od, struct nfs4_stateowner **replay_owner)
2315{ 2315{
2316 int status; 2316 __be32 status;
2317 struct nfs4_stateid *stp; 2317 struct nfs4_stateid *stp;
2318 unsigned int share_access; 2318 unsigned int share_access;
2319 2319
@@ -2365,10 +2365,10 @@ out:
2365/* 2365/*
2366 * nfs4_unlock_state() called after encode 2366 * nfs4_unlock_state() called after encode
2367 */ 2367 */
2368int 2368__be32
2369nfsd4_close(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_close *close, struct nfs4_stateowner **replay_owner) 2369nfsd4_close(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_close *close, struct nfs4_stateowner **replay_owner)
2370{ 2370{
2371 int status; 2371 __be32 status;
2372 struct nfs4_stateid *stp; 2372 struct nfs4_stateid *stp;
2373 2373
2374 dprintk("NFSD: nfsd4_close on file %.*s\n", 2374 dprintk("NFSD: nfsd4_close on file %.*s\n",
@@ -2404,10 +2404,10 @@ out:
2404 return status; 2404 return status;
2405} 2405}
2406 2406
2407int 2407__be32
2408nfsd4_delegreturn(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_delegreturn *dr) 2408nfsd4_delegreturn(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_delegreturn *dr)
2409{ 2409{
2410 int status; 2410 __be32 status;
2411 2411
2412 if ((status = fh_verify(rqstp, current_fh, S_IFREG, 0))) 2412 if ((status = fh_verify(rqstp, current_fh, S_IFREG, 0)))
2413 goto out; 2413 goto out;
@@ -2635,7 +2635,7 @@ check_lock_length(u64 offset, u64 length)
2635/* 2635/*
2636 * LOCK operation 2636 * LOCK operation
2637 */ 2637 */
2638int 2638__be32
2639nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock *lock, struct nfs4_stateowner **replay_owner) 2639nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock *lock, struct nfs4_stateowner **replay_owner)
2640{ 2640{
2641 struct nfs4_stateowner *open_sop = NULL; 2641 struct nfs4_stateowner *open_sop = NULL;
@@ -2644,8 +2644,9 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
2644 struct file *filp; 2644 struct file *filp;
2645 struct file_lock file_lock; 2645 struct file_lock file_lock;
2646 struct file_lock conflock; 2646 struct file_lock conflock;
2647 int status = 0; 2647 __be32 status = 0;
2648 unsigned int strhashval; 2648 unsigned int strhashval;
2649 int err;
2649 2650
2650 dprintk("NFSD: nfsd4_lock: start=%Ld length=%Ld\n", 2651 dprintk("NFSD: nfsd4_lock: start=%Ld length=%Ld\n",
2651 (long long) lock->lk_offset, 2652 (long long) lock->lk_offset,
@@ -2758,13 +2759,14 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
2758 * locks_copy_lock: */ 2759 * locks_copy_lock: */
2759 conflock.fl_ops = NULL; 2760 conflock.fl_ops = NULL;
2760 conflock.fl_lmops = NULL; 2761 conflock.fl_lmops = NULL;
2761 status = posix_lock_file_conf(filp, &file_lock, &conflock); 2762 err = posix_lock_file_conf(filp, &file_lock, &conflock);
2762 dprintk("NFSD: nfsd4_lock: posix_lock_file_conf status %d\n",status); 2763 dprintk("NFSD: nfsd4_lock: posix_lock_file_conf status %d\n",status);
2763 switch (-status) { 2764 switch (-err) {
2764 case 0: /* success! */ 2765 case 0: /* success! */
2765 update_stateid(&lock_stp->st_stateid); 2766 update_stateid(&lock_stp->st_stateid);
2766 memcpy(&lock->lk_resp_stateid, &lock_stp->st_stateid, 2767 memcpy(&lock->lk_resp_stateid, &lock_stp->st_stateid,
2767 sizeof(stateid_t)); 2768 sizeof(stateid_t));
2769 status = 0;
2768 break; 2770 break;
2769 case (EAGAIN): /* conflock holds conflicting lock */ 2771 case (EAGAIN): /* conflock holds conflicting lock */
2770 status = nfserr_denied; 2772 status = nfserr_denied;
@@ -2775,7 +2777,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
2775 status = nfserr_deadlock; 2777 status = nfserr_deadlock;
2776 break; 2778 break;
2777 default: 2779 default:
2778 dprintk("NFSD: nfsd4_lock: posix_lock_file_conf() failed! status %d\n",status); 2780 dprintk("NFSD: nfsd4_lock: posix_lock_file_conf() failed! status %d\n",err);
2779 status = nfserr_resource; 2781 status = nfserr_resource;
2780 break; 2782 break;
2781 } 2783 }
@@ -2793,14 +2795,14 @@ out:
2793/* 2795/*
2794 * LOCKT operation 2796 * LOCKT operation
2795 */ 2797 */
2796int 2798__be32
2797nfsd4_lockt(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lockt *lockt) 2799nfsd4_lockt(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lockt *lockt)
2798{ 2800{
2799 struct inode *inode; 2801 struct inode *inode;
2800 struct file file; 2802 struct file file;
2801 struct file_lock file_lock; 2803 struct file_lock file_lock;
2802 struct file_lock conflock; 2804 struct file_lock conflock;
2803 int status; 2805 __be32 status;
2804 2806
2805 if (nfs4_in_grace()) 2807 if (nfs4_in_grace())
2806 return nfserr_grace; 2808 return nfserr_grace;
@@ -2873,13 +2875,14 @@ out:
2873 return status; 2875 return status;
2874} 2876}
2875 2877
2876int 2878__be32
2877nfsd4_locku(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_locku *locku, struct nfs4_stateowner **replay_owner) 2879nfsd4_locku(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_locku *locku, struct nfs4_stateowner **replay_owner)
2878{ 2880{
2879 struct nfs4_stateid *stp; 2881 struct nfs4_stateid *stp;
2880 struct file *filp = NULL; 2882 struct file *filp = NULL;
2881 struct file_lock file_lock; 2883 struct file_lock file_lock;
2882 int status; 2884 __be32 status;
2885 int err;
2883 2886
2884 dprintk("NFSD: nfsd4_locku: start=%Ld length=%Ld\n", 2887 dprintk("NFSD: nfsd4_locku: start=%Ld length=%Ld\n",
2885 (long long) locku->lu_offset, 2888 (long long) locku->lu_offset,
@@ -2917,8 +2920,8 @@ nfsd4_locku(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
2917 /* 2920 /*
2918 * Try to unlock the file in the VFS. 2921 * Try to unlock the file in the VFS.
2919 */ 2922 */
2920 status = posix_lock_file(filp, &file_lock); 2923 err = posix_lock_file(filp, &file_lock);
2921 if (status) { 2924 if (err) {
2922 dprintk("NFSD: nfs4_locku: posix_lock_file failed!\n"); 2925 dprintk("NFSD: nfs4_locku: posix_lock_file failed!\n");
2923 goto out_nfserr; 2926 goto out_nfserr;
2924 } 2927 }
@@ -2937,7 +2940,7 @@ out:
2937 return status; 2940 return status;
2938 2941
2939out_nfserr: 2942out_nfserr:
2940 status = nfserrno(status); 2943 status = nfserrno(err);
2941 goto out; 2944 goto out;
2942} 2945}
2943 2946
@@ -2965,7 +2968,7 @@ out:
2965 return status; 2968 return status;
2966} 2969}
2967 2970
2968int 2971__be32
2969nfsd4_release_lockowner(struct svc_rqst *rqstp, struct nfsd4_release_lockowner *rlockowner) 2972nfsd4_release_lockowner(struct svc_rqst *rqstp, struct nfsd4_release_lockowner *rlockowner)
2970{ 2973{
2971 clientid_t *clid = &rlockowner->rl_clientid; 2974 clientid_t *clid = &rlockowner->rl_clientid;
@@ -2974,7 +2977,7 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp, struct nfsd4_release_lockowner *
2974 struct xdr_netobj *owner = &rlockowner->rl_owner; 2977 struct xdr_netobj *owner = &rlockowner->rl_owner;
2975 struct list_head matches; 2978 struct list_head matches;
2976 int i; 2979 int i;
2977 int status; 2980 __be32 status;
2978 2981
2979 dprintk("nfsd4_release_lockowner clientid: (%08x/%08x):\n", 2982 dprintk("nfsd4_release_lockowner clientid: (%08x/%08x):\n",
2980 clid->cl_boot, clid->cl_id); 2983 clid->cl_boot, clid->cl_id);
@@ -3111,7 +3114,7 @@ nfs4_find_reclaim_client(clientid_t *clid)
3111/* 3114/*
3112* Called from OPEN. Look for clientid in reclaim list. 3115* Called from OPEN. Look for clientid in reclaim list.
3113*/ 3116*/
3114int 3117__be32
3115nfs4_check_open_reclaim(clientid_t *clid) 3118nfs4_check_open_reclaim(clientid_t *clid)
3116{ 3119{
3117 return nfs4_find_reclaim_client(clid) ? nfs_ok : nfserr_reclaim_bad; 3120 return nfs4_find_reclaim_client(clid) ? nfs_ok : nfserr_reclaim_bad;
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 5be00436b5b8..f3f239db04bb 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -60,8 +60,16 @@
60 60
61#define NFSDDBG_FACILITY NFSDDBG_XDR 61#define NFSDDBG_FACILITY NFSDDBG_XDR
62 62
63static int 63/*
64check_filename(char *str, int len, int err) 64 * As per referral draft, the fsid for a referral MUST be different from the fsid of the containing
65 * directory in order to indicate to the client that a filesystem boundary is present
66 * We use a fixed fsid for a referral
67 */
68#define NFS4_REFERRAL_FSID_MAJOR 0x8000000ULL
69#define NFS4_REFERRAL_FSID_MINOR 0x8000000ULL
70
71static __be32
72check_filename(char *str, int len, __be32 err)
65{ 73{
66 int i; 74 int i;
67 75
@@ -86,8 +94,8 @@ check_filename(char *str, int len, int err)
86 * consistent with the style used in NFSv2/v3... 94 * consistent with the style used in NFSv2/v3...
87 */ 95 */
88#define DECODE_HEAD \ 96#define DECODE_HEAD \
89 u32 *p; \ 97 __be32 *p; \
90 int status 98 __be32 status
91#define DECODE_TAIL \ 99#define DECODE_TAIL \
92 status = 0; \ 100 status = 0; \
93out: \ 101out: \
@@ -136,13 +144,13 @@ xdr_error: \
136 } \ 144 } \
137} while (0) 145} while (0)
138 146
139static u32 *read_buf(struct nfsd4_compoundargs *argp, int nbytes) 147static __be32 *read_buf(struct nfsd4_compoundargs *argp, int nbytes)
140{ 148{
141 /* We want more bytes than seem to be available. 149 /* We want more bytes than seem to be available.
142 * Maybe we need a new page, maybe we have just run out 150 * Maybe we need a new page, maybe we have just run out
143 */ 151 */
144 int avail = (char*)argp->end - (char*)argp->p; 152 int avail = (char*)argp->end - (char*)argp->p;
145 u32 *p; 153 __be32 *p;
146 if (avail + argp->pagelen < nbytes) 154 if (avail + argp->pagelen < nbytes)
147 return NULL; 155 return NULL;
148 if (avail + PAGE_SIZE < nbytes) /* need more than a page !! */ 156 if (avail + PAGE_SIZE < nbytes) /* need more than a page !! */
@@ -189,7 +197,7 @@ defer_free(struct nfsd4_compoundargs *argp,
189 return 0; 197 return 0;
190} 198}
191 199
192static char *savemem(struct nfsd4_compoundargs *argp, u32 *p, int nbytes) 200static char *savemem(struct nfsd4_compoundargs *argp, __be32 *p, int nbytes)
193{ 201{
194 void *new = NULL; 202 void *new = NULL;
195 if (p == argp->tmp) { 203 if (p == argp->tmp) {
@@ -209,7 +217,7 @@ static char *savemem(struct nfsd4_compoundargs *argp, u32 *p, int nbytes)
209} 217}
210 218
211 219
212static int 220static __be32
213nfsd4_decode_bitmap(struct nfsd4_compoundargs *argp, u32 *bmval) 221nfsd4_decode_bitmap(struct nfsd4_compoundargs *argp, u32 *bmval)
214{ 222{
215 u32 bmlen; 223 u32 bmlen;
@@ -232,13 +240,14 @@ nfsd4_decode_bitmap(struct nfsd4_compoundargs *argp, u32 *bmval)
232 DECODE_TAIL; 240 DECODE_TAIL;
233} 241}
234 242
235static int 243static __be32
236nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, struct iattr *iattr, 244nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, struct iattr *iattr,
237 struct nfs4_acl **acl) 245 struct nfs4_acl **acl)
238{ 246{
239 int expected_len, len = 0; 247 int expected_len, len = 0;
240 u32 dummy32; 248 u32 dummy32;
241 char *buf; 249 char *buf;
250 int host_err;
242 251
243 DECODE_HEAD; 252 DECODE_HEAD;
244 iattr->ia_valid = 0; 253 iattr->ia_valid = 0;
@@ -272,7 +281,7 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, struct iattr *ia
272 281
273 *acl = nfs4_acl_new(); 282 *acl = nfs4_acl_new();
274 if (*acl == NULL) { 283 if (*acl == NULL) {
275 status = -ENOMEM; 284 host_err = -ENOMEM;
276 goto out_nfserr; 285 goto out_nfserr;
277 } 286 }
278 defer_free(argp, (void (*)(const void *))nfs4_acl_free, *acl); 287 defer_free(argp, (void (*)(const void *))nfs4_acl_free, *acl);
@@ -287,20 +296,20 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, struct iattr *ia
287 len += XDR_QUADLEN(dummy32) << 2; 296 len += XDR_QUADLEN(dummy32) << 2;
288 READMEM(buf, dummy32); 297 READMEM(buf, dummy32);
289 ace.whotype = nfs4_acl_get_whotype(buf, dummy32); 298 ace.whotype = nfs4_acl_get_whotype(buf, dummy32);
290 status = 0; 299 host_err = 0;
291 if (ace.whotype != NFS4_ACL_WHO_NAMED) 300 if (ace.whotype != NFS4_ACL_WHO_NAMED)
292 ace.who = 0; 301 ace.who = 0;
293 else if (ace.flag & NFS4_ACE_IDENTIFIER_GROUP) 302 else if (ace.flag & NFS4_ACE_IDENTIFIER_GROUP)
294 status = nfsd_map_name_to_gid(argp->rqstp, 303 host_err = nfsd_map_name_to_gid(argp->rqstp,
295 buf, dummy32, &ace.who); 304 buf, dummy32, &ace.who);
296 else 305 else
297 status = nfsd_map_name_to_uid(argp->rqstp, 306 host_err = nfsd_map_name_to_uid(argp->rqstp,
298 buf, dummy32, &ace.who); 307 buf, dummy32, &ace.who);
299 if (status) 308 if (host_err)
300 goto out_nfserr; 309 goto out_nfserr;
301 status = nfs4_acl_add_ace(*acl, ace.type, ace.flag, 310 host_err = nfs4_acl_add_ace(*acl, ace.type, ace.flag,
302 ace.access_mask, ace.whotype, ace.who); 311 ace.access_mask, ace.whotype, ace.who);
303 if (status) 312 if (host_err)
304 goto out_nfserr; 313 goto out_nfserr;
305 } 314 }
306 } else 315 } else
@@ -319,7 +328,7 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, struct iattr *ia
319 READ_BUF(dummy32); 328 READ_BUF(dummy32);
320 len += (XDR_QUADLEN(dummy32) << 2); 329 len += (XDR_QUADLEN(dummy32) << 2);
321 READMEM(buf, dummy32); 330 READMEM(buf, dummy32);
322 if ((status = nfsd_map_name_to_uid(argp->rqstp, buf, dummy32, &iattr->ia_uid))) 331 if ((host_err = nfsd_map_name_to_uid(argp->rqstp, buf, dummy32, &iattr->ia_uid)))
323 goto out_nfserr; 332 goto out_nfserr;
324 iattr->ia_valid |= ATTR_UID; 333 iattr->ia_valid |= ATTR_UID;
325 } 334 }
@@ -330,7 +339,7 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, struct iattr *ia
330 READ_BUF(dummy32); 339 READ_BUF(dummy32);
331 len += (XDR_QUADLEN(dummy32) << 2); 340 len += (XDR_QUADLEN(dummy32) << 2);
332 READMEM(buf, dummy32); 341 READMEM(buf, dummy32);
333 if ((status = nfsd_map_name_to_gid(argp->rqstp, buf, dummy32, &iattr->ia_gid))) 342 if ((host_err = nfsd_map_name_to_gid(argp->rqstp, buf, dummy32, &iattr->ia_gid)))
334 goto out_nfserr; 343 goto out_nfserr;
335 iattr->ia_valid |= ATTR_GID; 344 iattr->ia_valid |= ATTR_GID;
336 } 345 }
@@ -406,11 +415,11 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, struct iattr *ia
406 DECODE_TAIL; 415 DECODE_TAIL;
407 416
408out_nfserr: 417out_nfserr:
409 status = nfserrno(status); 418 status = nfserrno(host_err);
410 goto out; 419 goto out;
411} 420}
412 421
413static int 422static __be32
414nfsd4_decode_access(struct nfsd4_compoundargs *argp, struct nfsd4_access *access) 423nfsd4_decode_access(struct nfsd4_compoundargs *argp, struct nfsd4_access *access)
415{ 424{
416 DECODE_HEAD; 425 DECODE_HEAD;
@@ -421,7 +430,7 @@ nfsd4_decode_access(struct nfsd4_compoundargs *argp, struct nfsd4_access *access
421 DECODE_TAIL; 430 DECODE_TAIL;
422} 431}
423 432
424static int 433static __be32
425nfsd4_decode_close(struct nfsd4_compoundargs *argp, struct nfsd4_close *close) 434nfsd4_decode_close(struct nfsd4_compoundargs *argp, struct nfsd4_close *close)
426{ 435{
427 DECODE_HEAD; 436 DECODE_HEAD;
@@ -436,7 +445,7 @@ nfsd4_decode_close(struct nfsd4_compoundargs *argp, struct nfsd4_close *close)
436} 445}
437 446
438 447
439static int 448static __be32
440nfsd4_decode_commit(struct nfsd4_compoundargs *argp, struct nfsd4_commit *commit) 449nfsd4_decode_commit(struct nfsd4_compoundargs *argp, struct nfsd4_commit *commit)
441{ 450{
442 DECODE_HEAD; 451 DECODE_HEAD;
@@ -448,7 +457,7 @@ nfsd4_decode_commit(struct nfsd4_compoundargs *argp, struct nfsd4_commit *commit
448 DECODE_TAIL; 457 DECODE_TAIL;
449} 458}
450 459
451static int 460static __be32
452nfsd4_decode_create(struct nfsd4_compoundargs *argp, struct nfsd4_create *create) 461nfsd4_decode_create(struct nfsd4_compoundargs *argp, struct nfsd4_create *create)
453{ 462{
454 DECODE_HEAD; 463 DECODE_HEAD;
@@ -488,7 +497,7 @@ nfsd4_decode_create(struct nfsd4_compoundargs *argp, struct nfsd4_create *create
488 DECODE_TAIL; 497 DECODE_TAIL;
489} 498}
490 499
491static inline int 500static inline __be32
492nfsd4_decode_delegreturn(struct nfsd4_compoundargs *argp, struct nfsd4_delegreturn *dr) 501nfsd4_decode_delegreturn(struct nfsd4_compoundargs *argp, struct nfsd4_delegreturn *dr)
493{ 502{
494 DECODE_HEAD; 503 DECODE_HEAD;
@@ -500,13 +509,13 @@ nfsd4_decode_delegreturn(struct nfsd4_compoundargs *argp, struct nfsd4_delegretu
500 DECODE_TAIL; 509 DECODE_TAIL;
501} 510}
502 511
503static inline int 512static inline __be32
504nfsd4_decode_getattr(struct nfsd4_compoundargs *argp, struct nfsd4_getattr *getattr) 513nfsd4_decode_getattr(struct nfsd4_compoundargs *argp, struct nfsd4_getattr *getattr)
505{ 514{
506 return nfsd4_decode_bitmap(argp, getattr->ga_bmval); 515 return nfsd4_decode_bitmap(argp, getattr->ga_bmval);
507} 516}
508 517
509static int 518static __be32
510nfsd4_decode_link(struct nfsd4_compoundargs *argp, struct nfsd4_link *link) 519nfsd4_decode_link(struct nfsd4_compoundargs *argp, struct nfsd4_link *link)
511{ 520{
512 DECODE_HEAD; 521 DECODE_HEAD;
@@ -521,7 +530,7 @@ nfsd4_decode_link(struct nfsd4_compoundargs *argp, struct nfsd4_link *link)
521 DECODE_TAIL; 530 DECODE_TAIL;
522} 531}
523 532
524static int 533static __be32
525nfsd4_decode_lock(struct nfsd4_compoundargs *argp, struct nfsd4_lock *lock) 534nfsd4_decode_lock(struct nfsd4_compoundargs *argp, struct nfsd4_lock *lock)
526{ 535{
527 DECODE_HEAD; 536 DECODE_HEAD;
@@ -560,7 +569,7 @@ nfsd4_decode_lock(struct nfsd4_compoundargs *argp, struct nfsd4_lock *lock)
560 DECODE_TAIL; 569 DECODE_TAIL;
561} 570}
562 571
563static int 572static __be32
564nfsd4_decode_lockt(struct nfsd4_compoundargs *argp, struct nfsd4_lockt *lockt) 573nfsd4_decode_lockt(struct nfsd4_compoundargs *argp, struct nfsd4_lockt *lockt)
565{ 574{
566 DECODE_HEAD; 575 DECODE_HEAD;
@@ -579,7 +588,7 @@ nfsd4_decode_lockt(struct nfsd4_compoundargs *argp, struct nfsd4_lockt *lockt)
579 DECODE_TAIL; 588 DECODE_TAIL;
580} 589}
581 590
582static int 591static __be32
583nfsd4_decode_locku(struct nfsd4_compoundargs *argp, struct nfsd4_locku *locku) 592nfsd4_decode_locku(struct nfsd4_compoundargs *argp, struct nfsd4_locku *locku)
584{ 593{
585 DECODE_HEAD; 594 DECODE_HEAD;
@@ -598,7 +607,7 @@ nfsd4_decode_locku(struct nfsd4_compoundargs *argp, struct nfsd4_locku *locku)
598 DECODE_TAIL; 607 DECODE_TAIL;
599} 608}
600 609
601static int 610static __be32
602nfsd4_decode_lookup(struct nfsd4_compoundargs *argp, struct nfsd4_lookup *lookup) 611nfsd4_decode_lookup(struct nfsd4_compoundargs *argp, struct nfsd4_lookup *lookup)
603{ 612{
604 DECODE_HEAD; 613 DECODE_HEAD;
@@ -613,7 +622,7 @@ nfsd4_decode_lookup(struct nfsd4_compoundargs *argp, struct nfsd4_lookup *lookup
613 DECODE_TAIL; 622 DECODE_TAIL;
614} 623}
615 624
616static int 625static __be32
617nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open) 626nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
618{ 627{
619 DECODE_HEAD; 628 DECODE_HEAD;
@@ -691,7 +700,7 @@ nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
691 DECODE_TAIL; 700 DECODE_TAIL;
692} 701}
693 702
694static int 703static __be32
695nfsd4_decode_open_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_open_confirm *open_conf) 704nfsd4_decode_open_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_open_confirm *open_conf)
696{ 705{
697 DECODE_HEAD; 706 DECODE_HEAD;
@@ -705,7 +714,7 @@ nfsd4_decode_open_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_open_con
705 DECODE_TAIL; 714 DECODE_TAIL;
706} 715}
707 716
708static int 717static __be32
709nfsd4_decode_open_downgrade(struct nfsd4_compoundargs *argp, struct nfsd4_open_downgrade *open_down) 718nfsd4_decode_open_downgrade(struct nfsd4_compoundargs *argp, struct nfsd4_open_downgrade *open_down)
710{ 719{
711 DECODE_HEAD; 720 DECODE_HEAD;
@@ -721,7 +730,7 @@ nfsd4_decode_open_downgrade(struct nfsd4_compoundargs *argp, struct nfsd4_open_d
721 DECODE_TAIL; 730 DECODE_TAIL;
722} 731}
723 732
724static int 733static __be32
725nfsd4_decode_putfh(struct nfsd4_compoundargs *argp, struct nfsd4_putfh *putfh) 734nfsd4_decode_putfh(struct nfsd4_compoundargs *argp, struct nfsd4_putfh *putfh)
726{ 735{
727 DECODE_HEAD; 736 DECODE_HEAD;
@@ -736,7 +745,7 @@ nfsd4_decode_putfh(struct nfsd4_compoundargs *argp, struct nfsd4_putfh *putfh)
736 DECODE_TAIL; 745 DECODE_TAIL;
737} 746}
738 747
739static int 748static __be32
740nfsd4_decode_read(struct nfsd4_compoundargs *argp, struct nfsd4_read *read) 749nfsd4_decode_read(struct nfsd4_compoundargs *argp, struct nfsd4_read *read)
741{ 750{
742 DECODE_HEAD; 751 DECODE_HEAD;
@@ -750,7 +759,7 @@ nfsd4_decode_read(struct nfsd4_compoundargs *argp, struct nfsd4_read *read)
750 DECODE_TAIL; 759 DECODE_TAIL;
751} 760}
752 761
753static int 762static __be32
754nfsd4_decode_readdir(struct nfsd4_compoundargs *argp, struct nfsd4_readdir *readdir) 763nfsd4_decode_readdir(struct nfsd4_compoundargs *argp, struct nfsd4_readdir *readdir)
755{ 764{
756 DECODE_HEAD; 765 DECODE_HEAD;
@@ -766,7 +775,7 @@ nfsd4_decode_readdir(struct nfsd4_compoundargs *argp, struct nfsd4_readdir *read
766 DECODE_TAIL; 775 DECODE_TAIL;
767} 776}
768 777
769static int 778static __be32
770nfsd4_decode_remove(struct nfsd4_compoundargs *argp, struct nfsd4_remove *remove) 779nfsd4_decode_remove(struct nfsd4_compoundargs *argp, struct nfsd4_remove *remove)
771{ 780{
772 DECODE_HEAD; 781 DECODE_HEAD;
@@ -781,7 +790,7 @@ nfsd4_decode_remove(struct nfsd4_compoundargs *argp, struct nfsd4_remove *remove
781 DECODE_TAIL; 790 DECODE_TAIL;
782} 791}
783 792
784static int 793static __be32
785nfsd4_decode_rename(struct nfsd4_compoundargs *argp, struct nfsd4_rename *rename) 794nfsd4_decode_rename(struct nfsd4_compoundargs *argp, struct nfsd4_rename *rename)
786{ 795{
787 DECODE_HEAD; 796 DECODE_HEAD;
@@ -801,7 +810,7 @@ nfsd4_decode_rename(struct nfsd4_compoundargs *argp, struct nfsd4_rename *rename
801 DECODE_TAIL; 810 DECODE_TAIL;
802} 811}
803 812
804static int 813static __be32
805nfsd4_decode_renew(struct nfsd4_compoundargs *argp, clientid_t *clientid) 814nfsd4_decode_renew(struct nfsd4_compoundargs *argp, clientid_t *clientid)
806{ 815{
807 DECODE_HEAD; 816 DECODE_HEAD;
@@ -812,7 +821,7 @@ nfsd4_decode_renew(struct nfsd4_compoundargs *argp, clientid_t *clientid)
812 DECODE_TAIL; 821 DECODE_TAIL;
813} 822}
814 823
815static int 824static __be32
816nfsd4_decode_setattr(struct nfsd4_compoundargs *argp, struct nfsd4_setattr *setattr) 825nfsd4_decode_setattr(struct nfsd4_compoundargs *argp, struct nfsd4_setattr *setattr)
817{ 826{
818 DECODE_HEAD; 827 DECODE_HEAD;
@@ -826,7 +835,7 @@ nfsd4_decode_setattr(struct nfsd4_compoundargs *argp, struct nfsd4_setattr *seta
826 DECODE_TAIL; 835 DECODE_TAIL;
827} 836}
828 837
829static int 838static __be32
830nfsd4_decode_setclientid(struct nfsd4_compoundargs *argp, struct nfsd4_setclientid *setclientid) 839nfsd4_decode_setclientid(struct nfsd4_compoundargs *argp, struct nfsd4_setclientid *setclientid)
831{ 840{
832 DECODE_HEAD; 841 DECODE_HEAD;
@@ -851,7 +860,7 @@ nfsd4_decode_setclientid(struct nfsd4_compoundargs *argp, struct nfsd4_setclient
851 DECODE_TAIL; 860 DECODE_TAIL;
852} 861}
853 862
854static int 863static __be32
855nfsd4_decode_setclientid_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_setclientid_confirm *scd_c) 864nfsd4_decode_setclientid_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_setclientid_confirm *scd_c)
856{ 865{
857 DECODE_HEAD; 866 DECODE_HEAD;
@@ -864,7 +873,7 @@ nfsd4_decode_setclientid_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_s
864} 873}
865 874
866/* Also used for NVERIFY */ 875/* Also used for NVERIFY */
867static int 876static __be32
868nfsd4_decode_verify(struct nfsd4_compoundargs *argp, struct nfsd4_verify *verify) 877nfsd4_decode_verify(struct nfsd4_compoundargs *argp, struct nfsd4_verify *verify)
869{ 878{
870#if 0 879#if 0
@@ -900,7 +909,7 @@ nfsd4_decode_verify(struct nfsd4_compoundargs *argp, struct nfsd4_verify *verify
900 DECODE_TAIL; 909 DECODE_TAIL;
901} 910}
902 911
903static int 912static __be32
904nfsd4_decode_write(struct nfsd4_compoundargs *argp, struct nfsd4_write *write) 913nfsd4_decode_write(struct nfsd4_compoundargs *argp, struct nfsd4_write *write)
905{ 914{
906 int avail; 915 int avail;
@@ -926,32 +935,32 @@ nfsd4_decode_write(struct nfsd4_compoundargs *argp, struct nfsd4_write *write)
926 printk(KERN_NOTICE "xdr error! (%s:%d)\n", __FILE__, __LINE__); 935 printk(KERN_NOTICE "xdr error! (%s:%d)\n", __FILE__, __LINE__);
927 goto xdr_error; 936 goto xdr_error;
928 } 937 }
929 write->wr_vec[0].iov_base = p; 938 argp->rqstp->rq_vec[0].iov_base = p;
930 write->wr_vec[0].iov_len = avail; 939 argp->rqstp->rq_vec[0].iov_len = avail;
931 v = 0; 940 v = 0;
932 len = write->wr_buflen; 941 len = write->wr_buflen;
933 while (len > write->wr_vec[v].iov_len) { 942 while (len > argp->rqstp->rq_vec[v].iov_len) {
934 len -= write->wr_vec[v].iov_len; 943 len -= argp->rqstp->rq_vec[v].iov_len;
935 v++; 944 v++;
936 write->wr_vec[v].iov_base = page_address(argp->pagelist[0]); 945 argp->rqstp->rq_vec[v].iov_base = page_address(argp->pagelist[0]);
937 argp->pagelist++; 946 argp->pagelist++;
938 if (argp->pagelen >= PAGE_SIZE) { 947 if (argp->pagelen >= PAGE_SIZE) {
939 write->wr_vec[v].iov_len = PAGE_SIZE; 948 argp->rqstp->rq_vec[v].iov_len = PAGE_SIZE;
940 argp->pagelen -= PAGE_SIZE; 949 argp->pagelen -= PAGE_SIZE;
941 } else { 950 } else {
942 write->wr_vec[v].iov_len = argp->pagelen; 951 argp->rqstp->rq_vec[v].iov_len = argp->pagelen;
943 argp->pagelen -= len; 952 argp->pagelen -= len;
944 } 953 }
945 } 954 }
946 argp->end = (u32*) (write->wr_vec[v].iov_base + write->wr_vec[v].iov_len); 955 argp->end = (__be32*) (argp->rqstp->rq_vec[v].iov_base + argp->rqstp->rq_vec[v].iov_len);
947 argp->p = (u32*) (write->wr_vec[v].iov_base + (XDR_QUADLEN(len) << 2)); 956 argp->p = (__be32*) (argp->rqstp->rq_vec[v].iov_base + (XDR_QUADLEN(len) << 2));
948 write->wr_vec[v].iov_len = len; 957 argp->rqstp->rq_vec[v].iov_len = len;
949 write->wr_vlen = v+1; 958 write->wr_vlen = v+1;
950 959
951 DECODE_TAIL; 960 DECODE_TAIL;
952} 961}
953 962
954static int 963static __be32
955nfsd4_decode_release_lockowner(struct nfsd4_compoundargs *argp, struct nfsd4_release_lockowner *rlockowner) 964nfsd4_decode_release_lockowner(struct nfsd4_compoundargs *argp, struct nfsd4_release_lockowner *rlockowner)
956{ 965{
957 DECODE_HEAD; 966 DECODE_HEAD;
@@ -965,7 +974,7 @@ nfsd4_decode_release_lockowner(struct nfsd4_compoundargs *argp, struct nfsd4_rel
965 DECODE_TAIL; 974 DECODE_TAIL;
966} 975}
967 976
968static int 977static __be32
969nfsd4_decode_compound(struct nfsd4_compoundargs *argp) 978nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
970{ 979{
971 DECODE_HEAD; 980 DECODE_HEAD;
@@ -1171,7 +1180,7 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
1171 * task to translate them into Linux-specific versions which are more 1180 * task to translate them into Linux-specific versions which are more
1172 * consistent with the style used in NFSv2/v3... 1181 * consistent with the style used in NFSv2/v3...
1173 */ 1182 */
1174#define ENCODE_HEAD u32 *p 1183#define ENCODE_HEAD __be32 *p
1175 1184
1176#define WRITE32(n) *p++ = htonl(n) 1185#define WRITE32(n) *p++ = htonl(n)
1177#define WRITE64(n) do { \ 1186#define WRITE64(n) do { \
@@ -1201,8 +1210,8 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
1201 * Header routine to setup seqid operation replay cache 1210 * Header routine to setup seqid operation replay cache
1202 */ 1211 */
1203#define ENCODE_SEQID_OP_HEAD \ 1212#define ENCODE_SEQID_OP_HEAD \
1204 u32 *p; \ 1213 __be32 *p; \
1205 u32 *save; \ 1214 __be32 *save; \
1206 \ 1215 \
1207 save = resp->p; 1216 save = resp->p;
1208 1217
@@ -1223,6 +1232,120 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
1223 stateowner->so_replay.rp_buflen); \ 1232 stateowner->so_replay.rp_buflen); \
1224 } } while (0); 1233 } } while (0);
1225 1234
1235/* Encode as an array of strings the string given with components
1236 * seperated @sep.
1237 */
1238static __be32 nfsd4_encode_components(char sep, char *components,
1239 __be32 **pp, int *buflen)
1240{
1241 __be32 *p = *pp;
1242 __be32 *countp = p;
1243 int strlen, count=0;
1244 char *str, *end;
1245
1246 dprintk("nfsd4_encode_components(%s)\n", components);
1247 if ((*buflen -= 4) < 0)
1248 return nfserr_resource;
1249 WRITE32(0); /* We will fill this in with @count later */
1250 end = str = components;
1251 while (*end) {
1252 for (; *end && (*end != sep); end++)
1253 ; /* Point to end of component */
1254 strlen = end - str;
1255 if (strlen) {
1256 if ((*buflen -= ((XDR_QUADLEN(strlen) << 2) + 4)) < 0)
1257 return nfserr_resource;
1258 WRITE32(strlen);
1259 WRITEMEM(str, strlen);
1260 count++;
1261 }
1262 else
1263 end++;
1264 str = end;
1265 }
1266 *pp = p;
1267 p = countp;
1268 WRITE32(count);
1269 return 0;
1270}
1271
1272/*
1273 * encode a location element of a fs_locations structure
1274 */
1275static __be32 nfsd4_encode_fs_location4(struct nfsd4_fs_location *location,
1276 __be32 **pp, int *buflen)
1277{
1278 __be32 status;
1279 __be32 *p = *pp;
1280
1281 status = nfsd4_encode_components(':', location->hosts, &p, buflen);
1282 if (status)
1283 return status;
1284 status = nfsd4_encode_components('/', location->path, &p, buflen);
1285 if (status)
1286 return status;
1287 *pp = p;
1288 return 0;
1289}
1290
1291/*
1292 * Return the path to an export point in the pseudo filesystem namespace
1293 * Returned string is safe to use as long as the caller holds a reference
1294 * to @exp.
1295 */
1296static char *nfsd4_path(struct svc_rqst *rqstp, struct svc_export *exp, __be32 *stat)
1297{
1298 struct svc_fh tmp_fh;
1299 char *path, *rootpath;
1300
1301 fh_init(&tmp_fh, NFS4_FHSIZE);
1302 *stat = exp_pseudoroot(rqstp->rq_client, &tmp_fh, &rqstp->rq_chandle);
1303 if (*stat)
1304 return NULL;
1305 rootpath = tmp_fh.fh_export->ex_path;
1306
1307 path = exp->ex_path;
1308
1309 if (strncmp(path, rootpath, strlen(rootpath))) {
1310 printk("nfsd: fs_locations failed;"
1311 "%s is not contained in %s\n", path, rootpath);
1312 *stat = nfserr_notsupp;
1313 return NULL;
1314 }
1315
1316 return path + strlen(rootpath);
1317}
1318
1319/*
1320 * encode a fs_locations structure
1321 */
1322static __be32 nfsd4_encode_fs_locations(struct svc_rqst *rqstp,
1323 struct svc_export *exp,
1324 __be32 **pp, int *buflen)
1325{
1326 __be32 status;
1327 int i;
1328 __be32 *p = *pp;
1329 struct nfsd4_fs_locations *fslocs = &exp->ex_fslocs;
1330 char *root = nfsd4_path(rqstp, exp, &status);
1331
1332 if (status)
1333 return status;
1334 status = nfsd4_encode_components('/', root, &p, buflen);
1335 if (status)
1336 return status;
1337 if ((*buflen -= 4) < 0)
1338 return nfserr_resource;
1339 WRITE32(fslocs->locations_count);
1340 for (i=0; i<fslocs->locations_count; i++) {
1341 status = nfsd4_encode_fs_location4(&fslocs->locations[i],
1342 &p, buflen);
1343 if (status)
1344 return status;
1345 }
1346 *pp = p;
1347 return 0;
1348}
1226 1349
1227static u32 nfs4_ftypes[16] = { 1350static u32 nfs4_ftypes[16] = {
1228 NF4BAD, NF4FIFO, NF4CHR, NF4BAD, 1351 NF4BAD, NF4FIFO, NF4CHR, NF4BAD,
@@ -1231,9 +1354,9 @@ static u32 nfs4_ftypes[16] = {
1231 NF4SOCK, NF4BAD, NF4LNK, NF4BAD, 1354 NF4SOCK, NF4BAD, NF4LNK, NF4BAD,
1232}; 1355};
1233 1356
1234static int 1357static __be32
1235nfsd4_encode_name(struct svc_rqst *rqstp, int whotype, uid_t id, int group, 1358nfsd4_encode_name(struct svc_rqst *rqstp, int whotype, uid_t id, int group,
1236 u32 **p, int *buflen) 1359 __be32 **p, int *buflen)
1237{ 1360{
1238 int status; 1361 int status;
1239 1362
@@ -1253,25 +1376,44 @@ nfsd4_encode_name(struct svc_rqst *rqstp, int whotype, uid_t id, int group,
1253 return 0; 1376 return 0;
1254} 1377}
1255 1378
1256static inline int 1379static inline __be32
1257nfsd4_encode_user(struct svc_rqst *rqstp, uid_t uid, u32 **p, int *buflen) 1380nfsd4_encode_user(struct svc_rqst *rqstp, uid_t uid, __be32 **p, int *buflen)
1258{ 1381{
1259 return nfsd4_encode_name(rqstp, NFS4_ACL_WHO_NAMED, uid, 0, p, buflen); 1382 return nfsd4_encode_name(rqstp, NFS4_ACL_WHO_NAMED, uid, 0, p, buflen);
1260} 1383}
1261 1384
1262static inline int 1385static inline __be32
1263nfsd4_encode_group(struct svc_rqst *rqstp, uid_t gid, u32 **p, int *buflen) 1386nfsd4_encode_group(struct svc_rqst *rqstp, uid_t gid, __be32 **p, int *buflen)
1264{ 1387{
1265 return nfsd4_encode_name(rqstp, NFS4_ACL_WHO_NAMED, gid, 1, p, buflen); 1388 return nfsd4_encode_name(rqstp, NFS4_ACL_WHO_NAMED, gid, 1, p, buflen);
1266} 1389}
1267 1390
1268static inline int 1391static inline __be32
1269nfsd4_encode_aclname(struct svc_rqst *rqstp, int whotype, uid_t id, int group, 1392nfsd4_encode_aclname(struct svc_rqst *rqstp, int whotype, uid_t id, int group,
1270 u32 **p, int *buflen) 1393 __be32 **p, int *buflen)
1271{ 1394{
1272 return nfsd4_encode_name(rqstp, whotype, id, group, p, buflen); 1395 return nfsd4_encode_name(rqstp, whotype, id, group, p, buflen);
1273} 1396}
1274 1397
1398#define WORD0_ABSENT_FS_ATTRS (FATTR4_WORD0_FS_LOCATIONS | FATTR4_WORD0_FSID | \
1399 FATTR4_WORD0_RDATTR_ERROR)
1400#define WORD1_ABSENT_FS_ATTRS FATTR4_WORD1_MOUNTED_ON_FILEID
1401
1402static __be32 fattr_handle_absent_fs(u32 *bmval0, u32 *bmval1, u32 *rdattr_err)
1403{
1404 /* As per referral draft: */
1405 if (*bmval0 & ~WORD0_ABSENT_FS_ATTRS ||
1406 *bmval1 & ~WORD1_ABSENT_FS_ATTRS) {
1407 if (*bmval0 & FATTR4_WORD0_RDATTR_ERROR ||
1408 *bmval0 & FATTR4_WORD0_FS_LOCATIONS)
1409 *rdattr_err = NFSERR_MOVED;
1410 else
1411 return nfserr_moved;
1412 }
1413 *bmval0 &= WORD0_ABSENT_FS_ATTRS;
1414 *bmval1 &= WORD1_ABSENT_FS_ATTRS;
1415 return 0;
1416}
1275 1417
1276/* 1418/*
1277 * Note: @fhp can be NULL; in this case, we might have to compose the filehandle 1419 * Note: @fhp can be NULL; in this case, we might have to compose the filehandle
@@ -1280,9 +1422,9 @@ nfsd4_encode_aclname(struct svc_rqst *rqstp, int whotype, uid_t id, int group,
1280 * @countp is the buffer size in _words_; upon successful return this becomes 1422 * @countp is the buffer size in _words_; upon successful return this becomes
1281 * replaced with the number of words written. 1423 * replaced with the number of words written.
1282 */ 1424 */
1283int 1425__be32
1284nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp, 1426nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
1285 struct dentry *dentry, u32 *buffer, int *countp, u32 *bmval, 1427 struct dentry *dentry, __be32 *buffer, int *countp, u32 *bmval,
1286 struct svc_rqst *rqstp) 1428 struct svc_rqst *rqstp)
1287{ 1429{
1288 u32 bmval0 = bmval[0]; 1430 u32 bmval0 = bmval[0];
@@ -1291,11 +1433,13 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
1291 struct svc_fh tempfh; 1433 struct svc_fh tempfh;
1292 struct kstatfs statfs; 1434 struct kstatfs statfs;
1293 int buflen = *countp << 2; 1435 int buflen = *countp << 2;
1294 u32 *attrlenp; 1436 __be32 *attrlenp;
1295 u32 dummy; 1437 u32 dummy;
1296 u64 dummy64; 1438 u64 dummy64;
1297 u32 *p = buffer; 1439 u32 rdattr_err = 0;
1298 int status; 1440 __be32 *p = buffer;
1441 __be32 status;
1442 int err;
1299 int aclsupport = 0; 1443 int aclsupport = 0;
1300 struct nfs4_acl *acl = NULL; 1444 struct nfs4_acl *acl = NULL;
1301 1445
@@ -1303,14 +1447,20 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
1303 BUG_ON(bmval0 & ~NFSD_SUPPORTED_ATTRS_WORD0); 1447 BUG_ON(bmval0 & ~NFSD_SUPPORTED_ATTRS_WORD0);
1304 BUG_ON(bmval1 & ~NFSD_SUPPORTED_ATTRS_WORD1); 1448 BUG_ON(bmval1 & ~NFSD_SUPPORTED_ATTRS_WORD1);
1305 1449
1306 status = vfs_getattr(exp->ex_mnt, dentry, &stat); 1450 if (exp->ex_fslocs.migrated) {
1307 if (status) 1451 status = fattr_handle_absent_fs(&bmval0, &bmval1, &rdattr_err);
1452 if (status)
1453 goto out;
1454 }
1455
1456 err = vfs_getattr(exp->ex_mnt, dentry, &stat);
1457 if (err)
1308 goto out_nfserr; 1458 goto out_nfserr;
1309 if ((bmval0 & (FATTR4_WORD0_FILES_FREE | FATTR4_WORD0_FILES_TOTAL)) || 1459 if ((bmval0 & (FATTR4_WORD0_FILES_FREE | FATTR4_WORD0_FILES_TOTAL)) ||
1310 (bmval1 & (FATTR4_WORD1_SPACE_AVAIL | FATTR4_WORD1_SPACE_FREE | 1460 (bmval1 & (FATTR4_WORD1_SPACE_AVAIL | FATTR4_WORD1_SPACE_FREE |
1311 FATTR4_WORD1_SPACE_TOTAL))) { 1461 FATTR4_WORD1_SPACE_TOTAL))) {
1312 status = vfs_statfs(dentry, &statfs); 1462 err = vfs_statfs(dentry, &statfs);
1313 if (status) 1463 if (err)
1314 goto out_nfserr; 1464 goto out_nfserr;
1315 } 1465 }
1316 if ((bmval0 & (FATTR4_WORD0_FILEHANDLE | FATTR4_WORD0_FSID)) && !fhp) { 1466 if ((bmval0 & (FATTR4_WORD0_FILEHANDLE | FATTR4_WORD0_FSID)) && !fhp) {
@@ -1322,18 +1472,23 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
1322 } 1472 }
1323 if (bmval0 & (FATTR4_WORD0_ACL | FATTR4_WORD0_ACLSUPPORT 1473 if (bmval0 & (FATTR4_WORD0_ACL | FATTR4_WORD0_ACLSUPPORT
1324 | FATTR4_WORD0_SUPPORTED_ATTRS)) { 1474 | FATTR4_WORD0_SUPPORTED_ATTRS)) {
1325 status = nfsd4_get_nfs4_acl(rqstp, dentry, &acl); 1475 err = nfsd4_get_nfs4_acl(rqstp, dentry, &acl);
1326 aclsupport = (status == 0); 1476 aclsupport = (err == 0);
1327 if (bmval0 & FATTR4_WORD0_ACL) { 1477 if (bmval0 & FATTR4_WORD0_ACL) {
1328 if (status == -EOPNOTSUPP) 1478 if (err == -EOPNOTSUPP)
1329 bmval0 &= ~FATTR4_WORD0_ACL; 1479 bmval0 &= ~FATTR4_WORD0_ACL;
1330 else if (status == -EINVAL) { 1480 else if (err == -EINVAL) {
1331 status = nfserr_attrnotsupp; 1481 status = nfserr_attrnotsupp;
1332 goto out; 1482 goto out;
1333 } else if (status != 0) 1483 } else if (err != 0)
1334 goto out_nfserr; 1484 goto out_nfserr;
1335 } 1485 }
1336 } 1486 }
1487 if (bmval0 & FATTR4_WORD0_FS_LOCATIONS) {
1488 if (exp->ex_fslocs.locations == NULL) {
1489 bmval0 &= ~FATTR4_WORD0_FS_LOCATIONS;
1490 }
1491 }
1337 if ((buflen -= 16) < 0) 1492 if ((buflen -= 16) < 0)
1338 goto out_resource; 1493 goto out_resource;
1339 1494
@@ -1343,12 +1498,15 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
1343 attrlenp = p++; /* to be backfilled later */ 1498 attrlenp = p++; /* to be backfilled later */
1344 1499
1345 if (bmval0 & FATTR4_WORD0_SUPPORTED_ATTRS) { 1500 if (bmval0 & FATTR4_WORD0_SUPPORTED_ATTRS) {
1501 u32 word0 = NFSD_SUPPORTED_ATTRS_WORD0;
1346 if ((buflen -= 12) < 0) 1502 if ((buflen -= 12) < 0)
1347 goto out_resource; 1503 goto out_resource;
1504 if (!aclsupport)
1505 word0 &= ~FATTR4_WORD0_ACL;
1506 if (!exp->ex_fslocs.locations)
1507 word0 &= ~FATTR4_WORD0_FS_LOCATIONS;
1348 WRITE32(2); 1508 WRITE32(2);
1349 WRITE32(aclsupport ? 1509 WRITE32(word0);
1350 NFSD_SUPPORTED_ATTRS_WORD0 :
1351 NFSD_SUPPORTED_ATTRS_WORD0 & ~FATTR4_WORD0_ACL);
1352 WRITE32(NFSD_SUPPORTED_ATTRS_WORD1); 1510 WRITE32(NFSD_SUPPORTED_ATTRS_WORD1);
1353 } 1511 }
1354 if (bmval0 & FATTR4_WORD0_TYPE) { 1512 if (bmval0 & FATTR4_WORD0_TYPE) {
@@ -1402,7 +1560,10 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
1402 if (bmval0 & FATTR4_WORD0_FSID) { 1560 if (bmval0 & FATTR4_WORD0_FSID) {
1403 if ((buflen -= 16) < 0) 1561 if ((buflen -= 16) < 0)
1404 goto out_resource; 1562 goto out_resource;
1405 if (is_fsid(fhp, rqstp->rq_reffh)) { 1563 if (exp->ex_fslocs.migrated) {
1564 WRITE64(NFS4_REFERRAL_FSID_MAJOR);
1565 WRITE64(NFS4_REFERRAL_FSID_MINOR);
1566 } else if (is_fsid(fhp, rqstp->rq_reffh)) {
1406 WRITE64((u64)exp->ex_fsid); 1567 WRITE64((u64)exp->ex_fsid);
1407 WRITE64((u64)0); 1568 WRITE64((u64)0);
1408 } else { 1569 } else {
@@ -1425,7 +1586,7 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
1425 if (bmval0 & FATTR4_WORD0_RDATTR_ERROR) { 1586 if (bmval0 & FATTR4_WORD0_RDATTR_ERROR) {
1426 if ((buflen -= 4) < 0) 1587 if ((buflen -= 4) < 0)
1427 goto out_resource; 1588 goto out_resource;
1428 WRITE32(0); 1589 WRITE32(rdattr_err);
1429 } 1590 }
1430 if (bmval0 & FATTR4_WORD0_ACL) { 1591 if (bmval0 & FATTR4_WORD0_ACL) {
1431 struct nfs4_ace *ace; 1592 struct nfs4_ace *ace;
@@ -1513,6 +1674,13 @@ out_acl:
1513 goto out_resource; 1674 goto out_resource;
1514 WRITE64((u64) statfs.f_files); 1675 WRITE64((u64) statfs.f_files);
1515 } 1676 }
1677 if (bmval0 & FATTR4_WORD0_FS_LOCATIONS) {
1678 status = nfsd4_encode_fs_locations(rqstp, exp, &p, &buflen);
1679 if (status == nfserr_resource)
1680 goto out_resource;
1681 if (status)
1682 goto out;
1683 }
1516 if (bmval0 & FATTR4_WORD0_HOMOGENEOUS) { 1684 if (bmval0 & FATTR4_WORD0_HOMOGENEOUS) {
1517 if ((buflen -= 4) < 0) 1685 if ((buflen -= 4) < 0)
1518 goto out_resource; 1686 goto out_resource;
@@ -1536,12 +1704,12 @@ out_acl:
1536 if (bmval0 & FATTR4_WORD0_MAXREAD) { 1704 if (bmval0 & FATTR4_WORD0_MAXREAD) {
1537 if ((buflen -= 8) < 0) 1705 if ((buflen -= 8) < 0)
1538 goto out_resource; 1706 goto out_resource;
1539 WRITE64((u64) NFSSVC_MAXBLKSIZE); 1707 WRITE64((u64) svc_max_payload(rqstp));
1540 } 1708 }
1541 if (bmval0 & FATTR4_WORD0_MAXWRITE) { 1709 if (bmval0 & FATTR4_WORD0_MAXWRITE) {
1542 if ((buflen -= 8) < 0) 1710 if ((buflen -= 8) < 0)
1543 goto out_resource; 1711 goto out_resource;
1544 WRITE64((u64) NFSSVC_MAXBLKSIZE); 1712 WRITE64((u64) svc_max_payload(rqstp));
1545 } 1713 }
1546 if (bmval1 & FATTR4_WORD1_MODE) { 1714 if (bmval1 & FATTR4_WORD1_MODE) {
1547 if ((buflen -= 4) < 0) 1715 if ((buflen -= 4) < 0)
@@ -1652,7 +1820,7 @@ out:
1652 fh_put(&tempfh); 1820 fh_put(&tempfh);
1653 return status; 1821 return status;
1654out_nfserr: 1822out_nfserr:
1655 status = nfserrno(status); 1823 status = nfserrno(err);
1656 goto out; 1824 goto out;
1657out_resource: 1825out_resource:
1658 *countp = 0; 1826 *countp = 0;
@@ -1663,13 +1831,13 @@ out_serverfault:
1663 goto out; 1831 goto out;
1664} 1832}
1665 1833
1666static int 1834static __be32
1667nfsd4_encode_dirent_fattr(struct nfsd4_readdir *cd, 1835nfsd4_encode_dirent_fattr(struct nfsd4_readdir *cd,
1668 const char *name, int namlen, u32 *p, int *buflen) 1836 const char *name, int namlen, __be32 *p, int *buflen)
1669{ 1837{
1670 struct svc_export *exp = cd->rd_fhp->fh_export; 1838 struct svc_export *exp = cd->rd_fhp->fh_export;
1671 struct dentry *dentry; 1839 struct dentry *dentry;
1672 int nfserr; 1840 __be32 nfserr;
1673 1841
1674 dentry = lookup_one_len(name, cd->rd_fhp->fh_dentry, namlen); 1842 dentry = lookup_one_len(name, cd->rd_fhp->fh_dentry, namlen);
1675 if (IS_ERR(dentry)) 1843 if (IS_ERR(dentry))
@@ -1698,10 +1866,10 @@ out_put:
1698 return nfserr; 1866 return nfserr;
1699} 1867}
1700 1868
1701static u32 * 1869static __be32 *
1702nfsd4_encode_rdattr_error(u32 *p, int buflen, int nfserr) 1870nfsd4_encode_rdattr_error(__be32 *p, int buflen, __be32 nfserr)
1703{ 1871{
1704 u32 *attrlenp; 1872 __be32 *attrlenp;
1705 1873
1706 if (buflen < 6) 1874 if (buflen < 6)
1707 return NULL; 1875 return NULL;
@@ -1721,8 +1889,8 @@ nfsd4_encode_dirent(struct readdir_cd *ccd, const char *name, int namlen,
1721{ 1889{
1722 struct nfsd4_readdir *cd = container_of(ccd, struct nfsd4_readdir, common); 1890 struct nfsd4_readdir *cd = container_of(ccd, struct nfsd4_readdir, common);
1723 int buflen; 1891 int buflen;
1724 u32 *p = cd->buffer; 1892 __be32 *p = cd->buffer;
1725 int nfserr = nfserr_toosmall; 1893 __be32 nfserr = nfserr_toosmall;
1726 1894
1727 /* In nfsv4, "." and ".." never make it onto the wire.. */ 1895 /* In nfsv4, "." and ".." never make it onto the wire.. */
1728 if (name && isdotent(name, namlen)) { 1896 if (name && isdotent(name, namlen)) {
@@ -1778,7 +1946,7 @@ fail:
1778} 1946}
1779 1947
1780static void 1948static void
1781nfsd4_encode_access(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_access *access) 1949nfsd4_encode_access(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_access *access)
1782{ 1950{
1783 ENCODE_HEAD; 1951 ENCODE_HEAD;
1784 1952
@@ -1791,7 +1959,7 @@ nfsd4_encode_access(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_acc
1791} 1959}
1792 1960
1793static void 1961static void
1794nfsd4_encode_close(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_close *close) 1962nfsd4_encode_close(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_close *close)
1795{ 1963{
1796 ENCODE_SEQID_OP_HEAD; 1964 ENCODE_SEQID_OP_HEAD;
1797 1965
@@ -1806,7 +1974,7 @@ nfsd4_encode_close(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_clos
1806 1974
1807 1975
1808static void 1976static void
1809nfsd4_encode_commit(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_commit *commit) 1977nfsd4_encode_commit(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_commit *commit)
1810{ 1978{
1811 ENCODE_HEAD; 1979 ENCODE_HEAD;
1812 1980
@@ -1818,7 +1986,7 @@ nfsd4_encode_commit(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_com
1818} 1986}
1819 1987
1820static void 1988static void
1821nfsd4_encode_create(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_create *create) 1989nfsd4_encode_create(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_create *create)
1822{ 1990{
1823 ENCODE_HEAD; 1991 ENCODE_HEAD;
1824 1992
@@ -1832,8 +2000,8 @@ nfsd4_encode_create(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_cre
1832 } 2000 }
1833} 2001}
1834 2002
1835static int 2003static __be32
1836nfsd4_encode_getattr(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_getattr *getattr) 2004nfsd4_encode_getattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_getattr *getattr)
1837{ 2005{
1838 struct svc_fh *fhp = getattr->ga_fhp; 2006 struct svc_fh *fhp = getattr->ga_fhp;
1839 int buflen; 2007 int buflen;
@@ -1845,14 +2013,13 @@ nfsd4_encode_getattr(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_ge
1845 nfserr = nfsd4_encode_fattr(fhp, fhp->fh_export, fhp->fh_dentry, 2013 nfserr = nfsd4_encode_fattr(fhp, fhp->fh_export, fhp->fh_dentry,
1846 resp->p, &buflen, getattr->ga_bmval, 2014 resp->p, &buflen, getattr->ga_bmval,
1847 resp->rqstp); 2015 resp->rqstp);
1848
1849 if (!nfserr) 2016 if (!nfserr)
1850 resp->p += buflen; 2017 resp->p += buflen;
1851 return nfserr; 2018 return nfserr;
1852} 2019}
1853 2020
1854static void 2021static void
1855nfsd4_encode_getfh(struct nfsd4_compoundres *resp, int nfserr, struct svc_fh *fhp) 2022nfsd4_encode_getfh(struct nfsd4_compoundres *resp, __be32 nfserr, struct svc_fh *fhp)
1856{ 2023{
1857 unsigned int len; 2024 unsigned int len;
1858 ENCODE_HEAD; 2025 ENCODE_HEAD;
@@ -1892,7 +2059,7 @@ nfsd4_encode_lock_denied(struct nfsd4_compoundres *resp, struct nfsd4_lock_denie
1892} 2059}
1893 2060
1894static void 2061static void
1895nfsd4_encode_lock(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_lock *lock) 2062nfsd4_encode_lock(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lock *lock)
1896{ 2063{
1897 ENCODE_SEQID_OP_HEAD; 2064 ENCODE_SEQID_OP_HEAD;
1898 2065
@@ -1908,14 +2075,14 @@ nfsd4_encode_lock(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_lock
1908} 2075}
1909 2076
1910static void 2077static void
1911nfsd4_encode_lockt(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_lockt *lockt) 2078nfsd4_encode_lockt(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lockt *lockt)
1912{ 2079{
1913 if (nfserr == nfserr_denied) 2080 if (nfserr == nfserr_denied)
1914 nfsd4_encode_lock_denied(resp, &lockt->lt_denied); 2081 nfsd4_encode_lock_denied(resp, &lockt->lt_denied);
1915} 2082}
1916 2083
1917static void 2084static void
1918nfsd4_encode_locku(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_locku *locku) 2085nfsd4_encode_locku(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_locku *locku)
1919{ 2086{
1920 ENCODE_SEQID_OP_HEAD; 2087 ENCODE_SEQID_OP_HEAD;
1921 2088
@@ -1931,7 +2098,7 @@ nfsd4_encode_locku(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_lock
1931 2098
1932 2099
1933static void 2100static void
1934nfsd4_encode_link(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_link *link) 2101nfsd4_encode_link(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_link *link)
1935{ 2102{
1936 ENCODE_HEAD; 2103 ENCODE_HEAD;
1937 2104
@@ -1944,7 +2111,7 @@ nfsd4_encode_link(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_link
1944 2111
1945 2112
1946static void 2113static void
1947nfsd4_encode_open(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_open *open) 2114nfsd4_encode_open(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open *open)
1948{ 2115{
1949 ENCODE_SEQID_OP_HEAD; 2116 ENCODE_SEQID_OP_HEAD;
1950 2117
@@ -2009,7 +2176,7 @@ out:
2009} 2176}
2010 2177
2011static void 2178static void
2012nfsd4_encode_open_confirm(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_open_confirm *oc) 2179nfsd4_encode_open_confirm(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open_confirm *oc)
2013{ 2180{
2014 ENCODE_SEQID_OP_HEAD; 2181 ENCODE_SEQID_OP_HEAD;
2015 2182
@@ -2024,7 +2191,7 @@ nfsd4_encode_open_confirm(struct nfsd4_compoundres *resp, int nfserr, struct nfs
2024} 2191}
2025 2192
2026static void 2193static void
2027nfsd4_encode_open_downgrade(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_open_downgrade *od) 2194nfsd4_encode_open_downgrade(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open_downgrade *od)
2028{ 2195{
2029 ENCODE_SEQID_OP_HEAD; 2196 ENCODE_SEQID_OP_HEAD;
2030 2197
@@ -2038,8 +2205,9 @@ nfsd4_encode_open_downgrade(struct nfsd4_compoundres *resp, int nfserr, struct n
2038 ENCODE_SEQID_OP_TAIL(od->od_stateowner); 2205 ENCODE_SEQID_OP_TAIL(od->od_stateowner);
2039} 2206}
2040 2207
2041static int 2208static __be32
2042nfsd4_encode_read(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_read *read) 2209nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,
2210 struct nfsd4_read *read)
2043{ 2211{
2044 u32 eof; 2212 u32 eof;
2045 int v, pn; 2213 int v, pn;
@@ -2054,31 +2222,33 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_read
2054 2222
2055 RESERVE_SPACE(8); /* eof flag and byte count */ 2223 RESERVE_SPACE(8); /* eof flag and byte count */
2056 2224
2057 maxcount = NFSSVC_MAXBLKSIZE; 2225 maxcount = svc_max_payload(resp->rqstp);
2058 if (maxcount > read->rd_length) 2226 if (maxcount > read->rd_length)
2059 maxcount = read->rd_length; 2227 maxcount = read->rd_length;
2060 2228
2061 len = maxcount; 2229 len = maxcount;
2062 v = 0; 2230 v = 0;
2063 while (len > 0) { 2231 while (len > 0) {
2064 pn = resp->rqstp->rq_resused; 2232 pn = resp->rqstp->rq_resused++;
2065 svc_take_page(resp->rqstp); 2233 resp->rqstp->rq_vec[v].iov_base =
2066 read->rd_iov[v].iov_base = page_address(resp->rqstp->rq_respages[pn]); 2234 page_address(resp->rqstp->rq_respages[pn]);
2067 read->rd_iov[v].iov_len = len < PAGE_SIZE ? len : PAGE_SIZE; 2235 resp->rqstp->rq_vec[v].iov_len =
2236 len < PAGE_SIZE ? len : PAGE_SIZE;
2068 v++; 2237 v++;
2069 len -= PAGE_SIZE; 2238 len -= PAGE_SIZE;
2070 } 2239 }
2071 read->rd_vlen = v; 2240 read->rd_vlen = v;
2072 2241
2073 nfserr = nfsd_read(read->rd_rqstp, read->rd_fhp, read->rd_filp, 2242 nfserr = nfsd_read(read->rd_rqstp, read->rd_fhp, read->rd_filp,
2074 read->rd_offset, read->rd_iov, read->rd_vlen, 2243 read->rd_offset, resp->rqstp->rq_vec, read->rd_vlen,
2075 &maxcount); 2244 &maxcount);
2076 2245
2077 if (nfserr == nfserr_symlink) 2246 if (nfserr == nfserr_symlink)
2078 nfserr = nfserr_inval; 2247 nfserr = nfserr_inval;
2079 if (nfserr) 2248 if (nfserr)
2080 return nfserr; 2249 return nfserr;
2081 eof = (read->rd_offset + maxcount >= read->rd_fhp->fh_dentry->d_inode->i_size); 2250 eof = (read->rd_offset + maxcount >=
2251 read->rd_fhp->fh_dentry->d_inode->i_size);
2082 2252
2083 WRITE32(eof); 2253 WRITE32(eof);
2084 WRITE32(maxcount); 2254 WRITE32(maxcount);
@@ -2088,7 +2258,6 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_read
2088 resp->xbuf->page_len = maxcount; 2258 resp->xbuf->page_len = maxcount;
2089 2259
2090 /* Use rest of head for padding and remaining ops: */ 2260 /* Use rest of head for padding and remaining ops: */
2091 resp->rqstp->rq_restailpage = 0;
2092 resp->xbuf->tail[0].iov_base = p; 2261 resp->xbuf->tail[0].iov_base = p;
2093 resp->xbuf->tail[0].iov_len = 0; 2262 resp->xbuf->tail[0].iov_len = 0;
2094 if (maxcount&3) { 2263 if (maxcount&3) {
@@ -2101,8 +2270,8 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_read
2101 return 0; 2270 return 0;
2102} 2271}
2103 2272
2104static int 2273static __be32
2105nfsd4_encode_readlink(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_readlink *readlink) 2274nfsd4_encode_readlink(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_readlink *readlink)
2106{ 2275{
2107 int maxcount; 2276 int maxcount;
2108 char *page; 2277 char *page;
@@ -2113,8 +2282,7 @@ nfsd4_encode_readlink(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_r
2113 if (resp->xbuf->page_len) 2282 if (resp->xbuf->page_len)
2114 return nfserr_resource; 2283 return nfserr_resource;
2115 2284
2116 svc_take_page(resp->rqstp); 2285 page = page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused++]);
2117 page = page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused-1]);
2118 2286
2119 maxcount = PAGE_SIZE; 2287 maxcount = PAGE_SIZE;
2120 RESERVE_SPACE(4); 2288 RESERVE_SPACE(4);
@@ -2138,7 +2306,6 @@ nfsd4_encode_readlink(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_r
2138 resp->xbuf->page_len = maxcount; 2306 resp->xbuf->page_len = maxcount;
2139 2307
2140 /* Use rest of head for padding and remaining ops: */ 2308 /* Use rest of head for padding and remaining ops: */
2141 resp->rqstp->rq_restailpage = 0;
2142 resp->xbuf->tail[0].iov_base = p; 2309 resp->xbuf->tail[0].iov_base = p;
2143 resp->xbuf->tail[0].iov_len = 0; 2310 resp->xbuf->tail[0].iov_len = 0;
2144 if (maxcount&3) { 2311 if (maxcount&3) {
@@ -2151,12 +2318,12 @@ nfsd4_encode_readlink(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_r
2151 return 0; 2318 return 0;
2152} 2319}
2153 2320
2154static int 2321static __be32
2155nfsd4_encode_readdir(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_readdir *readdir) 2322nfsd4_encode_readdir(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_readdir *readdir)
2156{ 2323{
2157 int maxcount; 2324 int maxcount;
2158 loff_t offset; 2325 loff_t offset;
2159 u32 *page, *savep, *tailbase; 2326 __be32 *page, *savep, *tailbase;
2160 ENCODE_HEAD; 2327 ENCODE_HEAD;
2161 2328
2162 if (nfserr) 2329 if (nfserr)
@@ -2189,8 +2356,7 @@ nfsd4_encode_readdir(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_re
2189 goto err_no_verf; 2356 goto err_no_verf;
2190 } 2357 }
2191 2358
2192 svc_take_page(resp->rqstp); 2359 page = page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused++]);
2193 page = page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused-1]);
2194 readdir->common.err = 0; 2360 readdir->common.err = 0;
2195 readdir->buflen = maxcount; 2361 readdir->buflen = maxcount;
2196 readdir->buffer = page; 2362 readdir->buffer = page;
@@ -2215,10 +2381,10 @@ nfsd4_encode_readdir(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_re
2215 p = readdir->buffer; 2381 p = readdir->buffer;
2216 *p++ = 0; /* no more entries */ 2382 *p++ = 0; /* no more entries */
2217 *p++ = htonl(readdir->common.err == nfserr_eof); 2383 *p++ = htonl(readdir->common.err == nfserr_eof);
2218 resp->xbuf->page_len = ((char*)p) - (char*)page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused-1]); 2384 resp->xbuf->page_len = ((char*)p) - (char*)page_address(
2385 resp->rqstp->rq_respages[resp->rqstp->rq_resused-1]);
2219 2386
2220 /* Use rest of head for padding and remaining ops: */ 2387 /* Use rest of head for padding and remaining ops: */
2221 resp->rqstp->rq_restailpage = 0;
2222 resp->xbuf->tail[0].iov_base = tailbase; 2388 resp->xbuf->tail[0].iov_base = tailbase;
2223 resp->xbuf->tail[0].iov_len = 0; 2389 resp->xbuf->tail[0].iov_len = 0;
2224 resp->p = resp->xbuf->tail[0].iov_base; 2390 resp->p = resp->xbuf->tail[0].iov_base;
@@ -2232,7 +2398,7 @@ err_no_verf:
2232} 2398}
2233 2399
2234static void 2400static void
2235nfsd4_encode_remove(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_remove *remove) 2401nfsd4_encode_remove(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_remove *remove)
2236{ 2402{
2237 ENCODE_HEAD; 2403 ENCODE_HEAD;
2238 2404
@@ -2244,7 +2410,7 @@ nfsd4_encode_remove(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_rem
2244} 2410}
2245 2411
2246static void 2412static void
2247nfsd4_encode_rename(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_rename *rename) 2413nfsd4_encode_rename(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_rename *rename)
2248{ 2414{
2249 ENCODE_HEAD; 2415 ENCODE_HEAD;
2250 2416
@@ -2261,7 +2427,7 @@ nfsd4_encode_rename(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_ren
2261 * regardless of the error status. 2427 * regardless of the error status.
2262 */ 2428 */
2263static void 2429static void
2264nfsd4_encode_setattr(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_setattr *setattr) 2430nfsd4_encode_setattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_setattr *setattr)
2265{ 2431{
2266 ENCODE_HEAD; 2432 ENCODE_HEAD;
2267 2433
@@ -2280,7 +2446,7 @@ nfsd4_encode_setattr(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_se
2280} 2446}
2281 2447
2282static void 2448static void
2283nfsd4_encode_setclientid(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_setclientid *scd) 2449nfsd4_encode_setclientid(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_setclientid *scd)
2284{ 2450{
2285 ENCODE_HEAD; 2451 ENCODE_HEAD;
2286 2452
@@ -2299,7 +2465,7 @@ nfsd4_encode_setclientid(struct nfsd4_compoundres *resp, int nfserr, struct nfsd
2299} 2465}
2300 2466
2301static void 2467static void
2302nfsd4_encode_write(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_write *write) 2468nfsd4_encode_write(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_write *write)
2303{ 2469{
2304 ENCODE_HEAD; 2470 ENCODE_HEAD;
2305 2471
@@ -2315,7 +2481,7 @@ nfsd4_encode_write(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_writ
2315void 2481void
2316nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op) 2482nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
2317{ 2483{
2318 u32 *statp; 2484 __be32 *statp;
2319 ENCODE_HEAD; 2485 ENCODE_HEAD;
2320 2486
2321 RESERVE_SPACE(8); 2487 RESERVE_SPACE(8);
@@ -2453,7 +2619,7 @@ nfsd4_encode_replay(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
2453 */ 2619 */
2454 2620
2455int 2621int
2456nfs4svc_encode_voidres(struct svc_rqst *rqstp, u32 *p, void *dummy) 2622nfs4svc_encode_voidres(struct svc_rqst *rqstp, __be32 *p, void *dummy)
2457{ 2623{
2458 return xdr_ressize_check(rqstp, p); 2624 return xdr_ressize_check(rqstp, p);
2459} 2625}
@@ -2475,9 +2641,9 @@ void nfsd4_release_compoundargs(struct nfsd4_compoundargs *args)
2475} 2641}
2476 2642
2477int 2643int
2478nfs4svc_decode_compoundargs(struct svc_rqst *rqstp, u32 *p, struct nfsd4_compoundargs *args) 2644nfs4svc_decode_compoundargs(struct svc_rqst *rqstp, __be32 *p, struct nfsd4_compoundargs *args)
2479{ 2645{
2480 int status; 2646 __be32 status;
2481 2647
2482 args->p = p; 2648 args->p = p;
2483 args->end = rqstp->rq_arg.head[0].iov_base + rqstp->rq_arg.head[0].iov_len; 2649 args->end = rqstp->rq_arg.head[0].iov_base + rqstp->rq_arg.head[0].iov_len;
@@ -2496,7 +2662,7 @@ nfs4svc_decode_compoundargs(struct svc_rqst *rqstp, u32 *p, struct nfsd4_compoun
2496} 2662}
2497 2663
2498int 2664int
2499nfs4svc_encode_compoundres(struct svc_rqst *rqstp, u32 *p, struct nfsd4_compoundres *resp) 2665nfs4svc_encode_compoundres(struct svc_rqst *rqstp, __be32 *p, struct nfsd4_compoundres *resp)
2500{ 2666{
2501 /* 2667 /*
2502 * All that remains is to write the tag and operation count... 2668 * All that remains is to write the tag and operation count...
diff --git a/fs/nfsd/nfscache.c b/fs/nfsd/nfscache.c
index fdf7cf3dfadc..6100bbe27432 100644
--- a/fs/nfsd/nfscache.c
+++ b/fs/nfsd/nfscache.c
@@ -29,7 +29,7 @@
29 */ 29 */
30#define CACHESIZE 1024 30#define CACHESIZE 1024
31#define HASHSIZE 64 31#define HASHSIZE 64
32#define REQHASH(xid) ((((xid) >> 24) ^ (xid)) & (HASHSIZE-1)) 32#define REQHASH(xid) (((((__force __u32)xid) >> 24) ^ ((__force __u32)xid)) & (HASHSIZE-1))
33 33
34static struct hlist_head * hash_list; 34static struct hlist_head * hash_list;
35static struct list_head lru_head; 35static struct list_head lru_head;
@@ -127,8 +127,8 @@ nfsd_cache_lookup(struct svc_rqst *rqstp, int type)
127 struct hlist_node *hn; 127 struct hlist_node *hn;
128 struct hlist_head *rh; 128 struct hlist_head *rh;
129 struct svc_cacherep *rp; 129 struct svc_cacherep *rp;
130 u32 xid = rqstp->rq_xid, 130 __be32 xid = rqstp->rq_xid;
131 proto = rqstp->rq_prot, 131 u32 proto = rqstp->rq_prot,
132 vers = rqstp->rq_vers, 132 vers = rqstp->rq_vers,
133 proc = rqstp->rq_proc; 133 proc = rqstp->rq_proc;
134 unsigned long age; 134 unsigned long age;
@@ -258,7 +258,7 @@ found_entry:
258 * In this case, nfsd_cache_update is called with statp == NULL. 258 * In this case, nfsd_cache_update is called with statp == NULL.
259 */ 259 */
260void 260void
261nfsd_cache_update(struct svc_rqst *rqstp, int cachetype, u32 *statp) 261nfsd_cache_update(struct svc_rqst *rqstp, int cachetype, __be32 *statp)
262{ 262{
263 struct svc_cacherep *rp; 263 struct svc_cacherep *rp;
264 struct kvec *resv = &rqstp->rq_res.head[0], *cachv; 264 struct kvec *resv = &rqstp->rq_res.head[0], *cachv;
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index 5c6a477c20ec..39aed901514b 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -57,6 +57,7 @@ enum {
57 NFSD_Pool_Threads, 57 NFSD_Pool_Threads,
58 NFSD_Versions, 58 NFSD_Versions,
59 NFSD_Ports, 59 NFSD_Ports,
60 NFSD_MaxBlkSize,
60 /* 61 /*
61 * The below MUST come last. Otherwise we leave a hole in nfsd_files[] 62 * The below MUST come last. Otherwise we leave a hole in nfsd_files[]
62 * with !CONFIG_NFSD_V4 and simple_fill_super() goes oops 63 * with !CONFIG_NFSD_V4 and simple_fill_super() goes oops
@@ -82,6 +83,7 @@ static ssize_t write_threads(struct file *file, char *buf, size_t size);
82static ssize_t write_pool_threads(struct file *file, char *buf, size_t size); 83static ssize_t write_pool_threads(struct file *file, char *buf, size_t size);
83static ssize_t write_versions(struct file *file, char *buf, size_t size); 84static ssize_t write_versions(struct file *file, char *buf, size_t size);
84static ssize_t write_ports(struct file *file, char *buf, size_t size); 85static ssize_t write_ports(struct file *file, char *buf, size_t size);
86static ssize_t write_maxblksize(struct file *file, char *buf, size_t size);
85#ifdef CONFIG_NFSD_V4 87#ifdef CONFIG_NFSD_V4
86static ssize_t write_leasetime(struct file *file, char *buf, size_t size); 88static ssize_t write_leasetime(struct file *file, char *buf, size_t size);
87static ssize_t write_recoverydir(struct file *file, char *buf, size_t size); 89static ssize_t write_recoverydir(struct file *file, char *buf, size_t size);
@@ -100,6 +102,7 @@ static ssize_t (*write_op[])(struct file *, char *, size_t) = {
100 [NFSD_Pool_Threads] = write_pool_threads, 102 [NFSD_Pool_Threads] = write_pool_threads,
101 [NFSD_Versions] = write_versions, 103 [NFSD_Versions] = write_versions,
102 [NFSD_Ports] = write_ports, 104 [NFSD_Ports] = write_ports,
105 [NFSD_MaxBlkSize] = write_maxblksize,
103#ifdef CONFIG_NFSD_V4 106#ifdef CONFIG_NFSD_V4
104 [NFSD_Leasetime] = write_leasetime, 107 [NFSD_Leasetime] = write_leasetime,
105 [NFSD_RecoveryDir] = write_recoverydir, 108 [NFSD_RecoveryDir] = write_recoverydir,
@@ -523,18 +526,20 @@ static ssize_t write_ports(struct file *file, char *buf, size_t size)
523 err = nfsd_create_serv(); 526 err = nfsd_create_serv();
524 if (!err) { 527 if (!err) {
525 int proto = 0; 528 int proto = 0;
526 err = lockd_up(proto); 529 err = svc_addsock(nfsd_serv, fd, buf, &proto);
527 if (!err) { 530 if (err >= 0) {
528 err = svc_addsock(nfsd_serv, fd, buf, &proto); 531 err = lockd_up(proto);
529 if (err) 532 if (err < 0)
530 lockd_down(); 533 svc_sock_names(buf+strlen(buf)+1, nfsd_serv, buf);
531 } 534 }
532 /* Decrease the count, but don't shutdown the 535 /* Decrease the count, but don't shutdown the
533 * the service 536 * the service
534 */ 537 */
538 lock_kernel();
535 nfsd_serv->sv_nrthreads--; 539 nfsd_serv->sv_nrthreads--;
540 unlock_kernel();
536 } 541 }
537 return err; 542 return err < 0 ? err : 0;
538 } 543 }
539 if (buf[0] == '-') { 544 if (buf[0] == '-') {
540 char *toclose = kstrdup(buf+1, GFP_KERNEL); 545 char *toclose = kstrdup(buf+1, GFP_KERNEL);
@@ -545,12 +550,43 @@ static ssize_t write_ports(struct file *file, char *buf, size_t size)
545 if (nfsd_serv) 550 if (nfsd_serv)
546 len = svc_sock_names(buf, nfsd_serv, toclose); 551 len = svc_sock_names(buf, nfsd_serv, toclose);
547 unlock_kernel(); 552 unlock_kernel();
553 if (len >= 0)
554 lockd_down();
548 kfree(toclose); 555 kfree(toclose);
549 return len; 556 return len;
550 } 557 }
551 return -EINVAL; 558 return -EINVAL;
552} 559}
553 560
561int nfsd_max_blksize;
562
563static ssize_t write_maxblksize(struct file *file, char *buf, size_t size)
564{
565 char *mesg = buf;
566 if (size > 0) {
567 int bsize;
568 int rv = get_int(&mesg, &bsize);
569 if (rv)
570 return rv;
571 /* force bsize into allowed range and
572 * required alignment.
573 */
574 if (bsize < 1024)
575 bsize = 1024;
576 if (bsize > NFSSVC_MAXBLKSIZE)
577 bsize = NFSSVC_MAXBLKSIZE;
578 bsize &= ~(1024-1);
579 lock_kernel();
580 if (nfsd_serv && nfsd_serv->sv_nrthreads) {
581 unlock_kernel();
582 return -EBUSY;
583 }
584 nfsd_max_blksize = bsize;
585 unlock_kernel();
586 }
587 return sprintf(buf, "%d\n", nfsd_max_blksize);
588}
589
554#ifdef CONFIG_NFSD_V4 590#ifdef CONFIG_NFSD_V4
555extern time_t nfs4_leasetime(void); 591extern time_t nfs4_leasetime(void);
556 592
@@ -616,6 +652,7 @@ static int nfsd_fill_super(struct super_block * sb, void * data, int silent)
616 [NFSD_Pool_Threads] = {"pool_threads", &transaction_ops, S_IWUSR|S_IRUSR}, 652 [NFSD_Pool_Threads] = {"pool_threads", &transaction_ops, S_IWUSR|S_IRUSR},
617 [NFSD_Versions] = {"versions", &transaction_ops, S_IWUSR|S_IRUSR}, 653 [NFSD_Versions] = {"versions", &transaction_ops, S_IWUSR|S_IRUSR},
618 [NFSD_Ports] = {"portlist", &transaction_ops, S_IWUSR|S_IRUGO}, 654 [NFSD_Ports] = {"portlist", &transaction_ops, S_IWUSR|S_IRUGO},
655 [NFSD_MaxBlkSize] = {"max_block_size", &transaction_ops, S_IWUSR|S_IRUGO},
619#ifdef CONFIG_NFSD_V4 656#ifdef CONFIG_NFSD_V4
620 [NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR}, 657 [NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR},
621 [NFSD_RecoveryDir] = {"nfsv4recoverydir", &transaction_ops, S_IWUSR|S_IRUSR}, 658 [NFSD_RecoveryDir] = {"nfsv4recoverydir", &transaction_ops, S_IWUSR|S_IRUSR},
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c
index 501d83884530..727ab3bd450d 100644
--- a/fs/nfsd/nfsfh.c
+++ b/fs/nfsd/nfsfh.c
@@ -76,7 +76,7 @@ static int nfsd_acceptable(void *expv, struct dentry *dentry)
76 * comment in the NFSv3 spec says this is incorrect (implementation notes for 76 * comment in the NFSv3 spec says this is incorrect (implementation notes for
77 * the write call). 77 * the write call).
78 */ 78 */
79static inline int 79static inline __be32
80nfsd_mode_check(struct svc_rqst *rqstp, umode_t mode, int type) 80nfsd_mode_check(struct svc_rqst *rqstp, umode_t mode, int type)
81{ 81{
82 /* Type can be negative when creating hardlinks - not to a dir */ 82 /* Type can be negative when creating hardlinks - not to a dir */
@@ -110,13 +110,13 @@ nfsd_mode_check(struct svc_rqst *rqstp, umode_t mode, int type)
110 * This is only called at the start of an nfsproc call, so fhp points to 110 * This is only called at the start of an nfsproc call, so fhp points to
111 * a svc_fh which is all 0 except for the over-the-wire file handle. 111 * a svc_fh which is all 0 except for the over-the-wire file handle.
112 */ 112 */
113u32 113__be32
114fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access) 114fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
115{ 115{
116 struct knfsd_fh *fh = &fhp->fh_handle; 116 struct knfsd_fh *fh = &fhp->fh_handle;
117 struct svc_export *exp = NULL; 117 struct svc_export *exp = NULL;
118 struct dentry *dentry; 118 struct dentry *dentry;
119 u32 error = 0; 119 __be32 error = 0;
120 120
121 dprintk("nfsd: fh_verify(%s)\n", SVCFH_fmt(fhp)); 121 dprintk("nfsd: fh_verify(%s)\n", SVCFH_fmt(fhp));
122 122
@@ -315,7 +315,7 @@ static inline void _fh_update_old(struct dentry *dentry,
315 fh->ofh_dirino = 0; 315 fh->ofh_dirino = 0;
316} 316}
317 317
318int 318__be32
319fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, struct svc_fh *ref_fh) 319fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, struct svc_fh *ref_fh)
320{ 320{
321 /* ref_fh is a reference file handle. 321 /* ref_fh is a reference file handle.
@@ -451,7 +451,7 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, st
451 * Update file handle information after changing a dentry. 451 * Update file handle information after changing a dentry.
452 * This is only called by nfsd_create, nfsd_create_v3 and nfsd_proc_create 452 * This is only called by nfsd_create, nfsd_create_v3 and nfsd_proc_create
453 */ 453 */
454int 454__be32
455fh_update(struct svc_fh *fhp) 455fh_update(struct svc_fh *fhp)
456{ 456{
457 struct dentry *dentry; 457 struct dentry *dentry;
diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c
index 06cd0db0f32b..ec983b777680 100644
--- a/fs/nfsd/nfsproc.c
+++ b/fs/nfsd/nfsproc.c
@@ -30,22 +30,22 @@ typedef struct svc_buf svc_buf;
30#define NFSDDBG_FACILITY NFSDDBG_PROC 30#define NFSDDBG_FACILITY NFSDDBG_PROC
31 31
32 32
33static int 33static __be32
34nfsd_proc_null(struct svc_rqst *rqstp, void *argp, void *resp) 34nfsd_proc_null(struct svc_rqst *rqstp, void *argp, void *resp)
35{ 35{
36 return nfs_ok; 36 return nfs_ok;
37} 37}
38 38
39static int 39static __be32
40nfsd_return_attrs(int err, struct nfsd_attrstat *resp) 40nfsd_return_attrs(__be32 err, struct nfsd_attrstat *resp)
41{ 41{
42 if (err) return err; 42 if (err) return err;
43 return nfserrno(vfs_getattr(resp->fh.fh_export->ex_mnt, 43 return nfserrno(vfs_getattr(resp->fh.fh_export->ex_mnt,
44 resp->fh.fh_dentry, 44 resp->fh.fh_dentry,
45 &resp->stat)); 45 &resp->stat));
46} 46}
47static int 47static __be32
48nfsd_return_dirop(int err, struct nfsd_diropres *resp) 48nfsd_return_dirop(__be32 err, struct nfsd_diropres *resp)
49{ 49{
50 if (err) return err; 50 if (err) return err;
51 return nfserrno(vfs_getattr(resp->fh.fh_export->ex_mnt, 51 return nfserrno(vfs_getattr(resp->fh.fh_export->ex_mnt,
@@ -56,11 +56,11 @@ nfsd_return_dirop(int err, struct nfsd_diropres *resp)
56 * Get a file's attributes 56 * Get a file's attributes
57 * N.B. After this call resp->fh needs an fh_put 57 * N.B. After this call resp->fh needs an fh_put
58 */ 58 */
59static int 59static __be32
60nfsd_proc_getattr(struct svc_rqst *rqstp, struct nfsd_fhandle *argp, 60nfsd_proc_getattr(struct svc_rqst *rqstp, struct nfsd_fhandle *argp,
61 struct nfsd_attrstat *resp) 61 struct nfsd_attrstat *resp)
62{ 62{
63 int nfserr; 63 __be32 nfserr;
64 dprintk("nfsd: GETATTR %s\n", SVCFH_fmt(&argp->fh)); 64 dprintk("nfsd: GETATTR %s\n", SVCFH_fmt(&argp->fh));
65 65
66 fh_copy(&resp->fh, &argp->fh); 66 fh_copy(&resp->fh, &argp->fh);
@@ -72,11 +72,11 @@ nfsd_proc_getattr(struct svc_rqst *rqstp, struct nfsd_fhandle *argp,
72 * Set a file's attributes 72 * Set a file's attributes
73 * N.B. After this call resp->fh needs an fh_put 73 * N.B. After this call resp->fh needs an fh_put
74 */ 74 */
75static int 75static __be32
76nfsd_proc_setattr(struct svc_rqst *rqstp, struct nfsd_sattrargs *argp, 76nfsd_proc_setattr(struct svc_rqst *rqstp, struct nfsd_sattrargs *argp,
77 struct nfsd_attrstat *resp) 77 struct nfsd_attrstat *resp)
78{ 78{
79 int nfserr; 79 __be32 nfserr;
80 dprintk("nfsd: SETATTR %s, valid=%x, size=%ld\n", 80 dprintk("nfsd: SETATTR %s, valid=%x, size=%ld\n",
81 SVCFH_fmt(&argp->fh), 81 SVCFH_fmt(&argp->fh),
82 argp->attrs.ia_valid, (long) argp->attrs.ia_size); 82 argp->attrs.ia_valid, (long) argp->attrs.ia_size);
@@ -92,11 +92,11 @@ nfsd_proc_setattr(struct svc_rqst *rqstp, struct nfsd_sattrargs *argp,
92 * doesn't exist yet. 92 * doesn't exist yet.
93 * N.B. After this call resp->fh needs an fh_put 93 * N.B. After this call resp->fh needs an fh_put
94 */ 94 */
95static int 95static __be32
96nfsd_proc_lookup(struct svc_rqst *rqstp, struct nfsd_diropargs *argp, 96nfsd_proc_lookup(struct svc_rqst *rqstp, struct nfsd_diropargs *argp,
97 struct nfsd_diropres *resp) 97 struct nfsd_diropres *resp)
98{ 98{
99 int nfserr; 99 __be32 nfserr;
100 100
101 dprintk("nfsd: LOOKUP %s %.*s\n", 101 dprintk("nfsd: LOOKUP %s %.*s\n",
102 SVCFH_fmt(&argp->fh), argp->len, argp->name); 102 SVCFH_fmt(&argp->fh), argp->len, argp->name);
@@ -112,11 +112,11 @@ nfsd_proc_lookup(struct svc_rqst *rqstp, struct nfsd_diropargs *argp,
112/* 112/*
113 * Read a symlink. 113 * Read a symlink.
114 */ 114 */
115static int 115static __be32
116nfsd_proc_readlink(struct svc_rqst *rqstp, struct nfsd_readlinkargs *argp, 116nfsd_proc_readlink(struct svc_rqst *rqstp, struct nfsd_readlinkargs *argp,
117 struct nfsd_readlinkres *resp) 117 struct nfsd_readlinkres *resp)
118{ 118{
119 int nfserr; 119 __be32 nfserr;
120 120
121 dprintk("nfsd: READLINK %s\n", SVCFH_fmt(&argp->fh)); 121 dprintk("nfsd: READLINK %s\n", SVCFH_fmt(&argp->fh));
122 122
@@ -132,11 +132,11 @@ nfsd_proc_readlink(struct svc_rqst *rqstp, struct nfsd_readlinkargs *argp,
132 * Read a portion of a file. 132 * Read a portion of a file.
133 * N.B. After this call resp->fh needs an fh_put 133 * N.B. After this call resp->fh needs an fh_put
134 */ 134 */
135static int 135static __be32
136nfsd_proc_read(struct svc_rqst *rqstp, struct nfsd_readargs *argp, 136nfsd_proc_read(struct svc_rqst *rqstp, struct nfsd_readargs *argp,
137 struct nfsd_readres *resp) 137 struct nfsd_readres *resp)
138{ 138{
139 int nfserr; 139 __be32 nfserr;
140 140
141 dprintk("nfsd: READ %s %d bytes at %d\n", 141 dprintk("nfsd: READ %s %d bytes at %d\n",
142 SVCFH_fmt(&argp->fh), 142 SVCFH_fmt(&argp->fh),
@@ -146,20 +146,20 @@ nfsd_proc_read(struct svc_rqst *rqstp, struct nfsd_readargs *argp,
146 * status, 17 words for fattr, and 1 word for the byte count. 146 * status, 17 words for fattr, and 1 word for the byte count.
147 */ 147 */
148 148
149 if (NFSSVC_MAXBLKSIZE < argp->count) { 149 if (NFSSVC_MAXBLKSIZE_V2 < argp->count) {
150 printk(KERN_NOTICE 150 printk(KERN_NOTICE
151 "oversized read request from %u.%u.%u.%u:%d (%d bytes)\n", 151 "oversized read request from %u.%u.%u.%u:%d (%d bytes)\n",
152 NIPQUAD(rqstp->rq_addr.sin_addr.s_addr), 152 NIPQUAD(rqstp->rq_addr.sin_addr.s_addr),
153 ntohs(rqstp->rq_addr.sin_port), 153 ntohs(rqstp->rq_addr.sin_port),
154 argp->count); 154 argp->count);
155 argp->count = NFSSVC_MAXBLKSIZE; 155 argp->count = NFSSVC_MAXBLKSIZE_V2;
156 } 156 }
157 svc_reserve(rqstp, (19<<2) + argp->count + 4); 157 svc_reserve(rqstp, (19<<2) + argp->count + 4);
158 158
159 resp->count = argp->count; 159 resp->count = argp->count;
160 nfserr = nfsd_read(rqstp, fh_copy(&resp->fh, &argp->fh), NULL, 160 nfserr = nfsd_read(rqstp, fh_copy(&resp->fh, &argp->fh), NULL,
161 argp->offset, 161 argp->offset,
162 argp->vec, argp->vlen, 162 rqstp->rq_vec, argp->vlen,
163 &resp->count); 163 &resp->count);
164 164
165 if (nfserr) return nfserr; 165 if (nfserr) return nfserr;
@@ -172,11 +172,11 @@ nfsd_proc_read(struct svc_rqst *rqstp, struct nfsd_readargs *argp,
172 * Write data to a file 172 * Write data to a file
173 * N.B. After this call resp->fh needs an fh_put 173 * N.B. After this call resp->fh needs an fh_put
174 */ 174 */
175static int 175static __be32
176nfsd_proc_write(struct svc_rqst *rqstp, struct nfsd_writeargs *argp, 176nfsd_proc_write(struct svc_rqst *rqstp, struct nfsd_writeargs *argp,
177 struct nfsd_attrstat *resp) 177 struct nfsd_attrstat *resp)
178{ 178{
179 int nfserr; 179 __be32 nfserr;
180 int stable = 1; 180 int stable = 1;
181 181
182 dprintk("nfsd: WRITE %s %d bytes at %d\n", 182 dprintk("nfsd: WRITE %s %d bytes at %d\n",
@@ -185,7 +185,7 @@ nfsd_proc_write(struct svc_rqst *rqstp, struct nfsd_writeargs *argp,
185 185
186 nfserr = nfsd_write(rqstp, fh_copy(&resp->fh, &argp->fh), NULL, 186 nfserr = nfsd_write(rqstp, fh_copy(&resp->fh, &argp->fh), NULL,
187 argp->offset, 187 argp->offset,
188 argp->vec, argp->vlen, 188 rqstp->rq_vec, argp->vlen,
189 argp->len, 189 argp->len,
190 &stable); 190 &stable);
191 return nfsd_return_attrs(nfserr, resp); 191 return nfsd_return_attrs(nfserr, resp);
@@ -197,7 +197,7 @@ nfsd_proc_write(struct svc_rqst *rqstp, struct nfsd_writeargs *argp,
197 * and the actual create() call in compliance with VFS protocols. 197 * and the actual create() call in compliance with VFS protocols.
198 * N.B. After this call _both_ argp->fh and resp->fh need an fh_put 198 * N.B. After this call _both_ argp->fh and resp->fh need an fh_put
199 */ 199 */
200static int 200static __be32
201nfsd_proc_create(struct svc_rqst *rqstp, struct nfsd_createargs *argp, 201nfsd_proc_create(struct svc_rqst *rqstp, struct nfsd_createargs *argp,
202 struct nfsd_diropres *resp) 202 struct nfsd_diropres *resp)
203{ 203{
@@ -206,7 +206,8 @@ nfsd_proc_create(struct svc_rqst *rqstp, struct nfsd_createargs *argp,
206 struct iattr *attr = &argp->attrs; 206 struct iattr *attr = &argp->attrs;
207 struct inode *inode; 207 struct inode *inode;
208 struct dentry *dchild; 208 struct dentry *dchild;
209 int nfserr, type, mode; 209 int type, mode;
210 __be32 nfserr;
210 dev_t rdev = 0, wanted = new_decode_dev(attr->ia_size); 211 dev_t rdev = 0, wanted = new_decode_dev(attr->ia_size);
211 212
212 dprintk("nfsd: CREATE %s %.*s\n", 213 dprintk("nfsd: CREATE %s %.*s\n",
@@ -225,7 +226,7 @@ nfsd_proc_create(struct svc_rqst *rqstp, struct nfsd_createargs *argp,
225 nfserr = nfserr_exist; 226 nfserr = nfserr_exist;
226 if (isdotent(argp->name, argp->len)) 227 if (isdotent(argp->name, argp->len))
227 goto done; 228 goto done;
228 fh_lock(dirfhp); 229 fh_lock_nested(dirfhp, I_MUTEX_PARENT);
229 dchild = lookup_one_len(argp->name, dirfhp->fh_dentry, argp->len); 230 dchild = lookup_one_len(argp->name, dirfhp->fh_dentry, argp->len);
230 if (IS_ERR(dchild)) { 231 if (IS_ERR(dchild)) {
231 nfserr = nfserrno(PTR_ERR(dchild)); 232 nfserr = nfserrno(PTR_ERR(dchild));
@@ -348,11 +349,11 @@ done:
348 return nfsd_return_dirop(nfserr, resp); 349 return nfsd_return_dirop(nfserr, resp);
349} 350}
350 351
351static int 352static __be32
352nfsd_proc_remove(struct svc_rqst *rqstp, struct nfsd_diropargs *argp, 353nfsd_proc_remove(struct svc_rqst *rqstp, struct nfsd_diropargs *argp,
353 void *resp) 354 void *resp)
354{ 355{
355 int nfserr; 356 __be32 nfserr;
356 357
357 dprintk("nfsd: REMOVE %s %.*s\n", SVCFH_fmt(&argp->fh), 358 dprintk("nfsd: REMOVE %s %.*s\n", SVCFH_fmt(&argp->fh),
358 argp->len, argp->name); 359 argp->len, argp->name);
@@ -363,11 +364,11 @@ nfsd_proc_remove(struct svc_rqst *rqstp, struct nfsd_diropargs *argp,
363 return nfserr; 364 return nfserr;
364} 365}
365 366
366static int 367static __be32
367nfsd_proc_rename(struct svc_rqst *rqstp, struct nfsd_renameargs *argp, 368nfsd_proc_rename(struct svc_rqst *rqstp, struct nfsd_renameargs *argp,
368 void *resp) 369 void *resp)
369{ 370{
370 int nfserr; 371 __be32 nfserr;
371 372
372 dprintk("nfsd: RENAME %s %.*s -> \n", 373 dprintk("nfsd: RENAME %s %.*s -> \n",
373 SVCFH_fmt(&argp->ffh), argp->flen, argp->fname); 374 SVCFH_fmt(&argp->ffh), argp->flen, argp->fname);
@@ -381,11 +382,11 @@ nfsd_proc_rename(struct svc_rqst *rqstp, struct nfsd_renameargs *argp,
381 return nfserr; 382 return nfserr;
382} 383}
383 384
384static int 385static __be32
385nfsd_proc_link(struct svc_rqst *rqstp, struct nfsd_linkargs *argp, 386nfsd_proc_link(struct svc_rqst *rqstp, struct nfsd_linkargs *argp,
386 void *resp) 387 void *resp)
387{ 388{
388 int nfserr; 389 __be32 nfserr;
389 390
390 dprintk("nfsd: LINK %s ->\n", 391 dprintk("nfsd: LINK %s ->\n",
391 SVCFH_fmt(&argp->ffh)); 392 SVCFH_fmt(&argp->ffh));
@@ -401,12 +402,12 @@ nfsd_proc_link(struct svc_rqst *rqstp, struct nfsd_linkargs *argp,
401 return nfserr; 402 return nfserr;
402} 403}
403 404
404static int 405static __be32
405nfsd_proc_symlink(struct svc_rqst *rqstp, struct nfsd_symlinkargs *argp, 406nfsd_proc_symlink(struct svc_rqst *rqstp, struct nfsd_symlinkargs *argp,
406 void *resp) 407 void *resp)
407{ 408{
408 struct svc_fh newfh; 409 struct svc_fh newfh;
409 int nfserr; 410 __be32 nfserr;
410 411
411 dprintk("nfsd: SYMLINK %s %.*s -> %.*s\n", 412 dprintk("nfsd: SYMLINK %s %.*s -> %.*s\n",
412 SVCFH_fmt(&argp->ffh), argp->flen, argp->fname, 413 SVCFH_fmt(&argp->ffh), argp->flen, argp->fname,
@@ -430,11 +431,11 @@ nfsd_proc_symlink(struct svc_rqst *rqstp, struct nfsd_symlinkargs *argp,
430 * Make directory. This operation is not idempotent. 431 * Make directory. This operation is not idempotent.
431 * N.B. After this call resp->fh needs an fh_put 432 * N.B. After this call resp->fh needs an fh_put
432 */ 433 */
433static int 434static __be32
434nfsd_proc_mkdir(struct svc_rqst *rqstp, struct nfsd_createargs *argp, 435nfsd_proc_mkdir(struct svc_rqst *rqstp, struct nfsd_createargs *argp,
435 struct nfsd_diropres *resp) 436 struct nfsd_diropres *resp)
436{ 437{
437 int nfserr; 438 __be32 nfserr;
438 439
439 dprintk("nfsd: MKDIR %s %.*s\n", SVCFH_fmt(&argp->fh), argp->len, argp->name); 440 dprintk("nfsd: MKDIR %s %.*s\n", SVCFH_fmt(&argp->fh), argp->len, argp->name);
440 441
@@ -454,11 +455,11 @@ nfsd_proc_mkdir(struct svc_rqst *rqstp, struct nfsd_createargs *argp,
454/* 455/*
455 * Remove a directory 456 * Remove a directory
456 */ 457 */
457static int 458static __be32
458nfsd_proc_rmdir(struct svc_rqst *rqstp, struct nfsd_diropargs *argp, 459nfsd_proc_rmdir(struct svc_rqst *rqstp, struct nfsd_diropargs *argp,
459 void *resp) 460 void *resp)
460{ 461{
461 int nfserr; 462 __be32 nfserr;
462 463
463 dprintk("nfsd: RMDIR %s %.*s\n", SVCFH_fmt(&argp->fh), argp->len, argp->name); 464 dprintk("nfsd: RMDIR %s %.*s\n", SVCFH_fmt(&argp->fh), argp->len, argp->name);
464 465
@@ -470,11 +471,12 @@ nfsd_proc_rmdir(struct svc_rqst *rqstp, struct nfsd_diropargs *argp,
470/* 471/*
471 * Read a portion of a directory. 472 * Read a portion of a directory.
472 */ 473 */
473static int 474static __be32
474nfsd_proc_readdir(struct svc_rqst *rqstp, struct nfsd_readdirargs *argp, 475nfsd_proc_readdir(struct svc_rqst *rqstp, struct nfsd_readdirargs *argp,
475 struct nfsd_readdirres *resp) 476 struct nfsd_readdirres *resp)
476{ 477{
477 int nfserr, count; 478 int count;
479 __be32 nfserr;
478 loff_t offset; 480 loff_t offset;
479 481
480 dprintk("nfsd: READDIR %s %d bytes at %d\n", 482 dprintk("nfsd: READDIR %s %d bytes at %d\n",
@@ -509,11 +511,11 @@ nfsd_proc_readdir(struct svc_rqst *rqstp, struct nfsd_readdirargs *argp,
509/* 511/*
510 * Get file system info 512 * Get file system info
511 */ 513 */
512static int 514static __be32
513nfsd_proc_statfs(struct svc_rqst * rqstp, struct nfsd_fhandle *argp, 515nfsd_proc_statfs(struct svc_rqst * rqstp, struct nfsd_fhandle *argp,
514 struct nfsd_statfsres *resp) 516 struct nfsd_statfsres *resp)
515{ 517{
516 int nfserr; 518 __be32 nfserr;
517 519
518 dprintk("nfsd: STATFS %s\n", SVCFH_fmt(&argp->fh)); 520 dprintk("nfsd: STATFS %s\n", SVCFH_fmt(&argp->fh));
519 521
@@ -553,7 +555,7 @@ static struct svc_procedure nfsd_procedures2[18] = {
553 PROC(none, void, void, none, RC_NOCACHE, ST), 555 PROC(none, void, void, none, RC_NOCACHE, ST),
554 PROC(lookup, diropargs, diropres, fhandle, RC_NOCACHE, ST+FH+AT), 556 PROC(lookup, diropargs, diropres, fhandle, RC_NOCACHE, ST+FH+AT),
555 PROC(readlink, readlinkargs, readlinkres, none, RC_NOCACHE, ST+1+NFS_MAXPATHLEN/4), 557 PROC(readlink, readlinkargs, readlinkres, none, RC_NOCACHE, ST+1+NFS_MAXPATHLEN/4),
556 PROC(read, readargs, readres, fhandle, RC_NOCACHE, ST+AT+1+NFSSVC_MAXBLKSIZE/4), 558 PROC(read, readargs, readres, fhandle, RC_NOCACHE, ST+AT+1+NFSSVC_MAXBLKSIZE_V2/4),
557 PROC(none, void, void, none, RC_NOCACHE, ST), 559 PROC(none, void, void, none, RC_NOCACHE, ST),
558 PROC(write, writeargs, attrstat, fhandle, RC_REPLBUFF, ST+AT), 560 PROC(write, writeargs, attrstat, fhandle, RC_REPLBUFF, ST+AT),
559 PROC(create, createargs, diropres, fhandle, RC_REPLBUFF, ST+FH+AT), 561 PROC(create, createargs, diropres, fhandle, RC_REPLBUFF, ST+FH+AT),
@@ -579,11 +581,11 @@ struct svc_version nfsd_version2 = {
579/* 581/*
580 * Map errnos to NFS errnos. 582 * Map errnos to NFS errnos.
581 */ 583 */
582int 584__be32
583nfserrno (int errno) 585nfserrno (int errno)
584{ 586{
585 static struct { 587 static struct {
586 int nfserr; 588 __be32 nfserr;
587 int syserr; 589 int syserr;
588 } nfs_errtbl[] = { 590 } nfs_errtbl[] = {
589 { nfs_ok, 0 }, 591 { nfs_ok, 0 },
@@ -615,11 +617,10 @@ nfserrno (int errno)
615 { nfserr_badname, -ESRCH }, 617 { nfserr_badname, -ESRCH },
616 { nfserr_io, -ETXTBSY }, 618 { nfserr_io, -ETXTBSY },
617 { nfserr_notsupp, -EOPNOTSUPP }, 619 { nfserr_notsupp, -EOPNOTSUPP },
618 { -1, -EIO }
619 }; 620 };
620 int i; 621 int i;
621 622
622 for (i = 0; nfs_errtbl[i].nfserr != -1; i++) { 623 for (i = 0; i < ARRAY_SIZE(nfs_errtbl); i++) {
623 if (nfs_errtbl[i].syserr == errno) 624 if (nfs_errtbl[i].syserr == errno)
624 return nfs_errtbl[i].nfserr; 625 return nfs_errtbl[i].nfserr;
625 } 626 }
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index 19443056ec30..0aaccb03bf76 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -198,9 +198,26 @@ int nfsd_create_serv(void)
198 unlock_kernel(); 198 unlock_kernel();
199 return 0; 199 return 0;
200 } 200 }
201 if (nfsd_max_blksize == 0) {
202 /* choose a suitable default */
203 struct sysinfo i;
204 si_meminfo(&i);
205 /* Aim for 1/4096 of memory per thread
206 * This gives 1MB on 4Gig machines
207 * But only uses 32K on 128M machines.
208 * Bottom out at 8K on 32M and smaller.
209 * Of course, this is only a default.
210 */
211 nfsd_max_blksize = NFSSVC_MAXBLKSIZE;
212 i.totalram <<= PAGE_SHIFT - 12;
213 while (nfsd_max_blksize > i.totalram &&
214 nfsd_max_blksize >= 8*1024*2)
215 nfsd_max_blksize /= 2;
216 }
201 217
202 atomic_set(&nfsd_busy, 0); 218 atomic_set(&nfsd_busy, 0);
203 nfsd_serv = svc_create_pooled(&nfsd_program, NFSD_BUFSIZE, 219 nfsd_serv = svc_create_pooled(&nfsd_program,
220 nfsd_max_blksize,
204 nfsd_last_thread, 221 nfsd_last_thread,
205 nfsd, SIG_NOCLEAN, THIS_MODULE); 222 nfsd, SIG_NOCLEAN, THIS_MODULE);
206 if (nfsd_serv == NULL) 223 if (nfsd_serv == NULL)
@@ -474,12 +491,12 @@ out:
474} 491}
475 492
476int 493int
477nfsd_dispatch(struct svc_rqst *rqstp, u32 *statp) 494nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp)
478{ 495{
479 struct svc_procedure *proc; 496 struct svc_procedure *proc;
480 kxdrproc_t xdr; 497 kxdrproc_t xdr;
481 u32 nfserr; 498 __be32 nfserr;
482 u32 *nfserrp; 499 __be32 *nfserrp;
483 500
484 dprintk("nfsd_dispatch: vers %d proc %d\n", 501 dprintk("nfsd_dispatch: vers %d proc %d\n",
485 rqstp->rq_vers, rqstp->rq_proc); 502 rqstp->rq_vers, rqstp->rq_proc);
@@ -498,7 +515,7 @@ nfsd_dispatch(struct svc_rqst *rqstp, u32 *statp)
498 515
499 /* Decode arguments */ 516 /* Decode arguments */
500 xdr = proc->pc_decode; 517 xdr = proc->pc_decode;
501 if (xdr && !xdr(rqstp, (u32*)rqstp->rq_arg.head[0].iov_base, 518 if (xdr && !xdr(rqstp, (__be32*)rqstp->rq_arg.head[0].iov_base,
502 rqstp->rq_argp)) { 519 rqstp->rq_argp)) {
503 dprintk("nfsd: failed to decode arguments!\n"); 520 dprintk("nfsd: failed to decode arguments!\n");
504 nfsd_cache_update(rqstp, RC_NOCACHE, NULL); 521 nfsd_cache_update(rqstp, RC_NOCACHE, NULL);
@@ -511,7 +528,7 @@ nfsd_dispatch(struct svc_rqst *rqstp, u32 *statp)
511 */ 528 */
512 nfserrp = rqstp->rq_res.head[0].iov_base 529 nfserrp = rqstp->rq_res.head[0].iov_base
513 + rqstp->rq_res.head[0].iov_len; 530 + rqstp->rq_res.head[0].iov_len;
514 rqstp->rq_res.head[0].iov_len += sizeof(u32); 531 rqstp->rq_res.head[0].iov_len += sizeof(__be32);
515 532
516 /* Now call the procedure handler, and encode NFS status. */ 533 /* Now call the procedure handler, and encode NFS status. */
517 nfserr = proc->pc_func(rqstp, rqstp->rq_argp, rqstp->rq_resp); 534 nfserr = proc->pc_func(rqstp, rqstp->rq_argp, rqstp->rq_resp);
diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c
index 3f14a17eaa6e..56ebb1443e0e 100644
--- a/fs/nfsd/nfsxdr.c
+++ b/fs/nfsd/nfsxdr.c
@@ -37,8 +37,8 @@ static u32 nfs_ftypes[] = {
37/* 37/*
38 * XDR functions for basic NFS types 38 * XDR functions for basic NFS types
39 */ 39 */
40static u32 * 40static __be32 *
41decode_fh(u32 *p, struct svc_fh *fhp) 41decode_fh(__be32 *p, struct svc_fh *fhp)
42{ 42{
43 fh_init(fhp, NFS_FHSIZE); 43 fh_init(fhp, NFS_FHSIZE);
44 memcpy(&fhp->fh_handle.fh_base, p, NFS_FHSIZE); 44 memcpy(&fhp->fh_handle.fh_base, p, NFS_FHSIZE);
@@ -50,13 +50,13 @@ decode_fh(u32 *p, struct svc_fh *fhp)
50} 50}
51 51
52/* Helper function for NFSv2 ACL code */ 52/* Helper function for NFSv2 ACL code */
53u32 *nfs2svc_decode_fh(u32 *p, struct svc_fh *fhp) 53__be32 *nfs2svc_decode_fh(__be32 *p, struct svc_fh *fhp)
54{ 54{
55 return decode_fh(p, fhp); 55 return decode_fh(p, fhp);
56} 56}
57 57
58static inline u32 * 58static inline __be32 *
59encode_fh(u32 *p, struct svc_fh *fhp) 59encode_fh(__be32 *p, struct svc_fh *fhp)
60{ 60{
61 memcpy(p, &fhp->fh_handle.fh_base, NFS_FHSIZE); 61 memcpy(p, &fhp->fh_handle.fh_base, NFS_FHSIZE);
62 return p + (NFS_FHSIZE>> 2); 62 return p + (NFS_FHSIZE>> 2);
@@ -66,8 +66,8 @@ encode_fh(u32 *p, struct svc_fh *fhp)
66 * Decode a file name and make sure that the path contains 66 * Decode a file name and make sure that the path contains
67 * no slashes or null bytes. 67 * no slashes or null bytes.
68 */ 68 */
69static inline u32 * 69static inline __be32 *
70decode_filename(u32 *p, char **namp, int *lenp) 70decode_filename(__be32 *p, char **namp, int *lenp)
71{ 71{
72 char *name; 72 char *name;
73 int i; 73 int i;
@@ -82,8 +82,8 @@ decode_filename(u32 *p, char **namp, int *lenp)
82 return p; 82 return p;
83} 83}
84 84
85static inline u32 * 85static inline __be32 *
86decode_pathname(u32 *p, char **namp, int *lenp) 86decode_pathname(__be32 *p, char **namp, int *lenp)
87{ 87{
88 char *name; 88 char *name;
89 int i; 89 int i;
@@ -98,8 +98,8 @@ decode_pathname(u32 *p, char **namp, int *lenp)
98 return p; 98 return p;
99} 99}
100 100
101static inline u32 * 101static inline __be32 *
102decode_sattr(u32 *p, struct iattr *iap) 102decode_sattr(__be32 *p, struct iattr *iap)
103{ 103{
104 u32 tmp, tmp1; 104 u32 tmp, tmp1;
105 105
@@ -151,8 +151,8 @@ decode_sattr(u32 *p, struct iattr *iap)
151 return p; 151 return p;
152} 152}
153 153
154static u32 * 154static __be32 *
155encode_fattr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp, 155encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp,
156 struct kstat *stat) 156 struct kstat *stat)
157{ 157{
158 struct dentry *dentry = fhp->fh_dentry; 158 struct dentry *dentry = fhp->fh_dentry;
@@ -195,7 +195,7 @@ encode_fattr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp,
195} 195}
196 196
197/* Helper function for NFSv2 ACL code */ 197/* Helper function for NFSv2 ACL code */
198u32 *nfs2svc_encode_fattr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp) 198__be32 *nfs2svc_encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp)
199{ 199{
200 struct kstat stat; 200 struct kstat stat;
201 vfs_getattr(fhp->fh_export->ex_mnt, fhp->fh_dentry, &stat); 201 vfs_getattr(fhp->fh_export->ex_mnt, fhp->fh_dentry, &stat);
@@ -206,13 +206,13 @@ u32 *nfs2svc_encode_fattr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp)
206 * XDR decode functions 206 * XDR decode functions
207 */ 207 */
208int 208int
209nfssvc_decode_void(struct svc_rqst *rqstp, u32 *p, void *dummy) 209nfssvc_decode_void(struct svc_rqst *rqstp, __be32 *p, void *dummy)
210{ 210{
211 return xdr_argsize_check(rqstp, p); 211 return xdr_argsize_check(rqstp, p);
212} 212}
213 213
214int 214int
215nfssvc_decode_fhandle(struct svc_rqst *rqstp, u32 *p, struct nfsd_fhandle *args) 215nfssvc_decode_fhandle(struct svc_rqst *rqstp, __be32 *p, struct nfsd_fhandle *args)
216{ 216{
217 if (!(p = decode_fh(p, &args->fh))) 217 if (!(p = decode_fh(p, &args->fh)))
218 return 0; 218 return 0;
@@ -220,7 +220,7 @@ nfssvc_decode_fhandle(struct svc_rqst *rqstp, u32 *p, struct nfsd_fhandle *args)
220} 220}
221 221
222int 222int
223nfssvc_decode_sattrargs(struct svc_rqst *rqstp, u32 *p, 223nfssvc_decode_sattrargs(struct svc_rqst *rqstp, __be32 *p,
224 struct nfsd_sattrargs *args) 224 struct nfsd_sattrargs *args)
225{ 225{
226 if (!(p = decode_fh(p, &args->fh)) 226 if (!(p = decode_fh(p, &args->fh))
@@ -231,7 +231,7 @@ nfssvc_decode_sattrargs(struct svc_rqst *rqstp, u32 *p,
231} 231}
232 232
233int 233int
234nfssvc_decode_diropargs(struct svc_rqst *rqstp, u32 *p, 234nfssvc_decode_diropargs(struct svc_rqst *rqstp, __be32 *p,
235 struct nfsd_diropargs *args) 235 struct nfsd_diropargs *args)
236{ 236{
237 if (!(p = decode_fh(p, &args->fh)) 237 if (!(p = decode_fh(p, &args->fh))
@@ -242,7 +242,7 @@ nfssvc_decode_diropargs(struct svc_rqst *rqstp, u32 *p,
242} 242}
243 243
244int 244int
245nfssvc_decode_readargs(struct svc_rqst *rqstp, u32 *p, 245nfssvc_decode_readargs(struct svc_rqst *rqstp, __be32 *p,
246 struct nfsd_readargs *args) 246 struct nfsd_readargs *args)
247{ 247{
248 unsigned int len; 248 unsigned int len;
@@ -254,19 +254,18 @@ nfssvc_decode_readargs(struct svc_rqst *rqstp, u32 *p,
254 len = args->count = ntohl(*p++); 254 len = args->count = ntohl(*p++);
255 p++; /* totalcount - unused */ 255 p++; /* totalcount - unused */
256 256
257 if (len > NFSSVC_MAXBLKSIZE) 257 if (len > NFSSVC_MAXBLKSIZE_V2)
258 len = NFSSVC_MAXBLKSIZE; 258 len = NFSSVC_MAXBLKSIZE_V2;
259 259
260 /* set up somewhere to store response. 260 /* set up somewhere to store response.
261 * We take pages, put them on reslist and include in iovec 261 * We take pages, put them on reslist and include in iovec
262 */ 262 */
263 v=0; 263 v=0;
264 while (len > 0) { 264 while (len > 0) {
265 pn=rqstp->rq_resused; 265 pn = rqstp->rq_resused++;
266 svc_take_page(rqstp); 266 rqstp->rq_vec[v].iov_base = page_address(rqstp->rq_respages[pn]);
267 args->vec[v].iov_base = page_address(rqstp->rq_respages[pn]); 267 rqstp->rq_vec[v].iov_len = len < PAGE_SIZE?len:PAGE_SIZE;
268 args->vec[v].iov_len = len < PAGE_SIZE?len:PAGE_SIZE; 268 len -= rqstp->rq_vec[v].iov_len;
269 len -= args->vec[v].iov_len;
270 v++; 269 v++;
271 } 270 }
272 args->vlen = v; 271 args->vlen = v;
@@ -274,7 +273,7 @@ nfssvc_decode_readargs(struct svc_rqst *rqstp, u32 *p,
274} 273}
275 274
276int 275int
277nfssvc_decode_writeargs(struct svc_rqst *rqstp, u32 *p, 276nfssvc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p,
278 struct nfsd_writeargs *args) 277 struct nfsd_writeargs *args)
279{ 278{
280 unsigned int len; 279 unsigned int len;
@@ -286,25 +285,25 @@ nfssvc_decode_writeargs(struct svc_rqst *rqstp, u32 *p,
286 args->offset = ntohl(*p++); /* offset */ 285 args->offset = ntohl(*p++); /* offset */
287 p++; /* totalcount */ 286 p++; /* totalcount */
288 len = args->len = ntohl(*p++); 287 len = args->len = ntohl(*p++);
289 args->vec[0].iov_base = (void*)p; 288 rqstp->rq_vec[0].iov_base = (void*)p;
290 args->vec[0].iov_len = rqstp->rq_arg.head[0].iov_len - 289 rqstp->rq_vec[0].iov_len = rqstp->rq_arg.head[0].iov_len -
291 (((void*)p) - rqstp->rq_arg.head[0].iov_base); 290 (((void*)p) - rqstp->rq_arg.head[0].iov_base);
292 if (len > NFSSVC_MAXBLKSIZE) 291 if (len > NFSSVC_MAXBLKSIZE_V2)
293 len = NFSSVC_MAXBLKSIZE; 292 len = NFSSVC_MAXBLKSIZE_V2;
294 v = 0; 293 v = 0;
295 while (len > args->vec[v].iov_len) { 294 while (len > rqstp->rq_vec[v].iov_len) {
296 len -= args->vec[v].iov_len; 295 len -= rqstp->rq_vec[v].iov_len;
297 v++; 296 v++;
298 args->vec[v].iov_base = page_address(rqstp->rq_argpages[v]); 297 rqstp->rq_vec[v].iov_base = page_address(rqstp->rq_pages[v]);
299 args->vec[v].iov_len = PAGE_SIZE; 298 rqstp->rq_vec[v].iov_len = PAGE_SIZE;
300 } 299 }
301 args->vec[v].iov_len = len; 300 rqstp->rq_vec[v].iov_len = len;
302 args->vlen = v+1; 301 args->vlen = v+1;
303 return args->vec[0].iov_len > 0; 302 return rqstp->rq_vec[0].iov_len > 0;
304} 303}
305 304
306int 305int
307nfssvc_decode_createargs(struct svc_rqst *rqstp, u32 *p, 306nfssvc_decode_createargs(struct svc_rqst *rqstp, __be32 *p,
308 struct nfsd_createargs *args) 307 struct nfsd_createargs *args)
309{ 308{
310 if (!(p = decode_fh(p, &args->fh)) 309 if (!(p = decode_fh(p, &args->fh))
@@ -316,7 +315,7 @@ nfssvc_decode_createargs(struct svc_rqst *rqstp, u32 *p,
316} 315}
317 316
318int 317int
319nfssvc_decode_renameargs(struct svc_rqst *rqstp, u32 *p, 318nfssvc_decode_renameargs(struct svc_rqst *rqstp, __be32 *p,
320 struct nfsd_renameargs *args) 319 struct nfsd_renameargs *args)
321{ 320{
322 if (!(p = decode_fh(p, &args->ffh)) 321 if (!(p = decode_fh(p, &args->ffh))
@@ -329,18 +328,17 @@ nfssvc_decode_renameargs(struct svc_rqst *rqstp, u32 *p,
329} 328}
330 329
331int 330int
332nfssvc_decode_readlinkargs(struct svc_rqst *rqstp, u32 *p, struct nfsd_readlinkargs *args) 331nfssvc_decode_readlinkargs(struct svc_rqst *rqstp, __be32 *p, struct nfsd_readlinkargs *args)
333{ 332{
334 if (!(p = decode_fh(p, &args->fh))) 333 if (!(p = decode_fh(p, &args->fh)))
335 return 0; 334 return 0;
336 svc_take_page(rqstp); 335 args->buffer = page_address(rqstp->rq_respages[rqstp->rq_resused++]);
337 args->buffer = page_address(rqstp->rq_respages[rqstp->rq_resused-1]);
338 336
339 return xdr_argsize_check(rqstp, p); 337 return xdr_argsize_check(rqstp, p);
340} 338}
341 339
342int 340int
343nfssvc_decode_linkargs(struct svc_rqst *rqstp, u32 *p, 341nfssvc_decode_linkargs(struct svc_rqst *rqstp, __be32 *p,
344 struct nfsd_linkargs *args) 342 struct nfsd_linkargs *args)
345{ 343{
346 if (!(p = decode_fh(p, &args->ffh)) 344 if (!(p = decode_fh(p, &args->ffh))
@@ -352,7 +350,7 @@ nfssvc_decode_linkargs(struct svc_rqst *rqstp, u32 *p,
352} 350}
353 351
354int 352int
355nfssvc_decode_symlinkargs(struct svc_rqst *rqstp, u32 *p, 353nfssvc_decode_symlinkargs(struct svc_rqst *rqstp, __be32 *p,
356 struct nfsd_symlinkargs *args) 354 struct nfsd_symlinkargs *args)
357{ 355{
358 if (!(p = decode_fh(p, &args->ffh)) 356 if (!(p = decode_fh(p, &args->ffh))
@@ -365,7 +363,7 @@ nfssvc_decode_symlinkargs(struct svc_rqst *rqstp, u32 *p,
365} 363}
366 364
367int 365int
368nfssvc_decode_readdirargs(struct svc_rqst *rqstp, u32 *p, 366nfssvc_decode_readdirargs(struct svc_rqst *rqstp, __be32 *p,
369 struct nfsd_readdirargs *args) 367 struct nfsd_readdirargs *args)
370{ 368{
371 if (!(p = decode_fh(p, &args->fh))) 369 if (!(p = decode_fh(p, &args->fh)))
@@ -375,8 +373,7 @@ nfssvc_decode_readdirargs(struct svc_rqst *rqstp, u32 *p,
375 if (args->count > PAGE_SIZE) 373 if (args->count > PAGE_SIZE)
376 args->count = PAGE_SIZE; 374 args->count = PAGE_SIZE;
377 375
378 svc_take_page(rqstp); 376 args->buffer = page_address(rqstp->rq_respages[rqstp->rq_resused++]);
379 args->buffer = page_address(rqstp->rq_respages[rqstp->rq_resused-1]);
380 377
381 return xdr_argsize_check(rqstp, p); 378 return xdr_argsize_check(rqstp, p);
382} 379}
@@ -385,13 +382,13 @@ nfssvc_decode_readdirargs(struct svc_rqst *rqstp, u32 *p,
385 * XDR encode functions 382 * XDR encode functions
386 */ 383 */
387int 384int
388nfssvc_encode_void(struct svc_rqst *rqstp, u32 *p, void *dummy) 385nfssvc_encode_void(struct svc_rqst *rqstp, __be32 *p, void *dummy)
389{ 386{
390 return xdr_ressize_check(rqstp, p); 387 return xdr_ressize_check(rqstp, p);
391} 388}
392 389
393int 390int
394nfssvc_encode_attrstat(struct svc_rqst *rqstp, u32 *p, 391nfssvc_encode_attrstat(struct svc_rqst *rqstp, __be32 *p,
395 struct nfsd_attrstat *resp) 392 struct nfsd_attrstat *resp)
396{ 393{
397 p = encode_fattr(rqstp, p, &resp->fh, &resp->stat); 394 p = encode_fattr(rqstp, p, &resp->fh, &resp->stat);
@@ -399,7 +396,7 @@ nfssvc_encode_attrstat(struct svc_rqst *rqstp, u32 *p,
399} 396}
400 397
401int 398int
402nfssvc_encode_diropres(struct svc_rqst *rqstp, u32 *p, 399nfssvc_encode_diropres(struct svc_rqst *rqstp, __be32 *p,
403 struct nfsd_diropres *resp) 400 struct nfsd_diropres *resp)
404{ 401{
405 p = encode_fh(p, &resp->fh); 402 p = encode_fh(p, &resp->fh);
@@ -408,7 +405,7 @@ nfssvc_encode_diropres(struct svc_rqst *rqstp, u32 *p,
408} 405}
409 406
410int 407int
411nfssvc_encode_readlinkres(struct svc_rqst *rqstp, u32 *p, 408nfssvc_encode_readlinkres(struct svc_rqst *rqstp, __be32 *p,
412 struct nfsd_readlinkres *resp) 409 struct nfsd_readlinkres *resp)
413{ 410{
414 *p++ = htonl(resp->len); 411 *p++ = htonl(resp->len);
@@ -416,7 +413,6 @@ nfssvc_encode_readlinkres(struct svc_rqst *rqstp, u32 *p,
416 rqstp->rq_res.page_len = resp->len; 413 rqstp->rq_res.page_len = resp->len;
417 if (resp->len & 3) { 414 if (resp->len & 3) {
418 /* need to pad the tail */ 415 /* need to pad the tail */
419 rqstp->rq_restailpage = 0;
420 rqstp->rq_res.tail[0].iov_base = p; 416 rqstp->rq_res.tail[0].iov_base = p;
421 *p = 0; 417 *p = 0;
422 rqstp->rq_res.tail[0].iov_len = 4 - (resp->len&3); 418 rqstp->rq_res.tail[0].iov_len = 4 - (resp->len&3);
@@ -425,7 +421,7 @@ nfssvc_encode_readlinkres(struct svc_rqst *rqstp, u32 *p,
425} 421}
426 422
427int 423int
428nfssvc_encode_readres(struct svc_rqst *rqstp, u32 *p, 424nfssvc_encode_readres(struct svc_rqst *rqstp, __be32 *p,
429 struct nfsd_readres *resp) 425 struct nfsd_readres *resp)
430{ 426{
431 p = encode_fattr(rqstp, p, &resp->fh, &resp->stat); 427 p = encode_fattr(rqstp, p, &resp->fh, &resp->stat);
@@ -436,7 +432,6 @@ nfssvc_encode_readres(struct svc_rqst *rqstp, u32 *p,
436 rqstp->rq_res.page_len = resp->count; 432 rqstp->rq_res.page_len = resp->count;
437 if (resp->count & 3) { 433 if (resp->count & 3) {
438 /* need to pad the tail */ 434 /* need to pad the tail */
439 rqstp->rq_restailpage = 0;
440 rqstp->rq_res.tail[0].iov_base = p; 435 rqstp->rq_res.tail[0].iov_base = p;
441 *p = 0; 436 *p = 0;
442 rqstp->rq_res.tail[0].iov_len = 4 - (resp->count&3); 437 rqstp->rq_res.tail[0].iov_len = 4 - (resp->count&3);
@@ -445,7 +440,7 @@ nfssvc_encode_readres(struct svc_rqst *rqstp, u32 *p,
445} 440}
446 441
447int 442int
448nfssvc_encode_readdirres(struct svc_rqst *rqstp, u32 *p, 443nfssvc_encode_readdirres(struct svc_rqst *rqstp, __be32 *p,
449 struct nfsd_readdirres *resp) 444 struct nfsd_readdirres *resp)
450{ 445{
451 xdr_ressize_check(rqstp, p); 446 xdr_ressize_check(rqstp, p);
@@ -458,12 +453,12 @@ nfssvc_encode_readdirres(struct svc_rqst *rqstp, u32 *p,
458} 453}
459 454
460int 455int
461nfssvc_encode_statfsres(struct svc_rqst *rqstp, u32 *p, 456nfssvc_encode_statfsres(struct svc_rqst *rqstp, __be32 *p,
462 struct nfsd_statfsres *resp) 457 struct nfsd_statfsres *resp)
463{ 458{
464 struct kstatfs *stat = &resp->stats; 459 struct kstatfs *stat = &resp->stats;
465 460
466 *p++ = htonl(NFSSVC_MAXBLKSIZE); /* max transfer size */ 461 *p++ = htonl(NFSSVC_MAXBLKSIZE_V2); /* max transfer size */
467 *p++ = htonl(stat->f_bsize); 462 *p++ = htonl(stat->f_bsize);
468 *p++ = htonl(stat->f_blocks); 463 *p++ = htonl(stat->f_blocks);
469 *p++ = htonl(stat->f_bfree); 464 *p++ = htonl(stat->f_bfree);
@@ -476,7 +471,7 @@ nfssvc_encode_entry(struct readdir_cd *ccd, const char *name,
476 int namlen, loff_t offset, ino_t ino, unsigned int d_type) 471 int namlen, loff_t offset, ino_t ino, unsigned int d_type)
477{ 472{
478 struct nfsd_readdirres *cd = container_of(ccd, struct nfsd_readdirres, common); 473 struct nfsd_readdirres *cd = container_of(ccd, struct nfsd_readdirres, common);
479 u32 *p = cd->buffer; 474 __be32 *p = cd->buffer;
480 int buflen, slen; 475 int buflen, slen;
481 476
482 /* 477 /*
@@ -502,7 +497,7 @@ nfssvc_encode_entry(struct readdir_cd *ccd, const char *name,
502 *p++ = htonl((u32) ino); /* file id */ 497 *p++ = htonl((u32) ino); /* file id */
503 p = xdr_encode_array(p, name, namlen);/* name length & name */ 498 p = xdr_encode_array(p, name, namlen);/* name length & name */
504 cd->offset = p; /* remember pointer */ 499 cd->offset = p; /* remember pointer */
505 *p++ = ~(u32) 0; /* offset of next entry */ 500 *p++ = htonl(~0U); /* offset of next entry */
506 501
507 cd->buflen = buflen; 502 cd->buflen = buflen;
508 cd->buffer = p; 503 cd->buffer = p;
@@ -514,7 +509,7 @@ nfssvc_encode_entry(struct readdir_cd *ccd, const char *name,
514 * XDR release functions 509 * XDR release functions
515 */ 510 */
516int 511int
517nfssvc_release_fhandle(struct svc_rqst *rqstp, u32 *p, 512nfssvc_release_fhandle(struct svc_rqst *rqstp, __be32 *p,
518 struct nfsd_fhandle *resp) 513 struct nfsd_fhandle *resp)
519{ 514{
520 fh_put(&resp->fh); 515 fh_put(&resp->fh);
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 443ebc52e382..f21e917bb8ed 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -54,6 +54,7 @@
54#include <linux/nfsd_idmap.h> 54#include <linux/nfsd_idmap.h>
55#include <linux/security.h> 55#include <linux/security.h>
56#endif /* CONFIG_NFSD_V4 */ 56#endif /* CONFIG_NFSD_V4 */
57#include <linux/jhash.h>
57 58
58#include <asm/uaccess.h> 59#include <asm/uaccess.h>
59 60
@@ -81,10 +82,19 @@ struct raparms {
81 dev_t p_dev; 82 dev_t p_dev;
82 int p_set; 83 int p_set;
83 struct file_ra_state p_ra; 84 struct file_ra_state p_ra;
85 unsigned int p_hindex;
84}; 86};
85 87
88struct raparm_hbucket {
89 struct raparms *pb_head;
90 spinlock_t pb_lock;
91} ____cacheline_aligned_in_smp;
92
86static struct raparms * raparml; 93static struct raparms * raparml;
87static struct raparms * raparm_cache; 94#define RAPARM_HASH_BITS 4
95#define RAPARM_HASH_SIZE (1<<RAPARM_HASH_BITS)
96#define RAPARM_HASH_MASK (RAPARM_HASH_SIZE-1)
97static struct raparm_hbucket raparm_hash[RAPARM_HASH_SIZE];
88 98
89/* 99/*
90 * Called from nfsd_lookup and encode_dirent. Check if we have crossed 100 * Called from nfsd_lookup and encode_dirent. Check if we have crossed
@@ -100,7 +110,7 @@ nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry **dpp,
100 struct dentry *dentry = *dpp; 110 struct dentry *dentry = *dpp;
101 struct vfsmount *mnt = mntget(exp->ex_mnt); 111 struct vfsmount *mnt = mntget(exp->ex_mnt);
102 struct dentry *mounts = dget(dentry); 112 struct dentry *mounts = dget(dentry);
103 int err = nfs_ok; 113 int err = 0;
104 114
105 while (follow_down(&mnt,&mounts)&&d_mountpoint(mounts)); 115 while (follow_down(&mnt,&mounts)&&d_mountpoint(mounts));
106 116
@@ -138,14 +148,15 @@ out:
138 * clients and is explicitly disallowed for NFSv3 148 * clients and is explicitly disallowed for NFSv3
139 * NeilBrown <neilb@cse.unsw.edu.au> 149 * NeilBrown <neilb@cse.unsw.edu.au>
140 */ 150 */
141int 151__be32
142nfsd_lookup(struct svc_rqst *rqstp, struct svc_fh *fhp, const char *name, 152nfsd_lookup(struct svc_rqst *rqstp, struct svc_fh *fhp, const char *name,
143 int len, struct svc_fh *resfh) 153 int len, struct svc_fh *resfh)
144{ 154{
145 struct svc_export *exp; 155 struct svc_export *exp;
146 struct dentry *dparent; 156 struct dentry *dparent;
147 struct dentry *dentry; 157 struct dentry *dentry;
148 int err; 158 __be32 err;
159 int host_err;
149 160
150 dprintk("nfsd: nfsd_lookup(fh %s, %.*s)\n", SVCFH_fmt(fhp), len,name); 161 dprintk("nfsd: nfsd_lookup(fh %s, %.*s)\n", SVCFH_fmt(fhp), len,name);
151 162
@@ -183,7 +194,7 @@ nfsd_lookup(struct svc_rqst *rqstp, struct svc_fh *fhp, const char *name,
183 exp2 = exp_parent(exp->ex_client, mnt, dentry, 194 exp2 = exp_parent(exp->ex_client, mnt, dentry,
184 &rqstp->rq_chandle); 195 &rqstp->rq_chandle);
185 if (IS_ERR(exp2)) { 196 if (IS_ERR(exp2)) {
186 err = PTR_ERR(exp2); 197 host_err = PTR_ERR(exp2);
187 dput(dentry); 198 dput(dentry);
188 mntput(mnt); 199 mntput(mnt);
189 goto out_nfserr; 200 goto out_nfserr;
@@ -200,14 +211,14 @@ nfsd_lookup(struct svc_rqst *rqstp, struct svc_fh *fhp, const char *name,
200 } else { 211 } else {
201 fh_lock(fhp); 212 fh_lock(fhp);
202 dentry = lookup_one_len(name, dparent, len); 213 dentry = lookup_one_len(name, dparent, len);
203 err = PTR_ERR(dentry); 214 host_err = PTR_ERR(dentry);
204 if (IS_ERR(dentry)) 215 if (IS_ERR(dentry))
205 goto out_nfserr; 216 goto out_nfserr;
206 /* 217 /*
207 * check if we have crossed a mount point ... 218 * check if we have crossed a mount point ...
208 */ 219 */
209 if (d_mountpoint(dentry)) { 220 if (d_mountpoint(dentry)) {
210 if ((err = nfsd_cross_mnt(rqstp, &dentry, &exp))) { 221 if ((host_err = nfsd_cross_mnt(rqstp, &dentry, &exp))) {
211 dput(dentry); 222 dput(dentry);
212 goto out_nfserr; 223 goto out_nfserr;
213 } 224 }
@@ -226,7 +237,7 @@ out:
226 return err; 237 return err;
227 238
228out_nfserr: 239out_nfserr:
229 err = nfserrno(err); 240 err = nfserrno(host_err);
230 goto out; 241 goto out;
231} 242}
232 243
@@ -234,7 +245,7 @@ out_nfserr:
234 * Set various file attributes. 245 * Set various file attributes.
235 * N.B. After this call fhp needs an fh_put 246 * N.B. After this call fhp needs an fh_put
236 */ 247 */
237int 248__be32
238nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap, 249nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
239 int check_guard, time_t guardtime) 250 int check_guard, time_t guardtime)
240{ 251{
@@ -243,7 +254,8 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
243 int accmode = MAY_SATTR; 254 int accmode = MAY_SATTR;
244 int ftype = 0; 255 int ftype = 0;
245 int imode; 256 int imode;
246 int err; 257 __be32 err;
258 int host_err;
247 int size_change = 0; 259 int size_change = 0;
248 260
249 if (iap->ia_valid & (ATTR_ATIME | ATTR_MTIME | ATTR_SIZE)) 261 if (iap->ia_valid & (ATTR_ATIME | ATTR_MTIME | ATTR_SIZE))
@@ -309,19 +321,19 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
309 * If we are changing the size of the file, then 321 * If we are changing the size of the file, then
310 * we need to break all leases. 322 * we need to break all leases.
311 */ 323 */
312 err = break_lease(inode, FMODE_WRITE | O_NONBLOCK); 324 host_err = break_lease(inode, FMODE_WRITE | O_NONBLOCK);
313 if (err == -EWOULDBLOCK) 325 if (host_err == -EWOULDBLOCK)
314 err = -ETIMEDOUT; 326 host_err = -ETIMEDOUT;
315 if (err) /* ENOMEM or EWOULDBLOCK */ 327 if (host_err) /* ENOMEM or EWOULDBLOCK */
316 goto out_nfserr; 328 goto out_nfserr;
317 329
318 err = get_write_access(inode); 330 host_err = get_write_access(inode);
319 if (err) 331 if (host_err)
320 goto out_nfserr; 332 goto out_nfserr;
321 333
322 size_change = 1; 334 size_change = 1;
323 err = locks_verify_truncate(inode, NULL, iap->ia_size); 335 host_err = locks_verify_truncate(inode, NULL, iap->ia_size);
324 if (err) { 336 if (host_err) {
325 put_write_access(inode); 337 put_write_access(inode);
326 goto out_nfserr; 338 goto out_nfserr;
327 } 339 }
@@ -347,8 +359,8 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
347 err = nfserr_notsync; 359 err = nfserr_notsync;
348 if (!check_guard || guardtime == inode->i_ctime.tv_sec) { 360 if (!check_guard || guardtime == inode->i_ctime.tv_sec) {
349 fh_lock(fhp); 361 fh_lock(fhp);
350 err = notify_change(dentry, iap); 362 host_err = notify_change(dentry, iap);
351 err = nfserrno(err); 363 err = nfserrno(host_err);
352 fh_unlock(fhp); 364 fh_unlock(fhp);
353 } 365 }
354 if (size_change) 366 if (size_change)
@@ -360,7 +372,7 @@ out:
360 return err; 372 return err;
361 373
362out_nfserr: 374out_nfserr:
363 err = nfserrno(err); 375 err = nfserrno(host_err);
364 goto out; 376 goto out;
365} 377}
366 378
@@ -410,11 +422,12 @@ out:
410 return error; 422 return error;
411} 423}
412 424
413int 425__be32
414nfsd4_set_nfs4_acl(struct svc_rqst *rqstp, struct svc_fh *fhp, 426nfsd4_set_nfs4_acl(struct svc_rqst *rqstp, struct svc_fh *fhp,
415 struct nfs4_acl *acl) 427 struct nfs4_acl *acl)
416{ 428{
417 int error; 429 __be32 error;
430 int host_error;
418 struct dentry *dentry; 431 struct dentry *dentry;
419 struct inode *inode; 432 struct inode *inode;
420 struct posix_acl *pacl = NULL, *dpacl = NULL; 433 struct posix_acl *pacl = NULL, *dpacl = NULL;
@@ -430,22 +443,20 @@ nfsd4_set_nfs4_acl(struct svc_rqst *rqstp, struct svc_fh *fhp,
430 if (S_ISDIR(inode->i_mode)) 443 if (S_ISDIR(inode->i_mode))
431 flags = NFS4_ACL_DIR; 444 flags = NFS4_ACL_DIR;
432 445
433 error = nfs4_acl_nfsv4_to_posix(acl, &pacl, &dpacl, flags); 446 host_error = nfs4_acl_nfsv4_to_posix(acl, &pacl, &dpacl, flags);
434 if (error == -EINVAL) { 447 if (host_error == -EINVAL) {
435 error = nfserr_attrnotsupp; 448 error = nfserr_attrnotsupp;
436 goto out; 449 goto out;
437 } else if (error < 0) 450 } else if (host_error < 0)
438 goto out_nfserr; 451 goto out_nfserr;
439 452
440 if (pacl) { 453 host_error = set_nfsv4_acl_one(dentry, pacl, POSIX_ACL_XATTR_ACCESS);
441 error = set_nfsv4_acl_one(dentry, pacl, POSIX_ACL_XATTR_ACCESS); 454 if (host_error < 0)
442 if (error < 0) 455 goto out_nfserr;
443 goto out_nfserr;
444 }
445 456
446 if (dpacl) { 457 if (S_ISDIR(inode->i_mode)) {
447 error = set_nfsv4_acl_one(dentry, dpacl, POSIX_ACL_XATTR_DEFAULT); 458 host_error = set_nfsv4_acl_one(dentry, dpacl, POSIX_ACL_XATTR_DEFAULT);
448 if (error < 0) 459 if (host_error < 0)
449 goto out_nfserr; 460 goto out_nfserr;
450 } 461 }
451 462
@@ -456,7 +467,7 @@ out:
456 posix_acl_release(dpacl); 467 posix_acl_release(dpacl);
457 return (error); 468 return (error);
458out_nfserr: 469out_nfserr:
459 error = nfserrno(error); 470 error = nfserrno(host_error);
460 goto out; 471 goto out;
461} 472}
462 473
@@ -563,14 +574,14 @@ static struct accessmap nfs3_anyaccess[] = {
563 { 0, 0 } 574 { 0, 0 }
564}; 575};
565 576
566int 577__be32
567nfsd_access(struct svc_rqst *rqstp, struct svc_fh *fhp, u32 *access, u32 *supported) 578nfsd_access(struct svc_rqst *rqstp, struct svc_fh *fhp, u32 *access, u32 *supported)
568{ 579{
569 struct accessmap *map; 580 struct accessmap *map;
570 struct svc_export *export; 581 struct svc_export *export;
571 struct dentry *dentry; 582 struct dentry *dentry;
572 u32 query, result = 0, sresult = 0; 583 u32 query, result = 0, sresult = 0;
573 unsigned int error; 584 __be32 error;
574 585
575 error = fh_verify(rqstp, fhp, 0, MAY_NOP); 586 error = fh_verify(rqstp, fhp, 0, MAY_NOP);
576 if (error) 587 if (error)
@@ -590,7 +601,7 @@ nfsd_access(struct svc_rqst *rqstp, struct svc_fh *fhp, u32 *access, u32 *suppor
590 query = *access; 601 query = *access;
591 for (; map->access; map++) { 602 for (; map->access; map++) {
592 if (map->access & query) { 603 if (map->access & query) {
593 unsigned int err2; 604 __be32 err2;
594 605
595 sresult |= map->access; 606 sresult |= map->access;
596 607
@@ -629,13 +640,15 @@ nfsd_access(struct svc_rqst *rqstp, struct svc_fh *fhp, u32 *access, u32 *suppor
629 * The access argument indicates the type of open (read/write/lock) 640 * The access argument indicates the type of open (read/write/lock)
630 * N.B. After this call fhp needs an fh_put 641 * N.B. After this call fhp needs an fh_put
631 */ 642 */
632int 643__be32
633nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, 644nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
634 int access, struct file **filp) 645 int access, struct file **filp)
635{ 646{
636 struct dentry *dentry; 647 struct dentry *dentry;
637 struct inode *inode; 648 struct inode *inode;
638 int flags = O_RDONLY|O_LARGEFILE, err; 649 int flags = O_RDONLY|O_LARGEFILE;
650 __be32 err;
651 int host_err;
639 652
640 /* 653 /*
641 * If we get here, then the client has already done an "open", 654 * If we get here, then the client has already done an "open",
@@ -665,10 +678,10 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
665 * Check to see if there are any leases on this file. 678 * Check to see if there are any leases on this file.
666 * This may block while leases are broken. 679 * This may block while leases are broken.
667 */ 680 */
668 err = break_lease(inode, O_NONBLOCK | ((access & MAY_WRITE) ? FMODE_WRITE : 0)); 681 host_err = break_lease(inode, O_NONBLOCK | ((access & MAY_WRITE) ? FMODE_WRITE : 0));
669 if (err == -EWOULDBLOCK) 682 if (host_err == -EWOULDBLOCK)
670 err = -ETIMEDOUT; 683 host_err = -ETIMEDOUT;
671 if (err) /* NOMEM or WOULDBLOCK */ 684 if (host_err) /* NOMEM or WOULDBLOCK */
672 goto out_nfserr; 685 goto out_nfserr;
673 686
674 if (access & MAY_WRITE) { 687 if (access & MAY_WRITE) {
@@ -681,10 +694,9 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
681 } 694 }
682 *filp = dentry_open(dget(dentry), mntget(fhp->fh_export->ex_mnt), flags); 695 *filp = dentry_open(dget(dentry), mntget(fhp->fh_export->ex_mnt), flags);
683 if (IS_ERR(*filp)) 696 if (IS_ERR(*filp))
684 err = PTR_ERR(*filp); 697 host_err = PTR_ERR(*filp);
685out_nfserr: 698out_nfserr:
686 if (err) 699 err = nfserrno(host_err);
687 err = nfserrno(err);
688out: 700out:
689 return err; 701 return err;
690} 702}
@@ -743,16 +755,20 @@ nfsd_sync_dir(struct dentry *dp)
743 * Obtain the readahead parameters for the file 755 * Obtain the readahead parameters for the file
744 * specified by (dev, ino). 756 * specified by (dev, ino).
745 */ 757 */
746static DEFINE_SPINLOCK(ra_lock);
747 758
748static inline struct raparms * 759static inline struct raparms *
749nfsd_get_raparms(dev_t dev, ino_t ino) 760nfsd_get_raparms(dev_t dev, ino_t ino)
750{ 761{
751 struct raparms *ra, **rap, **frap = NULL; 762 struct raparms *ra, **rap, **frap = NULL;
752 int depth = 0; 763 int depth = 0;
764 unsigned int hash;
765 struct raparm_hbucket *rab;
753 766
754 spin_lock(&ra_lock); 767 hash = jhash_2words(dev, ino, 0xfeedbeef) & RAPARM_HASH_MASK;
755 for (rap = &raparm_cache; (ra = *rap); rap = &ra->p_next) { 768 rab = &raparm_hash[hash];
769
770 spin_lock(&rab->pb_lock);
771 for (rap = &rab->pb_head; (ra = *rap); rap = &ra->p_next) {
756 if (ra->p_ino == ino && ra->p_dev == dev) 772 if (ra->p_ino == ino && ra->p_dev == dev)
757 goto found; 773 goto found;
758 depth++; 774 depth++;
@@ -761,7 +777,7 @@ nfsd_get_raparms(dev_t dev, ino_t ino)
761 } 777 }
762 depth = nfsdstats.ra_size*11/10; 778 depth = nfsdstats.ra_size*11/10;
763 if (!frap) { 779 if (!frap) {
764 spin_unlock(&ra_lock); 780 spin_unlock(&rab->pb_lock);
765 return NULL; 781 return NULL;
766 } 782 }
767 rap = frap; 783 rap = frap;
@@ -769,15 +785,16 @@ nfsd_get_raparms(dev_t dev, ino_t ino)
769 ra->p_dev = dev; 785 ra->p_dev = dev;
770 ra->p_ino = ino; 786 ra->p_ino = ino;
771 ra->p_set = 0; 787 ra->p_set = 0;
788 ra->p_hindex = hash;
772found: 789found:
773 if (rap != &raparm_cache) { 790 if (rap != &rab->pb_head) {
774 *rap = ra->p_next; 791 *rap = ra->p_next;
775 ra->p_next = raparm_cache; 792 ra->p_next = rab->pb_head;
776 raparm_cache = ra; 793 rab->pb_head = ra;
777 } 794 }
778 ra->p_count++; 795 ra->p_count++;
779 nfsdstats.ra_depth[depth*10/nfsdstats.ra_size]++; 796 nfsdstats.ra_depth[depth*10/nfsdstats.ra_size]++;
780 spin_unlock(&ra_lock); 797 spin_unlock(&rab->pb_lock);
781 return ra; 798 return ra;
782} 799}
783 800
@@ -791,36 +808,41 @@ nfsd_read_actor(read_descriptor_t *desc, struct page *page, unsigned long offset
791{ 808{
792 unsigned long count = desc->count; 809 unsigned long count = desc->count;
793 struct svc_rqst *rqstp = desc->arg.data; 810 struct svc_rqst *rqstp = desc->arg.data;
811 struct page **pp = rqstp->rq_respages + rqstp->rq_resused;
794 812
795 if (size > count) 813 if (size > count)
796 size = count; 814 size = count;
797 815
798 if (rqstp->rq_res.page_len == 0) { 816 if (rqstp->rq_res.page_len == 0) {
799 get_page(page); 817 get_page(page);
800 rqstp->rq_respages[rqstp->rq_resused++] = page; 818 put_page(*pp);
819 *pp = page;
820 rqstp->rq_resused++;
801 rqstp->rq_res.page_base = offset; 821 rqstp->rq_res.page_base = offset;
802 rqstp->rq_res.page_len = size; 822 rqstp->rq_res.page_len = size;
803 } else if (page != rqstp->rq_respages[rqstp->rq_resused-1]) { 823 } else if (page != pp[-1]) {
804 get_page(page); 824 get_page(page);
805 rqstp->rq_respages[rqstp->rq_resused++] = page; 825 put_page(*pp);
826 *pp = page;
827 rqstp->rq_resused++;
806 rqstp->rq_res.page_len += size; 828 rqstp->rq_res.page_len += size;
807 } else { 829 } else
808 rqstp->rq_res.page_len += size; 830 rqstp->rq_res.page_len += size;
809 }
810 831
811 desc->count = count - size; 832 desc->count = count - size;
812 desc->written += size; 833 desc->written += size;
813 return size; 834 return size;
814} 835}
815 836
816static int 837static __be32
817nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, 838nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
818 loff_t offset, struct kvec *vec, int vlen, unsigned long *count) 839 loff_t offset, struct kvec *vec, int vlen, unsigned long *count)
819{ 840{
820 struct inode *inode; 841 struct inode *inode;
821 struct raparms *ra; 842 struct raparms *ra;
822 mm_segment_t oldfs; 843 mm_segment_t oldfs;
823 int err; 844 __be32 err;
845 int host_err;
824 846
825 err = nfserr_perm; 847 err = nfserr_perm;
826 inode = file->f_dentry->d_inode; 848 inode = file->f_dentry->d_inode;
@@ -837,32 +859,33 @@ nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
837 file->f_ra = ra->p_ra; 859 file->f_ra = ra->p_ra;
838 860
839 if (file->f_op->sendfile && rqstp->rq_sendfile_ok) { 861 if (file->f_op->sendfile && rqstp->rq_sendfile_ok) {
840 svc_pushback_unused_pages(rqstp); 862 rqstp->rq_resused = 1;
841 err = file->f_op->sendfile(file, &offset, *count, 863 host_err = file->f_op->sendfile(file, &offset, *count,
842 nfsd_read_actor, rqstp); 864 nfsd_read_actor, rqstp);
843 } else { 865 } else {
844 oldfs = get_fs(); 866 oldfs = get_fs();
845 set_fs(KERNEL_DS); 867 set_fs(KERNEL_DS);
846 err = vfs_readv(file, (struct iovec __user *)vec, vlen, &offset); 868 host_err = vfs_readv(file, (struct iovec __user *)vec, vlen, &offset);
847 set_fs(oldfs); 869 set_fs(oldfs);
848 } 870 }
849 871
850 /* Write back readahead params */ 872 /* Write back readahead params */
851 if (ra) { 873 if (ra) {
852 spin_lock(&ra_lock); 874 struct raparm_hbucket *rab = &raparm_hash[ra->p_hindex];
875 spin_lock(&rab->pb_lock);
853 ra->p_ra = file->f_ra; 876 ra->p_ra = file->f_ra;
854 ra->p_set = 1; 877 ra->p_set = 1;
855 ra->p_count--; 878 ra->p_count--;
856 spin_unlock(&ra_lock); 879 spin_unlock(&rab->pb_lock);
857 } 880 }
858 881
859 if (err >= 0) { 882 if (host_err >= 0) {
860 nfsdstats.io_read += err; 883 nfsdstats.io_read += host_err;
861 *count = err; 884 *count = host_err;
862 err = 0; 885 err = 0;
863 fsnotify_access(file->f_dentry); 886 fsnotify_access(file->f_dentry);
864 } else 887 } else
865 err = nfserrno(err); 888 err = nfserrno(host_err);
866out: 889out:
867 return err; 890 return err;
868} 891}
@@ -877,7 +900,7 @@ static void kill_suid(struct dentry *dentry)
877 mutex_unlock(&dentry->d_inode->i_mutex); 900 mutex_unlock(&dentry->d_inode->i_mutex);
878} 901}
879 902
880static int 903static __be32
881nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, 904nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
882 loff_t offset, struct kvec *vec, int vlen, 905 loff_t offset, struct kvec *vec, int vlen,
883 unsigned long cnt, int *stablep) 906 unsigned long cnt, int *stablep)
@@ -886,7 +909,8 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
886 struct dentry *dentry; 909 struct dentry *dentry;
887 struct inode *inode; 910 struct inode *inode;
888 mm_segment_t oldfs; 911 mm_segment_t oldfs;
889 int err = 0; 912 __be32 err = 0;
913 int host_err;
890 int stable = *stablep; 914 int stable = *stablep;
891 915
892#ifdef MSNFS 916#ifdef MSNFS
@@ -922,18 +946,18 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
922 946
923 /* Write the data. */ 947 /* Write the data. */
924 oldfs = get_fs(); set_fs(KERNEL_DS); 948 oldfs = get_fs(); set_fs(KERNEL_DS);
925 err = vfs_writev(file, (struct iovec __user *)vec, vlen, &offset); 949 host_err = vfs_writev(file, (struct iovec __user *)vec, vlen, &offset);
926 set_fs(oldfs); 950 set_fs(oldfs);
927 if (err >= 0) { 951 if (host_err >= 0) {
928 nfsdstats.io_write += cnt; 952 nfsdstats.io_write += cnt;
929 fsnotify_modify(file->f_dentry); 953 fsnotify_modify(file->f_dentry);
930 } 954 }
931 955
932 /* clear setuid/setgid flag after write */ 956 /* clear setuid/setgid flag after write */
933 if (err >= 0 && (inode->i_mode & (S_ISUID | S_ISGID))) 957 if (host_err >= 0 && (inode->i_mode & (S_ISUID | S_ISGID)))
934 kill_suid(dentry); 958 kill_suid(dentry);
935 959
936 if (err >= 0 && stable) { 960 if (host_err >= 0 && stable) {
937 static ino_t last_ino; 961 static ino_t last_ino;
938 static dev_t last_dev; 962 static dev_t last_dev;
939 963
@@ -959,7 +983,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
959 983
960 if (inode->i_state & I_DIRTY) { 984 if (inode->i_state & I_DIRTY) {
961 dprintk("nfsd: write sync %d\n", current->pid); 985 dprintk("nfsd: write sync %d\n", current->pid);
962 err=nfsd_sync(file); 986 host_err=nfsd_sync(file);
963 } 987 }
964#if 0 988#if 0
965 wake_up(&inode->i_wait); 989 wake_up(&inode->i_wait);
@@ -969,11 +993,11 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
969 last_dev = inode->i_sb->s_dev; 993 last_dev = inode->i_sb->s_dev;
970 } 994 }
971 995
972 dprintk("nfsd: write complete err=%d\n", err); 996 dprintk("nfsd: write complete host_err=%d\n", host_err);
973 if (err >= 0) 997 if (host_err >= 0)
974 err = 0; 998 err = 0;
975 else 999 else
976 err = nfserrno(err); 1000 err = nfserrno(host_err);
977out: 1001out:
978 return err; 1002 return err;
979} 1003}
@@ -983,12 +1007,12 @@ out:
983 * on entry. On return, *count contains the number of bytes actually read. 1007 * on entry. On return, *count contains the number of bytes actually read.
984 * N.B. After this call fhp needs an fh_put 1008 * N.B. After this call fhp needs an fh_put
985 */ 1009 */
986int 1010__be32
987nfsd_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, 1011nfsd_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
988 loff_t offset, struct kvec *vec, int vlen, 1012 loff_t offset, struct kvec *vec, int vlen,
989 unsigned long *count) 1013 unsigned long *count)
990{ 1014{
991 int err; 1015 __be32 err;
992 1016
993 if (file) { 1017 if (file) {
994 err = nfsd_permission(fhp->fh_export, fhp->fh_dentry, 1018 err = nfsd_permission(fhp->fh_export, fhp->fh_dentry,
@@ -1012,12 +1036,12 @@ out:
1012 * The stable flag requests synchronous writes. 1036 * The stable flag requests synchronous writes.
1013 * N.B. After this call fhp needs an fh_put 1037 * N.B. After this call fhp needs an fh_put
1014 */ 1038 */
1015int 1039__be32
1016nfsd_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, 1040nfsd_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
1017 loff_t offset, struct kvec *vec, int vlen, unsigned long cnt, 1041 loff_t offset, struct kvec *vec, int vlen, unsigned long cnt,
1018 int *stablep) 1042 int *stablep)
1019{ 1043{
1020 int err = 0; 1044 __be32 err = 0;
1021 1045
1022 if (file) { 1046 if (file) {
1023 err = nfsd_permission(fhp->fh_export, fhp->fh_dentry, 1047 err = nfsd_permission(fhp->fh_export, fhp->fh_dentry,
@@ -1049,12 +1073,12 @@ out:
1049 * Unfortunately we cannot lock the file to make sure we return full WCC 1073 * Unfortunately we cannot lock the file to make sure we return full WCC
1050 * data to the client, as locking happens lower down in the filesystem. 1074 * data to the client, as locking happens lower down in the filesystem.
1051 */ 1075 */
1052int 1076__be32
1053nfsd_commit(struct svc_rqst *rqstp, struct svc_fh *fhp, 1077nfsd_commit(struct svc_rqst *rqstp, struct svc_fh *fhp,
1054 loff_t offset, unsigned long count) 1078 loff_t offset, unsigned long count)
1055{ 1079{
1056 struct file *file; 1080 struct file *file;
1057 int err; 1081 __be32 err;
1058 1082
1059 if ((u64)count > ~(u64)offset) 1083 if ((u64)count > ~(u64)offset)
1060 return nfserr_inval; 1084 return nfserr_inval;
@@ -1082,14 +1106,15 @@ nfsd_commit(struct svc_rqst *rqstp, struct svc_fh *fhp,
1082 * 1106 *
1083 * N.B. Every call to nfsd_create needs an fh_put for _both_ fhp and resfhp 1107 * N.B. Every call to nfsd_create needs an fh_put for _both_ fhp and resfhp
1084 */ 1108 */
1085int 1109__be32
1086nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp, 1110nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
1087 char *fname, int flen, struct iattr *iap, 1111 char *fname, int flen, struct iattr *iap,
1088 int type, dev_t rdev, struct svc_fh *resfhp) 1112 int type, dev_t rdev, struct svc_fh *resfhp)
1089{ 1113{
1090 struct dentry *dentry, *dchild = NULL; 1114 struct dentry *dentry, *dchild = NULL;
1091 struct inode *dirp; 1115 struct inode *dirp;
1092 int err; 1116 __be32 err;
1117 int host_err;
1093 1118
1094 err = nfserr_perm; 1119 err = nfserr_perm;
1095 if (!flen) 1120 if (!flen)
@@ -1116,7 +1141,7 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
1116 /* called from nfsd_proc_mkdir, or possibly nfsd3_proc_create */ 1141 /* called from nfsd_proc_mkdir, or possibly nfsd3_proc_create */
1117 fh_lock_nested(fhp, I_MUTEX_PARENT); 1142 fh_lock_nested(fhp, I_MUTEX_PARENT);
1118 dchild = lookup_one_len(fname, dentry, flen); 1143 dchild = lookup_one_len(fname, dentry, flen);
1119 err = PTR_ERR(dchild); 1144 host_err = PTR_ERR(dchild);
1120 if (IS_ERR(dchild)) 1145 if (IS_ERR(dchild))
1121 goto out_nfserr; 1146 goto out_nfserr;
1122 err = fh_compose(resfhp, fhp->fh_export, dchild, fhp); 1147 err = fh_compose(resfhp, fhp->fh_export, dchild, fhp);
@@ -1155,22 +1180,22 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
1155 err = nfserr_perm; 1180 err = nfserr_perm;
1156 switch (type) { 1181 switch (type) {
1157 case S_IFREG: 1182 case S_IFREG:
1158 err = vfs_create(dirp, dchild, iap->ia_mode, NULL); 1183 host_err = vfs_create(dirp, dchild, iap->ia_mode, NULL);
1159 break; 1184 break;
1160 case S_IFDIR: 1185 case S_IFDIR:
1161 err = vfs_mkdir(dirp, dchild, iap->ia_mode); 1186 host_err = vfs_mkdir(dirp, dchild, iap->ia_mode);
1162 break; 1187 break;
1163 case S_IFCHR: 1188 case S_IFCHR:
1164 case S_IFBLK: 1189 case S_IFBLK:
1165 case S_IFIFO: 1190 case S_IFIFO:
1166 case S_IFSOCK: 1191 case S_IFSOCK:
1167 err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev); 1192 host_err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev);
1168 break; 1193 break;
1169 default: 1194 default:
1170 printk("nfsd: bad file type %o in nfsd_create\n", type); 1195 printk("nfsd: bad file type %o in nfsd_create\n", type);
1171 err = -EINVAL; 1196 host_err = -EINVAL;
1172 } 1197 }
1173 if (err < 0) 1198 if (host_err < 0)
1174 goto out_nfserr; 1199 goto out_nfserr;
1175 1200
1176 if (EX_ISSYNC(fhp->fh_export)) { 1201 if (EX_ISSYNC(fhp->fh_export)) {
@@ -1185,7 +1210,7 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
1185 * directories via NFS. 1210 * directories via NFS.
1186 */ 1211 */
1187 if ((iap->ia_valid &= ~(ATTR_UID|ATTR_GID|ATTR_MODE)) != 0) { 1212 if ((iap->ia_valid &= ~(ATTR_UID|ATTR_GID|ATTR_MODE)) != 0) {
1188 int err2 = nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0); 1213 __be32 err2 = nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0);
1189 if (err2) 1214 if (err2)
1190 err = err2; 1215 err = err2;
1191 } 1216 }
@@ -1200,7 +1225,7 @@ out:
1200 return err; 1225 return err;
1201 1226
1202out_nfserr: 1227out_nfserr:
1203 err = nfserrno(err); 1228 err = nfserrno(host_err);
1204 goto out; 1229 goto out;
1205} 1230}
1206 1231
@@ -1208,7 +1233,7 @@ out_nfserr:
1208/* 1233/*
1209 * NFSv3 version of nfsd_create 1234 * NFSv3 version of nfsd_create
1210 */ 1235 */
1211int 1236__be32
1212nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp, 1237nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
1213 char *fname, int flen, struct iattr *iap, 1238 char *fname, int flen, struct iattr *iap,
1214 struct svc_fh *resfhp, int createmode, u32 *verifier, 1239 struct svc_fh *resfhp, int createmode, u32 *verifier,
@@ -1216,7 +1241,8 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
1216{ 1241{
1217 struct dentry *dentry, *dchild = NULL; 1242 struct dentry *dentry, *dchild = NULL;
1218 struct inode *dirp; 1243 struct inode *dirp;
1219 int err; 1244 __be32 err;
1245 int host_err;
1220 __u32 v_mtime=0, v_atime=0; 1246 __u32 v_mtime=0, v_atime=0;
1221 int v_mode=0; 1247 int v_mode=0;
1222 1248
@@ -1246,7 +1272,7 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
1246 * Compose the response file handle. 1272 * Compose the response file handle.
1247 */ 1273 */
1248 dchild = lookup_one_len(fname, dentry, flen); 1274 dchild = lookup_one_len(fname, dentry, flen);
1249 err = PTR_ERR(dchild); 1275 host_err = PTR_ERR(dchild);
1250 if (IS_ERR(dchild)) 1276 if (IS_ERR(dchild))
1251 goto out_nfserr; 1277 goto out_nfserr;
1252 1278
@@ -1302,8 +1328,8 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
1302 goto out; 1328 goto out;
1303 } 1329 }
1304 1330
1305 err = vfs_create(dirp, dchild, iap->ia_mode, NULL); 1331 host_err = vfs_create(dirp, dchild, iap->ia_mode, NULL);
1306 if (err < 0) 1332 if (host_err < 0)
1307 goto out_nfserr; 1333 goto out_nfserr;
1308 1334
1309 if (EX_ISSYNC(fhp->fh_export)) { 1335 if (EX_ISSYNC(fhp->fh_export)) {
@@ -1332,7 +1358,7 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
1332 */ 1358 */
1333 set_attr: 1359 set_attr:
1334 if ((iap->ia_valid &= ~(ATTR_UID|ATTR_GID)) != 0) { 1360 if ((iap->ia_valid &= ~(ATTR_UID|ATTR_GID)) != 0) {
1335 int err2 = nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0); 1361 __be32 err2 = nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0);
1336 if (err2) 1362 if (err2)
1337 err = err2; 1363 err = err2;
1338 } 1364 }
@@ -1350,7 +1376,7 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
1350 return err; 1376 return err;
1351 1377
1352 out_nfserr: 1378 out_nfserr:
1353 err = nfserrno(err); 1379 err = nfserrno(host_err);
1354 goto out; 1380 goto out;
1355} 1381}
1356#endif /* CONFIG_NFSD_V3 */ 1382#endif /* CONFIG_NFSD_V3 */
@@ -1360,13 +1386,14 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
1360 * fits into the buffer. On return, it contains the true length. 1386 * fits into the buffer. On return, it contains the true length.
1361 * N.B. After this call fhp needs an fh_put 1387 * N.B. After this call fhp needs an fh_put
1362 */ 1388 */
1363int 1389__be32
1364nfsd_readlink(struct svc_rqst *rqstp, struct svc_fh *fhp, char *buf, int *lenp) 1390nfsd_readlink(struct svc_rqst *rqstp, struct svc_fh *fhp, char *buf, int *lenp)
1365{ 1391{
1366 struct dentry *dentry; 1392 struct dentry *dentry;
1367 struct inode *inode; 1393 struct inode *inode;
1368 mm_segment_t oldfs; 1394 mm_segment_t oldfs;
1369 int err; 1395 __be32 err;
1396 int host_err;
1370 1397
1371 err = fh_verify(rqstp, fhp, S_IFLNK, MAY_NOP); 1398 err = fh_verify(rqstp, fhp, S_IFLNK, MAY_NOP);
1372 if (err) 1399 if (err)
@@ -1385,18 +1412,18 @@ nfsd_readlink(struct svc_rqst *rqstp, struct svc_fh *fhp, char *buf, int *lenp)
1385 */ 1412 */
1386 1413
1387 oldfs = get_fs(); set_fs(KERNEL_DS); 1414 oldfs = get_fs(); set_fs(KERNEL_DS);
1388 err = inode->i_op->readlink(dentry, buf, *lenp); 1415 host_err = inode->i_op->readlink(dentry, buf, *lenp);
1389 set_fs(oldfs); 1416 set_fs(oldfs);
1390 1417
1391 if (err < 0) 1418 if (host_err < 0)
1392 goto out_nfserr; 1419 goto out_nfserr;
1393 *lenp = err; 1420 *lenp = host_err;
1394 err = 0; 1421 err = 0;
1395out: 1422out:
1396 return err; 1423 return err;
1397 1424
1398out_nfserr: 1425out_nfserr:
1399 err = nfserrno(err); 1426 err = nfserrno(host_err);
1400 goto out; 1427 goto out;
1401} 1428}
1402 1429
@@ -1404,7 +1431,7 @@ out_nfserr:
1404 * Create a symlink and look up its inode 1431 * Create a symlink and look up its inode
1405 * N.B. After this call _both_ fhp and resfhp need an fh_put 1432 * N.B. After this call _both_ fhp and resfhp need an fh_put
1406 */ 1433 */
1407int 1434__be32
1408nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp, 1435nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp,
1409 char *fname, int flen, 1436 char *fname, int flen,
1410 char *path, int plen, 1437 char *path, int plen,
@@ -1412,7 +1439,8 @@ nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp,
1412 struct iattr *iap) 1439 struct iattr *iap)
1413{ 1440{
1414 struct dentry *dentry, *dnew; 1441 struct dentry *dentry, *dnew;
1415 int err, cerr; 1442 __be32 err, cerr;
1443 int host_err;
1416 umode_t mode; 1444 umode_t mode;
1417 1445
1418 err = nfserr_noent; 1446 err = nfserr_noent;
@@ -1428,7 +1456,7 @@ nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp,
1428 fh_lock(fhp); 1456 fh_lock(fhp);
1429 dentry = fhp->fh_dentry; 1457 dentry = fhp->fh_dentry;
1430 dnew = lookup_one_len(fname, dentry, flen); 1458 dnew = lookup_one_len(fname, dentry, flen);
1431 err = PTR_ERR(dnew); 1459 host_err = PTR_ERR(dnew);
1432 if (IS_ERR(dnew)) 1460 if (IS_ERR(dnew))
1433 goto out_nfserr; 1461 goto out_nfserr;
1434 1462
@@ -1440,21 +1468,21 @@ nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp,
1440 if (unlikely(path[plen] != 0)) { 1468 if (unlikely(path[plen] != 0)) {
1441 char *path_alloced = kmalloc(plen+1, GFP_KERNEL); 1469 char *path_alloced = kmalloc(plen+1, GFP_KERNEL);
1442 if (path_alloced == NULL) 1470 if (path_alloced == NULL)
1443 err = -ENOMEM; 1471 host_err = -ENOMEM;
1444 else { 1472 else {
1445 strncpy(path_alloced, path, plen); 1473 strncpy(path_alloced, path, plen);
1446 path_alloced[plen] = 0; 1474 path_alloced[plen] = 0;
1447 err = vfs_symlink(dentry->d_inode, dnew, path_alloced, mode); 1475 host_err = vfs_symlink(dentry->d_inode, dnew, path_alloced, mode);
1448 kfree(path_alloced); 1476 kfree(path_alloced);
1449 } 1477 }
1450 } else 1478 } else
1451 err = vfs_symlink(dentry->d_inode, dnew, path, mode); 1479 host_err = vfs_symlink(dentry->d_inode, dnew, path, mode);
1452 1480
1453 if (!err) 1481 if (!host_err) {
1454 if (EX_ISSYNC(fhp->fh_export)) 1482 if (EX_ISSYNC(fhp->fh_export))
1455 err = nfsd_sync_dir(dentry); 1483 host_err = nfsd_sync_dir(dentry);
1456 if (err) 1484 }
1457 err = nfserrno(err); 1485 err = nfserrno(host_err);
1458 fh_unlock(fhp); 1486 fh_unlock(fhp);
1459 1487
1460 cerr = fh_compose(resfhp, fhp->fh_export, dnew, fhp); 1488 cerr = fh_compose(resfhp, fhp->fh_export, dnew, fhp);
@@ -1464,7 +1492,7 @@ out:
1464 return err; 1492 return err;
1465 1493
1466out_nfserr: 1494out_nfserr:
1467 err = nfserrno(err); 1495 err = nfserrno(host_err);
1468 goto out; 1496 goto out;
1469} 1497}
1470 1498
@@ -1472,13 +1500,14 @@ out_nfserr:
1472 * Create a hardlink 1500 * Create a hardlink
1473 * N.B. After this call _both_ ffhp and tfhp need an fh_put 1501 * N.B. After this call _both_ ffhp and tfhp need an fh_put
1474 */ 1502 */
1475int 1503__be32
1476nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp, 1504nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp,
1477 char *name, int len, struct svc_fh *tfhp) 1505 char *name, int len, struct svc_fh *tfhp)
1478{ 1506{
1479 struct dentry *ddir, *dnew, *dold; 1507 struct dentry *ddir, *dnew, *dold;
1480 struct inode *dirp, *dest; 1508 struct inode *dirp, *dest;
1481 int err; 1509 __be32 err;
1510 int host_err;
1482 1511
1483 err = fh_verify(rqstp, ffhp, S_IFDIR, MAY_CREATE); 1512 err = fh_verify(rqstp, ffhp, S_IFDIR, MAY_CREATE);
1484 if (err) 1513 if (err)
@@ -1499,24 +1528,25 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp,
1499 dirp = ddir->d_inode; 1528 dirp = ddir->d_inode;
1500 1529
1501 dnew = lookup_one_len(name, ddir, len); 1530 dnew = lookup_one_len(name, ddir, len);
1502 err = PTR_ERR(dnew); 1531 host_err = PTR_ERR(dnew);
1503 if (IS_ERR(dnew)) 1532 if (IS_ERR(dnew))
1504 goto out_nfserr; 1533 goto out_nfserr;
1505 1534
1506 dold = tfhp->fh_dentry; 1535 dold = tfhp->fh_dentry;
1507 dest = dold->d_inode; 1536 dest = dold->d_inode;
1508 1537
1509 err = vfs_link(dold, dirp, dnew); 1538 host_err = vfs_link(dold, dirp, dnew);
1510 if (!err) { 1539 if (!host_err) {
1511 if (EX_ISSYNC(ffhp->fh_export)) { 1540 if (EX_ISSYNC(ffhp->fh_export)) {
1512 err = nfserrno(nfsd_sync_dir(ddir)); 1541 err = nfserrno(nfsd_sync_dir(ddir));
1513 write_inode_now(dest, 1); 1542 write_inode_now(dest, 1);
1514 } 1543 }
1544 err = 0;
1515 } else { 1545 } else {
1516 if (err == -EXDEV && rqstp->rq_vers == 2) 1546 if (host_err == -EXDEV && rqstp->rq_vers == 2)
1517 err = nfserr_acces; 1547 err = nfserr_acces;
1518 else 1548 else
1519 err = nfserrno(err); 1549 err = nfserrno(host_err);
1520 } 1550 }
1521 1551
1522 dput(dnew); 1552 dput(dnew);
@@ -1526,7 +1556,7 @@ out:
1526 return err; 1556 return err;
1527 1557
1528out_nfserr: 1558out_nfserr:
1529 err = nfserrno(err); 1559 err = nfserrno(host_err);
1530 goto out_unlock; 1560 goto out_unlock;
1531} 1561}
1532 1562
@@ -1534,13 +1564,14 @@ out_nfserr:
1534 * Rename a file 1564 * Rename a file
1535 * N.B. After this call _both_ ffhp and tfhp need an fh_put 1565 * N.B. After this call _both_ ffhp and tfhp need an fh_put
1536 */ 1566 */
1537int 1567__be32
1538nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen, 1568nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen,
1539 struct svc_fh *tfhp, char *tname, int tlen) 1569 struct svc_fh *tfhp, char *tname, int tlen)
1540{ 1570{
1541 struct dentry *fdentry, *tdentry, *odentry, *ndentry, *trap; 1571 struct dentry *fdentry, *tdentry, *odentry, *ndentry, *trap;
1542 struct inode *fdir, *tdir; 1572 struct inode *fdir, *tdir;
1543 int err; 1573 __be32 err;
1574 int host_err;
1544 1575
1545 err = fh_verify(rqstp, ffhp, S_IFDIR, MAY_REMOVE); 1576 err = fh_verify(rqstp, ffhp, S_IFDIR, MAY_REMOVE);
1546 if (err) 1577 if (err)
@@ -1571,22 +1602,22 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen,
1571 fill_pre_wcc(tfhp); 1602 fill_pre_wcc(tfhp);
1572 1603
1573 odentry = lookup_one_len(fname, fdentry, flen); 1604 odentry = lookup_one_len(fname, fdentry, flen);
1574 err = PTR_ERR(odentry); 1605 host_err = PTR_ERR(odentry);
1575 if (IS_ERR(odentry)) 1606 if (IS_ERR(odentry))
1576 goto out_nfserr; 1607 goto out_nfserr;
1577 1608
1578 err = -ENOENT; 1609 host_err = -ENOENT;
1579 if (!odentry->d_inode) 1610 if (!odentry->d_inode)
1580 goto out_dput_old; 1611 goto out_dput_old;
1581 err = -EINVAL; 1612 host_err = -EINVAL;
1582 if (odentry == trap) 1613 if (odentry == trap)
1583 goto out_dput_old; 1614 goto out_dput_old;
1584 1615
1585 ndentry = lookup_one_len(tname, tdentry, tlen); 1616 ndentry = lookup_one_len(tname, tdentry, tlen);
1586 err = PTR_ERR(ndentry); 1617 host_err = PTR_ERR(ndentry);
1587 if (IS_ERR(ndentry)) 1618 if (IS_ERR(ndentry))
1588 goto out_dput_old; 1619 goto out_dput_old;
1589 err = -ENOTEMPTY; 1620 host_err = -ENOTEMPTY;
1590 if (ndentry == trap) 1621 if (ndentry == trap)
1591 goto out_dput_new; 1622 goto out_dput_new;
1592 1623
@@ -1594,14 +1625,14 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen,
1594 if ((ffhp->fh_export->ex_flags & NFSEXP_MSNFS) && 1625 if ((ffhp->fh_export->ex_flags & NFSEXP_MSNFS) &&
1595 ((atomic_read(&odentry->d_count) > 1) 1626 ((atomic_read(&odentry->d_count) > 1)
1596 || (atomic_read(&ndentry->d_count) > 1))) { 1627 || (atomic_read(&ndentry->d_count) > 1))) {
1597 err = -EPERM; 1628 host_err = -EPERM;
1598 } else 1629 } else
1599#endif 1630#endif
1600 err = vfs_rename(fdir, odentry, tdir, ndentry); 1631 host_err = vfs_rename(fdir, odentry, tdir, ndentry);
1601 if (!err && EX_ISSYNC(tfhp->fh_export)) { 1632 if (!host_err && EX_ISSYNC(tfhp->fh_export)) {
1602 err = nfsd_sync_dir(tdentry); 1633 host_err = nfsd_sync_dir(tdentry);
1603 if (!err) 1634 if (!host_err)
1604 err = nfsd_sync_dir(fdentry); 1635 host_err = nfsd_sync_dir(fdentry);
1605 } 1636 }
1606 1637
1607 out_dput_new: 1638 out_dput_new:
@@ -1609,8 +1640,7 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen,
1609 out_dput_old: 1640 out_dput_old:
1610 dput(odentry); 1641 dput(odentry);
1611 out_nfserr: 1642 out_nfserr:
1612 if (err) 1643 err = nfserrno(host_err);
1613 err = nfserrno(err);
1614 1644
1615 /* we cannot reply on fh_unlock on the two filehandles, 1645 /* we cannot reply on fh_unlock on the two filehandles,
1616 * as that would do the wrong thing if the two directories 1646 * as that would do the wrong thing if the two directories
@@ -1629,13 +1659,14 @@ out:
1629 * Unlink a file or directory 1659 * Unlink a file or directory
1630 * N.B. After this call fhp needs an fh_put 1660 * N.B. After this call fhp needs an fh_put
1631 */ 1661 */
1632int 1662__be32
1633nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, 1663nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
1634 char *fname, int flen) 1664 char *fname, int flen)
1635{ 1665{
1636 struct dentry *dentry, *rdentry; 1666 struct dentry *dentry, *rdentry;
1637 struct inode *dirp; 1667 struct inode *dirp;
1638 int err; 1668 __be32 err;
1669 int host_err;
1639 1670
1640 err = nfserr_acces; 1671 err = nfserr_acces;
1641 if (!flen || isdotent(fname, flen)) 1672 if (!flen || isdotent(fname, flen))
@@ -1649,7 +1680,7 @@ nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
1649 dirp = dentry->d_inode; 1680 dirp = dentry->d_inode;
1650 1681
1651 rdentry = lookup_one_len(fname, dentry, flen); 1682 rdentry = lookup_one_len(fname, dentry, flen);
1652 err = PTR_ERR(rdentry); 1683 host_err = PTR_ERR(rdentry);
1653 if (IS_ERR(rdentry)) 1684 if (IS_ERR(rdentry))
1654 goto out_nfserr; 1685 goto out_nfserr;
1655 1686
@@ -1666,22 +1697,23 @@ nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
1666#ifdef MSNFS 1697#ifdef MSNFS
1667 if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) && 1698 if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) &&
1668 (atomic_read(&rdentry->d_count) > 1)) { 1699 (atomic_read(&rdentry->d_count) > 1)) {
1669 err = -EPERM; 1700 host_err = -EPERM;
1670 } else 1701 } else
1671#endif 1702#endif
1672 err = vfs_unlink(dirp, rdentry); 1703 host_err = vfs_unlink(dirp, rdentry);
1673 } else { /* It's RMDIR */ 1704 } else { /* It's RMDIR */
1674 err = vfs_rmdir(dirp, rdentry); 1705 host_err = vfs_rmdir(dirp, rdentry);
1675 } 1706 }
1676 1707
1677 dput(rdentry); 1708 dput(rdentry);
1678 1709
1679 if (err == 0 && 1710 if (host_err)
1680 EX_ISSYNC(fhp->fh_export)) 1711 goto out_nfserr;
1681 err = nfsd_sync_dir(dentry); 1712 if (EX_ISSYNC(fhp->fh_export))
1713 host_err = nfsd_sync_dir(dentry);
1682 1714
1683out_nfserr: 1715out_nfserr:
1684 err = nfserrno(err); 1716 err = nfserrno(host_err);
1685out: 1717out:
1686 return err; 1718 return err;
1687} 1719}
@@ -1690,11 +1722,12 @@ out:
1690 * Read entries from a directory. 1722 * Read entries from a directory.
1691 * The NFSv3/4 verifier we ignore for now. 1723 * The NFSv3/4 verifier we ignore for now.
1692 */ 1724 */
1693int 1725__be32
1694nfsd_readdir(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t *offsetp, 1726nfsd_readdir(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t *offsetp,
1695 struct readdir_cd *cdp, encode_dent_fn func) 1727 struct readdir_cd *cdp, encode_dent_fn func)
1696{ 1728{
1697 int err; 1729 __be32 err;
1730 int host_err;
1698 struct file *file; 1731 struct file *file;
1699 loff_t offset = *offsetp; 1732 loff_t offset = *offsetp;
1700 1733
@@ -1716,10 +1749,10 @@ nfsd_readdir(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t *offsetp,
1716 1749
1717 do { 1750 do {
1718 cdp->err = nfserr_eof; /* will be cleared on successful read */ 1751 cdp->err = nfserr_eof; /* will be cleared on successful read */
1719 err = vfs_readdir(file, (filldir_t) func, cdp); 1752 host_err = vfs_readdir(file, (filldir_t) func, cdp);
1720 } while (err >=0 && cdp->err == nfs_ok); 1753 } while (host_err >=0 && cdp->err == nfs_ok);
1721 if (err) 1754 if (host_err)
1722 err = nfserrno(err); 1755 err = nfserrno(host_err);
1723 else 1756 else
1724 err = cdp->err; 1757 err = cdp->err;
1725 *offsetp = vfs_llseek(file, 0, 1); 1758 *offsetp = vfs_llseek(file, 0, 1);
@@ -1736,10 +1769,10 @@ out:
1736 * Get file system stats 1769 * Get file system stats
1737 * N.B. After this call fhp needs an fh_put 1770 * N.B. After this call fhp needs an fh_put
1738 */ 1771 */
1739int 1772__be32
1740nfsd_statfs(struct svc_rqst *rqstp, struct svc_fh *fhp, struct kstatfs *stat) 1773nfsd_statfs(struct svc_rqst *rqstp, struct svc_fh *fhp, struct kstatfs *stat)
1741{ 1774{
1742 int err = fh_verify(rqstp, fhp, 0, MAY_NOP); 1775 __be32 err = fh_verify(rqstp, fhp, 0, MAY_NOP);
1743 if (!err && vfs_statfs(fhp->fh_dentry,stat)) 1776 if (!err && vfs_statfs(fhp->fh_dentry,stat))
1744 err = nfserr_io; 1777 err = nfserr_io;
1745 return err; 1778 return err;
@@ -1748,7 +1781,7 @@ nfsd_statfs(struct svc_rqst *rqstp, struct svc_fh *fhp, struct kstatfs *stat)
1748/* 1781/*
1749 * Check for a user's access permissions to this inode. 1782 * Check for a user's access permissions to this inode.
1750 */ 1783 */
1751int 1784__be32
1752nfsd_permission(struct svc_export *exp, struct dentry *dentry, int acc) 1785nfsd_permission(struct svc_export *exp, struct dentry *dentry, int acc)
1753{ 1786{
1754 struct inode *inode = dentry->d_inode; 1787 struct inode *inode = dentry->d_inode;
@@ -1829,11 +1862,11 @@ nfsd_permission(struct svc_export *exp, struct dentry *dentry, int acc)
1829void 1862void
1830nfsd_racache_shutdown(void) 1863nfsd_racache_shutdown(void)
1831{ 1864{
1832 if (!raparm_cache) 1865 if (!raparml)
1833 return; 1866 return;
1834 dprintk("nfsd: freeing readahead buffers.\n"); 1867 dprintk("nfsd: freeing readahead buffers.\n");
1835 kfree(raparml); 1868 kfree(raparml);
1836 raparm_cache = raparml = NULL; 1869 raparml = NULL;
1837} 1870}
1838/* 1871/*
1839 * Initialize readahead param cache 1872 * Initialize readahead param cache
@@ -1842,19 +1875,31 @@ int
1842nfsd_racache_init(int cache_size) 1875nfsd_racache_init(int cache_size)
1843{ 1876{
1844 int i; 1877 int i;
1878 int j = 0;
1879 int nperbucket;
1880
1845 1881
1846 if (raparm_cache) 1882 if (raparml)
1847 return 0; 1883 return 0;
1884 if (cache_size < 2*RAPARM_HASH_SIZE)
1885 cache_size = 2*RAPARM_HASH_SIZE;
1848 raparml = kmalloc(sizeof(struct raparms) * cache_size, GFP_KERNEL); 1886 raparml = kmalloc(sizeof(struct raparms) * cache_size, GFP_KERNEL);
1849 1887
1850 if (raparml != NULL) { 1888 if (raparml != NULL) {
1851 dprintk("nfsd: allocating %d readahead buffers.\n", 1889 dprintk("nfsd: allocating %d readahead buffers.\n",
1852 cache_size); 1890 cache_size);
1891 for (i = 0 ; i < RAPARM_HASH_SIZE ; i++) {
1892 raparm_hash[i].pb_head = NULL;
1893 spin_lock_init(&raparm_hash[i].pb_lock);
1894 }
1895 nperbucket = cache_size >> RAPARM_HASH_BITS;
1853 memset(raparml, 0, sizeof(struct raparms) * cache_size); 1896 memset(raparml, 0, sizeof(struct raparms) * cache_size);
1854 for (i = 0; i < cache_size - 1; i++) { 1897 for (i = 0; i < cache_size - 1; i++) {
1855 raparml[i].p_next = raparml + i + 1; 1898 if (i % nperbucket == 0)
1899 raparm_hash[j++].pb_head = raparml + i;
1900 if (i % nperbucket < nperbucket-1)
1901 raparml[i].p_next = raparml + i + 1;
1856 } 1902 }
1857 raparm_cache = raparml;
1858 } else { 1903 } else {
1859 printk(KERN_WARNING 1904 printk(KERN_WARNING
1860 "nfsd: Could not allocate memory read-ahead cache.\n"); 1905 "nfsd: Could not allocate memory read-ahead cache.\n");