Re: [syzbot] [ext4?] possible deadlock in ext4_destroy_inline_data (2)

Theodore Tso
2025-12-01T16:20:48Z

This is a flase positive. The potential deadlock scenarious dentified
by lockdep doesn't happen in real life because one of the locking
dependency chain happens when we are doing orphan file cleanup while
we are also eneding to expand an inode's extra size:

> -> #1 (&sbi->s_writepages_rwsem){++++}-{0:0}:
> lock_acquire+0x120/0x360 kernel/locking/lockdep.c:5868
> percpu_down_read_internal+0x48/0x1c0 include/linux/percpu-rwsem.h:53
> percpu_down_read include/linux/percpu-rwsem.h:77 [inline]
> ext4_writepages_down_read fs/ext4/ext4.h:1796 [inline]
> ext4_writepages+0x1cc/0x350 fs/ext4/inode.c:3024
> do_writepages+0x32e/0x550 mm/page-writeback.c:2604
> __writeback_single_inode+0x145/0xff0 fs/fs-writeback.c:1719
> writeback_single_inode+0x1f9/0x6a0 fs/fs-writeback.c:1840
> write_inode_now+0x160/0x1d0 fs/fs-writeback.c:2903
> iput_final fs/inode.c:1901 [inline]
> iput+0x830/0xc50 fs/inode.c:1966
> ext4_xattr_block_set+0x1fce/0x2ac0 fs/ext4/xattr.c:2199
> ext4_xattr_move_to_block fs/ext4/xattr.c:2664 [inline]
> ext4_xattr_make_inode_space fs/ext4/xattr.c:2739 [inline]
> ext4_expand_extra_isize_ea+0x12da/0x1ea0 fs/ext4/xattr.c:2827
> __ext4_expand_extra_isize+0x30d/0x400 fs/ext4/inode.c:6364
> ext4_try_to_expand_extra_isize fs/ext4/inode.c:6407 [inline]
> __ext4_mark_inode_dirty+0x46c/0x700 fs/ext4/inode.c:6485
> ext4_evict_inode+0x80d/0xee0 fs/ext4/inode.c:254
> evict+0x504/0x9c0 fs/inode.c:810
> ext4_orphan_cleanup+0xc20/0x1460 fs/ext4/orphan.c:470
> __ext4_fill_super fs/ext4/super.c:5617 [inline]
> ext4_fill_super+0x5920/0x61e0 fs/ext4/super.c:5736
....

And the other is in the inode writeback path:

> -> #0 (&ei->xattr_sem){++++}-{4:4}:
> check_prev_add kernel/locking/lockdep.c:3165 [inline]
> check_prevs_add kernel/locking/lockdep.c:3284 [inline]
> validate_chain+0xb9b/0x2140 kernel/locking/lockdep.c:3908
> __lock_acquire+0xab9/0xd20 kernel/locking/lockdep.c:5237
> lock_acquire+0x120/0x360 kernel/locking/lockdep.c:5868
> down_write+0x96/0x1f0 kernel/locking/rwsem.c:1590
> ext4_write_lock_xattr fs/ext4/xattr.h:157 [inline]
> ext4_destroy_inline_data+0x28/0xe0 fs/ext4/inline.c:1787
> ext4_do_writepages+0x526/0x4610 fs/ext4/inode.c:2810
> ext4_writepages+0x205/0x350 fs/ext4/inode.c:3025
> do_writepages+0x32e/0x550 mm/page-writeback.c:2604
> __writeback_single_inode+0x145/0xff0 fs/fs-writeback.c:1719
> writeback_sb_inodes+0x6c7/0x1010 fs/fs-writeback.c:2015
> wb_writeback+0x43b/0xaf0 fs/fs-writeback.c:2195
...

So the first happens while we are mounting the file system, and the
second happens after the file system is mounted and we have written to
a file.

That being said, we probably should just not try to expand the inode's
extra size while evicting the inode. In practice we don't actually do
this since we haven't expanded the inode's extra size space in over a
decade, and so this only happens in a debugging mount option that
syzbot helpfully uses, and not in real life.

Also, there's no real point in doing this on the evict path,
especially if the inode is about to be released as part of the
eviction.

- Ted