]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - fs/nfs/nfs4file.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
[karo-tx-linux.git] / fs / nfs / nfs4file.c
index eb5eb8eef4d34db3c7bafe3c84c1db0bf43e8974..afddd6639afb1bd5242e95c5b659fa2b86174181 100644 (file)
@@ -95,16 +95,25 @@ nfs4_file_fsync(struct file *file, loff_t start, loff_t end, int datasync)
        int ret;
        struct inode *inode = file->f_path.dentry->d_inode;
 
-       ret = filemap_write_and_wait_range(inode->i_mapping, start, end);
-       if (ret != 0)
-               goto out;
-       mutex_lock(&inode->i_mutex);
-       ret = nfs_file_fsync_commit(file, start, end, datasync);
-       if (!ret && !datasync)
-               /* application has asked for meta-data sync */
-               ret = pnfs_layoutcommit_inode(inode, true);
-       mutex_unlock(&inode->i_mutex);
-out:
+       do {
+               ret = filemap_write_and_wait_range(inode->i_mapping, start, end);
+               if (ret != 0)
+                       break;
+               mutex_lock(&inode->i_mutex);
+               ret = nfs_file_fsync_commit(file, start, end, datasync);
+               if (!ret && !datasync)
+                       /* application has asked for meta-data sync */
+                       ret = pnfs_layoutcommit_inode(inode, true);
+               mutex_unlock(&inode->i_mutex);
+               /*
+                * If nfs_file_fsync_commit detected a server reboot, then
+                * resend all dirty pages that might have been covered by
+                * the NFS_CONTEXT_RESEND_WRITES flag
+                */
+               start = 0;
+               end = LLONG_MAX;
+       } while (ret == -EAGAIN);
+
        return ret;
 }