aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/file.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/file.c')
-rw-r--r--fs/nfs/file.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 2f093ed16980..28b8c3f3cda3 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -55,7 +55,7 @@ static ssize_t nfs_file_splice_write(struct pipe_inode_info *pipe,
55static ssize_t nfs_file_write(struct kiocb *, const struct iovec *iov, 55static ssize_t nfs_file_write(struct kiocb *, const struct iovec *iov,
56 unsigned long nr_segs, loff_t pos); 56 unsigned long nr_segs, loff_t pos);
57static int nfs_file_flush(struct file *, fl_owner_t id); 57static int nfs_file_flush(struct file *, fl_owner_t id);
58static int nfs_file_fsync(struct file *, int datasync); 58static int nfs_file_fsync(struct file *, loff_t, loff_t, int datasync);
59static int nfs_check_flags(int flags); 59static int nfs_check_flags(int flags);
60static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl); 60static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl);
61static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl); 61static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl);
@@ -187,8 +187,11 @@ static loff_t nfs_file_llseek(struct file *filp, loff_t offset, int origin)
187 filp->f_path.dentry->d_name.name, 187 filp->f_path.dentry->d_name.name,
188 offset, origin); 188 offset, origin);
189 189
190 /* origin == SEEK_END => we must revalidate the cached file length */ 190 /*
191 if (origin == SEEK_END) { 191 * origin == SEEK_END || SEEK_DATA || SEEK_HOLE => we must revalidate
192 * the cached file length
193 */
194 if (origin != SEEK_SET || origin != SEEK_CUR) {
192 struct inode *inode = filp->f_mapping->host; 195 struct inode *inode = filp->f_mapping->host;
193 196
194 int retval = nfs_revalidate_file_size(inode, filp); 197 int retval = nfs_revalidate_file_size(inode, filp);
@@ -305,7 +308,7 @@ nfs_file_mmap(struct file * file, struct vm_area_struct * vma)
305 * fall back to doing a synchronous write. 308 * fall back to doing a synchronous write.
306 */ 309 */
307static int 310static int
308nfs_file_fsync(struct file *file, int datasync) 311nfs_file_fsync(struct file *file, loff_t start, loff_t end, int datasync)
309{ 312{
310 struct dentry *dentry = file->f_path.dentry; 313 struct dentry *dentry = file->f_path.dentry;
311 struct nfs_open_context *ctx = nfs_file_open_context(file); 314 struct nfs_open_context *ctx = nfs_file_open_context(file);
@@ -313,11 +316,15 @@ nfs_file_fsync(struct file *file, int datasync)
313 int have_error, status; 316 int have_error, status;
314 int ret = 0; 317 int ret = 0;
315 318
316
317 dprintk("NFS: fsync file(%s/%s) datasync %d\n", 319 dprintk("NFS: fsync file(%s/%s) datasync %d\n",
318 dentry->d_parent->d_name.name, dentry->d_name.name, 320 dentry->d_parent->d_name.name, dentry->d_name.name,
319 datasync); 321 datasync);
320 322
323 ret = filemap_write_and_wait_range(inode->i_mapping, start, end);
324 if (ret)
325 return ret;
326 mutex_lock(&inode->i_mutex);
327
321 nfs_inc_stats(inode, NFSIOS_VFSFSYNC); 328 nfs_inc_stats(inode, NFSIOS_VFSFSYNC);
322 have_error = test_and_clear_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags); 329 have_error = test_and_clear_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags);
323 status = nfs_commit_inode(inode, FLUSH_SYNC); 330 status = nfs_commit_inode(inode, FLUSH_SYNC);
@@ -329,6 +336,7 @@ nfs_file_fsync(struct file *file, int datasync)
329 if (!ret && !datasync) 336 if (!ret && !datasync)
330 /* application has asked for meta-data sync */ 337 /* application has asked for meta-data sync */
331 ret = pnfs_layoutcommit_inode(inode, true); 338 ret = pnfs_layoutcommit_inode(inode, true);
339 mutex_unlock(&inode->i_mutex);
332 return ret; 340 return ret;
333} 341}
334 342