if (!count)
                goto out;
 
-       if (mapping->nrpages) {
-               retval = filemap_fdatawrite(mapping);
-               if (retval == 0)
-                       retval = nfs_wb_all(inode);
-               if (retval == 0)
-                       retval = filemap_fdatawait(mapping);
-               if (retval)
-                       goto out;
-       }
+       retval = nfs_sync_mapping(mapping);
+       if (retval)
+               goto out;
 
        retval = nfs_direct_read(inode, ctx, &iov, pos, 1);
        if (retval > 0)
        if (!count)
                goto out;
 
-       if (mapping->nrpages) {
-               retval = filemap_fdatawrite(mapping);
-               if (retval == 0)
-                       retval = nfs_wb_all(inode);
-               if (retval == 0)
-                       retval = filemap_fdatawait(mapping);
-               if (retval)
-                       goto out;
-       }
+       retval = nfs_sync_mapping(mapping);
+       if (retval)
+               goto out;
 
        retval = nfs_direct_write(inode, ctx, &iov, pos, 1);
        if (mapping->nrpages)
 
         * 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
         * 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();
         * 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);
 
        return 0;
 }
 
+/**
+ * nfs_sync_mapping - helper to flush all mmapped dirty data to disk
+ */
+int nfs_sync_mapping(struct address_space *mapping)
+{
+       int ret;
+
+       if (mapping->nrpages == 0)
+               return 0;
+       unmap_mapping_range(mapping, 0, 0, 0);
+       ret = filemap_fdatawrite(mapping);
+       if (ret != 0)
+               goto out;
+       ret = filemap_fdatawait(mapping);
+       if (ret != 0)
+               goto out;
+       ret = nfs_wb_all(mapping->host);
+out:
+       return ret;
+}
+
 /*
  * Invalidate the local caches
  */
        struct nfs_inode *nfsi = NFS_I(inode);
 
        if (nfsi->cache_validity & NFS_INO_INVALID_DATA) {
-               if (S_ISREG(inode->i_mode)) {
-                       if (filemap_fdatawrite(mapping) == 0)
-                               filemap_fdatawait(mapping);
-                       nfs_wb_all(inode);
-               }
+               if (S_ISREG(inode->i_mode))
+                       nfs_sync_mapping(mapping);
                invalidate_inode_pages2(mapping);
 
                spin_lock(&inode->i_lock);
 
 /*
  * linux/fs/nfs/inode.c
  */
+extern int nfs_sync_mapping(struct address_space *mapping);
 extern void nfs_zap_caches(struct inode *);
 extern struct inode *nfs_fhget(struct super_block *, struct nfs_fh *,
                                struct nfs_fattr *);