• Jan Kara's avatar
    ext4: Fix occasional generic/418 failure · 5899593f
    Jan Kara authored
    Eric has noticed that after pagecache read rework, generic/418 is
    occasionally failing for ext4 when blocksize < pagesize. In fact, the
    pagecache rework just made hard to hit race in ext4 more likely. The
    problem is that since ext4 conversion of direct IO writes to iomap
    framework (commit 378f32ba), we update inode size after direct IO
    write only after invalidating page cache. Thus if buffered read sneaks
    at unfortunate moment like:
    
    CPU1 - write at offset 1k                       CPU2 - read from offset 0
    iomap_dio_rw(..., IOMAP_DIO_FORCE_WAIT);
                                                    ext4_readpage();
    ext4_handle_inode_extension()
    
    the read will zero out tail of the page as it still sees smaller inode
    size and thus page cache becomes inconsistent with on-disk contents with
    all the consequences.
    
    Fix the problem by moving inode size update into end_io handler which
    gets called before the page cache is invalidated.
    Reported-and-tested-by: default avatarEric Whitney <enwlinux@gmail.com>
    Fixes: 378f32ba ("ext4: introduce direct I/O write using iomap infrastructure")
    CC: stable@vger.kernel.org
    Signed-off-by: default avatarJan Kara <jack@suse.cz>
    Acked-by: default avatarDave Chinner <dchinner@redhat.com>
    Link: https://lore.kernel.org/r/20210415155417.4734-1-jack@suse.czSigned-off-by: default avatarTheodore Ts'o <tytso@mit.edu>
    5899593f
file.c 23.8 KB