• Aneesh Kumar K.V's avatar
    ext4: Fix mmap/truncate race when blocksize < pagesize && delayed allocation · c364b22c
    Aneesh Kumar K.V authored
    It is possible to see buffer_heads which are not mapped in the
    writepage callback in the following scneario (where the fs blocksize
    is 1k and the page size is 4k):
    
    1) truncate(f, 1024)
    2) mmap(f, 0, 4096)
    3) a[0] = 'a'
    4) truncate(f, 4096)
    5) writepage(...)
    
    Now if we get a writepage callback immediately after (4) and before an
    attempt to write at any other offset via mmap address (which implies we
    are yet to get a pagefault and do a get_block) what we would have is the
    page which is dirty have first block allocated and the other three
    buffer_heads unmapped.
    
    In the above case the writepage should go ahead and try to write the
    first blocks and clear the page_dirty flag. Further attempts to write
    to the page will again create a fault and result in allocating blocks
    and marking page dirty.  If we don't write any other offset via mmap
    address we would still have written the first block to the disk and
    rest of the space will be considered as a hole.
    
    So to address this, we change all of the places where we look for
    delayed, unmapped, or unwritten buffer heads, and only check for
    delayed or unwritten buffer heads instead.
    Signed-off-by: default avatarAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
    Acked-by: default avatarJan Kara <jack@suse.cz>
    Signed-off-by: default avatar"Theodore Ts'o" <tytso@mit.edu>
    c364b22c
inode.c 157 KB