• Jan Kara's avatar
    jbd: Issue cache flush after checkpointing · fde1c262
    Jan Kara authored
    commit 353b67d8 upstream.
    
    When we reach cleanup_journal_tail(), there is no guarantee that
    checkpointed buffers are on a stable storage - especially if buffers were
    written out by log_do_checkpoint(), they are likely to be only in disk's
    caches. Thus when we update journal superblock, effectively removing old
    transaction from journal, this write of superblock can get to stable storage
    before those checkpointed buffers which can result in filesystem corruption
    after a crash.
    
    A similar problem can happen if we replay the journal and wipe it before
    flushing disk's caches.
    
    Thus we must unconditionally issue a cache flush before we update journal
    superblock in these cases. The fix is slightly complicated by the fact that we
    have to get log tail before we issue cache flush but we can store it in the
    journal superblock only after the cache flush. Otherwise we risk races where
    new tail is written before appropriate cache flush is finished.
    
    I managed to reproduce the corruption using somewhat tweaked Chris Mason's
    barrier-test scheduler. Also this should fix occasional reports of 'Bit already
    freed' filesystem errors which are totally unreproducible but inspection of
    several fs images I've gathered over time points to a problem like this.
    Signed-off-by: default avatarJan Kara <jack@suse.cz>
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    fde1c262
recovery.c 14.4 KB