• D
    ext4: handle unwritten or delalloc buffers before enabling data journaling · 4c546592
    Daeho Jeong 提交于
    We already allocate delalloc blocks before changing the inode mode into
    "per-file data journal" mode to prevent delalloc blocks from remaining
    not allocated, but another issue concerned with "BH_Unwritten" status
    still exists. For example, by fallocate(), several buffers' status
    change into "BH_Unwritten", but these buffers cannot be processed by
    ext4_alloc_da_blocks(). So, they still remain in unwritten status after
    per-file data journaling is enabled and they cannot be changed into
    written status any more and, if they are journaled and eventually
    checkpointed, these unwritten buffer will cause a kernel panic by the
    below BUG_ON() function of submit_bh_wbc() when they are submitted
    during checkpointing.
    
    static int submit_bh_wbc(int rw, struct buffer_head *bh,...
    {
            ...
            BUG_ON(buffer_unwritten(bh));
    
    Moreover, when "dioread_nolock" option is enabled, the status of a
    buffer is changed into "BH_Unwritten" after write_begin() completes and
    the "BH_Unwritten" status will be cleared after I/O is done. Therefore,
    if a buffer's status is changed into unwrutten but the buffer's I/O is
    not submitted and completed, it can cause the same problem after
    enabling per-file data journaling. You can easily generate this bug by
    executing the following command.
    
    ./kvm-xfstests -C 10000 -m nodelalloc,dioread_nolock generic/269
    
    To resolve these problems and define a boundary between the previous
    mode and per-file data journaling mode, we need to flush and wait all
    the I/O of buffers of a file before enabling per-file data journaling
    of the file.
    Signed-off-by: NDaeho Jeong <daeho.jeong@samsung.com>
    Signed-off-by: NTheodore Ts'o <tytso@mit.edu>
    Reviewed-by: NJan Kara <jack@suse.cz>
    4c546592
inode.c 163.9 KB