On Wed, Dec 16, 2020 at 11:18:42AM +0100, Jan Kara wrote: > Xattr code using inodes with large xattr data can end up dropping last > inode reference (and thus deleting the inode) from places like > ext4_xattr_set_entry(). That function is called with transaction started > and so ext4_evict_inode() can deadlock against fs freezing like: > > CPU1 CPU2 > > removexattr() freeze_super() > vfs_removexattr() > ext4_xattr_set() > handle = ext4_journal_start() > ... > ext4_xattr_set_entry() > iput(old_ea_inode) > ext4_evict_inode(old_ea_inode) > sb->s_writers.frozen = SB_FREEZE_FS; > sb_wait_write(sb, SB_FREEZE_FS); > ext4_freeze() > jbd2_journal_lock_updates() > -> blocks waiting for all > handles to stop > sb_start_intwrite() > -> blocks as sb is already in SB_FREEZE_FS state > > Generally it is advisable to delete inodes from a separate transaction > as it can consume quite some credits however in this case it would be > quite clumsy and furthermore the credits for inode deletion are quite > limited and already accounted for. So just tweak ext4_evict_inode() to > avoid freeze protection if we have transaction already started and thus > it is not really needed anyway. > > CC: stable@xxxxxxxxxxxxxxx > Fixes: dec214d00e0d ("ext4: xattr inode deduplication") > CC: Tahsin Erdogan <tahsin@xxxxxxxxxx> > Signed-off-by: Jan Kara <jack@xxxxxxx> Already applied. - Ted