diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 26f0f9714f03..8dd3dc9e0217 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -6603,8 +6603,14 @@ static int ext4_try_to_expand_extra_isize(struct inode *inode, * When !SB_ACTIVE, iput triggers write_inode_now() which acquires * s_writepages_rwsem, causing a deadlock with the caller's active * jbd2 handle (lock order: s_writepages_rwsem -> jbd2_handle). + * + * Skip it while unmounting as well. shrink_dcache_for_umount() + * clears s_root before generic_shutdown_super() clears SB_ACTIVE, and + * the last iput() of a lazytime inode in that window redirties it and + * lands here. Moving xattrs out to a block then needs a new EA inode, + * which ext4_xattr_inode_create() refuses without s_root. */ - if (unlikely(!(inode->i_sb->s_flags & SB_ACTIVE))) + if (unlikely(!(inode->i_sb->s_flags & SB_ACTIVE) || !inode->i_sb->s_root)) return -EBUSY; /*