diff options
Diffstat (limited to 'fs/btrfs/file.c')
| -rw-r--r-- | fs/btrfs/file.c | 17 | 
1 files changed, 12 insertions, 5 deletions
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index d3afac292d67..36861b7a6757 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -1840,7 +1840,15 @@ int btrfs_release_file(struct inode *inode, struct file *filp)  {  	if (filp->private_data)  		btrfs_ioctl_trans_end(filp); -	filemap_flush(inode->i_mapping); +	/* +	 * ordered_data_close is set by settattr when we are about to truncate +	 * a file from a non-zero size to a zero size.  This tries to +	 * flush down new bytes that may have been written if the +	 * application were using truncate to replace a file in place. +	 */ +	if (test_and_clear_bit(BTRFS_INODE_ORDERED_DATA_CLOSE, +			       &BTRFS_I(inode)->runtime_flags)) +			filemap_flush(inode->i_mapping);  	return 0;  } @@ -2088,10 +2096,9 @@ static int fill_holes(struct btrfs_trans_handle *trans, struct inode *inode,  		goto out;  	} -	if (hole_mergeable(inode, leaf, path->slots[0]+1, offset, end)) { +	if (hole_mergeable(inode, leaf, path->slots[0], offset, end)) {  		u64 num_bytes; -		path->slots[0]++;  		key.offset = offset;  		btrfs_set_item_key_safe(root, path, &key);  		fi = btrfs_item_ptr(leaf, path->slots[0], @@ -2216,7 +2223,7 @@ static int btrfs_punch_hole(struct inode *inode, loff_t offset, loff_t len)  		goto out_only_mutex;  	} -	lockstart = round_up(offset , BTRFS_I(inode)->root->sectorsize); +	lockstart = round_up(offset, BTRFS_I(inode)->root->sectorsize);  	lockend = round_down(offset + len,  			     BTRFS_I(inode)->root->sectorsize) - 1;  	same_page = ((offset >> PAGE_CACHE_SHIFT) == @@ -2277,7 +2284,7 @@ static int btrfs_punch_hole(struct inode *inode, loff_t offset, loff_t len)  						tail_start + tail_len, 0, 1);  				if (ret)  					goto out_only_mutex; -				} +			}  		}  	}  | 
