• Robbie Ko's avatar
    Btrfs: fiemap: pass correct bytenr when fm_extent_count is zero · 9d311e11
    Robbie Ko authored
    [BUG]
    fm_mapped_extents is not correct when fm_extent_count is 0
    Like:
       # mount /dev/vdb5 /mnt/btrfs
       # dd if=/dev/zero bs=16K count=4 oflag=dsync of=/mnt/btrfs/file
       # xfs_io -c "fiemap -v" /mnt/btrfs/file
       /mnt/btrfs/file:
       EXT: FILE-OFFSET      BLOCK-RANGE      TOTAL FLAGS
         0: [0..127]:        25088..25215       128   0x1
    
    When user space wants to get the number of file extents,
    set fm_extent_count to 0 to run fiemap and then read fm_mapped_extents.
    
    In the above example, fiemap will return with fm_mapped_extents set to 4,
    but it should be 1 since there's only one entry in the output.
    
    [REASON]
    The problem seems to be that disko is only set if
    fieinfo->fi_extents_max is set. And this member is initialized, in the
    generic ioctl_fiemap function, to the value of used-passed
    fm_extent_count. So when the user passes 0 then fi_extent_max is also
    set to zero and this causes btrfs to not initialize disko at all.
    Eventually this leads emit_fiemap_extent being called with a bogus
    'phys' argument preventing proper fiemap entries merging.
    
    [FIX]
    Move the disko initialization earlier in extent_fiemap making it
    independent of user-passed arguments, allowing emit_fiemap_extent to
    properly handle consecutive extent entries.
    Signed-off-by: default avatarRobbie Ko <robbieko@synology.com>
    Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
    9d311e11
extent_io.c 150 KB