]> git.baikalelectronics.ru Git - kernel.git/commit
ext4: Avoid freeing inodes on dirty list
authorJan Kara <jack@suse.cz>
Tue, 21 Apr 2020 08:54:45 +0000 (10:54 +0200)
committerTheodore Ts'o <tytso@mit.edu>
Thu, 4 Jun 2020 03:16:49 +0000 (23:16 -0400)
commitd3f8507965c5fcd6b51f15ae6bf2185020279843
treea1e650ad7d90a72bbe0363076f715b188463989b
parentdeaa1278342328dd20c68fa2ec6df5bf89489cf1
ext4: Avoid freeing inodes on dirty list

When we are evicting inode with journalled data, we may race with
transaction commit in the following way:

CPU0 CPU1
jbd2_journal_commit_transaction() evict(inode)
  inode_io_list_del()
  inode_wait_for_writeback()
  process BJ_Forget list
    __jbd2_journal_insert_checkpoint()
    __jbd2_journal_refile_buffer()
      __jbd2_journal_unfile_buffer()
        if (test_clear_buffer_jbddirty(bh))
          mark_buffer_dirty(bh)
    __mark_inode_dirty(inode)
  ext4_evict_inode(inode)
    frees the inode

This results in use-after-free issues in the writeback code (or
the assertion added in the previous commit triggering).

Fix the problem by removing inode from writeback lists once all the page
cache is evicted and so inode cannot be added to writeback lists again.

Signed-off-by: Jan Kara <jack@suse.cz>
Link: https://lore.kernel.org/r/20200421085445.5731-4-jack@suse.cz
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
fs/ext4/inode.c