• Lukas Czerner's avatar
    ext4: fix data corruption caused by unaligned direct AIO · c37b79ce
    Lukas Czerner authored
    BugLink: https://bugs.launchpad.net/bugs/1826212
    
    commit 372a03e0 upstream.
    
    Ext4 needs to serialize unaligned direct AIO because the zeroing of
    partial blocks of two competing unaligned AIOs can result in data
    corruption.
    
    However it decides not to serialize if the potentially unaligned aio is
    past i_size with the rationale that no pending writes are possible past
    i_size. Unfortunately if the i_size is not block aligned and the second
    unaligned write lands past i_size, but still into the same block, it has
    the potential of corrupting the previous unaligned write to the same
    block.
    
    This is (very simplified) reproducer from Frank
    
        // 41472 = (10 * 4096) + 512
        // 37376 = 41472 - 4096
    
        ftruncate(fd, 41472);
        io_prep_pwrite(iocbs[0], fd, buf[0], 4096, 37376);
        io_prep_pwrite(iocbs[1], fd, buf[1], 4096, 41472);
    
        io_submit(io_ctx, 1, &iocbs[1]);
        io_submit(io_ctx, 1, &iocbs[2]);
    
        io_getevents(io_ctx, 2, 2, events, NULL);
    
    Without this patch the 512B range from 40960 up to the start of the
    second unaligned write (41472) is going to be zeroed overwriting the data
    written by the first write. This is a data corruption.
    
    00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00
    *
    00009200  30 30 30 30 30 30 30 30  30 30 30 30 30 30 30 30
    *
    0000a000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00
    *
    0000a200  31 31 31 31 31 31 31 31  31 31 31 31 31 31 31 31
    
    With this patch the data corruption is avoided because we will recognize
    the unaligned_aio and wait for the unwritten extent conversion.
    
    00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00
    *
    00009200  30 30 30 30 30 30 30 30  30 30 30 30 30 30 30 30
    *
    0000a200  31 31 31 31 31 31 31 31  31 31 31 31 31 31 31 31
    *
    0000b200
    Reported-by: default avatarFrank Sorenson <fsorenso@redhat.com>
    Signed-off-by: default avatarLukas Czerner <lczerner@redhat.com>
    Signed-off-by: default avatarTheodore Ts'o <tytso@mit.edu>
    Fixes: e9e3bcec ("ext4: serialize unaligned asynchronous DIO")
    Cc: stable@vger.kernel.org
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    Signed-off-by: default avatarStefan Bader <stefan.bader@canonical.com>
    Signed-off-by: default avatarKleber Sacilotto de Souza <kleber.souza@canonical.com>
    c37b79ce
file.c 18.4 KB