aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2014-04-14 04:15:11 -0400
committerDave Chinner <david@fromorbit.com>2014-04-14 04:15:11 -0400
commit897b73b6a2ee5d3c06648b601beb1724f7fbd678 (patch)
treeff158ae7a438e38ee856eb8fd213350a052ffd45 /fs
parentaad3f3755e7f043789b772856d1a2935f2b41a4b (diff)
xfs: zeroing space needs to punch delalloc blocks
When we are zeroing space andit is covered by a delalloc range, we need to punch the delalloc range out before we truncate the page cache. Failing to do so leaves and inconsistency between the page cache and the extent tree, which we later trip over when doing direct IO over the same range. Signed-off-by: Dave Chinner <dchinner@redhat.com> Tested-by: Brian Foster <bfoster@redhat.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Dave Chinner <david@fromorbit.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/xfs/xfs_bmap_util.c13
-rw-r--r--fs/xfs/xfs_trace.h1
2 files changed, 13 insertions, 1 deletions
diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c
index 01f6a646caa1..296160b8e78c 100644
--- a/fs/xfs/xfs_bmap_util.c
+++ b/fs/xfs/xfs_bmap_util.c
@@ -1418,6 +1418,8 @@ xfs_zero_file_space(
1418 xfs_off_t end_boundary; 1418 xfs_off_t end_boundary;
1419 int error; 1419 int error;
1420 1420
1421 trace_xfs_zero_file_space(ip);
1422
1421 granularity = max_t(uint, 1 << mp->m_sb.sb_blocklog, PAGE_CACHE_SIZE); 1423 granularity = max_t(uint, 1 << mp->m_sb.sb_blocklog, PAGE_CACHE_SIZE);
1422 1424
1423 /* 1425 /*
@@ -1432,9 +1434,18 @@ xfs_zero_file_space(
1432 ASSERT(end_boundary <= offset + len); 1434 ASSERT(end_boundary <= offset + len);
1433 1435
1434 if (start_boundary < end_boundary - 1) { 1436 if (start_boundary < end_boundary - 1) {
1435 /* punch out the page cache over the conversion range */ 1437 /*
1438 * punch out delayed allocation blocks and the page cache over
1439 * the conversion range
1440 */
1441 xfs_ilock(ip, XFS_ILOCK_EXCL);
1442 error = xfs_bmap_punch_delalloc_range(ip,
1443 XFS_B_TO_FSBT(mp, start_boundary),
1444 XFS_B_TO_FSB(mp, end_boundary - start_boundary));
1445 xfs_iunlock(ip, XFS_ILOCK_EXCL);
1436 truncate_pagecache_range(VFS_I(ip), start_boundary, 1446 truncate_pagecache_range(VFS_I(ip), start_boundary,
1437 end_boundary - 1); 1447 end_boundary - 1);
1448
1438 /* convert the blocks */ 1449 /* convert the blocks */
1439 error = xfs_alloc_file_space(ip, start_boundary, 1450 error = xfs_alloc_file_space(ip, start_boundary,
1440 end_boundary - start_boundary - 1, 1451 end_boundary - start_boundary - 1,
diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h
index a4ae41c179a8..65d8c793a25c 100644
--- a/fs/xfs/xfs_trace.h
+++ b/fs/xfs/xfs_trace.h
@@ -603,6 +603,7 @@ DEFINE_INODE_EVENT(xfs_readlink);
603DEFINE_INODE_EVENT(xfs_inactive_symlink); 603DEFINE_INODE_EVENT(xfs_inactive_symlink);
604DEFINE_INODE_EVENT(xfs_alloc_file_space); 604DEFINE_INODE_EVENT(xfs_alloc_file_space);
605DEFINE_INODE_EVENT(xfs_free_file_space); 605DEFINE_INODE_EVENT(xfs_free_file_space);
606DEFINE_INODE_EVENT(xfs_zero_file_space);
606DEFINE_INODE_EVENT(xfs_collapse_file_space); 607DEFINE_INODE_EVENT(xfs_collapse_file_space);
607DEFINE_INODE_EVENT(xfs_readdir); 608DEFINE_INODE_EVENT(xfs_readdir);
608#ifdef CONFIG_XFS_POSIX_ACL 609#ifdef CONFIG_XFS_POSIX_ACL