diff options
Diffstat (limited to 'fs/nfs/nfs4file.c')
| -rw-r--r-- | fs/nfs/nfs4file.c | 29 | 
1 files changed, 19 insertions, 10 deletions
diff --git a/fs/nfs/nfs4file.c b/fs/nfs/nfs4file.c index eb5eb8eef4d..afddd6639af 100644 --- a/fs/nfs/nfs4file.c +++ b/fs/nfs/nfs4file.c @@ -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;  }  |