aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfsd/vfs.c299
-rw-r--r--include/linux/nfsd/nfsd.h38
2 files changed, 176 insertions, 161 deletions
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 1141bd29e4e3..f21e917bb8ed 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -110,7 +110,7 @@ nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry **dpp,
110 struct dentry *dentry = *dpp; 110 struct dentry *dentry = *dpp;
111 struct vfsmount *mnt = mntget(exp->ex_mnt); 111 struct vfsmount *mnt = mntget(exp->ex_mnt);
112 struct dentry *mounts = dget(dentry); 112 struct dentry *mounts = dget(dentry);
113 int err = nfs_ok; 113 int err = 0;
114 114
115 while (follow_down(&mnt,&mounts)&&d_mountpoint(mounts)); 115 while (follow_down(&mnt,&mounts)&&d_mountpoint(mounts));
116 116
@@ -148,14 +148,15 @@ out:
148 * clients and is explicitly disallowed for NFSv3 148 * clients and is explicitly disallowed for NFSv3
149 * NeilBrown <neilb@cse.unsw.edu.au> 149 * NeilBrown <neilb@cse.unsw.edu.au>
150 */ 150 */
151int 151__be32
152nfsd_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,
153 int len, struct svc_fh *resfh) 153 int len, struct svc_fh *resfh)
154{ 154{
155 struct svc_export *exp; 155 struct svc_export *exp;
156 struct dentry *dparent; 156 struct dentry *dparent;
157 struct dentry *dentry; 157 struct dentry *dentry;
158 int err; 158 __be32 err;
159 int host_err;
159 160
160 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);
161 162
@@ -193,7 +194,7 @@ nfsd_lookup(struct svc_rqst *rqstp, struct svc_fh *fhp, const char *name,
193 exp2 = exp_parent(exp->ex_client, mnt, dentry, 194 exp2 = exp_parent(exp->ex_client, mnt, dentry,
194 &rqstp->rq_chandle); 195 &rqstp->rq_chandle);
195 if (IS_ERR(exp2)) { 196 if (IS_ERR(exp2)) {
196 err = PTR_ERR(exp2); 197 host_err = PTR_ERR(exp2);
197 dput(dentry); 198 dput(dentry);
198 mntput(mnt); 199 mntput(mnt);
199 goto out_nfserr; 200 goto out_nfserr;
@@ -210,14 +211,14 @@ nfsd_lookup(struct svc_rqst *rqstp, struct svc_fh *fhp, const char *name,
210 } else { 211 } else {
211 fh_lock(fhp); 212 fh_lock(fhp);
212 dentry = lookup_one_len(name, dparent, len); 213 dentry = lookup_one_len(name, dparent, len);
213 err = PTR_ERR(dentry); 214 host_err = PTR_ERR(dentry);
214 if (IS_ERR(dentry)) 215 if (IS_ERR(dentry))
215 goto out_nfserr; 216 goto out_nfserr;
216 /* 217 /*
217 * check if we have crossed a mount point ... 218 * check if we have crossed a mount point ...
218 */ 219 */
219 if (d_mountpoint(dentry)) { 220 if (d_mountpoint(dentry)) {
220 if ((err = nfsd_cross_mnt(rqstp, &dentry, &exp))) { 221 if ((host_err = nfsd_cross_mnt(rqstp, &dentry, &exp))) {
221 dput(dentry); 222 dput(dentry);
222 goto out_nfserr; 223 goto out_nfserr;
223 } 224 }
@@ -236,7 +237,7 @@ out:
236 return err; 237 return err;
237 238
238out_nfserr: 239out_nfserr:
239 err = nfserrno(err); 240 err = nfserrno(host_err);
240 goto out; 241 goto out;
241} 242}
242 243
@@ -244,7 +245,7 @@ out_nfserr:
244 * Set various file attributes. 245 * Set various file attributes.
245 * N.B. After this call fhp needs an fh_put 246 * N.B. After this call fhp needs an fh_put
246 */ 247 */
247int 248__be32
248nfsd_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,
249 int check_guard, time_t guardtime) 250 int check_guard, time_t guardtime)
250{ 251{
@@ -253,7 +254,8 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
253 int accmode = MAY_SATTR; 254 int accmode = MAY_SATTR;
254 int ftype = 0; 255 int ftype = 0;
255 int imode; 256 int imode;
256 int err; 257 __be32 err;
258 int host_err;
257 int size_change = 0; 259 int size_change = 0;
258 260
259 if (iap->ia_valid & (ATTR_ATIME | ATTR_MTIME | ATTR_SIZE)) 261 if (iap->ia_valid & (ATTR_ATIME | ATTR_MTIME | ATTR_SIZE))
@@ -319,19 +321,19 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
319 * If we are changing the size of the file, then 321 * If we are changing the size of the file, then
320 * we need to break all leases. 322 * we need to break all leases.
321 */ 323 */
322 err = break_lease(inode, FMODE_WRITE | O_NONBLOCK); 324 host_err = break_lease(inode, FMODE_WRITE | O_NONBLOCK);
323 if (err == -EWOULDBLOCK) 325 if (host_err == -EWOULDBLOCK)
324 err = -ETIMEDOUT; 326 host_err = -ETIMEDOUT;
325 if (err) /* ENOMEM or EWOULDBLOCK */ 327 if (host_err) /* ENOMEM or EWOULDBLOCK */
326 goto out_nfserr; 328 goto out_nfserr;
327 329
328 err = get_write_access(inode); 330 host_err = get_write_access(inode);
329 if (err) 331 if (host_err)
330 goto out_nfserr; 332 goto out_nfserr;
331 333
332 size_change = 1; 334 size_change = 1;
333 err = locks_verify_truncate(inode, NULL, iap->ia_size); 335 host_err = locks_verify_truncate(inode, NULL, iap->ia_size);
334 if (err) { 336 if (host_err) {
335 put_write_access(inode); 337 put_write_access(inode);
336 goto out_nfserr; 338 goto out_nfserr;
337 } 339 }
@@ -357,8 +359,8 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
357 err = nfserr_notsync; 359 err = nfserr_notsync;
358 if (!check_guard || guardtime == inode->i_ctime.tv_sec) { 360 if (!check_guard || guardtime == inode->i_ctime.tv_sec) {
359 fh_lock(fhp); 361 fh_lock(fhp);
360 err = notify_change(dentry, iap); 362 host_err = notify_change(dentry, iap);
361 err = nfserrno(err); 363 err = nfserrno(host_err);
362 fh_unlock(fhp); 364 fh_unlock(fhp);
363 } 365 }
364 if (size_change) 366 if (size_change)
@@ -370,7 +372,7 @@ out:
370 return err; 372 return err;
371 373
372out_nfserr: 374out_nfserr:
373 err = nfserrno(err); 375 err = nfserrno(host_err);
374 goto out; 376 goto out;
375} 377}
376 378
@@ -420,11 +422,12 @@ out:
420 return error; 422 return error;
421} 423}
422 424
423int 425__be32
424nfsd4_set_nfs4_acl(struct svc_rqst *rqstp, struct svc_fh *fhp, 426nfsd4_set_nfs4_acl(struct svc_rqst *rqstp, struct svc_fh *fhp,
425 struct nfs4_acl *acl) 427 struct nfs4_acl *acl)
426{ 428{
427 int error; 429 __be32 error;
430 int host_error;
428 struct dentry *dentry; 431 struct dentry *dentry;
429 struct inode *inode; 432 struct inode *inode;
430 struct posix_acl *pacl = NULL, *dpacl = NULL; 433 struct posix_acl *pacl = NULL, *dpacl = NULL;
@@ -440,20 +443,20 @@ nfsd4_set_nfs4_acl(struct svc_rqst *rqstp, struct svc_fh *fhp,
440 if (S_ISDIR(inode->i_mode)) 443 if (S_ISDIR(inode->i_mode))
441 flags = NFS4_ACL_DIR; 444 flags = NFS4_ACL_DIR;
442 445
443 error = nfs4_acl_nfsv4_to_posix(acl, &pacl, &dpacl, flags); 446 host_error = nfs4_acl_nfsv4_to_posix(acl, &pacl, &dpacl, flags);
444 if (error == -EINVAL) { 447 if (host_error == -EINVAL) {
445 error = nfserr_attrnotsupp; 448 error = nfserr_attrnotsupp;
446 goto out; 449 goto out;
447 } else if (error < 0) 450 } else if (host_error < 0)
448 goto out_nfserr; 451 goto out_nfserr;
449 452
450 error = set_nfsv4_acl_one(dentry, pacl, POSIX_ACL_XATTR_ACCESS); 453 host_error = set_nfsv4_acl_one(dentry, pacl, POSIX_ACL_XATTR_ACCESS);
451 if (error < 0) 454 if (host_error < 0)
452 goto out_nfserr; 455 goto out_nfserr;
453 456
454 if (S_ISDIR(inode->i_mode)) { 457 if (S_ISDIR(inode->i_mode)) {
455 error = set_nfsv4_acl_one(dentry, dpacl, POSIX_ACL_XATTR_DEFAULT); 458 host_error = set_nfsv4_acl_one(dentry, dpacl, POSIX_ACL_XATTR_DEFAULT);
456 if (error < 0) 459 if (host_error < 0)
457 goto out_nfserr; 460 goto out_nfserr;
458 } 461 }
459 462
@@ -464,7 +467,7 @@ out:
464 posix_acl_release(dpacl); 467 posix_acl_release(dpacl);
465 return (error); 468 return (error);
466out_nfserr: 469out_nfserr:
467 error = nfserrno(error); 470 error = nfserrno(host_error);
468 goto out; 471 goto out;
469} 472}
470 473
@@ -571,14 +574,14 @@ static struct accessmap nfs3_anyaccess[] = {
571 { 0, 0 } 574 { 0, 0 }
572}; 575};
573 576
574int 577__be32
575nfsd_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)
576{ 579{
577 struct accessmap *map; 580 struct accessmap *map;
578 struct svc_export *export; 581 struct svc_export *export;
579 struct dentry *dentry; 582 struct dentry *dentry;
580 u32 query, result = 0, sresult = 0; 583 u32 query, result = 0, sresult = 0;
581 unsigned int error; 584 __be32 error;
582 585
583 error = fh_verify(rqstp, fhp, 0, MAY_NOP); 586 error = fh_verify(rqstp, fhp, 0, MAY_NOP);
584 if (error) 587 if (error)
@@ -598,7 +601,7 @@ nfsd_access(struct svc_rqst *rqstp, struct svc_fh *fhp, u32 *access, u32 *suppor
598 query = *access; 601 query = *access;
599 for (; map->access; map++) { 602 for (; map->access; map++) {
600 if (map->access & query) { 603 if (map->access & query) {
601 unsigned int err2; 604 __be32 err2;
602 605
603 sresult |= map->access; 606 sresult |= map->access;
604 607
@@ -637,13 +640,15 @@ nfsd_access(struct svc_rqst *rqstp, struct svc_fh *fhp, u32 *access, u32 *suppor
637 * The access argument indicates the type of open (read/write/lock) 640 * The access argument indicates the type of open (read/write/lock)
638 * N.B. After this call fhp needs an fh_put 641 * N.B. After this call fhp needs an fh_put
639 */ 642 */
640int 643__be32
641nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, 644nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
642 int access, struct file **filp) 645 int access, struct file **filp)
643{ 646{
644 struct dentry *dentry; 647 struct dentry *dentry;
645 struct inode *inode; 648 struct inode *inode;
646 int flags = O_RDONLY|O_LARGEFILE, err; 649 int flags = O_RDONLY|O_LARGEFILE;
650 __be32 err;
651 int host_err;
647 652
648 /* 653 /*
649 * 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",
@@ -673,10 +678,10 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
673 * Check to see if there are any leases on this file. 678 * Check to see if there are any leases on this file.
674 * This may block while leases are broken. 679 * This may block while leases are broken.
675 */ 680 */
676 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));
677 if (err == -EWOULDBLOCK) 682 if (host_err == -EWOULDBLOCK)
678 err = -ETIMEDOUT; 683 host_err = -ETIMEDOUT;
679 if (err) /* NOMEM or WOULDBLOCK */ 684 if (host_err) /* NOMEM or WOULDBLOCK */
680 goto out_nfserr; 685 goto out_nfserr;
681 686
682 if (access & MAY_WRITE) { 687 if (access & MAY_WRITE) {
@@ -689,10 +694,9 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
689 } 694 }
690 *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);
691 if (IS_ERR(*filp)) 696 if (IS_ERR(*filp))
692 err = PTR_ERR(*filp); 697 host_err = PTR_ERR(*filp);
693out_nfserr: 698out_nfserr:
694 if (err) 699 err = nfserrno(host_err);
695 err = nfserrno(err);
696out: 700out:
697 return err; 701 return err;
698} 702}
@@ -830,14 +834,15 @@ nfsd_read_actor(read_descriptor_t *desc, struct page *page, unsigned long offset
830 return size; 834 return size;
831} 835}
832 836
833static int 837static __be32
834nfsd_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,
835 loff_t offset, struct kvec *vec, int vlen, unsigned long *count) 839 loff_t offset, struct kvec *vec, int vlen, unsigned long *count)
836{ 840{
837 struct inode *inode; 841 struct inode *inode;
838 struct raparms *ra; 842 struct raparms *ra;
839 mm_segment_t oldfs; 843 mm_segment_t oldfs;
840 int err; 844 __be32 err;
845 int host_err;
841 846
842 err = nfserr_perm; 847 err = nfserr_perm;
843 inode = file->f_dentry->d_inode; 848 inode = file->f_dentry->d_inode;
@@ -855,12 +860,12 @@ nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
855 860
856 if (file->f_op->sendfile && rqstp->rq_sendfile_ok) { 861 if (file->f_op->sendfile && rqstp->rq_sendfile_ok) {
857 rqstp->rq_resused = 1; 862 rqstp->rq_resused = 1;
858 err = file->f_op->sendfile(file, &offset, *count, 863 host_err = file->f_op->sendfile(file, &offset, *count,
859 nfsd_read_actor, rqstp); 864 nfsd_read_actor, rqstp);
860 } else { 865 } else {
861 oldfs = get_fs(); 866 oldfs = get_fs();
862 set_fs(KERNEL_DS); 867 set_fs(KERNEL_DS);
863 err = vfs_readv(file, (struct iovec __user *)vec, vlen, &offset); 868 host_err = vfs_readv(file, (struct iovec __user *)vec, vlen, &offset);
864 set_fs(oldfs); 869 set_fs(oldfs);
865 } 870 }
866 871
@@ -874,13 +879,13 @@ nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
874 spin_unlock(&rab->pb_lock); 879 spin_unlock(&rab->pb_lock);
875 } 880 }
876 881
877 if (err >= 0) { 882 if (host_err >= 0) {
878 nfsdstats.io_read += err; 883 nfsdstats.io_read += host_err;
879 *count = err; 884 *count = host_err;
880 err = 0; 885 err = 0;
881 fsnotify_access(file->f_dentry); 886 fsnotify_access(file->f_dentry);
882 } else 887 } else
883 err = nfserrno(err); 888 err = nfserrno(host_err);
884out: 889out:
885 return err; 890 return err;
886} 891}
@@ -895,7 +900,7 @@ static void kill_suid(struct dentry *dentry)
895 mutex_unlock(&dentry->d_inode->i_mutex); 900 mutex_unlock(&dentry->d_inode->i_mutex);
896} 901}
897 902
898static int 903static __be32
899nfsd_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,
900 loff_t offset, struct kvec *vec, int vlen, 905 loff_t offset, struct kvec *vec, int vlen,
901 unsigned long cnt, int *stablep) 906 unsigned long cnt, int *stablep)
@@ -904,7 +909,8 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
904 struct dentry *dentry; 909 struct dentry *dentry;
905 struct inode *inode; 910 struct inode *inode;
906 mm_segment_t oldfs; 911 mm_segment_t oldfs;
907 int err = 0; 912 __be32 err = 0;
913 int host_err;
908 int stable = *stablep; 914 int stable = *stablep;
909 915
910#ifdef MSNFS 916#ifdef MSNFS
@@ -940,18 +946,18 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
940 946
941 /* Write the data. */ 947 /* Write the data. */
942 oldfs = get_fs(); set_fs(KERNEL_DS); 948 oldfs = get_fs(); set_fs(KERNEL_DS);
943 err = vfs_writev(file, (struct iovec __user *)vec, vlen, &offset); 949 host_err = vfs_writev(file, (struct iovec __user *)vec, vlen, &offset);
944 set_fs(oldfs); 950 set_fs(oldfs);
945 if (err >= 0) { 951 if (host_err >= 0) {
946 nfsdstats.io_write += cnt; 952 nfsdstats.io_write += cnt;
947 fsnotify_modify(file->f_dentry); 953 fsnotify_modify(file->f_dentry);
948 } 954 }
949 955
950 /* clear setuid/setgid flag after write */ 956 /* clear setuid/setgid flag after write */
951 if (err >= 0 && (inode->i_mode & (S_ISUID | S_ISGID))) 957 if (host_err >= 0 && (inode->i_mode & (S_ISUID | S_ISGID)))
952 kill_suid(dentry); 958 kill_suid(dentry);
953 959
954 if (err >= 0 && stable) { 960 if (host_err >= 0 && stable) {
955 static ino_t last_ino; 961 static ino_t last_ino;
956 static dev_t last_dev; 962 static dev_t last_dev;
957 963
@@ -977,7 +983,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
977 983
978 if (inode->i_state & I_DIRTY) { 984 if (inode->i_state & I_DIRTY) {
979 dprintk("nfsd: write sync %d\n", current->pid); 985 dprintk("nfsd: write sync %d\n", current->pid);
980 err=nfsd_sync(file); 986 host_err=nfsd_sync(file);
981 } 987 }
982#if 0 988#if 0
983 wake_up(&inode->i_wait); 989 wake_up(&inode->i_wait);
@@ -987,11 +993,11 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
987 last_dev = inode->i_sb->s_dev; 993 last_dev = inode->i_sb->s_dev;
988 } 994 }
989 995
990 dprintk("nfsd: write complete err=%d\n", err); 996 dprintk("nfsd: write complete host_err=%d\n", host_err);
991 if (err >= 0) 997 if (host_err >= 0)
992 err = 0; 998 err = 0;
993 else 999 else
994 err = nfserrno(err); 1000 err = nfserrno(host_err);
995out: 1001out:
996 return err; 1002 return err;
997} 1003}
@@ -1001,12 +1007,12 @@ out:
1001 * 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.
1002 * N.B. After this call fhp needs an fh_put 1008 * N.B. After this call fhp needs an fh_put
1003 */ 1009 */
1004int 1010__be32
1005nfsd_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,
1006 loff_t offset, struct kvec *vec, int vlen, 1012 loff_t offset, struct kvec *vec, int vlen,
1007 unsigned long *count) 1013 unsigned long *count)
1008{ 1014{
1009 int err; 1015 __be32 err;
1010 1016
1011 if (file) { 1017 if (file) {
1012 err = nfsd_permission(fhp->fh_export, fhp->fh_dentry, 1018 err = nfsd_permission(fhp->fh_export, fhp->fh_dentry,
@@ -1030,12 +1036,12 @@ out:
1030 * The stable flag requests synchronous writes. 1036 * The stable flag requests synchronous writes.
1031 * N.B. After this call fhp needs an fh_put 1037 * N.B. After this call fhp needs an fh_put
1032 */ 1038 */
1033int 1039__be32
1034nfsd_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,
1035 loff_t offset, struct kvec *vec, int vlen, unsigned long cnt, 1041 loff_t offset, struct kvec *vec, int vlen, unsigned long cnt,
1036 int *stablep) 1042 int *stablep)
1037{ 1043{
1038 int err = 0; 1044 __be32 err = 0;
1039 1045
1040 if (file) { 1046 if (file) {
1041 err = nfsd_permission(fhp->fh_export, fhp->fh_dentry, 1047 err = nfsd_permission(fhp->fh_export, fhp->fh_dentry,
@@ -1067,12 +1073,12 @@ out:
1067 * 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
1068 * 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.
1069 */ 1075 */
1070int 1076__be32
1071nfsd_commit(struct svc_rqst *rqstp, struct svc_fh *fhp, 1077nfsd_commit(struct svc_rqst *rqstp, struct svc_fh *fhp,
1072 loff_t offset, unsigned long count) 1078 loff_t offset, unsigned long count)
1073{ 1079{
1074 struct file *file; 1080 struct file *file;
1075 int err; 1081 __be32 err;
1076 1082
1077 if ((u64)count > ~(u64)offset) 1083 if ((u64)count > ~(u64)offset)
1078 return nfserr_inval; 1084 return nfserr_inval;
@@ -1100,14 +1106,15 @@ nfsd_commit(struct svc_rqst *rqstp, struct svc_fh *fhp,
1100 * 1106 *
1101 * 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
1102 */ 1108 */
1103int 1109__be32
1104nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp, 1110nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
1105 char *fname, int flen, struct iattr *iap, 1111 char *fname, int flen, struct iattr *iap,
1106 int type, dev_t rdev, struct svc_fh *resfhp) 1112 int type, dev_t rdev, struct svc_fh *resfhp)
1107{ 1113{
1108 struct dentry *dentry, *dchild = NULL; 1114 struct dentry *dentry, *dchild = NULL;
1109 struct inode *dirp; 1115 struct inode *dirp;
1110 int err; 1116 __be32 err;
1117 int host_err;
1111 1118
1112 err = nfserr_perm; 1119 err = nfserr_perm;
1113 if (!flen) 1120 if (!flen)
@@ -1134,7 +1141,7 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
1134 /* called from nfsd_proc_mkdir, or possibly nfsd3_proc_create */ 1141 /* called from nfsd_proc_mkdir, or possibly nfsd3_proc_create */
1135 fh_lock_nested(fhp, I_MUTEX_PARENT); 1142 fh_lock_nested(fhp, I_MUTEX_PARENT);
1136 dchild = lookup_one_len(fname, dentry, flen); 1143 dchild = lookup_one_len(fname, dentry, flen);
1137 err = PTR_ERR(dchild); 1144 host_err = PTR_ERR(dchild);
1138 if (IS_ERR(dchild)) 1145 if (IS_ERR(dchild))
1139 goto out_nfserr; 1146 goto out_nfserr;
1140 err = fh_compose(resfhp, fhp->fh_export, dchild, fhp); 1147 err = fh_compose(resfhp, fhp->fh_export, dchild, fhp);
@@ -1173,22 +1180,22 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
1173 err = nfserr_perm; 1180 err = nfserr_perm;
1174 switch (type) { 1181 switch (type) {
1175 case S_IFREG: 1182 case S_IFREG:
1176 err = vfs_create(dirp, dchild, iap->ia_mode, NULL); 1183 host_err = vfs_create(dirp, dchild, iap->ia_mode, NULL);
1177 break; 1184 break;
1178 case S_IFDIR: 1185 case S_IFDIR:
1179 err = vfs_mkdir(dirp, dchild, iap->ia_mode); 1186 host_err = vfs_mkdir(dirp, dchild, iap->ia_mode);
1180 break; 1187 break;
1181 case S_IFCHR: 1188 case S_IFCHR:
1182 case S_IFBLK: 1189 case S_IFBLK:
1183 case S_IFIFO: 1190 case S_IFIFO:
1184 case S_IFSOCK: 1191 case S_IFSOCK:
1185 err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev); 1192 host_err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev);
1186 break; 1193 break;
1187 default: 1194 default:
1188 printk("nfsd: bad file type %o in nfsd_create\n", type); 1195 printk("nfsd: bad file type %o in nfsd_create\n", type);
1189 err = -EINVAL; 1196 host_err = -EINVAL;
1190 } 1197 }
1191 if (err < 0) 1198 if (host_err < 0)
1192 goto out_nfserr; 1199 goto out_nfserr;
1193 1200
1194 if (EX_ISSYNC(fhp->fh_export)) { 1201 if (EX_ISSYNC(fhp->fh_export)) {
@@ -1203,7 +1210,7 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
1203 * directories via NFS. 1210 * directories via NFS.
1204 */ 1211 */
1205 if ((iap->ia_valid &= ~(ATTR_UID|ATTR_GID|ATTR_MODE)) != 0) { 1212 if ((iap->ia_valid &= ~(ATTR_UID|ATTR_GID|ATTR_MODE)) != 0) {
1206 int err2 = nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0); 1213 __be32 err2 = nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0);
1207 if (err2) 1214 if (err2)
1208 err = err2; 1215 err = err2;
1209 } 1216 }
@@ -1218,7 +1225,7 @@ out:
1218 return err; 1225 return err;
1219 1226
1220out_nfserr: 1227out_nfserr:
1221 err = nfserrno(err); 1228 err = nfserrno(host_err);
1222 goto out; 1229 goto out;
1223} 1230}
1224 1231
@@ -1226,7 +1233,7 @@ out_nfserr:
1226/* 1233/*
1227 * NFSv3 version of nfsd_create 1234 * NFSv3 version of nfsd_create
1228 */ 1235 */
1229int 1236__be32
1230nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp, 1237nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
1231 char *fname, int flen, struct iattr *iap, 1238 char *fname, int flen, struct iattr *iap,
1232 struct svc_fh *resfhp, int createmode, u32 *verifier, 1239 struct svc_fh *resfhp, int createmode, u32 *verifier,
@@ -1234,7 +1241,8 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
1234{ 1241{
1235 struct dentry *dentry, *dchild = NULL; 1242 struct dentry *dentry, *dchild = NULL;
1236 struct inode *dirp; 1243 struct inode *dirp;
1237 int err; 1244 __be32 err;
1245 int host_err;
1238 __u32 v_mtime=0, v_atime=0; 1246 __u32 v_mtime=0, v_atime=0;
1239 int v_mode=0; 1247 int v_mode=0;
1240 1248
@@ -1264,7 +1272,7 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
1264 * Compose the response file handle. 1272 * Compose the response file handle.
1265 */ 1273 */
1266 dchild = lookup_one_len(fname, dentry, flen); 1274 dchild = lookup_one_len(fname, dentry, flen);
1267 err = PTR_ERR(dchild); 1275 host_err = PTR_ERR(dchild);
1268 if (IS_ERR(dchild)) 1276 if (IS_ERR(dchild))
1269 goto out_nfserr; 1277 goto out_nfserr;
1270 1278
@@ -1320,8 +1328,8 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
1320 goto out; 1328 goto out;
1321 } 1329 }
1322 1330
1323 err = vfs_create(dirp, dchild, iap->ia_mode, NULL); 1331 host_err = vfs_create(dirp, dchild, iap->ia_mode, NULL);
1324 if (err < 0) 1332 if (host_err < 0)
1325 goto out_nfserr; 1333 goto out_nfserr;
1326 1334
1327 if (EX_ISSYNC(fhp->fh_export)) { 1335 if (EX_ISSYNC(fhp->fh_export)) {
@@ -1350,7 +1358,7 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
1350 */ 1358 */
1351 set_attr: 1359 set_attr:
1352 if ((iap->ia_valid &= ~(ATTR_UID|ATTR_GID)) != 0) { 1360 if ((iap->ia_valid &= ~(ATTR_UID|ATTR_GID)) != 0) {
1353 int err2 = nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0); 1361 __be32 err2 = nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0);
1354 if (err2) 1362 if (err2)
1355 err = err2; 1363 err = err2;
1356 } 1364 }
@@ -1368,7 +1376,7 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
1368 return err; 1376 return err;
1369 1377
1370 out_nfserr: 1378 out_nfserr:
1371 err = nfserrno(err); 1379 err = nfserrno(host_err);
1372 goto out; 1380 goto out;
1373} 1381}
1374#endif /* CONFIG_NFSD_V3 */ 1382#endif /* CONFIG_NFSD_V3 */
@@ -1378,13 +1386,14 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
1378 * fits into the buffer. On return, it contains the true length. 1386 * fits into the buffer. On return, it contains the true length.
1379 * N.B. After this call fhp needs an fh_put 1387 * N.B. After this call fhp needs an fh_put
1380 */ 1388 */
1381int 1389__be32
1382nfsd_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)
1383{ 1391{
1384 struct dentry *dentry; 1392 struct dentry *dentry;
1385 struct inode *inode; 1393 struct inode *inode;
1386 mm_segment_t oldfs; 1394 mm_segment_t oldfs;
1387 int err; 1395 __be32 err;
1396 int host_err;
1388 1397
1389 err = fh_verify(rqstp, fhp, S_IFLNK, MAY_NOP); 1398 err = fh_verify(rqstp, fhp, S_IFLNK, MAY_NOP);
1390 if (err) 1399 if (err)
@@ -1403,18 +1412,18 @@ nfsd_readlink(struct svc_rqst *rqstp, struct svc_fh *fhp, char *buf, int *lenp)
1403 */ 1412 */
1404 1413
1405 oldfs = get_fs(); set_fs(KERNEL_DS); 1414 oldfs = get_fs(); set_fs(KERNEL_DS);
1406 err = inode->i_op->readlink(dentry, buf, *lenp); 1415 host_err = inode->i_op->readlink(dentry, buf, *lenp);
1407 set_fs(oldfs); 1416 set_fs(oldfs);
1408 1417
1409 if (err < 0) 1418 if (host_err < 0)
1410 goto out_nfserr; 1419 goto out_nfserr;
1411 *lenp = err; 1420 *lenp = host_err;
1412 err = 0; 1421 err = 0;
1413out: 1422out:
1414 return err; 1423 return err;
1415 1424
1416out_nfserr: 1425out_nfserr:
1417 err = nfserrno(err); 1426 err = nfserrno(host_err);
1418 goto out; 1427 goto out;
1419} 1428}
1420 1429
@@ -1422,7 +1431,7 @@ out_nfserr:
1422 * Create a symlink and look up its inode 1431 * Create a symlink and look up its inode
1423 * 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
1424 */ 1433 */
1425int 1434__be32
1426nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp, 1435nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp,
1427 char *fname, int flen, 1436 char *fname, int flen,
1428 char *path, int plen, 1437 char *path, int plen,
@@ -1430,7 +1439,8 @@ nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp,
1430 struct iattr *iap) 1439 struct iattr *iap)
1431{ 1440{
1432 struct dentry *dentry, *dnew; 1441 struct dentry *dentry, *dnew;
1433 int err, cerr; 1442 __be32 err, cerr;
1443 int host_err;
1434 umode_t mode; 1444 umode_t mode;
1435 1445
1436 err = nfserr_noent; 1446 err = nfserr_noent;
@@ -1446,7 +1456,7 @@ nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp,
1446 fh_lock(fhp); 1456 fh_lock(fhp);
1447 dentry = fhp->fh_dentry; 1457 dentry = fhp->fh_dentry;
1448 dnew = lookup_one_len(fname, dentry, flen); 1458 dnew = lookup_one_len(fname, dentry, flen);
1449 err = PTR_ERR(dnew); 1459 host_err = PTR_ERR(dnew);
1450 if (IS_ERR(dnew)) 1460 if (IS_ERR(dnew))
1451 goto out_nfserr; 1461 goto out_nfserr;
1452 1462
@@ -1458,21 +1468,21 @@ nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp,
1458 if (unlikely(path[plen] != 0)) { 1468 if (unlikely(path[plen] != 0)) {
1459 char *path_alloced = kmalloc(plen+1, GFP_KERNEL); 1469 char *path_alloced = kmalloc(plen+1, GFP_KERNEL);
1460 if (path_alloced == NULL) 1470 if (path_alloced == NULL)
1461 err = -ENOMEM; 1471 host_err = -ENOMEM;
1462 else { 1472 else {
1463 strncpy(path_alloced, path, plen); 1473 strncpy(path_alloced, path, plen);
1464 path_alloced[plen] = 0; 1474 path_alloced[plen] = 0;
1465 err = vfs_symlink(dentry->d_inode, dnew, path_alloced, mode); 1475 host_err = vfs_symlink(dentry->d_inode, dnew, path_alloced, mode);
1466 kfree(path_alloced); 1476 kfree(path_alloced);
1467 } 1477 }
1468 } else 1478 } else
1469 err = vfs_symlink(dentry->d_inode, dnew, path, mode); 1479 host_err = vfs_symlink(dentry->d_inode, dnew, path, mode);
1470 1480
1471 if (!err) 1481 if (!host_err) {
1472 if (EX_ISSYNC(fhp->fh_export)) 1482 if (EX_ISSYNC(fhp->fh_export))
1473 err = nfsd_sync_dir(dentry); 1483 host_err = nfsd_sync_dir(dentry);
1474 if (err) 1484 }
1475 err = nfserrno(err); 1485 err = nfserrno(host_err);
1476 fh_unlock(fhp); 1486 fh_unlock(fhp);
1477 1487
1478 cerr = fh_compose(resfhp, fhp->fh_export, dnew, fhp); 1488 cerr = fh_compose(resfhp, fhp->fh_export, dnew, fhp);
@@ -1482,7 +1492,7 @@ out:
1482 return err; 1492 return err;
1483 1493
1484out_nfserr: 1494out_nfserr:
1485 err = nfserrno(err); 1495 err = nfserrno(host_err);
1486 goto out; 1496 goto out;
1487} 1497}
1488 1498
@@ -1490,13 +1500,14 @@ out_nfserr:
1490 * Create a hardlink 1500 * Create a hardlink
1491 * 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
1492 */ 1502 */
1493int 1503__be32
1494nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp, 1504nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp,
1495 char *name, int len, struct svc_fh *tfhp) 1505 char *name, int len, struct svc_fh *tfhp)
1496{ 1506{
1497 struct dentry *ddir, *dnew, *dold; 1507 struct dentry *ddir, *dnew, *dold;
1498 struct inode *dirp, *dest; 1508 struct inode *dirp, *dest;
1499 int err; 1509 __be32 err;
1510 int host_err;
1500 1511
1501 err = fh_verify(rqstp, ffhp, S_IFDIR, MAY_CREATE); 1512 err = fh_verify(rqstp, ffhp, S_IFDIR, MAY_CREATE);
1502 if (err) 1513 if (err)
@@ -1517,24 +1528,25 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp,
1517 dirp = ddir->d_inode; 1528 dirp = ddir->d_inode;
1518 1529
1519 dnew = lookup_one_len(name, ddir, len); 1530 dnew = lookup_one_len(name, ddir, len);
1520 err = PTR_ERR(dnew); 1531 host_err = PTR_ERR(dnew);
1521 if (IS_ERR(dnew)) 1532 if (IS_ERR(dnew))
1522 goto out_nfserr; 1533 goto out_nfserr;
1523 1534
1524 dold = tfhp->fh_dentry; 1535 dold = tfhp->fh_dentry;
1525 dest = dold->d_inode; 1536 dest = dold->d_inode;
1526 1537
1527 err = vfs_link(dold, dirp, dnew); 1538 host_err = vfs_link(dold, dirp, dnew);
1528 if (!err) { 1539 if (!host_err) {
1529 if (EX_ISSYNC(ffhp->fh_export)) { 1540 if (EX_ISSYNC(ffhp->fh_export)) {
1530 err = nfserrno(nfsd_sync_dir(ddir)); 1541 err = nfserrno(nfsd_sync_dir(ddir));
1531 write_inode_now(dest, 1); 1542 write_inode_now(dest, 1);
1532 } 1543 }
1544 err = 0;
1533 } else { 1545 } else {
1534 if (err == -EXDEV && rqstp->rq_vers == 2) 1546 if (host_err == -EXDEV && rqstp->rq_vers == 2)
1535 err = nfserr_acces; 1547 err = nfserr_acces;
1536 else 1548 else
1537 err = nfserrno(err); 1549 err = nfserrno(host_err);
1538 } 1550 }
1539 1551
1540 dput(dnew); 1552 dput(dnew);
@@ -1544,7 +1556,7 @@ out:
1544 return err; 1556 return err;
1545 1557
1546out_nfserr: 1558out_nfserr:
1547 err = nfserrno(err); 1559 err = nfserrno(host_err);
1548 goto out_unlock; 1560 goto out_unlock;
1549} 1561}
1550 1562
@@ -1552,13 +1564,14 @@ out_nfserr:
1552 * Rename a file 1564 * Rename a file
1553 * 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
1554 */ 1566 */
1555int 1567__be32
1556nfsd_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,
1557 struct svc_fh *tfhp, char *tname, int tlen) 1569 struct svc_fh *tfhp, char *tname, int tlen)
1558{ 1570{
1559 struct dentry *fdentry, *tdentry, *odentry, *ndentry, *trap; 1571 struct dentry *fdentry, *tdentry, *odentry, *ndentry, *trap;
1560 struct inode *fdir, *tdir; 1572 struct inode *fdir, *tdir;
1561 int err; 1573 __be32 err;
1574 int host_err;
1562 1575
1563 err = fh_verify(rqstp, ffhp, S_IFDIR, MAY_REMOVE); 1576 err = fh_verify(rqstp, ffhp, S_IFDIR, MAY_REMOVE);
1564 if (err) 1577 if (err)
@@ -1589,22 +1602,22 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen,
1589 fill_pre_wcc(tfhp); 1602 fill_pre_wcc(tfhp);
1590 1603
1591 odentry = lookup_one_len(fname, fdentry, flen); 1604 odentry = lookup_one_len(fname, fdentry, flen);
1592 err = PTR_ERR(odentry); 1605 host_err = PTR_ERR(odentry);
1593 if (IS_ERR(odentry)) 1606 if (IS_ERR(odentry))
1594 goto out_nfserr; 1607 goto out_nfserr;
1595 1608
1596 err = -ENOENT; 1609 host_err = -ENOENT;
1597 if (!odentry->d_inode) 1610 if (!odentry->d_inode)
1598 goto out_dput_old; 1611 goto out_dput_old;
1599 err = -EINVAL; 1612 host_err = -EINVAL;
1600 if (odentry == trap) 1613 if (odentry == trap)
1601 goto out_dput_old; 1614 goto out_dput_old;
1602 1615
1603 ndentry = lookup_one_len(tname, tdentry, tlen); 1616 ndentry = lookup_one_len(tname, tdentry, tlen);
1604 err = PTR_ERR(ndentry); 1617 host_err = PTR_ERR(ndentry);
1605 if (IS_ERR(ndentry)) 1618 if (IS_ERR(ndentry))
1606 goto out_dput_old; 1619 goto out_dput_old;
1607 err = -ENOTEMPTY; 1620 host_err = -ENOTEMPTY;
1608 if (ndentry == trap) 1621 if (ndentry == trap)
1609 goto out_dput_new; 1622 goto out_dput_new;
1610 1623
@@ -1612,14 +1625,14 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen,
1612 if ((ffhp->fh_export->ex_flags & NFSEXP_MSNFS) && 1625 if ((ffhp->fh_export->ex_flags & NFSEXP_MSNFS) &&
1613 ((atomic_read(&odentry->d_count) > 1) 1626 ((atomic_read(&odentry->d_count) > 1)
1614 || (atomic_read(&ndentry->d_count) > 1))) { 1627 || (atomic_read(&ndentry->d_count) > 1))) {
1615 err = -EPERM; 1628 host_err = -EPERM;
1616 } else 1629 } else
1617#endif 1630#endif
1618 err = vfs_rename(fdir, odentry, tdir, ndentry); 1631 host_err = vfs_rename(fdir, odentry, tdir, ndentry);
1619 if (!err && EX_ISSYNC(tfhp->fh_export)) { 1632 if (!host_err && EX_ISSYNC(tfhp->fh_export)) {
1620 err = nfsd_sync_dir(tdentry); 1633 host_err = nfsd_sync_dir(tdentry);
1621 if (!err) 1634 if (!host_err)
1622 err = nfsd_sync_dir(fdentry); 1635 host_err = nfsd_sync_dir(fdentry);
1623 } 1636 }
1624 1637
1625 out_dput_new: 1638 out_dput_new:
@@ -1627,8 +1640,7 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen,
1627 out_dput_old: 1640 out_dput_old:
1628 dput(odentry); 1641 dput(odentry);
1629 out_nfserr: 1642 out_nfserr:
1630 if (err) 1643 err = nfserrno(host_err);
1631 err = nfserrno(err);
1632 1644
1633 /* we cannot reply on fh_unlock on the two filehandles, 1645 /* we cannot reply on fh_unlock on the two filehandles,
1634 * as that would do the wrong thing if the two directories 1646 * as that would do the wrong thing if the two directories
@@ -1647,13 +1659,14 @@ out:
1647 * Unlink a file or directory 1659 * Unlink a file or directory
1648 * N.B. After this call fhp needs an fh_put 1660 * N.B. After this call fhp needs an fh_put
1649 */ 1661 */
1650int 1662__be32
1651nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, 1663nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
1652 char *fname, int flen) 1664 char *fname, int flen)
1653{ 1665{
1654 struct dentry *dentry, *rdentry; 1666 struct dentry *dentry, *rdentry;
1655 struct inode *dirp; 1667 struct inode *dirp;
1656 int err; 1668 __be32 err;
1669 int host_err;
1657 1670
1658 err = nfserr_acces; 1671 err = nfserr_acces;
1659 if (!flen || isdotent(fname, flen)) 1672 if (!flen || isdotent(fname, flen))
@@ -1667,7 +1680,7 @@ nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
1667 dirp = dentry->d_inode; 1680 dirp = dentry->d_inode;
1668 1681
1669 rdentry = lookup_one_len(fname, dentry, flen); 1682 rdentry = lookup_one_len(fname, dentry, flen);
1670 err = PTR_ERR(rdentry); 1683 host_err = PTR_ERR(rdentry);
1671 if (IS_ERR(rdentry)) 1684 if (IS_ERR(rdentry))
1672 goto out_nfserr; 1685 goto out_nfserr;
1673 1686
@@ -1684,22 +1697,23 @@ nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
1684#ifdef MSNFS 1697#ifdef MSNFS
1685 if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) && 1698 if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) &&
1686 (atomic_read(&rdentry->d_count) > 1)) { 1699 (atomic_read(&rdentry->d_count) > 1)) {
1687 err = -EPERM; 1700 host_err = -EPERM;
1688 } else 1701 } else
1689#endif 1702#endif
1690 err = vfs_unlink(dirp, rdentry); 1703 host_err = vfs_unlink(dirp, rdentry);
1691 } else { /* It's RMDIR */ 1704 } else { /* It's RMDIR */
1692 err = vfs_rmdir(dirp, rdentry); 1705 host_err = vfs_rmdir(dirp, rdentry);
1693 } 1706 }
1694 1707
1695 dput(rdentry); 1708 dput(rdentry);
1696 1709
1697 if (err == 0 && 1710 if (host_err)
1698 EX_ISSYNC(fhp->fh_export)) 1711 goto out_nfserr;
1699 err = nfsd_sync_dir(dentry); 1712 if (EX_ISSYNC(fhp->fh_export))
1713 host_err = nfsd_sync_dir(dentry);
1700 1714
1701out_nfserr: 1715out_nfserr:
1702 err = nfserrno(err); 1716 err = nfserrno(host_err);
1703out: 1717out:
1704 return err; 1718 return err;
1705} 1719}
@@ -1708,11 +1722,12 @@ out:
1708 * Read entries from a directory. 1722 * Read entries from a directory.
1709 * The NFSv3/4 verifier we ignore for now. 1723 * The NFSv3/4 verifier we ignore for now.
1710 */ 1724 */
1711int 1725__be32
1712nfsd_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,
1713 struct readdir_cd *cdp, encode_dent_fn func) 1727 struct readdir_cd *cdp, encode_dent_fn func)
1714{ 1728{
1715 int err; 1729 __be32 err;
1730 int host_err;
1716 struct file *file; 1731 struct file *file;
1717 loff_t offset = *offsetp; 1732 loff_t offset = *offsetp;
1718 1733
@@ -1734,10 +1749,10 @@ nfsd_readdir(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t *offsetp,
1734 1749
1735 do { 1750 do {
1736 cdp->err = nfserr_eof; /* will be cleared on successful read */ 1751 cdp->err = nfserr_eof; /* will be cleared on successful read */
1737 err = vfs_readdir(file, (filldir_t) func, cdp); 1752 host_err = vfs_readdir(file, (filldir_t) func, cdp);
1738 } while (err >=0 && cdp->err == nfs_ok); 1753 } while (host_err >=0 && cdp->err == nfs_ok);
1739 if (err) 1754 if (host_err)
1740 err = nfserrno(err); 1755 err = nfserrno(host_err);
1741 else 1756 else
1742 err = cdp->err; 1757 err = cdp->err;
1743 *offsetp = vfs_llseek(file, 0, 1); 1758 *offsetp = vfs_llseek(file, 0, 1);
@@ -1754,10 +1769,10 @@ out:
1754 * Get file system stats 1769 * Get file system stats
1755 * N.B. After this call fhp needs an fh_put 1770 * N.B. After this call fhp needs an fh_put
1756 */ 1771 */
1757int 1772__be32
1758nfsd_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)
1759{ 1774{
1760 int err = fh_verify(rqstp, fhp, 0, MAY_NOP); 1775 __be32 err = fh_verify(rqstp, fhp, 0, MAY_NOP);
1761 if (!err && vfs_statfs(fhp->fh_dentry,stat)) 1776 if (!err && vfs_statfs(fhp->fh_dentry,stat))
1762 err = nfserr_io; 1777 err = nfserr_io;
1763 return err; 1778 return err;
@@ -1766,7 +1781,7 @@ nfsd_statfs(struct svc_rqst *rqstp, struct svc_fh *fhp, struct kstatfs *stat)
1766/* 1781/*
1767 * Check for a user's access permissions to this inode. 1782 * Check for a user's access permissions to this inode.
1768 */ 1783 */
1769int 1784__be32
1770nfsd_permission(struct svc_export *exp, struct dentry *dentry, int acc) 1785nfsd_permission(struct svc_export *exp, struct dentry *dentry, int acc)
1771{ 1786{
1772 struct inode *inode = dentry->d_inode; 1787 struct inode *inode = dentry->d_inode;
diff --git a/include/linux/nfsd/nfsd.h b/include/linux/nfsd/nfsd.h
index 2f75160a5824..19a3c83d496e 100644
--- a/include/linux/nfsd/nfsd.h
+++ b/include/linux/nfsd/nfsd.h
@@ -72,57 +72,57 @@ int nfsd_racache_init(int);
72void nfsd_racache_shutdown(void); 72void nfsd_racache_shutdown(void);
73int nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry **dpp, 73int nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry **dpp,
74 struct svc_export **expp); 74 struct svc_export **expp);
75int nfsd_lookup(struct svc_rqst *, struct svc_fh *, 75__be32 nfsd_lookup(struct svc_rqst *, struct svc_fh *,
76 const char *, int, struct svc_fh *); 76 const char *, int, struct svc_fh *);
77int nfsd_setattr(struct svc_rqst *, struct svc_fh *, 77__be32 nfsd_setattr(struct svc_rqst *, struct svc_fh *,
78 struct iattr *, int, time_t); 78 struct iattr *, int, time_t);
79#ifdef CONFIG_NFSD_V4 79#ifdef CONFIG_NFSD_V4
80int nfsd4_set_nfs4_acl(struct svc_rqst *, struct svc_fh *, 80__be32 nfsd4_set_nfs4_acl(struct svc_rqst *, struct svc_fh *,
81 struct nfs4_acl *); 81 struct nfs4_acl *);
82int nfsd4_get_nfs4_acl(struct svc_rqst *, struct dentry *, struct nfs4_acl **); 82int nfsd4_get_nfs4_acl(struct svc_rqst *, struct dentry *, struct nfs4_acl **);
83#endif /* CONFIG_NFSD_V4 */ 83#endif /* CONFIG_NFSD_V4 */
84int nfsd_create(struct svc_rqst *, struct svc_fh *, 84__be32 nfsd_create(struct svc_rqst *, struct svc_fh *,
85 char *name, int len, struct iattr *attrs, 85 char *name, int len, struct iattr *attrs,
86 int type, dev_t rdev, struct svc_fh *res); 86 int type, dev_t rdev, struct svc_fh *res);
87#ifdef CONFIG_NFSD_V3 87#ifdef CONFIG_NFSD_V3
88int nfsd_access(struct svc_rqst *, struct svc_fh *, u32 *, u32 *); 88__be32 nfsd_access(struct svc_rqst *, struct svc_fh *, u32 *, u32 *);
89int nfsd_create_v3(struct svc_rqst *, struct svc_fh *, 89__be32 nfsd_create_v3(struct svc_rqst *, struct svc_fh *,
90 char *name, int len, struct iattr *attrs, 90 char *name, int len, struct iattr *attrs,
91 struct svc_fh *res, int createmode, 91 struct svc_fh *res, int createmode,
92 u32 *verifier, int *truncp); 92 u32 *verifier, int *truncp);
93int nfsd_commit(struct svc_rqst *, struct svc_fh *, 93__be32 nfsd_commit(struct svc_rqst *, struct svc_fh *,
94 loff_t, unsigned long); 94 loff_t, unsigned long);
95#endif /* CONFIG_NFSD_V3 */ 95#endif /* CONFIG_NFSD_V3 */
96int nfsd_open(struct svc_rqst *, struct svc_fh *, int, 96__be32 nfsd_open(struct svc_rqst *, struct svc_fh *, int,
97 int, struct file **); 97 int, struct file **);
98void nfsd_close(struct file *); 98void nfsd_close(struct file *);
99int nfsd_read(struct svc_rqst *, struct svc_fh *, struct file *, 99__be32 nfsd_read(struct svc_rqst *, struct svc_fh *, struct file *,
100 loff_t, struct kvec *, int, unsigned long *); 100 loff_t, struct kvec *, int, unsigned long *);
101int nfsd_write(struct svc_rqst *, struct svc_fh *,struct file *, 101__be32 nfsd_write(struct svc_rqst *, struct svc_fh *,struct file *,
102 loff_t, struct kvec *,int, unsigned long, int *); 102 loff_t, struct kvec *,int, unsigned long, int *);
103int nfsd_readlink(struct svc_rqst *, struct svc_fh *, 103__be32 nfsd_readlink(struct svc_rqst *, struct svc_fh *,
104 char *, int *); 104 char *, int *);
105int nfsd_symlink(struct svc_rqst *, struct svc_fh *, 105__be32 nfsd_symlink(struct svc_rqst *, struct svc_fh *,
106 char *name, int len, char *path, int plen, 106 char *name, int len, char *path, int plen,
107 struct svc_fh *res, struct iattr *); 107 struct svc_fh *res, struct iattr *);
108int nfsd_link(struct svc_rqst *, struct svc_fh *, 108__be32 nfsd_link(struct svc_rqst *, struct svc_fh *,
109 char *, int, struct svc_fh *); 109 char *, int, struct svc_fh *);
110int nfsd_rename(struct svc_rqst *, 110__be32 nfsd_rename(struct svc_rqst *,
111 struct svc_fh *, char *, int, 111 struct svc_fh *, char *, int,
112 struct svc_fh *, char *, int); 112 struct svc_fh *, char *, int);
113int nfsd_remove(struct svc_rqst *, 113__be32 nfsd_remove(struct svc_rqst *,
114 struct svc_fh *, char *, int); 114 struct svc_fh *, char *, int);
115int nfsd_unlink(struct svc_rqst *, struct svc_fh *, int type, 115__be32 nfsd_unlink(struct svc_rqst *, struct svc_fh *, int type,
116 char *name, int len); 116 char *name, int len);
117int nfsd_truncate(struct svc_rqst *, struct svc_fh *, 117int nfsd_truncate(struct svc_rqst *, struct svc_fh *,
118 unsigned long size); 118 unsigned long size);
119int nfsd_readdir(struct svc_rqst *, struct svc_fh *, 119__be32 nfsd_readdir(struct svc_rqst *, struct svc_fh *,
120 loff_t *, struct readdir_cd *, encode_dent_fn); 120 loff_t *, struct readdir_cd *, encode_dent_fn);
121int nfsd_statfs(struct svc_rqst *, struct svc_fh *, 121__be32 nfsd_statfs(struct svc_rqst *, struct svc_fh *,
122 struct kstatfs *); 122 struct kstatfs *);
123 123
124int nfsd_notify_change(struct inode *, struct iattr *); 124int nfsd_notify_change(struct inode *, struct iattr *);
125int nfsd_permission(struct svc_export *, struct dentry *, int); 125__be32 nfsd_permission(struct svc_export *, struct dentry *, int);
126int nfsd_sync_dir(struct dentry *dp); 126int nfsd_sync_dir(struct dentry *dp);
127 127
128#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) 128#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)