diff options
Diffstat (limited to 'fs/nfs/file.c')
-rw-r--r-- | fs/nfs/file.c | 18 |
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, | |||
55 | static ssize_t nfs_file_write(struct kiocb *, const struct iovec *iov, | 55 | static 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); |
57 | static int nfs_file_flush(struct file *, fl_owner_t id); | 57 | static int nfs_file_flush(struct file *, fl_owner_t id); |
58 | static int nfs_file_fsync(struct file *, int datasync); | 58 | static int nfs_file_fsync(struct file *, loff_t, loff_t, int datasync); |
59 | static int nfs_check_flags(int flags); | 59 | static int nfs_check_flags(int flags); |
60 | static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl); | 60 | static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl); |
61 | static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl); | 61 | static 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 | */ |
307 | static int | 310 | static int |
308 | nfs_file_fsync(struct file *file, int datasync) | 311 | nfs_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 | ||