fs: push i_mutex and filemap_write_and_wait down into ->fsync() handlers
[platform/adaptation/renesas_rcar/renesas_kernel.git] / fs / nfs / file.c
index 2c1705b..28b8c3f 100644 (file)
@@ -55,7 +55,7 @@ static ssize_t nfs_file_splice_write(struct pipe_inode_info *pipe,
 static ssize_t nfs_file_write(struct kiocb *, const struct iovec *iov,
                                unsigned long nr_segs, loff_t pos);
 static int  nfs_file_flush(struct file *, fl_owner_t id);
-static int  nfs_file_fsync(struct file *, int datasync);
+static int  nfs_file_fsync(struct file *, loff_t, loff_t, int datasync);
 static int nfs_check_flags(int flags);
 static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl);
 static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl);
@@ -308,7 +308,7 @@ nfs_file_mmap(struct file * file, struct vm_area_struct * vma)
  * fall back to doing a synchronous write.
  */
 static int
-nfs_file_fsync(struct file *file, int datasync)
+nfs_file_fsync(struct file *file, loff_t start, loff_t end, int datasync)
 {
        struct dentry *dentry = file->f_path.dentry;
        struct nfs_open_context *ctx = nfs_file_open_context(file);
@@ -316,11 +316,15 @@ nfs_file_fsync(struct file *file, int datasync)
        int have_error, status;
        int ret = 0;
 
-
        dprintk("NFS: fsync file(%s/%s) datasync %d\n",
                        dentry->d_parent->d_name.name, dentry->d_name.name,
                        datasync);
 
+       ret = filemap_write_and_wait_range(inode->i_mapping, start, end);
+       if (ret)
+               return ret;
+       mutex_lock(&inode->i_mutex);
+
        nfs_inc_stats(inode, NFSIOS_VFSFSYNC);
        have_error = test_and_clear_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags);
        status = nfs_commit_inode(inode, FLUSH_SYNC);
@@ -332,6 +336,7 @@ nfs_file_fsync(struct file *file, int datasync)
        if (!ret && !datasync)
                /* application has asked for meta-data sync */
                ret = pnfs_layoutcommit_inode(inode, true);
+       mutex_unlock(&inode->i_mutex);
        return ret;
 }