• Gabriel Krisman Bertazi's avatar
    direct-io: defer alignment check until after the EOF check · 41b21af3
    Gabriel Krisman Bertazi authored
    Prior to commit 9fe55eea ("Fix race when checking i_size on direct
    i/o read"), an unaligned direct read past end of file would trigger EOF,
    since generic_file_aio_read detected this read-at-EOF condition and
    skipped the direct IO read entirely, returning 0. After that change, the
    read now reaches dio_generic, which detects the misalignment and returns
    EINVAL.
    
    This consolidates the generic direct-io to follow the same behavior of
    filesystems.  Apparently, this fix will only affect ocfs2 since other
    filesystems do this verification before calling do_blockdev_direct_IO,
    with the exception of f2fs, which has the same bug, but is fixed in the
    next patch.
    
    it can be verified by a read loop on a file that does a partial read
    before EOF (On file that doesn't end at an aligned address).  The
    following code fails on an unaligned file on filesystems without
    prior validation without this patch, but not on btrfs, ext4, and xfs.
    
      while (done < total) {
        ssize_t delta = pread(fd, buf + done, total - done, off + done);
        if (!delta)
          break;
        ...
      }
    
    Fix this regression by moving the misalignment check to after the EOF
    check added by commit 74cedf9b ("direct-io: Fix negative return from
    dio read beyond eof").
    
    Based on a patch by Jamie Liu.
    
    Link: https://lore.kernel.org/r/20201008062620.2928326-4-krisman@collabora.comReported-by: default avatarJamie Liu <jamieliu@google.com>
    Reviewed-by: default avatarJan Kara <jack@suse.cz>
    Reviewed-by: default avatarJens Axboe <axboe@kernel.dk>
    Signed-off-by: default avatarGabriel Krisman Bertazi <krisman@collabora.com>
    Signed-off-by: default avatarJan Kara <jack@suse.cz>
    41b21af3
direct-io.c 40 KB