Re: [BUG] ext4: NULL/invalid pointer dereference in ext4_writepages() during generic/039
Ojaswin Mujoo <[email protected]> Tue, 4 Aug 2026 17:18:57 +0530
| Newsgroups | org.kernel.vger.linux-ext4,org.kernel.vger.linux-fsdevel,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
On Tue, Aug 04, 2026 at 12:41:09PM +0200, Jan Kara wrote: > Hello! > > On Tue 04-08-26 01:18:49, Ojaswin Mujoo wrote: > > On Mon, Aug 03, 2026 at 12:22:35PM +0530, Ojaswin Mujoo wrote: > ... > > > > Meanwhile, I will attempt bisection. > > > > > > > > If you happen to fix this issue, please add below tag. > > > > > > > > Reported-by: Venkat Rao Bagalkote <[email protected]> > > > > > > > > > > Hey thanks for reporting this Venkat, I'll try to replicate this at my > > > end. > > > > > > In the meantime, can you please share the complete Oops message and also > > > your local.config. > > > > > > Thanks, > > > ojaswin > > > > (+cc Jan, Christian) > > > > Okay so I'm able to replicate this in an x86 machine as well with 4kb > > block size. The issue is replicable in vfs/vfs.all and is occurring > > after Jan's change to nojournal mode writeout [1], with fast_commit. > > > > The issue is as follows: > > > > __ext4_fill_super > > ext4_load_and_init_journal > > ... > > jbd2_journal_recover > > do_one_pass > > fc_do_one_pass > > ... > > ext4_fc_replay_unlink > > __ext4_unlink > > __ext4_mark_iloc_dirty > > if (sbi->s_journal == NULL) // s_journal is not set yet > > set_inode_metadata_writeback(inode); // sets I_METADATA_WRITEBACK > > iput(inode) > > iput_final(inode) > > ... > > writeback_single_inode > > __writeback_single_inode // since I_METADATA_WRITEBACK is set > > ... > > ext4_writepages > > ext4_writepages_down_read > > percpu_down_read(sbi->s_writepages_rwsem) > > <--- OOPS because this is initialized > > later in ext4_percpu_param_init() > > > > A simple fix seems to be to move ext4_percpu_param_init() call before > > ext4_load_journal() so that we can safely call ext4_writepages(). The > > below diff seems to be fixing the issue for me, does this look okay to > > you Jan? > > Thanks for report and the analysis! I didn't realize fastcommit replay > actually runs in nojournal mode. I don't think moving > ext4_percpu_param_init() is really correct - it initializes also directory, > free blocks and other counters and those depend on filesystem already being > in consistent state (i.e., after journal replay). We would have to move > just s_writepages_rwsem initialization. Hey Jan, yes right thanks for pointing that out. > > That being said I think a nicer fix is to just avoid setting > I_METADATA_WRITEBACK flag during fastcommit replay. We don't really need > it for anything during replay (it flushes the whole bdev anyway), it just > slows things down by more frequent buffer writeout. I've tested that change > and it fixes the problem for me. I'll post it officially shortly. Sure thanks! Regards, ojaswin > > Honza > > > Also, venkat can you please help test this in your system: > > > > diff --git a/fs/ext4/super.c b/fs/ext4/super.c > > index 2877a6cf6d09..6e05f191542c 100644 > > --- a/fs/ext4/super.c > > +++ b/fs/ext4/super.c > > @@ -5511,6 +5511,10 @@ static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb) > > goto failed_mount3a; > > } > > > > + err = ext4_percpu_param_init(sbi); > > + if (err) > > + goto failed_mount3a; > > + > > err = -EINVAL; > > /* > > * The first inode we look at is the journal inode. Don't try > > @@ -5659,10 +5663,6 @@ static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb) > > clear_opt2(sb, MB_OPTIMIZE_SCAN); > > } > > > > - err = ext4_percpu_param_init(sbi); > > - if (err) > > - goto failed_mount5; > > - > > err = ext4_mb_init(sb); > > if (err) { > > ext4_msg(sb, KERN_ERR, "failed to initialize mballoc (%d)", > > @@ -5764,7 +5764,6 @@ failed_mount8: __maybe_unused > > ext4_mb_release(sb); > > ext4_flex_groups_free(sbi); > > failed_mount5: > > - ext4_percpu_param_destroy(sbi); > > ext4_ext_release(sb); > > ext4_release_system_zone(sb); > > failed_mount4a: > > @@ -5785,6 +5784,7 @@ failed_mount8: __maybe_unused > > ext4_journal_destroy(sbi, sbi->s_journal); > > } > > failed_mount3a: > > + ext4_percpu_param_destroy(sbi); > > ext4_es_unregister_shrinker(sbi); > > failed_mount3: > > /* flush s_sb_upd_work before sbi destroy */ > > > > [1] https://lore.kernel.org/linux-ext4/[email protected]/ > > > > > > > > > > > > Thanks, > > > > Venkat. > > > > > -- > Jan Kara <[email protected]> > SUSE Labs, CR