• Qu Wenruo's avatar
    btrfs: fix the filemap_range_has_page() call in btrfs_punch_hole_lock_range() · 0528476b
    Qu Wenruo authored
    [BUG]
    With current subpage RW support, the following script can hang the fs
    with 64K page size.
    
     # mkfs.btrfs -f -s 4k $dev
     # mount $dev -o nospace_cache $mnt
     # fsstress -w -n 50 -p 1 -s 1607749395 -d $mnt
    
    The kernel will do an infinite loop in btrfs_punch_hole_lock_range().
    
    [CAUSE]
    In btrfs_punch_hole_lock_range() we:
    
    - Truncate page cache range
    - Lock extent io tree
    - Wait any ordered extents in the range.
    
    We exit the loop until we meet all the following conditions:
    
    - No ordered extent in the lock range
    - No page is in the lock range
    
    The latter condition has a pitfall, it only works for sector size ==
    PAGE_SIZE case.
    
    While can't handle the following subpage case:
    
      0       32K     64K     96K     128K
      |       |///////||//////|       ||
    
    lockstart=32K
    lockend=96K - 1
    
    In this case, although the range crosses 2 pages,
    truncate_pagecache_range() will invalidate no page at all, but only zero
    the [32K, 96K) range of the two pages.
    
    Thus filemap_range_has_page(32K, 96K-1) will always return true, thus we
    will never meet the loop exit condition.
    
    [FIX]
    Fix the problem by doing page alignment for the lock range.
    
    Function filemap_range_has_page() has already handled lend < lstart
    case, we only need to round up @lockstart, and round_down @lockend for
    truncate_pagecache_range().
    
    This modification should not change any thing for sector size ==
    PAGE_SIZE case, as in that case our range is already page aligned.
    
    Tested-by: Ritesh Harjani <riteshh@linux.ibm.com> # [ppc64]
    Tested-by: Anand Jain <anand.jain@oracle.com> # [aarch64]
    Signed-off-by: default avatarQu Wenruo <wqu@suse.com>
    Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
    Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
    0528476b
file.c 99.2 KB