aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/vfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfsd/vfs.c')
-rw-r--r--fs/nfsd/vfs.c381
1 files changed, 213 insertions, 168 deletions
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");