• Jan Kara's avatar
    jbd: Fix a race between checkpointing code and journal_get_write_access() · 1e9fd53b
    Jan Kara authored
    The following race can happen:
    
      CPU1                          CPU2
                                    checkpointing code checks the buffer, adds
                                      it to an array for writeback
    do_get_write_access()
      ...
      lock_buffer()
      unlock_buffer()
                                      flush_batch() submits the buffer for IO
      __jbd_journal_file_buffer()
    
      So a buffer under writeout is returned from do_get_write_access(). Since
    the filesystem code relies on the fact that journaled buffers cannot be
    written out, it does not take the buffer lock and so it can modify buffer
    while it is under writeout. That can lead to a filesystem corruption
    if we crash at the right moment. The similar problem can happen with
    the journal_get_create_access() path.
      We fix the problem by clearing the buffer dirty bit under buffer_lock
    even if the buffer is on BJ_None list. Actually, we clear the dirty bit
    regardless the list the buffer is in and warn about the fact if
    the buffer is already journalled.
    
    Thanks for spotting the problem goes to dingdinghua <dingdinghua85@gmail.com>.
    Reported-by: default avatardingdinghua <dingdinghua85@gmail.com>
    Signed-off-by: default avatarJan Kara <jack@suse.cz>
    1e9fd53b
transaction.c 63.9 KB