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.c40
1 files changed, 25 insertions, 15 deletions
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index af7c3c3074b0..df4019f04560 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -717,27 +717,33 @@ nfsd_close(struct file *filp)
717 * As this calls fsync (not fdatasync) there is no need for a write_inode 717 * As this calls fsync (not fdatasync) there is no need for a write_inode
718 * after it. 718 * after it.
719 */ 719 */
720static inline void nfsd_dosync(struct file *filp, struct dentry *dp, 720static inline int nfsd_dosync(struct file *filp, struct dentry *dp,
721 struct file_operations *fop) 721 struct file_operations *fop)
722{ 722{
723 struct inode *inode = dp->d_inode; 723 struct inode *inode = dp->d_inode;
724 int (*fsync) (struct file *, struct dentry *, int); 724 int (*fsync) (struct file *, struct dentry *, int);
725 int err = nfs_ok;
725 726
726 filemap_fdatawrite(inode->i_mapping); 727 filemap_fdatawrite(inode->i_mapping);
727 if (fop && (fsync = fop->fsync)) 728 if (fop && (fsync = fop->fsync))
728 fsync(filp, dp, 0); 729 err=fsync(filp, dp, 0);
729 filemap_fdatawait(inode->i_mapping); 730 filemap_fdatawait(inode->i_mapping);
731
732 return nfserrno(err);
730} 733}
731 734
732 735
733static void 736static int
734nfsd_sync(struct file *filp) 737nfsd_sync(struct file *filp)
735{ 738{
739 int err;
736 struct inode *inode = filp->f_dentry->d_inode; 740 struct inode *inode = filp->f_dentry->d_inode;
737 dprintk("nfsd: sync file %s\n", filp->f_dentry->d_name.name); 741 dprintk("nfsd: sync file %s\n", filp->f_dentry->d_name.name);
738 down(&inode->i_sem); 742 down(&inode->i_sem);
739 nfsd_dosync(filp, filp->f_dentry, filp->f_op); 743 err=nfsd_dosync(filp, filp->f_dentry, filp->f_op);
740 up(&inode->i_sem); 744 up(&inode->i_sem);
745
746 return err;
741} 747}
742 748
743void 749void
@@ -874,6 +880,16 @@ out:
874 return err; 880 return err;
875} 881}
876 882
883static void kill_suid(struct dentry *dentry)
884{
885 struct iattr ia;
886 ia.ia_valid = ATTR_KILL_SUID | ATTR_KILL_SGID;
887
888 down(&dentry->d_inode->i_sem);
889 notify_change(dentry, &ia);
890 up(&dentry->d_inode->i_sem);
891}
892
877static inline int 893static inline int
878nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, 894nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
879 loff_t offset, struct kvec *vec, int vlen, 895 loff_t offset, struct kvec *vec, int vlen,
@@ -927,14 +943,8 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
927 } 943 }
928 944
929 /* clear setuid/setgid flag after write */ 945 /* clear setuid/setgid flag after write */
930 if (err >= 0 && (inode->i_mode & (S_ISUID | S_ISGID))) { 946 if (err >= 0 && (inode->i_mode & (S_ISUID | S_ISGID)))
931 struct iattr ia; 947 kill_suid(dentry);
932 ia.ia_valid = ATTR_KILL_SUID | ATTR_KILL_SGID;
933
934 down(&inode->i_sem);
935 notify_change(dentry, &ia);
936 up(&inode->i_sem);
937 }
938 948
939 if (err >= 0 && stable) { 949 if (err >= 0 && stable) {
940 static ino_t last_ino; 950 static ino_t last_ino;
@@ -962,7 +972,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
962 972
963 if (inode->i_state & I_DIRTY) { 973 if (inode->i_state & I_DIRTY) {
964 dprintk("nfsd: write sync %d\n", current->pid); 974 dprintk("nfsd: write sync %d\n", current->pid);
965 nfsd_sync(file); 975 err=nfsd_sync(file);
966 } 976 }
967#if 0 977#if 0
968 wake_up(&inode->i_wait); 978 wake_up(&inode->i_wait);
@@ -1066,7 +1076,7 @@ nfsd_commit(struct svc_rqst *rqstp, struct svc_fh *fhp,
1066 return err; 1076 return err;
1067 if (EX_ISSYNC(fhp->fh_export)) { 1077 if (EX_ISSYNC(fhp->fh_export)) {
1068 if (file->f_op && file->f_op->fsync) { 1078 if (file->f_op && file->f_op->fsync) {
1069 nfsd_sync(file); 1079 err = nfsd_sync(file);
1070 } else { 1080 } else {
1071 err = nfserr_notsupp; 1081 err = nfserr_notsupp;
1072 } 1082 }