[Devel] [PATCH rh7 1/2] ms/ext4: Avoid freeing inodes on dirty list
Konstantin Khorenko
khorenko at virtuozzo.com
Wed Feb 3 18:40:52 MSK 2021
Oops, disregard this one,
wrong patch sent.
--
Best regards,
Konstantin Khorenko,
Virtuozzo Linux Kernel Team
On 02/03/2021 06:37 PM, Konstantin Khorenko wrote:
> From: Jan Kara <jack at suse.cz>
>
> 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 at suse.cz>
> Link: https://lore.kernel.org/r/20200421085445.5731-4-jack@suse.cz
> Signed-off-by: Theodore Ts'o <tytso at mit.edu>
>
> (cherry picked from commit ceff86fddae8748fe00d4f2d249cb02cae62ad84)
> Signed-off-by: Konstantin Khorenko <khorenko at virtuozzo.com>
> ---
> fs/ext4/inode.c | 10 ++++++++++
> 1 file changed, 10 insertions(+)
>
> diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
> index f89fdb951aee..1c8e0cb64116 100644
> --- a/fs/ext4/inode.c
> +++ b/fs/ext4/inode.c
> @@ -232,6 +232,16 @@ void ext4_evict_inode(struct inode *inode)
> ext4_begin_ordered_truncate(inode, 0);
> truncate_inode_pages_final(&inode->i_data);
>
> + /*
> + * For inodes with journalled data, transaction commit could have
> + * dirtied the inode. Flush worker is ignoring it because of I_FREEING
> + * flag but we still need to remove the inode from the writeback lists.
> + */
> + if (!list_empty_careful(&inode->i_io_list)) {
> + WARN_ON_ONCE(!ext4_should_journal_data(inode));
> + inode_io_list_del(inode);
> + }
> +
> /*
> * Protect us against freezing - iput() caller didn't have to have any
> * protection against it
>
More information about the Devel
mailing list