On Fri 22-03-24 12:06:16, Andreas Dilger wrote: > On Mar 21, 2024, at 10:26 AM, Jan Kara <jack@xxxxxxx> wrote: > > > > ext4_xattr_set_entry() creates new EA inodes while holding buffer lock > > on the external xattr block. This is problematic as it nests all the > > allocation locking (which acquires locks on other buffers) under the > > buffer lock. This can even deadlock when the filesystem is corrupted and > > e.g. quota file is setup to contain xattr block as data block. Move the > > allocation of EA inode out of ext4_xattr_set_entry() into the callers. > > This looks like it will allocate a new inode for every setxattr called, > even if the xattr is small and will likely fit inside the inode itself? > This would seem to add a lot of extra overhead for the 99% of cases when > an external inode is not needed. This is not the case AFAICT. We call ext4_xattr_inode_lookup_create() only in: if (i->value && i->in_inode) { so that means we've already decided we need to put the xattr value in the EA inode. Note that ext4_xattr_set_handle() for smaller xattr value first calls ext4_xattr_block_set() with i.in_inode == 0 and if that fails due to ENOSPC, it sets i.in_inode = 1 and tries again. So I think everything is fine. Honza -- Jan Kara <jack@xxxxxxxx> SUSE Labs, CR