• Linus Torvalds's avatar
    vfs: fix O_DIRECT read past end of block device · 684c9aae
    Linus Torvalds authored
    The direct-IO write path already had the i_size checks in mm/filemap.c,
    but it turns out the read path did not, and removing the block size
    checks in fs/block_dev.c (commit bbec0270: "blkdev_max_block: make
    private to fs/buffer.c") removed the magic "shrink IO to past the end of
    the device" code there.
    
    Fix it by truncating the IO to the size of the block device, like the
    write path already does.
    
    NOTE! I suspect the write path would be *much* better off doing it this
    way in fs/block_dev.c, rather than hidden deep in mm/filemap.c.  The
    mm/filemap.c code is extremely hard to follow, and has various
    conditionals on the target being a block device (ie the flag passed in
    to 'generic_write_checks()', along with a conditional update of the
    inode timestamp etc).
    
    It is also quite possible that we should treat this whole block device
    size as a "s_maxbytes" issue, and try to make the logic even more
    generic.  However, in the meantime this is the fairly minimal targeted
    fix.
    
    Noted by Milan Broz thanks to a regression test for the cryptsetup
    reencrypt tool.
    Reported-and-tested-by: default avatarMilan Broz <mbroz@redhat.com>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    684c9aae
block_dev.c 42 KB