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.c89
1 files changed, 46 insertions, 43 deletions
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index eef0576a7785..5320e5afaddb 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -710,14 +710,15 @@ static inline int nfsd_dosync(struct file *filp, struct dentry *dp,
710{ 710{
711 struct inode *inode = dp->d_inode; 711 struct inode *inode = dp->d_inode;
712 int (*fsync) (struct file *, struct dentry *, int); 712 int (*fsync) (struct file *, struct dentry *, int);
713 int err = nfs_ok; 713 int err;
714 714
715 filemap_fdatawrite(inode->i_mapping); 715 err = filemap_fdatawrite(inode->i_mapping);
716 if (fop && (fsync = fop->fsync)) 716 if (err == 0 && fop && (fsync = fop->fsync))
717 err=fsync(filp, dp, 0); 717 err = fsync(filp, dp, 0);
718 filemap_fdatawait(inode->i_mapping); 718 if (err == 0)
719 err = filemap_fdatawait(inode->i_mapping);
719 720
720 return nfserrno(err); 721 return err;
721} 722}
722 723
723 724
@@ -734,10 +735,10 @@ nfsd_sync(struct file *filp)
734 return err; 735 return err;
735} 736}
736 737
737void 738int
738nfsd_sync_dir(struct dentry *dp) 739nfsd_sync_dir(struct dentry *dp)
739{ 740{
740 nfsd_dosync(NULL, dp, dp->d_inode->i_fop); 741 return nfsd_dosync(NULL, dp, dp->d_inode->i_fop);
741} 742}
742 743
743/* 744/*
@@ -814,7 +815,7 @@ nfsd_read_actor(read_descriptor_t *desc, struct page *page, unsigned long offset
814 return size; 815 return size;
815} 816}
816 817
817static inline int 818static int
818nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, 819nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
819 loff_t offset, struct kvec *vec, int vlen, unsigned long *count) 820 loff_t offset, struct kvec *vec, int vlen, unsigned long *count)
820{ 821{
@@ -878,7 +879,7 @@ static void kill_suid(struct dentry *dentry)
878 mutex_unlock(&dentry->d_inode->i_mutex); 879 mutex_unlock(&dentry->d_inode->i_mutex);
879} 880}
880 881
881static inline int 882static int
882nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, 883nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
883 loff_t offset, struct kvec *vec, int vlen, 884 loff_t offset, struct kvec *vec, int vlen,
884 unsigned long cnt, int *stablep) 885 unsigned long cnt, int *stablep)
@@ -890,9 +891,9 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
890 int err = 0; 891 int err = 0;
891 int stable = *stablep; 892 int stable = *stablep;
892 893
894#ifdef MSNFS
893 err = nfserr_perm; 895 err = nfserr_perm;
894 896
895#ifdef MSNFS
896 if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) && 897 if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) &&
897 (!lock_may_write(file->f_dentry->d_inode, offset, cnt))) 898 (!lock_may_write(file->f_dentry->d_inode, offset, cnt)))
898 goto out; 899 goto out;
@@ -1064,7 +1065,7 @@ nfsd_commit(struct svc_rqst *rqstp, struct svc_fh *fhp,
1064 return err; 1065 return err;
1065 if (EX_ISSYNC(fhp->fh_export)) { 1066 if (EX_ISSYNC(fhp->fh_export)) {
1066 if (file->f_op && file->f_op->fsync) { 1067 if (file->f_op && file->f_op->fsync) {
1067 err = nfsd_sync(file); 1068 err = nfserrno(nfsd_sync(file));
1068 } else { 1069 } else {
1069 err = nfserr_notsupp; 1070 err = nfserr_notsupp;
1070 } 1071 }
@@ -1132,7 +1133,7 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
1132 "nfsd_create: parent %s/%s not locked!\n", 1133 "nfsd_create: parent %s/%s not locked!\n",
1133 dentry->d_parent->d_name.name, 1134 dentry->d_parent->d_name.name,
1134 dentry->d_name.name); 1135 dentry->d_name.name);
1135 err = -EIO; 1136 err = nfserr_io;
1136 goto out; 1137 goto out;
1137 } 1138 }
1138 } 1139 }
@@ -1175,7 +1176,7 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
1175 goto out_nfserr; 1176 goto out_nfserr;
1176 1177
1177 if (EX_ISSYNC(fhp->fh_export)) { 1178 if (EX_ISSYNC(fhp->fh_export)) {
1178 nfsd_sync_dir(dentry); 1179 err = nfserrno(nfsd_sync_dir(dentry));
1179 write_inode_now(dchild->d_inode, 1); 1180 write_inode_now(dchild->d_inode, 1);
1180 } 1181 }
1181 1182
@@ -1185,9 +1186,11 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
1185 * send along the gid when it tries to implement setgid 1186 * send along the gid when it tries to implement setgid
1186 * directories via NFS. 1187 * directories via NFS.
1187 */ 1188 */
1188 err = 0; 1189 if ((iap->ia_valid &= ~(ATTR_UID|ATTR_GID|ATTR_MODE)) != 0) {
1189 if ((iap->ia_valid &= ~(ATTR_UID|ATTR_GID|ATTR_MODE)) != 0) 1190 int err2 = nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0);
1190 err = nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0); 1191 if (err2)
1192 err = err2;
1193 }
1191 /* 1194 /*
1192 * Update the file handle to get the new inode info. 1195 * Update the file handle to get the new inode info.
1193 */ 1196 */
@@ -1306,17 +1309,10 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
1306 goto out_nfserr; 1309 goto out_nfserr;
1307 1310
1308 if (EX_ISSYNC(fhp->fh_export)) { 1311 if (EX_ISSYNC(fhp->fh_export)) {
1309 nfsd_sync_dir(dentry); 1312 err = nfserrno(nfsd_sync_dir(dentry));
1310 /* setattr will sync the child (or not) */ 1313 /* setattr will sync the child (or not) */
1311 } 1314 }
1312 1315
1313 /*
1314 * Update the filehandle to get the new inode info.
1315 */
1316 err = fh_update(resfhp);
1317 if (err)
1318 goto out;
1319
1320 if (createmode == NFS3_CREATE_EXCLUSIVE) { 1316 if (createmode == NFS3_CREATE_EXCLUSIVE) {
1321 /* Cram the verifier into atime/mtime/mode */ 1317 /* Cram the verifier into atime/mtime/mode */
1322 iap->ia_valid = ATTR_MTIME|ATTR_ATIME 1318 iap->ia_valid = ATTR_MTIME|ATTR_ATIME
@@ -1337,8 +1333,17 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
1337 * implement setgid directories via NFS. Clear out all that cruft. 1333 * implement setgid directories via NFS. Clear out all that cruft.
1338 */ 1334 */
1339 set_attr: 1335 set_attr:
1340 if ((iap->ia_valid &= ~(ATTR_UID|ATTR_GID)) != 0) 1336 if ((iap->ia_valid &= ~(ATTR_UID|ATTR_GID)) != 0) {
1341 err = nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0); 1337 int err2 = nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0);
1338 if (err2)
1339 err = err2;
1340 }
1341
1342 /*
1343 * Update the filehandle to get the new inode info.
1344 */
1345 if (!err)
1346 err = fh_update(resfhp);
1342 1347
1343 out: 1348 out:
1344 fh_unlock(fhp); 1349 fh_unlock(fhp);
@@ -1447,10 +1452,10 @@ nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp,
1447 } else 1452 } else
1448 err = vfs_symlink(dentry->d_inode, dnew, path, mode); 1453 err = vfs_symlink(dentry->d_inode, dnew, path, mode);
1449 1454
1450 if (!err) { 1455 if (!err)
1451 if (EX_ISSYNC(fhp->fh_export)) 1456 if (EX_ISSYNC(fhp->fh_export))
1452 nfsd_sync_dir(dentry); 1457 err = nfsd_sync_dir(dentry);
1453 } else 1458 if (err)
1454 err = nfserrno(err); 1459 err = nfserrno(err);
1455 fh_unlock(fhp); 1460 fh_unlock(fhp);
1456 1461
@@ -1506,7 +1511,7 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp,
1506 err = vfs_link(dold, dirp, dnew); 1511 err = vfs_link(dold, dirp, dnew);
1507 if (!err) { 1512 if (!err) {
1508 if (EX_ISSYNC(ffhp->fh_export)) { 1513 if (EX_ISSYNC(ffhp->fh_export)) {
1509 nfsd_sync_dir(ddir); 1514 err = nfserrno(nfsd_sync_dir(ddir));
1510 write_inode_now(dest, 1); 1515 write_inode_now(dest, 1);
1511 } 1516 }
1512 } else { 1517 } else {
@@ -1590,13 +1595,14 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen,
1590 if ((ffhp->fh_export->ex_flags & NFSEXP_MSNFS) && 1595 if ((ffhp->fh_export->ex_flags & NFSEXP_MSNFS) &&
1591 ((atomic_read(&odentry->d_count) > 1) 1596 ((atomic_read(&odentry->d_count) > 1)
1592 || (atomic_read(&ndentry->d_count) > 1))) { 1597 || (atomic_read(&ndentry->d_count) > 1))) {
1593 err = nfserr_perm; 1598 err = -EPERM;
1594 } else 1599 } else
1595#endif 1600#endif
1596 err = vfs_rename(fdir, odentry, tdir, ndentry); 1601 err = vfs_rename(fdir, odentry, tdir, ndentry);
1597 if (!err && EX_ISSYNC(tfhp->fh_export)) { 1602 if (!err && EX_ISSYNC(tfhp->fh_export)) {
1598 nfsd_sync_dir(tdentry); 1603 err = nfsd_sync_dir(tdentry);
1599 nfsd_sync_dir(fdentry); 1604 if (!err)
1605 err = nfsd_sync_dir(fdentry);
1600 } 1606 }
1601 1607
1602 out_dput_new: 1608 out_dput_new:
@@ -1661,7 +1667,7 @@ nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
1661#ifdef MSNFS 1667#ifdef MSNFS
1662 if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) && 1668 if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) &&
1663 (atomic_read(&rdentry->d_count) > 1)) { 1669 (atomic_read(&rdentry->d_count) > 1)) {
1664 err = nfserr_perm; 1670 err = -EPERM;
1665 } else 1671 } else
1666#endif 1672#endif
1667 err = vfs_unlink(dirp, rdentry); 1673 err = vfs_unlink(dirp, rdentry);
@@ -1671,17 +1677,14 @@ nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
1671 1677
1672 dput(rdentry); 1678 dput(rdentry);
1673 1679
1674 if (err) 1680 if (err == 0 &&
1675 goto out_nfserr; 1681 EX_ISSYNC(fhp->fh_export))
1676 if (EX_ISSYNC(fhp->fh_export)) 1682 err = nfsd_sync_dir(dentry);
1677 nfsd_sync_dir(dentry);
1678
1679out:
1680 return err;
1681 1683
1682out_nfserr: 1684out_nfserr:
1683 err = nfserrno(err); 1685 err = nfserrno(err);
1684 goto out; 1686out:
1687 return err;
1685} 1688}
1686 1689
1687/* 1690/*