diff options
Diffstat (limited to 'fs/nfsd/vfs.c')
-rw-r--r-- | fs/nfsd/vfs.c | 48 |
1 files changed, 19 insertions, 29 deletions
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 140c496f612c..f501a9b5c9df 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c | |||
@@ -189,8 +189,7 @@ nfsd_lookup_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
189 | dprintk("nfsd: nfsd_lookup(fh %s, %.*s)\n", SVCFH_fmt(fhp), len,name); | 189 | dprintk("nfsd: nfsd_lookup(fh %s, %.*s)\n", SVCFH_fmt(fhp), len,name); |
190 | 190 | ||
191 | dparent = fhp->fh_dentry; | 191 | dparent = fhp->fh_dentry; |
192 | exp = fhp->fh_export; | 192 | exp = exp_get(fhp->fh_export); |
193 | exp_get(exp); | ||
194 | 193 | ||
195 | /* Lookup the name, but don't follow links */ | 194 | /* Lookup the name, but don't follow links */ |
196 | if (isdotent(name, len)) { | 195 | if (isdotent(name, len)) { |
@@ -464,7 +463,7 @@ out_put_write_access: | |||
464 | if (size_change) | 463 | if (size_change) |
465 | put_write_access(inode); | 464 | put_write_access(inode); |
466 | if (!err) | 465 | if (!err) |
467 | commit_metadata(fhp); | 466 | err = nfserrno(commit_metadata(fhp)); |
468 | out: | 467 | out: |
469 | return err; | 468 | return err; |
470 | } | 469 | } |
@@ -820,7 +819,8 @@ static int nfsd_direct_splice_actor(struct pipe_inode_info *pipe, | |||
820 | return __splice_from_pipe(pipe, sd, nfsd_splice_actor); | 819 | return __splice_from_pipe(pipe, sd, nfsd_splice_actor); |
821 | } | 820 | } |
822 | 821 | ||
823 | __be32 nfsd_finish_read(struct file *file, unsigned long *count, int host_err) | 822 | static __be32 |
823 | nfsd_finish_read(struct file *file, unsigned long *count, int host_err) | ||
824 | { | 824 | { |
825 | if (host_err >= 0) { | 825 | if (host_err >= 0) { |
826 | nfsdstats.io_read += host_err; | 826 | nfsdstats.io_read += host_err; |
@@ -831,7 +831,7 @@ __be32 nfsd_finish_read(struct file *file, unsigned long *count, int host_err) | |||
831 | return nfserrno(host_err); | 831 | return nfserrno(host_err); |
832 | } | 832 | } |
833 | 833 | ||
834 | int nfsd_splice_read(struct svc_rqst *rqstp, | 834 | __be32 nfsd_splice_read(struct svc_rqst *rqstp, |
835 | struct file *file, loff_t offset, unsigned long *count) | 835 | struct file *file, loff_t offset, unsigned long *count) |
836 | { | 836 | { |
837 | struct splice_desc sd = { | 837 | struct splice_desc sd = { |
@@ -847,7 +847,7 @@ int nfsd_splice_read(struct svc_rqst *rqstp, | |||
847 | return nfsd_finish_read(file, count, host_err); | 847 | return nfsd_finish_read(file, count, host_err); |
848 | } | 848 | } |
849 | 849 | ||
850 | int nfsd_readv(struct file *file, loff_t offset, struct kvec *vec, int vlen, | 850 | __be32 nfsd_readv(struct file *file, loff_t offset, struct kvec *vec, int vlen, |
851 | unsigned long *count) | 851 | unsigned long *count) |
852 | { | 852 | { |
853 | mm_segment_t oldfs; | 853 | mm_segment_t oldfs; |
@@ -1121,7 +1121,8 @@ nfsd_create_setattr(struct svc_rqst *rqstp, struct svc_fh *resfhp, | |||
1121 | iap->ia_valid &= ~(ATTR_UID|ATTR_GID); | 1121 | iap->ia_valid &= ~(ATTR_UID|ATTR_GID); |
1122 | if (iap->ia_valid) | 1122 | if (iap->ia_valid) |
1123 | return nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0); | 1123 | return nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0); |
1124 | return 0; | 1124 | /* Callers expect file metadata to be committed here */ |
1125 | return nfserrno(commit_metadata(resfhp)); | ||
1125 | } | 1126 | } |
1126 | 1127 | ||
1127 | /* HPUX client sometimes creates a file in mode 000, and sets size to 0. | 1128 | /* HPUX client sometimes creates a file in mode 000, and sets size to 0. |
@@ -1253,9 +1254,10 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
1253 | err = nfsd_create_setattr(rqstp, resfhp, iap); | 1254 | err = nfsd_create_setattr(rqstp, resfhp, iap); |
1254 | 1255 | ||
1255 | /* | 1256 | /* |
1256 | * nfsd_setattr already committed the child. Transactional filesystems | 1257 | * nfsd_create_setattr already committed the child. Transactional |
1257 | * had a chance to commit changes for both parent and child | 1258 | * filesystems had a chance to commit changes for both parent and |
1258 | * simultaneously making the following commit_metadata a noop. | 1259 | * child * simultaneously making the following commit_metadata a |
1260 | * noop. | ||
1259 | */ | 1261 | */ |
1260 | err2 = nfserrno(commit_metadata(fhp)); | 1262 | err2 = nfserrno(commit_metadata(fhp)); |
1261 | if (err2) | 1263 | if (err2) |
@@ -1426,7 +1428,8 @@ do_nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
1426 | err = nfsd_create_setattr(rqstp, resfhp, iap); | 1428 | err = nfsd_create_setattr(rqstp, resfhp, iap); |
1427 | 1429 | ||
1428 | /* | 1430 | /* |
1429 | * nfsd_setattr already committed the child (and possibly also the parent). | 1431 | * nfsd_create_setattr already committed the child |
1432 | * (and possibly also the parent). | ||
1430 | */ | 1433 | */ |
1431 | if (!err) | 1434 | if (!err) |
1432 | err = nfserrno(commit_metadata(fhp)); | 1435 | err = nfserrno(commit_metadata(fhp)); |
@@ -1504,16 +1507,15 @@ out_nfserr: | |||
1504 | __be32 | 1507 | __be32 |
1505 | nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp, | 1508 | nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp, |
1506 | char *fname, int flen, | 1509 | char *fname, int flen, |
1507 | char *path, int plen, | 1510 | char *path, |
1508 | struct svc_fh *resfhp, | 1511 | struct svc_fh *resfhp) |
1509 | struct iattr *iap) | ||
1510 | { | 1512 | { |
1511 | struct dentry *dentry, *dnew; | 1513 | struct dentry *dentry, *dnew; |
1512 | __be32 err, cerr; | 1514 | __be32 err, cerr; |
1513 | int host_err; | 1515 | int host_err; |
1514 | 1516 | ||
1515 | err = nfserr_noent; | 1517 | err = nfserr_noent; |
1516 | if (!flen || !plen) | 1518 | if (!flen || path[0] == '\0') |
1517 | goto out; | 1519 | goto out; |
1518 | err = nfserr_exist; | 1520 | err = nfserr_exist; |
1519 | if (isdotent(fname, flen)) | 1521 | if (isdotent(fname, flen)) |
@@ -1534,18 +1536,7 @@ nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
1534 | if (IS_ERR(dnew)) | 1536 | if (IS_ERR(dnew)) |
1535 | goto out_nfserr; | 1537 | goto out_nfserr; |
1536 | 1538 | ||
1537 | if (unlikely(path[plen] != 0)) { | 1539 | host_err = vfs_symlink(dentry->d_inode, dnew, path); |
1538 | char *path_alloced = kmalloc(plen+1, GFP_KERNEL); | ||
1539 | if (path_alloced == NULL) | ||
1540 | host_err = -ENOMEM; | ||
1541 | else { | ||
1542 | strncpy(path_alloced, path, plen); | ||
1543 | path_alloced[plen] = 0; | ||
1544 | host_err = vfs_symlink(dentry->d_inode, dnew, path_alloced); | ||
1545 | kfree(path_alloced); | ||
1546 | } | ||
1547 | } else | ||
1548 | host_err = vfs_symlink(dentry->d_inode, dnew, path); | ||
1549 | err = nfserrno(host_err); | 1540 | err = nfserrno(host_err); |
1550 | if (!err) | 1541 | if (!err) |
1551 | err = nfserrno(commit_metadata(fhp)); | 1542 | err = nfserrno(commit_metadata(fhp)); |
@@ -2093,8 +2084,7 @@ nfsd_racache_init(int cache_size) | |||
2093 | if (raparm_hash[0].pb_head) | 2084 | if (raparm_hash[0].pb_head) |
2094 | return 0; | 2085 | return 0; |
2095 | nperbucket = DIV_ROUND_UP(cache_size, RAPARM_HASH_SIZE); | 2086 | nperbucket = DIV_ROUND_UP(cache_size, RAPARM_HASH_SIZE); |
2096 | if (nperbucket < 2) | 2087 | nperbucket = max(2, nperbucket); |
2097 | nperbucket = 2; | ||
2098 | cache_size = nperbucket * RAPARM_HASH_SIZE; | 2088 | cache_size = nperbucket * RAPARM_HASH_SIZE; |
2099 | 2089 | ||
2100 | dprintk("nfsd: allocating %d readahead buffers.\n", cache_size); | 2090 | dprintk("nfsd: allocating %d readahead buffers.\n", cache_size); |