[BUG] ext4: possible circular locking dependency between xattr_sem and s_writepages_rwsem

From: ZW Tang

Date: Mon Aug 10 2026 - 23:56:01 EST


Hi,

I am reporting a possible circular locking dependency triggered by a
syzkaller reproducer on Linux 7.2-rc3.

The warning is reported by lockdep in the ext4 writeback / xattr path.
The task is mounting a crafted ext4 image and enters orphan cleanup
during ext4_fill_super(). During inode eviction, ext4_evict_inode()
calls __ext4_mark_inode_dirty(), which holds &ei->xattr_sem. The same
path then reaches ext4_xattr_block_set(), iput(), write_inode_now(),
writeback_single_inode(), do_writepages(), and finally
ext4_writepages(), where it tries to acquire &sbi->s_writepages_rwsem.

Lockdep reports that this creates a circular dependency, because
another dependency chain already exists in the reverse order:
ext4_writepages() / ext4_do_writepages() can acquire
&sbi->s_writepages_rwsem first and later acquire &ei->xattr_sem
through ext4_destroy_inline_data().

This looks like a potential ext4 lock-ordering issue between inode
xattr expansion / inline-data handling and writeback during mount-time
orphan cleanup, rather than a generic VFS or lockdep issue.

Reproducer:
syz reproducer: https://pastebin.com/raw/FspxvagG
console output: https://pastebin.com/raw/kQeWyFgs
kernel config: https://pastebin.com/raw/XUJkfYA0

Kernel:
kernel version: 7.2.0-rc3 #1 PREEMPT(full)
HEAD commit: 1137d8b5df06137fb49513cc923b3b24d94cb809
environment: QEMU Ubuntu 24.10
taint: Not tainted

Relevant warning:

WARNING: possible circular locking dependency detected
7.2.0-rc3 #1 Not tainted

syz.4.27/12346 is trying to acquire lock:
&sbi->s_writepages_rwsem, at: do_writepages+0x241/0x5b0

but task is already holding lock:
&ei->xattr_sem, at: __ext4_mark_inode_dirty+0x5c6/0x860

Existing dependency chain:

-> #1 (&ei->xattr_sem):
down_write
ext4_destroy_inline_data
ext4_do_writepages
ext4_writepages
do_writepages
filemap_writeback
file_write_and_wait_range
mmb_fsync_noflush
ext4_fsync_nojournal
ext4_sync_file
vfs_fsync_range
ext4_buffered_write_iter
ext4_file_write_iter
vfs_write
ksys_pwrite64

-> #0 (&sbi->s_writepages_rwsem):
ext4_writepages
do_writepages
__writeback_single_inode
writeback_single_inode
write_inode_now
iput
ext4_xattr_block_set
ext4_expand_extra_isize_ea
__ext4_expand_extra_isize
__ext4_mark_inode_dirty
ext4_evict_inode
evict
iput
ext4_orphan_cleanup
ext4_fill_super
get_tree_bdev_flags
vfs_get_tree
fc_mount
path_mount
do_mount
__x64_sys_mount

Lockdep also reports the following possible unsafe locking scenario:

CPU0 CPU1

lock(&ei->xattr_sem);
lock(&sbi->s_writepages_rwsem);
lock(&ei->xattr_sem);
rlock(&sbi->s_writepages_rwsem);

*** DEADLOCK ***

The reproducer mounts crafted ext4 images with options including
grpid, auto_da_alloc, lazytime, dioread_nolock, init_itable,
debug_want_extra_isize, bsdgroups, and min_batch_time, and then
performs a pwrite64() before mounting another crafted ext4 image. The
log also shows ext4 metadata errors before the warning, including
invalid indirect mapped block, invalid block bitmap, delayed block
allocation failures, and bad extra_isize, which appear to drive the
mount/orphan-cleanup and xattr expansion paths.

Thanks