aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@redhat.com>2012-10-26 16:12:31 -0400
committerJ. Bruce Fields <bfields@redhat.com>2012-11-07 19:31:34 -0500
commitface15025ffdf664de95e86ae831544154d26c9c (patch)
tree7b848b1a55182da4368e182ab5bc9e3f52043263 /fs/nfsd
parentfae5096ad217db2e3368e980c1d86223f786856b (diff)
nfsd: use vfs_fsync_range(), not O_SYNC, for stable writes
NFSv4 shares the same struct file across multiple writes. (And we'd like NFSv2 and NFSv3 to do that as well some day.) So setting O_SYNC on the struct file as a way to request a synchronous write doesn't work. Instead, do a vfs_fsync_range() in that case. Reported-by: Peter Staubach <pstaubach@exagrid.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs/nfsd')
-rw-r--r--fs/nfsd/vfs.c13
1 files changed, 6 insertions, 7 deletions
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index ed3eb59b607e..b584205b25b4 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -1024,11 +1024,6 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
1024 1024
1025 if (!EX_ISSYNC(exp)) 1025 if (!EX_ISSYNC(exp))
1026 stable = 0; 1026 stable = 0;
1027 if (stable && !use_wgather) {
1028 spin_lock(&file->f_lock);
1029 file->f_flags |= O_SYNC;
1030 spin_unlock(&file->f_lock);
1031 }
1032 1027
1033 /* Write the data. */ 1028 /* Write the data. */
1034 oldfs = get_fs(); set_fs(KERNEL_DS); 1029 oldfs = get_fs(); set_fs(KERNEL_DS);
@@ -1044,8 +1039,12 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
1044 if (inode->i_mode & (S_ISUID | S_ISGID)) 1039 if (inode->i_mode & (S_ISUID | S_ISGID))
1045 kill_suid(dentry); 1040 kill_suid(dentry);
1046 1041
1047 if (stable && use_wgather) 1042 if (stable) {
1048 host_err = wait_for_concurrent_writes(file); 1043 if (use_wgather)
1044 host_err = wait_for_concurrent_writes(file);
1045 else
1046 host_err = vfs_fsync_range(file, offset, offset+*cnt, 0);
1047 }
1049 1048
1050out_nfserr: 1049out_nfserr:
1051 dprintk("nfsd: write complete host_err=%d\n", host_err); 1050 dprintk("nfsd: write complete host_err=%d\n", host_err);