diff options
Diffstat (limited to 'fs/nfsd/vfs.c')
-rw-r--r-- | fs/nfsd/vfs.c | 89 |
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 | ||
737 | void | 738 | int |
738 | nfsd_sync_dir(struct dentry *dp) | 739 | nfsd_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 | ||
817 | static inline int | 818 | static int |
818 | nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, | 819 | nfsd_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 | ||
881 | static inline int | 882 | static int |
882 | nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, | 883 | nfsd_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 | |||
1679 | out: | ||
1680 | return err; | ||
1681 | 1683 | ||
1682 | out_nfserr: | 1684 | out_nfserr: |
1683 | err = nfserrno(err); | 1685 | err = nfserrno(err); |
1684 | goto out; | 1686 | out: |
1687 | return err; | ||
1685 | } | 1688 | } |
1686 | 1689 | ||
1687 | /* | 1690 | /* |