diff options
Diffstat (limited to 'fs/xfs/xfs_dfrag.c')
| -rw-r--r-- | fs/xfs/xfs_dfrag.c | 13 | 
1 files changed, 13 insertions, 0 deletions
diff --git a/fs/xfs/xfs_dfrag.c b/fs/xfs/xfs_dfrag.c index 3b9582c60a2..e60490bc00a 100644 --- a/fs/xfs/xfs_dfrag.c +++ b/fs/xfs/xfs_dfrag.c @@ -377,6 +377,19 @@ xfs_swap_extents(  	ip->i_d.di_format = tip->i_d.di_format;  	tip->i_d.di_format = tmp; +	/* +	 * The extents in the source inode could still contain speculative +	 * preallocation beyond EOF (e.g. the file is open but not modified +	 * while defrag is in progress). In that case, we need to copy over the +	 * number of delalloc blocks the data fork in the source inode is +	 * tracking beyond EOF so that when the fork is truncated away when the +	 * temporary inode is unlinked we don't underrun the i_delayed_blks +	 * counter on that inode. +	 */ +	ASSERT(tip->i_delayed_blks == 0); +	tip->i_delayed_blks = ip->i_delayed_blks; +	ip->i_delayed_blks = 0; +  	ilf_fields = XFS_ILOG_CORE;  	switch(ip->i_d.di_format) {  |