• Eric Sandeen's avatar
    ext4: serialize unaligned asynchronous DIO · e9e3bcec
    Eric Sandeen authored
    ext4 has a data corruption case when doing non-block-aligned
    asynchronous direct IO into a sparse file, as demonstrated
    by xfstest 240.
    
    The root cause is that while ext4 preallocates space in the
    hole, mappings of that space still look "new" and 
    dio_zero_block() will zero out the unwritten portions.  When
    more than one AIO thread is going, they both find this "new"
    block and race to zero out their portion; this is uncoordinated
    and causes data corruption.
    
    Dave Chinner fixed this for xfs by simply serializing all
    unaligned asynchronous direct IO.  I've done the same here.
    The difference is that we only wait on conversions, not all IO.
    This is a very big hammer, and I'm not very pleased with
    stuffing this into ext4_file_write().  But since ext4 is
    DIO_LOCKING, we need to serialize it at this high level.
    
    I tried to move this into ext4_ext_direct_IO, but by then
    we have the i_mutex already, and we will wait on the
    work queue to do conversions - which must also take the
    i_mutex.  So that won't work.
    
    This was originally exposed by qemu-kvm installing to
    a raw disk image with a normal sector-63 alignment.  I've
    tested a backport of this patch with qemu, and it does
    avoid the corruption.  It is also quite a lot slower
    (14 min for package installs, vs. 8 min for well-aligned)
    but I'll take slow correctness over fast corruption any day.
    
    Mingming suggested that we can track outstanding
    conversions, and wait on those so that non-sparse
    files won't be affected, and I've implemented that here;
    unaligned AIO to nonsparse files won't take a perf hit.
    
    [tytso@mit.edu: Keep the mutex as a hashed array instead
     of bloating the ext4 inode]
    
    [tytso@mit.edu: Fix up namespace issues so that global
     variables are protected with an "ext4_" prefix.]
    Signed-off-by: default avatarEric Sandeen <sandeen@redhat.com>
    Signed-off-by: default avatar"Theodore Ts'o" <tytso@mit.edu>
    e9e3bcec
ext4.h 73.5 KB