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.c48
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));
468out: 467out:
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) 822static __be32
823nfsd_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
834int 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
850int 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
1505nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp, 1508nfsd_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);