• M
    ext4: fix delalloc i_disksize early update issue · 632eaeab
    Mingming Cao 提交于
    Ext4_da_write_end() used walk_page_buffers() with a callback function of
    ext4_bh_unmapped_or_delay() to check if it extended the file size
    without allocating any blocks (since in this case i_disksize needs to be
    updated).  However, this is didn't work proprely because the buffer head
    has not been marked dirty yet --- this is done later in
    block_commit_write() --- which caused ext4_bh_unmapped_or_delay() to
    always return false.
    
    In addition, walk_page_buffers() checks all of the buffer heads covering
    the page, and the only buffer_head that should be checked is the one
    covering the end of the write.  Otherwise, given a 1k blocksize
    filesystem and a 4k page size, the buffer head covering the first 1k
    stripe of the file could be unmapped (because it was a sparse file), and
    the second or third buffer_head covering that page could be mapped, and
    using walk_page_buffers() would fail in this case since it would stop at
    the first unmapped buffer_head and return true.
    
    The core problem is that walk_page_buffers() was intended to do work in
    a callback function, and a non-zero return value indicated a failure,
    which termined the walk of the buffer heads covering the page.  It was
    not intended to be used with a boolean function, such as
    ext4_bh_unmapped_or_delay().
    
    Add addtional fix from Aneesh to protect i_disksize update rave with truncate.
    Signed-off-by: NMingming Cao <cmm@us.ibm.com>
    Signed-off-by: NAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
    Signed-off-by: N"Theodore Ts'o" <tytso@mit.edu>
    632eaeab
inode.c 130.7 KB