diff options
Diffstat (limited to 'fs/btrfs/file.c')
| -rw-r--r-- | fs/btrfs/file.c | 15 | 
1 files changed, 15 insertions, 0 deletions
| diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 8a144f9cb7ac..719e68ab552c 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -2098,6 +2098,21 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)  	atomic_inc(&root->log_batch);  	/* +	 * If the inode needs a full sync, make sure we use a full range to +	 * avoid log tree corruption, due to hole detection racing with ordered +	 * extent completion for adjacent ranges and races between logging and +	 * completion of ordered extents for adjancent ranges - both races +	 * could lead to file extent items in the log with overlapping ranges. +	 * Do this while holding the inode lock, to avoid races with other +	 * tasks. +	 */ +	if (test_bit(BTRFS_INODE_NEEDS_FULL_SYNC, +		     &BTRFS_I(inode)->runtime_flags)) { +		start = 0; +		end = LLONG_MAX; +	} + +	/*  	 * Before we acquired the inode's lock, someone may have dirtied more  	 * pages in the target range. We need to make sure that writeback for  	 * any such pages does not start while we are logging the inode, because |