xfs
[Top] [All Lists]

[PATCH 4/6] xfs: zeroing space needs to punch delalloc blocks

To: xfs@xxxxxxxxxxx
Subject: [PATCH 4/6] xfs: zeroing space needs to punch delalloc blocks
From: Dave Chinner <david@xxxxxxxxxxxxx>
Date: Fri, 21 Mar 2014 21:11:48 +1100
Cc: Al@xxxxxxxxxxxxxxxxxxxxxxx, Viro@xxxxxxxxxxxxxxxxxxxxxxx, <viro@xxxxxxxxxxxxxxxxxx>
Delivered-to: xfs@xxxxxxxxxxx
In-reply-to: <1395396710-3824-1-git-send-email-david@xxxxxxxxxxxxx>
References: <1395396710-3824-1-git-send-email-david@xxxxxxxxxxxxx>
From: Dave Chinner <dchinner@xxxxxxxxxx>

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@xxxxxxxxxx>
---
 fs/xfs/xfs_bmap_util.c | 13 ++++++++++++-
 fs/xfs/xfs_trace.h     |  1 +
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c
index 01f6a64..3235b74 100644
--- a/fs/xfs/xfs_bmap_util.c
+++ b/fs/xfs/xfs_bmap_util.c
@@ -1418,6 +1418,8 @@ xfs_zero_file_space(
        xfs_off_t               end_boundary;
        int                     error;
 
+       trace_xfs_zero_file_space(ip);
+
        granularity = max_t(uint, 1 << mp->m_sb.sb_blocklog, PAGE_CACHE_SIZE);
 
        /*
@@ -1432,9 +1434,18 @@ xfs_zero_file_space(
        ASSERT(end_boundary <= offset + len);
 
        if (start_boundary < end_boundary - 1) {
-               /* punch out the page cache over the conversion range */
+               /*
+                * punch out delayed allocation blocks and the page cache over
+                * the conversion range
+                */
+               xfs_ilock(ip, XFS_ILOCK_EXCL);
+               error = xfs_bmap_punch_delalloc_range(ip,
+                               XFS_B_TO_FSB(mp, start_boundary),
+                               XFS_B_TO_FSB(mp, end_boundary - 
start_boundary));
+               xfs_iunlock(ip, XFS_ILOCK_EXCL);
                truncate_pagecache_range(VFS_I(ip), start_boundary,
                                         end_boundary - 1);
+
                /* convert the blocks */
                error = xfs_alloc_file_space(ip, start_boundary,
                                        end_boundary - start_boundary - 1,
diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h
index a4ae41c..65d8c79 100644
--- a/fs/xfs/xfs_trace.h
+++ b/fs/xfs/xfs_trace.h
@@ -603,6 +603,7 @@ DEFINE_INODE_EVENT(xfs_readlink);
 DEFINE_INODE_EVENT(xfs_inactive_symlink);
 DEFINE_INODE_EVENT(xfs_alloc_file_space);
 DEFINE_INODE_EVENT(xfs_free_file_space);
+DEFINE_INODE_EVENT(xfs_zero_file_space);
 DEFINE_INODE_EVENT(xfs_collapse_file_space);
 DEFINE_INODE_EVENT(xfs_readdir);
 #ifdef CONFIG_XFS_POSIX_ACL
-- 
1.9.0

<Prev in Thread] Current Thread [Next in Thread>