• Dave Chinner's avatar
    xfs: don't map ranges that span EOF for direct IO · 0e1f789d
    Dave Chinner authored
    Al Viro tracked down the problem that has caused generic/263 to fail
    on XFS since the test was introduced. If is caused by
    xfs_get_blocks() mapping a single extent that spans EOF without
    marking it as buffer-new() so that the direct IO code does not zero
    the tail of the block at the new EOF. This is a long standing bug
    that has been around for many, many years.
    
    Because xfs_get_blocks() starts the map before EOF, it can't set
    buffer_new(), because that causes he direct IO code to also zero
    unaligned sectors at the head of the IO. This would overwrite valid
    data with zeros, and hence we cannot validly return a single extent
    that spans EOF to direct IO.
    
    Fix this by detecting a mapping that spans EOF and truncate it down
    to EOF. This results in the the direct IO code doing the right thing
    for unaligned data blocks before EOF, and then returning to get
    another mapping for the region beyond EOF which XFS treats correctly
    by setting buffer_new() on it. This makes direct Io behave correctly
    w.r.t. tail block zeroing beyond EOF, and fsx is happy about that.
    
    Again, thanks to Al Viro for finding what I couldn't.
    
    [ dchinner: Fix for __divdi3 build error:
    Reported-by: default avatarPaul Gortmaker <paul.gortmaker@windriver.com>
    Tested-by: default avatarPaul Gortmaker <paul.gortmaker@windriver.com>
    Signed-off-by: default avatarMark Tinguely <tinguely@sgi.com>
    Reviewed-by: default avatarEric Sandeen <sandeen@redhat.com>
    ]
    Signed-off-by: default avatarDave Chinner <dchinner@redhat.com>
    Tested-by: default avatarBrian Foster <bfoster@redhat.com>
    Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
    Signed-off-by: default avatarDave Chinner <david@fromorbit.com>
    0e1f789d
xfs_aops.c 45 KB