add patch return-eio-on-read-error-in-ext4_find_dentry
[ext4-patch-queue.git] / do-not-set-posix-acls-on-xattr-inodes
blobd427b56eec896405226d3447ce10f9790914eb41
1 ext4: do not set posix acls on xattr inodes
3 From: Tahsin Erdogan <tahsin@google.com>
5 We don't need acls on xattr inodes because they are not directly
6 accessible from user mode.
8 Besides lockdep complains about recursive locking of xattr_sem as seen
9 below.
11   =============================================
12   [ INFO: possible recursive locking detected ]
13   4.11.0-rc8+ #402 Not tainted
14   ---------------------------------------------
15   python/1894 is trying to acquire lock:
16    (&ei->xattr_sem){++++..}, at: [<ffffffff804878a6>] ext4_xattr_get+0x66/0x270
18   but task is already holding lock:
19    (&ei->xattr_sem){++++..}, at: [<ffffffff80489500>] ext4_xattr_set_handle+0xa0/0x5d0
21   other info that might help us debug this:
22    Possible unsafe locking scenario:
24          CPU0
25          ----
26     lock(&ei->xattr_sem);
27     lock(&ei->xattr_sem);
29    *** DEADLOCK ***
31    May be due to missing lock nesting notation
33   3 locks held by python/1894:
34    #0:  (sb_writers#10){.+.+.+}, at: [<ffffffff803d829f>] mnt_want_write+0x1f/0x50
35    #1:  (&sb->s_type->i_mutex_key#15){+.+...}, at: [<ffffffff803dda27>] vfs_setxattr+0x57/0xb0
36    #2:  (&ei->xattr_sem){++++..}, at: [<ffffffff80489500>] ext4_xattr_set_handle+0xa0/0x5d0
38   stack backtrace:
39   CPU: 0 PID: 1894 Comm: python Not tainted 4.11.0-rc8+ #402
40   Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
41   Call Trace:
42    dump_stack+0x67/0x99
43    __lock_acquire+0x5f3/0x1830
44    lock_acquire+0xb5/0x1d0
45    down_read+0x2f/0x60
46    ext4_xattr_get+0x66/0x270
47    ext4_get_acl+0x43/0x1e0
48    get_acl+0x72/0xf0
49    posix_acl_create+0x5e/0x170
50    ext4_init_acl+0x21/0xc0
51    __ext4_new_inode+0xffd/0x16b0
52    ext4_xattr_set_entry+0x5ea/0xb70
53    ext4_xattr_block_set+0x1b5/0x970
54    ext4_xattr_set_handle+0x351/0x5d0
55    ext4_xattr_set+0x124/0x180
56    ext4_xattr_user_set+0x34/0x40
57    __vfs_setxattr+0x66/0x80
58    __vfs_setxattr_noperm+0x69/0x1c0
59    vfs_setxattr+0xa2/0xb0
60    setxattr+0x129/0x160
61    path_setxattr+0x87/0xb0
62    SyS_setxattr+0xf/0x20
63    entry_SYSCALL_64_fastpath+0x18/0xad
65 Signed-off-by: Tahsin Erdogan <tahsin@google.com>
66 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
67 ---
68  fs/ext4/ext4.h    | 11 ++++++-----
69  fs/ext4/ialloc.c  | 14 +++++++++-----
70  fs/ext4/migrate.c |  2 +-
71  fs/ext4/xattr.c   |  3 ++-
72  4 files changed, 18 insertions(+), 12 deletions(-)
74 diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
75 index 24ef56b4572f..5d5fc0d0e2bc 100644
76 --- a/fs/ext4/ext4.h
77 +++ b/fs/ext4/ext4.h
78 @@ -2400,16 +2400,17 @@ extern int ext4fs_dirhash(const char *name, int len, struct
79  /* ialloc.c */
80  extern struct inode *__ext4_new_inode(handle_t *, struct inode *, umode_t,
81                                       const struct qstr *qstr, __u32 goal,
82 -                                     uid_t *owner, int handle_type,
83 -                                     unsigned int line_no, int nblocks);
84 +                                     uid_t *owner, __u32 i_flags,
85 +                                     int handle_type, unsigned int line_no,
86 +                                     int nblocks);
88 -#define ext4_new_inode(handle, dir, mode, qstr, goal, owner) \
89 +#define ext4_new_inode(handle, dir, mode, qstr, goal, owner, i_flags) \
90         __ext4_new_inode((handle), (dir), (mode), (qstr), (goal), (owner), \
91 -                        0, 0, 0)
92 +                        i_flags, 0, 0, 0)
93  #define ext4_new_inode_start_handle(dir, mode, qstr, goal, owner, \
94                                     type, nblocks)                  \
95         __ext4_new_inode(NULL, (dir), (mode), (qstr), (goal), (owner), \
96 -                        (type), __LINE__, (nblocks))
97 +                        0, (type), __LINE__, (nblocks))
100  extern void ext4_free_inode(handle_t *, struct inode *);
101 diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
102 index e2eb3cc06820..fb1b3df17f6e 100644
103 --- a/fs/ext4/ialloc.c
104 +++ b/fs/ext4/ialloc.c
105 @@ -742,8 +742,9 @@ static int recently_deleted(struct super_block *sb, ext4_group_t group, int ino)
106   */
107  struct inode *__ext4_new_inode(handle_t *handle, struct inode *dir,
108                                umode_t mode, const struct qstr *qstr,
109 -                              __u32 goal, uid_t *owner, int handle_type,
110 -                              unsigned int line_no, int nblocks)
111 +                              __u32 goal, uid_t *owner, __u32 i_flags,
112 +                              int handle_type, unsigned int line_no,
113 +                              int nblocks)
115         struct super_block *sb;
116         struct buffer_head *inode_bitmap_bh = NULL;
117 @@ -1052,6 +1053,7 @@ struct inode *__ext4_new_inode(handle_t *handle, struct inode *dir,
118         /* Don't inherit extent flag from directory, amongst others. */
119         ei->i_flags =
120                 ext4_mask_flags(mode, EXT4_I(dir)->i_flags & EXT4_FL_INHERITED);
121 +       ei->i_flags |= i_flags;
122         ei->i_file_acl = 0;
123         ei->i_dtime = 0;
124         ei->i_block_group = group;
125 @@ -1108,9 +1110,11 @@ struct inode *__ext4_new_inode(handle_t *handle, struct inode *dir,
126                         goto fail_free_drop;
127         }
129 -       err = ext4_init_acl(handle, inode, dir);
130 -       if (err)
131 -               goto fail_free_drop;
132 +       if (!(ei->i_flags & EXT4_EA_INODE_FL)) {
133 +               err = ext4_init_acl(handle, inode, dir);
134 +               if (err)
135 +                       goto fail_free_drop;
136 +       }
138         err = ext4_init_security(handle, inode, dir, qstr);
139         if (err)
140 diff --git a/fs/ext4/migrate.c b/fs/ext4/migrate.c
141 index 364ea4d4a943..cf5181b62df1 100644
142 --- a/fs/ext4/migrate.c
143 +++ b/fs/ext4/migrate.c
144 @@ -475,7 +475,7 @@ int ext4_ext_migrate(struct inode *inode)
145         owner[0] = i_uid_read(inode);
146         owner[1] = i_gid_read(inode);
147         tmp_inode = ext4_new_inode(handle, d_inode(inode->i_sb->s_root),
148 -                                  S_IFREG, NULL, goal, owner);
149 +                                  S_IFREG, NULL, goal, owner, 0);
150         if (IS_ERR(tmp_inode)) {
151                 retval = PTR_ERR(tmp_inode);
152                 ext4_journal_stop(handle);
153 diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
154 index 09ba0137d529..12210fe87ea3 100644
155 --- a/fs/ext4/xattr.c
156 +++ b/fs/ext4/xattr.c
157 @@ -832,7 +832,8 @@ static struct inode *ext4_xattr_inode_create(handle_t *handle,
158          * in the same group, or nearby one.
159          */
160         ea_inode = ext4_new_inode(handle, inode->i_sb->s_root->d_inode,
161 -                                 S_IFREG | 0600, NULL, inode->i_ino + 1, NULL);
162 +                                 S_IFREG | 0600, NULL, inode->i_ino + 1, NULL,
163 +                                 EXT4_EA_INODE_FL);
164         if (!IS_ERR(ea_inode)) {
165                 ea_inode->i_op = &ext4_file_inode_operations;
166                 ea_inode->i_fop = &ext4_file_operations;
167 -- 
168 2.13.1.611.g7e3b11ae1-goog