diff options
author | J. Bruce Fields <bfields@redhat.com> | 2012-10-26 16:12:31 -0400 |
---|---|---|
committer | J. Bruce Fields <bfields@redhat.com> | 2012-11-07 19:31:34 -0500 |
commit | face15025ffdf664de95e86ae831544154d26c9c (patch) | |
tree | 7b848b1a55182da4368e182ab5bc9e3f52043263 /fs/nfsd | |
parent | fae5096ad217db2e3368e980c1d86223f786856b (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.c | 13 |
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 | ||
1050 | out_nfserr: | 1049 | out_nfserr: |
1051 | dprintk("nfsd: write complete host_err=%d\n", host_err); | 1050 | dprintk("nfsd: write complete host_err=%d\n", host_err); |