diff options
author | J. Bruce Fields <bfields@redhat.com> | 2012-10-27 00:12:31 +0400 |
---|---|---|
committer | J. Bruce Fields <bfields@redhat.com> | 2012-11-08 04:31:34 +0400 |
commit | face15025ffdf664de95e86ae831544154d26c9c (patch) | |
tree | 7b848b1a55182da4368e182ab5bc9e3f52043263 /fs/nfsd | |
parent | fae5096ad217db2e3368e980c1d86223f786856b (diff) | |
download | linux-face15025ffdf664de95e86ae831544154d26c9c.tar.xz |
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, if (!EX_ISSYNC(exp)) stable = 0; - if (stable && !use_wgather) { - spin_lock(&file->f_lock); - file->f_flags |= O_SYNC; - spin_unlock(&file->f_lock); - } /* Write the data. */ 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, if (inode->i_mode & (S_ISUID | S_ISGID)) kill_suid(dentry); - if (stable && use_wgather) - host_err = wait_for_concurrent_writes(file); + if (stable) { + if (use_wgather) + host_err = wait_for_concurrent_writes(file); + else + host_err = vfs_fsync_range(file, offset, offset+*cnt, 0); + } out_nfserr: dprintk("nfsd: write complete host_err=%d\n", host_err); |