--- a/fs/ext4/ext4.h 2022-08-08 18:33:25.799893400 +0800 +++ b/fs/ext4/ext4.h 2022-08-08 18:40:22.348551400 +0800 @@ -441,6 +441,7 @@ struct flex_groups { #define EXT4_VERITY_FL 0x00100000 /* Verity protected inode */ #define EXT4_EA_INODE_FL 0x00200000 /* Inode used for large EA */ /* 0x00400000 was formerly EXT4_EOFBLOCKS_FL */ +#define EXT4_EA_NOQUOTA_FL 0x00800000 /* Create inode with S__NOQUOTA set */ #define EXT4_DAX_FL 0x02000000 /* Inode is DAX */ --- a/fs/ext4/ialloc.c 2022-08-08 18:33:45.089849400 +0800 +++ b/fs/ext4/ialloc.c 2022-08-08 18:44:05.175154200 +0800 @@ -962,6 +962,8 @@ struct inode *__ext4_new_inode(struct us return ERR_PTR(-ENOMEM); ei = EXT4_I(inode); + if (i_flags & EXT4_EA_NOQUOTA_FL) + inode->i_flags |= S_NOQUOTA; /* * Initialize owners and quota early so that we don't have to account * for quota initialization worst case in standard inode creating --- a/fs/ext4/xattr.c 2022-08-08 18:33:07.849816600 +0800 +++ b/fs/ext4/xattr.c 2022-08-08 21:25:55.872674700 +0800 @@ -647,7 +647,8 @@ ext4_xattr_get(struct inode *inode, int if (strlen(name) > 255) return -ERANGE; - down_read(&EXT4_I(inode)->xattr_sem); + if (!down_read_trylock(&EXT4_I(inode)->xattr_sem)) + return -EDEADLK; error = ext4_xattr_ibody_get(inode, name_index, name, buffer, buffer_size); if (error == -ENODATA) @@ -1388,7 +1389,10 @@ retry: block += 1; } - inode_lock(ea_inode); + if (!inode_trylock(ea_inode)) { + ret = -EDEADLK; + goto out; + } i_size_write(ea_inode, wsize); ext4_update_i_disksize(ea_inode, wsize); inode_unlock(ea_inode); @@ -1419,7 +1423,7 @@ static struct inode *ext4_xattr_inode_cr */ ea_inode = ext4_new_inode(handle, inode->i_sb->s_root->d_inode, S_IFREG | 0600, NULL, inode->i_ino + 1, owner, - EXT4_EA_INODE_FL); + EXT4_EA_INODE_FL | EXT4_EA_NOQUOTA_FL); if (!IS_ERR(ea_inode)) { ea_inode->i_op = &ext4_file_inode_operations; ea_inode->i_fop = &ext4_file_operations; @@ -1442,9 +1446,6 @@ static struct inode *ext4_xattr_inode_cr */ dquot_free_inode(ea_inode); dquot_drop(ea_inode); - inode_lock(ea_inode); - ea_inode->i_flags |= S_NOQUOTA; - inode_unlock(ea_inode); } return ea_inode;