NFS: Fix another O_DIRECT race
Ensure we call unmap_mapping_range() and sync dirty pages to disk before
doing an NFS direct write.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 57d3e77..eb5cd4c 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -433,11 +433,7 @@
* Flush all pending writes before doing anything
* with locks..
*/
- filemap_fdatawrite(filp->f_mapping);
- down(&inode->i_sem);
- nfs_wb_all(inode);
- up(&inode->i_sem);
- filemap_fdatawait(filp->f_mapping);
+ nfs_sync_mapping(filp->f_mapping);
/* NOTE: special case
* If we're signalled while cleaning up locks on process exit, we
@@ -465,15 +461,8 @@
* Flush all pending writes before doing anything
* with locks..
*/
- status = filemap_fdatawrite(filp->f_mapping);
- if (status == 0) {
- down(&inode->i_sem);
- status = nfs_wb_all(inode);
- up(&inode->i_sem);
- if (status == 0)
- status = filemap_fdatawait(filp->f_mapping);
- }
- if (status < 0)
+ status = nfs_sync_mapping(filp->f_mapping);
+ if (status != 0)
goto out;
lock_kernel();
@@ -497,11 +486,7 @@
* Make sure we clear the cache whenever we try to get the lock.
* This makes locking act as a cache coherency point.
*/
- filemap_fdatawrite(filp->f_mapping);
- down(&inode->i_sem);
- nfs_wb_all(inode); /* we may have slept */
- up(&inode->i_sem);
- filemap_fdatawait(filp->f_mapping);
+ nfs_sync_mapping(filp->f_mapping);
nfs_zap_caches(inode);
out:
rpc_clnt_sigunmask(NFS_CLIENT(inode), &oldset);