All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Theodore Ts'o" <tytso@mit.edu>
To: Murphy Zhou <jencce.kernel@gmail.com>
Cc: Jan Kara <jack@suse.cz>, linux-ext4@vger.kernel.org
Subject: Re: ext4 regression panic
Date: Thu, 21 Jan 2021 12:40:56 -0500	[thread overview]
Message-ID: <YAm8qH/0oo2ofSMR@mit.edu> (raw)
In-Reply-To: <20210121101547.fwh35hov3hshogbz@xzhoux.usersys.redhat.com>

On Thu, Jan 21, 2021 at 06:15:47PM +0800, Murphy Zhou wrote:
> Hi Jack,
> 
> A panic was introduced by this commit. It's easy and reliable to
> reproduce.
> 
> commit 2d01ddc86606564fb08c56e3bc93a0693895f710
> Author: Jan Kara <jack@suse.cz>
> Date:   Wed Dec 16 11:18:40 2020 +0100
> 
>     ext4: save error info to sb through journal if available

Hi Murphy,

Thanks for the bug report.  What's happening is that we haven't yet
initialized mballoc yet --- that happens in line 4943 of
fs/ext4/super.c, in ext4_fill_super().

But in line 4903 (in the case of the BZ #199275 reproducer), we
attempt to fetch the root inode, which is fails because it is
unallocated.  That then triggers a call to ext4_error(), which now
results in a journalled change, since the journal is initialized
starting in line 4793, and in line 4838, we set up the
j_commit_callback, which is what ends up calling
ext4_process_freed_data(), but since the multiblock allocator hasn't
been set up yet, that causes the NULL pointer dereference.

So what we need to do is to *not* set up the callback until after the
call to ext4_mb_init().

We should probably create an ext4-specific test in xfstests which
tries mounting a small, deliberately corrupted file system, to make
sure we handle this case correctly in the future.

						- Ted

commit 6c2f9a8247273cf1108ff71c99680b7457f48318
Author: Theodore Ts'o <tytso@mit.edu>
Date:   Thu Jan 21 12:33:20 2021 -0500

    ext4: don't try to processed freed blocks until mballoc is initialized
    
    If we try to make any changes via the journal between when the journal
    is initialized, but before the multi-block allocated is initialized,
    we will end up deferencing a NULL pointer when the journal commit
    callback function calls ext4_process_freed_data().
    
    The proximate cause of this failure was commit 2d01ddc86606 ("ext4:
    save error info to sb through journal if available") since file system
    corruption problems detected before the call to ext4_mb_init() would
    result in a journal commit before we aborted the mount of the file
    system.... and we would then trigger the NULL pointer deref.
    
    Cc: Jan Kara <jack@suse.cz>
    Reported by: Murphy Zhou <jencce.kernel@gmail.com>
    Signed-off-by: Theodore Ts'o <tytso@mit.edu>

diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 0f0db49031dc..802ef55f0a55 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -4876,7 +4876,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
 
 	set_task_ioprio(sbi->s_journal->j_task, journal_ioprio);
 
-	sbi->s_journal->j_commit_callback = ext4_journal_commit_callback;
 	sbi->s_journal->j_submit_inode_data_buffers =
 		ext4_journal_submit_inode_data_buffers;
 	sbi->s_journal->j_finish_inode_data_buffers =
@@ -4993,6 +4992,14 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
 		goto failed_mount5;
 	}
 
+	/*
+	 * We can only set up the journal commit callback once
+	 * mballoc is initialized
+	 */
+	if (sbi->s_journal)
+		sbi->s_journal->j_commit_callback =
+			ext4_journal_commit_callback;
+
 	block = ext4_count_free_clusters(sb);
 	ext4_free_blocks_count_set(sbi->s_es, 
 				   EXT4_C2B(sbi, block));

  reply	other threads:[~2021-01-21 17:44 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-01-21 10:15 ext4 regression panic Murphy Zhou
2021-01-21 17:40 ` Theodore Ts'o [this message]
2021-01-21 21:09   ` Jan Kara
2021-01-23  8:57     ` Murphy Zhou
2021-01-21 18:13 ` Jan Kara

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=YAm8qH/0oo2ofSMR@mit.edu \
    --to=tytso@mit.edu \
    --cc=jack@suse.cz \
    --cc=jencce.kernel@gmail.com \
    --cc=linux-ext4@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.