• Q
    btrfs: Use right extent length when inserting overlap extent map. · 51f395ad
    Qu Wenruo 提交于
    When current btrfs finds that a new extent map is going to be insereted
    but failed with -EEXIST, it will try again to insert the extent map
    but with the length of sectorsize.
    This is OK if we don't enable 'no-holes' feature since all extent space
    is continuous, we will not go into the not found->insert routine.
    
    But if we enable 'no-holes' feature, it will make things out of control.
    e.g. in 4K sectorsize, we pass the following args to btrfs_get_extent():
    btrfs_get_extent() args: start:  27874 len 4100
    28672		  27874		28672	27874+4100	32768
                        |-----------------------|
    |---------hole--------------------|---------data----------|
    
    1) not found and insert
    Since no extent map containing the range, btrfs_get_extent() will go
    into the not_found and insert routine, which will try to insert the
    extent map (27874, 27847 + 4100).
    
    2) first overlap
    But it overlaps with (28672, 32768) extent, so -EEXIST will be returned
    by add_extent_mapping().
    
    3) retry but still overlap
    After catching the -EEXIST, then btrfs_get_extent() will try insert it
    again but with 4K length, which still overlaps, so -EEXIST will be
    returned.
    
    This makes the following patch fail to punch hole.
    d7781546 btrfs: Avoid trucating page or punching hole in a already existed hole.
    
    This patch will use the right length, which is the (exsisting->start -
    em->start) to insert, making the above patch works in 'no-holes' mode.
    Also, some small code style problems in above patch is fixed too.
    Reported-by: NFilipe David Manana <fdmanana@gmail.com>
    Signed-off-by: NQu Wenruo <quwenruo@cn.fujitsu.com>
    Reviewed-by: NFilipe David Manana <fdmanana@suse.com>
    Tested-by: NFilipe David Manana <fdmanana@suse.com>
    Signed-off-by: NChris Mason <clm@fb.com>
    51f395ad
inode.c 241.4 KB