add patch add-get_inode_usage-callback-to-transfer-multi-inode-charges
[ext4-patch-queue.git] / modify-ext4_xattr_inode_array_to_hold_struct_inode_ptr
blob2939f8e5d51c04e312c246e7035412878e736be7
1 ext4: modify ext4_xattr_ino_array to hold struct inode *
3 From: Tahsin Erdogan <tahsin@google.com>
5 Tracking struct inode * rather than the inode number eliminates the
6 repeated ext4_xattr_inode_iget() call later. The second call cannot
7 fail in practice but still requires explanation when it wants to ignore
8 the return value. Avoid the trouble and make things simple.
10 Signed-off-by: Tahsin Erdogan <tahsin@google.com>
11 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
12 ---
13  fs/ext4/ext4.h  |  6 ++--
14  fs/ext4/inode.c |  8 ++---
15  fs/ext4/xattr.c | 93 ++++++++++++++++++++++++++++-----------------------------
16  fs/ext4/xattr.h |  5 ++--
17  4 files changed, 53 insertions(+), 59 deletions(-)
19 diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
20 index 2cdd6070e348..603edb5ff304 100644
21 --- a/fs/ext4/ext4.h
22 +++ b/fs/ext4/ext4.h
23 @@ -2232,9 +2232,9 @@ struct mmpd_data {
24  # define ATTRIB_NORET  __attribute__((noreturn))
25  # define NORET_AND     noreturn,
27 -struct ext4_xattr_ino_array {
28 -       unsigned int xia_count;         /* # of used item in the array */
29 -       unsigned int xia_inodes[0];
30 +struct ext4_xattr_inode_array {
31 +       unsigned int count;             /* # of used items in the array */
32 +       struct inode *inodes[0];
33  };
34  /* bitmap.c */
35  extern unsigned int ext4_count_free(char *bitmap, unsigned numchars);
36 diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
37 index d095bf7ad390..8ee20b586567 100644
38 --- a/fs/ext4/inode.c
39 +++ b/fs/ext4/inode.c
40 @@ -188,7 +188,7 @@ void ext4_evict_inode(struct inode *inode)
41         handle_t *handle;
42         int err;
43         int extra_credits = 3;
44 -       struct ext4_xattr_ino_array *lea_ino_array = NULL;
45 +       struct ext4_xattr_inode_array *ea_inode_array = NULL;
47         trace_ext4_evict_inode(inode);
49 @@ -257,7 +257,7 @@ void ext4_evict_inode(struct inode *inode)
50         /*
51          * Delete xattr inode before deleting the main inode.
52          */
53 -       err = ext4_xattr_delete_inode(handle, inode, &lea_ino_array);
54 +       err = ext4_xattr_delete_inode(handle, inode, &ea_inode_array);
55         if (err) {
56                 ext4_warning(inode->i_sb,
57                              "couldn't delete inode's xattr (err %d)", err);
58 @@ -345,9 +345,7 @@ void ext4_evict_inode(struct inode *inode)
60         ext4_journal_stop(handle);
61         sb_end_intwrite(inode->i_sb);
63 -       if (lea_ino_array != NULL)
64 -               ext4_xattr_inode_array_free(inode, lea_ino_array);
65 +       ext4_xattr_inode_array_free(ea_inode_array);
66         return;
67  no_delete:
68         ext4_clear_inode(inode);        /* We must guarantee clearing of inode... */
69 diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
70 index fd017faaf221..c09fcffb0878 100644
71 --- a/fs/ext4/xattr.c
72 +++ b/fs/ext4/xattr.c
73 @@ -1942,44 +1942,44 @@ int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize,
75  #define EIA_INCR 16 /* must be 2^n */
76  #define EIA_MASK (EIA_INCR - 1)
77 -/* Add the large xattr @ino into @lea_ino_array for later deletion.
78 - * If @lea_ino_array is new or full it will be grown and the old
79 +/* Add the large xattr @inode into @ea_inode_array for later deletion.
80 + * If @ea_inode_array is new or full it will be grown and the old
81   * contents copied over.
82   */
83  static int
84 -ext4_expand_ino_array(struct ext4_xattr_ino_array **lea_ino_array, __u32 ino)
85 +ext4_expand_inode_array(struct ext4_xattr_inode_array **ea_inode_array,
86 +                       struct inode *inode)
87  {
88 -       if (*lea_ino_array == NULL) {
89 +       if (*ea_inode_array == NULL) {
90                 /*
91                  * Start with 15 inodes, so it fits into a power-of-two size.
92 -                * If *lea_ino_array is NULL, this is essentially offsetof()
93 +                * If *ea_inode_array is NULL, this is essentially offsetof()
94                  */
95 -               (*lea_ino_array) =
96 -                       kmalloc(offsetof(struct ext4_xattr_ino_array,
97 -                                        xia_inodes[EIA_MASK]),
98 +               (*ea_inode_array) =
99 +                       kmalloc(offsetof(struct ext4_xattr_inode_array,
100 +                                        inodes[EIA_MASK]),
101                                 GFP_NOFS);
102 -               if (*lea_ino_array == NULL)
103 +               if (*ea_inode_array == NULL)
104                         return -ENOMEM;
105 -               (*lea_ino_array)->xia_count = 0;
106 -       } else if (((*lea_ino_array)->xia_count & EIA_MASK) == EIA_MASK) {
107 +               (*ea_inode_array)->count = 0;
108 +       } else if (((*ea_inode_array)->count & EIA_MASK) == EIA_MASK) {
109                 /* expand the array once all 15 + n * 16 slots are full */
110 -               struct ext4_xattr_ino_array *new_array = NULL;
111 -               int count = (*lea_ino_array)->xia_count;
112 +               struct ext4_xattr_inode_array *new_array = NULL;
113 +               int count = (*ea_inode_array)->count;
115                 /* if new_array is NULL, this is essentially offsetof() */
116                 new_array = kmalloc(
117 -                               offsetof(struct ext4_xattr_ino_array,
118 -                                        xia_inodes[count + EIA_INCR]),
119 +                               offsetof(struct ext4_xattr_inode_array,
120 +                                        inodes[count + EIA_INCR]),
121                                 GFP_NOFS);
122                 if (new_array == NULL)
123                         return -ENOMEM;
124 -               memcpy(new_array, *lea_ino_array,
125 -                      offsetof(struct ext4_xattr_ino_array,
126 -                               xia_inodes[count]));
127 -               kfree(*lea_ino_array);
128 -               *lea_ino_array = new_array;
129 +               memcpy(new_array, *ea_inode_array,
130 +                      offsetof(struct ext4_xattr_inode_array, inodes[count]));
131 +               kfree(*ea_inode_array);
132 +               *ea_inode_array = new_array;
133         }
134 -       (*lea_ino_array)->xia_inodes[(*lea_ino_array)->xia_count++] = ino;
135 +       (*ea_inode_array)->inodes[(*ea_inode_array)->count++] = inode;
136         return 0;
139 @@ -1987,16 +1987,16 @@ ext4_expand_ino_array(struct ext4_xattr_ino_array **lea_ino_array, __u32 ino)
140   * Add xattr inode to orphan list
141   */
142  static int
143 -ext4_xattr_inode_orphan_add(handle_t *handle, struct inode *inode,
144 -                       int credits, struct ext4_xattr_ino_array *lea_ino_array)
145 +ext4_xattr_inode_orphan_add(handle_t *handle, struct inode *inode, int credits,
146 +                           struct ext4_xattr_inode_array *ea_inode_array)
148 -       struct inode *ea_inode;
149         int idx = 0, error = 0;
150 +       struct inode *ea_inode;
152 -       if (lea_ino_array == NULL)
153 +       if (ea_inode_array == NULL)
154                 return 0;
156 -       for (; idx < lea_ino_array->xia_count; ++idx) {
157 +       for (; idx < ea_inode_array->count; ++idx) {
158                 if (!ext4_handle_has_enough_credits(handle, credits)) {
159                         error = ext4_journal_extend(handle, credits);
160                         if (error > 0)
161 @@ -2009,10 +2009,7 @@ ext4_xattr_inode_orphan_add(handle_t *handle, struct inode *inode,
162                                 return error;
163                         }
164                 }
165 -               error = ext4_xattr_inode_iget(inode,
166 -                               lea_ino_array->xia_inodes[idx], &ea_inode);
167 -               if (error)
168 -                       continue;
169 +               ea_inode = ea_inode_array->inodes[idx];
170                 inode_lock(ea_inode);
171                 ext4_orphan_add(handle, ea_inode);
172                 inode_unlock(ea_inode);
173 @@ -2034,13 +2031,14 @@ ext4_xattr_inode_orphan_add(handle_t *handle, struct inode *inode,
174   */
175  int
176  ext4_xattr_delete_inode(handle_t *handle, struct inode *inode,
177 -                       struct ext4_xattr_ino_array **lea_ino_array)
178 +                       struct ext4_xattr_inode_array **ea_inode_array)
180         struct buffer_head *bh = NULL;
181         struct ext4_xattr_ibody_header *header;
182         struct ext4_inode *raw_inode;
183         struct ext4_iloc iloc;
184         struct ext4_xattr_entry *entry;
185 +       struct inode *ea_inode;
186         unsigned int ea_ino;
187         int credits = 3, error = 0;
189 @@ -2057,8 +2055,12 @@ ext4_xattr_delete_inode(handle_t *handle, struct inode *inode,
190                 if (!entry->e_value_inum)
191                         continue;
192                 ea_ino = le32_to_cpu(entry->e_value_inum);
193 -               error = ext4_expand_ino_array(lea_ino_array, ea_ino);
194 +               error = ext4_xattr_inode_iget(inode, ea_ino, &ea_inode);
195 +               if (error)
196 +                       continue;
197 +               error = ext4_expand_inode_array(ea_inode_array, ea_inode);
198                 if (error) {
199 +                       iput(ea_inode);
200                         brelse(iloc.bh);
201                         goto cleanup;
202                 }
203 @@ -2070,7 +2072,7 @@ ext4_xattr_delete_inode(handle_t *handle, struct inode *inode,
204         if (!EXT4_I(inode)->i_file_acl) {
205                 /* add xattr inode to orphan list */
206                 error = ext4_xattr_inode_orphan_add(handle, inode, credits,
207 -                                                   *lea_ino_array);
208 +                                                   *ea_inode_array);
209                 goto cleanup;
210         }
211         bh = sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl);
212 @@ -2093,7 +2095,10 @@ ext4_xattr_delete_inode(handle_t *handle, struct inode *inode,
213                 if (!entry->e_value_inum)
214                         continue;
215                 ea_ino = le32_to_cpu(entry->e_value_inum);
216 -               error = ext4_expand_ino_array(lea_ino_array, ea_ino);
217 +               error = ext4_xattr_inode_iget(inode, ea_ino, &ea_inode);
218 +               if (error)
219 +                       continue;
220 +               error = ext4_expand_inode_array(ea_inode_array, ea_inode);
221                 if (error)
222                         goto cleanup;
223                 entry->e_value_inum = 0;
224 @@ -2101,7 +2106,7 @@ ext4_xattr_delete_inode(handle_t *handle, struct inode *inode,
226         /* add xattr inode to orphan list */
227         error = ext4_xattr_inode_orphan_add(handle, inode, credits,
228 -                                       *lea_ino_array);
229 +                                       *ea_inode_array);
230         if (error)
231                 goto cleanup;
233 @@ -2128,28 +2133,20 @@ ext4_xattr_delete_inode(handle_t *handle, struct inode *inode,
234         return error;
237 -void
238 -ext4_xattr_inode_array_free(struct inode *inode,
239 -                           struct ext4_xattr_ino_array *lea_ino_array)
240 +void ext4_xattr_inode_array_free(struct ext4_xattr_inode_array *ea_inode_array)
242         struct inode    *ea_inode;
243         int             idx = 0;
244 -       int             err;
246 -       if (lea_ino_array == NULL)
247 +       if (ea_inode_array == NULL)
248                 return;
250 -       for (; idx < lea_ino_array->xia_count; ++idx) {
251 -               err = ext4_xattr_inode_iget(inode,
252 -                               lea_ino_array->xia_inodes[idx], &ea_inode);
253 -               if (err)
254 -                       continue;
255 -               /* for inode's i_count get from ext4_xattr_delete_inode */
256 -               iput(ea_inode);
257 +       for (; idx < ea_inode_array->count; ++idx) {
258 +               ea_inode = ea_inode_array->inodes[idx];
259                 clear_nlink(ea_inode);
260                 iput(ea_inode);
261         }
262 -       kfree(lea_ino_array);
263 +       kfree(ea_inode_array);
266  /*
267 diff --git a/fs/ext4/xattr.h b/fs/ext4/xattr.h
268 index e82c5fe36a26..323eba54f72f 100644
269 --- a/fs/ext4/xattr.h
270 +++ b/fs/ext4/xattr.h
271 @@ -164,9 +164,8 @@ extern int ext4_xattr_set_credits(struct inode *inode, size_t value_len);
273  extern int ext4_xattr_inode_unlink(struct inode *inode, unsigned long ea_ino);
274  extern int ext4_xattr_delete_inode(handle_t *handle, struct inode *inode,
275 -                                  struct ext4_xattr_ino_array **array);
276 -extern void ext4_xattr_inode_array_free(struct inode *inode,
277 -                                       struct ext4_xattr_ino_array *array);
278 +                                  struct ext4_xattr_inode_array **array);
279 +extern void ext4_xattr_inode_array_free(struct ext4_xattr_inode_array *array);
281  extern int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize,
282                             struct ext4_inode *raw_inode, handle_t *handle);
283 -- 
284 2.13.1.611.g7e3b11ae1-goog