Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ext4: do not set posix acls on xattr inodes

We don't need acls on xattr inodes because they are not directly
accessible from user mode.

Besides lockdep complains about recursive locking of xattr_sem as seen
below.

=============================================
[ INFO: possible recursive locking detected ]
4.11.0-rc8+ #402 Not tainted
---------------------------------------------
python/1894 is trying to acquire lock:
(&ei->xattr_sem){++++..}, at: [<ffffffff804878a6>] ext4_xattr_get+0x66/0x270

but task is already holding lock:
(&ei->xattr_sem){++++..}, at: [<ffffffff80489500>] ext4_xattr_set_handle+0xa0/0x5d0

other info that might help us debug this:
Possible unsafe locking scenario:

CPU0
----
lock(&ei->xattr_sem);
lock(&ei->xattr_sem);

*** DEADLOCK ***

May be due to missing lock nesting notation

3 locks held by python/1894:
#0: (sb_writers#10){.+.+.+}, at: [<ffffffff803d829f>] mnt_want_write+0x1f/0x50
#1: (&sb->s_type->i_mutex_key#15){+.+...}, at: [<ffffffff803dda27>] vfs_setxattr+0x57/0xb0
#2: (&ei->xattr_sem){++++..}, at: [<ffffffff80489500>] ext4_xattr_set_handle+0xa0/0x5d0

stack backtrace:
CPU: 0 PID: 1894 Comm: python Not tainted 4.11.0-rc8+ #402
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
Call Trace:
dump_stack+0x67/0x99
__lock_acquire+0x5f3/0x1830
lock_acquire+0xb5/0x1d0
down_read+0x2f/0x60
ext4_xattr_get+0x66/0x270
ext4_get_acl+0x43/0x1e0
get_acl+0x72/0xf0
posix_acl_create+0x5e/0x170
ext4_init_acl+0x21/0xc0
__ext4_new_inode+0xffd/0x16b0
ext4_xattr_set_entry+0x5ea/0xb70
ext4_xattr_block_set+0x1b5/0x970
ext4_xattr_set_handle+0x351/0x5d0
ext4_xattr_set+0x124/0x180
ext4_xattr_user_set+0x34/0x40
__vfs_setxattr+0x66/0x80
__vfs_setxattr_noperm+0x69/0x1c0
vfs_setxattr+0xa2/0xb0
setxattr+0x129/0x160
path_setxattr+0x87/0xb0
SyS_setxattr+0xf/0x20
entry_SYSCALL_64_fastpath+0x18/0xad

Signed-off-by: Tahsin Erdogan <tahsin@google.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>

authored by

Tahsin Erdogan and committed by
Theodore Ts'o
1b917ed8 0de5983d

+18 -12
+6 -5
fs/ext4/ext4.h
··· 2411 2411 /* ialloc.c */ 2412 2412 extern struct inode *__ext4_new_inode(handle_t *, struct inode *, umode_t, 2413 2413 const struct qstr *qstr, __u32 goal, 2414 - uid_t *owner, int handle_type, 2415 - unsigned int line_no, int nblocks); 2414 + uid_t *owner, __u32 i_flags, 2415 + int handle_type, unsigned int line_no, 2416 + int nblocks); 2416 2417 2417 - #define ext4_new_inode(handle, dir, mode, qstr, goal, owner) \ 2418 + #define ext4_new_inode(handle, dir, mode, qstr, goal, owner, i_flags) \ 2418 2419 __ext4_new_inode((handle), (dir), (mode), (qstr), (goal), (owner), \ 2419 - 0, 0, 0) 2420 + i_flags, 0, 0, 0) 2420 2421 #define ext4_new_inode_start_handle(dir, mode, qstr, goal, owner, \ 2421 2422 type, nblocks) \ 2422 2423 __ext4_new_inode(NULL, (dir), (mode), (qstr), (goal), (owner), \ 2423 - (type), __LINE__, (nblocks)) 2424 + 0, (type), __LINE__, (nblocks)) 2424 2425 2425 2426 2426 2427 extern void ext4_free_inode(handle_t *, struct inode *);
+9 -5
fs/ext4/ialloc.c
··· 742 742 */ 743 743 struct inode *__ext4_new_inode(handle_t *handle, struct inode *dir, 744 744 umode_t mode, const struct qstr *qstr, 745 - __u32 goal, uid_t *owner, int handle_type, 746 - unsigned int line_no, int nblocks) 745 + __u32 goal, uid_t *owner, __u32 i_flags, 746 + int handle_type, unsigned int line_no, 747 + int nblocks) 747 748 { 748 749 struct super_block *sb; 749 750 struct buffer_head *inode_bitmap_bh = NULL; ··· 1053 1052 /* Don't inherit extent flag from directory, amongst others. */ 1054 1053 ei->i_flags = 1055 1054 ext4_mask_flags(mode, EXT4_I(dir)->i_flags & EXT4_FL_INHERITED); 1055 + ei->i_flags |= i_flags; 1056 1056 ei->i_file_acl = 0; 1057 1057 ei->i_dtime = 0; 1058 1058 ei->i_block_group = group; ··· 1110 1108 goto fail_free_drop; 1111 1109 } 1112 1110 1113 - err = ext4_init_acl(handle, inode, dir); 1114 - if (err) 1115 - goto fail_free_drop; 1111 + if (!(ei->i_flags & EXT4_EA_INODE_FL)) { 1112 + err = ext4_init_acl(handle, inode, dir); 1113 + if (err) 1114 + goto fail_free_drop; 1115 + } 1116 1116 1117 1117 err = ext4_init_security(handle, inode, dir, qstr); 1118 1118 if (err)
+1 -1
fs/ext4/migrate.c
··· 475 475 owner[0] = i_uid_read(inode); 476 476 owner[1] = i_gid_read(inode); 477 477 tmp_inode = ext4_new_inode(handle, d_inode(inode->i_sb->s_root), 478 - S_IFREG, NULL, goal, owner); 478 + S_IFREG, NULL, goal, owner, 0); 479 479 if (IS_ERR(tmp_inode)) { 480 480 retval = PTR_ERR(tmp_inode); 481 481 ext4_journal_stop(handle);
+2 -1
fs/ext4/xattr.c
··· 830 830 * in the same group, or nearby one. 831 831 */ 832 832 ea_inode = ext4_new_inode(handle, inode->i_sb->s_root->d_inode, 833 - S_IFREG | 0600, NULL, inode->i_ino + 1, NULL); 833 + S_IFREG | 0600, NULL, inode->i_ino + 1, NULL, 834 + EXT4_EA_INODE_FL); 834 835 if (!IS_ERR(ea_inode)) { 835 836 ea_inode->i_op = &ext4_file_inode_operations; 836 837 ea_inode->i_fop = &ext4_file_operations;