Skip to content
  • Lukas Czerner's avatar
    ext4: rewrite punch hole to use ext4_ext_remove_space() · 5f95d21f
    Lukas Czerner authored
    
    
    This commit rewrites ext4 punch hole implementation to use
    ext4_ext_remove_space() instead of its home gown way of doing this via
    ext4_ext_map_blocks(). There are several reasons for changing this.
    
    Firstly it is quite non obvious that punching hole needs to
    ext4_ext_map_blocks() to punch a hole, especially given that this
    function should map blocks, not unmap it. It also required a lot of new
    code in ext4_ext_map_blocks().
    
    Secondly the design of it is not very effective. The reason is that we
    are trying to punch out blocks in ext4_ext_punch_hole() in opposite
    direction than in ext4_ext_rm_leaf() which causes the ext4_ext_rm_leaf()
    to iterate through the whole tree from the end to the start to find the
    requested extent for every extent we are going to punch out.
    
    And finally the current implementation does not use the existing code,
    but bring a lot of new code, which is IMO unnecessary since there
    already is some infrastructure we can use. Specifically
    ext4_ext_remove_space().
    
    This commit changes ext4_ext_remove_space() to accept 'end' parameter so
    we can not only truncate to the end of file, but also remove the space
    in the middle of the file (punch a hole). Moreover, because the last
    block to punch out, might be in the middle of the extent, we have to
    split the extent at 'end + 1' so ext4_ext_rm_leaf() can easily either
    remove the whole fist part of split extent, or change its size.
    
    ext4_ext_remove_space() is then used to actually remove the space
    (extents) from within the hole, instead of ext4_ext_map_blocks().
    
    Note that this also fix the issue with punch hole, where we would forget
    to remove empty index blocks from the extent tree, resulting in double
    free block error and file system corruption. This is simply because we
    now use different code path, where this problem does not exist.
    
    This has been tested with fsx running for several days and xfstests,
    plus xfstest #251 with '-o discard' run on the loop image (which
    converts discard requestes into punch hole to the backing file). All of
    it on 1K and 4K file system block size.
    
    Signed-off-by: default avatarLukas Czerner <lczerner@redhat.com>
    Signed-off-by: default avatar"Theodore Ts'o" <tytso@mit.edu>
    5f95d21f